Skip to content
chipdeck

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.

chipdeck — Br8kout ⏸
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