Example flow
LDA #$20 / STA $2006 Low-Level Hardware Flow
- **CPU Fetch Opcode**
- CPU places **Program Counter (PC)** on address bus (A0–A15).
- NES address decoder asserts **CE (chip enable)** for **PRG ROM**.
- PRG ROM drives **data bus D0–D7** with opcode `A9`.
- CPU reads opcode into instruction register.
- **CPU Fetch Operand**
- CPU increments PC → address bus points to next byte.
- PRG ROM CE active, data bus outputs operand `20`.
- CPU reads operand → Accumulator (A) will later be loaded with `20`.
- **Execute LDA**
- CPU loads operand into **Accumulator (A)**.
- No external bus activity required for execution.
2. Instruction: STA $2006
- Target:* PPUADDR (PPU register $2006)
- **CPU Places Address on Bus**
- CPU puts `$2006` on address bus (A0–A15).
- NES address decoder activates **PPU CE**, deactivates other devices.
- **CPU Drives Data Bus**
- CPU places **Accumulator value `20`** on data bus D0–D7.
- CPU asserts **WR (write)** signal.
- **PPU Latches Data**
- PPU detects **CE active + WR active**.
- `$2006` first write → high byte of VRAM address latched.
- `$2006` second write → low byte latched.
- PPU internal flip-flop tracks first/second write.
| Step | CPU Address Bus | CPU Data Bus | CE | RD/WR | Notes |
|---|
| Fetch Opcode (A9) | PC | D0–D7 | PRG ROM CE active | RD | PRG ROM outputs opcode |
| Fetch Operand (20) | PC+1 | D0–D7 | PRG ROM CE active | RD | PRG ROM outputs operand |
| STA $2006 | $2006 | D0–D7 = Accumulator | PPU CE active | WR | PPU latches VRAM address |
- Only one device drives the data bus at a time to prevent conflicts.
- PPU registers $2000–$2007 are memory-mapped; accessed via address decoder.
- Internal PPU latches track high/low byte for $2006 VRAM address writes.
Edit this page on GitHub