So a while back during one of my ROM Hacking sessions (I believe it was either my Skitty Titlescreen hack or my Gold Intro remake) I had the slight idea that it would be cool to do a ROM dumper. At the time it was just a thought but after seeing a Game Boy ROM dumper based on the Arduino a few days later I decided to try and give it a shot.
So naturally I started by looking on the interwebs and seeing if someone else had, by chance, done the project before, because why on earth would I reinvent the wheel when I can just use someone else’s code? Alas, the results turned up quite a few Game Boy ROM dumpers, but nothing for the Game Boy Advance which is the actual cartridge I wanted to dump.
Despite my lazy effort of looking for a TV dinner style ROM Dumper, I pressed forward and looked up a pinout for the GBA cartridges. At last I had arrived at this document which contained a detailed pinout for both RAM and ROM reading/writing modes. However, I still wasn’t entirely sure as to how I could interface with these pins. As such I continued looking and I found reiner ziegler’s rather colorful page detailing how the GBA cartridge interface works. In particular, I found this quote to be the most useful in getting an idea of how to dump:
Cart accesses can be either sequential or non-sequential. The first access to a random cart ROM location must be non-sequential. This type of access is done by putting the lower 16 bits of the ROM address on cart lines AD0-AD15 and setting /CS low to latch address lines A0-A15. Then /RD is strobed low to read 16 bits of data from that ROM location. (Data is valid on the rising edge of /RD.) The following sequential ROM location(s) can be read by again strobing /RD low. Sequential ROM access does not require doing another /CS high-to-low transitions because there are count up registers in the cart ROM chip that keep track of the next ROM location to read.
So with the pinout and the reading instructions, I was able to deduce the following process to read 2-byte values from the ROM:
So it seems to be easy enough considering that all we have to do is pulse a few pins, but since RAM reading doesn’t have the same internal address counter we will eventually be needing the address select pins, although in a slightly different manner since RAM reading and writing is closer to the reading and writing of Game Boy cartridges.
So with my plan set I designed a PCB breakout board based on the one at insidergadgets here. I originally planned on desoldering a header from a broken GBA SP but as it turns out desoldering 32 pins isn’t very easy with an $8 RadioShack soldering iron. So instead I ordered a replacement GBA cartridge header for the DS Lite at DealExtreme for $2.50 which isn’t too bad and saves you from wrecking your GBA. You can find it here and I will also be linking a full parts list at the conclusion of this post.
So eventually the final PCB design I got was this:
I could have made it a bit smaller but since it was my first time using Eagle (or even ordering a PCB) I wanted to have all the pins labeled to make debugging easier (and it did in fact make things easier). The final price came out to about $20 on OSHPark and the received boards were spectacular. The timing was also remarkably quick with about a week for fabrication and a week for shipping. Unfortunately I cannot say the same with DealExtreme, but it’s a Chinese retailer so there’s always the risk of slow or missing packages.
After almost an entire month of waiting my DealExtreme order came in, and thankfully everything was there. With all my parts gathered and soldered onto the boards I began coding my dumper.
The first thing I did was set up all the wires to the cartridge so as to allow for quick performance through port registers as opposed to insidergadget’s rather crude method which involved a lot of for loops which can drag out a lot more time on GBA ROMs due to their size. I initially attempted to use resistors to drop the voltage to 5v but as it turns out it made the incoming signal less stable and I ended up ditching the resistors and just directly connecting with the cartridge, which worked remarkably well since it turns out that GBA cartridges are 5v tolerant. That aside, my system ended up making the writing of the values onto the pins as easy as one line per 8 pins:
PORTL = value;
So using this and a bit of bitshifting it was easy to lay down 24 bit addresses and recieve the resulting 16 bit values. However, things didn’t quite go as I wanted initially, but after a bit of work and tweaking I managed to get it to dump the first two bytes by latching the address 0 and reading the bytes:
Serial.println(“Dumping GBA ROM…”);
String hex = String(PINL + (PINC « 8), HEX);
So the next step was to remove the latchAddress and get it to display some header information to make sure that we’re dumping all the bytes properly. After a bit of research on converting byte values to characters and then Strings, I managed to get it to display this:
Yes, the date is off, I forgot to take screenshots while making this thing.
At last it seemed that I had a successful ROM dumper. However, since I had only been testing one cartridge the entire time, I had a really big problem: Only Spyro 3 would dump.
So after much frustration tweaking timing values and rewriting lines and lines of code, I got frustrated to the point where I gathered every single GBA cartridge I owned and I tested each and every one and I came up with the following results:
So as I began dumping these cartridges I began to notice a pattern that all my Pokemon games (and for some reason Treasure Planet) wouldn’t dump while all my crappy games did. Still frustrated, I looked inside the cartridges one by one and I realized yet another pattern: All the crap cartridges had only a tiny EEPROM chip or no chip at all, and all the good games had a full SRAM chip (except Treasure Planet which remarkable had no save at all). The one things that really boggled me was Treasure Planet, so I began researching on the ROM chip ids and it was exactly the same as the other cartridges. It also boggled me how Spyro 3 didn’t have an SRAM chip like Fire Red’s since I knew that it had save support. Then it hit me: CS2. I checked every single of the passing cartridges and all of their CS2 pins were detached. As I looked at the Pokemon boards I realized that their CS2 pin was attached, and then I quickly realized that I must have forgot to set it to high. Alas, my stupid mistake that had caused me hours of pain was simply fixed by a wire from VCC to CS2, and I quickly added a wire for CS2 since I made another mistake of not including a wire for it in the first place.
So the moral of the story is that if something isn’t working, check your wires and make sure you have one for every single pin, even if it’s never used at all (well, except CLK and IRQ since those are virtually useless on every board I’ve found).
So obviously I’m probably not going to just stop with just grabbing bytes from the ROM since that’s pretty pointless and defeats the purpose of having a ROM dumper in the first place. The next step is to get the ROM onto a form of storage, either SD or MicroSD. However, since I didn’t think this far ahead and I foolishly thought that reading the bytes off the serial was a good idea, which was not fun at all and ended up being a waste of time since it kept loosing bytes along the way, not to mention it being very very slow. However, since I am still in need of a project to occupy myself with, I’m going to get started on reading and writing the SRAM and I’ll make a post on that once I get it completed and done. I also need to figure out how to check the GBA header checksum to make sure we’re dumping the ROM correctly (or if any cartridge is inserted at all).
Another obvious note is the support for Game Boy ROM dumping to allow for the dumping of both types of game cartridges. I plan on supporting Game Boy games in the future but for now I’ll get GBA dumping finalized before moving onto that. It shouldn’t be too difficult with all the available documentation on previous Game Boy dumpers done with an Arduino in addition to the fact that GBA cartridges are 5v tolerant making the need for voltage changes gone.
One last note I should mention is the departure from breadboard prototyping and the movement into a complete ROM dumping package. My idea is to have it in a small, compact box where you put in your game, flip a switch to select GBA or GB dumping mode, and press a button to start dumping. For progress checking and errors I figured I’d use a combination of LEDs to display progress. My idea is this:
Other than that, I’m open to suggestions, comments, and criticism. I’d also like to know if you would be interested in buying (or DIY’ing) a GB/GBA ROM dumping package that just dumps straight to an SD card. I think it would be cool since so many people are doing emulation on their phones that it would be much more convenient to just insert your phone’s MicroSD, dump the ROM, and play. I also think a battery powered solution would be nice but at the same time USB is very easily accessible. Let me know what you think in the comments.
Photos of the Dumper
Parts and Links
Arduino Mega (or Mega 2560 compatible)
GBA Cartridge Header - $2.50
My OSHPark profile for those looking to order the PCB - $20.85 + Shipping