User Defined Graphics (UDGs)
Custom 8×8 character glyphs on the Sinclair ZX Spectrum
Twenty-one programmer-supplied 8×8 patterns that the Spectrum's character system treats as ordinary letters, opening pixel-level graphics to BASIC programs.
Overview
A UDG — User Defined Graphic — is a programmer-supplied 8×8 pixel pattern that the Spectrum's character system treats as if it were one of the resident font glyphs. Sinclair BASIC reserves twenty-one UDG slots, addressed from USR "a" through USR "u". Once a UDG is defined, it can be printed with PRINT CHR$ 144 (the code for USR "a"), set as the cursor character, or drawn into any string. The eight bytes that describe a UDG live in the UDG buffer — by default at $FF58 on a 48K machine — and the value of the system variable UDG ($5C7B) points to wherever the buffer currently sits.
UDGs are the BASIC programmer's bridge into pixel art. Without them, the highest-resolution thing a BASIC program could draw was a coloured 8×8 cell. With them, every character on screen could be a hand-designed piece of art.
How they work
The Spectrum's character ROM defines 96 standard 8×8 glyphs (letters, digits, punctuation, the cursor). When the ROM's PRINT routine encounters a character code above the ASCII range (codes 144-164), it doesn't look at the character ROM — it looks at the UDG buffer pointed to by the UDG system variable.
Each UDG is exactly 8 bytes. Top row first, bottom row last; within each byte, bit 7 is the leftmost pixel.
Row 0: byte 0 — top pixel row
Row 1: byte 1
...
Row 7: byte 7 — bottom pixel row
So 21 UDGs × 8 bytes = 168 bytes total. The default UDG buffer starts at $FF58 and runs to $FFFF, sitting at the top of 48K RAM where BASIC's variable space won't normally encroach.
Defining a UDG in BASIC
10 FOR n=0 TO 7
20 READ b
30 POKE USR "a"+n, b
40 NEXT n
50 PRINT CHR$ 144
60 DATA 24,60,126,90,255,90,36,36
Lines 10-40 walk through eight bytes of DATA, poking each into successive bytes of the UDG buffer starting at USR "a" (= $FF58 by default). Line 50 then prints the UDG glyph at the current cursor position, where it appears as an 8×8 piece of art rendered from the bytes the program just wrote.
The same loop works for any of the 21 slots — USR "b", USR "c", etc. The numeric codes are 144 through 164.
Defining a UDG in assembly
Assembly programs typically bypass the BASIC UDG mechanism entirely and write directly to the Spectrum's bitmap memory at $4000-$57FF. The design discipline is identical — eight bytes, one bit per pixel, bit 7 leftmost — but the destination is the cell's actual bitmap row addresses rather than the UDG buffer:
Cell (row, col) → top bitmap byte at:
$4000 + (third × $0800) + (row_in_third × $0020) + col
Subsequent rows of the same cell are at +$0100, +$0200, ..., +$0700.
The UDG mechanism is convenient for BASIC programs that want characters in a string. Assembly games that want a sprite at an arbitrary screen position write the eight bytes directly to where the sprite should appear.
Cultural significance
UDGs are what made BASIC games on the Spectrum look like games rather than ASCII art. The 21-slot limit was tight — most magazine listings of arcade clones used UDGs aggressively, with multiple glyphs combining to form a single visual element (a 16×16 spaceship might be four UDGs side by side). The USR "..." syntax in BASIC was famously clunky to type-in, requiring the user to enter graphics mode (CAPS SHIFT + 9), then the letter, then back out — a small ritual that magazine articles like those in Crash and Your Sinclair walked readers through.
For programmers coming from Commodore's PETSCII (which had a fixed graphics character set baked into ROM), the Spectrum's UDGs offered far more flexibility at the cost of a per-game design step. Every Spectrum BASIC game with custom visuals went through this design step.