Skip to content

PPU 2C02

DoubleGate edited this page Oct 16, 2026 · 2 revisions

PPU: the Ricoh 2C02

Specification: docs/ppu-2c02.md. Crate: crates/rustynes-ppu.

The PPU is a state machine that advances one dot per tick: 341 dots per scanline, with the frame structure, VBlank timing and odd-frame behaviour of each region. It produces the framebuffer, raises NMI at the start of VBlank, runs sprite evaluation, and exposes $2000-$2007.

Key points

  • Per-dot fetches. Background and sprite fetches happen on the dots the hardware performs them, so a mapper watching the PPU address bus sees the same sequence of A12 edges that a real cartridge would. That is what makes MMC3-style scanline counters work without special cases.
  • Sprite evaluation is modelled at cycle resolution, including the hardware sprite-overflow bug.
  • Register quirks such as the $2002 read/VBlank race, the $2007 read buffer and its behaviour during rendering, and open-bus decay are part of the model; the specification lists each with its source.
  • Mapper interaction goes through the PpuBus trait: CHR and nametable reads are mapper-mediated, and the mapper is notified of A12 transitions and scanline/VBlank events (Mapper-Ecosystem).
  • Optional, default-off options cover hardware variations and user preferences: disabling the eight-sprite limit (v3.1.0), a Famicom console model, OAM decay, power-up RAM and palette models, PPU die revisions. Each is described in the specification, and those that change emulation are recorded in movies and checked by netplay.

The NTSC palette can be generated from a composite-signal model or loaded from a .pal file; display filters and shaders run after the core and do not change the emulated framebuffer (Frontend-Architecture).

How it is checked

blargg's VBlank/NMI, sprite-hit and sprite-overflow suites, the PPU sections of AccuracyCoin, and the commercial-ROM framebuffer oracle. Current results are in docs/STATUS.md; known approximations are in docs/accuracy-ledger.md.

Clone this wiki locally