Skip to content
Game 14 Unit 1 of 32 1 hr learning time

Custom Characters

USR, POKE and BIN — define your first user-defined graphic on the Spectrum.

3% of Blockstorm

Every game so far has used the characters the Spectrum provides — letters, numbers, symbols from the built-in set. Blockstorm is different. Every sprite on screen is a character you design yourself. The player ship, every enemy type, bullets, explosions — all custom. This unit introduces user-defined graphics (UDGs) and the three commands that make them work: USR, POKE and BIN.

The Program

5 REM === CUSTOM CHARACTERS ===
10 BORDER 0: PAPER 0: INK 7: CLS
20 PRINT AT 3, 10; BRIGHT 1; "BLOCKSTORM"
30 PRINT AT 6, 2; INK 6; "Learning to define UDGs"
40 REM Define UDG A: a simple block alien
50 FOR i = 0 TO 7
60 READ a
70 POKE USR "A" + i, a
80 NEXT i
90 DATA 36, 126, 219, 255, 255, 102, 66, 0
100 PRINT AT 10, 14; INK 4; "A = "; CHR$ 144
110 PRINT AT 12, 2; INK 7; "That character is a UDG."
120 PRINT AT 13, 2; INK 7; "We defined it with POKE USR."
130 PRINT AT 15, 2; INK 6; "Each row is 8 pixels wide."
140 PRINT AT 16, 2; INK 6; "8 rows = 8 bytes of DATA."
150 PRINT AT 20, 6; INK 7; "Press any key"
160 PAUSE 0

How It Works

Line 10 sets the screen to black background with white text — the colour scheme for the entire game. BORDER 0 makes the border black, PAPER 0 makes the background black, INK 7 sets the text to white, and CLS clears the screen.

Lines 20-50 define a custom character. The Spectrum reserves space for 21 user-defined graphics, labelled A through U. Each UDG is 8 bytes — one byte per row of the 8x8 pixel grid. The POKE command writes each byte directly into the memory address where the Spectrum stores UDG data. USR “A” returns the starting address for UDG A, and we add 0 through 7 to reach each row.

Line 60 displays the custom character using PRINT AT and CHR$ 144. UDG A is character code 144, UDG B is 145, and so on. Once defined, a UDG works exactly like any built-in character — you print it at any position on screen.

Lines 70-80 show the title and the UDG side by side, demonstrating that custom characters and normal text mix freely.

The USR Function

USR “A” returns the memory address where UDG A is stored. On a 48K Spectrum, this is 65368. UDG B starts at 65376 (eight bytes later), UDG C at 65384, and so on. You do not need to memorise these addresses — USR calculates them for you.

Binary and Pixels

Each row of a UDG is one byte — eight bits, one per pixel. A 1 bit means the pixel is filled (drawn in the current INK colour). A 0 bit means the pixel is empty (shows the PAPER colour). BIN converts a string of ones and zeros into the number that byte represents:

BIN 00111100 = 60
BIN 01111110 = 126
BIN 11111111 = 255

Reading the binary values top to bottom, you can see the shape. Ones form the visible pixels. Zeros form the gaps. An 8x8 grid of ones and zeros is your sprite.

Try This

Design a simple shape. Draw an 8x8 grid on paper. Fill in squares to make a pattern — a smiley face, an arrow, a diamond. Convert each row to binary and POKE it into UDG B (USR “B”). Display it with CHR$ 145.

Fill a row. Use a FOR/NEXT loop to print your UDG across an entire row of the screen. One custom character, repeated 32 times, creates a border or a wall.