FOUR FLOORS DOWN, NO WAY UP
A DOOM-flavoured first-person shooter for a 1983 Atari 800XL · 6502 assembly · 28 KB · built in one night · runs on the real thing
This is the real game — byte-for-byte the same 28,723-byte executable that runs on the hardware, here running in an Atari 800XL emulator compiled to WebAssembly. PAL, with sound: an audio engine that for most of this game's life was verified only as POKEY register traces, never actually heard.
Four hand-authored floors, each casting its own monsters: husks that fall to one point-blank blast, fragile gunners that fire twice as often, spitters that never stop, and hulks that soak exactly two shells and tower a third taller — every one placed, and typed, by the level files. A shotgun with range-banded damage, a muzzle flash that lights the room rather than replacing it, and a real exit on every floor, proven reachable by a test that walks there.






An Atari 800XL has a 1.77 MHz 6502 and 64 KB of RAM. A full-screen repaint costs more than a frame. Every part of this is a small measured decision:
Columns are painted by JSR-ing into unrolled store chains at a computed
offset. The entry point is the run length: no loop counter, no compare per pixel,
no overdraw. Five cycles a pixel is the floor for a 6502, and this sits on it.
The world redraws at ~11 fps, but input, the weapon, the kick, the bob, audio and the HUD all run in the vertical-blank interrupt at 50 Hz and never wait. Pull the trigger and the gun fires on the next video frame. The parts you feel are never on the slow path.
GTIA mode 9 ORs each pixel into the background colour's low nibble — which every reference says to keep at zero. Writing a single bit there instead lifts the whole picture: a full-screen muzzle flash, four register writes, in a mode with no business having one.
Every screenshot on this page is generated by a tool that asserts each frame against the game state it claims to show. The acceptance sweep path-finds to every exit, plays the whole game through, and soaks it for 60,000 frames. The DEVLOG records every wrong turn.
Built overnight, 31 July 2026, by Claude and Tony Gillett — an experiment in how close an 8-bit machine can get to the feel of DOOM, with an emulator harness measuring every step. Then it met real hardware.
Three modules lived at $A000–$BFFF: the BASIC ROM's address space on a real XL. The emulator boots with BASIC off; the hardware boots with it on. 130 green test runs never stood a chance of seeing it. Fixed with an eight-byte stub that banks the ROM out before anything loads.
The display list asked ANTIC for 248 scanlines against a hard limit of 240 — playfield DMA running where the vertical sync should be. The emulator renders a fixed window and simply clipped it; a CRT rolls. Two of the four status rows were blank anyway. Now 232.
1 August 2026: the fixed build boots, locks and plays on the real 800XL, off an SD card, on a CRT. Both fixes are now assertions in the test sweep, and the question they left behind is the project's best souvenir: not does it pass? but what can this harness not see, even in principle?