243. Ppuctrl 控制 ppudata 的递增量

PPUCTRL 控制 PPUDATA 将 vram_addr 递增多少。

243 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_243_ppuctrl_controls_ppudata_increment.py

参考资料

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

要更新的文件

emulator/ppu/ppu.py

要添加的常量

CTRL_VRAM_INCREMENT_BY_32 = 1 << 2

为什么需要这一步

PPUDATA ($2007) 会访问当前内部 VRAM 地址上的 PPU 内存。每次访问之后,PPU 都会将该地址递增。

递增量由 PPUCTRL ($2000) 的第 2 位控制:

bit 2 clear -> increment by 1
bit 2 set   -> increment by 32

为什么这很重要

递增 1 适用于沿一行连续的 PPU 内存进行写入。递增 32 适用于在命名表内存中沿一列向下写入。

建议的实现伪代码

CTRL_VRAM_INCREMENT_BY_32 = 1 << 2

case 0x2007:
    self.data = value
    self.ppu_bus.write(self.vram_addr, value)

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

重要事项

请继续用 0x3FFF 对 vram_addr 进行掩码运算,因为 PPU 地址空间是 14 位的:

$0000-$3FFF

超出范围

  • 其他 PPUCTRL 位
  • NMI 启用
  • 图案表选择
  • 基础命名表选择
  • 渲染

运行本课

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