218. Mapper000 NROM
创建
第 218 / 356 · tests/chapter_02_rom_loading/test_218_mapper000_nrom.py
创建 emulator/cartridge/mapper000.py::Mapper000.read_prg,用于 NROM 的 CPU 地址映射。
此步骤存在的原因
NROM-128 将一个 16 KiB 存储体镜像到 $8000-$FFFF;NROM-256 则直接映射 32 KiB。把这种转换保留在映射器中,可以避免 Cartridge 变成硬件行为的载体。它使用了第 217 课暴露出的 PRG 和 CHR 负载。
在此课程边界下的建议实现
from dataclasses import dataclass
PRG_ROM_START = 0x8000
PRG_ROM_END = 0xFFFF
NROM_128_SIZE = 16 * 1024
NROM_256_SIZE = 32 * 1024
CHR_ROM_SIZE = 8 * 1024
@dataclass(frozen=True)
class Mapper000:
prg_rom: bytes
chr_rom: bytes
def read_prg(self, addr: int) -> int:
if not (PRG_ROM_START <= addr <= PRG_ROM_END):
raise ValueError(
f"Address out of PRG ROM range: {addr:04X}"
)
if len(self.prg_rom) == NROM_128_SIZE:
offset = (addr - PRG_ROM_START) % NROM_128_SIZE
elif len(self.prg_rom) == NROM_256_SIZE:
offset = addr - PRG_ROM_START
else:
raise ValueError(
"Mapper000 supports only 16KB or 32KB PRG ROM"
)
return self.prg_rom[offset]不变量:只接受 CPU 地址 $8000-$FFFF,且 PRG 必须恰好是 16 或 32 KiB;仅在 16 KiB 情形下做镜像;保持 PRG/CHR 构造函数参数顺序不变。一个常见错误是直接用 CPU 地址索引 prg_rom,或者把这种转换实现在 Cartridge 上。read_chr、PPU 路由、CHR RAM、写入、镜像方式以及存储体切换均不在此步骤范围内。
此步骤范围之外
1. Lesson 219 adds `read_chr` for the PPU-side CHR range.
2. Lesson 220 adds mapper selection.
3. PPU routing, CHR RAM, writes, mirroring, and bank switching come later.运行本课
uv run pytest tests/chapter_02_rom_loading/test_218_mapper000_nrom.py -v