237. Ppu 总线的 chr 区域路由

将 PpuBus 的 CHR 区域读取路由到 mapper。

237 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_237_ppu_bus_chr_area_routing.py

要更新的文件

emulator/bus/ppu_bus.py

要添加/使用的常量

CHR_START = 0x0000
CHR_END = 0x1FFF

什么是 CHR 区域?PPU 地址范围 $0000-$1FFF 是图案表(pattern table)区域,包含之后用于背景和精灵像素的图块图形字节。

重要的 NES 事实

这个区域通常属于卡带,而不是内部 VRAM。

CHR ROM cartridge:
    PPU reads pattern bytes from cartridge CHR ROM.

CHR RAM cartridge:
    PPU can write pattern bytes into cartridge CHR RAM.

当前范围

目前,PpuBus 必须能检测出 CHR 区域的地址。当存在 mapper 时,读取应使用 mapper.read_chr(addr)。

我们在本测试中有意不锁定 CHR 写入行为。未来的步骤可能会为 CHR RAM 支持添加 mapper.write_chr(addr, value),本测试不应阻碍这种演进。

建议的读取伪代码

def read(self, addr: int) -> int:
    addr = addr & PPU_ADDRESS_MASK

    if CHR_START <= addr <= CHR_END:
        if self.mapper is not None:
            return self.mapper.read_chr(addr)
        return self.vram.read(addr)

    return self.vram.read(addr)

目前可能的写入伪代码

def write(self, addr: int, value: int) -> None:
    addr = addr & PPU_ADDRESS_MASK

    if CHR_START <= addr <= CHR_END:
        if self.mapper is not None:
            raise ValueError("CHR writes are not supported yet")
        self.vram.write(addr, value)
        return

    self.vram.write(addr, value)

未来可能的写入伪代码

if CHR_START <= addr <= CHR_END and self.mapper is not None:
    self.mapper.write_chr(addr, value)
    return

未来的区域

$2000-$3EFF:
    currently backed by big VRAM, later nametable VRAM/mirroring

$3F00-$3FFF:
    currently backed by big VRAM, later palette RAM/mirroring

运行本课

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