Skip to content

Run the test suites ​

gameboy proves its accuracy with published test ROMs. One script runs them all without a window. You can also run single ROMs with gb_run_rom, script button presses and capture screenshots and sound.

Run everything ​

  1. Build the project. See Install.

  2. Download the test ROMs, once:

    bash
    ./tests/roms/fetch_roms.sh

    This fetches blargg's suites and dmg-acid2.gb into tests/roms, pinned to the revisions the expected results were recorded with.

  3. Run the suite:

    bash
    ./tests/run_tests.sh

    If your build folder is not build, pass it: ./tests/run_tests.sh my-build.

Each test prints a PASS or FAIL line. A full passing run ends with:

text
18/18 passed

The script exits with status 0 when everything passes and non-zero otherwise.

What the suite checks ​

TestsCountHow the result is read
cpu_instrs individual sub-tests11The ROM reports Passed
cpu_instrs full ROM (uses MBC1)1The ROM reports Passed
instr_timing1The ROM reports Passed
mem_timing, mem_timing-22The ROM reports Passed
halt_bug1Final screen matches a recorded hash
dmg-acid21Final screen matches a recorded hash
frontend1The real gameboy window program runs 120 frames with SDL's dummy video and audio drivers

When a test fails ​

  • FAIL <name> (exit 1) means the ROM reported a failure. exit 2 means it gave no verdict in time. The last lines of the ROM's output follow.
  • FAIL <name> (framebuffer hash …) means the picture changed. The screenshot is saved under tests/out/ so you can look at it.
  • test ROMs missing means you have not run tests/roms/fetch_roms.sh.

Run one ROM by hand ​

bash
./build/gb_run_rom tests/roms/gb-test-roms/cpu_instrs/cpu_instrs.gb
./build/gb_run_rom tests/roms/gb-test-roms/instr_timing/instr_timing.gb
./build/gb_run_rom tests/roms/gb-test-roms/mem_timing/mem_timing.gb
./build/gb_run_rom tests/roms/gb-test-roms/mem_timing-2/mem_timing.gb

To run all eleven CPU sub-tests:

bash
for rom in tests/roms/gb-test-roms/cpu_instrs/individual/*.gb; do ./build/gb_run_rom "$rom"; done

The runner prints the text the ROM sends over its serial port, and reads results that newer blargg ROMs write to memory. It stops as soon as it sees a verdict.

Exit codeMeaning
0The ROM reported Passed
1The ROM reported Failed, or the runner hit an error
2No verdict before the cycle budget ran out, or a bad command line

Take a screenshot ​

ROMs that show their result on screen, and games, have no verdict. Run them for a set number of frames and save the picture:

bash
./build/gb_run_rom tests/roms/dmg-acid2.gb --frames 120 --screenshot acid2.bmp

With --frames, the runner exits 0 when the frames are done.

Script button presses ​

--press BUTTON:FRAME presses a button at a frame and releases it 8 frames later. Button names are right, left, up, down, a, b, select and start. Repeat the option for more presses.

bash
./build/gb_run_rom game.gb --press start:120 --press a:200 --frames 400 --screenshot after.bmp

This is how the homebrew games were checked without anyone at the keyboard.

Record the sound ​

--wav PATH writes everything the sound chip produced to a 48 kHz stereo WAV file:

bash
./build/gb_run_rom game.gb --frames 600 --wav game.wav

Update the recorded hashes ​

After an intended change to the graphics code:

bash
./tests/run_tests.sh --update

This rewrites tests/expected/*.sha256. Look at the screenshots in tests/out/ before you keep the new hashes.

Next steps ​