A while back I began work on my FPGABoy project (a completely clone of the original GameBoy
as a system-on-a-chip implementation on FPGA.) I have mostly completed the project since then
(most GB original games run almost flawlessly on FPGABoy) with just a few minor things left to
be done, including bug fixes and completing the sound core. Anyway, this page is not about
FPGABoy; it is about hacking actual GameBoy's and dumping their boot ROMs!
There was great news in the GB scene a short while ago, when Neviksti from CherryRom forums
announced that he had been able to extract the BIOS image from the original GameBoy by decapping
the chip, staining the ROM, and using a really powerful microscope to individually resolve and read
out each bit one by one.
There are many other variants of the GameBoy however, namely the GameBoy Pocket, the Super GameBoy,
and the GameBoy Color, all whose boot ROM images have not been dumped. My goal is to dump these
remaining boot ROMs electrically (no chip decapping or microscopes.) I just successfully dumped the
Super GameBoy's boot ROM tonight which you can download at the botom of this page.
The Super GameBoy (similar to the handheld versions of the system) has two external buses. A bus for
the video RAM (VRAM) and a bus where the external work RAM as well as the cartridge are connected.
I soldered up wires from all of the address, data, and control lines of the WRAM/ROM bus to my FPGA
board and wrote up some quicky code to dump the values of all of these signals on both the rising and
falling edge of every clock cycle. I also cut the trace on the PCB of the clock line going to the
SGB CPU and soldered a wire directly to the pin of the CPU from my FPGA so that I could directly control
the clock.
After taking a several dumps, I noticed several things:
1. Almost all areas in the memory map that the SGB accesses appear on these external address lines (!),
except for VRAM (different bus) and accesses to the 0x0000 to 0x0100 region (since it is mapped to the
internal boot ROM.) This means that I not only see accesses to the external WRAM/ROM, but also to the
FFxx registers and internal RAM regions!
2. The data lines always have FF on them when accessing a region which is not external WRAM or external
ROM. That's a bit unfortunate.
3. The last thing that goes on the address lines before my usercode at address 0x0100 executes is an
access to location 0xFF50. This is known from the dump of the original GameBoy bootrom to be the
register which locks out the bootrom forever (until the GB is power cycled or reset) once something is
written to it.
OK, so now I just counted clock cycles until I saw that write to the 0xFF50 register and I wrote up some
quick (and rather dirty) VHDL which sends slow (around 2MHz) clock cycles until we reach that spot. Then,
it sends a burst of fast clock cycles (24MHz) which are meant to overclock the system beyond the point
where it can execute the register write instruction properly, but slow enough for the PC to increment.
This essentially causes this instruction to not be executed! Thus, the boot ROM falls through to my
usercode at 0x0100 without running the disable instruction where I have this little block of code:
ld hl, 0
ld de, $4000
ld b, 0
copy_loop:
ld a, [hl]
ld [de], a
inc hl
inc de
dec b
jr nz, copy_loop
end_loop: jr end_loop
This writes the 256 bytes from 0x0000 to 0x0100 (boot ROM region) to a bogus spot in ROM region where
my FPGA will trace the writes and forward them on to PC. To my surprise, all this worked beautifully
without too much tinkering!