Arduino powered interface for Super Nintendo Entertainment System game carts. A DIY alternative to the retrode.
Features:
- Read cart info from header
- Dump cart ROM
- Backup cart SRAM
- Restore cart SRAM
Games that use certain enhancement chips are not compatible with this setup. Specifically, enhancement chips that sit between the console and the ROM/SRAM will not work. These chips, like the SA1, require a signal from the Nintendo CIC lockout chip to start up. No cart data can be accessed without the CIC signal. In the future, I may integrate the CIC chip in the design or emulate it in the firmware.
Most games do not use enhancement chips. For a list of which games use which enhancement chips, see: List of Super NES games that use enhancement chips.
Confirmed incompatible:
- SA1
- S-DD1
Confirmed compatible:
- Super FX
- DSP-1
The desktop software is written in python and provides an interactive text-based interface for reading and writing to carts. It communicates with the Arduino using the built in USB to serial converter. It has been tested on macOS and Linux.
The firmware is written against the Arduino standard libraries and therefore requires the Arduino IDE and toolchain.
The firmware is very simple. The majority of the logic for dumping the carts is implemented on the desktop side. It communicates with the desktop software over serial. The firmware has three main functions:
CTRL
- for setting cartridge control linesREADSECTION
- for reading chunks of ROM and SRAMWRITESECTION
- for writing to SRAM
The main hardware components are an Arduino Nano microcontroller (ATmega328P based), three shift registers, and an original SNES cart edge connector.
The basic design is as follows. The A and B buses are connected to three 8 bit shift registers. The B bus occupies the most upper 8 bits. The A bus occupies the lower 16 bits. The shift registers are connected to the Arduino's hardware SPI pins. This allows for much higher data rates than controlling the registers through software. One byte can be shifted out by writing to the SPDR
register or by calling SPI.transfer(byte)
. The data bus is connected directly to the microcontroller, and each line is has a 10.0 kΩ pull down resistor.
SNES carts have a 1.2mm card thickness and 2.50mm pin pitch. I do not know of any off the shelf components that will work in the place of an original connector. An original cart connector can be obtained from a broken SNES console. This requires desoldering skills. The cart connector pinout is documented at the end.
Be sure to use an Arduino board with a legitimate FTDI USB to serial converter chip. Some clone chips have issues with higher baud rates. If you are having issues with an Arduino board that does not have an FTDI chip, try lowering the baud rate.
Parts list:
- 1x SNES cartridge connector
- 1x Arduino or AVR compatible micro controller (FTDI USB to serial converter recommended)
- 8x 10.0 kΩ resistors
- 3x 74HC595 shift registers
- Wire for connecting address bus, data bus, and control lines
- A good source of wire for projects like this is old PATA cables
SNES cartridges use a 62 pin edge connector and have three buses:
A
- 16 bit address busB
- 8 bit bank/page selectData
- 8 bit bi-directional data bus
Full addresses are notated the the following format: $BB:AAAA
, where 'BB' is an 8 bit hex value corresponding to the value on bus B, and 'AAAA' is a 16 bit hex value corresponding to the value on bus A. For example: $00:7FFF
.
Information about the cartridge is found in the cart header. The header is 32 bytes of data located at $00:FFC0
. When interfacing with a cart, you must first read the header to determine the layout, ROM size, SRAM size, number of banks, etc.
Address | Length | Data |
---|---|---|
$00:FFC0 | 21 bytes | Game Title |
$00:FFD5 | 1 byte | ROM Makeup |
$00:FFD6 | 1 byte | ROM Type |
$00:FFD7 | 1 byte | ROM Size |
$00:FFD8 | 1 byte | SRAM Size |
$00:FFD9 | 1 byte | Country code |
$00:FFDA | 1 byte | 0x33 (fixed value?) |
$00:FFDB | 1 byte | ? |
$00:FFDC | 2 bytes | Complement check |
$00:FFDE | 2 bytes | Checksum |
There are two cart layouts: HiROM and LoROM. The lowest bit of the ROM makeup field indicates the layout (0 == LoROM, 1 == HiROM).
LoROM carts have page 32KB pages. A15 is not used and usually internally disconnected. $0000
to $7FFF
is a mirror of $8000
to $FFFF
. Pull A15 high when reading LoROM carts. HiROM carts have 64KB pages. All 16 lines of bus A are used.
Reading ROM (# of banks can be calculated from data in cart header):
LoROM
: Read all banks, from address $8000-$FFFFHiROM
: Read all banks, from address $0000-$FFFF
Reading SRAM (size of SRAM in cart header):
LoROM
: Read from $30:8000 onHiROM
: Read from $20:6000 on
Writing SRAM (size of SRAM in cart header):
LoROM
: Write from $30:8000 onHiROM
: Write from $20:6000 on
In addition to the three buses, the carts have four control lines (active low):
RD
- Read. Pull low when reading data.WR
- Write. Pull low when writing data.CS
- Cart select.RESET
- Reset. Pull high when accessing cart.
Read ROM | Read SRAM | Write SRAM | ||||
---|---|---|---|---|---|---|
HiROM | LoROM | HiROM | LoROM | HiROM | LoROM | |
RD | 0 | 0 | 1 | 1 | 1 | 1 |
WR | 1 | 1 | 0 | 0 | 0 | 0 |
CS | 0 | 0 | 1 | 0 | 1 | 0 |
RESET | 1 | 1 | 1 | 1 | 1 | 1 |
Bus A is marked in light blue. Bus B is marked in dark blue. The data bus is marked in green. The control lines are orange. Power pins are marked in yellow. The gray pins are not used for this project.