C64 Maps

The Commodore 64's character mode is a tile display. Screen RAM holds a grid of character codes, each a tile, and Colour RAM gives each tile its colour. A screenful is 40×25 tiles; a larger world is stored in memory and windowed onto the screen as it scrolls.

C64 Maps

Overview

In character mode each screen cell names a tile: the VIC-II reads a character code from screen RAM, looks up its 8×8 shape in the charset, and draws it in the cell's colour. A redefined charset turns those glyphs into map tiles, so screen RAM is effectively a 40×25 tile map that costs one byte per cell.

PropertyValue
Visible tiles40 × 25
Tile size8 × 8 pixels
Distinct tiles256 (one charset)
Screen RAM1000 bytes, default $0400
Colour RAM1000 nibbles, $D800–$DBFF

Screen RAM and tiles

Screen RAM is 1000 bytes, one per cell, in plain row order: cell at column cx, row cy is at base + cy × 40 + cx. The default base is $0400, though $D018 can move it in 1K steps within the VIC bank. Each byte is a screen code, the direct index of the tile in the charset, so writing a code paints that tile.

ByteMeaning
Screen code 0–255Tile index into the charset for that cell.

With 256 possible tiles, a map's building blocks are drawn once into the charset and then placed by code across screen RAM, the same way text is drawn but with tile artwork.

Colour RAM

Colour RAM is a separate 1000-cell area at $D800–$DBFF, one nibble per screen cell, in the same row order as screen RAM. Only the low four bits are used, giving each tile one of the 16 colours in standard mode. So a tile's identity comes from screen RAM and its colour from the matching Colour RAM nibble.

AreaAddressPer cellHolds
Screen RAM$0400 (default)1 byteTile screen code.
Colour RAM$D8001 nibbleTile colour (0–15).

Coloured tiles

Standard character mode gives each tile one colour over the background. Turning on multicolour character mode lets a tile show up to four colours. When the cell's Colour RAM nibble has bit 3 set, the tile's glyph is read two bits per pixel, so it is 4×8 double-width pixels, and each pair picks one of four colours.

Bit pairColour source
00Background colour, register $D021
01Shared colour, register $D022
10Shared colour, register $D023
11Low three bits of the cell's Colour RAM nibble

This gives colourful tiles at half the horizontal resolution, with two colours shared across the whole map and one chosen per tile, plus the background. A multicolour charset is the usual way to draw detailed map scenery.

Large maps and scrolling

A world larger than 40×25 is stored in memory as its own tile array and windowed onto the screen. As the view moves, the code copies the newly visible strip of tiles and colours into screen RAM and Colour RAM. For smooth motion the VIC-II offers fine scrolling: the low three bits of $D011 shift the display vertically and $D016 horizontally, up to 7 pixels.

The usual technique is to fine-scroll one pixel at a time, and when the offset wraps past 7, shift the whole map by a tile and reset the fine offset. Narrowing the display by one row or column with the same registers hides the partly-drawn edge cell while scrolling.

RegisterBitsMeaning
$D0110–2Fine vertical scroll, 0–7 pixels.
$D0160–2Fine horizontal scroll, 0–7 pixels.
$D016338-column mode, hides the edge cell while scrolling.
$D011324-row mode, hides the edge row while scrolling.