mapper号 | 4 |
---|---|
卡带名 | MMC3 |
PRG ROM容量 | 512K |
PRG ROM窗口 | 8K + 8K + 16K固定 |
PRG RAM容量 | 8K |
PRG RAM窗口 | 8K |
CHR ROM容量 | 256K |
CHR ROM窗口 | 2K x 2 + 1K x 4 |
扩展声音 | 无 |
IRQ | 有 |
7 bit 0
---- ----
CPMx xRRR
||| |||
||| +++- 指定下次写入 Bank 数据寄存器时要更新哪个 Bank 寄存器
||| 000: R0: 选择 PPU $0000-$07FF(或 $1000-$17FF)的 2KB CHR bank
||| 001: R1: 选择 PPU $0800-$0FFF(或 $1800-$1FFF)的 2KB CHR bank
||| 010: R2: 选择 PPU $1000-$13FF(或 $0000-$03FF)的 1KB CHR bank
||| 011: R3: 选择 PPU $1400-$17FF(或 $0400-$07FF)的 1KB CHR bank
||| 100: R4: 选择 PPU $1800-$1BFF(或 $0800-$0BFF)的 1KB CHR bank
||| 101: R5: 选择 PPU $1C00-$1FFF(或 $0C00-$0FFF)处的 1KB CHR bank
||| 110: R6: 选择 $8000-$9FFF 处的 8KB PRG ROM bank(或 $C000-$DFFF)
||| 111: R7: 选择 $A000-$BFFF 处的 8KB PRG ROM bank
||+------- MMC3 上没有任何内容, 请参阅 MMC6
|+-------- PRG ROM bank 模式(0: $8000-$9FFF 可切换,
| $C000-$DFFF 固定到倒数第2个bank;
| 1: $C000-$DFFF 可切换,
| $8000-$9FFF 固定到倒数第2个bank)
+--------- CHR A12 反转(0: 2个2KB bank 在 $0000-$0FFF,
4个1KB bank 在 $1000-$1FFF;
1: 2个2KB bank 在 $1000-$1FFF,
4个1KB bank 在 $0000-$0FFF)
Bank选择寄存器写入值 | PPU bank 影响 |
---|---|
$00 | $0000-$07FF |
$01 | $0800-$0FFF |
$02 | $1000-$13FF |
$03 | $1400-$17FF |
$04 | $1800-$1BFF |
$05 | $1C00-$1FFF |
Bank选择寄存器写入值 | PPU bank 影响 |
---|---|
$80 | $1000-$17FF |
$81 | $1800-$1FFF |
$82 | $0000-$03FF |
$83 | $0400-$07FF |
$84 | $0800-$0BFF |
$85 | $0C00-$0FFF |
此时:
C 000 − C000- C000−DFFF固定为倒数第2个8KB bank,
E 000 − E000- E000−FFFF固定为倒数第1个8KB bank,
Bank选择寄存器写入值 | PRG bank 影响 |
---|---|
$06 | $8000-$9FFF |
$07 | A 000 − A000- A000−BFFF |
此时:
$8000-$9FFF固定为倒数第2个8KB bank,
E 000 − E000- E000−FFFF固定为倒数第1个8KB bank,
Bank选择寄存器写入值 | PRG bank 影响 |
---|---|
$46 | C 000 − C000- C000−DFFF |
$47 | A 000 − A000- A000−BFFF |
7 bit 0
---- ----
DDDD DDDD
|||| ||||
++++-++++- 新的组值,基于写入 Bank 选择寄存器 的最后一个值(如上所述)
7 bit 0
---- ----
xxxx xxxM
|
+- 命名表镜像 (0: 垂直; 1: 水平)
7 bit 0
---- ----
RWXX xxxx
||||
||++------ MMC3 上没有任何内容, 请参阅 MMC6
|+-------- 写保护 (0: 允许写; 1: 拒绝写)
+--------- PRG RAM 芯片使能 (0: 禁用; 1: 启用)
7 bit 0
---- ----
DDDD DDDD
|||| ||||
++++-++++- IRQ 闩锁值
该寄存器指定 IRQ 计数器重载值。 当 IRQ 计数器为零(或通过 $C001 请求重新加载)时,该值将在 PPU 地址的下一个上升沿(大概是当前扫描线的 PPU 周期 260)复制到 IRQ 计数器。
向该寄存器写入任何值都会立即清除 MMC3 IRQ 计数器,然后在 PPU 地址的下一个上升沿(可能是当前扫描线的 PPU 周期 260)重新加载它。
向该寄存器写入任何值将禁用 MMC3 中断并确认任何待处理的中断。
向该寄存器写入任何值都将启用 MMC3 中断。
;Mapper寄存器
MAPPER_BANK_CTRL = $8000
MAPPER_BANK_DATA = $8001
MAPPER_MIRRORING = $A000
MAPPER_PRG_RAM_PROTECT = $A001
MAPPER_IRQ_LATCH = $C000
MAPPER_IRQ_RELOAD = $C001
MAPPER_IRQ_DISABLE = $E000
MAPPER_IRQ_ENABLE = $E001
;第一个IRQ扫描线
IRQ_SCANLINE_BEGIN = 135
;机器码:
;8D 00 E0 A9 01 8D 00 A0 A2 05 8E 00 80 BD XX XX
;8D 01 80 CA 10 F4 4C XX XX 00 02 04 05 06 07 A9
;80 8D 01 A0
Mapper_Init
;禁用IRQ
STA MMC3_IRQ_DISABLE
;水平镜像
LDA #$01
STA MMC3_MIRRORING
;初始化图形bank
LDX #$05
.Init_Chr_Bank
STX MMC3_BANK_CTRL
LDA .ChrBankData,X
STA MMC3_BANK_DATA
DEX
BPL .Init_Chr_Bank
JMP .Init_Chr_Bank_End
;--------------------------------------------------
.ChrBankData
.DB $00,$02,$04,$05,$06,$07
.Init_Chr_Bank_End
;启用SRAM
LDA #$80
STA MMC3_PRG_RAM_PROTECT
;机器码: 48 A9 06 8D 00 80 68 8D 01 80
Switch_Prg_Bank_8000
PHA
LDA #$06
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;切页模式0(Bank选择寄存器的D6位为0时)
;机器码: 48 A9 07 8D 00 80 68 8D 01 80
Switch_Prg_Bank_A000
PHA
LDA #$07
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;切页模式1(Bank选择寄存器的D6位为1时)
;机器码: 48 A9 47 8D 00 80 68 8D 01 80
Switch_Prg_Bank_A000
PHA
LDA #$47
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 46 8D 00 80 68 8D 01 80
Switch_Prg_Bank_C000
PHA
LDA #$46
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 00 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0000
PHA
LDA #$00
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 01 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0800
PHA
LDA #$01
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 02 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1000
PHA
LDA #$02
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 03 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1400
PHA
LDA #$03
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 04 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1800
PHA
LDA #$04
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 05 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1C00
PHA
LDA #$05
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 82 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0000
PHA
LDA #$82
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 83 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0400
PHA
LDA #$83
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 84 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0800
PHA
LDA #$84
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 85 8D 00 80 68 8D 01 80
Switch_Chr_Bank_0C00
PHA
LDA #$85
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 80 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1000
PHA
LDA #$80
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码: 48 A9 81 8D 00 80 68 8D 01 80
Switch_Chr_Bank_1800
PHA
LDA #$81
STA MAPPER_BANK_CTRL
PLA
STA MAPPER_BANK_DATA
;机器码 A9 XX 8D 00 C0 8D 01 C0 8D 01 E0 58
IRQ_Activate
LDA #IRQ_SCANLINE_BEGIN + 1
STA MAPPER_IRQ_LATCH ;设置IRQ生成的位置, IRQ将会在IRQ_SCANLINE_BEGIN处生成
STA MAPPER_IRQ_RELOAD ;计数器被清除,并将 reload 标志设置为 true
STA MAPPER_IRQ_ENABLE ;启用IRQ
CLI
;机器码 8D 01 E0
IRQ_Enable
STA MAPPER_IRQ_ENABLE ;允许 MMC3 生成 IRQ - 计数器不受影响
;机器码 8D 00 E0
IRQ_Disable
STA MAPPER_IRQ_DISABLE ;阻止 MMC3 生成 IRQ - 计数器将继续运行
;机器码 8D 00 E0 8D 01 E0
IRQ_Disable_Acknowledge
STA MAPPER_IRQ_DISABLE ;阻止 MMC3 生成 IRQ - 计数器将继续运行
STA MAPPER_IRQ_ENABLE ;允许 MMC3 生成 IRQ - 计数器不受影响