I have always been into retro devices and hardware projects, and the Game Boy is almost ideal for this: the architecture is relatively simple, and the cartridge interface is well documented.
In this article, I will show how I approached reverse-engineering the GB-MAX cartridge and how I implemented minimal read access through an Arduino Due without extra chips like 74HC595/74HC165.
How the project started
I bought a Game Boy on eBay and a universal GB-MAX cartridge plus microSD card on AliExpress. After experimenting with it, I became curious about the low-level design: how the OS is loaded, how bank selection works, and how to dump data directly.
After opening the cartridge, I found that the GB-MAX board uses:
- CPLD
Altera MAX II EPM240T100C5N - SRAM
LY62L2568 - Flash
M29W640FB
The logic is powered at 3.3V (converted from 5V), and there are resistor-based level drops on address/control/data lines. This is an important detail for safe interfacing.
Why dump onboard Flash if there is microSD?
Even though the cartridge loads the main OS from microSD, it also contains onboard Flash with an older factory firmware version.
The obvious way to read it would be desoldering the chip and using a programmer. But I wanted to do it through the standard Game Boy cartridge interface, as if I were the console reading memory.
Game Boy cartridge interface (short overview)
According to Pan Docs, the cartridge connector exposes a classic parallel bus:1
A0..A15- address (16-bit)D0..D7- data (8-bit)/CS- chip select/RD- read/WR- write/RES- resetVDD- +5VGND- ground
Useful minimum address map:
0x0000..0x3FFF- fixed ROM bank0x4000..0x7FFF- switchable ROM bank (via MBC)0xA000..0xBFFF- external RAM (if present)
Basic read cycle:
- Set
D0..D7as input. - Put the target address on
A0..A15. - Pull
/CSand/RDlow. - Read one byte from the data bus.
- Release
/RDand/CShigh.
Why Arduino Due fits this project
I specifically wanted to avoid intermediate shift registers, so I went with direct wiring to a dev board. From what I had available, Arduino Due was the best option:
- 54 digital pins, enough for address/data/control lines.
- 84 MHz clock, plenty of timing headroom for a slow external bus.
- 3.3V logic, which matches the 3.3V logic section inside GB-MAX.
Important: Due GPIO pins are not 5V-tolerant. Do not feed more than 3.3V into inputs.2 In my case, I am working with GB-MAX where the logic already runs at 3.3V and input levels are lowered internally.
Basic wiring
Wiring concept (I will add a real build photo in the post):
- Cartridge
VDD-> Arduino Due5V GND->GNDA0..A15-> any 16 GPIO pinsD0..D7-> any 8 GPIO pins (bidirectional)/CS,/RD,/WR,/RES-> dedicated GPIO pins
Practical tips that help:
- Keep bus wires short.
- Use a solid common ground topology.
- During reads, always keep
D0..D7asINPUTto avoid bus contention.
Minimal firmware example (byte reads)
| |
This is already enough to verify that the bus works and bytes can be read reliably.
Next
In part 2, I will cover:
- how to select banks through MBC,
- how to read onboard Flash in a more systematic way,
- and how to build a full dumper.
Pan Docs, External Connectors / Cartridge Slot: https://gbdev.io/pandocs/External_Connectors.html ↩︎
Arduino Due docs/store warning (I/O max 3.3V): https://store.arduino.cc/products/arduino-due ↩︎