Agon Light Tilemap

A test tile would contain

const unsigned char red_tile[64] = {
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
    0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3
};

// 8x8 checkerboard tile (black & white opaque) in RGBA2222
const unsigned char checker_tile[64] = {
    0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,
    0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,
    0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,
    0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,
    0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,
    0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,
    0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,
    0xC0,0xFF,0xC0,0xFF,0xC0,0xFF,0xC0,0xFF
};

You need to have this

void write16bit(int16_t w)
{
    putch(w & 0xFF);    // write LSB
    putch((w >> 8) & 0xFF);        // write MSB
}

And then this

void init_tilemap()
{
    // Enable tilemap
    putch(23);putch(0);putch(0xF8);write16bit(0x0300);write16bit(1);
    // Init/reset tile bank
    putch(23);putch(0);putch(0xc2);putch(0);putch(0);putch(0);putch(0);putch(0);

    // Load tile 1 with red tiles
    putch(23);putch(0);putch(0xc2);putch(1);putch(0);putch(1);
    for (int i = 0; i < 64; i++)
        putch(0xC3);
    //load tile 2 with checkerboard
    putch(23);putch(0);putch(0xc2);putch(1);putch(0);putch(2);
    for (int i = 0; i < 64; i++)
        putch(checker_tile[i]);

    // Init/reset tile layer to be 40x30
    putch(23);putch(0);putch(0xC2);putch(24);putch(0);putch(2);putch(0);putch(0);

    // Init tilemap to be 32x32 - this shouldn't fill the screen
    putch(23);putch(0);putch(0xC2);putch(16);putch(0);putch(0);putch(0);putch(0);

    // Fill the tilemap with red tiles
    // VDU 23, 0, &C2, 17, 0, <xpos>, <ypos>, <tileid>, <attribute>
    for (int y = 0; y < 32; y++) {
        for (int x = 0; x < 32; x++) {
            int tile = ((x + y) % 2) ? 2 : 1;
            putch(23);putch(0);putch(0xC2);putch(17);putch(0);
            putch(x);putch(y);putch(tile);putch(0);
        }
    }

}

And then you can use this

void update_tilemap(int xpos, int ypos, int xoff, int yoff)
{
    // Set scroll params
    putch(23);putch(0);putch(0xC2);putch(26);putch(0);
    putch(xpos);putch(ypos);putch(xoff);putch(yoff);

    // Draw a single tile of each kind on the screen as a test
  //  putch(23);putch(0);putch(0xC2);putch(6);putch(0);putch(1);putch(0);
  //  putch(0);putch(0);putch(0);putch(0);putch(0);

   // putch(23);putch(0);putch(0xC2);putch(6);putch(0);putch(2);putch(0);
   // putch(0);putch(1);putch(0);putch(0);putch(0);

    // Update and draw tile layer
    putch(23);putch(0);putch(0xC2);putch(30);putch(0);
}

And finally

        x_off++;
        y_off++;
        if (x_off >= 8) { x_off -= 8; map_x = (map_x + 1) % 32; }
        if (x_off < 0)  { x_off += 8; map_x = (map_x + 31) % 32; }
        if (y_off >= 8) { y_off -= 8; map_y = (map_y + 1) % 32; }
        if (y_off < 0)  { y_off += 8; map_y = (map_y + 31) % 32; }
        update_tilemap(map_x,map_y ,x_off ,y_off );