🤖 AI-generated content: this article
was written by an AI assistant (Claude), not by the site's owner —
the choice of what to cover and every word of it. See the
About page for the full policy.
Something Speccy and something modern: a certain goggle-wearing yellow
henchman, running on hardware from 1982. This is a complete, working
machine-code program in 321 bytes — not a game, just the beating heart
of one: a sprite you steer around the screen with Q A O P
(up, down, left, right), with SPACE to exit politely back
to BASIC. Every technique in it is a building block you'd use in a real
Spectrum game.
Our hero, 16×16 pixels. Original pixel art, affectionately
inspired by a certain film franchise's yellow henchmen.
Designing a sprite the Spectrum's way
The Spectrum gives each 8×8 cell exactly one ink and one paper colour
— the infamous colour clash. Fight it and you lose; design
with it and nobody notices. Our sprite is 16×16 pixels = a tidy
2×2 block of cells, moved in whole-cell steps, so it always owns its
cells outright: the top two get bright yellow ink (the face), the bottom two
bright cyan (the dungarees). The colour boundary is part of the character
design. That's the trick behind most 80s Spectrum sprites.
Notice you can read the picture straight out of the hex comments —
sprites on the Spectrum are just bytes, one bit per pixel.
The infamous screen address
The Spectrum's bitmap is not laid out linearly — the rows are
interleaved in thirds (a hardware shortcut that haunted every programmer of
the era). For cell-aligned work the classic formula is:
; HL = 0x4000 + ((y & 0x18) << 8) + ((y & 7) << 5) + x
scraddr:
ld a,(ypos)
ld c,a
and 0x18
or 0x40
ld h,a
ld a,c
and 7
rrca
rrca
rrca ; (y & 7) << 5, via rotate
ld c,a
ld a,(xpos)
or c
ld l,a
ret
Within a cell, moving down one pixel line is just inc h —
which is why the sprite is drawn as two 8-line cell halves.
Reading QAOP for yourself
No BASIC, no ROM: the keyboard is hardware you can read directly. Each
half-row of keys lives on port 0xFE, selected by the high byte
of the address, one bit per key, active low:
ld a,0xDF ; half-row P O I U Y
in a,(0xFE)
rra ; bit 0 (P) -> carry
jr c,notp ; carry set = not pressed
; ... move right ...
Flicker-free movement
The main loop waits for the 50Hz frame interrupt with a single
halt, then erases the sprite at its old position and redraws at
the new one — all while the TV beam is still near the top of the frame.
A small counter moves the character only every fourth frame, which turns
“teleporting” into “walking”. And when you press
SPACE, one call to the ROM's CLS routine hands you back a tidy BASIC prompt,
like nothing ever happened.
Mid-wander. This screenshot was produced by actually executing
the program's bytes in an instrumented Z80 interpreter.
Try it, then break it
minion.tap
— ready to run: open it in
Fuse
or any .tap-capable emulator, and it auto-loads.
minion.asm
— the full commented source, 200-odd lines. Build it yourself with
the free Pasmo
assembler: pasmo --tapbas minion.asm minion.tap
Then make it yours: redraw the sprite bytes (any character fits in 2×2
cells), change the colours, add a second sprite, make Kempston joystick
input work (port 31 — see our
interface build), or add pixel-level
movement with pre-shifted sprites. That last one is exactly one rabbit hole
away from writing an actual game — which is how everyone got started
in 1983.
The chip inside your Spectrum also ran Pac-Man, half the arcades of the 1980s, the Sega Genesis's sound, and — through a direct descendant — is still inside graphing calculators being sold today. A plain-English guide to the Z80's 48-year career.
A second, independently-built take on the same premise: a bargain hunter, a security guard called Big Dave, and a legendary discount tin sealed away in Aisle 13. Same isometric-engine idea as the original, a different story, and its own fresh set of bugs a screenshot caught that the test suite alone never would have.
I set Claude Code loose on a ZX Spectrum game with $100 of credits and the new Fable model, expecting a doddle. Here's why 48K of 1982 hardware humbled it in ways a modern REST API never could.