Skip to content

GameBoy Netplay Emulator (Rust) A deterministic GameBoy (DMG-01) emulator with M-cycle precision and lockstep netplay support, built in Rust.

License

Notifications You must be signed in to change notification settings

guicybercode/rust_gb_emulator

Repository files navigation

GameBoy Netplay Emulator (Rust)

A deterministic GameBoy (DMG-01) emulator with M-cycle precision and lockstep netplay support, built in Rust.

Features

  • Deterministic Emulation: Precise M-cycle timing (70224 cycles per frame at 60 Hz)
  • Complete CPU: All 512 opcodes (256 base + 256 CB-prefixed) of the Sharp LR35902
  • PPU with Mode Tracking: Accurate timing with temporal memory access restrictions
  • Lockstep Netplay: Frame-perfect synchronization via FF01/FF02 serial protocol
  • Dual Network Transport: TCP (reliable) and UDP (low-latency with custom reliability)
  • Desync Detection: Automatic checksum validation with freeze-on-desync
  • TUI Interface: Beautiful terminal UI with Ratatui for monitoring and control

Architecture

Core Modules

  • gameboy_core: Synchronous 60Hz emulation loop

    • cpu.rs: Sharp LR35902 CPU with all opcodes
    • mmu.rs: Memory orchestration with PPU mode-based access control
    • ppu.rs: Picture Processing Unit with mode state machine
    • timer.rs: Timer subsystem (DIV, TIMA, TMA, TAC)
    • checksum.rs: Deterministic state hashing for netplay
  • gameboy_netplay: Async networking and lockstep

    • bridge.rs: Event types and channel definitions
    • emulator_task.rs: Async wrapper with try_recv() anti-gravity pattern
    • lockstep.rs: Frame synchronization and input buffering
    • transport/: TCP and UDP implementations
  • gameboy_tui: Terminal User Interface

    • app.rs: Application state management
    • ui.rs: Three-panel layout (control, display, status)
    • main.rs: Event loop and integration

Building

# Build all crates
cargo build --release

# Run the TUI
cargo run --release --bin gameboy_tui

# Run tests
cargo test

Loading ROMs

Place your GameBoy .gb ROM files in the roms/ directory:

gameboy_rust/
└── roms/
    ├── tetris.gb
    ├── dr_mario.gb
    └── your_game.gb

The emulator will automatically load the first ROM it finds. See LOADING_ROMS.md for detailed instructions.

Note: Currently only MBC0 cartridges (≤32KB) are supported.

Usage

Controls

Menu Mode:

  • Tab: Cycle through input fields (IP, Port, Buffer)
  • T: Toggle transport (TCP/UDP)
  • H: Host a game
  • J: Join a game
  • Q: Quit

Emulator Mode:

  • Esc: Return to menu
  • Arrow keys, Z, X, A, S: Joypad inputs

Configuration

  • IP Address: Remote host IP (for joining)
  • Port: Network port (default: 8888)
  • Buffer (B): Frame buffer size for jitter absorption (default: 3)
  • Transport: TCP (reliable) or UDP (low-latency)

Network Protocol

The lockstep protocol uses the GameBoy serial port (FF01/FF02):

  1. Each frame, if FF02 is written with 0x81, a serial transfer is triggered
  2. The emulator sends: {frame_number, serial_data (FF01), checksum}
  3. Remote input is buffered until B frames are available
  4. Checksums are validated each frame; mismatch triggers desync alert

Testing

# Run unit tests
cargo test --all

# Run specific test
cargo test test_deterministic_execution

# Run with output
cargo test -- --nocapture

Integration with Blargg Test ROMs

Place test ROMs in tests/blargg/ directory:

  • cpu_instrs.gb
  • mem_timing.gb
  • instr_timing.gb

Implementation Notes

M-Cycle Precision

Every operation returns exact M-cycle count. The frame loop accumulates exactly 70224 M-cycles per frame (4.194304 MHz / 59.73 Hz).

Memory Access Restrictions

  • VRAM (0x8000-0x9FFF): Blocked during PPU Mode 3 (Drawing)
  • OAM (0xFE00-0xFE9F): Blocked during PPU Modes 2 (OAM Search) and 3

Anti-Gravity Pattern

The emulator task uses try_recv() to consume input events without blocking, preserving timing precision:

while let Ok(event) = input_rx.try_recv() {
    // Process input
}
// Continue with frame execution

Performance

  • Target: 60 FPS (16.67ms per frame)
  • CPU Usage: ~5-10% on modern hardware (single-threaded)
  • Network: < 1ms latency on LAN, 10-50ms typical WAN

Known Limitations

  • MBC0 only (no cartridge mappers)
  • No audio (APU not implemented)
  • No boot ROM (starts at 0x0100)
  • Simplified sprite rendering
  • No link cable features beyond netplay

License

MIT

Credits

Based on GameBoy hardware specifications from:

  • Pan Docs (pandocs.gbdev.io)
  • The Cycle-Accurate Game Boy Docs
  • Blargg's test ROMs

About

GameBoy Netplay Emulator (Rust) A deterministic GameBoy (DMG-01) emulator with M-cycle precision and lockstep netplay support, built in Rust.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages