I've been working on a GameBoy Cartridge memory dumper for the past month or so. A cartridge memory dumper reads the memory from the cartridge and saves it an external file. It is a way to make backups of cartridge based games. There are two types of memory that can be read, ROM and RAM. ROM is well the ROM. It's Read Only Memory. The game and other data like sprites are stored in ROM. RAM is where game saves and runtime data is stored. Below is my journey to dump the memory of my Pokemon Red cart. I also have a pretty neat idea on how this could be used in another way but that's for a another project post.
Hardware
I'm using the Cygni Dev board from TehoLabs for this project. This project is a way to help me learn some more about TI's LM3S MCUs. I also have a GameBoy cartridge connector that I pulled out of an GBA that my friend gave me. The connector has 32 pins. It has 16 address pins,8 data pins, read, write and a couple other pins. To interface the MCU with the connector, the Cygni has enough pins to connect each pin on the connector to a pin on the MCU. If I used a MCU with a smaller pin count, I could have used shift registers or some I/O expander in order to connect all the pins.
Software
One of my goals for the software of this project was to make it very portable. I accomplished this by having one file that handled the high level dumping and communication and another file that handled hardware interfacing; specific addressing/data lines, UART and MCU initialization. That one if someone wanted to port it to another MCU all they would have to do is change 4 to 5 functions that deal with previously mentioned things.
The hardware file deals with serial com and controlling the I/O pins like I mentioned before. This was handled very easily with the use of the StellarisWare software library. A vast majority of the hardware level software that you would normally write for a MCU has already been written for you. StellarisWare has drivers for all of the periphals, to use them you just have to find the right functions to use rather than digging through the data sheet to figure out what to set the correct registers to. To continue on, the readCart and writeCart functions set address lines to the given address and either read the data at that address or write to the address. The initialize function is straight forward and just initializes the hardware that is used. The UART functions are just wrappers for the StellarisWare functions so that the main program file can be platform independent.
The main file sits in a loop waiting for commands from the PC side program. Once it receives a command it executes that command. The scan command, reads certain memory location on the GameBoy cart to get information like ROM size, RAM size, Game Tile, Cartridge type. The ROM size is used to determine how many 16k Banks the cart has. The number banks is used latter when dumping the ROM to switch ROM banks the correct number of times. All of the scanned information is sent back to the PC side program, mostly for debugging purposes.
->
Code as a Gist <-
Results
I ran the the scan function from my Python script and it came back with the correct info on the first run! That made my confident that the whole dump would work, so I ran that command. I had to wait around 30-60 seconds for the whole dump. SLLOOOW! Anyway when it finished I took a look at the ROM in my text editor. Everything looked correct to me however when I tried to run it in a GameBoy Emulator nothing happened. So I compared the ROM I had dumped with one I downloaded. It turned out that for reason I wasn't reading the 8th bit of the data bus. After a little digging through my code at first and then the MCUs datasheet, I found that that pin(PB7) requires unlocking in order to change its configuration. So it was stuck as an output and never changing to an input. I didn't feeling like figuring out the unlocking sequence but luckily I had one extra pin. I switched the upper data bus bit to that pin and added code to read/write that pin.
With those changes I tried dumping the ROM again. This time it did read the upper bit and the dumped ROM matched the one I had downloaded. It also ran in the emulator as you can see in the following picture.
 |
| Success! |
Pokemon is the only GameBoy Game I have so I can't really test it with any other games. I some GBA games but I'd have to rewrite the program to read those. I might do that down the line depending on the complexity.
With this under my belt, I'm thinking about making a SNES Flash Cart or something else that relates to videogames. Most likely something else because a Flash Cart would be intense but it would be a good learning experience.
Oh I finally got an edge finder for my mill and an indicator for my mill/lathe. So expect some projects soon.