[FC][常见Mapper IRQ研究]

本次IRQ研究了如下表所示Mapper的IRQ操作:

卡带名 Mapper号
VRC3 73
VRC4 21,23,25
VRC6 24 & 26
VRC7 85
MMC3 4
MMC4 10
MMC5 5
Sunsoft FME-7 69
Namco163 19
Jaleco SS 88006 18
RAMBO-1 64

共计11种Mapper的IRQ操作使用例子
代码内有详细注释, 希望能帮助到感兴趣的人.

[FC][常见Mapper IRQ研究]_第1张图片[FC][常见Mapper IRQ研究]_第2张图片[FC][常见Mapper IRQ研究]_第3张图片

Mapper控制代码(MMC3为例)

[FC][Mapper][MMC3].asm

;==================================================
;Mapper号
MAPPER_NUMBER           = 04
;==================================================
;MMC3 (Mapper 4) 寄存器常量
MAPPER_REG_BANK_CTRL        =   $8000
MAPPER_REG_BANK_DATA        =   $8001
MAPPER_REG_MIRRORING        =   $A000
MAPPER_REG_PRG_RAM_PROTECT  =   $A001
MAPPER_REG_IRQ_LATCH        =   $C000
MAPPER_REG_IRQ_RELOAD       =   $C001
MAPPER_REG_IRQ_DISABLE      =   $E000
MAPPER_REG_IRQ_ENABLE       =   $E001
;==================================================
IRQ_SCANLINE_BEGIN          = 135
IRQ_SCANLINE_1              = 8
IRQ_SCANLINE_2              = 54
IRQ_SCANLINE_3              = 8
;==================================================

;====================================================================================================
;宏常量
;====================================================================================================

;====================================================================================================
MACRO_MAPPER_INIT .MACRO
 ;禁用IRQ
 STA MAPPER_REG_IRQ_DISABLE
 
 ;水平镜像
 LDA #$01
 STA MAPPER_REG_MIRRORING
 
 ;初始化图形bank
 LDX #$05
.Init_Chr_Bank
 STX MAPPER_REG_BANK_CTRL
 LDA .ChrBankData,X
 STA MAPPER_REG_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 MAPPER_REG_PRG_RAM_PROTECT
 .ENDM

;====================================================================================================
MACRO_MAPPER_SOUND_CLEAR .MACRO
 .ENDM
 
;====================================================================================================
MACRO_SRAM_ENABLE .MACRO
 LDA #$80
 STA MAPPER_REG_PRG_RAM_PROTECT
 .ENDM
 
;====================================================================================================
MACRO_SWITCH_BANK_8000_A .MACRO
 PHA
 LDA #$06
 STA MAPPER_REG_BANK_CTRL
 PLA
 STA MAPPER_REG_BANK_DATA
 .ENDM

MACRO_SWITCH_BANK_A000_A .MACRO
 PHA
 LDA #$07
 STA MAPPER_REG_BANK_CTRL
 PLA
 STA MAPPER_REG_BANK_DATA
 .ENDM
 
MACRO_SWITCH_BANK_C000_A .MACRO
 .ENDM

MACRO_SWITCH_BANK_E000_A .MACRO
 .ENDM

;====================================================================================================
MACRO_TRIGGER_FIRST_IRQ .MACRO
 LDA #IRQ_SCANLINE_BEGIN + 1
 STA MAPPER_REG_IRQ_LATCH
 STA MAPPER_REG_IRQ_RELOAD
 STA MAPPER_REG_IRQ_ENABLE
 CLI
 .ENDM
 
;====================================================================================================
MACRO_ENABLE_IRQ  .MACRO
 STA MAPPER_REG_IRQ_ENABLE
 .ENDM
 
;====================================================================================================
MACRO_DISABLE_IRQ  .MACRO
 LDA #$00
 STA MAPPER_REG_IRQ_CTRL
 STA MAPPER_REG_IRQ_ACK
 .ENDM
 
;====================================================================================================
MACRO_ACK_IRQ .MACRO
 STA MAPPER_REG_IRQ_DISABLE
 STA MAPPER_REG_IRQ_ENABLE
 .ENDM
 
;====================================================================================================
MACRO_IRQ_OPERATE   .MACRO

;==================================================
;IRQ滚动模式常量
IRQ_SCROLL_MODE_ZERO    =   0       ;不滚动
IRQ_SCROLL_MODE_LEFT    =   1       ;向左滚动
IRQ_SCROLL_MODE_RIGHT   =   2       ;向右滚动

;IRQ扫描线数据
IRQ_Scanline_Data
 .DB IRQ_SCANLINE_1
 .DB IRQ_SCANLINE_2
 .DB IRQ_SCANLINE_3
 .DW 00 ;关闭IRQ

;IRQ滚动控制模式
IRQ_Scanline_Mode
 .DB IRQ_SCROLL_MODE_RIGHT
 .DB IRQ_SCROLL_MODE_LEFT
 .DB IRQ_SCROLL_MODE_RIGHT
 .DB IRQ_SCROLL_MODE_LEFT

;==================================================
;;IRQ滚动控制
IRQ_Set_Scroll
 LDX IRQ_Process_Index
 LDA IRQ_Scanline_Mode,X
 CMP #IRQ_SCROLL_MODE_LEFT
 BEQ IRQ_Set_Scroll_Left
 CMP #IRQ_SCROLL_MODE_RIGHT
 BEQ IRQ_Set_Scroll_Right
IRQ_Set_Scroll_Zero;不滚动
 LDA #$00
 STA PPU_SCROLL
 STA PPU_SCROLL
 RTS
IRQ_Set_Scroll_Left;向左滚动
 LDA Scroll_H
 STA PPU_SCROLL
 STA PPU_SCROLL
 RTS
IRQ_Set_Scroll_Right;向右滚动
 LDA #$00
 SEC
 SBC Scroll_H
 STA PPU_SCROLL
 STA PPU_SCROLL
 RTS
 
;==================================================
;;IRQ滚动控制
IRQ_Set_Ctrl
 LDX IRQ_Process_Index
 LDA IRQ_Scanline_Data,X
 BNE IRQ_Process_Latch
IRQ_Process_Disable;禁用IRQ
 STA MAPPER_REG_IRQ_DISABLE
 STA IRQ_Process_Index
 RTS
IRQ_Process_Latch;设置下次 IRQ 触发扫描线
 STA MAPPER_REG_IRQ_LATCH
 INC IRQ_Process_Index
 RTS

;==================================================
;IRQ处理
IRQ_Process_By_Index
 JSR IRQ_Set_Scroll
 JSR IRQ_Set_Ctrl
IRQ_Process_End
 RTS
 
 .ENDM
 

公用配置

[FC][Mapper][Config].asm

;[FC][Mapper][IRQ]
;FlameCyclone 20231201

 .INCLUDE "[FC][Mapper][MMC3].asm"
 ;.INCLUDE "[FC][Mapper][MMC5].asm"
 ;.INCLUDE "[FC][Mapper][Namco163].asm"
 ;.INCLUDE "[FC][Mapper][VRC2&4].asm"
 ;.INCLUDE "[FC][Mapper][VRC3].asm"
 ;.INCLUDE "[FC][Mapper][VRC6].asm"
 ;.INCLUDE "[FC][Mapper][VRC7].asm"
 ;.INCLUDE "[FC][Mapper][FME7].asm"
 ;.INCLUDE "[FC][Mapper][Mapper18].asm"
 ;.INCLUDE "[FC][Mapper][Mapper64].asm"
 
;文件头配置
NES_16KB_PRG_SIZE           =   2
NES_8KB_CHR_SIZE            =   1
BANK_DATA_MASK              =   NES_16KB_PRG_SIZE * 2 - 1     ;bank号掩码
RESET_BANK                  =   NES_16KB_PRG_SIZE * 2 - 1
;======================================================================
PRG_DATA_BANK_C000          =   NES_16KB_PRG_SIZE * 2 - 2
PRG_DATA_BANK_E000          =   NES_16KB_PRG_SIZE * 2 - 1

;文件头
;======================================================================
 .INESPRG NES_16KB_PRG_SIZE ;16KB PRG 数量
 .INESCHR NES_8KB_CHR_SIZE  ;8KB CHR 数量
 .INESMAP MAPPER_NUMBER
 .INESMIR 0     ;命名表镜像 0水平 1垂直

;==================================================
;NES端口常量
PPU_CTRL                    =   $2000   ;PPU控制寄存器
PPU_MASK                    =   $2001   ;PPU掩码寄存器
PPU_STATUS                  =   $2002   ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
PPU_OAM_ADDR                =   $2003   ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
PPU_OAM_DATA                =   $2004   ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
PPU_SCROLL                  =   $2005   ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 
PPU_ADDRESS                 =   $2006   ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
PPU_DATA                    =   $2007   ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 
OAM_DMA                     =   $4014   ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
APU_STATUS                  =   $4015   ;声音通道切换
JOY1_FRAME                  =   $4016   ;手柄1 + 选通
JOY2_FRAME                  =   $4017   ;手柄2 + 选通

;--------------------------------------------------
PROGRAM_BANK                =   PRG_DATA_BANK_E000
PROGRAM_ADDR                =   $E000

;==================================================
;零页内存地址配置
Use_Ram_Begin               =   $80
 .RSSET Use_Ram_Begin
PPU_Ctrl_Buf                .RS 1
PPU_Msak_Buf                .RS 1
PPU_Scroll_H                .RS 1
PPU_Scroll_V                .RS 1
FC_Data_L                   .RS 1
FC_Data_H                   .RS 1
FC_Data_Buf                 .RS 1
FC_Data_Index               .RS 1

;==================================================
GAMEPAD_MERGE_FLAG          =   $04
    
Gamepad_Keep                .RS 2
Gamepad_Once                .RS 2
Gamepad_Temp                .RS 2   
Gamepad_0_State             .RS 1
Gamepad_1_State             .RS 1
Gamepad_0_Value             .RS 1
Gamepad_1_Value             .RS 1
Gamepad_Port_Value          .RS 1
Gamepad_Merge               .RS 1

;==================================================
Scroll_H                    .RS 1
Scroll_V                    .RS 1
IRQ_Process_Index           .RS 1

;==================================================
Prg_Bank_8000               .RS 1
Prg_Bank_A000               .RS 1
Prg_Bank_C000               .RS 1
Prg_Bank_E000               .RS 1
Prg_Bank_8000_Bak           .RS 1
Prg_Bank_A000_Bak           .RS 1
Prg_Bank_C000_Bak           .RS 1
Prg_Bank_E000_Bak           .RS 1

;==================================================
Prg_Bank_A_Bak              .RS 1

;==================================================

公用主程序代码

[FC][Mapper][IRQ].asm

 .INCLUDE "[FC][Mapper][Config].asm"
 
;CHR图形数据
;======================================================================
 .BANK NES_16KB_PRG_SIZE * 2
 .INCBIN "chr_bank/chr_data.chr"
 
 .BANK PROGRAM_BANK & BANK_DATA_MASK
 .ORG PROGRAM_ADDR
 
;--------------------------------------------------
Attributes_Data
;命名表属性
 .DB $00,$00,$00,$00,$00,$00,$00,$00,$55,$55,$55,$55,$55,$55,$55,$55
 .DB $55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55
 .DB $55,$F5,$F5,$F5,$F5,$F5,$F5,$55,$55,$FF,$FF,$FF,$FF,$FF,$FF,$75
 .DB $A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
;--------------------------------------------------
;调色板数据
Palette_Data
 .DB $0F,$27,$20,$0F,$0F,$23,$20,$0F,$0F,$21,$20,$0F,$0F,$24,$20,$0F
 .DB $0F,$21,$24,$25,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F

;--------------------------------------------------
;命名表文本索引
Name_Table_Text_Index
 .DW .Name_Table_Text_Data_1
 .DW .Name_Table_Text_Data_2
 .DW .Name_Table_Text_Data_3
 .DW .Name_Table_Text_Data_4
 .DW .Name_Table_Text_Data_5
 .DW $00;结束标记

.Name_Table_Text_Data_1
 .DB $20,$48
 .STR "MAPPER IRQ TEST"

.Name_Table_Text_Data_2
 .DB $22,$28
 .STR "SCROLL RIGHT"

.Name_Table_Text_Data_3
 .DB $22,$68
 .STR "SCROLL LEFT"

.Name_Table_Text_Data_4
 .DB $23,$26
 .STR "MADE BY FLAMECYCLONE"
 
.Name_Table_Text_Data_5
 .DB $23,$6B
 .STR "2023.12.01"
 
;==================================================
;命名表初始化
Init_Name_Table
 LDA #$20
 STA PPU_ADDRESS
 LDA #$00
 STA PPU_ADDRESS
 LDA #$00
 LDY #$00
 LDX #$10
Init_Name_Table_Write
 STA PPU_DATA
 INY
 BNE Init_Name_Table_Write
 DEX
 BNE Init_Name_Table_Write
 RTS
 
;==================================================
;调色板初始化
Init_Palette
 BIT PPU_STATUS
 LDA #$3F
 STA PPU_ADDRESS
 LDA #$00
 STA PPU_ADDRESS
 LDX #$00
Init_Palette_Write
 LDA Palette_Data,X
 STA PPU_DATA
 INX
 CPX #$20
 BCC Init_Palette_Write
 RTS
 
;==================================================
;设置命名表属性
Init_NameTable_Attributes
 BIT PPU_STATUS
 LDA #$23
 STA PPU_ADDRESS
 LDA #$C0
 STA PPU_ADDRESS
 LDX #$00
Init_NameTable_Attributes_Write
 LDA Attributes_Data,X
 STA PPU_DATA
 INX
 CPX #$40
 BCC Init_NameTable_Attributes_Write
 RTS

;==================================================
;初始化命名表文本
Init_Name_Table_Text
 BIT PPU_STATUS
 BIT $FFFF
 
 LDA #$00
 STA 

gitee代码库:

FlameCyclone/FC IRQ (gitee.com)

你可能感兴趣的:(FC,6502,nes,fc,红白机,IRQ)