239. Ppu 内部滚动地址寄存器

引入 PPU 内部的滚动/地址寄存器。

239 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_239_ppu_internal_scroll_address_registers.py

参考资料

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

要更新的文件

emulator/ppu/ppu.py

要添加的字段

vram_addr: int = 0
temp_vram_addr: int = 0
fine_x: int = 0
second_write_toggle: bool = False

为什么需要这一步

PPUADDR($2006)、PPUSCROLL($2005)、PPUDATA($2007)以及渲染,并不只是使用简单的单字节寄存器字段。PPU 拥有内部的地址/滚动状态。

常见的 nesdev 命名

v = current VRAM address
t = temporary VRAM address
x = fine X scroll
w = first/second write toggle

本教程中的命名

vram_addr           -> v
temp_vram_addr      -> t
fine_x              -> x
second_write_toggle -> w

简要含义

  • vram_addr 是当前 PPU 内存地址,被 PPUDATA 和渲染逻辑使用。
  • temp_vram_addr 由 PPUADDR/PPUSCROLL 写入逐步构建,之后再被复制。
  • fine_x 存储精细的水平滚动偏移量,范围 0-7。(图块内像素级的水平滚动偏移)
  • second_write_toggle 用于跟踪对 $2005/$2006 的第一次写入与第二次写入。

建议实现的伪代码

@dataclass
class PPU:
    ...
    vram_addr: int = 0
    temp_vram_addr: int = 0
    fine_x: int = 0
    second_write_toggle: bool = False

不在本步范围内

  • PPUSCROLL 行为
  • 精确的渲染滚动重载时序
  • 名称表渲染

运行本课

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