Mooneye Test Suite

October 22, 2022 · View on GitHub

Mooneye Test Suite is a suite of Game Boy test ROMs.

Build Status

Prebuilt binary test ROMs are available here. They are automatically built and deployed whenever there's new changes in the main branch.

For documentation about known behaviour, see Game Boy: Complete Technical Reference

Suite structure

  • acceptance: the main "acceptance" tests which form the bulk of the test suite and are easily verifiable on hardware
  • emulator-only: tests that are complicated to verify on hardware (e.g. require special test hardware), so they are commonly executed only on emulators
  • madness: nope
  • manual-only: tests that require manual verification (e.g. looking at the screen, or listening to audio) on real hardware
  • misc: extra tests for CGB / AGB hardware that are not part of the main suite
  • utils: utilities that are not really tests, but might be useful to some people

Test naming

Some tests are expected to pass only a single console model:

  • dmg = Game Boy
  • mgb = Game Boy Pocket
  • sgb = Super Game Boy
  • sgb2 = Super Game Boy 2
  • cgb = Game Boy Color
  • agb = Game Boy Advance
  • ags = Game Boy Advance SP

In addition to model differences, SoC revisions can affect the behaviour. Revision 0 refers always to the initial version of a SoC (e.g. CPU CGB). AGB and AGS use the same SoC models, but in two different packages. The following SoC models have several revisions:

  • DMG: 0, A, B, C
  • CGB: 0, A, B, C, D, E
  • AGB: 0, A, A E, B, B E. Revision E also exists, but only in Game Boy Micro (OXY) so it is out of this project's scope. However, A E and B E are most likely actually just E revision in A or B-compatible package.

In general, hardware can be divided to a couple of groups based on their behaviour. Some tests are expected to pass on a single or multiple groups:

  • G = dmg+mgb
  • S = sgb+sgb2
  • C = cgb+agb+ags
  • A = agb+ags

For example, a test with GS in the name is expected to pass on dmg+mgb + sgb+sgb2.

Pass/fail reporting

Most tests report a single pass/fail state using a simple protocol which is designed to make it easy to detect the test result in both emulators and real hardware. On real hardware you can use the link port to read data sent by the test ROM. In emulators you can either use the link port, or detect the use of the LD B, B opcode, which is used as a "debug breakpoint" in some emulators.

A passing test:

  • writes the Fibonacci numbers 3/5/8/13/21/34 to the registers B/C/D/E/H/L
  • executes an LD B, B opcode
  • sends the same Fibonacci numbers using the link port. In emulators, the serial interrupt doesn't need to be implemented since the mechanism uses busy looping to wait for the transfer to complete instead of relying on the interrupt
  • executes an LD B, B opcode, followed by an infinite JR loop (JR pointing to itself)

A failing test:

  • writes the byte 0x42 to the registers B/C/D/E/H/L
  • executes an LD B, B opcode
  • sends the byte 0x42 6 times using the serial port
  • executes an LD B, B opcode, followed by an infinite JR loop (JR pointing to itself)

If you don't have a full Game boy system, pass/fail reporting can be sped up by making sure LY (0xff44) and SC (0xff02) both return 0xff when read. This will bypass some unnecessary drawing code and waiting for serial transfer to finish.

Hardware testing

There's tons of documentation and tons of emulators in the internet, but in the end I only trust real hardware. I follow a fairly "scientific" process when developing emulation for a feature:

  1. Think of different ways how it might behave on real hardware
  2. Make a hypothesis based on the most probable behaviour
  3. Write a test ROM for such behaviour
  4. Run the test ROM on real hardware. If the test ROM made an invalid hypothesis, go back to 1.
  5. Success!

All test ROMs are manually run with these devices:

DeviceModelMainboardSoCDetailed information
Game BoyDMG-01DMG-CPU-01DMG-CPUG01176542
Game BoyDMG-01DMG-CPU-02DMG-CPU AG02487032
Game BoyDMG-01DMG-CPU-04DMG-CPU BG10888299
Game BoyDMG-01 DMG-CPU-06DMG-CPU CGM6058180
Super Game BoySHVC-027SGB-R-10SGB-CPU-01SGB Unit #2 [gekkio]
Game Boy PocketMGB-001MGB-CPU-01CPU MGB  M10280516
Super Game Boy 2SHVC-042SHVC-SGB2-01CPU SGB2SGB2 Unit #1 [gekkio]
Game Boy ColorCGB-001CGB-CPU-01CPU CGBC10203977
Game Boy ColorCGB-001CGB-CPU-01CPU CGB AC10400331
Game Boy ColorCGB-001CGB-CPU-02CPU CGB BC11778414
Game Boy ColorCGB-001CGB-CPU-03CPU CGB CCGB Unit #1 [gekkio]
Game Boy ColorCGB-001CGB-CPU-05CPU CGB DCH20983903
Game Boy ColorCGB-001CGB-CPU-06CPU CGB ECH24224683
Game Boy AdvanceAGB-001AGB-CPU-01CPU AGBAH10045235
Game Boy AdvanceAGB-001AGB-CPU-10CPU AGB AAH12465671
Game Boy PlayerDOL-017DOL-GBS-20CPU AGB A EGBS Unit #3 [gekkio]
Game Boy Advance SPAGS-001 C/AGS-CPU-01CPU AGB BXJH10027945
Game Boy Advance SPAGS-001 C/AGS-CPU-21CPU AGB B EXEH17807928

Additional devices

I also have access to more devices with different mainboard revisions, but I think the CPU revision is all that matters if we study the deterministic behaviour and not analog characteristics (e.g. audio filtering), or behaviour that is known to be non-deterministic. Even if audio sounded different between two units with the same CPU revision but different mainboard revisions, I'd expect the difference to be caused by individual device variation or different revisions of support chips (e.g. RAM/AMP/REG).

The main "test fleet" is already very big, so I only test on these devices if there's evidence of behaviour that depends on mainboard revision or individual units.

DeviceModelMainboardSoCDetailed information
Game BoyDMG-01DMG-CPU-01DMG-CPUG01036814
Game BoyDMG-01DMG-CPU-03DMG-CPU BG06551776
Game BoyDMG-01DMG-CPU-05DMG-CPU BG13289095
Game BoyDMG-01DMG-CPU-06DMG-CPU B
Game BoyDMG-01DMG-CPU-07DMG-CPU B (blob)G38953646
Game BoyDMG-01DMG-CPU-08DMG-CPU C (blob)
Super Game BoySNSP-027SGB-R-10SGB-CPU-01SGB Unit #7 [gekkio]
Game Boy PocketMGB-001MGB-ECPU-01CPU MGB  MH12573718
Game Boy PocketMGB-001MGB-LCPU-01CPU MGB  M12827347
Game Boy PocketMGB-001MGB-LCPU-02CPU MGB  MH20284468
Game Boy LightMGB-101MGL-CPU-01CPU MGBL10610653
Game Boy ColorCGB-001CGB-CPU-04CPU CGB DC19220030
Game Boy AdvanceAGB-001AGB-CPU-02CPU AGBAJ12569062
Game Boy AdvanceAGB-001AGB-CPU-03CPU AGB AAJ14804298
Game Boy AdvanceAGB-001AGB-CPU-04CPU AGB AAJ15529163
Game Boy PlayerDOL-017DOL-GBS-10CPU AGB AGBS Unit #1 [gekkio]
Game Boy Advance SPAGS-001 C/AGS-CPU-10CPU AGB BXEH12776954
Game Boy Advance SPAGS-001 C/AGS-CPU-11CPU AGB BXJF10485171
Game Boy Advance SPAGS-001 C/AGS-CPU-30CPU AGB B EXEH20137204
Game Boy Advance SPAGS-101 C/AGT-CPU-01CPU AGB B EXU72764025-1

I'm still looking for the following mainboards, but these are probably not required for reverse engineering:

  • SGB-R-01
  • SGB-N-01
  • SGB-N-10
  • C/AGS-CPU-20
  • DOL-GBS-01

For now, the focus is on DMG/MGB/SGB/SGB2, so not all tests pass on CGB/AGB/AGS or emulators emulating those devices.

License and copyright

Mooneye Test Suite is licensed under MIT. Copyright (C) 2014-2022 Joonas Javanainen joonas.javanainen@gmail.com