Game Boy family emulation in Rust, written from scratch. GBA first.
  • Rust 97.7%
  • Python 2.3%
Find a file
0xrsydn 652ea397f2 feat(cartridge): add 512-byte and 8 KiB serial EEPROM saves
Select them with --save-type eeprom512 or eeprom8k. The part follows GBATEK's
protocol on Game Pak data bit 0: DMA3 sends one bit per halfword, '11' +
address + '0' requests a 64-bit block that reads back after four dummy bits,
and '10' + address + data + '0' writes one. A write reports busy for a nominal
108,368 cycles before the block is stored. 8 KiB parts decode the low 10
address bits. ROMs above 16 MiB map EEPROM only at 0x0dffff00..0x0dffffff.

Bits shift out only inside machine steps, so failed steps roll back. CPU
stores, byte/word accesses, CPU reads during a read-out, and malformed or
overlapping requests are diagnostics. Blocks are stored first-bit-as-MSB,
matching common .sav layouts, and work with save files and save states.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
2026-10-14 14:28:41 +07:00
.pi feat(tooling): add bounded Jev game-debugging workflow 2026-10-07 01:19:19 +07:00
crates feat(cartridge): add 512-byte and 8 KiB serial EEPROM saves 2026-10-14 14:28:41 +07:00
docs feat(cartridge): add 512-byte and 8 KiB serial EEPROM saves 2026-10-14 14:28:41 +07:00
tools feat(tooling): add bounded Jev game-debugging workflow 2026-10-07 01:19:19 +07:00
.envrc chore(dev): bootstrap Rust and Nix environments for Darwin 2026-10-05 12:58:37 +07:00
.gitignore feat(desktop): add safe explicit Flash save-file persistence 2026-10-07 08:36:12 +07:00
AGENTS.md feat(core): add whole-machine save states with F5/F9 window slots 2026-10-14 14:28:41 +07:00
Cargo.lock feat(desktop): add opt-in Darwin audio output 2026-10-07 07:35:19 +07:00
Cargo.toml refactor: split into gameboy-rust workspace with core, demos, and desktop crates 2026-10-05 16:09:46 +07:00
CLAUDE.md docs: split README into docs/ and add AGENTS.md 2026-10-05 16:20:18 +07:00
flake.lock chore(dev): bootstrap Rust and Nix environments for Darwin 2026-10-05 12:58:37 +07:00
flake.nix feat(testing): pin public ARM fixture and document compatibility baseline 2026-10-05 20:01:08 +07:00
README.md feat(core): add whole-machine save states with F5/F9 window slots 2026-10-14 14:28:41 +07:00

gameboy-rust

Game Boy family emulation in Rust, written from scratch. The Game Boy Advance (GBA) is the first and currently only system.

This cannot run Pokémon Emerald or other commercial games yet. It is an emulator foundation: an ARM7TDMI interpreter, memory bus, timers, DMA, Mode 0–5 video, and an original BIOS replacement. The included demos run original ARM test programs through the emulated hardware. Raw ROM files can run in terminal sessions or a window with keyboard input. Audio and saves are not implemented. A pinned Pong homebrew passes scripted menu, ball-motion, and paddle-input checks.

Layout

Crate Purpose
crates/gba-core Platform-independent GBA emulator. No external Rust dependencies.
crates/gba-demos Original test programs that drive the core.
crates/desktop Native window frontend on minifb. Builds the gameboy-rust executable.

Quick start

macOS on Apple Silicon is the verified platform. Install Nix (with flakes) and direnv, then:

direnv allow .
direnv exec . cargo run --locked --release -- --tile-demo
direnv exec . cargo test --locked

Arrows scroll, Q rotates, W zooms, Z flips, X changes priority, Enter resets, and Escape exits. Run direnv exec . cargo run --locked -- --help to list all modes. For original ROM files, use --rom path/to/original.gba --window, or --steps 100000 instead of --window for terminal diagnostics. See cartridge loading for limits and report meanings. Use --test-suite suite.json for repeatable headless ROM assertions.

Documentation

Document Contents
docs/status.md What works today, deliberate limits, and next steps
docs/usability-roadmap.md General GBA usability criteria and feature priorities
docs/demos.md Every demo, its command, and its controls
docs/development.md Nix, direnv, and macOS build notes
docs/testing.md Validation commands and what the test suites cover
docs/rom-tests.md Headless ROM suites, completion checks, assertions, and JSON reports
docs/jev-debugging.md Optional /jev-gb-debug workflow, evidence review, and local evaluation records
docs/public-arm-tests.md Pinned public ARM test, preparation command, results, and limits
docs/public-thumb-tests.md Pinned public Thumb test, result protocol, and compatibility baseline
docs/public-memory-tests.md Pinned public memory test, results, and video-byte coverage limits
docs/public-bios-tests.md Pinned BIOS read-protection result and firmware limits
docs/public-pong.md Playable homebrew setup, scripted gameplay baseline, and limits
docs/architecture.md Crate boundaries and a file-by-file map
docs/hardware/cpu.md ARM/Thumb execution rules, modes, exceptions, and timing
docs/hardware/cartridge.md ROM loading, window/input controls, original ROM generator, and diagnostics
docs/hardware/save-states.md Whole-machine save states, F5/F9 hotkeys, format, and limits
docs/hardware/bios.md The original BIOS replacement and each supported service
docs/hardware/timers-irq.md Timers, interrupt registers, HALT/STOP, and power control
docs/hardware/dma.md DMA channels, triggers, and timing
docs/hardware/audio.md Sound devices, stereo capture, optional Darwin output, and limits
docs/hardware/serial.md Disconnected serial initialization and transfer limits
docs/hardware/display-timing.md Display clock, status, IRQs, and scanline capture
docs/hardware/video.md Backgrounds, sprites, mosaic, windows, color effects, and input
docs/references.md External hardware references and emulator sources consulted

Coding agents should start with AGENTS.md.

All demo content and the BIOS replacement are original. No Nintendo code or assets are included. Only use game ROMs that you may lawfully use. Do not commit game ROMs, BIOS files, or game assets.