225. PPU 写寄存器
添加 PPU.write_register(addr, value)。
第 225 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_225_ppu_write_register.py
待更新文件
emulator/ppu/ppu.py待实现方法
PPU.write_register(addr: int, value: int) -> None该步骤存在的原因
CPU 通过内存映射 I/O 写入 PPU 寄存器。当 CPU 写入地址 $2000 时,它写入的不是 RAM,而是在更新 PPUCTRL 寄存器。
在这一步中,PPU.write_register 接收的是范围在 $2000-$2007 内的规范化 PPU 寄存器地址。CpuBus 针对 $2008-$3FFF 的镜像将在之后的步骤中实现。
在这个简化阶段可写的寄存器
$2000 -> ctrl
$2001 -> mask
$2003 -> oam_addr
$2004 -> oam_data / OAMDATA port
$2005 -> scroll
$2006 -> addr
$2007 -> data注意 $2002 被有意排除在外。
$2002 不可写的原因:$2002 是 PPUSTATUS。从 CPU 一侧来看,它是只读的。测试在需要模拟某个状态值时,可以直接设置 ppu.status,但 write_register($2002, value) 应当失败。
单字节策略
PPU 寄存器是 8 位的。目前,写入操作只应保留数值的低字节。这意味着写入 0x123 会存储 0x23。
建议的实现伪代码
def write_register(self, addr: int, value: int) -> None:
value = value & 0xFF
match addr:
case 0x2000:
self.ctrl = value
case 0x2001:
self.mask = value
case 0x2003:
self.oam_addr = value
case 0x2004:
self.oam_data = value
case 0x2005:
self.scroll = value
case 0x2006:
self.addr = value
case 0x2007:
self.data = value
case _:
raise ValueError(...)未来说明
之后,$2004/OAMDATA 会成为通往内部 OAM 精灵内存的一个端口。到那时,写入 $2004 也可能会使 oam_addr 递增。这个早期测试不应要求在一次 OAMDATA 写入之后 oam_addr 保持不变。
运行本课
uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_225_ppu_write_register.py -v