FC MMC3 (Mapper 4) 操作

MMC3(TxROM)

概览

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

寄存器

Bank 选择 ($8000-$9FFE, 偶数)

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)
CHR Bank 切换
切换模式0(Bank选择寄存器的D7位为0时)
Bank选择寄存器写入值 PPU bank 影响
$00 $0000-$07FF
$01 $0800-$0FFF
$02 $1000-$13FF
$03 $1400-$17FF
$04 $1800-$1BFF
$05 $1C00-$1FFF
切换模式1(Bank选择寄存器的D7位为1时)
Bank选择寄存器写入值 PPU bank 影响
$80 $1000-$17FF
$81 $1800-$1FFF
$82 $0000-$03FF
$83 $0400-$07FF
$84 $0800-$0BFF
$85 $0C00-$0FFF
PRG Bank 切换
切换模式0(Bank选择寄存器的D6位为0时)

此时:

C 000 − C000- C000DFFF固定为倒数第2个8KB bank,

E 000 − E000- E000FFFF固定为倒数第1个8KB bank,

Bank选择寄存器写入值 PRG bank 影响
$06 $8000-$9FFF
$07 A 000 − A000- A000BFFF
切换模式1(Bank选择寄存器的D6位为1时)

此时:

$8000-$9FFF固定为倒数第2个8KB bank,

E 000 − E000- E000FFFF固定为倒数第1个8KB bank,

Bank选择寄存器写入值 PRG bank 影响
$46 C 000 − C000- C000DFFF
$47 A 000 − A000- A000BFFF

Bank 数据 ($8001-$9FFF, 奇数)

7  bit  0
---- ----
DDDD DDDD
|||| ||||
++++-++++- 新的组值,基于写入 Bank 选择寄存器 的最后一个值(如上所述)

镜像 ( A 000 − A000- A000BFFE, 偶数)

7  bit  0
---- ----
xxxx xxxM
        |
        +- 命名表镜像 (0: 垂直; 1: 水平)

PRG RAM 保护 ( A 001 − A001- A001BFFF, 奇数)

7  bit  0
---- ----
RWXX xxxx
||||
||++------ MMC3 上没有任何内容, 请参阅 MMC6
|+-------- 写保护 (0: 允许写; 1: 拒绝写)
+--------- PRG RAM 芯片使能 (0: 禁用; 1: 启用)

IRQ闩锁 ( C 000 − C000- C000DFFE, 偶数)

7  bit  0
---- ----
DDDD DDDD
|||| ||||
++++-++++- IRQ 闩锁值

该寄存器指定 IRQ 计数器重载值。 当 IRQ 计数器为零(或通过 $C001 请求重新加载)时,该值将在 PPU 地址的下一个上升沿(大概是当前扫描线的 PPU 周期 260)复制到 IRQ 计数器。

IRQ 重新加载 ( C 001 − C001- C001DFFF, 奇数)

向该寄存器写入任何值都会立即清除 MMC3 IRQ 计数器,然后在 PPU 地址的下一个上升沿(可能是当前扫描线的 PPU 周期 260)重新加载它。

IRQ 禁用 ( E 000 − E000- E000FFFE, 偶数)

向该寄存器写入任何值将禁用 MMC3 中断并确认任何待处理的中断。

IRQ 启用 ( E 001 − E001- E001FFFF, 奇数)

向该寄存器写入任何值都将启用 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

切换 PRG bank

切换 PRG bank 到 $8000-9FFF ($8000写入$00或$06, $8001写入 bank 号)
;机器码: 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
切换 PRG bank 到 $A000-BFFF ($8000写入$07或$47, $8001写入 bank 号)
;切页模式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
切换 PRG bank 到 $C000-DFFF ($8000写入$46, $8001写入 bank 号)
;机器码: 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

切换 CHR bank

CHR切换模式0(Bank选择寄存器的D7位为0时)
切换 CHR bank 到 PPU $0000-$07FF ($8000写入$00, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $0800-$0FFF ($8000写入$01, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1000-$13FF ($8000写入$02, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1400-$17FF ($8000写入$03, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1800-$1BFF ($8000写入$04, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1C00-$1FFF ($8000写入$05, $8001写入 bank 号)
;机器码: 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
CHR切换模式1(Bank选择寄存器的D7位为1时)
切换 CHR bank 到 PPU $0000-$03FF ($8000写入$82, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $0400-$07FF ($8000写入$83, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $0800-$0BFF ($8000写入$84, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $0C00-$0FFF ($8000写入$85, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1000-$17FF ($8000写入$80, $8001写入 bank 号)
;机器码: 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
切换 CHR bank 到 PPU $1800-$1FFF ($8000写入$81, $8001写入 bank 号)
;机器码: 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

IRQ使用

IRQ首次启用 ($C000写入扫描线, $C001, $E001写入任意值)
;机器码 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
IRQ启用 ($E001写入任意值)
;机器码 8D 01 E0
IRQ_Enable
 STA MAPPER_IRQ_ENABLE	;允许 MMC3 生成 IRQ - 计数器不受影响
IRQ禁用 ($E000写入任意值)
;机器码 8D 00 E0
IRQ_Disable
 STA MAPPER_IRQ_DISABLE	;阻止 MMC3 生成 IRQ - 计数器将继续运行
IRQ确认 ($E000写入任意值)
;机器码 8D 00 E0 8D 01 E0
IRQ_Disable_Acknowledge
 STA MAPPER_IRQ_DISABLE	;阻止 MMC3 生成 IRQ - 计数器将继续运行
 STA MAPPER_IRQ_ENABLE	;允许 MMC3 生成 IRQ - 计数器不受影响

你可能感兴趣的:(6502,6502asm,FC,6502,fc,NES)