238. Ppu owns ppu bus

Connect PPU to PpuBus.

Lesson 238 of 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_238_ppu_owns_ppu_bus.py

File to update

emulator/ppu/ppu.py

Field to add

ppu_bus: PpuBus = field(default_factory=PpuBus)

Why this step exists

The PPU has registers that the CPU can access through CpuBus, but the PPU also has its own address space:

PPU address space: $0000-$3FFF

That address space should be routed by PpuBus.

This creates the stable boundary needed before implementing PPUADDR/PPUDATA:

CPU writes $2006 / $2007
    -> CpuBus routes to PPU.write_register(...)
    -> PPU uses internal PPU address state
    -> PPU writes through PpuBus

Important dependency direction

PPU -> PpuBus -> VRAM / mapper CHR later

Not

PPU -> raw VRAM directly

Why this matters

PPUDATA behavior should not need to change when PpuBus later becomes more accurate. Today PpuBus may use big VRAM. Later it may route:

$0000-$1FFF -> mapper CHR ROM/RAM
$2000-$3EFF -> nametable VRAM/mirrors
$3F00-$3FFF -> palette RAM/mirrors

Suggested implementation pseudocode

from dataclasses import dataclass, field
from emulator.bus.ppu_bus import PpuBus


@dataclass
class PPU:
    ctrl: int = 0
    mask: int = 0
    status: int = 0
    oam_addr: int = 0
    oam_data: int = 0
    scroll: int = 0
    addr: int = 0
    data: int = 0

    ppu_bus: PpuBus = field(default_factory=PpuBus)

Out of scope

  • PPUADDR latch behavior
  • PPUDATA writes through PpuBus
  • palette/nametable accuracy
  • CHR RAM writes

Run this lesson

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_238_ppu_owns_ppu_bus.py -v