DocBoy

June 9, 2026 ยท View on GitHub

Tests Build

DocBoy

DocBoy is an open source, accuracy-focused, GameBoy emulator, written in C++17.

It supports emulation of both the original DMG (GameBoy) or CGB (GameBoy Color).

Can be used either with the standalone SDL frontend or as a libretro core (e.g. with RetroArch).


Features

GameBoy features

Core

  • CPU: M-cycle accurate
  • PPU: T-cycle accurate (implements Pixel FIFO)
  • APU (audio)
  • Cartridges: NoMBC, MBC1, MBC2, MBC3, MBC5, MBC7, HUC1, HUC3
  • Real Time Clock (RTC) emulation
  • Memory buses (EXT, CPU, OAM, VRAM) and MMU (for accurately handle read/write conflicts)
  • Timers
  • Interrupts
  • DMA
  • JoyPad
  • STOP instruction
  • Serial Transfer (bitwise, as happens with the Serial Link)
  • Accelerometer (MBC7)

CGB Only

  • HDMA
  • Speed Switch and Double Speed Mode
  • VRAM/WRAM bank switch
  • DMG compatibility mode (with proper palette selection)
  • PPU: CGB only features (CGB palettes, BG attributes, VRAM banks, ...)

Frontend features

  • CLI debugger (in GDB style): supports disassemble, breakpoints, watchpoints, step by step execution, rewind, memory viewer, interrupts viewer, IO viewer
  • Serial Link (output to console)
  • Save/Load
  • Save/Load state
  • Fast-forward
  • Configurable palette
  • Screenshots
  • Graphical menu (SDL)

Installation

You can find the latest executables for both Windows and Linux in the Releases Page.

Alternatively, you can build the project by yourself as explained below.

Clone

Clone the repository and its submodules.

git clone https://github.com/Docheinstein/docboy.git --recurse-submodules

Build

DocBoy can be compiled as a static library which can be used by a frontend.

These are the CMake options for the available frontends.

  • BUILD_SDL_FRONTEND (default)
  • BUILD_LIBRETRO_CORE
  • BUILD_LIBRETRO_CORE_ANDROID
  • BUILD_NOGUI_FRONTEND

SDL

mkdir build
cd build
cmake ..
make -j 8

Additional dependencies:

  • An audio framework: for Linux you can install alsa-lib

Libretro Core

mkdir build
cd build
cmake .. -DBUILD_LIBRETRO_CORE=ON
make -j 8

Android

  1. Install NDK.
  2. Enable the CMake option BUILD_LIBRETRO_CORE_ANDROID.
  3. Set the CMake option NDK_PATH to your NDK path (the folder should contain the ndk-path executable).

That is:

mkdir build
cd build
cmake .. -DBUILD_LIBRETRO_CORE_ANDROID=ON -DNDK_PATH=/opt/AndroidSdk/ndk/25.2.9519653/build
make

Note: use just make instead of make -j; the latter does not work with NDK build.

CMake options

These are all the supported CMake options.

CMake optionDescriptionDefault Value
BUILD_TESTSBuild testsOFF
BUILD_DEVTOOLSBuild devtoolsOFF
BUILD_NOGUI_FRONTENDBuild NoGUI frontendOFF
BUILD_SDL_FRONTENDBuild SDL frontendON
BUILD_LIBRETRO_COREBuild libretro coreOFF
BUILD_LIBRETRO_CORE_ANDROIDBuild libretro core for AndroidOFF
NDK_PATHNDK path for Android build
ENABLE_DEBUGGEREnable debuggerOFF
ENABLE_BOOTROMEnable boot romOFF
ENABLE_AUDIOEnable audioON
ENABLE_CGBEnable GameBoy ColorON
ENABLE_TWO_PLAYERS_MODEEnable two players mode (serial link)ON
ENABLE_ASSERTSEnable assertsOFF
ENABLE_STATE_DEBUG_SYMBOLSAdd source code symbols to state filesOFF
ENABLE_DIRECT_LCD_RENDERINGEnable rendering directly to LCD framebufferOFF

Usage

SDL

usage: [rom] [--config CONFIG] [--serial] [--scaling SCALING] [--cartridge-info]
       [--debugger] [--help]

positional arguments:
  rom                    ROM

options:
  -c, --config CONFIG    Read configuration file
  -s, --serial           Display serial console
  -z, --scaling SCALING  Scaling factor
  -i, --cartridge-info   Dump cartridge info and quit
  -d, --debugger         Attach debugger
  -h, --help             Display this help message and quit

Controls

These are the default controls.

All the joypad keys can be remapped through the Control Options menu.

ButtonAction
F1Save State
F2Load State
F11Dump framebuffer
F12Screenshot
FShow / Hide FPS
QDecrease speed
WIncrease speed
DAttach / Detach debugger
EnterSTART
TabSELECT
ZA
XB
UpUP
RightRIGHT
DownDOWN
LeftLEFT

Retroarch (libretro)

With RetroArch (supported by almost every existing platform, including Android and iOS), you can Load Core the libretro core compiled with the BUILD_LIBRETRO_CORE or BUILD_LIBRETRO_CORE_ANDROID.

If you're on a desktop environment, you can also load the core from command line:

retroarch -L build/docboy_libretro.so <rom>


Tests

The road to perfect emulation is impossible still far away, nevertheless DocBoy aims to be a fairly accurate emulator, eventually at the cost of sacrificing a bit of performance.

Practically all the features are covered by the tests under the tests/roms folder, most of which come either from docboy-test-suite or other public test suites.

DocBoy is part of the GBEmulatorShootout comparison as well, which contains the tests results of the most popular emulators.

To run the tests locally, build with the CMake option BUILD_TESTS enabled:

mkdir build
cd build
cmake .. --DBUILD_TESTS=ON
make -j 8

Then run the docboy-tests executable (run with --help or see Catch2 for allowed options).

Debugging

DocBoy offers a CLI debugger (in GDB style) that's really useful to see what's going on under the hood.

To build with the debugger support, enable the CMake ENABLE_DEBUGGER option.

mkdir build
cd build
cmake .. -DENABLE_DEBUGGER=ON
make -j 8

Use the -d option to run with the debugger already attached from the beginning, or press the key D to attach/detach the debugger at any time.

Commands

With help you can list the commands:

h
b <addr>                                      : Set breakpoint at <addr>
w[/r|a] <start>,<end> [<cond>]                : Set watchpoint from <start> to <end>
w[/r|a] <addr> [<cond>]                       : Set watchpoint at <addr>
del <num>                                     : Delete breakpoint or watchpoint <num>
ad <past> <next>                              : Automatically disassemble past <past> and next <next> instructions
ad <num>                                      : Automatically disassemble next <num> instructions (default = 10)
x[x][/<length><format>] [<bank>:]<addr>       : Display memory at <addr> (x: raw) (<format>: x, h[<cols>], b, d, i)
/b <bytes>                                    : Search for <bytes>
/i <bytes>                                    : Search for instructions matching <bytes>
display[x][/<length><format>] [<bank>:]<addr> : Automatically display memory at <addr> (x: raw) (<format>: x, h[<cols>], b, d, i)
undisplay                                     : Undisplay expressions set with display
key <press|release> <key>                     : Send 'press' or 'release' event for <key> (<key>: a, b, start, select, up, down, left, right)
t [<count>]                                   : Continue running for <count> clock ticks (default = 1)
. [<count>]                                   : Continue running for <count> PPU dots (default = 1)
s [<count>]                                   : Continue running for <count> instructions (default = 1)
si [<count>]                                  : Continue running for <count> micro-operations (default = 1)
n [<count>]                                   : Continue running for <count> instructions at the same stack level (default = 1)
ni [<count>]                                  : Continue running for <count> micro-operations at the same stack level (default = 1)
f [<count>]                                   : Continue running for <count> frames (default = 1)
fb [<count>]                                  : Step back by <count> frames (default = 1, max = 600)
l [<count>]                                   : Continue running for <count> lines (default = 1)
c [<address>]                                 : Continue (optionally stop at <address>)
trace [<flag1>] [<flagN>]                     : Set the trace modes (output on stderr)
d                                             : Dump the disassemble (output on stderr)
symbols                                       : Show the symbols (if .sym is available)
r                                             : Reset the emulator to its initial state
save [<path>]                                 : Save state to <path>
load [<path>]                                 : Load state from <path>
h                                             : Display help
q                                             : Quit

Here's the debugger!

Debugger


Screenshots

CGB

Pokemon Silver CGB Pokemon Silver FightCGB Zelda Link's Awekening CGB Mario Tennis CGB Wario Land 3 CGB

DMG

Tetris Alleyway Bubble Bobble Donkey Kong Preistorik Man Launcher Screen Launcher Screen


Contributing

Contributions are welcome!

If you encounter a bug, a failing test ROM, or would like to propose a new feature, please open an issue and/or submit a PR.