How the Super Nintendo thought.
We start from the very beginning — what a processor even is — assuming you know nothing about computer architecture. Once the vocabulary is solid, we meet the Ricoh 5A22: a 16-bit 65816 core wrapped in Nintendo's own DMA, HDMA and math hardware. We finish inside bsnes, where a single master clock keeps the whole console honest. Fifteen modules, with ten live, clickable machines along the way so you can watch every idea run, not just read about it. No game code ships with this page; every simulation is built in your browser.
How CPUs work
Instructions, registers, binary and two's complement, addressing modes, the stack, interrupts and clocks — the universal vocabulary of processors, explained from zero.
The 5A22
The chip itself: the 8/16-bit M & X flags, the 24-bit banked address space, DMA and HDMA, and the hardware multiply/divide unit.
Emulating in bsnes
How a single shared clock runs the CPU, the accuracy traps that make it hard, and the debuggers where you can see it all.
How CPUs work
This first part is pure fundamentals — nothing about any specific console or chip yet. It's the toolkit every processor is built from, whether that's your phone, your laptop, or the chip we'll meet in Part II. We build the vocabulary one word at a time — instruction, register, addressing mode, stack, interrupt — and you can step and run each idea in a tiny simulated machine. If a term is ever used before it's explained, that's a bug; tell us. Everything in Parts II and III is just these six ideas wired together.
The fetch–decode–execute loop
Let's start with what a processor physically is. Strip away the marketing and a CPU is a machine that repeats one tiny ritual, millions of times per second, without ever getting bored. The ritual has three steps: fetch a number from memory, decode it — work out what command that number stands for — and execute it. Then do the next one. That's the whole job. Everything a Super Nintendo ever did — every Mode 7 castle, every Chrono Trigger battle, every pixel — is that loop, running fast. What sets the relentless pace is a clock — a steady electrical pulse, a metronome inside the chip; each tick lets the machine take its next tiny step. Module 06 puts real numbers on it.
Two words in that ritual need unpacking. Memory is
a long row of numbered pigeonholes, each holding one small number (a
byte).
The pigeonhole's position in the row is its
address — cell 0, cell 1, cell 2, and so on. And an
instruction is just one of those stored numbers
that the CPU has agreed to treat as a command. There is nothing
special about the number itself: $A9 (the $
just marks a number written in hexadecimal, base 16 — Module 03
unpacks that notation) sitting in memory might mean “load the
accumulator” to the processor, or it
might just be the number 169 in someone's data. Position and
convention decide, nothing else. Programs and data live in the same
memory, side by side — this is the single most important idea in
all of computing, and (in Module 14) it's also what makes emulators
sweat.
So how does the CPU know which cell holds its next command? It keeps a bookmark: a counter called the program counter (PC). Each trip round the loop it fetches the instruction the PC points at, then bumps the PC forward so the next trip fetches the next cell. The exception is a branch or jump: an instruction whose whole job is to overwrite the PC with a new address, so execution leaps somewhere else. Branches are how programs make decisions and loops.
Picture a cook working from a stack of numbered recipe cards, one short command per card: “fetch the flour”, “add two eggs”, “go back to card 3”. The cook keeps a finger on the current card — that finger is the program counter. Read a card, do what it says, slide the finger to the next card. The cook never sees the “whole recipe”; only ever one card at a time. A CPU is exactly this cook — just one who reads a couple of million cards a second and never misreads one.
$A9, $6D, $8D, $4C — are the real 65816 codes for LDA, ADC, STA and JMP.A worked example, by hand
Let's invent the smallest possible machine and run it on paper. Our
toy CPU has 16 memory cells (addresses 0–15), one working register
called A — the accumulator (a
register is a scratch value inside the CPU — Module 02 is all about
them), and a PC. Each instruction is one byte: the first hex digit
says what to do — the
opcode
— and the second says which cell to do it to. Our whole
instruction set is four opcodes: 1n = LDA
(load) cell n into A, 2n = ADC
(add) cell n to A, 3n = STA
(store) A into cell n, 4n = JMP
(jump) to cell n. The 65816 is, at heart, exactly this
kind of accumulator machine — just with a real, rich instruction
set.
Now put this five-instruction program in cells 0–4, with data in cells 12–14. Read it: load cell 14, add cell 13, add cell 12, store cell 14, jump to 0. Cell 13 holds 2 and cell 12 holds 1, so each trip round the loop the number in cell 14 grows by 3. That's it — a counter, the “hello world” of hardware. The lab below is this exact machine. Press Step and watch each fetch, decode and execute happen; press Run and watch it become a program.
- A CPU repeats one loop forever: fetch an instruction, decode it, execute it.
- Instructions are ordinary numbers in memory — programs and data share the same pigeonholes.
- The program counter is the bookmark; a branch or jump is an instruction that rewrites it.
- An instruction's number splits into an opcode (what to do) and operands (what to do it to).
Registers, memory & the ISA
Our toy CPU had one working register, A. Real processors have more,
and the reason is distance — literally. Memory is a large structure
physically far (in chip terms) from the circuits that do arithmetic,
so every trip to it costs time. A register is a
small storage slot built inside the CPU, right next to the
arithmetic circuitry. It holds one value and reading or writing it
costs almost nothing. Registers are the workbench; memory is the
warehouse. There are only a handful precisely because
they're so close — you can't fit a warehouse on a workbench. And the
difference is measurable in clock ticks: an instruction that works
purely with registers (like INX, add 1 to X) takes the
65816 about 2 cycles, while one that must fetch its operand from
memory (like ADC $2000) takes 4 or more. Multiply that
gap by millions of instructions a second and you see why compilers
and programmers fight to keep hot values in registers.
A carpenter doesn't walk to the warehouse for every screw. They fetch a tray of parts to the bench, work there — where everything is within arm's reach — and carry results back when done. A register is a spot on the bench; a load is the walk to the warehouse shelf; a store is the walk back.
The 65816 programmer's model
Here is every register a Super Nintendo programmer actually touches. The star is the accumulator A, where arithmetic lands. Two index registers X and Y count and point. The stack pointer S tracks a scratch area we'll meet in Module 05. The processor status register P is a row of one-bit flags. And a cluster of registers exist purely to reach the 65816's big 24-bit address space: the program bank PBR, the data bank DBR, and the direct page D (Modules 04 and 09 explain those in full).
| Register | Width | What it holds |
|---|---|---|
| A | 8 or 16 | Accumulator — the main work register for arithmetic and logic. Its width is a flag you set (Module 08). |
| X · Y | 8 or 16 | Index registers — counters and pointers, used to walk arrays. Their width is a separate flag. |
| S | 16-bit | Stack pointer — the top of the stack (Module 05). In emulation mode its high byte is locked to $01. |
| P | 8 flags | Status: N V M X D I Z C — plus the hidden E emulation bit. |
| PC | 16-bit | Program counter — the bookmark from Module 01, within the current program bank. |
| PBR · DBR | 8-bit | Program & data bank registers — which 64 KB bank code and data live in (Module 09). |
| D | 16-bit | Direct page register — a movable fast-access window into bank 0 (Module 04). |
The flags in P record the outcome of the last operation and steer branches: N (negative, top bit set), V (signed overflow), Z (zero), C (carry). I masks interrupts, D switches arithmetic into decimal mode (Module 03). And two flags are the whole reason Part II exists: M sets the accumulator's width and X sets the index registers' width — 8 or 16 bits — which is Module 08's headline story.
B:A — the M flag hides or reveals B — while X and Y simply lose their high bytes when the X flag is 1 (Module 08 has the fine print). PBR prefixes the PC, DBR banks absolute data, and P is eight one-bit flags with the hidden E bit hanging off the side.All of this — which registers exist, every instruction the chip understands, how each is encoded into bytes, what the flags mean — is written down in the chip's ISA, its instruction set architecture: the documented contract between hardware and software. Write your program to the contract and it runs on any chip that implements it — which is exactly how the same 65816 ISA could serve the Apple IIGS and the Super Nintendo, and why an emulator (Part III) is, at heart, a program that honours the contract in software.
CISC: arithmetic that touches memory
Now the family question. Many modern chips are
RISC
load/store machines: arithmetic only works
register-to-register, and the only instructions that touch
memory are explicit loads and stores. The 65816 is the opposite — a
CISC
design. A single ADC $2000 reads a value straight out
of memory, adds it to A, and sets the flags, all in one
instruction. And 65816 instructions are variable length:
one byte (INX), two (LDA #$10), three
(LDA $2000), even four (LDA $7E2000). The
opcode's identity and — as Module 08 will show — the current flag
state decide how many bytes follow. This flexibility is exactly what
makes decoding trickier than a fixed-size RISC, and it shapes every
emulator in Part III.
LDA $2000ADC $2002STA $2004Three instructions on the 65816 where a RISC would need a load, a load, an add, and a store — because ADC is allowed to read memory directly.
- Registers are ultra-fast slots inside the CPU; memory is the big, slow warehouse.
- The 65816 model: accumulator A, index X/Y, stack S, status P (N V M X D I Z C + hidden E), PC, and the bank/page registers PBR, DBR, D.
- The 65816 is CISC: arithmetic can read a memory operand directly, and instructions are variable length.
- The M and X flags set register widths — the pivot the whole of Part II turns on.
Numbers in silicon
Everything a CPU touches is stored in bits —
switches that are either 0 or 1. A row of bits reads as a number in
binary, exactly like decimal but with columns worth
1, 2, 4, 8, 16… instead of 1, 10, 100. So 1011 is
8 + 2 + 1 = 11. With n bits you get
2n patterns: a byte (8 bits) covers 0–255, and a 16-bit
value covers 0–65535. Programmers write these in
hexadecimal — base 16, one hex digit per four bits —
because it lines up with the hardware. So $FF is 255,
$100 is 256, and a full bank address like
$7E2000 is just six tidy hex digits.
Negative numbers need a convention, and the universal one is
two's complement: keep counting past the top and
let the value wrap around, like an odometer rolling over — except we
relabel the top half of the patterns as the negatives. In 8
bits, $FF is −1, $FE is −2, down to
$80 = −128. The lovely consequence: the same adder
circuit adds signed and unsigned numbers correctly without knowing
which it's doing. Two flags watch the edges: the
carry flag
catches an unsigned result spilling past the top of the register,
and the overflow flag
catches a signed result whose sign came out wrong. Carry is also how
you chain bytes: add the low bytes, then add the high bytes
plus carry, and you've added a 16-bit number on an 8-bit ALU.
Here is overflow in four lines. Take $7F — read as
signed, +127, the largest positive byte. Add $01. The
adder produces $80 — which, read as signed, is
−128. Two positives just made a negative: the sign came out
wrong, so the CPU sets V. (Carry stays clear —
nothing spilled past the top, and the unsigned reading 127 + 1 = 128
is perfectly correct.)
An 8-bit register is a car odometer with three... no, with room for 0 to 255. Drive one past 255 and it clicks back to 0 — that click is the carry. Two's complement just decides to call the top half of the dial — 128 to 255 — the negatives −128 to −1 instead. Same physical dial, two ways of reading it, and the same clicking works for both.
The 65xx oddity: decimal mode
Here's something most CPUs never had. The 65816 (like the 6502
before it) has a decimal mode, switched on by the
D flag in the status register. With D set,
ADC and SBC stop doing plain binary
arithmetic and instead treat each byte as two
packed BCD
digits. In BCD, the byte $25 literally means the number
twenty-five — each half of the byte (a
nibble,
four bits, one hex digit) holds one decimal digit: the high nibble is
the tens, the low nibble the units — and ADC carries from the units to
the tens at 10, not 16. Add $25 and
$18 in decimal mode and you get $43
(forty-three), not $3D. It's built for score counters,
clocks and anything displayed as decimal digits, sparing the
programmer a binary-to-decimal conversion. The catch: a nibble
greater than 9 (like the $F in $1F) isn't
a valid BCD digit, and feeding one to a decimal-mode add gives
nonsense — one more thing an accurate emulator must reproduce
exactly.
Go poke the bits yourself. Every square below is a button. Flip them and read the same pattern four ways at once — as an unsigned number, as a two's-complement signed number, as hex, and as packed BCD. Then switch the width between 8 and 16 bits and watch the ranges change: it's the M/X flag width choice of Module 08, previewed.
- Binary counts in powers of two; hexadecimal groups four bits per digit and lines up with the hardware.
- Two's complement relabels the top half of the pattern space so one adder handles signed and unsigned.
- Carry catches unsigned overflow (and chains multi-byte adds); the V flag catches signed overflow.
- The D flag switches ADC/SBC into BCD decimal mode — base-10 arithmetic in hardware, a 65xx trademark.
Addressing modes
An instruction like LDA — load the accumulator — needs
to know where to load from. The way it specifies that
“where” is its addressing mode, and the
65816 is famous for having a rich set of them. The same mnemonic
plus a different mode produces a different opcode byte, a different
instruction length, and a different number of cycles. Master the
modes and you've mastered most of what makes 65816 code look the way
it does.
The address a mode finally computes is called the
effective address.
Some modes build it from operand bytes alone; others fold in a
register. The simplest is immediate
(LDA #$42): the operand is the data, so there's
no address at all. Absolute (LDA $2000)
gives a 16-bit address, and the current data bank
supplies the top 8 bits. Absolute long
(LDA $7E2000) spells out all 24 bits itself. One
spelling habit to absorb now: the 65816 is
little-endian
— it stores multi-byte values low byte first. In memory the
operand $2000 is the byte 00 followed by
20, and the CPU glues them back together low-then-high.
Two register-backed shortcuts matter enormously. The
direct page (the 65816's grown-up version of the
6502's “zero page”) is a movable 256-byte window into
bank 0, its base held in the
D register.
LDA $10 means “D plus $10” — a one-byte
operand reaching a fast, nearby scratch area. And indexed
modes add X or Y to the address, so
a loop can walk an array by simply incrementing an index. Stack
everything up — direct or absolute, short or long, plain or indexed,
direct or through a pointer (indirect) — and you get
the two dozen ways the 65816 can say “there”.
“Here, take this” is immediate — the thing is in your hand. “House number 8000” is absolute — but only makes sense once you know the town (the data bank). “Number 16 on our street” is direct-page — short, because “our street” (D) is understood. “Go to the address written on that note” is indirect. And “the fourth house past this one” is indexed. Same destination, wildly different instructions to reach it.
LDA ($10),Y adds the operand to D to locate a pointer in bank 0, reads the 16-bit pointer stored there (little-endian!), borrows the bank from DBR, then adds Y. The lab below runs these exact numbers.
The lab lets you pick a mode and watch it resolve. The register file
is fixed at plausible values (data bank $7E, direct page
$1F00, X = 4, Y = $10, stack at $01FF); a
small memory holds the pointers the indirect modes chase. Choose a
mode and watch the numbered steps combine the operand with the
highlighted registers into one 24-bit effective address.
- An addressing mode is how an instruction names its data; the result is a 24-bit effective address.
- Immediate needs no address; absolute borrows the data bank; absolute long spells all 24 bits out.
- The direct-page register D gives a movable short-operand window; X and Y index for array walks.
- Indirect modes chase a pointer stored in memory — the workhorse
(dp),Yis how you scan arrays.
The stack & subroutines
Programs are built from subroutines — reusable chunks of code you can call from anywhere. But that raises a question: when a subroutine finishes, how does the CPU know where to return to? The answer is the stack: a region of memory used strictly last-in-first-out, like a spike where you impale receipts. You push a value on top; you pull (pop) the top value back off. The stack pointer S always marks the top.
On the 65816 the stack grows downward: a push writes to the
address in S and then decrements S; a pull increments S and then
reads. In emulation mode (how the console boots) the
stack is locked to page 1 — addresses
$0100–$01FF, just like the 6502 — so only the low byte
of S moves. Switch to native mode (Module 08) and
the stack becomes a full 16-bit pointer that can live
anywhere in bank 0, so a program can have as much stack as
it needs.
Subroutines ride on this. JSR (jump to subroutine)
pushes the return address onto the stack, then jumps;
RTS (return) pulls that address back and resumes just
after the call. Because pushes stack up, calls can nest as deep as
memory allows — each RTS unwinds one level. The 65816
adds long versions for its 24-bit world: JSL pushes the
program bank too and RTL restores it, so a
subroutine can live in a different 64 KB bank. One convention worth
knowing, because every 65xx debugger shows it: JSR
actually pushes the address of the last byte of the JSR
instruction itself, not of the instruction after it — and
RTS compensates by adding 1 to the address it pulls
before resuming. You'll see that +1 happen in the lab's narration.
And interrupts (Module 06) use the very same
mechanism — they push the return address (in native mode the program
bank PBR too) and the status register P, so
RTI can restore everything and the interrupted code
resumes exactly as it was.
A cafeteria plate dispenser: you add clean plates to the top and
take them from the top. The last plate on is the first plate off —
LIFO.
When a subroutine calls another which calls another, each return
address is a plate; every RTS lifts the top plate and
goes back exactly where it came from. Lose track of the plates —
push without pulling, or vice versa — and the program returns to a
wrong address and crashes. The stack's discipline is what keeps
nesting sane.
JSR pushed a two-byte return address (high byte first, so it reads low-then-high in memory) — the address of the JSR's own last byte, which RTS will pull and add 1 to. Three frames deep, S has walked down six bytes; each RTS will unwind exactly one frame, newest first.
Play with it below. PHA pushes the accumulator;
PLA pulls it back. JSR pushes a
two-byte return address (high byte first) and RTS
pulls it. Watch S walk downward on every push and back
up on every pull, and watch the top-of-stack byte light up.
Violet outline = S (next free byte) · cyan = the current top of stack.
- The stack is a last-in-first-out scratch area; the stack pointer S marks the top, and it grows downward.
- Emulation mode locks the stack to page 1 ($0100–$01FF); native mode frees S to roam all of bank 0.
- JSR/RTS push and pull a return address; JSL/RTL do it across banks for the 24-bit world.
- Interrupts push the return address (plus PBR in native mode) and the P status register, so RTI resumes interrupted code intact.
Interrupts & timing
So far our CPU has run in a straight line, one instruction after the next. But a games console is full of hardware that needs attention at precise moments — most of all the video chip, which draws the screen line by line and must be left alone while it draws. The mechanism is the interrupt: a hardware signal that makes the CPU stop what it's doing, save its place, and jump to a special handler routine — then, via RTI, resume the interrupted code exactly where it left off. The stack from Module 05 is what makes that clean resume possible: the interrupt pushes the return address (in native mode the program bank PBR too) and the P register before jumping, and RTI restores them all.
Because so much of this module is about the television, here is how a television of that era actually drew. A CRT paints the picture with an electron beam sweeping left to right, one thin scanline at a time, working from the top of the screen to the bottom — on an NTSC console, 262 scanlines per frame, about 60 frames every second. After the last visible line the beam must travel back up to the top-left corner, and that enforced pause — a band of lines during which nothing is being drawn — is the vertical blank.
The Super Nintendo's CPU listens for three: NMI (non-maskable interrupt), which fires at the start of V-blank — the moment the screen finishes drawing and it's finally safe to update video memory; IRQ (interrupt request), which games program to fire at a chosen horizontal/vertical beam position for mid-screen effects; and RESET, which starts the machine. The names are literal, and they connect back to a flag from Module 02: IRQ is a request the program may refuse — setting the I flag masks it — while NMI is non-maskable: no flag can shut it out.
How does the CPU know where each handler lives? A fixed
vector table
at the top of bank 0 — and there are really two of them,
one per personality of the chip (Module 08 explains the two modes).
In native mode the entries are: COP
$FFE4, BRK $FFE6, NMI $FFEA,
IRQ $FFEE. In emulation mode, the
6502-style set: COP $FFF4, NMI $FFFA,
RESET $FFFC, and one shared IRQ/BRK entry at
$FFFE. Notice RESET appears only in the emulation
column: the 65816 always wakes up in emulation mode,
which is why the first thing nearly every game does is the
mode-switch spell you'll meet in Module 08. On an interrupt the CPU
reads the address from the right slot and jumps — no guessing.
You're doing paperwork when the phone rings. You mark your line, take the call, deal with it, then return to the exact word you stopped at. The ring is the interrupt; the bookmark you jot is the stack push; the phone number you dial back is the vector. NMI is the call you're not allowed to ignore — the screen is blanking now and won't wait.
$FFE4–$FFEE column; emulation mode the 6502-compatible $FFF4–$FFFE column. RESET exists only on the emulation side — the chip always boots as a 6502, which is exactly the situation Module 08 picks up from.The clock, and why it has three speeds
First, what a clock even is, with numbers. A quartz crystal
on the console's circuit board vibrates about 21 million times a
second — precisely 21.477 MHz
on an NTSC console — and provides the master clock:
a metronome ticking 21 million times a second, where each tick is
one master cycle, the smallest unit of time the
console knows. The 5A22 doesn't generate that beat; it takes the
crystal's signal and divides it. The CPU does not
run one instruction per tick; instead each memory access takes a
whole number of master cycles, and that number depends on
what is being accessed.
Fast regions (including cartridge ROM wired for
FastROM)
cost 6 master cycles per access — an effective
3.58 MHz. Most of the map, including
SlowROM,
costs 8 cycles — 2.68 MHz. And
the slow I/O area (the old serial joypad ports at
$4000–$41FF) costs 12 cycles —
1.79 MHz. Same CPU, three speeds, chosen by the
address bus.
The lab draws one NTSC frame as a vertical timeline: 262 scanlines, the visible region on top and V-blank below. A beam sweeps down; the instant it crosses into V-blank, NMI fires and the counter ticks. Below, pick a memory-access speed and read how the master clock divides into the CPU's three real rates.
That's the whole Part I toolkit: the loop, registers, number formats, addressing modes, the stack, and interrupts & timing. Everything in Part II is these six ideas put into real Nintendo silicon. Time to meet the chip.
- An interrupt makes the CPU save its place on the stack and jump to a handler, then resume via RTI.
- NMI fires at V-blank (the only safe time to touch video memory); IRQ fires at a chosen beam position; RESET boots the machine.
- Two vector tables at $FFE0–$FFFF — native (NMI $FFEA, IRQ $FFEE, BRK $FFE6, COP $FFE4) and emulation (NMI $FFFA, IRQ/BRK $FFFE, COP $FFF4, RESET $FFFC); RESET always lands in emulation mode.
- The board's crystal provides the 21.477 MHz master clock; the 5A22 divides it into 3.58 / 2.68 / 1.79 MHz access speeds, chosen by the address.
The 5A22
Now we put the Part I toolkit into real silicon. Nintendo didn't design a CPU core from scratch — it licensed the proven 65816 and asked Ricoh to wrap it in exactly the peripherals a games console needs: DMA and HDMA controllers to move data fast, a hardware multiply/divide unit, controller ports, WRAM refresh, and clock generation, all on one die called the 5A22. These six modules cover the CPU's two operating widths, its unusual 24-bit banked memory, the two DMA engines, and the math unit — each mapping straight back to a fundamental you already know.
Meet the 5A22
The Super Nintendo's CPU chip is the Ricoh 5A22. At its heart is a 65C816 processor core — the 16-bit successor to the 6502 family that powered a generation of home machines: the Apple II used the 6502 itself, the Commodore 64 its 6510 variant, and the NES a Ricoh 2A03 built around a 6502 core. But the 5A22 is more than the core: Ricoh integrated onto the same die a set of peripherals that would otherwise need separate chips. That's why we call it the 5A22 and not just “the 65816” — the CPU you program is the core, but the silicon in the box does far more.
What Ricoh added around the core: the DMA and HDMA controllers (eight channels that copy blocks of memory without the CPU lifting a finger — Modules 10 and 11), a hardware multiply and divide unit (the 65816 core can't multiply on its own — Module 12), the parallel I/O and controller ports plus automatic joypad reading, the H/V counters and timer that track the drawing beam's position and can fire an IRQ at a chosen screen coordinate (Module 14 returns to these), WRAM refresh logic to keep the 128 KB of work RAM alive — work RAM is DRAM, which forgets its contents within milliseconds unless every row is periodically re-read, so the 5A22 quietly does that re-reading itself — and the clock circuitry that takes the 21.477 MHz master signal from the board's quartz crystal and divides it into the access speeds of Module 06. The core thinks; the 5A22's peripherals do the heavy lifting around it.
The 65816 core is a skilled chef. But a chef alone in an empty room can't cook — the 5A22 is the fitted kitchen built around them: the dishwasher that clears plates while they work (DMA), the calculator on the wall for portions (the math unit), the intercom to the dining room (the controller ports), and the clock on the wall everyone works to. Nintendo bought the chef and built the kitchen to suit exactly one restaurant.
- The SNES CPU chip is the Ricoh 5A22: a 65C816 core plus Nintendo's on-die peripherals.
- Those peripherals are the DMA/HDMA controllers, the multiply/divide unit, I/O and joypad ports, the H/V counters and timer IRQ, WRAM refresh, and the clock divider.
- The core is the processor you program; the 5A22's extras do the fast data movement and math around it.
- One 21.477 MHz master clock feeds the three region access speeds from Module 06.
8-bit or 16-bit? The M & X flags
Here is the 65816's defining trick — and its most notorious trap. The
chip can run in two personalities. It boots in
emulation mode, where it behaves as a fast 6502: all
registers 8-bit, the stack pinned to page 1. A game switches to
native mode with a two-instruction spell —
CLC then XCE (exchange carry with the hidden
E flag)
— and unlocks the full 16-bit machine.
In native mode two status flags choose register widths independently.
The M flag sets the accumulator and memory
width: M = 0 makes A a full 16-bit register, M = 1 keeps it 8-bit. The
X flag sets the index registers X and Y the
same way. You flip them whenever you like with REP
(reset = clear flag bits, going 16-bit) and SEP (set
flag bits, going 8-bit); each takes an operand mask naming the P
bits to touch — REP #$30 clears both M and X
(everything 16-bit), SEP #$20 sets just M (8-bit A,
16-bit indexes). Want 16-bit maths but 8-bit loop counters? Set
M = 0, X = 1. It's yours.
Two follow-on traps hide in the resizing itself. Setting X = 1 is
destructive: the high bytes of X and Y are forced to $00
and their old contents are gone — flip back to 16-bit and they stay
zero. Setting M = 1 is gentler: A's high byte (called
B) is hidden, not erased, and reappears intact when
M returns to 0 — you can even swap it in and out with
XBA. And emulation mode simply forces M = X = 1
outright, one more reason the CLC:XCE
escape is the first thing games run.
And now the classic gotcha. An immediate instruction like
LDA # carries its value inline — so how many
operand bytes follow depends on the current M flag. With M = 0 (16-bit)
A9 34 12 is LDA #$1234, a three-byte
instruction. With M = 1 (8-bit) the very same opcode reads only one
operand byte: A9 34 is LDA #$34, and the
12 that follows is now the next instruction. The
identical bytes decode into completely different programs depending on
invisible processor state. Get the flag tracking wrong — in your head,
in a disassembler, or in an emulator — and everything downstream
shifts. It's the single most common way to misread 65816 code.
Imagine a recipe where “add 2 cups” means two cups in one
chef's dialect but two and a half in another's — and the
dialect can switch mid-page with a tiny margin note. Read on without
noticing the note and every later line is off by an ingredient. The
M and X flags are that margin note: REP/SEP
silently change how many bytes each following instruction eats.
The lab makes it tangible. Toggle M and X and watch A, X and Y resize between 8 and 16 bits. Below them, a fixed stream of bytes is re-decoded live under the current flags — watch instruction boundaries slide as immediate operands grow and shrink, turning one byte stream into two different programs.
A9 34 12 A2 10 00 E8 CA 60 — re-decoded- The 65816 boots in 6502 emulation mode; CLC:XCE switches it to native 16-bit mode via the hidden E flag.
- In native mode, the M flag sets accumulator/memory width and the X flag sets index width — each 8 or 16 bit.
- REP #$30 clears the flags (16-bit); SEP #$30 sets them (8-bit) — toggle at will, even mid-routine.
- X = 1 destroys the high bytes of X/Y (forced $00); M = 1 merely hides A's B byte; emulation mode forces M = X = 1.
- Immediate operand length tracks the flags, so the same bytes decode into different instructions depending on M/X.
The 24-bit address space & banks
The 6502 could address 64 KB — 16 bits of address. The 65816 widens
that to 24 bits: 16 MB, organised as
256 banks of 64 KB each. A full
address is written bank:offset, like
$7E:2000. The registers from Module 02 do the widening:
the program bank PBR supplies the top 8 bits of the
PC (which bank code runs in), and the data bank DBR
supplies the bank for absolute data accesses. The direct page
D gives a movable fast window inside bank 0.
What's actually at those addresses is the SNES
memory map, and it's worth knowing by heart. The
128 KB of work RAM lives in banks $7E–$7F; the low
8 KB ($0000–$1FFF) is mirrored into the bottom of every
“system” bank. The win isn't speed — the mirror is
metered at the same 8 cycles — it's encoding: with the
mirror under its feet, code can reach that RAM through short
one-byte direct-page operands and plain absolute addresses,
whatever the DBR currently points at, instead of spelling out
24-bit long addresses into $7E.
The hardware registers sit in a narrow band of every system bank:
the PPU (video) at $2100–$213F, the
APU (sound) mailbox ports at
$2140–$2143, the CPU registers (NMI
control, the math unit, DMA enables) around $4200–$421F,
and the DMA channel registers at
$4300–$437F. Cartridge ROM fills the upper halves of the
banks ($8000–$FFFF) and the big upper banks.
Picture a 256-floor tower, each floor a 64 KB bank. Some floors are pure storage (RAM in $7E–$7F, ROM up top). But every “system” floor shares an identical service corridor near the entrance — the same lift buttons to the PPU, the APU, the DMA desk — because the hardware is wired into all of them. The bank registers are which floor you're currently standing on.
The lab is a live map probe. Type any 24-bit address — or hit a preset
— and it tells you which region (or mirror) that address lands in, with
a bar showing where inside the bank it falls. Try $7E0100
(work RAM), $002100 (a PPU register), $004202
(the multiply register from Module 12), and $808000
(cartridge ROM).
- The 65816 addresses 24 bits: 16 MB in 256 banks of 64 KB, written bank:offset.
- PBR sets the code bank, DBR the data bank, D the direct-page window — together they reach the whole space.
- WRAM is $7E–$7F, with its low 8 KB mirrored into every system bank; PPU $2100, APU $2140, CPU/DMA $4200/$4300.
- Cartridge ROM occupies the upper halves of banks and the big upper banks; the exact layout is the mapper's job.
DMA — feeding the PPU fast
A frame of SNES graphics needs a lot of data poured into the
PPU during V-blank: new tiles into VRAM, new colours into the palette,
new sprites into OAM. Doing it with the CPU — a loop of load, store,
load, store — is painfully slow, and V-blank is short. So the 5A22
includes a
DMA
controller: eight channels that copy a block of memory into a
hardware port at a fixed cost of 8 master cycles per
byte. The two ends of the copy live on different buses.
The source side rides the A-bus — the CPU's
ordinary 24-bit address bus, the one that reaches WRAM and
cartridge ROM. The destination is on the B-bus — a
small 8-bit side bus that carries only the $21xx
register ports (VRAM, palette, sprite memory and friends), which is
why a DMA destination is named by a single port byte.
You set a channel up by writing its registers at
$43x0–$43x6 (where x is the channel number): the
control byte and transfer pattern, the destination port, the 24-bit
source address, and the byte count. Then you write a single bit to
$420B (MDMAEN) to arm the channels you
want, and the transfer fires immediately. A common destination is
$2118/$2119, the VRAM data port — feed it a stream and the
PPU fills video memory. The transfer pattern chooses
how bytes fan out across the destination ports: one register (mode 0),
alternating two (mode 1, perfect for the low/high VRAM pair), and so on.
The price: while a DMA runs, the CPU is halted. The DMA engine owns the bus; the processor simply stops until the transfer completes. And at 8 master cycles per byte (≈ 2.68 MB/s), the budget is tighter than you'd hope. An NTSC V-blank is only about 38 scanlines — roughly 52,000 master cycles — which is room for just 5–6 KB of DMA before the beam starts drawing again. Filling all 64 KB of VRAM costs about 524,000 cycles — nearly a frame and a half. So real games budget: they split big uploads across several V-blanks, or switch the display off entirely (forced blank) during loading screens and transfer at leisure while nothing is drawn. It's a deliberate trade — pause the thinker so the mover can go flat out — but only for as long as the blank lasts.
The CPU copying bytes one instruction at a time is a bucket chain:
correct, but slow, and it ties up everyone. DMA is a fire hose bolted
straight from the reservoir to the fire — you turn one valve
($420B) and it pours. You can't do anything else while
the hose is running full-bore, but you don't need to: it's done in a
blink.
The lab is a channel you configure and fire. Pick a destination port and transfer pattern, set a byte count, and press Run: watch bytes stream from work RAM into the PPU port while the cycle counter climbs and the CPU sits halted. The elapsed microseconds show why DMA, not a CPU loop, is how the SNES moves graphics.
- DMA is a hardware copy engine — eight channels that move blocks from memory to a fixed hardware port.
- Configure a channel at $43x0–$43x6, then arm it with a bit in $420B (MDMAEN); the transfer fires at once.
- Transfer patterns fan bytes across destination ports — mode 1 feeds the $2118/$2119 VRAM pair.
- DMA costs 8 master cycles per byte (≈ 2.68 MB/s) and halts the CPU for its duration — a deliberate trade.
- One NTSC V-blank (~38 lines ≈ 52k master cycles) fits only ~5–6 KB of DMA — big loads span frames or run under forced blank.
HDMA — mid-frame magic
Module 10's DMA runs once, in a burst, during V-blank. Its sibling is cleverer. HDMA — horizontal-blank DMA — performs a tiny transfer every scanline, in the sliver of time between drawing one line and the next. Instead of one big block up front, HDMA drips a handful of bytes to a hardware register 224 times a frame, so that register can hold a different value on every line of the screen. That single idea is behind a huge fraction of the SNES's signature look.
You arm HDMA channels by writing $420C
(HDMAEN) instead of $420B, and each channel reads from a
table
in memory. The table format is compact: each entry starts with a
line-count byte, followed by the data to write to
the target register — or, in indirect mode, a
pointer to that data. The count byte does double duty via its top
bit. Values $01–$80 mean hold: write the
data once, then keep it for 1–128 lines. Values
$81–$FF switch on
repeat mode:
write fresh data on every line, for
(count & $7F) lines. And $00
ends the table. A concrete table, in real bytes — say we're feeding
the fixed-colour register: $20 $48 (hold: write
$48 once, keep it 32 lines) · $83 $50 $58 $60
(repeat: 3 lines, each getting its own value) ·
$20 $00 (hold $00 for 32 lines) · $00
(end). The CPU sets the table up once; the HDMA hardware then walks
it with no CPU instructions at all — though not quite for free: each
active channel steals a few machine cycles from the CPU every
scanline it writes (Module 14 counts the cost).
What can you paint with a register that changes every line? A colour gradient in the sky (drip a slightly different colour to the fixed-colour register each line). Per-line scrolling to shear the screen into parallax layers or wavy water. Changing the Mode 7 transformation matrix each line to bend a flat plane into a curved horizon. Moving the window registers to carve circular spotlights and iris wipes. All of it is “change one register, every scanline” — and all of it is HDMA.
A single-DMA burst is painting the whole fence one colour before the parade starts. HDMA is a painter who dabs one fresh shade on the fence in the instant between each float passing — so by the end the fence is a smooth rainbow, even though only a dab was applied at a time. The “instant between floats” is H-blank; the dab is the tiny per-line transfer.
$20 $48) set a value and coast; the repeat-mode entry ($83 …) hands the register a fresh byte on every one of its lines. Every write is squeezed into the H-blank sliver at the end of a scanline; the whole dance resets during V-blank.
The lab is HDMA painting a sky. It writes the fixed-colour register
$2132 a new value on each scanline, interpolating between a
top and bottom colour you pick — and animates the beam filling the
gradient line by line, exactly as the hardware would. The table on
the side shows the entries a gradient this smooth really needs:
repeat-mode counts (top bit set) followed by one
colour byte per line — a hold-mode table would paint bands, not a
fade.
- HDMA does a small transfer every scanline, in H-blank, so a register can change value down the screen.
- Channels are armed by $420C (HDMAEN) and driven by a table: a line-count byte ($01–$80 = hold; $81–$FF = repeat, fresh data every line) plus data, or a pointer (indirect).
- It powers gradients, per-line scroll and parallax, per-line Mode 7 matrices, and window shapes.
- The CPU builds the table once; the hardware walks it all frame with no CPU instructions — at the price of a few stolen cycles per active line (Module 14).
The math registers
The 65816 core has add, subtract, and bit operations — but no multiply and no divide instruction. Doing them in software is slow, and games need them constantly (scaling, positioning, dividing a span into steps). So Ricoh built a small multiply/divide unit into the 5A22, reached not through instructions but through memory-mapped registers: you write the operands to certain addresses, wait, then read the result back from others. It's a peripheral, like DMA — the core just moves bytes to and from it.
Multiply is unsigned 8×8→16. Write the first operand to
$4202 and the second to $4203; writing
$4203 starts the calculation. After 8 CPU
cycles — machine cycles of the CPU, note, not master-clock
ticks — the 16-bit product is waiting in
$4216 (low) and $4217 (high).
Divide is unsigned 16÷8. Write the 16-bit dividend to
$4204/$4205 and the 8-bit divisor to $4206;
writing $4206 starts it. After 16 cycles
the quotient sits in $4214/$4215 and the remainder in
$4216/$4217. The counts aren't arbitrary: the unit is a
shift-and-add machine that grinds out one bit of the answer per
cycle — 8 cycles for an 8-bit multiplier, 16 for a 16-bit
quotient. Even division by zero is defined rather than fatal: the
quotient comes back $FFFF and the remainder is the
dividend, passed through untouched — the lab reproduces exactly
that.
That wait is the crucial detail. The unit isn't instantaneous — it grinds through the math over those 8 or 16 cycles. Read the result registers too early and you get a half-finished value, a subtle bug that plagued real 65816 programmers. In practice you just make sure a few instructions pass between writing the last operand and reading the result — easy once you know, mysterious if you don't. (And an emulator has to model exactly this delay to run buggy games faithfully — a Part III theme.)
You put in your operands (press the buttons), and the machine whirs. Reach into the tray immediately and it's empty — the can hasn't dropped yet. Wait the few seconds it takes and the answer is there. The math unit is exactly this: the whir is those 8 or 16 cycles, and grabbing the tray early gets you nothing useful.
$4216/$4217 is one pair of registers with two jobs: multiply parks its product there, divide its remainder. Start a divide and the last product is gone. The bottom strip is the ritual the vending-machine analogy describes — and the red mark is the classic too-early read.
The lab is the math unit with its wait modelled. Choose multiply or
divide, set the operands, and press Go: the cycle bar fills over the 8 or
16 cycles, and only when it's done do the result registers show the true
answer. Notice the register names match the real hardware — and that the
product and the division's remainder share $4216/$4217.
- The 65816 core can't multiply or divide; the 5A22 adds a hardware unit reached through memory-mapped registers.
- Multiply (8×8→16): write $4202 and $4203, wait 8 cycles, read the product from $4216/$4217.
- Divide (16÷8): write $4204/5 and $4206, wait 16 cycles, read quotient $4214/5 and remainder $4216/7.
- You must wait the cycles before reading — an early read returns a half-finished value.
Emulating it in bsnes
Finally: how does software on your PC stand in for the whole 5A22 — the CPU, the PPU drawing beam, the sound chip, the DMA engines — all at once, and all in step? Your processor can't run a single 65816 instruction, so an emulator must interpret them; but the harder half is timing, because on real hardware everything shares one clock. These three modules cover how bsnes runs the CPU, the accuracy traps that separate a screenshot-correct emulator from a truthful one, and the debuggers where you can watch it all with your own eyes.
Interpreters & cycle accuracy
Strip the problem to its core: bsnes holds the game's memory in a big
array, and in that array sit 65816 instructions — numbers, as Module
01 taught you. Your CPU can't execute them, so bsnes runs an
interpreter:
a software re-enactment of the fetch–decode–execute loop. It keeps a
variable for the PC and for each of the 65816's registers, reads the
opcode byte at PC, looks at it, jumps to the matching handler
(“this is ADC: add this memory value to the emulated
A, set the flags”), advances the virtual PC, and repeats. It is
Module 01's toy lab, grown up to the full instruction set — including
the M/X width tracking from Module 08, which the interpreter must
follow byte by byte.
But the Super Nintendo is not just a CPU. While the CPU runs, the PPU is drawing the beam across the screen, the APU's SPC700 is generating sound, and the DMA engines may be moving memory — and on real hardware all of them share the one 21.477 MHz master clock from Module 06. The genius of bsnes is that it emulates that literally. A single scheduler steps every component off the same master clock: run the CPU forward a few clocks, run the PPU forward the same few, run the APU, keep them all pinned to the same instant. This is cycle accuracy — the emulator's model of time is the hardware's model of time.
The alternative, which faster emulators of the past took, is instruction stepping: run a whole CPU instruction, then catch the other chips up in a lump. It's quicker, but it smears time — the PPU “sees” the CPU's writes only at instruction boundaries, not at the exact clock they happened. For most games that's invisible. For the ones that lean on the precise interleaving of CPU, PPU and DMA — reading a beam-position counter mid-instruction, timing an effect to a specific clock — only the shared single-clock model gets it right. That's why bsnes's author built it around one clock: one clock matters because the real machine only ever had one.
An orchestra where each player follows their own watch drifts apart in seconds. A real orchestra follows one conductor's baton — every player on the same beat. Instruction stepping is players glancing at the score only at the end of each bar; cycle accuracy is watching the baton on every single beat. The master-clock scheduler is that conductor, and the 5A22's 21.477 MHz clock is the beat.
Look back at the toy CPU (Module 01). An interpreter is literally that lab, scaled up: a PC variable, register variables, a dispatch on the opcode, a handler per instruction. bsnes genuinely contains one — the difference is that its loop advances a shared clock every step, so the drawing beam and the sound chip stay welded to the CPU at all times.
- An interpreter re-enacts fetch–decode–execute in software: a PC, register variables, a per-opcode handler.
- bsnes steps the CPU, PPU, APU and DMA off one shared 21.477 MHz master clock — a single scheduler.
- Cycle-stepping keeps every chip pinned to the same instant; instruction-stepping smears time to boundaries.
- One clock matters because the real console only ever had one — games can depend on the exact interleaving.
The accuracy traps
If Module 13 made cycle accuracy sound like a solved recipe, this module is the cold shower. The traps are all the things the real 5A22 does implicitly — leftover values on the bus, transfers that steal exact cycles, counters that tick with the beam, chips that must agree at boot — which software has to reproduce explicitly and precisely. Miss one and the emulator isn't slow; it's wrong, often in a way that only shows up in one scene of one game.
Trap 1 · Open bus
Not every address has hardware behind it. When the CPU reads an unmapped address, real silicon doesn't return a clean zero — it returns whatever value was last on the bus, because nothing drove new bits onto the wires. This is open bus, and some games genuinely depend on the specific leftover value they get back. An emulator that returns 0 (or a random number) there will run most games and then mysteriously break the one that read open bus on purpose.
Trap 2 · DMA and HDMA steal exact cycles
Module 10's DMA halts the CPU — but for exactly how long, and starting on exactly which master cycle, matters. HDMA is worse: it interrupts the CPU for a few cycles on every scanline, at a precise point in H-blank, and the amount stolen depends on how many channels are active and their transfer sizes. Get the count or the timing of these steals slightly wrong and any game that counts cycles — or times an effect against the beam — drifts out of sync.
Trap 3 · The H/V timer and the “early IRQ”
First, a correction to a widespread misattribution: the beam-chasing
hardware lives in the 5A22 itself, not in the PPU.
It's the CPU chip (Module 07's peripheral list) that keeps
horizontal and vertical counters tracking the beam,
and it's the CPU chip you program: write a target position into
$4207–$420A and the timer fires an IRQ when the beam
gets there, acknowledged by reading $4211 (TIMEUP).
The PPU's only role is on the reading side: touching
$2137 latches
the counters — freezes a snapshot of the moving beam position — and
software then reads that snapshot from $213C/$213D.
The exact relationship between the CPU's clock and those counters
is delicate, and there's a famous class of bug where an
IRQ fires one cycle early
because the timer-to-CPU timing was modelled a hair off. One cycle is
enough to make a raster effect tear or a game hang.
Trap 4 · The CPU↔APU boot handshake
The single most infamous trap. The sound subsystem is a whole separate
CPU — the SPC700 — running on its own clock, and the two
processors talk through the four mailbox ports at
$2140–$2143 (Module 09). At boot they perform a precise
handshake:
the main CPU uploads the sound driver, and both sides step through an
agreed protocol whose timing games silently rely on. Because the two chips
run on different clocks that only bsnes-style scheduling keeps
correctly related, a small timing error makes the handshake desync — and
the game hangs on a black screen at boot. Whole eras of emulators fought
this exact bug.
$2140–$2143 mailboxes — each side just polls until the other's byte appears. Get the two clocks' ratio wrong by a whisker and one read lands one cycle early, the echo check fails, and the handshake deadlocks. Only a scheduler that keeps both clocks honestly related (Module 13) survives it.Trap 5 · Programs and data share memory
Module 01 called this “the single most important idea in all of computing” and promised it makes emulators sweat. Here's the sweat. Because instructions are just bytes in the same memory as data, nothing stops a program from writing over its own instructions — and SNES games really do it: code copied into WRAM and patched on the fly, loop operands rewritten each frame, self-modifying code of every flavour. A naive interpreter survives this for free — it re-reads memory every fetch. But the moment an emulator gets clever and caches anything derived from those bytes (pre-decoded instructions, translated blocks), it must watch every write and throw away any cached copy the write just invalidated. Miss one store and the emulator cheerfully executes code that no longer exists.
A flight sim that only looks right is a video game; one a licensing examiner accepts must match the aircraft's numbers, because pilots build reflexes against the real machine's behaviour, not its appearance. Games are those pilots: a thousand accidental dependencies on open-bus values, exact DMA steals, precise counter timing and the boot handshake. Fast gets the plane in the air; accurate is what keeps three decades of software from noticing it changed aircraft.
Why not always be maximally accurate? Because faithfully modelling every cycle-steal, counter and open-bus read is expensive — the reason cycle-accurate cores like bsnes/higan need far more host horsepower than the faster, looser emulators that came before. The art is a model that's truthful where games can tell and cheap where they can't; the reference cores simply refuse to cut the corners at all.
- Open bus: unmapped reads return the last value on the bus, and some games depend on it.
- DMA and especially HDMA steal exact cycles at exact times; sloppy timing desyncs cycle-counting games.
- The H/V timer lives in the 5A22 ($4207–$420A, $4211); the PPU only latches counters for reading ($2137, $213C/D). Mis-timing the IRQ by one cycle is a classic, visible bug.
- The CPU↔APU (SPC700) boot handshake across separate clocks is the notorious make-or-break sync.
- Programs can rewrite their own bytes — anything an emulator caches from memory must be invalidated on writes.
Try it in bsnes / Mesen
You now have the full picture, so let's make it hands-on. Modern SNES emulators ship debuggers that expose every mechanism this course described. Mesen 2 (mesen.ca) gives you the most complete 65816 debugger going; bsnes (github.com/bsnes-emu/bsnes) is the reference cycle-accurate core this course leaned on, and its debug-oriented fork bsnes-plus adds a similar tool set. All are accurate enough to trust what they show you. Here's what to open and what you'll recognise:
- The disassembler & CPU register view — see A, X, Y, S, the P flags (including
MandX), and the PBR/DBR/D bank registers live. Watch the flags flip on aREP/SEPand the disassembly re-length its immediates, exactly as your Module 08 lab did. - The trace logger — dump every instruction the CPU executes, with the effective address each addressing mode resolved to (Module 04) and the cycle it ran on. This is the fetch–decode–execute loop of Module 01, written to a file.
- Breakpoints & the memory viewer — break when the code writes
$420B(a DMA kicking off, Module 10) or$420C(HDMA, Module 11), or reads$4216(a multiply result, Module 12). Watch the memory map from Module 09 light up as regions are touched. - The event/PPU viewer — see NMI fire at V-blank and IRQs at their beam positions (Module 06), and watch HDMA writes march down the scanlines painting a gradient (Module 11).
Three experiments worth actually running
- Catch a mode switch. Set a breakpoint on the first
XCEafter boot and step it. You'll watch the machine leave 6502 emulation mode and become the 16-bit 65816 — Module 08, live, on the first few instructions of nearly every game. - Follow a DMA. Break on a write to
$420B, then read the channel registers at$4300–$4306the game just set up: source, destination port, size. You've just decoded a real transfer by hand (Module 10). - Watch HDMA paint. Find a game with a gradient sky, open the PPU/event viewer, and watch a colour register change value scanline by scanline (Module 11). The gradient in your lab is happening for real, 224 times a frame.
And that's the course. You began with a cook and a stack of numbered cards; you end able to read a 65816 trace, explain why the same bytes can decode two ways, and predict which register a DMA or the math unit will touch. The fetch–decode–execute loop from Module 01 is still down there, under everything, turning — on a 1990 games console, on the machine you're reading this with, and in bsnes faithfully pretending to be one on the other, one shared clock at a time.
- You can trace a frame end-to-end: the CPU sets up DMA/HDMA, the beam draws, NMI fires at V-blank, repeat.
- You know the 65816 model — A/X/Y/S/P, the M & X width flags, the 24-bit banked address space — and the 5A22's DMA, HDMA and math peripherals.
- You understand why bsnes runs everything off one master clock, and the accuracy traps that make it hard.
- You can open a debugger and map every register and event to a mechanism you now understand.