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 КиБ на диапазон $8000-$FFFF; NROM-256 отображает 32 КиБ напрямую. Хранение этой трансляции в mapper не даёт Cartridge превратиться в аппаратное поведение. Он использует полезные нагрузки PRG и CHR, предоставленные уроком 217.

Предлагаемая реализация на границе этого урока

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 и ровно 16 или 32 КиБ PRG; зеркалируйте только случай с 16 КиБ; сохраняйте порядок конструктора PRG/CHR. Частая ошибка — индексировать prg_rom напрямую адресом CPU или реализовывать трансляцию в 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