This program copies the current ROM font data into RAM and redirects the system font pointer to use the RAM copy, enabling user-defined character shapes across the full printable ASCII range. It reads 96 characters (each 8 bytes tall) from the address stored in system variables 23606–23607, storing them starting at address 64000 with the byte order within each character reversed vertically (the loop uses `7-P` to mirror each glyph). After copying, it reprograms the font pointer (system variables 23606–23607) to point to address 63744 (0×F900), so the ROM character set routine finds the new RAM data. A recovery routine at line 100 restores the pointer to address 15360 (60×256), which is the standard ROM font location.
Program Analysis
Program Structure
The program is a short utility divided into two logical parts. Lines 10–90 perform the font-copy operation and redirect the system font pointer. Line 100 onward provides a recovery routine that can be run independently to restore the original ROM font pointer.
- Line 10:
CLEAR 63999— reserves the top of BASIC RAM and protects memory from address 64000 upward for the font buffer. - Lines 20–60: Locate the current font, copy all 96 characters into RAM with vertically-mirrored byte order.
- Line 80: Update the font pointer system variables to address 63744 (0×F900).
- Line 90:
STOPprevents the recovery routine from running automatically. - Lines 100–110: Recovery — restores system variables 23606–23607 to point back to the ROM font at 15360.
Font Pointer and System Variables
System variables at addresses 23606 and 23607 hold the low and high bytes of a pointer to the font data. The font address stored there points to the data for the character whose ASCII code is 32 (space) minus 256 bytes, following the standard convention. After the copy, POKE 23606,0: POKE 23607,249 sets the pointer to 249×256 = 63744, which is exactly 256 bytes before the copied data at 64000 — correctly accounting for the offset convention.
The recovery routine at line 110 restores the pointer to 60×256 = 15360, which is the standard ROM font base address (again, 256 bytes before the ROM character data at 15616).
Font Source Address Calculation
Line 20 uses a notable BASIC idiom:
LET C=VAL "PEEK 23606+256*PEEK 23607+256"
The VAL keyword evaluates its string argument as a numeric expression at runtime. This computes the font start address from the current system variable values and adds 256 — giving the address of the actual first character glyph (for space, ASCII 32) by reversing the −256 offset convention. This is a compact way to embed an expression that would otherwise require temporary variables or nested arithmetic.
Vertical Byte Reversal
The inner loop copies each 8-byte character glyph with the destination index 7-P instead of P. This reverses the vertical order of the pixel rows within each character. Depending on intent, this could be a deliberate artistic effect (producing upside-down characters in the RAM copy) or a bug — a straightforward copy would use POKE 64000+P+8*J, PEEK (C+P+8*J). The reversal means the RAM font will display all characters vertically flipped relative to the ROM originals.
Notable Techniques
CLEAR 63999is used as a memory reservation mechanism, preventing BASIC from allocating variables or the stack into the font buffer area above 64000.VAL "expression"is used to evaluate a multi-term arithmetic expression involvingPEEK, saving a line and avoiding intermediate variables — a well-known memory and speed optimization.- The font pointer offset convention (pointer = font address − 256) is handled correctly in both the copy destination setup and the recovery routine.
- Looping over 96 characters (J = 0 to 95) covers the full printable ASCII range from space (32) to tilde/copyright (127).
Potential Issues
| Issue | Detail |
|---|---|
| Vertical byte reversal | The use of 7-P in the destination POKE flips each glyph upside-down. Whether this is intentional or a bug depends on the author’s goal. |
| Line 80 split with colon | Two POKEs on one line is valid and saves memory; no issue. |
| Missing line 70 | Line numbers jump from 60 to 80; this is cosmetic and has no functional effect. |
Content
Source Code
10 CLEAR 63999
20 LET C=VAL "PEEK 23606+256*PEEK 23607+256"
30 FOR J=0 TO 95
40 FOR P=0 TO 7
50 POKE 64000+7-P+8*J,PEEK (C+P+8*J)
60 NEXT P: NEXT J
80 POKE 23606,0: POKE 23607,249
90 STOP
100 REM RECOVERY
110 POKE 23606,0: POKE 23607,60
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
