Skip to content

The character set

Two hundred and fifty-six characters, in ROM, eight bytes each. They are IBM Code Page 437 — the set the original PC shipped with, which is why it has box-drawing lines, card suits, Greek letters and three densities of shading alongside the alphabet.

Each glyph is an 8 × 8 cell with the drawing five pixels wide and pushed to the left of the byte. The Kernal copies the whole lot into the video card at power-on, so this table is what the screen has to work with.

Row is the high hex digit, column the low one. A is row 4, column 1$41, which is also 65, which is also what ASC("A") tells you.

0123456789ABCDEF
0x
1x
2x
3x
4x
5x
6x
7x
8x
9x
Ax
Bx
Cx
Dx
Ex
Fx

What PRINT can reach

Not all of it — and this is the thing that catches people.

PRINT CHR$(n) goes through the Kernal's Chrout, and Chrout's video path passes $20 to $7E through to the screen, honours four control codes (carriage return, line feed, backspace and bell), and discards everything else. That includes every code from $7F up: all the box drawing, all the shading, every accented letter.

So this does nothing at all:

basic
PRINT CHR$(219)

The character is there in ROM. It is Chrout that will not pass it on.

Getting at the rest

From assembly there is a second routine, VideoChroutRaw, which puts any of the 256 codes on the screen unfiltered. That is how a program draws a box or fills an area with shading — see The screen.

From BASIC, the way to reach the upper half is to redefine the characters you can print. The pattern table is writable, so you can point A at whatever shape you like and then print A.

Which codes are which

RangeWhat is in it
$00$1FFaces, card suits, arrows, musical notes. Historically the control codes; here they are pictures
$20$7ESpace, punctuation, digits, capitals, lower case — plain ASCII, and the only part PRINT will pass
$7FA house
$80$AFAccented letters, currency, fractions, Spanish punctuation
$B0$B2Light, medium and dark shading — the three densities
$B3$DABox drawing, single and double lined
$DB$DFSolid blocks: full, half, quarters
$E0$FEGreek letters and math symbols
$FFA blank, distinct from space only in that it is a different code

Where it lives

The set sits at $B800$BFFF, immediately above the Kernal and below BASIC. It is 2 KB of the 32 KB ROM: 256 characters × 8 bytes each, exactly.

The memory map has the rest of the ROM; The screen covers writing to the pattern table and the character-set tricks that make text-mode games work.

Written for BIOS v1.5. Released under the MIT License.