SNES (Super Nintendo Emulated System)
After I set up the hardware and the Linux environment, I was ready to read and rip cartridges! So where to start? I remember reading about a SNES cartridge reader that would later be known as the Retrode on Hack-a-Day. So I went to read one of the original blog posts to see what resources the original engineer used.
The only resource mentioned was an old blog, titled “SNES Kart.” It is hosted on emularonia.com and was written by DiskDude. While the resource helped tremendously, a lot of it is a collection of observations DiskDude made way back in 1996. Since then, let’s just say there are less uncertainties; a lot of time has passed, and the SNES hardware has been thoroughly reverse engineered by now. A break down of this information was a pain in the ass to find though.
Try Googling “Reading SNES Cartridges.” Most of the results link you to already available commercial solutions, or a forum post where the answer is using a commercial solution.The other 99% of the results are for reading ABOUT the SNES, and nothing technical. Searching for “Ripping” or “Dumping” largely links to ROM sites. The obvious issue is that every commercial SNES title has already been ripped, and not too many people are interested in re-ripping them. I wanted to though, damn it!
To spare time, I will break down my findings. Use the notes below as a supplement to other ROM reading documents on the internet. I’m going to document things I feel will save others time.
SNES Cartridges have:
- 4 Control Pins, and an IRQ Pin. To read a cart, hold the control pins RD, and CS low. WR Should be held high. Also, RESET should be held high, despite the “SNES Kart” document indicating the opposite. The IRQ pin can send a signal from the cart to the console when the CPU should be halted. I’m not sure if it will ever be necessary for cartridge reading, but I broke it out just in case.
- 4 CIC Security Check Pins. In SNES consoles there is a chip known as the “CIC” chip. This chip acts as an anti-counterfeiting “lock,” and will hold the console in reset until it is unlocked by the corresponding “key” in a legitimate cartridge. Cartridges typically don’t care if the CIC lock is missing from the device communicating to it, and some people would disable this chip to thwart the anti-piracy.
Nintendo got smart to this, and games with SA-1 chips actually won’t work if the CIC chip doesn’t communicate with it. The CIC chips have been reverse engineered, and the SuperCIC was designed to emulate the original chip, and will work as a drop-in replacement. I haven’t attempted to emulate the CIC yet, but expect to have to in order to read games such as Super Mario RPG. - 16 OPTIONAL “Bus B” (Expansion Chip) Pins. If you’ve ever looked at the bottom of a Super FX game, or any other cartridge with an expansion chip, you’ll notice an additional 16 pins on both sides of the center PCB. As far as I can conclude, these are useful for speedy (CPU<>Expansion Chip) communications. While I wouldn’t be surprised if a handful of carts use these pins for transferring ROM data at faster rates, I don’t expect you’ll ever NEED them to dump a cart. Besides, every expansion chipped game I’ve visually inspected seem to only utilize the SNES clock pin. (Likely for sync)
- 16 Address pins, and an 8-pin Data Bus. When you move to an address, the 8-bit piece of data held at that address could be read from the data bus. If you understand bits, bytes, and binary, this shouldn’t be too hard to follow so far.
As 8 bits are in a byte, in actuality there is exactly 1 byte at every address read. Counting by the number of addresses (2^16), you’ll find that you could read up to 65536 bytes, which converts to 64 Kilobytes. SNES games often contain a lot more data, so how do you read more than 64Kilobytes? By switching banks! - 8 Bank pins, giving a maximum of 256 banks that could be accessed. There are two ways of bank switching you must be aware of. One method for LoROM, and another for HiROM games. HiROM reading is simply the matter of incrementing the address for the full 16-bit length. Then you increment the bank, and read the next 64 Kilobytes. LoROM games only use half of each bank, leaving only 32 Kilobytes per bank.
Reading LoROMs:
The way I understood LoROM addressing was to read the first 32 Kilobytes, switch banks,and then read the next lower 32KB, starting again at address 0. Many different resources seemed to allude that having pin A15 high was optional, but this is not the case.
In actuality, you NEED to hold A15 high with LoROMs, so you are in essence reading the UPPER 32KB. Many docs say that the lower 32KB is mirrored with the top 32KB on LoROM games. NOPE. Super Mario World worked reading the lower half, Super Metroid did not, though.
All SNES games hold a standardized header at the same address. The SNES Kart document has this address at two separate offsets, depending on LoROM or HiROM. In practice, these two addresses are the same.
The header for LoROM games is said to be held at offset DEC: 32704. This is
- 0111111111000000 in binary.
The header for HiROM games is said to be held at offset DEC: 65472. This is
- 1111111111000000 in binary.
Notice the only difference is at bit 15.
My code ORs a ‘1’ to bit 15 regardless of the specified address in LoROM mode. So moving to address 32704 in LoROM is actually 65472 when accounting for that fact that A15 will be high.
ROM Type Detection, and Checksums:
So the question you may be asking is how would you know if a game is LoROM or HiROM? Good question! It’s in the header! As I mentioned, since the header is at the same location on both types of ROMs, the nibble containing the ROM type is, as well.
The ROM Type is at address DEC:65493, contained in the lower nibble.
- 0x0 is for LoROM, and
- 0x1 is for HiROM.
If the cartridge connector is dirty, the Data Pins will not be accurate, or in the case where these is no cart, will be held high by the MCP23017’s internal pull-up resistors.
A good way to test if a cartridge is connected, and is working properly is to check it’s checksum bytes.
In SNES carts, at addresses DEC:65500-65501 are two bytes that make up a 16-bit ROM Checksum. Lower byte at 65500, and upper byte at 65501.
There is also an 16-bit Inverse Checksum at addresses DEC:65002-65003, respectively.
XOR’ing the ROM Checksum to the Inverse Checksum should produce 0xffff. If it does not, I assume that the cartridge data is invalid. As this is stored in the header, I could check for this rather quickly.
As an example, Super Mario Kart has a ROM Checksum of 0xeb44, and the Inverse Checksum is 0x14bb. XOR-ing them together equals 0xfff.
The ROM checksum is also the last 16-bits of the calculated checksum from reading the contents of the cartridge. For example, Super Mario Kart is a 512 Kilobyte HiROM game. Since it’s HiROM, you read in 64-Kilobyte “pages.* (512/64 = 8 pages.) When reading a ROM, add each byte of 64-Kilobyte pages together, then add the results of each page together.
For Super Mario Kart, the calculated checksum is 0x286eb44.The 16-bit ROM Checksum in the header is 0xeb44. Notice the header checksum is indeed the last 16-bits of the fully calculated checksum..
To know how many pages will need to be read, in addition to the ROM type, you’d need to know the ROM size. This too is stored in the header, at offset DEC:65494. Unfortunately, it’s size is listed as exponents of 2. The size in Megabits can be 2, 4, 8, 16, or 32 Megabits, but games could be of different sizes.
Super Metroid is a 24 Megabit game, but going by the header, is listed as a 32 Megabit game. In this case I read the full 32-Megabits, and calculated the checksum. It matches the checksum in the header, but it’s possible the file size is 8 Megabits longer than it has to be. It works for now, though, and I doubt emulators will care there is data passed the declared ROM length.
What address to begin reading at:
For both HiROM, and LoROM games I used to start at offset 0. That is Address 0, and Bank 0. I started noticing checksum errors, so I attempted to clarify. It helps to actually have some very specific knowledge to Google search with! I used the search term for “SNES rom” with hexadecimal addresses I had been using and finally found comments in source code.
I found a SNES ROM reading driver for the M.E.S.S (Multi-Emulator Super System) Project, and used the memory maps it uses.
In short:
For LoRom Games:
- Read up to 96 possible pages starting at bank 0x00.
For HiROM Games:
- Read the first 64 pages beginning at bank 0xc0.
- IF the ROM is larger than 32-Megabits (VERY rare!,) read the final 32 pages starting at bank 0x40.
and that’s about it. I haven’t attempted to read or write save game data yet, but that too is just a matter of software.
For additional reading, use these resources:
http://wiki.superfamicom.org/snes/show/Memory+Mapping
http://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map
http://www.programmersheaven.com/download/13299/4/ZipView.aspx
Next, the Reset Switch, along with Bash and Python scripting..
Oh my god. I LOVE that! How awesome to play anything emulated on the original hardware. Plus carts!
Pingback: Turning a Raspberry Pi into an SNES | Daily IT News on it news..it news..
Congrats for that neat project!
Might be a silly question (as questions usually are) but assuming someone who can write / edit / hack, would it be possible to address the speed issues by throwing two Pi’s in the box, one to handle the graphics, the other to handle sound and other I/O rather than waiting for a faster PI?
Very nice project, congratulations!
I still have two SNES in perfect working condition 🙂 They are bullet proof console!
Can you post the wiring you did for this? Rather than just showing off? 😛 JK man, very cool
Andy, I have actually considered something along those lines. I hadn’t considered offloading audio and I/O to a second Pi, I had just imagined spitting the threads, but your suggestion sounds better. Thanks for the tip! 😀
I’m not exactly sure how I would pull it off though. I could link both Pis via GPIO, or Ethernet. I’m guessing GPIO communications would be the best, but I lack the skills needed for re-coding major portions of the emulator.
Shake, there are no schematics. I wired the level shifters by the datasheets, and actually screwed up a few times due to the fact I was wiring on a whim.
As for the other components, the Arduino sketch has the pin numbers for power management, and the cart_reader.py script could clue you in to what cart pins go where. Also because you asked, I appended a spreadsheet I used for the cart to my GIT. 🙂
Why is not in fullscreen?
This is very interesting, but I must find a broken SNES console and buy another Pi (my only one is in use).
Very awesome project, congratulations.
You win 1 Internet Sir. Well done!!!!!!
Would it be possible to release a fast snes emulator which we can use with the RasPi? Every snes emulator I tried was very slow.
The cart reader aspect is pretty awesome!
>> offloading audio
Maybe a USB soundcard with its own processor might be able to help.
I’m just about to start doing the same thing as you yet to buy the raspberry Pi but got the broken snes lol 🙂 now who still got me soldering Iron lol
You are a god amongst men Ted. Awesome project. Well done.
Hey! I could have sworn I’ve been to this site before but
after checking through some of the post I realized it’s new to me.
Anyhow, I’m definitely delighted I found it and I’ll be book-marking and checking
back frequently!
Hey I’m working on a similar project but my work is nothing compared to yours nice work.
Hey! Nice job! Is it possible that you publish the material list and the solder layout. I realy love to reproduce this ’cause my old SNES start to bug :/.
Excellent site you have here but I was wanting to know if you knew of any forums
that cover the same topics discussed in this article?
I’d really like to be a part of community where I can get feedback from
other knowledgeable people that share the same interest.
If you have any suggestions, please let me know. Thanks a
lot!
Feel free to visit my web blog http://www.huishige.com
Hey just wanted to give you a quick heads up and let you know a few of the images
aren’t loading properly. I’m not sure why but I
think its a linking issue. I’ve tried it in two different
browsers and both show the same results.
Another interesting project would be to put an raspberry pi in a snes cartridge which emulates an snes game on the cartridge pins. That would make it possible to play any rom with the original untouched snes 🙂 that would also make it possible to play custom roms, to build a simple web browser or an mdp client and much more, everything with the original untouched snes hardware 🙂 And who knows what you could do with the snes when you extend the snes with the 16 Bus B Expansion Chip Pins (or the ext port) and the help of the raspberry pi..
Pingback: 5 Old School Gadgets You Can Create With a Raspberry Pi | Retro Gamer
Pingback: 5 Old School Gadgets You Can Create With a Raspberry Pi | Retro Bunny
Hello. I really admire your work. Congratulations.
I wanted to run Gameboy & Gameboy color cartridges with the Raspberry Pi 3B.
Do you believe to be possible? Basing their work believed to be viable?
Can you clarify some doubts if I need it?
Thank you very much.