Loading

从零开始的nes模拟器-[8] Mapper适配

参考:

这篇博文会随着适配的mappers而更新......

iNES 1.0 mapper

mapper 000

参考:

image-20220215145600547

这是最简单的 mapper, mapper000对应的卡带的 PRG ROM 最多只有 32k , 刚好可以塞进 0x8000 - 0xFFFF , 也就是不涉及 bank 的切换。 不过因为存在 PRG ROM16k 的情况 (填不满默认的地址范围), 所以会存在mirror的情况。

关键代码

cpu读写内存

bool Mapper_000::cpuMapRead(uint16_t addr, uint32_t &mapped_addr, uint8_t &data)
{
    // if PRGROM is 16KB
    //     CPU Address Bus          PRG ROM
    //     0x8000 -> 0xBFFF: Map    0x0000 -> 0x3FFF
    //     0xC000 -> 0xFFFF: Mirror 0x0000 -> 0x3FFF
    // if PRGROM is 32KB
    //     CPU Address Bus          PRG ROM
    //     0x8000 -> 0xFFFF: Map    0x0000 -> 0x7FFF

    // PRGROM分为16KB和32KB两种情况
    // 如果16KB,则其实只有0x3FFF使用到,从0x4000 -> 0x7FFF等同于0x0000 -> 0x3FFF
    if (addr >= 0x8000 && addr <= 0xFFFF)
    {
        mapped_addr = addr & (nPRGBanks > 1 ? 0x7FFF : 0x3FFF);
        return true;
    }

    return false;
}

bool Mapper_000::cpuMapWrite(uint16_t addr, uint32_t &mapped_addr, uint8_t data)
{
    // data没有使用,map中没有寄存器,cpu不会向map写入数据
    if (addr >= 0x8000 && addr <= 0xFFFF)
    {
        mapped_addr = addr & (nPRGBanks > 1 ? 0x7FFF : 0x3FFF);
        return true;
    }

    return false;
}

mapper 002

参考:

image-20220215134810368

banks 的规划(映射关系)

  • CPU 0x8000-0xBFFF,16KB 可切换的 PRG ROM bank ( 也就是说一个 bank 的大小为 16 k )
  • CPU 0xCFFF-0xFFFF,16KB 固定的 PRG ROM bank,这部分地址空间固定映射到最后一块 PRG bank
  • CHR 容量 8KB,就映射到 PPU 开头的 2KB

UxROM 只支持 2 种镜像垂直和水平,而且设置方式是制作卡带时就焊接好的,它有一个 bank 选择寄存器,向 0x8000-0xFFFF 这部分地址空间的任一地址写入 PRG bank number 即可选择一 PRG bank 映射到 0x8000

关键代码

内部变量

//内部寄存器
uint8_t regLo = 0x00; // 0x8000-0xBFFF 的 bank 的 id
uint8_t regHi = 0x00; // 0xCFFF-0xFFFF 的 bank 的 id ( 这个是 固定 的)

初始化

regLo = 0x00;
regHi = nPRGBanks - 1;

地址映射

// cpuMapRead
// 低地址 0x4000 对应 16 k 
mapped_addr = regLo * 0x4000 + (addr & 0x3FFF);
// 高地址
mapped_addr = regHi * 0x4000 + (addr & 0x3FFF);

切换bank

// cpuMapWrit
regLo = data & 0x0F;
posted @ 2022-02-15 15:21  CHZarles  阅读(772)  评论(0)    收藏  举报