SNES (Super Nintendo Emulated System)
I chose Python to read carts as I’ve used it a lot in the past, and felt it would be useful for quick rewrites. The trade-off is that it’s an interpretedย language, and is not nearly as efficient or quick as C++.
When it came down to reading carts, I found that the ripping speed was not as fast as I’d hope due to the Pi’s configured I2C speed. The time needed was dependent on the size of the game, with most titles being between 4 to 16 Megabits. I was finding that an 8-Megabit title would take almost 18 minutes to rip. As you’d only need to rip a cartridge once, a long wait may be tolerable for a one time deal, but the waits became extreme for larger titles.
For example, ripping Donkey Kong Country, a full 32-Megabit title,ย took a little over 70 minutes. I set out to find a way to increase the speed of the Pi’s I2C bus, and finally found a solution on the official Raspberry Pi forums. Using Modprobe, I was able to force the I2C bus to operate at a faster rate, and well, the results were rather astounding. DKC now ripped in about 34 minutes. That is more than twice as fast!
To prevent re-ripping of already read carts, I check the Game Title which is in the header represented by 21-characters. When reading a cart, I have been using the full 21 characters as it is for the file name. This is less than ideal as many game titles have trailing spaces, and some will have a not so detailed Game Title. For instance, A Legend of Zelda: A Link to the Past has the header name of “THE LEGEND OF ZELDA “. This is not so bad considering there was only one Zelda title for the SNES, and the title is close to 21 characters, but for automating game ripping I may include a way to manually enter a Game Title in the future.
The python script I wrote, “cart_reader.py” sets up the SNES Cart reader by turning on a MOSFET I connected to the cartridge port for hot-swapping games. It then initializes the address, bank, and control lines by changing their states from input to output. I normally keep all the pins as inputs so they are in high impedance; this also helps the cartridge port go into isolation for hot-swapping.
The next step is to scan the checksums, and if valid pulls the game title. The game title text is then written to /tmp/insertedCart. If the game title matches an existing file name by the same Game Title, it quits, else it rips. If no valid game is found, the text “NULL” is written to insertedCart.
The BASH script “cartCheckAndEmulate.sh” runs cart_reader.py and when done uses the text of insertedCart to pass as an argument to the emulator to be called next. If no cartridge was detected, it launches EmulatioStation, a front end for Raspberry Pi Game ROMs, namely the ones previously ripped.
As previously mentioned, I modified SNESDev-RPi for my Reset Button. When the Reset is pressed, it sended the ESC key to the console, then the F4 key. ESC is to quit out of the emulator, if it is running, and to then quit out of EmulationStation, assuming that is running. It then launches cartCheckAndEmulate.sh. As all of this is being invoked by a daemon, I ran into issues.
Originally, I was using RetroArch with PocketSNES libs for SNES emulation, but found that the emulation speed was quite lacking with sound enabled. More importantly for use with the Reset Button, it uses raw keyboard drivers. When it is not launched from a console connected to the keyboard, it refuses to accept keyboard input. As both the controllers, and the Reset button sends virtual keyboard presses to the emulator, this became a serious problem.
For decent emulation speed with sound enabled, I went with an ancient build of SNES9X. It’s emulation accuracy is not nearly as accurate as recent emulators, but was deisgned for much older harder, and as such works for my purposes. More importantly, when evoked by a daemon, still allows key presses. I modified my cartCheckAndEmulate script, and when called without an argument, uses RetroArch. If called with any argument, uses SNES9x. With a quick re-code, the Reset Button now works as I intended.
My modified SNESDev-Rpi fork may be found here.
To further aid in emulation speed,recently I decided to finally mess with the Raspberry Pi’s “Core” overclock, …again. You see, back in September, 2012, the Raspberry Pi Foundation announced an officially sanctioned way to “safely” overclock the Pi using rasp-config. I utilized this overclock for when Eben and Liz Upton of the Raspberry Pi Foundation came to visit our hackerspace. I had a music controlled Raspberry Pi stop light display ready to go, and when the event was ready to start, my image corrupted. I found out later from Eben that Core overclocks have been known to corrupt SD cards.
The new official Core overclock doubles the Core speed from 250MHz to 500MHz. The thinking of the community is that maintaining the same ratio of the 250MHz clock, in this case twice the clock, helps.
It helped not only in emulation, but in cart ripping. Look at my Results with Donkey Kong Country below!
It took 4213.22911692seconds to read cartย – Default Core & I2C speed
It took 2036.41756105seconds to read cart – Default Core; Increased I2C Baud
It took 1172.85034895seconds to read cart – 500MHz Core; Increased I2C Baud
Next up, some final thoughts..
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.