A Nintendo Game Boy (DMG) emulator written in Zig.
nibble is actively in-progress but already runs many ROMs and test ROMs.
Implemented core pieces:
- CPU instruction decode/execute loop with interrupt handling
- Memory bus with cartridge support and MBC banking (
ROM,MBC1,MBC2,MBC3,MBC5) - Timer (
DIV/TIMA/TMA/TAC) - PPU timing + background/window/sprite rendering
- SDL2 window output (with automatic headless fallback if SDL init fails)
- Joypad input mapping + joypad interrupt signaling
- Around-screen control deck UI:
- Left side joypad visualization (D-pad, A/B, Start/Select)
- Right side management panel with status, slot info, and action buttons
- Emulator management hotkeys (pause, reset, save/load state, slot selection)
- In-memory save states (10 slots per run session)
- Headless mode and serial output capture for test ROM workflows
Known gaps:
- No audio/APU emulation
- OAM corruption behavior is only partially accurate (
blargg/oam_bugstill has failing subtests) STOPinstruction behavior is stubbed- MBC3 RTC latch/register behavior is not implemented
- Zig
0.15.x(project minimum inbuild.zig.zonis0.15.0-dev.383+927f233ff) SDL2development librariespkg-config(used by Zig build to find SDL2)
zig buildThis produces the executable at zig-out/bin/nibble.
# graphical mode (SDL window)
zig build run -- roms/Dr.\ Mario\ \(World\).gb
# headless mode (useful for test ROMs / CI)
zig build run -- --headless roms/blargg/cpu_instrs/cpu_instrs.gb
# limit execution to N instructions
zig build run -- --headless -s 100000 roms/blargg/cpu_instrs/cpu_instrs.gb
# debug trace mode
zig build run -- -d -s 1000 roms/blargg/cpu_instrs/cpu_instrs.gbCLI options:
-h,--help: show help-d,--debug: verbose step-by-step debug output-s,--steps <COUNT>: stop after a maximum number of steps-b,--breakpoint <ADDR>: stop whenPC == ADDR--headless: run without graphics
Controls (default):
- D-pad: Arrow keys
- A:
XorA - B:
ZorS - Start:
Enter, keypadEnter, orSpace - Select:
BackspaceorTab - Mouse: click the on-screen joypad/buttons in the side panels
Management hotkeys (SDL mode):
P: pause/resume emulationR: reset emulatorF5: save state to active slotF9: load state from active slot[ / ]: previous/next save slotF1: toggle side panel visibilityEsc: quit- Mouse: click
PAUSE,RESET,SAVE,LOAD, and slot buttons in the right panel
Save state notes:
- Save states are currently in-memory only (session-local, not persisted to disk).
- 10 slots are available (
0-9), managed with[ / ].
zig build testTest and reference ROMs are available under roms/ (for example roms/blargg/ and roms/scribbltests/).
src/main.zig: CLI entrypointsrc/emulator.zig: emulator orchestration loopsrc/cpu/: CPU core + instruction decode/executesrc/memory/: memory bus, IO registers, and MBC logicsrc/ppu/: PPU timing and renderingsrc/timer.zig: timer/divider logicsrc/sdl.zig: minimal SDL2 bindingsroms/: local ROMs used for development/testing
This project is for educational and development purposes. Use only ROMs you are legally allowed to run.