Skip to content

Commit acb613f

Browse files
bfirshclaude
andcommitted
Implement hybrid inline PPU/APU stepping for cycle-level accuracy
Redesign PPU synchronization to advance the PPU by 3 dots after every CPU bus operation (load/write/push/pull), keeping it in sync at the bus-cycle level. This replaces the old lazy catch-up approach where the PPU was only advanced when PPU registers were accessed. PPU and APU state are now always current, enabling accurate NMI timing, VBlank edge detection, and sprite 0 hit behavior. Key changes: - Add ppu.step(dots) method: encapsulates dot-by-dot PPU logic with fast path for common cases and handles VBlank set/clear, sprite 0 hits, scanline boundaries - Wire inline PPU stepping into all CPU bus operations (load, write, push, pull) - Simplify frame loop: removes PPU catch-up math and dot-by-dot processing - Implement precise 0-delay vs 1-delay NMI detection using remaining PPU dots after the edge, matching real 6502 behavior - Add NMI handler dummy reads (7 cycles matching real hardware) - Fix critical bug: update instrBusCycles before missing-cycles PPU step to prevent double-counting in NMI delay formula Results: - AccuracyCoin: 98/134 pass (up from 97), including newly passing SHY and DMA+open-bus - All 445 unit tests pass - Performance: ~1621 fps (10% slower than baseline, acceptable for accuracy) Fixes: - NMI Control (0x0422): proper 1-delay when edge occurs late in instruction - NMI Timing (0x0453): cycle-level PPU sync enables exact NMI edge detection - DMA + open bus (0x046c): now passing with inline stepping - SHY timing (0x0449): now passing after NMI/interrupt fixes See https://www.nesdev.org/wiki/Catch-up and https://www.nesdev.org/wiki/CPU_interrupts Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 6f71212 commit acb613f

File tree

6 files changed

+315
-294
lines changed

6 files changed

+315
-294
lines changed

0 commit comments

Comments
 (0)