SNES cartridges come in a few different variants, distinct in a few major ways. As noted in the main SNES reproduction guide, there are six major categories that set apart different boards – bank type, ROM size, SRAM size, extra chips, speed, and the video type or region. If you check out my big list of SNES games you’ll see the games sorted by these different categories. For the purpose of this post, since we don’t have an easy way of reproducing these chips (and I lack the knowledge to sufficiently explain their functions), we’re only going to focus on cartridges that use “Normal” chips. The other types are “enhancement chips” – usually proprietary graphics-boosting chips. The popular example that you probably already know about is the Super FX chip, used in games like Star Fox to generate better 3D graphics. (Note that you can still make these games, you’ll just need to use a donor cartridge that already has one of these chips on it.) The “normal” chips include one or more EPROMs and a CIC region lockout chip. And if your game saves, then it’ll also have a mapper, battery, and SRAM. There are also various capacitors and possibly resistors and diodes for games that have a battery.
Table of Contents
- The Cartridge Connector
- Power Supplies
- CIC Region Lockout Chip
- EPROM Connections
- SNES Memory Map
- Further Remarks
The Cartridge Connector
Let’s start out our analysis at the cartridge connector – the exposed teeth-looking pads at the bottom of the board that goes into your SNES. There are two major variations of the connector – one that has just a large 46-pin section, and another variation that additionally has two sections of 8 more pins on each side of the main 46-pin connector (for a total of 62 pins). We’ll be looking at only the 46-pin variation. Since we’re ignoring 8 pins on either side of the 46-pin part, the numbering is going to be offset by a bit. If you look closely, you’ll see some of the pins called out in green above the gold teeth. Thanks to neviksti for the convenient pinout.
VCC, GND: Power pins
A0-A15: Address pins (offset)
BA0-BA7: Address pins (bank)
D0-D7: Data pins
/RD: Read command
/WR: Write command
/CART: Low when accessing EPROM data (only goes low during certain addresses, based on the memory map)
CIC pins: CIC interface with the SNES
/RESET: Reset signal
/IRQ: Interrupt request
As far as I have seen, the /IRQ pin isn’t really used for much on the cartridge. It might have some use in some niche areas, probably with some extra enhancement chips on the board, but for the purposes of this post we will be ignoring it. Let’s start the analysis with an overview of the components on the board and how power is applied.
On every SNES board you’ll notice a handful of capacitors. There’s one large bulk electrolytic capacitor (looks like a metal can) that’s used to keep the VCC rail powered on and steady, so that varying voltages supplied from the SNES don’t interrupt the operation of the game, and to help maintain power during any voltage dropouts or similar events. Similarly, there are usually multiple small ceramic capacitors scattered across the board. There should be at least one for each major chip on the board, like the EPROM, RAM, and CIC. These are called decoupling capacitors, and are used to filter out any stray noisy signals that may be propagating through the VCC line that could disturb the chips and circuitry on the board. If you don’t have these, the board will still probably work ok, but it’s good electrical engineering practice to include them. For my custom boards, I use 22 uF electrolytic capacitors and 0.1 uF ceramic capacitors.
CIC Region Lockout Chip
Every SNES game comes with one of these region lockout chips. They were used by Nintendo to prevent you from using a game from one region in the hardware from a different region. They had their reasons for this… with only one of which that actually benefited the consumer. There are two main types of video encoding in the world – NTSC and PAL. There’s a huge history behind these standards, and it’s quite interesting if you’re a nerd like me and think video encoding standards are something worth learning about, but the only thing that really matters for our purposes is that some PAL games played on NTSC consoles (and vice versa) can get really weird. NTSC runs at 60 Hz, while PAL runs at 50 Hz, making the games run slower or faster depending on which you’re using, and a bunch of graphical glitches can occur too. That’s even if the game will start up.
Anyway… the CIC chip is a necessary evil. I’m not going to go into how it works (because I’m not even too sure or curious to know myself at the moment), but I WILL tell you how to fake out the chip with your own. All you need is a PIC12F629, a tiny little 8-pin microcontroller, and some custom code from SD2SNES. Just extract the folder and find the file named “supercic-key.hex” and MAKE SURE it ends with -key, NOT -lock. You can load this file up into a cheap programmer, like the TL866, and load it into the PIC. Then, route the pins as shown below.
To start talking about how the EPROM connects to the cartridge connector, let’s get the easy ones out of the way first.
D0 through D7 are the data lines. Whenever an address is called from the SNES onto the EPROM A (and BA) pins, an 8-bit word is placed on the data lines and read by the SNES. So, it makes sense that D0 on the EPROM connects to D0 on the cartridge connector, and so on.
The /CS pin on the EPROM (chip select) is connected to the /CART pin of the cartridge connector. Pretty straightforward. The /CS pin needs to be activated in order to allow data to be accessed and read on the EPROM.
The /OE pin on the EPROM (output enable) is usually connected to the /RD pin (read data) on the cartridge connector, because we want the EPROM to output data whenever the SNES is requesting cartridge data. The only instance where the /OE pin is connected elsewhere is when you have a LoROM board with SRAM. In this instance, we connect the /OE pin to a specific output of an on-board ‘139 decoder. This seems weird right now, but I’ll explain it further on.
All that leaves is the address lines, A0 through A23. As it happens, EPROM pins A0 through A14 are all connected to their respective pins on the cartridge connector. And on HiROM boards, this continues with A15, A16 (which connects to BA0), A17 (BA1), etc.
However, on LoROM boards, A15 is skipped. Instead of the EPROM A15 connecting to the cartridge connector A15, it instead connects to cartridge connector BA0. Then, BA1 connects to A16. And so on, until BA7, which connects to EPROM A22.
You might be asking, what’s A15 connected to then? Well, if you have a LoROM board with no SRAM, it’s connected to nothing! But if you have SRAM, it plays a bigger role. Let’s look at the SRAM for now, and revisit this mess later.
Like the EPROM, a lot of the SRAM pins are straightforward. The digital pins D0 through D7 are all connected to the D0 through D7 pins on the cartridge connector. /WE (write enable) is connected to /WR on the cartridge connector, which tells the cartridge when to write data onto the SRAM (like when you’re saving your game). And /OE is connected to /RD on the cartridge connector so that it only outputs data when the SNES requests cartridge data.
The VCC pin on the SRAM chip is powered by either the VCC from the SNES (5 V) or the voltage from the battery (VBAT, 3.3 V). This is done with two small diodes connected to each voltage source. When VCC is on, the voltage on the SRAM supply is ~5 V, which causes the battery to not discharge any power through its diode. When VCC is off, the voltage on the SRAM supply is ~3.3 V, supplied by the battery.
The address pins on the SRAM are actually more straightforward than the EPROM address lines. A0 through A12 all connect to their respective cartridge connector address lines. A13 and A14 on LoROM boards also connect to A13 and A14 on the cartridge connector. The only difference is on HiROM boards, A13 and A14 are connected to BA0 and BA1 on the connector, respectively. You’ll only ever see A13 and A14 used on a few games, that is games with 256 Kbit (32 KB) of SRAM. It’s good to note that on games with 64Kb (8KB) of SRAM, A13 and A14 on the SRAM chip are just tied to VCC or GND, and on games with 16 Kbit (2 KB) of SRAM, A11 and A12 are also tied to VCC or GND.
This leaves us with the /CE pin (chip enable), and, in the case of 64 Kbit SRAM, CE2 pin (secondary chip enable). If the SRAM chip has both pins, the /CE pin and the CE2 pin both need to be at the correct voltage level in order to allow the SRAM to operate – if one is disabled, the chip will be disabled and not do anything. For /CE, it needs to be pulled to GND to activate. The CE2 pin is similar to the /CE pin, but inverse logic (hence, the omitting of the slash at the beginning of the pin name) and needs to be pulled to VCC to activate. If either of these pins are not at the correct voltage, the chip will remain disabled. On my boards and on standard SNES boards (without the MAD-1 chip), the /CE pin is controlled by the SRAM decoder, and the CE2 pin is controlled by the NPN circuit. The SRAM decoder is commonly a 74HCT139, or equivalent part (I’ll denote it as ‘139).
When the game is removed, or powered off, the SRAM needs to exist in a low-power standby mode while the battery backup is supplying the SRAM as described earlier. The SRAM on SNES games is volatile. This means that whenever power is removed from the chip, all the memory is erased. That’s why you have the battery inside games that save, and why you need to go replace all of your old NES, SNES, Genesis, and Gameboy game batteries RIGHT NOW OR ELSE YOU’LL LOSE YOUR SAVE DATA GO DO IT NOW!! But be sure to keep your SRAM powered while you replace them!
Anyway… as I mentioned earlier, the /CE pin is connected to the SRAM decoder. Where on the decoder it’s connected and when it’s activated is determined by the resulting memory map the game follows based on the “bank type” of the game – LoROM or HiROM. Basically, whenever the SRAM needs to be activated for saving, the decoder pulls the /CE pin to GND, and whenever it isn’t being used, it keeps it at VCC. The memory mapping will be covered later, as it requires a lot of explanation. For now, let’s look at the standby mode and battery circuit and see what’s going on there.
The typical coin cell batteries (CR2032) are rated at 220 mAh. This isn’t very high when talking about long-term saving, if your board operates with just 1 mA when disconnected from the SNES, your save game will last at most around 220 hours! So it’s crucial to get that current as low as possible to keep your save games going for a long time. This is exactly what the NPN transistor circuit is designed to do. Let’s look at the circuit below.
The NPN is activated by the /RESET signal coming from the cartridge connector. The /RESET pin is held at VCC during normal gameplay, but pulled to GND when the reset button is held down, or when the console is off. When /RESET is at VCC, the NPN transistor conducts and the CE2 pin is pulled to VCC, allowing the operation of the SRAM chip (depending on what /CE is doing). When /RESET is at GND or disconnected, the transistor turns off and the CE2 pin is pulled low through the lower resistor, automatically disabling the SRAM.
You might be asking yourself – what’s the point? Why not just tie CE2 to VCC, control the SRAM activation with only /CE, and be done with it? Why add this extra step with a transistor that seemingly does nothing, since the CE2 pin is always going to be at VCC when the game is on? That’s what I thought too, originally – I had the ‘139 decoder take care of the /CE pin, and separately held CE2 to VCC. And when the cartridge wasn’t powered, I had a pull-up resistor from /CE to the SRAM’s VCC pin, which was powered by the battery, to keep the chip from operating while off (to make sure no random data got written to the SRAM from noise). This worked great – the game would save just fine. Except for one tiny detail. If you look at the datasheet of a standard 64K SRAM chip, and look at the standby current, you’ll see this:
The conditions in the middle column (Test Condition) say that CE2 needs to be held to GND, or /CE needs to be held to VCC (within 0.2 V) in order to get the low standby current in the microamps. Otherwise, the standby current would be in the milliamp range, even though the /WE and /OE pins aren’t being activated. Well, in my original circuit, CE2 was pulled to VCC, so that wasn’t any good for getting low standby current, but /CE was held high to VCC (on the SRAM) through a pull-up resistor, so it should have the lower standby current, right?
Wrong! The /CE pin was ALSO connected to the ‘139 decoder, which isn’t powered by the battery. It’s just off. This actually causes some leakage current – in the tens of microamps – to flow through the output pin of the ‘139 to GND. This leakage current can only come from one place – the pull-up resistor on the /CE pin. This extra leakage current caused a voltage drop across the pull-up resistor and actually put the /CE pin voltage below the 0.2 V threshold for low standby current. This caused the SRAM to have a high standby current, which ultimately drained the battery faster.
So back to the NPN circuit. We can see that if the /RESET pin is at GND (or floating, if the game is removed from the SNES), then the transistor won’t be conducting. Then, the resistor RE pulls down the CE2 pin all the way to GND – no voltage drop to worry about. This puts the SRAM in the low standby current mode. Depending on the chip you get, you could see as little as 1 microamp of power being pulled from the battery – this would theoretically allow your game to last for 220,000 hours, or about 25 years!
Now, 256 Kbit SRAM doesn’t have a CE2 pin. So in order to get to a low power state, we need to keep /CE within 0.2 V of the SRAM VCC. Our decoder circuit won’t work, since this would introduce a leakage current through the output pin on the decoder (unless someone out there finds me a low-leakage decoder, or a decoder that puts the output to a high impedance state when there isn’t power!). I believe Nintendo’s answer to this was the custom-built MAD-1 decoder, as that chip controls the SRAM’s /CE pin and has connections to the battery and voltage supply pin of the SRAM. Our answer to this problem is gonna look a bit different!
The save circuit for using 256K SRAM chips is actually quite similar to the 64K SRAM circuit above. Instead of attaching the emitter to GND through a resistor, we’ll instead connect that to the output of the ‘139 decoder that activates the /CE pin of the SRAM. And instead of connecting the collector to VCC, this will instead go to the /CE pin of the 256K SRAM. Finally, we add a pull-up resistor from the collector to the VCC of the SRAM (note that this VCC is the voltage bus after the two diodes combining the SNES power and battery power on the cartridge together). The transistor stays an NPN, and the base is still connected to the /RESET line through a resistor. See the circuit below.
Now, a bit of analysis. This NPN transistor basically combines previously separated two inputs – /RESET and /CE from the decoder. When /RESET is HIGH (normal operation), the ‘139 output will directly change the /CE state on the SRAM so the two match. During this normal operation, when the ‘139 output is HIGH, then the base current is zero, so the /CE pin is also HIGH. And when the ‘139 output is LOW, then the base current is high enough to allow the NPN to conduct, which pulls the /CE pin LOW as well. And when /RESET is LOW (or disconnected completely, when the cartridge is removed), the transistor base current is zero, and the /CE pin is pulled up to the VCC of the SRAM through the pull-up resistor RC. Because there is very little leakage through the NPN transistor, there will be little to no voltage drop seen on the /CE pin, ensuring the voltage is within the 0.2 V margin allowed for data retention. Note that this can easily be applied to the 64K SRAM circuit as well, we just need to tie CE2 to VCC!
So now, I think it’s time we finally talk about the memory map of SNES games, what the true difference is between LoROM and HiROM, and how that affects our connections. This next section is going to get a bit confusing and wordy, so bear with me! This is the real meat and potatoes of this entry.
SNES Memory Map
The SNES organizes information into different areas of memory for different purposes. Based on development manuals we can figure out where different types of memory are stored. There’s some pretty technical stuff going on here, and I’ll do my best to explain it in as simple of terms as possible. And I’ll only go into what we care about as it relates to the mapper on the cartridge, rather than trying to explain all of it (because I’ll probably embarrass myself with misinformation if I try to anyway).
It’s important to remember that the memory maps detailed below are driven by the SNES, not by the cartridge. The SNES CPU generates the address lines, and what is activated and what is not is (mostly) determined by how the cartridge is wired. Traditionally, you usually see LoROM and HiROM types (or modes 20 and 21, respectively, as seen in the manual). The actual difference between these cartridges lies in how they are wired up. Let’s take a quick look at how the SNES CPU memory is divided up.
This is from the official manual and honestly it’s hard to look at. The only thing I really want to point out here is the cross-shaded part of the map. This represents when the SNES is expecting data from the EPROM. Whenever the CPU address (on pins A0-A15 and BA0-BA7) is in these locations, the /CART pin on the cartridge connector is pulled LOW to activate the EPROM’s memory. In all the other locations, the /CART pin will be pulled HIGH to deactivate the EPROM output.
You’re about to get blasted with some more charts with a lot of hexadecimal numbers all over the place. Luckily, the next few charts you’ll be looking at are a lot easier to read than the first one up there. So I’m going to briefly explain what these hex numbers are referencing. Take a look at what the memory map becomes when a LoROM board is used (from page 95 of the manual) for an easier look:
If you ever took any kind of digital logic class in school, recall that one hexadecimal number is four binary numbers. So one hex digit represents four address pins. The standard notation to show a hex number instead of a decimal number has an 0x before the number. Similarly, binary numbers have 0b before the number (decimal numbers are just written out). So 0xC is 12 in decimal, 0b1100 in binary. 0xFF is 255 in decimal, 0b11111111 in binary.
Refer back to the cartridge connector – there are sixteen “A” address pins (offset, making a four digit hex number) and eight “BA” address pins (bank, making a two digit hex number). This chart shows why they’re known as “bank” and “offset” address pins. Essentially, the A pins determine where in the row the data is accessed, and the BA pins determine the column. For example, an offset of 0x0000 means that the bottom sixteen address pins (A0 to A15) are all 0. An offset of 0xFFFF means all the pins are 1. A bank of 0x00 means the top eight address pins (BA0 to BA7) are all 0, and 0xFF means they’re all 1. It’s a very common practice to organize data into different banks like this.
So, if the SNES CPU sends the address for bank 0x73, with an offset 0x6000, the data on the address pins of the cartridge connector would look like this:
Yeah, Windows’ built in programming calculator comes in handy here. You’ll see the binary number up there – each digit references a different address pin on the cartridge connector. So if BA6, BA5, BA4, BA1, BA0, A14, and A13 are all 1’s and the rest 0’s, the SNES will access the data at address 0x73:6000, wherever it may come from based on the memory map.
Before going any further, it’s time to briefly talk about the chip known as the “mapper”. On my boards, and most other unofficial reproduction boards, the mapper used is a dual ‘139 decoder. Official Nintendo boards sometimes use the ‘139, but also use a proprietary MAD-1 decoder. I’ll only be talking about the ‘139. Each of the two decoders on this dual chip have two inputs and four outputs, along with an enable pin. The truth table is below.
Remember that for the /OE or /CE pins on the various chips on the board, the logic level is pulled LOW to enable. So we use the decoder to tie these lines low. The way the inputs are wired will manipulate how the SNES memory map from before actually functions. We can then redraw the memory map for the two main different wirings for cartridges (LoROM and HiROM).
LoROM Memory Map (Mode 20)
Remember how I mentioned the CPU A15 address was skipped on LoROM boards? Well, it’s actually connected to both the A0 and A1 inputs on the decoder for games that save. This means that when CPU A15 is 0, output Y0 will be pulled LOW. When CPU A15 is 1, output Y3 is pulled LOW. The enable pin of this decoder is connected to the /CART pin on the cartridge connector, so only when the SNES requests ROM data will the decoder pull one of the outputs low.
The output of Y3 is directly connected to the /CE pin on the EPROM. Therefore, the output of the EPROM is only enabled when CPU A15 is 1, and when /CART is LOW. Take a look at the resulting memory map for LoROM boards again.
Because CPU A15 must be 1 to enable the ROM output, any offset below 0x8000 disables the EPROM output (because 0x8000 means A15 is 1 and every address below that is 0). Any offset above 0x8000 means CPU A15 is set to 1, and therefore the EPROM output is enabled (as long as the decoder is enabled with the /CART line). The only region of the memory where the EPROM output would be enabled, but is pulled HIGH because the /CART pin will not be enabled, is between banks 0x7E to 0x7F (which is reserved for use by the SNES WRAM).
Ever wonder why we call LoROM and HiROM different “bank” types? It’s because of the memory map – LoROM uses only half of each bank for ROM information. HiROM uses the entire bank, but we’ll talk about that type later.
Another important thing to note is the symmetry of the map. Doesn’t it look like the memory is symmetrical across the line between banks 0x7F and 0x80? There’s a reason for this! Any bank above 0x80 (0b1000000) means the BA7 line is 1. But, if you didn’t notice already, BA7 isn’t actually connected anywhere on a LoROM board. Therefore, the cartridge outputs the same data when banks above 0x80 are called, treating it as if the address was actually in banks 0x00 and above. 0x80 corresponds to 0x00, 0x81 corresponds to 0x01, and so on. This effect is called “mirroring”. This will be important later.
Now, look at that LoROM memory map picture again and find that location 0x73:6000 we talked about earlier. Because the offset is below 0x8000, the EPROM output is disabled from the decoder. You’ll see this address is in a lightly shaded box labelled “Static RAM Area”. As it happens, when this specific memory location is accessed, the Static RAM (or SRAM) on the cartridge is being used. In fact, if you look at the entire shaded box, you’ll see that on a cartridge wired in the LoROM PCB type, the SRAM is enabled anytime the SNES accesses banks 0x70 to 0x7D with an offset of 0x0000 to 0x8000. Essentially, the SRAM needs to be enabled whenever the memory in this region is being accessed, which is done by the second decoder in our dual ‘139 package.
Remember the Y0 output from the first decoder? It’s set to 0 whenever CPU A15 is also 0. If we put this Y0 pin on the enable line of the second decoder, we can make this second decoder only allow output whenever CPU A15 is 0. Since the SRAM region in the LoROM memory map is located in a region when CPU A15 is 0 (below offset 0x8000), we can achieve this very effect. So now with the offset taken care of, we have to take into account the bank region. This is where it gets a bit tricky.
First, remember that along with CPU A15, /CART is controlling the output of Y0 as well. Below offset 0x8000, /CART is only active in the banks 0x40 to 0x7D and 0xC0 to 0xFF. Because of the mirroring effect we discussed earlier, we will ignore 0xC0 to 0xFF and focus on 0x40 to 0x7D. Because /CART is disabled in banks above 0x7D, and the SRAM region also stops at 0x7D, we have one boundary already ready to go for enabling the SRAM. Now all we need is to check if the address is above 0x70.
0x70 corresponds to 0b01110000 in binary, or BA4, BA5, and BA6 set to 1 and the rest set to 0. Here, we run into a small issue. We have to check for 3 pins, but we only have 2 inputs available. Check out that memory map again, though. The area next to the SRAM between banks 0x60 and 0x6F is labelled “DSP Area”. Well, hot dog, we’re making simple reproductions that don’t have any extra chips on them! Essentially, because we won’t ever be using the DSP area on our boards, we can treat this memory region as unused. So we can actually ignore BA4, and extend our SRAM region from 0x60 (0b01100000 in binary) to 0x7D. To get our 0x60 boundary, looking at the number in binary, we see that all we need to do is to check if BA5 and BA6 are 1’s. If they are 0’s, the bank will be lower than 0x60. So the second decoder will have these two address lines as inputs, making the Y3 output go low when they are both 1’s. Tie this Y3 to the SRAM /CE line and we’ve got our SRAM memory region covered!
HiROM Memory Map (Mode 21)
Now that we’ve got a grasp on how this memory map works, let’s take a look at the HiROM memory map.
In my opinion, figuring out HiROM is easier than LoROM, at least in terms of setting up the decoder. For starters, look at the ROM area. It’s waaaay off to the left of the map. Why is that?
The ROM area is between banks 0xC0 to 0xFF. This corresponds to the values of BA6 and BA7 being 1. But….. those pins aren’t even connected on the EPROM! How can you prove this to yourself without looking at a board? Well, if each SNES address pin was connected to its corresponding EPROM address pin, BA5 connects to A21 on the EPROM. And A21 is the 22nd address pin. Meaning, we have 2^22 bytes available to work with, or 4,194,304 bytes (4MB, or 32Mbit). That’s exactly the maximum size of (most) SNES games, and the maximum size of the 27C322. And it’s also the size of the area of the ROM area on the memory map!
Now, you might be asking yourself, what about that big ol’ empty space in the middle between banks 0x40 and 0x7D? Isn’t that data going to be accessed too if BA7 and BA6 are 0? Well, maybe. That area is part of the memory where /CART would enable the EPROM, sure, but we’re missing another detail. You may have seen the terms “FastROM” and “SlowROM” thrown around. Generally, you don’t need to bother worrying about the differences between the two unless you’re looking at the actual operation of the board. FastROM is defined as a response time of 120 nanoseconds, and SlowROM is 200 nanoseconds. Apparently, at the start of the SNES life cycle, EPROMs that responded at faster speeds were more expensive. So Nintendo made it so the SNES can operate only at slower speeds in banks below 0x80, restricting the game to operate in a “SlowROM” mode. However, in banks above 0x80, the clock speed of the SNES can be increased in the code to accommodate faster response times from EPROMs, if they had the capability, in a “FastROM” mode.
Since the memory in the upper banks can operate at both fast AND slow speeds, and the memory that would be mirrored in the slower lower banks is also cut off at 0x7D by the WRAM of the SNES, it was probably easier to just define the working ROM area to be in banks above 0xC0.
So what does that mean for us? Well, if you recall the SNES CPU map way up above, remember that the /CART line is LOW in these upper banks. So we don’t have to worry at all about trying to figure out when to enable the EPROM – we just tie the /CART line directly to the EPROM’s /CE pin! Now all that’s left is to figure out how to enable the SRAM properly. The RAM in the HiROM memory map above is specified between offsets 0x6000 to 0x8000, in banks 0x30 to 0x3F.
Let’s start with the offset addresses. 0x8000 and lower requires our good ol’ friend A15 to be 0, since 0x8000 and above means A15 is 1. 0x6 is 0b0110 in binary, which in 0x6000 corresponds to A14 and A13 needing to be 1’s. So, so far, our requirements are that A13 and A14 are 1, and A15 is 0.
As for the banks, 0x40 is the upper bound. 0x40 in binary is 0b01000000, or BA6 as 1. So we need BA6 to stay 0 to keep it below 0x40. 0x30 in binary is 0b00110000, or BA5 and BA4 as 1. Our bank requirements are that BA4 and BA5 are 1, and BA6 is 0. Similar to the offset requirements!
However, this is where we hit a roadblock. We have two decoders to work with. How are we supposed to wire this up with 6 input conditions? I’ll save you the thought experiment – we can’t. Not without extra circuitry. But! Similar to the LoROM SRAM mapping, there’s a way around this problem. The area around the SRAM area in the memory map is blank, meaning it might be ok if we extend our SRAM area a bit. According to the SNES CPU memory map way up above, the area next to bank 0x30, all the way down to 0x00, is part of the “Expansion” region of the memory map. Let’s confine ourselves to this area, instead of extending downwards into the “CPU” and “DMA” region (sounds important!), and extend our SRAM region to some neighboring banks. What if we just ignored BA4? So our only bank requirement was that BA6 was 0, and BA5 was 1? This would extend our SRAM region down to bank 0x20 instead. Perfect!
Now, wiring up the two decoders. Remember, our requirements are A13, A14, and BA5 are 1, while A15 and BA6 are 0. We have six inputs to work with – four “selector” pins, and two enable pins. Enable pins on the decoder are active low, meaning they MUST be 0 in order for the decoder to make any kind of output. Ok, so prime candidate for A15, since we need A15 to be 0. Let’s put the other two A pins on the selectors of this first decoder. When A15 is 0, and A13 and A14 are 1, that makes Y3 on the decoder become 0. Let’s feed that into the second decoder to activate it. Then, we just need BA5 and BA6 on the second selector pins (BA5 on the first input, BA6 on the second input). When BA5 is 1, and BA6 is 0, that makes pin Y1 become 0. Great! Y1, which we can tie to the SRAM /CE pin, will become 0 and activate the SRAM when our criteria is met.
ExHiROM Memory Map (Mode 25)
ExHiROM is basically the same as HiROM, except it’s… well, extended! Expanded? Extra? Whatever. The memory map looks much like how it does for HiROM.
Compare that to the HiROM memory map, and it looks nearly identical, except there are now two program ROM areas called out. One is in the banks 0xC0 to 0xFF, and the second is in banks 0x40 to 0x7D. We also have a tiny sliver between 0x30 and 0x3F, in the offset area above 0x8000. This gives us nearly twice as much space to play with, just shy a bit. This is due to the WRAM restricting the banks 0x7E to 0x7F, and the mirror image of the second ROM area being restricted to offsets above 0x8000. Since that adds a bit of complexity, and because I don’t know of any games that fill up the ENTIRE 63.5 Mbits of space, we’ll narrow our view to ignore the third ROM area called out and stick to 63 Mbits total. But theoretically, this small area can be used for game data.
Because the areas of memory between banks 0x80 and 0xBF (and 0x00 and 0x3F) are restricted to the top half of the offset range, Mode 25 treats these regions as mirror images. BA6 is the line responsible for creating the mirror region of the program ROM area – for example, bank 0xFF (or 0b11111111, where BA6 is a “1”) mirrors to bank 0xBF (0b10111111, where BA6 is “0”). So if we ignore the BA6 line, we don’t have to worry about interfering with the reserved areas below offsets 0x8000 in those lower banks. If you remember, BA6 was also ignored in the HiROM format. But, what about BA7? That’s the exact line we can use to switch between the two program ROM areas.
Since EPROMs typically top out at 32 Mbits (as the 27C322 does), we need to add another EPROM. We can therefore use the BA7 line and a decoder to switch between two separate EPROMs, which is exactly what the MAD-1 chip can do on multi-ROM boards (sometimes with different address lines depending on the board, for boards that have two 16 Mbit Mask ROMs or 8 Mbit Mask ROMs). Along with the existing decoder logic for HiROM creates the ExHiROM memory map – since the SRAM decoder logic doesn’t take into account BA7, we can use the decoder scheme from HiROM without modification.
We want to make sure when BA7 is high, that the first EPROM is activated (since it’s the area in the upper banks, from 0xC0 to 0xFF) and when BA7 is low, the second EPROM is activated (as it’s in the lower banks, from 0x40 to 0x7D, where the banks above 0x7D is cut off for the SNES WRAM).
This post was a compilation of all the information I gathered and surmised in order to create my own SNES PCBs. And all the research and work resulted in this beautiful white SNES board:
The information in this post isn’t necessarily comprehensive of every SNES board, even those without fancy enhancement chips. There are many types of boards that work in the SNES (by matching the memory map), and there are many other ways to create your own cartridge PCB. I just wanted to give a look into how I understand the boards to work, and convey the important bits of information I’ve collected over the past year or so as I’ve worked to design and implement my own boards.
I found a bunch of information on the NesDev forums, and you may even run into some of my own questions and contributions on there. Everyone starts somewhere (I mean, come on, it took me over 2 years to get to this point!), so if you have some more in-depth questions or need better explanations, don’t hesitate to contact me or submit a forum post. Thanks for sticking around til the end of the post, your time reading this means a lot to me!