C64 Fonts
The Commodore 64 draws text from a character generator holding 8×8 glyphs. Two charsets live in the character ROM, and a program can point the VIC-II at RAM instead to use its own redefined font. Each glyph is 8 bytes, one row per byte, with the top bit on the left.
Overview
In text mode the screen is 40×25 character cells. Each cell holds one screen code, and the VIC-II looks up that code's 8×8 shape in the character generator and draws it in the cell's colour. The generator is a table of 256 glyphs, 8 bytes each, so a full charset is 2K.
| Property | Value |
|---|---|
| Cells | 40 × 25 |
| Glyph size | 8 × 8 pixels |
| Bytes per glyph | 8 (one row each) |
| Glyphs per charset | 256 |
| Charset size | 2048 bytes |
The character ROM
The character ROM is 4K and is visible to the VIC-II at $D000–$DFFF in its address space. It holds two 256-glyph charsets of 2K each. The first is the uppercase and graphics set; the second is the upper and lowercase set. A program picks between them at runtime, and each is a full 8×8 font.
| Offset in ROM | Charset |
|---|---|
| $0000–$07FF | Uppercase and graphics (256 glyphs) |
| $0800–$0FFF | Upper and lowercase (256 glyphs) |
Glyph byte format
A glyph is 8 consecutive bytes. Byte 0 is the top pixel row and byte 7 the bottom. In each byte the most significant bit is the leftmost pixel: a 1 draws the character colour, a 0 leaves the background. So the glyph for code c starts at charset base + c × 8.
| Byte | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|---|
| 0 (top) | Leftmost pixel … rightmost pixel of the top row | |||||||
| 1–6 | Middle rows, top to bottom | |||||||
| 7 (bottom) | Bottom row, left to right | |||||||
In multicolour character mode a cell can show up to four colours. When the cell's Colour RAM nibble has bit 3 set, the glyph bytes are read two bits per pixel, giving 4×8 double-width pixels whose pairs select the background and two shared colours from $D022 and $D023, plus the low three bits of the cell's colour.
Screen codes and PETSCII
Two numbering schemes exist. PETSCII is Commodore's character encoding used for keyboard input, strings and printing; it resembles ASCII but with its own order and the graphics characters. Screen codes are what actually goes into a screen cell, and they run 0 to 255 as the direct index into the charset.
The two differ: for example the letter A is PETSCII 65 but screen code 1. The KERNAL converts PETSCII to screen codes when it prints, so code you place directly into screen RAM must already be a screen code.
| Scheme | Range | Role |
|---|---|---|
| PETSCII | 0–255 | Keyboard, strings, printing. |
| Screen code | 0–255 | Direct glyph index written to screen RAM. |
Redefining the font
The VIC-II does not have to use the ROM font. The upper bits of the memory-control register $D018 set the character base, in 2K steps, within the current 16K VIC bank. Pointing that base at RAM and filling it with new glyphs replaces the whole charset, so a game can draw with custom tiles and symbols.
The usual method is to copy the ROM font into RAM, edit the glyphs that need to change, then set $D018 to the new base. Two ROM areas, $1000–$1FFF and $9000–$9FFF, are where the character ROM appears to the VIC-II by default, so a redefined font is normally placed elsewhere in the bank.
| Register | Bits | Meaning |
|---|---|---|
| $D018 | 1–3 | Character base within bank, in 2K steps. |
| $DD00 | 0–1 | VIC bank select, so the font must be in that bank. |