FC合卡菜单精简版编码

文件下载(源码, 菜单nes, 魂斗罗3合1合卡): http://flamecyclone.ys168.com/ 目录: [04][修改文件][HackRom]/[FC][精简合卡菜单].zip
;[FC][精简合卡菜单]
;FlameCyclone
;2020.02.23
;==================================================
RESET_PORT = $E000
MENU_INDEX = 01
MENU_RESET = $F80D
;==================================================
Char_Arrow = $1F
ARROW_X_OFFSET = $35 ;箭头横坐标
ARROW_Y_OFFSET = $47 ;箭头纵坐标
ITEM_COUNT = 03 ;节目总数
;==================================================
BTN_DELAY = 30 ;按键重复触发时长
BTN_SPEED = 10 ;按键重复触发速度
;==================================================
Data_L = $00
Data_H = Data_L + $01
Data_Count = Data_H + $01
;==================================================
Sel_Index = Data_Count + $01
;==================================================
Button_Keep = Sel_Index + $01
Button_Once = Button_Keep+$01
Button_Temp = Button_Once+$01
Button_Buf = Button_Temp+$01
Button_Status = Button_Buf+$01
;==================================================
Second_Time = Button_Status + $01
Btn_Delay = Second_Time + $01
;==================================================
ATTRIBUTE_OPEN = 0
ROM_CHAR_OPEN = 0
SOUND_OPEN = 0
;==================================================
.ORG RESET_PORT
;==================================================
ProgramBegin:
SEI
CLD
LDA #$00
STA $2000
STA $2001
LDA #$C0
STA $4017
LDX #$FF
TXS
;=================================================
;选择菜单rom
LDX #MENU_INDEX
LDA Rom_Select_Data,X
AND #$7F
STA $6000
JSR PaletteClear
JSR TimeWait
;==================================================
RamClear:;RAM清空
LDA #$00
STA $00
STA $01
LDX #$08
LDY #$00
RamClearWrite:
STA ($00),Y
INY
BNE RamClearWrite
INC $01
DEX
BNE RamClearWrite
JSR ChrSteup
JSR SpriteClear
JSR VramClear
JSR TextWrite
JSR TimeWait
JSR PaletteSet
.IF ATTRIBUTE_OPEN == 0
JSR AttributeSet
.ENDIF
JSR ResetScroll
LDA #$10
STA Button_Buf
LDA #$1E
STA $2001
;==================================================
;循环等待
WaitLoop:
JSR NmiDelay
JSR SelectChange
JMP WaitLoop
RTS
;==================================================
;NMI延时
NmiDelay:
JSR TimeWait
JSR SpriteSet
LDA #$02
STA $4014
JSR Button_Process
JSR ResetScroll
RTS
;==================================================
;延时等待
TimeWait:
LDA $2002
BPL TimeWait
RTS
;==================================================
;重设滚动
ResetScroll:
LDA #$00
LDA #$00
STA $2006
STA $2005
STA $2005
RTS
;==================================================
;按键处理
Button_Process:
JSR Button_Scan
LDA Button_Keep
STA Button_Temp
JSR Button_Scan
LDA Button_Keep
CMP Button_Temp
BEQ Button_Get_Once
LDA Button_Buf
STA Button_Keep
Button_Get_Once:
TAY
EOR Button_Buf
AND Button_Keep
STA Button_Once
STY Button_Buf
JSR ButtonDelay
RTS
;==================================================
;按键扫描
Button_Scan:
LDX #$01
STX $4016
DEX
STX $4016
LDY #$08
Button_Value:
LDA $4016
STA Button_Status
LSR
ORA Button_Status
LSR
ROL Button_Keep
DEY
BNE Button_Value
RTS
;==================================================
;按键延时重复
ButtonDelay:
LDA Button_Keep
AND #$EF
BNE ButtonDelaySet
LDA #$00
STA Btn_Delay
ButtonDelaySet:
INC Btn_Delay
LDA Btn_Delay
CMP #BTN_DELAY + BTN_SPEED
BCC ButtonDelayEnd
LDA #BTN_DELAY
STA Btn_Delay
LDA Button_Keep
STA Button_Once
ButtonDelayEnd:
RTS
;========================================
ChrSteup: ;图形块设置
LDX #$00
ChrSteupSet:
STX $8000
LDA ChrBankData,X
STA $8001
INX
CPX #$06
BCC ChrSteupSet
RTS
;========================================
ChrBankData: ;图形块号
.DB $00,$02,$04,$05,$06,$07
;==================================================
;精灵清除
SpriteClear:
LDX #$00
LDA #$F8
SpriteClearWrite:
STA $0200,X
INX
BNE SpriteClearWrite
RTS
;==================================================
;精灵设置
SpriteSet:
LDA Sel_Index
ASL
ASL
ASL
ASL
CLC
ADC #ARROW_Y_OFFSET
STA $0200
LDA #Char_Arrow
STA $0201
LDA #$00
STA $0202
LDA #ARROW_X_OFFSET
STA $0203
RTS
;==================================================
;清空PPU内存
VramClear:
LDA #$20
STA $2006
LDA #$00
STA $2006
TAX
LDY #$08
LDA #$00
NameTableClearBeg:
STA $2007
INX
BNE NameTableClearBeg
DEY
BNE NameTableClearBeg
RTS
;==================================================
;清空调色板
PaletteClear:
JSR PaletteAddrSet
LDA #$0F
LDX #$00
PaletteClearWrite:
STA $2007
INX
CPX #$20
BCC PaletteClearWrite
RTS
;==================================================
;设置调色板
PaletteSet:
JSR PaletteAddrSet
LDX #$00
PaletteSetWrite:
LDA PaletteData,X
STA $2007
INX
CPX #$20
BCC PaletteSetWrite
RTS
;==================================================
;调色板地址设置
PaletteAddrSet:
LDA #$3F
STA $2006
LDA #$00
STA $2006
RTS
.IF ATTRIBUTE_OPEN == 0
;==================================================
;设置属性表
AttributeSet:
LDA #$23
STA $2006
LDA #$C0
STA $2006
LDX #$00
AttributeSetWrite:
LDA AttributeData,X
STA $2007
INX
CPX #$40
BCC AttributeSetWrite
RTS
.ENDIF
;==================================================
;写入文本
TextWrite:
LDA #<TextData
STA Data_L
LDA #>TextData
STA Data_H
LDY #$00
TextWriteCheckMode:
LDA (Data_L),Y
BEQ TextWriteOver
CMP #$FF
BEQ TextWriteOver
AND #$04
STA $2000
JSR CheckAddr
LDA (Data_L),Y
STA $2006
JSR CheckAddr
LDA (Data_L),Y
STA $2006
JSR CheckAddr
LDA (Data_L),Y
TAX
JSR CheckAddr
TextWriteData:
STX Data_Count
LDA (Data_L),Y
.IF ROM_CHAR_OPEN == 0
TAX
LDA Char_Rom,X
.ENDIF
STA $2007
JSR CheckAddr
LDX Data_Count
DEX
BNE TextWriteData
JMP TextWriteCheckMode
TextWriteOver:
LDA #$00
STA $2000
RTS
;--------------------------------------------------
CheckAddr:
INY
BNE CheckAddrOver
INC Data_H
CheckAddrOver:
RTS
;==================================================
;选项切换
SelectChange:
LDA Button_Once
AND #$FF
BEQ SelectChangeEnd
SelectChangeSound:
.IF SOUND_OPEN == 0
JSR ButtonSound
.ENDIF
SelectInc:
LDA Button_Once
AND #$24
BEQ SelectDec
LDA Sel_Index
CMP #ITEM_COUNT - 1
BCC SelectIncSet
LDA #$FF
STA Sel_Index
SelectIncSet:
INC Sel_Index
SelectDec:
LDA Button_Once
CMP #$08
BNE SelectBeg
LDA Sel_Index
BNE SelectDecSet
LDA #ITEM_COUNT
STA Sel_Index
SelectDecSet:
DEC Sel_Index
SelectBeg:
LDA Button_Once
AND #$42
BEQ SelectEnd
LDA #$00
STA Sel_Index
SelectEnd:
LDA Button_Once
AND #$81
BEQ SelectOver
LDA #ITEM_COUNT - 1
STA Sel_Index
SelectOver:
LDA Button_Once
CMP #$10
BNE SelectChangeEnd
.IF SOUND_OPEN == 0
JSR EnterSound
.ENDIF
JMP SelectProcess
SelectChangeEnd:
RTS
.IF SOUND_OPEN == 0
;========================================
;按键音效
ButtonSound:
LDA #$03
STA $4015
LDX #$00
ButtonSoundWrite:
LDA ButtonSoundData,X
STA $4000,X
INX
CPX #$04
BCC ButtonSoundWrite
RTS
ButtonSoundData:
.DB $87,$89,$F0,$00
.ENDIF
.IF SOUND_OPEN == 0
;========================================
;进入音效
EnterSound:
LDA #$02
STA $4015
LDX #$00
EnterSoundWrite:
LDA EnterSoundData,X
STA $4004,X
INX
CPX #$04
BCC EnterSoundWrite
LDA #$18
JSR SecondDelay
RTS
EnterSoundData:
.DB $3F,$9A,$FF,$00
.ENDIF
.IF SOUND_OPEN == 0
;========================================
;等待延时
SecondDelay:
STA Second_Time
BEQ SecondDelayEnd
SecondDelayWait:
JSR NmiDelay
LDA Button_Once
AND #$90
BNE SecondDelayEnd
DEC Second_Time
BNE SecondDelayWait
SecondDelayEnd:
RTS
.ENDIF
.IF SOUND_OPEN == 0
;=================================================
;音频清理
SoundClean:
LDA #$30
STA $4000
STA $4004
STA $4008
STA $400C
STA $4010
LDA #$00
STA $4010
TAX
SoundCleanReg:
STA $4001,X
STA $4005,X
STA $4009,X
STA $400D,X
STA $4011,X
INX
CPX #$03
BCC SoundCleanReg
LDA #$00
STA $4015
RTS
.ENDIF
;==================================================
SEL_PROCESS_SIZE = SelectGameLength - SelectGame
Sel_Process_Addr = $0300
;==================================================
SelectProcess:;选择节目处理
.IF SOUND_OPEN == 0
JSR SoundClean
.ENDIF
LDX #$00
SelectProcessWrite:
LDA SelectGame,X
STA Sel_Process_Addr,X
INX
CPX #SEL_PROCESS_SIZE
BCC SelectProcessWrite
JSR TimeWait
JSR PaletteClear
LDX Sel_Index
SelectProcessCheckMenu:
CPX #MENU_INDEX
BCC SelectProcessCheckMenuOver
INX
SelectProcessCheckMenuOver:
LDA Rom_Select_Data,X
JMP Sel_Process_Addr
;==================================================
SelectGame:;选择节目
STA $6000
SelectGameEnd:
LDX #$06
LDY #$00
STX $8000
STY $8001
INX
INY
STX $8000
STY $8001
JMP ($FFFC)
SelectGameLength:
;==================================================
;调色板数据
PaletteData:
.DB $0F,$2A,$2A,$2A,$0F,$25,$25,$25,$0F,$29,$26,$26,$0F,$21,$20,$20
.DB $0F,$20,$20,$20,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.IF ATTRIBUTE_OPEN == 0
;==================================================
;属性表数据
AttributeData:
.DB $55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55
.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.ENDIF
;==================================================
;文本数据
TextData:
.DB $80,$20,$A9
.STR "CONTRA 3 IN 1"
.DB $80,$21,$28
.STR "01.CONTRA"
.DB $80,$21,$68
.STR "02.SUPER CONTRA"
.DB $80,$21,$A8
.STR "03.CONTRA FORCE"
.DB $FF
Rom_Select_Data: ;ROM选择数据
;;;;;WMCCSBPP
.DB @11001000 ;001
.DB @11011001 ;002
.DB @11101010 ;003
.DB @11111011 ;004
.DB @11001100 ;005
.DB @11011101 ;006
.DB @11101110 ;007
.DB @11111111 ;008
.IF ROM_CHAR_OPEN == 0
;==================================================
Char_Rom:
.DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F
.DB $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$1B,$1C,$1D,$1E,$1F
.DB $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
.DB $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
.DB $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F
.DB $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$5B,$5C,$5D,$5E,$5F
.ENDIF