What the Super Nintendo read its games from.
We start from the very beginning — how a chip of frozen bits can hand a byte to a processor — assuming you know nothing about memory. Once the vocabulary is solid, we crack open a Super Nintendo Game Pak: the mask ROM, the battery-backed save memory, the region lock, and the astonishing little coprocessors — Super FX, SA-1, the DSPs — that games smuggled in on the cartridge itself. Then we follow the ROM into an emulator. Thirteen modules, each with live simulations so you can watch every idea. No game data ships with this page; every ROM you'll see is synthetic, generated in your browser.
Storage from zero
ROM vs RAM, how a chip is addressed, chip-select decoding and bank switching, battery-backed saves, and the cartridge bus — the universal vocabulary, from nothing.
The Game Pak
Inside the shell: the memory map, save RAM & clocks, and the whole zoo of enhancement chips — Super FX, SA-1, DSP-1, S-DD1, SPC7110, CX4.
Emulating in bsnes
The ROM dump, the internal header and the copier header, how an emulator identifies the mapping and re-creates each coprocessor.
Storage from zero
This first part is pure fundamentals — nothing about any specific console yet. It's how every memory chip works: how bits get frozen into a ROM, how a processor picks one byte out of millions by raising address lines, why a small CPU can still reach a big ROM, and how a save survives with the power off. We build the vocabulary one word at a time — ROM, RAM, address line, chip-select, bank, SRAM, bus — and you can watch each idea run live. If a term is ever used before it's explained, that's a bug. Everything in Parts II and III is just these four ideas wired together.
ROM vs RAM
A Super Nintendo game is not a program that gets "installed." It is a chip. Snap a Game Pak apart and the largest object on the little green board is a single black rectangle: the game's mask ROM. ROM stands for read-only memory, and mask tells you when the bits were decided: at the semiconductor factory, the 1s and 0s are etched into the silicon by one of the photographic masks used to pattern the chip. From that moment the data is frozen. The console can read the ROM a billion times, but it can never write to it — there is physically nothing to write with.
That permanence is the whole point. A mask ROM is non-volatile: unplug the console, leave the cartridge in a drawer for thirty years, and every bit is exactly where the factory put it. Contrast that with the console's own working memory. Inside the Super Nintendo sits 128 KB of RAM (random-access memory), the scratch pad where the running game keeps its variables. RAM is fast and freely writable, but it is volatile: the instant power drops, it forgets everything. ROM remembers forever and never changes; RAM changes constantly and remembers nothing. A game needs both.
A mask ROM is a printed book: the words were set in type once at the press, and no reader can rewrite them — but they'll still be there next century. The console's RAM is the notepad beside you: you scribble and erase freely while reading, but close the book and the notepad is wiped clean. The game is the book; playing it is the scribbling.
How a ROM turns an address into a byte
Here's the mechanism, and it is beautifully simple. A ROM has two bundles of wires. One bundle carries the address — a number, presented as a pattern of high and low voltages, one wire per bit. These are the address lines, named A0, A1, A2 and up. The other bundle is the data lines — D0 through D7 — which the chip drives as its output. Put a number on the address lines and, a few dozen nanoseconds later, the byte stored at that location appears on the data lines. That's the entire contract: address in, data out.
The count of address lines sets how much the chip can hold. Each line doubles the reach: n address lines address 2n locations. Eight lines reach 256 bytes; sixteen reach 64 KB; twenty-one reach 2 MB. Inside, those lines feed a decoder that lights up exactly one row of storage cells and switches its bits onto the data lines. No moving parts, no seeking, no waiting for a disc to spin around — every byte is equally, instantly reachable. That's what "random access" means.
How to read the numbers on this page. A leading
$ means a number is written in
hexadecimal
(base 16, digits 0–9 then A–F); a leading % means
binary (base 2). They're just different spellings of the same
value. One worked example: $42 is 4×16 + 2
= 66 in everyday decimal, which in binary is
%0100 0010. And a byte is 8 bits —
eight binary digits, one value from 0 to 255, exactly two hex
digits. That's why the data lines come in a bundle of eight.
The lab below is that mechanism made visible. Drive the address with the slider and watch the addressed cell light up in a 256-byte mask ROM, its stored byte appearing bit-for-bit on the data lines. The contents never change no matter how many times you read them — that is what "read-only" and "non-volatile" feel like in motion.
- A Game Pak's main content is a mask ROM: bits fixed at the fab, read-only and non-volatile (kept with no power).
- The console's own 128 KB of RAM is the opposite: freely writable but volatile — it forgets everything when power drops.
- A ROM's job is a contract: put an address on the address lines, get that location's byte on the data lines.
- n address lines reach 2ⁿ locations; access is instant and uniform — "random access."
Address decoding & bank switching
Module 01 had a ROM alone on its wires. A real console is a
crowd: the same address and data lines are shared by the work RAM,
the picture and sound chips' registers, and the cartridge. If two of
them tried to drive the data lines at once, you'd get a garbage
collision. So something must decide, for every single access,
which device is allowed to answer. That job is
address decoding, and its output is a set of
chip-select
signals — one per device, and never more than one active at a time.
One notation note before we go on: signal names written with a
leading slash, like /CS or /CART, are
active-low — the wire idles at a high voltage and
is pulled low to mean "yes, now." The slash is the
engineer's reminder that low is the active state.
The decoder is just logic watching the top address lines.
The low lines pick a byte within a device; the high lines
pick which device. On the Super Nintendo's processor —
a chip called the
65816
— a memory access carries a 24-bit address split into an 8-bit
bank
number and a 16-bit offset within that bank. Written out, an
address like $03:9C40 splits at the colon: bank
$03 (the top 8 bits) and offset $9C40
(the low 16 bits) within that bank. Inside the ordinary
"system" banks, the offset alone tells the decoder everything: low
addresses map to work RAM, a middle window to the console's
registers, and the top half of the bank ($8000–$FFFF)
to the cartridge — that's the /CART select the Game Pak
listens for.
A 24-bit address is a mailing address for a byte. The bank is the building number; the 16-bit offset is the apartment. The mail carrier (the decoder) reads the building number to pick the right building — that's the chip-select — and only then walks to the specific apartment. No two buildings share a number, so mail never lands in two places at once.
Bank switching: reaching more than you can address
Now the twist that makes cartridges interesting. A humble 8-bit CPU with only 16 address lines can point at just 64 KB — but games were far bigger. The classic fix, older than the SNES, is bank switching: the CPU's small window looks onto a big memory through a hatch, and a latch decides which slice of the big memory the hatch currently shows. Change the latch and a different 32 KB of ROM appears at the same addresses. The Super Nintendo's 65816 is more generous — its 24 address lines natively reach 16 MB, so it rarely needs crude bank switching — but the same idea returns in Part II as the whole basis of the LoROM and HiROM memory maps, and enhancement chips like the SA-1 lean on a bank-switching unit to give themselves a bigger reach.
The lab lets you sweep an address across one 64 KB bank and watch the chip-selects fire. Notice how the top three address lines alone decide the region — and that in these system banks the cartridge ROM only answers in the upper half. That upper-half-only picture is exactly what the LoROM map (Module 06) is built on; HiROM cartridges also claim other banks outright, as Module 06 shows.
- Many devices share one set of address/data lines; a decoder issues one chip-select at a time so only one answers.
- Low address lines pick a byte within a device; high lines pick which device — that's all "decoding" is.
- On the SNES a 24-bit address = an 8-bit bank + a 16-bit offset; the cartridge answers in the top half of system banks.
- Bank switching maps a big memory into a small window a slice at a time — the seed of the LoROM/HiROM maps in Part II.
Saving without a disk
The mask ROM can't be written, and the console's work RAM forgets on power-off. So where does a saved game go? On the Super Nintendo the answer lives on the cartridge, and it is delightfully low-tech: a small static RAM chip with a battery wired to keep it awake. SRAM is ordinary read/write memory — volatile like any RAM — but it draws almost nothing to hold a value once written. The "static" is the point: the dynamic RAM in bigger computers forgets its bits within milliseconds unless the machine constantly refreshes them, while a static cell holds its bit for as long as any power at all reaches it. Pair it with a 3-volt lithium coin cell soldered onto the board, and the SRAM stays powered even when the console is unplugged. The save persists not because the memory is non-volatile, but because you never actually turn it off.
When you play, the console powers the SRAM and the game reads and
writes it like any other RAM — through its own chip-select window
(Module 02), using the /WR strobe. When you switch the
console off, a little steering circuit disconnects the SRAM from the
dead console supply and connects it to the coin cell instead, which
trickles just enough current to preserve the bits. Because the draw
is tiny, a single cell can keep a save alive for
years — often a decade or more.
Volatile memory is a room lit only while the mains are on: cut the power and the room goes dark, and whatever was written on the whiteboard is "forgotten" (the chip can't hold its state). Battery SRAM is that same room with a tiny battery-powered night-light that never goes out. Nothing on the whiteboard is special — it just never gets dark enough to lose it. When the battery finally dies, the light goes out and, one day, so does the save.
The lab makes the difference tangible. Write a save into both a battery-backed SRAM and the volatile work RAM, then hit Power off: the SRAM holds its bytes while the work RAM settles into meaningless garbage. This exact behaviour — and the slow death of an aging coin cell — is why old cartridges eventually "lose their saves."
- Saves can't go in the ROM (read-only) or the console's RAM (volatile), so they go in on-cart SRAM.
- SRAM is ordinary volatile memory, but a soldered 3 V coin cell keeps it powered so the save persists with the console off.
- The game reads/writes SRAM through its own chip-select window using the /WR strobe, like any RAM.
- A dying battery is why decades-old cartridges eventually lose their saved games.
The cartridge bus
Turn a Game Pak over and you see a row of gold contacts — the edge connector. Here is the crucial thing to internalise, because the whole second half of this course flows from it: those contacts are essentially the 65816's own address and data bus, brought straight out to the slot, plus a handful of control, clock and expansion pins. When you insert a cartridge, you are not attaching a passive data store off in the distance — you are wiring new chips directly onto the processor's bus, where they can watch every address the CPU emits and answer it in real time.
Walk the pins. There are 24 bits' worth of address —
the sixteen offset lines A0–A15 plus eight bank-address
lines (BA0–BA7) that carry the bank byte — enough to name any byte
in the 16 MB space. There are 8 data lines
(D0–D7): the SNES moves one byte at a time, and the lines are
bidirectional — the same eight wires carry a byte out of
the cartridge on a read and into it on a write. There are the read
and write strobes
(/RD, /WR) — a strobe is a brief timing
pulse that says now — telling the cartridge when and
which direction an access goes; the cartridge chip-select
(/CART) from Module 02; the CPU clock (φ2,
"phi-two" — the steady tick every bus access is timed against)
so on-cart chips stay in step; a DRAM /REFRESH pulse;
/RESET and /IRQ; audio lines routed through
the connector; power and ground; and a few
expansion
pins. That last group is the open door.
Most consoles treat the cartridge slot like a mail slot: you post data in and it trickles to the CPU. The Super Nintendo instead pulls a chair up to the CPU's own desk and hands whoever sits there the same address book and the same in/out trays the processor uses. A plain ROM just reads from the trays. But nothing stops a far cleverer guest — a whole second processor — from taking that seat. That is precisely what the enhancement chips did.
Why does this matter so much? Because a cartridge that can see the CPU bus directly can contain active hardware that participates in the machine — memory that decodes its own accesses, or a coprocessor that the CPU can hand work to and read results back from through ordinary reads and writes. The connector isn't a loading dock; it's an expansion port. Hold that thought: Module 08 opens it fully, and Modules 09–12 meet the chips that walked through it.
The lab is a pin-by-pin explorer. Hover any contact on the edge connector to see what it carries and why it's there — the address and data lines you already know, the strobes and clocks, and the spare expansion pins. (Remember though: the real superpower isn't any one special pin — it's that the bus itself is here at all.)
- The Game Pak edge connector is the 65816's own address/data bus, plus control, clock, audio and expansion pins.
- A0–A15 plus the bank-byte pins BA0–BA7 give 24 address bits (16 MB); 8 data lines (D0–D7) move one byte per access; /RD, /WR, /CART, φ2 govern timing and selection.
- Because chips on the cartridge see the CPU bus directly, they can be active participants, not just passive storage.
- What made enhancement chips possible is the ordinary address/data bus itself being exposed at the slot — that, more than any special expansion pin, turned the connector into an expansion port.
The Game Pak
Now we put the Part I toolkit into a real cartridge. We open the shell to name every part, learn the two ways a ROM projects itself into the CPU's address space (LoROM and HiROM), see where saves and clocks live, and then spend five modules with the reason SNES cartridges are legendary among hardware people: the enhancement chips. Because the connector exposes the CPU bus, cartridges could smuggle in accelerators, second CPUs, math units and decompressors. We'll meet the Super FX, the SA-1, the DSP family, and the exotic compression chips — real names, real clocks, real games.
Inside a Game Pak
Crack the shell and the board is refreshingly legible. At minimum a Game Pak holds exactly one thing: a mask ROM (Module 01), 4 to 48 megabits of frozen game, its data lines wired to the connector. Many carts add a save SRAM and its coin cell (Module 03). Some add an enhancement chip — the star of the coming modules. And nearly every licensed cartridge carries one more, easy-to-miss part: a slim 16- or 18-pin chip (the F411/F413 family — a tiny 4-bit microcontroller) called the CIC.
The CIC (Checking Integrated Circuit) is the authentication — and,
between TV standards, the region — lock. A matching CIC sits in the
console, and from power-on the two run in lockstep, each generating
the same seeded stream of bits continuously while the console side
keeps comparing. If the cartridge CIC is missing, wrong, or ever
disagrees, the console's CIC yanks /RESET low and holds
the machine in a reset loop — the classic blinking, never-booting
console. The CIC's keys differ between the NTSC and PAL worlds, so
it is what stops, say, a European cartridge booting on an American
console. The US–Japan divide is a different story: an American SNES
and a Japanese
Super Famicom
use the same NTSC CIC, and a Japanese cartridge board passes
lockout in a US console perfectly. The only barrier between those two
regions is the plastic: the US SNES pak is boxy with locking tabs,
the Super Famicom pak rounded, with different cartridge-slot
notches so the wrong shape won't even fit the slot.
The lab is an interactive board. Click each component to learn its role — mask ROM, save SRAM, coin cell, enhancement chip, CIC lockout, and the edge connector that ties them to the bus.
- The one guaranteed part is the mask ROM (4–48 Mbit); SRAM+battery and an enhancement chip are optional additions.
- The CIC lockout runs a continuous seeded stream in lockstep with a twin in the console; any mismatch holds the machine in reset — authentication, and (between TV standards) the region lock.
- US and Japanese machines share the same NTSC CIC — a Japanese cart passes lockout in a US console. That barrier is purely shell shape and slot notches; the CIC's differing keys separate NTSC from PAL.
- Everything on the board communicates through the edge connector's exposed CPU bus.
The memory map: LoROM vs HiROM
A ROM chip stores its bytes at offsets 0, 1, 2, 3… but the CPU never asks for "offset 12345." It emits 24-bit addresses, and the cartridge's wiring decides how those addresses land on the ROM's own address lines. There are two dominant wiring conventions, and every game picks one. They're called LoROM and HiROM.
LoROM maps 32 KB of ROM into the
upper half of each bank ($8000–$FFFF), leaving
the lower half of the system banks free for RAM and registers — the
layout from Module 02. Each successive 32 KB slab of the ROM file
appears in the next bank. HiROM instead uses the
whole 64 KB of a bank for ROM
($0000–$FFFF), with the ROM appearing in banks
$C0–$FF and in banks $40–$7D, so
each bank holds twice as much and big contiguous data (like sampled
audio or long tables) doesn't get chopped every 32 KB. Both maps
also
mirror
the ROM into other bank ranges, and both reserve a spot for save SRAM
(Module 07).
Two things make the rest of this module painless. First, the worked
conversion, once, by hand: take file offset $018000 in
a LoROM cart. Divide by $8000 (32 KB): the
quotient is 3, the remainder is 0 — so the byte lands in bank
$03 at address $8000 + 0. File
offset $018000 → CPU address $03:8000.
Every LoROM conversion is that one division. Second, the word
mirror, properly: a mirror is not a copy —
it is the same physical bytes answering at more than one
address, because the decoder ignores some high address bits. The
biggest mirror of all: banks $80–$FF repeat (almost)
the whole $00–$7D picture — that's the image FastROM
uses below, and it's why the lab's default CPU address
$C0:8000 works under LoROM at all: bank $C0
is the fast mirror of bank $40. The one exception is
banks $7E–$7F, which the console's work RAM claims
outright — no cartridge ROM ever appears there (their would-be
mirrors $FE–$FF stay ROM). And why does HiROM start at
$C0? Because the low banks' upper halves are already
spoken for by the system layout, $C0–$FF is the first
clean stretch where a cartridge can own every byte of every bank.
$7E–$7F are the console's WRAM and banks $80+ are the fast mirror.FastROM: the same map, sped up
One orthogonal knob: FastROM.
The 65816 can read the cartridge at two speeds. In the lower bank
image the CPU runs its slow 2.68 MHz memory cycle; in the
$80–$FF image, if the game sets a speed bit, the same ROM
is read at 3.58 MHz. FastROM isn't a different layout — it's the
same LoROM or HiROM ROM, addressed through the high-bank
mirror with the fast timing enabled. Games that wanted the extra
headroom simply ran their code from the $80+ image.
The lab is a two-way translator. Pick LoROM or HiROM, type a ROM-file offset to see the CPU address it appears at, or type a CPU address to see which file offset it reads — the exact conversion an emulator or a debugger does thousands of times a second.
—
- LoROM maps 32 KB of ROM into $8000–$FFFF of each bank; HiROM uses full 64 KB banks — in $40–$7D as well as $C0–$FF — for bigger contiguous data.
- Convert LoROM: bank = offset÷$8000, addr = $8000+(offset mod $8000) — e.g. $018000 → $03:8000. HiROM: bank = $C0+(offset÷$10000), addr = offset mod $10000.
- A mirror is the same physical bytes at multiple addresses; banks $80–$FF repeat the $00–$7D picture (except $7E–$7F, which are always WRAM). Both maps reserve an SRAM window.
- FastROM is not a different map — it's the same ROM read at 3.58 MHz through the $80–$FF bank image with a speed bit set.
Save RAM & the real-time clock
Module 03 explained why saves live in battery-backed SRAM;
now the specifics. Save SRAM on the Super Nintendo ranged from
16 Kbit (2 KB — a few save slots) up to
256 Kbit (32 KB) in the most save-hungry
RPGs. The size is declared in the ROM header (Module 13) as a
power-of-two count of kilobytes — which is also why nothing smaller
than 2 KB ever shipped: the header's code can't even express
less than a kilobyte. Where that SRAM appears in the address space
depends on the map: in LoROM it typically sits in
banks $70–$7D at $0000–$7FFF; in
HiROM it lives in banks $20–$3F at
$6000–$7FFF, mirrored again in banks
$A0–$BF. Either way it's the /SRAM
chip-select window you decoded in Module 02.
A handful of games wanted more than persistent bytes — they wanted to know what time it is, even while switched off. For that, a few cartridges carried a real-time clock. Nintendo's S-RTC appeared in games like Daikaijuu Monogatari II, keeping date and time ticking off the same kind of coin cell that preserves a save. The SPC7110 (Module 12) also bundled a clock alongside its compression hardware. These are rare — most carts have no sense of time at all — but they show how far the "active cartridge" idea stretched: a Game Pak could quietly count the days in your drawer.
Battery SRAM is a diary the coin cell keeps from fading. An RTC cartridge glues a running wristwatch into that same diary: the battery not only preserves what you wrote, it keeps the second hand moving while the book is shut — so when you open it again, it knows how long you were gone.
| SRAM size | Bytes | Typical use |
|---|---|---|
| 16 Kbit | 2 KB | a few save slots |
| 64 Kbit | 8 KB | action-RPG saves |
| 128 Kbit | 16 KB | bigger RPGs, track/edit data |
| 256 Kbit | 32 KB | large multi-slot RPGs |
The lab lets you pick an SRAM size and a memory map and see exactly where the save window lands in the address space — then toggle an RTC on and watch a live clock the way an S-RTC cartridge would keep it.
- Save SRAM ranged from 16 Kbit (2 KB) to 256 Kbit (32 KB); the size is declared in the ROM header as a power-of-two count of KB.
- LoROM puts SRAM around banks $70–$7D; HiROM around banks $20–$3F (mirrored at $A0–$BF) at $6000–$7FFF — the /SRAM window.
- A few cartridges added a battery-backed real-time clock: Nintendo's S-RTC, and the SPC7110's built-in clock.
- The same coin cell that preserves a save can keep an RTC ticking while the console is off.
The expansion bus: enhancement chips
Here is the payoff of Module 04. Because the connector exposes the CPU bus, a cartridge is not limited to storing a game — it can upgrade the console. The Super Nintendo shipped in 1990 with a capable-but-aging CPU, and rather than let that ceiling define the library, developers put the extra silicon they needed on the cartridge, where the CPU could reach it as plainly as it reaches RAM. Every SNES enhancement chip is a guest that took the chair Module 04 pulled up to the CPU's desk.
They fall into a few families, and the rest of Part II takes each in turn:
- Accelerators / coprocessors. Whole processors that do heavy lifting the CPU can't — the Super FX (GSU) and the SA-1 (Modules 09–10).
- Math / DSP chips. Fixed-point number crunchers that feed Mode-7 and 3D projection — the NEC DSP-1 family and Capcom's CX4 (Module 11).
- Compression / data chips. Real-time decompressors that let a small ROM hold more apparent art — the S-DD1 and the SPC7110 (Module 12).
- Helpers & oddities. Small special-purpose parts like the OBC1 sprite helper and the stand-alone S-RTC clock.
The lab is that catalog, live. Filter by family, and sort by chip name or clock speed — a bird's-eye view before the deep dives.
| Chip ▲ | Family | Clock | What it did | Notable games |
|---|
- The exposed CPU bus turned the cartridge slot into an expansion port: cartridges could upgrade the console itself.
- Enhancement chips group into accelerators (Super FX, SA-1), math/DSP (DSP-1…4, CX4), compression (S-DD1, SPC7110), and small helpers.
- The CPU reaches all of them through ordinary reads and writes to their cartridge address windows.
- The next four modules take one family (and its flagship games) at a time.
The Super FX
The Super FX is the chip that put a spaceship-shaped hole in everyone's expectations. Its core, the GSU (Graphics Support Unit), is a genuine RISC processor with its own instruction set, running at about 10.7 MHz in the original revision (the later GSU-2 in Yoshi's Island and Doom effectively ran work through at roughly double that). It isn't a helper the CPU pokes occasionally; it's a co-equal processor that takes over the drawing.
Its trick is a plot instruction: dedicated hardware that writes one pixel into a framebuffer held in the cartridge's own RAM, doing the fiddly bitplane math the SNES's tile-based picture unit makes painful (in that native format each tile's pixels are sliced into bit-layers — the format Part II of the graphics course walks through). The GSU runs a program that transforms and rasterises 3D geometry, plotting it pixel-by-pixel into that cart-RAM framebuffer. When a frame is finished, the main CPU copies the rendered image into the console's video memory — usually with a DMA burst — and shows it; the picture unit cannot read cart RAM itself, so the finished frame always makes that hop. That division of labour — GSU draws into cart RAM, CPU ferries the result to the screen — is how Star Fox's polygon fighters, Stunt Race FX's cars and Yoshi's Island's stretchy effects existed on a machine with no 3D hardware of its own.
One constraint defines Super FX programming, and it answers the
question you should be itching to ask: two processors, one ROM —
who gets the bus? The answer is not both at once. Control
bits (called RON and RAN) hand ownership
of the cartridge ROM and RAM to the GSU while it renders, and during
that time the main CPU is locked out of the cartridge entirely — an
access there won't reach the real chips. So Super FX games copy
their 65816 code into the console's work RAM and run from
there while the GSU owns the cart, waiting for the chip to
signal it's finished and hand the bus back. Two drivers, one
steering wheel, taking strict turns — and it's why the main CPU's
role in these games is mostly to direct traffic.
Picture the CPU as a director who can't draw. Bolted into the cartridge is a fast sketch artist — the GSU — with a private sketch pad (the cart-RAM framebuffer). The director shouts the scene; the artist draws it dot by dot on the pad; then the director simply holds the finished pad up to the audience. The console never learned to draw polygons — it learned to display someone else's drawing.
The lab is a miniature GSU. Watch it plot a rotating wireframe object into a small framebuffer one pixel at a time — the plot cursor sweeping each edge — then "hand off" the finished frame before rotating and starting again. Switch between a Rev-1 and a faster Rev-2 plot rate and see the frame build quicker.
- The Super FX's core is the GSU, a real RISC processor (~10.7 MHz; Rev 2 roughly double) living on the cartridge.
- Its plot hardware writes pixels into a framebuffer in cart RAM, doing the SNES's painful bitplane math in hardware.
- The GSU renders whole 3D/polygon scenes; the main CPU DMA-copies the finished framebuffer to video RAM — the picture unit can't read cart RAM.
- While the GSU renders it owns the cart ROM/RAM (the RON/RAN bits); the locked-out main CPU runs from work RAM until handback — the defining Super FX constraint.
- Star Fox, Stunt Race FX and Yoshi's Island are the Super FX in action.
The SA-1
Where the Super FX was an exotic RISC drawing engine, the SA-1 took a blunter, arguably smarter route: it put a second copy of the console's own CPU on the cartridge — a 65816, the same architecture as the SNES's — but clocked at roughly 10.7 MHz, about three times the main CPU's typical speed, and paired with its own fast on-cart RAM. Because it speaks the same instruction set, developers already knew how to program it; they simply handed it the heaviest work.
That work was rarely polygons. The SA-1 shone at logic: game AI, physics, the bookkeeping of a big turn-based battle, and fast graphics decompression — unpacking compressed art into RAM far quicker than the main CPU could. Super Mario RPG leaned on it, and the Kirby titles (Kirby Super Star, Kirby's Dream Land 3) used its muscle to keep dense action moving. Beyond raw clock speed the SA-1 also included conveniences — a fast built-in multiplier and divider, a bank-switching memory controller, and its own DMA — so a lot of small operations that were slow on the base CPU became cheap.
Imagine you could hire an assistant who is you — same skills, same habits, nothing new to teach — but who thinks three times as fast and has their own tidy desk. You'd offload your busywork instantly, because there's no translation cost. The SA-1 was exactly that: the SNES's CPU again, quicker, right there in the cartridge.
The lab races the same workload on both processors: the main CPU at its ~3.58 MHz against the SA-1 at ~10.7 MHz. Press Run and watch the SA-1's bar pull decisively ahead — roughly the throughput multiple that let these games do more per frame.
- The SA-1 is a second 65816 — the console's own CPU architecture — on the cartridge, clocked ~10.7 MHz with its own fast RAM.
- It targeted logic, AI and graphics decompression rather than polygon drawing.
- Built-in fast multiply/divide, DMA and a memory controller made many small operations cheap.
- Super Mario RPG, Kirby Super Star and Kirby's Dream Land 3 are showcases.
The DSP & math chips
Not every problem needs a whole second CPU — sometimes you just need arithmetic the base processor is bad at. The 65816 has no fast floating-point and only modest multiply support, yet 3D and perspective effects are drowning in multiplications: to rotate and project a point you multiply it by a matrix, over and over, thousands of times a frame. The answer was a DSP: a chip built to do exactly that repetitive fixed-point math at speed.
"Fixed-point" is worth thirty seconds. The chip stores only whole numbers, and everyone simply agrees that a stored value really means "this ÷ 256." So 1.5 is stored as 384 (because 384 ÷ 256 = 1.5), and doubling it gives 768 — which reads back as 3.0. All the speed of integer hardware, most of the usefulness of fractions; the decimal point never moves because it's imaginary, "fixed" at an agreed position.
The workhorse was the NEC µPD77C25 family, whose most common configuration on SNES cartridges was the DSP-1. It appeared in Pilotwings, Super Mario Kart and many others, doing the matrix, vector and trigonometric calculations that drove Mode 7 perspective and 3D projection — the CPU fed it coordinates and read back screen positions. Variants followed (DSP-2, DSP-3, DSP-4) for other games' needs, and later NEC-core parts (the ST010/ST011) pushed the same idea further. Capcom rolled its own math chip, the CX4, to do trig and wireframe transforms for the vector effects in Mega Man X2 and X3.
The 65816 doing 3D math by hand is a clerk multiplying long numbers on paper — accurate but slow. The DSP is a calculator on the clerk's desk: hand it the matrix and the point, and the answer comes back before the clerk could have written the first partial product. The clerk still runs the office; the calculator just makes the numbers instant.
The lab is a DSP-1 in spirit: it takes a set of 3D points and projects them to 2D through a fixed-point rotation matrix — the same kind of transform the chip performed — and shows you both the spinning result and the live matrix values feeding it. Drag the sliders to steer, and watch the matrix change.
- 3D and perspective are dominated by repeated fixed-point multiplies — work the 65816 is slow at.
- The NEC µPD77C25 (as DSP-1) did the matrix/vector/trig math for Mode 7 and 3D in Pilotwings, Super Mario Kart and more.
- DSP-2/3/4 and later NEC parts handled other games' math; Capcom's CX4 did trig/wireframe for Mega Man X2/X3.
- The CPU feeds coordinates and reads back projected results — the DSP is a calculator bolted to the bus.
Exotic chips: compression & more
ROM was expensive, and by the mid-90s games wanted more art than a reasonably-priced ROM could hold. One answer, seen in the SA-1 games, was to compress the art and unpack it on load. But a couple of cartridges went further and decompressed graphics in real time, as the console demanded them — so the ROM only ever stored the squeezed version, and the full-size art existed only for the instant it was needed.
The star is the S-DD1, used in Star Ocean and Street Fighter Alpha 2: games so art-heavy they'd have needed implausibly large ROMs uncompressed. The SPC7110 did a similar decompression job and, as noted in Module 07, bundled a real-time clock. Rounding out the zoo: Capcom's CX4 (trig/wireframe, from Module 11), the OBC1 sprite helper (which shipped in exactly one game, Metal Combat: Falcon's Revenge), and a long tail of one-off and licensed parts. The common thread is the same as ever: because the chip sits on the CPU bus, the console fetches "graphics" and the cartridge quietly manufactures them.
The warm-up idea behind all compression fits in one line:
AAAABBB squeezes down to "4×A, 3×B" — say what
repeats instead of repeating it. The lab below is that idea
grown up: a short stream of compression tokens — literals and
back-references, the bones of any LZ/RLE scheme — is unpacked "on
the cart" into a small graphic, byte-by-byte, so you can watch a
tiny compressed input bloom into a full tile and see the ratio it
bought. One honest footnote: the real S-DD1's scheme is not LZ at
all — it is a bitplane-aware entropy coder (Golomb-style
codes, driven by per-bitplane probability estimates). The lab shows
the simpler LZ idea, in the same store-less-expand-on-demand
spirit.
- Some cartridges decompressed graphics in real time so the ROM only stored the compressed version.
- The S-DD1 (Star Ocean, SF Alpha 2) is the flagship real-time decompressor — in silicon it's a bitplane-aware entropy coder; the SPC7110 combined compression with an RTC.
- Capcom's CX4 (trig/wireframe) and the OBC1 sprite helper (one game: Metal Combat: Falcon's Revenge) round out the family, alongside many one-off parts.
- As always, it works because the chip sits on the CPU bus: the console reads "graphics," the cartridge makes them.
Emulating in bsnes
Every cartridge in this course now lives, for most people, as a file: a ROM image read by an emulator. The final module follows the Game Pak into software — the dump, the internal header that names the game and declares its mapping and chips, the pesky 512-byte copier header, and how a cycle-accurate emulator like bsnes identifies the mapping and re-creates each coprocessor. One module, one lab, and a callback to where we began.
ROM images, headers & co-processors
A ROM image
is just the mask ROM's bytes in a file — a
dump.
But a bare pile of bytes doesn't say whether it's LoROM or HiROM,
whether there's a Super FX or an SA-1 aboard, or how big the save
is. Almost all of that is answered by a small
internal header —
and reading it needs this module's one big idea: there are
two rulers for measuring the same bytes. One ruler
is file offsets: 0, 1, 2… from the start of the dump. The
other is CPU addresses: where those bytes land once the
Module 06 mapping is applied. On the CPU ruler the header always
sits in the same place — $00:FFB0–$FFDF, just below
the 65816's interrupt and reset vectors at
$FFE0–$FFFF — under both maps. On the file
ruler it lands at different offsets:
$7FB0–$7FDF in a LoROM file (that CPU range is the top
of the first 32 KB slab) and $FFB0–$FFDF in a
HiROM file (the top of the first full 64 KB bank) — plus 512
more if a copier header is stuck on the front. And one honesty
note: the console itself never "reads the header" — at power-on it
fetches just the reset vector at $FFFC and starts
executing. The header is a convention parsed by humans, tools and
emulators.
$00:FFB0–$FFDF, just below the interrupt vectors. On the file ruler it lands wherever the map's arithmetic puts it: $7FB0 in a LoROM dump, $FFB0 in a HiROM dump, +512 if an SMC header is present. That's why an emulator probes both places and lets the checksum arbitrate.
Walk the key bytes — quoted as CPU addresses from here on (subtract
$8000 for the LoROM file offset). At $FFC0 is the 21-character
title. At $FFD5 the
map mode
byte (e.g. $20 LoROM, $21 HiROM,
$23 for an SA-1 layout; bit 4 flags FastROM). At
$FFD6 the chipset
byte, whose nibbles say whether there's RAM, a battery and which
coprocessor. Then ROM size ($FFD7) and
RAM size ($FFD8) as power-of-two codes,
the region ($FFD9, which also implies
NTSC vs PAL), and a checksum at $FFDE
with its complement at $FFDC — the two should XOR to
$FFFF, a quick sanity check the emulator uses to help
locate the header in the first place.
One wrinkle from the dumping era: some files carry an extra
SMC/copier header,
512 bytes bolted onto the very front by old backup devices. It shifts
every offset by $200, so an emulator detects it simply —
if the file size divided by 32 KB leaves a remainder of 512,
there's a copier header to skip. To decide LoROM vs HiROM and spot
coprocessors, bsnes uses a mix of a
manifest/database
and header heuristics — the internal header is a good hint, but real
dumps have enough quirks that a known-good database is the trustworthy
source. Then it emulates each coprocessor: the Super FX and SA-1
as full CPU cores, the DSP-1 by running its actual microcode, each with
careful cycle timing so the game can't tell it left the cartridge.
The lab is a header parser. Load one of several sample cartridges — each with a realistic map/chipset/size/region — and watch it decode into readable fields, with the raw header bytes shown and the map/chipset/size bytes highlighted. Toggle a copier header on to see the note appear.
- A ROM image is the mask ROM's bytes; its internal header (CPU $00:FFB0–$FFDF — file offset $7FB0 LoROM / $FFB0 HiROM) declares title, map mode, chipset, ROM/RAM sizes, region and checksum. The console itself only fetches the reset vector ($FFFC); tools and emulators parse the header.
- The map byte picks LoROM/HiROM/FastROM; the chipset byte's nibbles reveal RAM, battery and which coprocessor — DSP, GSU, SA-1, S-DD1…
- A 512-byte SMC/copier header shifts every offset by $200; detect it from a file-size remainder and skip it. bsnes leans on a database plus heuristics.
- And it all closes the loop on Module 01: an emulator's whole job is to answer "address in, data out" for this ROM — and now to be a Super FX, an SA-1 or a DSP-1 exactly when the header says so.