← Back to selected work

Emulation / Systems / C++20 DMG emulator

Matchaboy

A small machine, made inspectable.

Run a Game Boy in software and inspect the hardware state behind every frame.

My contribution
Built the C++20 emulator core, timing and graphics systems, native inspector, and replay test harnesses.
Result
The frozen campaign matched all 24 Mealybug reference images and retained traces from 131 ROM checks.

FROM THE PROJECT

The newer Game Boy Advance interface

Newer Matchaboy Game Boy Advance interface with a game title screen, keyboard controls, library, and inspector navigation.
Newer Matchaboy interface: Game Boy Advance playback with keyboard controls. Screenshot supplied by Vetri; game artwork belongs to its respective owners. Source ↗
131
ROM checks in the frozen campaign
24/24
Mealybug reference images matched
1,000
frames in the recorded UDP fault run

THE CHALLENGE

Keeping a whole machine in sync

Emulation is a coordination problem: CPU instructions, memory access, timers, video, and sound must advance together. Matchaboy explores those interactions directly, then makes the internal machine state visible and testable.

ENGINEERING

Timing the bus, pixels, and replay

The core is C++20 and uses the standard library rather than an emulator framework. The CPU decodes primary and CB instructions through a real memory bus that advances the PPU, timer, DMA, serial, and audio hardware. Cartridge support includes ROM-only, MBC1, MBC3/RTC, and MBC5 banking.

The renderer emits pixels through eight-slot background and object FIFOs. Per-dot fetches, window and object stalls, priority rules, and register-write timing are part of the implementation. The harness records original test-ROM verdicts, framebuffers, instruction traces, cycle counts, and hashes.

The wider Matcha platform adds deterministic snapshots, a preallocated 60-frame history, real UDP serial-link rollback/replay, and batched emulator instances through a C ABI and Python/Gymnasium wrapper. Silicon Autopsy displays memory activity, disassembly, FIFO state, and the four APU channels.

Test through the actual hardware path

Unit programs and external ROMs use the same CPU/bus/peripheral instances. Completion of a fixed-frame run is not automatically counted as a test pass.

Retain reproducible evidence

Frozen campaigns preserve source and ROM hashes, binaries, traces, and reference frames. The dashboard readback is checked against the headless view.

Report correctness and speed separately

The documented M3 campaign passes its correctness checks but misses the 50,000 aggregate-FPS and low-latency rollback targets. The implementation keeps those failures visible.

ARCHITECTURE

One clock across the virtual hardware

Matchaboy architectureThe cartridge and CPU interact through the shared memory bus. Each hardware tick advances video, timing/DMA/serial, and audio. Snapshots preserve the full machine for restore and replay.Cartridge / MBCROM + banked RAMSM83 CPUInstructions + interruptsShared memory busOrdered accesses + T-cyclesPPU / pixel FIFOsFramebufferTimer / DMA / serialPeripheral stateFour-channel APUPCM audioDeterministic snapshotsRestore / UDP rollback / Gym

The cartridge and CPU interact through the shared memory bus. Each hardware tick advances video, timing/DMA/serial, and audio. Snapshots preserve the full machine for restore and replay.

RESULTS AND LIMITS

Pixel comparisons, not only “it runs”

The frozen platform report records 131 ROM checks, exact dmg-acid2 and all 24 Mealybug images, and 9,408,187 assertions in optimized and sanitizer runs. A 1,000-frame UDP fault campaign matches clean state, video, and PCM output. Its measured aggregate throughput is about 4,408 simulated frames/s on the documented Apple M3 workload—not gameplay FPS or a universal hardware claim.

Current boundaries

The historical platform campaign misses its performance targets. The netplay runner is not an interactive competitive-game frontend, and finite ROM coverage does not establish accuracy for every hardware edge case. No commercial games are bundled.

EXPLORE THE SOURCE

Inspect ROM checks and retained frame evidence

Repository review: 14 September 2026. Recorded test results retain their original scope; they were not rerun for this site.

← All selected workNEXT PROJECTSiteMorph ↗