226. PPU 读寄存器

添加 PPU.read_register(addr)。

226 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_226_ppu_read_register.py

待更新文件

emulator/ppu/ppu.py

待实现方法

PPU.read_register(addr: int) -> int

该步骤存在的原因

有些 PPU 寄存器可以被 CPU 读取。读取同样是内存映射 I/O,而不是普通的 RAM 访问。PPU 决定 CPU 收到的值。

在这个简化阶段可读的寄存器

$2002 -> status
$2007 -> data

关于 $2004/OAMDATA 的说明:OAMDATA 是可读的,但之后它会成为通往内部 OAM 精灵内存的一个端口。该行为将在 OAM 专门的步骤中进行测试。这个早期的寄存器读取测试不会将自己绑定在旧的占位字段 oam_data 的行为上。

关于 $2007/PPUDATA 的说明:PPUDATA 是可读的,但之后它会成为一个带缓冲的 PPU 内存读取端口。该行为将在 PPUDATA 专门的步骤中进行测试。这个早期的寄存器读取测试不会将自己绑定在旧的占位字段 data 的行为上。

为何只有这些

从 CPU 一侧来看,有几个 PPU 寄存器主要是只写的。不受支持的读取应当明确地失败,而不是假装所有 PPU 寄存器都是普通的 RAM。

重要的未来准确性说明

真实的 PPUSTATUS 读取具有副作用。读取 $2002 会清除 VBlank 标志,并重置内部的地址/滚动锁存器。我们暂时有意不对这些副作用进行建模。这一步只是建立基本的寄存器边界。

建议的实现伪代码

def read_register(self, addr: int) -> int:
    match addr:
        case 0x2002:
            return self.status
        case 0x2007:
            return self.data
        case _:
            raise ValueError(...)

运行本课

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