Game Fighter posts:
- Dumping the boot ROM
Inside every Gameboy there’s a small boot ROM, which scrolls the Nintendo logo down from the top of the screen, and plays the iconic po-ling sound. This 256 byte boot ROM also checks that said Nintendo logo is present in the ROM chip of the cartridge, and validates the checksum of the header. Up until the 1992 legal case Sega v. Accolade it was believed that this check gave Nintendo the legal authority to control which games were allowed to run on the console, as the “Nintendo” logo was copyrighted by Nintendo, but the the ruling gave a strong precedent that using this small piece of copyrighted data to achieve interoperability was allowable.
The boot ROM locks itself out from being read before leaving control of the CPU to the program running on the cartridge, maybe more due to necessity than preventing read-out of the ROM, since the bottom memory area near the CPU entry point also covers the interrupt vectors, which the game needs access to. But as a result, this boot ROM remained an elusive secret, which was assumed would never see the light of day.
It was not until 2003 that Neviksti extracted this ROM from a DMG, decapping the CPU chip, looking at the CPU die with a scanning electron microscope and painstakingly reading out the bits visually, all 2048 (8*256) of them.
In 2009, costis extracted the SGB boot ROM by externally overclocking the CPU right at the time when the boot ROM shuts itself out, which causes the write to the lock-out register to be ignored, and then it could be copied to the outside world. The GBC boot ROM was also dumped this way by costis soon after.
Just this year (2014) BennVenn made the process child’s play with a silly but effective method. All you need to perform the attack is a piece of wire! You solder one end of the wire to one of the crystal oscillation circuit, and scrape the other end of the wire against any grounded surface in the Gameboy, such as copper shielding plate. This causes the CPU to glitch to jump to a random location. If you’re lucky, this allows you take control of the code execution and, again, dump the boot ROM.
But, what about pirate Gameboy clones? For example this Game Fighter, which is a horizontal Gameboy clone. Also see my detailed teardown and analysis of this beauty. It also has a boot ROM, though slightly different in function. The Game Fighter, instead of scrolling the logo down the screen, starts the game immediately. I also knew from before that it checked that the logo was correct, but not the game’s ROM header checksum.
So I wrote a small program, did the glitching procedure and voila! I had the boot ROM. You can download it here:
If you really wanted, you could use this ROM with BGB and for example single step through it in BGB’s debugger. To do this, go into BGB’s settings, go to the system tab, then check the bootroms enabled option, and point the DMG boot ROM field to the ROM file.
Since the Game Fighter boots immediately, unlike an original ‘boy, I made the ROM have an invalid logo in its header so it would lock up and give me time to try to glitch the execution. The procedure was the same as on an original Gameboy: Find the one the pins of the crystal driver that is the input, solder a wire to it, (pictured above) and brush the other side to a part of the board that is ground. For the Game Fighter, I found that I had better luck getting it to work if I first shorted it to ground (for example the negative battery terminal) on power on, then brushing it against the surface as I let it go.
I will post the program I used for dumping the boot ROM later, along with a more detailed description of how it works.
Here’s the boot ROM disassembled, which holds an interesting secret! (Disassembly of the original DMG boot ROM for comparison.)
ld sp,$FFFE ; 0000 Set up the stack pointer. ; Clear VRAM. xor a ; 0003 ld hl,$9FFF ; 0004 Addr_0007: ldd [hl],a ; 0007 bit 7,h ; 0008 jr nz,Addr_0007 ; 000A ; Set up sound. ld hl,$FF26 ; 000C ld c,$11 ; 000F ld a,$80 ; 0011 ldd [hl],a ; 0013 [$FF26] = $80 Turn on sound ld [$ff00+c],a ; 0014 [$FF11] = $80 Channel 1 wave duty inc c ; 0015 ld a,$F3 ; 0016 ld [$ff00+c],a ; 0018 [$FF12] = $F3 Channel 1 envelope ldd [hl],a ; 0019 [$FF25] = $F3 Channel routing inc c ; 001A ld a,$C1 ; 001B ld [$ff00+c],a ; 001D [$FF13] = $C1 Channel 1 low frequency byte ld a,$77 ; 001E ld [hl],a ; 0020 [$FF24] = $77 Master volume ; Set up graphics. ld a,$FC ; 0021 ldh [$FF47],a ; 0023 [$FF47] = $FC BG palette ld a,$91 ; 0025 ldh [$FF40],a ; 0027 [$FF40] = $91 Turn on LCD ; Compare the second half of the logo in the header against ; the second half of the Nintendo logo stored in the boot ROM. ld de,Addr_0043 ; 0029 call Addr_0073 ; 002C cp a,$34 ; 002F Will return $34 if successful. jr nz,Addr_0036 ; 0031 If not, jump to a second compare operation. jp Addr_00FC ; 0033 ; Compare the second half of the logo in the header against ; the second half of the mystery logo stored in the boot ROM. Addr_0036: ld de,Addr_005B ; 0036 call Addr_0073 ; 0039 cp a,$34 ; 003C Will return $34 if successful. Addr_003E: jr nz,Addr_003E ; 003E If not, get stuck in an endless loop. jp Addr_00FC ; 0040 ; Second half of the Nintendo logo, $18 bytes Addr_0043: db $DC, $CC, $6E, $E6, $DD, $DD, $D9, $99 db $BB, $BB, $67, $63, $6E, $0E, $EC, $CC db $DD, $DC, $99, $9F, $BB, $B9, $33, $3E ; Second half of mysterious RIS or KIS logo, $18 bytes Addr_005B: db $00, $00, $00, $00, $76, $66, $C6, $31 db $00, $19, $66, $FF, $01, $88, $38, $C7 db $C6, $C8, $00, $00, $00, $00, $00, $00 ; Subroutine: Compare the cartridge header’s logo against ; a given memory location Addr_0073: ld hl,$011C ; 0073 Start comparing halfway into the logo Addr_0076: ld a,[de] ; 0076 inc de ; 0077 cp [hl] ; 0078 jr nz,Addr_0082 ; 0079 inc hl ; 007B ld a,l ; 007C cp a,$34 ; 007D $xx34 = The first byte after the header logo jr nz,Addr_0076 ; 007F ret ; 0081 Addr_0082: ld a,$85 ; 0082 Compare failed! ret ; 0084 ; $77 filler bytes Addr_0085: db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff db $ff, $ff, $ff, $ff, $ff, $ff, $ff ; Disable the boot ROM and hand over control to the game cartridge. Addr_00FC: ld a,$01 ; 00FC Write to the ROM disable register ldh [$FF50],a ; 00FE
It’s mostly like a stripped down version of the original Nintendo bootstrap. It turns on the sound circuit even though it does not play any sound. Perhaps this is for compatibility with some game that expects it to be turned on on start-up. The boot ROM also clears the video RAM, sets the background palette and finally turns on the LCD circuit.
The boot ROM interestingly enough only stores a reference copy of the second half of the Nintendo logo, even though there’s plenty of unused space. So the first half of the logo could be incorrect and the program would still start. Incidentally, Gameboy Color has a similar bug where only the first half of the logo is checked, which has prompted some pirate publishers to get creative and make logo combinations like HotKid, Niutoude and Yiutoudz using the bottom half of the logo that they can control freely. Read more on Neofuji. It wouldn’t matter in this case anyway, as the logo isn’t shown on the screen, only checked.
But what’s weirder is what the boot ROM does if the Nintendo logo check fails. It then does a second check, against an alternative logo that perhaps says KIS or RIS, simulated to the right for illustrative purposes. Again, the boot ROM only stores half the logo in this case as well, so there’s no way of getting the full logo without finding a matching game that contains the full logo in it header.
It may be checking specifically for a certain game by the same publisher. But why would the game have an alternative logo, when this logo is not shown on the Game Fighter, and would hang a genuine Gameboy? The only logical conclusion I can come to is that the game that this check was made for does a logo swap. Some examples of logo swaps (apart form the half logo hacks) can be found in the Neofuji post linked above. A logo swap works by switching in memory containing your own logo when the boot ROM copies the logo the into VRAM, and then switching back to the real logo when the check is done. This would normally fail on the Game Fighter, since it checks the logo much earlier than a real Gameboy.
But in the end, we may never know. If you have any clue which pirate publisher KIS/RIS/??? is please let me know!
Thanks to BennVenn for coming up with this method of accessing the boot ROM!