MMC3
- iNES mapper IDs: 004, 118, 119
- PRG ROM 容量: 512K
- PRG ROM 页大小: 8 KiB
- PRG RAM: 8 KiB
- CHR 容量: 256 KiB ROM
- CHR 页大小: 1 KiB
- Nametable 镜像模式: 可编程,垂直或水平镜像
PRG ROM 内存映射
表格解释:
+-------------+-------------------+
| | Bank Selection |
| CPU MEM |-------------------|
| ADDR. | Mode 0 | Mode 1 |
+-------------+---------+---------+
| $8000-$9FFF | R6 | (-2) |
+-------------+---------+---------+
| $A000-$BFFF | R7 | R7 |
+-------------+---------+---------+
| $C000-$DFFF | (-2) | R6 |
+-------------+---------+---------+
| $E000-$FFFF | (-1) | (-1) |
+-------------+---------+---------+
代码解释:
constexpr const unsigned A14 = 0x4000;
int bank_no = 0;
if (prg_bank_mode1)
addr ^= A14; // $0800 <--> $0c00
switch ((addr & 0x7fff) / 8192) {
case 0: bank_no = R[6]; break;
case 1: bank_no = R[7]; break;
case 2: bank_no = -2; break;
case 3: bank_no = -1; break;
}
prg_addr = bank_no < 0 ? prg_rom.size() : 0;
prg_addr += bank_no * 8192 + addr & 8191;
图形化解释:
Mode 0
------
...
+--------+ |--------|
$8000 | 8 KB |~~~~~~~~~~>| 8 KB |
|--------| |--------|
$A000 | 8 KB |~~~~~~~~~~>| 8 KB |
|--------| |--------|
$C000 | 8 KB |------. | 8 KB |
|--------| | |--------|
$E000 | 8 KB |---. | ...
+--------+ | | |--------|
| `--->| 8 KB |
| |--------|
`------>| 8 KB |
+--------+
Mode 1
------
...
+--------+ |--------|
$8000 | 8 KB |------. | 8 KB |
|--------| | |--------|
$A000 | 8 KB |~~~~~~|~~~>| 8 KB |
|--------| | |--------|
$C000 | 8 KB |~~~~~~|~~~>| 8 KB |
|--------| | |--------|
$E000 | 8 KB |---. | ...
+--------+ | | |--------|
| `--->| 8 KB |
| |--------|
`------>| 8 KB |
+--------+
CHR ROM 内存映射
表格解释:
+-------------+---------------------+
| | Bank Selection |
| PPU MEM |---------------------|
| ADDR. | A12 Inv. | A12 Inv. |
| | = 0 | = 1 |
+-------------+----------+----------+
| $0000-$03FF | | R2 |
+-------------+ R0 +----------|
| $0400-$07FF | | R3 |
+-------------+----------+----------+
| $0800-$0BFF | | R4 |
+-------------+ R1 |----------|
| $0C00-$0FFF | | R5 |
+-------------+----------+----------+
| $1000-$13FF | R2 | |
+-------------+----------+ R0 |
| $1400-$17FF | R3 | |
+-------------+----------+----------+
| $1800-$1BFF | R4 | |
+-------------+----------+ R1 |
| $1C00-$1FFF | R5 | |
+-------------+----------+----------+
R0 和 R1 的最低位被视作 0 处理,导致 R0、R1 只能选中偶数号内存页。每页大小 1KB,因此 R0、R1 实际可分别映射 2KB 内存
代码解释
constexpr const unsigned A12 = 0x1000;
int bank_no = 0;
int offset = addr & 0x03ff;
if (A12_inv)
addr ^= A12;
if (addr < 0x1000) {
offset = addr & 0x07ff;
bank_no = R[addr / 2048] & ~1;
} else {
bank_no = R[2 + (addr & 0x0fff) / 1024];
}
chr_addr = bank_no * 1024 + offset;
图形化解释:
A12 Inversion = 0
-----------------
+--------+
$0000 | 2 KB |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
| | |
|--------| |
$0800 | 2 KB |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~. |
| | ... | |
|--------| |--------+--------| | |
$1000 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | | |
|--------| |--------+ 2 KB |<~~~~~' |
$1400 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | |
|--------| |--------+--------| |
$1800 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | |
|--------| |--------+ 2 KB |<~~~~~~~~~'
$1C00 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | |
+--------+ |--------+--------|
...
A12 Inversion = 1
-----------------
...
+--------+ |--------+--------|
$0000 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | |
|--------| |--------+ 2 KB |<~~~~~~~~~.
$0400 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | |
|--------| |--------+--------| |
$0800 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | |
|--------| |--------+ 2 KB |<~~~~~. |
$0C00 | 1 KB |~~~~~~~~~~~~~~~~>| 1 KB | | | |
|--------| |--------+--------| | |
$1000 | 2 KB | ... | |
| |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' |
|--------| |
$1800 | 2 KB |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
| |
+--------+