Skip to content

jpf/goboy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

185 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GoBoy

Build Status codecov Go Report Card GoDoc

GoBoy is a multi-platform Nintendo GameBoy and GameBoy Color emulator written in go. The emulator can run the majority of GB games and some CGB games. There is also colour and sound support. This emulator was primarily built as a development exercise and is still work in progress. Please feel free to contribute if you're interested in GameBoy emulator development.

The program includes debugging functions making it useful for understanding the emulator operation for building one yourself. These functions include printing of opcodes and register values to the console at each step (although will greatly slow down the emulation) and toggling of individual sound channels.

Installation

Download the latest release of GoBoy from the releases page.

Building from source

With go installed, you can install GoBoy into your go bin by running:

go get github.com/Humpheh/goboy/cmd/goboy

If you have Go 1.11 you can also do:

git clone https://github.com/Humpheh/goboy.git
cd goboy
go build -o goboy cmd/goboy/main.go

GoBoy is compatible with MacOS, Windows and Linux. Building on Windows 10 requires MinGW and on Linux, you'll need to install gtk.

GoBoy uses the go library pixel for control binding and graphics rendering, which requires OpenGL. You may need to install some requirements which can be found on the pixels readme.

Usage

goboy zelda.gb

Controls: Z X Enter Backspace

The colour palette can be cycled with = (in DMG mode), and the game can be made fullscreen with F.

Other options:

  -dmg
    	set to force dmg mode
  -mute
    	mute sound output

Debug or experimental options:

  -9p-port int
    	enable 9P server on port (0 = disabled)
  -cpuprofile string
    	write cpu profile to file (debugging)
  -disableVsync
    	set to disable vsync (debugging)
  -stepthrough
    	step through opcodes (debugging)
  -unlocked
    	if to unlock the cpu speed (debugging)

9P Filesystem Interface

GoBoy includes a 9P2000.L server that exposes the emulator's internal state as a virtual filesystem. This enables advanced features like:

  • Save states - Save and restore complete emulator state using standard Unix tools
  • Live debugging - Inspect and modify CPU registers, memory, and graphics state in real-time
  • TAS (Tool-Assisted Speedrun) support - Frame-perfect state reproduction
  • ROM hacking - Direct access to memory and graphics data

Quick Start

Start the emulator with 9P enabled:

./goboy --9p-port 5640 pokemon.gb

On Linux, mount the filesystem:

mkdir -p /tmp/goboy
sudo mount -t 9p -o trans=tcp,port=5640,version=9p2000.L localhost /tmp/goboy

On macOS/other systems, use the included test client:

# List files
./test-9p-client localhost:5640 ls /

# Read CPU state
./test-9p-client localhost:5640 cat /state/cpu

# Pause emulation
./test-9p-client localhost:5640 write /ctl "pause"

Save States

Create a complete save state:

# Pause emulator
echo "pause" > /tmp/goboy/ctl

# Save all state
tar -czf save-state.tar.gz -C /tmp/goboy state/

# Resume
echo "resume" > /tmp/goboy/ctl

Restore a save state:

echo "pause" > /tmp/goboy/ctl
tar -xzf save-state.tar.gz -C /tmp/goboy
echo "resume" > /tmp/goboy/ctl

Frame Stepping

Execute the game frame-by-frame for debugging or TAS creation:

# Pause the game
echo "pause" > /tmp/goboy/ctl

# Advance exactly 1 frame
echo "step" > /tmp/goboy/ctl

# Advance N frames (e.g., 10 frames)
echo "step 10" > /tmp/goboy/ctl

The step command executes frames while paused. This is essential for:

  • Tool-Assisted Speedruns (TAS) - Frame-perfect input timing
  • Debugging - Step through execution to find bugs
  • Testing - Verify game behavior at specific frames

Button Input

Control game buttons remotely via the /state/buttons file. Reading shows currently pressed buttons, writing sends button commands.

Reading button state:

# Show currently pressed buttons (empty if none pressed)
cat /state/buttons

# Example output: "a start" (when A and Start are pressed)

Button command formats:

# Momentary press (press + auto-release next frame)
echo "a" > /state/buttons
echo "start" > /state/buttons

# Explicit press (button stays pressed until released)
echo "press left" > /state/buttons

# Explicit release
echo "release left" > /state/buttons

Available buttons: a, b, start, select, up, down, left, right

TAS example - Create frame-perfect input sequence:

echo "pause" > /tmp/goboy/ctl

# Frame 1: Press A
echo "a" > /state/buttons
echo "step" > /tmp/goboy/ctl

# Frame 2-5: Hold right
echo "press right" > /state/buttons
echo "step 4" > /tmp/goboy/ctl
echo "release right" > /state/buttons

# Frame 6: Jump
echo "a" > /state/buttons
echo "step" > /tmp/goboy/ctl

echo "resume" > /tmp/goboy/ctl

Graphics Visualization

The /meta/vram.png file provides a bidirectional PNG interface to VRAM tile data, enabling visual inspection and editing of graphics using standard image tools.

Reading VRAM as PNG:

# Export current VRAM contents as PNG
cat /tmp/goboy/meta/vram.png > vram-dump.png

# View with any image viewer
open vram-dump.png  # macOS
xdg-open vram-dump.png  # Linux

The PNG format:

  • Dimensions: 128×512 pixels (16 tiles wide × 64 tiles tall)
  • Color palette: DMG grayscale (white, light gray, dark gray, black)
  • Layout: 8×8 pixel tiles in a grid (1:1 pixel mapping, no scaling)

Writing PNG to VRAM:

# Edit graphics in any image editor (GIMP, Photoshop, etc.)
# Must use exact DMG colors and dimensions

# Write modified PNG back to VRAM
cat modified-tiles.png > /tmp/goboy/meta/vram.png

Validation: Writes are strictly validated - invalid dimensions or colors are rejected with an error message.

Example - Extract and modify Mario sprite:

echo "pause" > /tmp/goboy/ctl

# Export current VRAM
cat /tmp/goboy/meta/vram.png > mario-tiles.png

# Edit mario-tiles.png in image editor
# (Change colors, modify sprites, etc.)

# Import modified tiles
cat mario-tiles.png > /tmp/goboy/meta/vram.png

echo "resume" > /tmp/goboy/ctl

Note: Writes are processed asynchronously. Pause emulation for immediate effect.

Filesystem Structure

/
├── README          # Interface documentation
├── ctl             # Control commands (pause/resume/step)
├── meta/
│   └── vram.png    # VRAM visualization (read/write PNG)
└── state/
    ├── cpu         # CPU registers and timers
    ├── buttons     # Button input (read/write)
    ├── memory/
    │   ├── vram        # Video RAM (16KB)
    │   ├── wram        # Work RAM (36KB)
    │   ├── oam         # Sprite data (256B)
    │   ├── highram     # I/O registers (256B)
    │   └── state       # Memory banking state
    ├── cartridge/
    │   ├── info        # ROM header (read-only)
    │   ├── ram         # Save data
    │   └── state       # MBC banking state
    ├── apu/
    │   └── state       # Audio state (77B)
    └── ppu/
        ├── state       # PPU internal state
        ├── screen      # Frame buffer (69KB RGB)
        ├── bgpalette   # Background palette
        ├── spritepalette # Sprite palette
        ├── bgpriority  # Priority map
        └── tilescanline # Scanline data

For complete documentation, see the built-in README:

cat /tmp/goboy/README

Debugging

There are a few keyboard shortcuts useful for debugging:

Q - force toggle background
W - force toggle sprites
A - print gb background palette data (cgb)
S - print sprite palette data (cgb)
D - print background map to log
E - toggle opcode printing to console (will slow down execution)
7,8,9,0 - toggle sound channels 1 through 4.

Saving

If the loaded rom supports a battery a <rom-name>.sav (e.g. zelda.gb.sav) file will be created next to the loaded rom containing a dump of the RAM from the cartridge. A loop in the program will update this save file every second while the game is running.

Testing

GoBoy currently passes all of the tests in Blargg's cpu_instrs and instr_timing test roms.

These roms are included in the source code along with a test to check the output is as expected (instructions_test.go and timing_test.go). These tests are also run on each commit.

Contributing

Please feel free to open pull requests to this project or play around if you're interested! There are still plenty of small bugs that can easily be found through playing games on the emulator, or take a task from the TODO list below!

Known Bugs and TODO list

  • Sprites near edge of screen not drawing
  • Top half of sprite disappearing off top of screen
  • Small sprites row glitch
  • BG tile window offset issue - visible on Pokemon Red splash screen - possibly mistimed interrupt?
  • Harry Potter and The Chamber of Secrets has odd sprite issues
  • Request to set screen to white does not do so
  • MBC3 banking support
  • Improve APU (see Pokemon Yellow opening screen for reason why)
  • Resizable window
  • White screen when off
  • STOP opcode behaviour
  • Sprite Z-drawing bugs
  • Minor APU timing issues
  • Better APU buffering
  • Stop jittering
  • MBC3 clock support
  • Speed up CPU and PPU
  • Platform native UI?
  • More DMG colour palettes
  • Support save-states (via 9P filesystem)
  • Support boot roms
  • Blargg's test ROMs

Resources

A large variety of resources were used to understand and test the GameBoy hardware. Some of these include:

About

Multi-platform Nintendo Game Boy Color emulator written in Go

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Go 99.5%
  • Shell 0.5%