CPU Introduction
Last updated:
The NES CPU is a Ricoh 2A03 — a 6502 with no decimal mode. Each cycle below is one memory access on the bus; the CPU never sits idle, so even "do nothing" steps show up as discarded reads.
CPU flow
The CPU is built to execute instructions sequentially, one by one, by reading them from memory. An instruction is 1, 2, or 3 bytes long, and the first byte is always the opcode ("operation code") — a one-byte number that identifies the instruction.
Addresses on this CPU are 16 bits long (2 bytes) — that's a 64 KiB
address space, $0000 to $FFFF.
The CPU tracks where it's reading from with a 16-bit register
called PC (program counter): the address of the next byte to read.
The basic operation read [PC]; PC++ is called a fetch. Executing an instruction is
a sequence of fetches — first the opcode, then the remaining bytes
(if any).
Cycle 1 of every instruction is therefore the same: fetch the opcode to identify the instruction.
So the whole CPU is a loop: fetch an opcode, do whatever it says, repeat.
loop {
opcode = read(PC); PC++ // cycle 1: fetch the opcode
execute(opcode) // the rest of the cycles depend on the instruction
}
execute is empty for now — filling it in, one opcode at a time, is the work of
the checkpoint. Everything else on the CPU pages is
detail that hangs off this loop.
Example
Say PC = $8000 and memory contains:
$8000 C9
$8001 42
$8002 ...
The CPU is about to start a new instruction. It fetches the opcode:
cycle 1 read [$8000] → C9 (opcode); PC = $8001
C9 is the opcode for an instruction that does something specific
with one operand byte (what exactly isn't important here). The CPU
fetches the operand:
cycle 2 read [$8001] → 42 (operand); PC = $8002
PC sits at $8002, ready for the next opcode fetch.