Skip to content

The character set

Two hundred and fifty-six characters, 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 a 6 × 8 cell with the drawing five pixels wide, leaving a column of space to its right so that letters don't touch. The set belongs to the video card, which carries it in its own firmware, 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 on the card. 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

Not in the ROM. The video card keeps the set in its firmware and copies it into its own memory, at $0800$0FFF of the card's 64 KB: 2 KB, 256 characters × 8 bytes each, exactly. That copy is the pattern table text mode draws from, and nothing in the computer's own address space holds another.

Because it is a copy, it can be changed and put back. Rewrite a character's eight bytes and every place it appears on the screen changes shape; the Kernal's InitVideo has the card copy its set in again, and VdpLoadFont copies it into any pattern table a program has set up. The screen covers both, and the character-set tricks that make text-mode games work.

Written for BIOS v2.0. Released under the MIT License.