The toy CPU's instructions
| Bytes | Written as | Length | What it does | Cycles |
|---|---|---:|---|---|
| `01 n` | `LDX #n` | 2 | X = n; Z = 1 if X is 0 | 2 |
| `02 a` | `LDA a` | 2 | A = the byte at address a; Z = 1 if A is 0 | 3 |
| `03 n` | `ADD #n` | 2 | A = A + n, wrapping past 255 back to 0; Z = 1 if A is 0 | 2 |
| `04 a` | `STA a` | 2 | store A at address a | 3 |
| `05` | `DEX` | 1 | X = X − 1, wrapping below 0 to 255; Z = 1 if X is 0 | 1 |
| `06 a` | `JNZ a` | 2 | if Z is 0, jump: PC = a | 2, or 3 if it jumps |
| `FF` | `HLT` | 1 | stop | 1 |
A `#` marks an **immediate**: `#5` means the number 5 itself, while an operand
without `#` is an address, and the instruction uses the byte stored there. `STA`
and `JNZ` leave Z alone. Every other byte value is not an instruction, and the
lab reports it as an error instead of guessing.
Every number in the last column comes from one rule: the CPU spends one cycle on
each memory access, meaning each instruction byte it fetches and each data byte
it reads or writes, plus one extra cycle when a jump is taken, to load the new
address into PC. So `LDX #n` and `ADD #n` each fetch 2 bytes, 2 cycles; `LDA a`
fetches 2 and reads 1, 3 cycles; `STA a` fetches 2 and writes 1, 3 cycles;
`DEX` and `HLT` each fetch 1, 1 cycle; and `JNZ a` fetches 2, plus 1 if it
jumps. Real 8-bit CPUs, such as the 6502 inside the NES, have similar costs for
similar reasons.
## The program in memory
The program adds 5 gold twice and then shows the total on the console's
display. Gold lives at address `0x80` and starts at 10:
```text
address bytes instruction meaning
0x00 01 02 LDX #2 X = 2: go round the loop twice
0x02 02 80 LDA 0x80 A = gold
0x04 03 05 ADD #5 A = A + 5
0x06 04 80 STA 0x80 gold = A
0x08 05 DEX X = X - 1
0x09 06 02 JNZ 0x02 back to 0x02 while X is not 0
0x0B 04 F0 STA 0xF0 show A on the display
0x0D FF HLT stop
```
Each address is the one before it plus that instruction's length:
`0x00` + 2 = `0x02`, and so on down to `0x08` + 1 = `0x09`,
`0x09` + 2 = `0x0B`, and `0x0B` + 2 = `0x0D`. The last byte sits at `0x0D`,
which is 13, so the program fills addresses 0 to 13, which is 14 bytes: