1977 · emulation · webassembly
The first fantasy console, with the lid off.
chipdeck runs CHIP-8 — the 1977 virtual machine that started it all — in your browser, with a live debugger beside the screen: registers, disassembly, and instruction traces updating as the game runs. Pause it. Step it. Watch a 65-byte snake game think. Written entirely in Go.
REGISTERS V0 02 V1 15 V2 00 V3 00 I 203 V4 00 V5 00 V6 0D V7 02 PC 223 V8 FF V9 FF VA 1D VB 40 SP 1 DISASSEMBLY 221 8F17 SUBN VF, V1 > 223 4F00 SNE VF, 00 225 1217 JP 217 227 7002 ADD V0, 02 n step · space resume · all quirks ✓
what you get
An emulator that shows its work.
Seven bundled games
Cave Explorer, Outlaw, Br8kout, Flight Runner, Glitch Ghost, Danm8ku, and a 65-byte Snek — all CC0 from the chip8Archive, credited in the app.
Live debugger
Registers, stack, a disassembly window tracking PC, and an instruction trace — pause with space, single-step with N, and watch the machine think.
Verified accuracy
Original COSMAC VIP behavior — all six quirks pass the Timendus test suite in CHIP-8 mode, enforced in CI as golden framebuffer hashes.
100% Go → WASM
A pure-Go interpreter core with zero dependencies, under an Ebitengine front end. One codebase runs native and in the browser.
Bring your own ROMs
Drop any .ch8 file onto the page (or browse on mobile). Dropped ROMs run with authentic 1977 pacing; bundled games use their Octo tickrates.
Touch keypad
The COSMAC hex keypad on screen — tap on mobile, click on desktop, or use the classic 1234/QWER/ASDF/ZXCV mapping.
under the hood
1977 semantics, tested like it's 2026.
The core reproduces the original COSMAC VIP interpreter: vF resets on logic ops, I increments on register load/store, draws wait for vertical blank, sprites clip at the edges, shifts read vY, and Fx0A waits for key release — every quirk toggleable, and every one verified against the Timendus test suite as golden framebuffer hashes in CI, with a negative test proving the goldens can actually fail.
# the whole machine, testable headlessly m := chip8.New(chip8.DefaultQuirks()) m.LoadROM(rom) for !done { m.TickTimers() // 60Hz m.RunCycles(11) // ~700 ips }
# keys 1234/QWER/ASDF/ZXCV hex keypad space pause n step b reset g debugger p phosphor +/- speed