I remember
my first attempts at programming outside my pocket calculator, 8 years
ago… I read a lot of things of GameBoy homebrew development, and decided
to code a small clone of Pokemon, for the GameBoy. Even without any
knowledge of C, or assembly, or hardware programming, or toolchains, it
was fun : I actually managed to get a moving character, basic
collisions, and a dynamically-loaded Pokemon-style map using the
original tiles.
The GameBoy was fully reverse-engineered some times ago, leading to the development of several emulators — but one thing no one ever managed to get is the boot ROM of these devices. Oh, it’s no big deal : unlike the GameBoy Advance BIOS (which contain a lot of hard-to-emulate compression and decompression routines), the boot ROM of a GameBoy is very small, and doesn’t do much. It initialize some hardware registers, displays the GameBoy logo, plays the sound, and check the CRC of the cartridge. Additionally, the GameBoy Color sets up a color palette, based on the combination of buttons pressed on startup, with a hardcoded-list of specific palettes for a few games (like Super Mario, Zelda, Metroid, etc.) Not very usefull, but still nice to have, for the sake of computer history :)
Now why is getting this ROM so hard ? We could hack a small bit of code that reads the ROM, load it into our favorite homebrew-loader cartridge, and voilà. Well, the issue is that after it initialized the hardware, the boot ROM locks itself, just before giving the control to the cartridge code. That means you can’t read the boot ROM memory location anymore. The only thing someone managed to do was to dump the original black & white GameBoy ROM, using a powerfull microscope to read the bits one-by-one on the chip — that’s how easy this locking protection is to bypass.
And
now this guy finally managed to dump the GameBoy Color
ROM — one week after getting the GameBoy
Color one. You can read all the
details on his page, and it is really
interesting — but if you only want a less-technical summary, here are
some explanations.
Basically, he breaked out the GameBoy Color case, and took control of the cartridge connector, the CPU clock cristal and the CPU voltage. That means he could inject any code he wants, and control the CPU speed and power — even stop the CPU completely. Now the idea was to avoid the execution of the locking-bit, the instruction at the end of the boot ROM code that locks access to this part of the memory. And the best way is to confuse the CPU, so it would somehow skip this locking instruction.
So he overclocked heavily the CPU, hoping that it would disfunction, and skip the locking instruction. But unlike the original GameBoy, the GameBoy Color CPU is very well-engineered, and the CPU wouldn’t misbehave.
Then he tried to completely halt the CPU for a few seconds, plus cut the power for good measure. And then, when waking up the CPU, a lot of strange glitches would happen, as some of the internal state had been lost. At some point, the boot ROM could even jump to a completely random location in the memory : maybe in the video buffer, maybe in the RAM… or maybe in the cartridge code.
So he filled his cartridge code with a lot of “NOP” (do-nothing instructions), followed by a “JMP dump”, that would go straight to his dumping routine. Then he started the boot ROM, and began to confuse the CPU. At some point, the boot ROM code jumped to a random location on the cartridge code, and arrived in the middle of NOP codes — it went down all the NOPs, reached the JMP, and started executing the dumping routine. Without having completed the boot ROM code, that is without the locking-bit enabled. And here we go : we can read the boot ROM memory location, and dump the 256 bits code.
If you’re interested, you can get a commentated dissassembly of the dumped ROM — beware, work in progress. And don’t forget to read about the FPGABoy project — you wouldn’t miss a complete GameBoy implementation in VHDL, would you ?