220. 映射器工厂

创建一个映射器工厂。

220 / 356 · tests/chapter_02_rom_loading/test_220_mapper_factory.py

要创建的文件

emulator/cartridge/mapper_factory.py

要实现的函数

create_mapper(cartridge: Cartridge)

此步骤存在的原因

Cartridge 对象存储了从 ROM 中加载出的事实

Cartridge(prg_rom, chr_rom, mapper_number)

但 CPU/PPU 并不直接与原始的 PRG/CHR 字节打交道,而是通过映射器进行交互,因为映射器就是那块把模拟器地址转换为 ROM 偏移量的卡带硬件。

当前流程

raw .nes bytes
    -> Cartridge.from_ines_bytes(data)
    -> create_mapper(cartridge)
    -> Mapper000(prg_rom, chr_rom)

工厂的职责

  • 检查 cartridge.mapper_number
  • 创建正确的映射器对象
  • 对不受支持的映射器明确报错

工厂不应该做的事情

  • 解析 iNES 字节
  • 执行 CPU 地址转换
  • 了解 CpuBus 的路由方式
  • 修改 Cartridge

预期的实现形态

from emulator.cartridge.cartridge import Cartridge
from emulator.cartridge.mapper000 import Mapper000


def create_mapper(cartridge: Cartridge):
    if cartridge.mapper_number == 0:
        return Mapper000(
            prg_rom=cartridge.prg_rom,
            chr_rom=cartridge.chr_rom,
        )

    raise ValueError(f"Unsupported mapper: {cartridge.mapper_number}")

为何要把它与 CpuBus 分开

CpuBus 应当负责读写的路由。它不应该承担每一条卡带映射器选择规则的职责。在我们把基于卡带的 PRG ROM 读取整合进总线之前,把映射器的创建放在这里可以降低耦合度。

运行本课

uv run pytest tests/chapter_02_rom_loading/test_220_mapper_factory.py -v