224. PPU 数据类寄存器属性

创建带有显式寄存器属性的 PPU 数据类。

224 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_224_ppu_dataclass_register_attributes.py

待创建文件

emulator/ppu/ppu.py

待实现的类

PPU

该步骤存在的原因

CPU 通过位于地址 $2000-$2007 的 CPU 可见硬件寄存器与 NES 图像处理单元通信。这些不是普通的 RAM 字节;它们是具有特定含义的命名硬件寄存器。

在这第一个 PPU 步骤中,我们只创建寄存器状态。我们尚未实现读取、写入、渲染、VBlank、滚动、VRAM 或 DMA。

该测试验证最初的 CPU 可见 PPU 寄存器字段是否存在。它并不要求这些字段永远是唯一的字段。之后的步骤可能会添加内部 PPU 状态,例如 ppu_bus、vram_addr 或 addr_latch。

CPU 可见的 PPU 寄存器窗口

$2000 PPUCTRL   -> ctrl
$2001 PPUMASK   -> mask
$2002 PPUSTATUS -> status
$2003 OAMADDR   -> oam_addr
$2004 OAMDATA   -> oam_data
$2005 PPUSCROLL -> scroll
$2006 PPUADDR   -> addr
$2007 PPUDATA   -> data

重要的设计选择

使用显式的整数字段,类似于 CPU 寄存器。这样可以让调试保持简单,并使硬件模型清晰可见:

assert ppu.ctrl == 0x80

此处不要添加 OAMDMA。OAMDMA 在 CPU 地址 $4014 处被访问,会触发一次 256 字节的 DMA 拷贝到精灵内存中。它与 PPU 相关,但并不属于常规的 $2000-$2007 PPU 寄存器窗口。

建议的实现伪代码

from dataclasses import dataclass


@dataclass
class PPU:
    ctrl: int = 0
    mask: int = 0
    status: int = 0
    oam_addr: int = 0
    oam_data: int = 0
    scroll: int = 0
    addr: int = 0
    data: int = 0

运行本课

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