ROM-Reader for Super Nintendo / Super Famicom Game Cartridges

No risk that I know of.

Here I have re-arranged the commands so that it’s easier to go line by line

void setROM_GBA() {
// CS_SRAM(PH0)
DDRH |= (1 << 0); PORTH |= (1 << 0);
// CS_ROM(PH3)
DDRH |= (1 << 3); PORTH |= (1 << 3);
// WR(PH5)
DDRH |= (1 << 5); PORTH |= (1 << 5);
// RD(PH6)
DDRH |= (1 << 6); PORTH |= (1 << 6);
// AD0-AD7
DDRF = 0xFF;
// AD8-AD15
DDRK = 0xFF;
// AD16-AD23
DDRC = 0xFF;
// Wait
delay(500);
}

I'm having trouble with the eprom programmer, when i blackcheck it, it says that it is empty, so i proceed to write the rom. While writting the rom it starts making a weird noise like static noise, after 3 minutes it starts verifying and then it gives me an error, i restart the cartreader and verify again, but still says that there was an error, and if i blankcheck it, it says the eprom is empty. I set both buttons to down position for writing, do i need to change them to the up position when Reading? This is how my adapter looks like.

Edit: Forgot to mention that i didn't solder the 22uf tantalum capacitor, probably they will arrive on monday. Can i damage something by not having that capacitor?

You should read out the eprom and check the file with a hex editor to see if it's really empty. If it is then you need to use a multimeter to check if the 6V pin gets 6V during programming and 5V during reading. And also that the O/P pin is getting 12V while programming.

That being said the 27C322 flash code is still very unreliable but it should at least program something even if it'S the wrong thing.

I get the weird noise too. Missing the 22uF tantalum will not do any harm.

I found the problem, there was a resistor in short. Now the O/P pin shows 12V on the multimeter. Flashed and verified the rom successfully on the first try.

Hi Sanni,

I finally got around to building my cart reader. It was my first time doing any major soldering other than battery replacements so I'm pretty happy everything worked (except the OLED screen isn't turning on but serial monitor works fine for me)!

Overall it was a great experience. I got the whole thing built for under $60 CAD including shipping (N64 cartridge support only and I was able to 3D print the parts at the library for $1).

A couple nitpicks though:

1) The SD card spacer is a bit weird. The one in the combined .stl file doesn't look exactly like the one in the video tutorial and the LED was loose in there. I had to wrap the top and bottom in tape to get the LED to stay in space. Also the standalone spacer .stl file has a different design the combined .stl file. Was there a change in this design?

2) It was wasn't very clear why you needed to desolder the pin header on the OLED screen since it seems like you put it back on later in the tutorial. Based on what I tell you just flipped the long and short side of the pins around?

3) The two wires that need to be soldered at the end aren't listed in the needed parts list. I understand most people would have spare ones lying around but I had to cannabilize an unused PC fan connector to finish my build. I think those wires should be listed in the parts list so someone doesn't get to the end and find out they're missing the last thing to complete the build.

4) The SMD buttons should be noted that they're only required if using the OLED screen. In case someone wants to save as much money as possible with just using the serial monitor.

5) Why two different screw sizes for screwing in the 3D printed parts?

1) The SD spacer in the video was made out of laser-cut acrylic, it's a leftover from an earlier design, where the backplate was out of acrylic since I didn't have a 3D printer yet. The one in the combined .stl is meant to be printed in coloured ABS/PLA and the one in the standalone .stl is meant to be printed in transparent ABS/PLA. Therefore they have different designs.

2) You could probably also solder the OLED to the Cart Reader without flipping the pins first. I haven't tried that. But yes all that the desoldering archives is to make the pins longer on the side that faces the Cart Reader PCB.

3+4) Changed the parts lists accordingly.

5) In the beginning, everything was M2 but I didn't like the look of the M2x15 female spacers in the front so I changed them to M3.

|500x375

I thought about how the next hardware version could look like but I can't think of a design that I really like. First I got rid of all the modules and put everything on a single PCB. But halfway through populating the PCB in Sketchup I got bored, way too many components. This would be a nightmare to solder.

|500x241

So next I added an Arduino Mega 2560 Pro, a mSD and a clock generator module and also added the OLED back since I now had some free space on the PCB. Much easier soldering job but there is something I don't like about this design either.

|500x275

The goal should be to make it as cheap and easy to build as possible.

Sorry that it took me a while to get back to you about this:

sanni: No risk that I know of.

Here I have re-arranged the commands so that it's easier to go line by line

Huh, well this is weird. I copy-pasted that re-arranged code, and was going to comment all of it out and one-by-one uncomment each line to see which one causes it.

But just as a baseline test, I uploaded it to the cart reader as-is without anything commented out yet just to make sure I get the same behavior as the original arrangement of the code.

.... and I didn't.

This time, it actually didn't erase the save from the cart, even though I had not commented any of the lines in that post out. I tried doing both a save and rom dump of all 4 SRAM GBA games I have (even though only two of them were erasing), and none of them erased their saves. I did a CRC-check of both the saves and roms from the earlier dumps and they matched as well. One had the latest save be different, but I think I actually had played it a bit so that's understandable.

Seems that somehow re-arranging the order of instructions in setROM_GBA in the order you write in post #743 makes it work correctly... I have no idea how or why though.

sanni: |500x275

I notice that this redesign has five cartridge ports now, is support for another system being added? If it was mentioned before in the thread I must have missed it. I recall there were people contributing to TG16 support via an adapter, I admit I am not too familiar with the TG16 but that doesn't look like a TG16 card port.

I don't know exactly why this fixed it but I updated the code on github anyway. :) The added slot on the design idea I posted is a NES slot but ofc there is no code written for it.

I worked on the design idea a little more, now it has two build options: with or without a backplate.

First build option that should be cheaper. |500x340

Second build option with the modules mounted on the underside and thus requiring a backplate. |500x322

And the backside of the second build option. |500x330

Also by using those longer male pin headers to connect the Mega 2560 Pro you can make an expansion port where you can plug in daughter boards like this one that breaks-out all the pins to two 40pin IDE connectors for prototyping.

Hi,

I was wondering how to write a rom to the satellaview 8m cart through bsx. The rom must be .sfc? I get invalid file response. Please any info will be helpful. Thanks

sanni: According to the datasheet of the 29W640 the flash commands are pretty much the same as with the 29F033, so if you re-solder the WE wire or change the WE pin in the code and change the flash ID in the code from "04D4" to "22ED" or "22FD", depending on if you have a 29W640FT or 29W640FB, it might just program without any major changes.

Is the code I’d need to change to change the WE pin within the “Write 29F032 flashrom” function in gb.ino? I’m trying hard to attempt to figure things out on my own and not ask too many questions, but narrowing down what to look at would be very helpful.

Yes it’s inside gb.ino, right now WE/WR is set to PH5.

void setup_GB() {
// Set RST(PH0) to Input
DDRH &= ~(1 << 0);
// Activate Internal Pullup Resistors
PORTH |= (1 << 0);

// Set Address Pins to Output
//A0-A7
DDRF = 0xFF;
//A8-A15
DDRK = 0xFF;

// Set Control Pins to Output CS(PH3) WR(PH5) RD(PH6)
DDRH |= (1 << 3) | (1 << 5) | (1 << 6);
// Output a high signal on all pins, pins are active low therefore everything is disabled now
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);

void writeByte_GB(int myAddress, uint8_t myData) {
PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF;
PORTC = myData;

// Arduino running at 16Mhz → one nop = 62.5ns
// Wait till output is stable
asm(“nop\n\t”“nop\n\t”“nop\n\t”“nop\n\t”);

// Pull WR(PH5) low
PORTH &= ~(1 << 5);

// Leave WE low for at least 60ns
asm(“nop\n\t”“nop\n\t”“nop\n\t”“nop\n\t”);

// Pull WR(PH5) HIGH
PORTH |= (1 << 5);

// Leave WE high for at least 50ns
asm(“nop\n\t”“nop\n\t”“nop\n\t”“nop\n\t”);
}

The pinout.xls from the github will help you with figuring out what Arduino pin is connected to which GB cart slot pin.

Perfect, I will give it a shot and see what happens.

sanni: I don't know exactly why this fixed it but I updated the code on github anyway. :) The added slot on the design idea I posted is a NES slot but ofc there is no code written for it.

Oh wow, I'm surprised you added an NES slot to the cart reader sanni.

Just wondering if you're working on code for it? I think I remember seeing another device which can backup/restore NES saves, although I believe it's in the beta stage (as tempting as it is to buy this device, I think I'm gonna stick with the Arduino). I'm looking forward to hearing more news about the new NES slot in the future.

Well, I would love to order the new PCB but it's $50 or more just to see if I made any mistakes designing it so I'm probably not going to place the order since there are better alternatives to read NES carts with the new infinitneslives dumper.

The goal of the new PCB design was to make building the Cart Reader cheaper but since a 150x100mm PCB is so much more expensive than a 100x100mm PCB that didn't really happen. Maybe when PCBs get cheaper in the future I'll build it just for fun.

In terms of the pcb redesign, would doing an nes adapter be feasible as an alternative? The other item that might be attractive to people is a gamegear adapter.

Tried the bennvenn cart, but after making the changes it gets past the “Blankcheck” and erase phase but then stops at the flashing stage. On the plus side, it didn’t actually erase the cart, so it still functions as before.

Any additional suggestions?

Edit: Could the fact that MBM29F033C expects 256 bank be an issue? Or does the flashing effectively ignore that and just use whatever it detects the cartridge has (it correctly detects the cart is 128 bank)

Hey, new here, really like the project you made Sanni. Having bought a SFC not too long ago with a few games on ebay, I wanted to read and patch some of my Japanese games.

The github page / wiki has all the links necessary to buy everything you need to build one of these, thanks for that!

My advice, as you mentioned yourself, is to try and keep the PCB to 10x10cm, unless some other PCB fab has a better deal than JLPCB.

Now, I've put the dimensions of your new board (15x10cm) into PCB shopper and JLPCB is still the cheapest at 20$ for 5, https://pcbshopper.com/

I do want to build one, but I'd like to know if and when you're going to update the current design to the new one? Should I just wait for the new board or go ahead and buy the current version ?

I'm not planning to update the PCB on github any time soon so you can go ahead and build the current version.

sanni: I'm not planning to update the PCB on github any time soon so you can go ahead and build the current version.

All right, just bought the essentials for the SNES. Some of the components from the BOM list are unavailable, but I found replacements pretty easily.

Hope nothing gets lost in transit from China.

Newbie2:
Any additional suggestions?

First, you should make sure that the cart gets erased properly.
So you could, for example, add while(1); into the function void writeFlash_GB:

delay(100);
println_Msg(F(“Erasing flash”));
display_Update();

// Erase flash
writeByte_GB(0x555, 0xaa);
writeByte_GB(0x2aa, 0x55);
writeByte_GB(0x555, 0x80);
writeByte_GB(0x555, 0xaa);
writeByte_GB(0x2aa, 0x55);
writeByte_GB(0x555, 0x10);

dataIn_GB();

// Read the status register
byte statusReg = readByte_GB(0);

// After a completed erase D7 will output 1
while ((statusReg & 0x80) != 0x80) {
// Blink led
PORTB ^= (1 << 4);
delay(100);
// Update Status
statusReg = readByte_GB(0);
}

// Blankcheck
println_Msg(F(“Blankcheck”));
display_Update();

to:

delay(100);
println_Msg(F(“Erasing flash”));
display_Update();

// Erase flash
writeByte_GB(0x555, 0xaa);
writeByte_GB(0x2aa, 0x55);
writeByte_GB(0x555, 0x80);
writeByte_GB(0x555, 0xaa);
writeByte_GB(0x2aa, 0x55);
writeByte_GB(0x555, 0x10);

dataIn_GB();

// Read the status register
byte statusReg = readByte_GB(0);

// After a completed erase D7 will output 1
while ((statusReg & 0x80) != 0x80) {
// Blink led
PORTB ^= (1 << 4);
delay(100);
// Update Status
statusReg = readByte_GB(0);
}

// Blankcheck
println_Msg(F(“Blankcheck”));
display_Update();
while(1);

The while(1); will make sure that after the erase nothing will be written to the cartridge. Then once “Blankcheck” is displayed you can switch the Cart Reader off and then on again and try to dump the cartridge and then check with a hex editor like HxD if the whole file you dumped consists out of 0xFF, meaning it erased fully.

If it did not erase then you need to change the code according to the datasheet of the used flashrom until it is erased.

If it is fully erased you can remove the while(1); again and write a rom to the cartridge, then dump the cartridge again and compare the dump in HxD to the file you wanted to write and see where exactly the writing failed.