242. Ppudata 通过 PPU 总线写入

实现通过 PpuBus 进行的 PPUDATA ($2007) 写入。

242 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_242_ppudata_writes_through_ppu_bus.py

参考资料

https://www.nesdev.org/wiki/PPU_registers#PPUDATA

要更新的文件

emulator/ppu/ppu.py

要更新的方法

PPU.write_register(addr, value)

为什么需要这一步

PPUDATA 是位于 $2007 的 CPU 可见寄存器。CPU 写入的是 $2007,但实际被写入的 PPU 内存地址并不是 CPU 地址 $2007。真正的目标是 PPU 内部的 VRAM 地址:

vram_addr

该地址由 PPUADDR ($2006) 设置,随后 PPUDATA ($2007) 通过

PPU 侧总线

PPU.write_register($2007, value)
    -> ppu_bus.write(vram_addr, value)
    -> increment vram_addr

本测试中关于未来兼容性的重要选择

- Use non-CHR addresses such as $2000, not $0000-$1FFF.
  CHR writes will later involve mapper.write_chr / CHR RAM behavior.

- Test increment-by-1 only when PPUCTRL increment mode is clear.
  Later, PPUCTRL bit 2 may select increment-by-32. These tests should not
  block that future behavior.

针对当前阶段的建议实现伪代码

case 0x2007:
    self.data = value
    self.ppu_bus.write(self.vram_addr, value)
    self.vram_addr = (self.vram_addr + 1) & 0x3FFF

未来实现说明

之后,递增量可能变为

increment = 32 if self.ctrl & VRAM_INCREMENT_BY_32 else 1
self.vram_addr = (self.vram_addr + increment) & 0x3FFF

超出范围

  • PPUDATA 读取
  • PPUDATA 读取缓冲
  • 调色板读取例外
  • CHR RAM 写入
  • PPUCTRL 递增 32 行为

运行本课

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