[FC][Multicart 14 in 1][Source code][Mapper 45]

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
FlameCyclone
Posts: 15
Joined: Fri Jun 02, 2017 2:45 am

[FC][Multicart 14 in 1][Source code][Mapper 45]

Post by FlameCyclone » Sun Apr 05, 2020 7:07 am

Code: Select all

;[FC][Multicart 14 in 1]
;FlameCyclone
;20200329

 .ORG $E000
 
 
MENU_INDEX             = 03
;==================================================
User_Addr = $40
;==================================================
Button_Keep        = User_Addr      + $01
Button_Once        = Button_Keep    + $01
Button_Temp        = Button_Once    + $01
Button_Buf         = Button_Temp    + $01
Button_Status      = Button_Buf     + $01
Button_Delay       = Button_Status  + $01
;==================================================
BUTTON_DELAY_MAX   = 30
BUTTON_DELAY_SPEED = 5
;==================================================
Page_Cur_L         = Button_Delay  + $01
Page_Cur_H         = Page_Cur_L  + $01
Page_Old_L         = Page_Cur_H + $01
Page_Old_H         = Page_Old_L + $01
Sel_Cur_L          = Page_Old_H  + $01
Sel_Cur_H          = Sel_Cur_L  + $01
Sel_Old_L          = Sel_Cur_H + $01
Sel_Old_H          = Sel_Old_L + $01
Sel_Data_L         = Sel_Old_H + $01
Sel_Data_H         = Sel_Data_L + $01
;==================================================
ITEM_BUF_MAX       = 2
;==================================================
Item_Update        = Sel_Data_H + $01
Item_Update_Index   = Item_Update + $01
Item_Show_Cnt        = Item_Update_Index + $01
Item_Show_L        = Item_Show_Cnt + $01
Item_Show_H        = Item_Show_L + $01
Item_Clean_L        = Item_Show_H + $01
Item_Clean_H        = Item_Clean_L + $01

;============================================================
FC_Data_L   = Item_Clean_H + $01                ;数据地址低位
FC_Data_H   = FC_Data_L+$01                     ;数据地址高位
FC_Data_Cnt = FC_Data_H+$01                         ;数据计数
;============================================================
FC_PPU_Status = FC_Data_Cnt+$01                ;PPU显示状态
FC_PPU_Cursor = FC_PPU_Status + $01          ;当前PPU缓冲位置
FC_PPU_Addr_L = FC_PPU_Cursor + $01              ;PPU地址低位
FC_PPU_Addr_H = FC_PPU_Addr_L + $01              ;PPU地址高位
;============================================================
FC_PPU_Buffer = $0200                            ;PPU缓冲地址
FC_PPU_Palette = FC_PPU_Buffer + $E0                            ;PPU缓冲地址
;==================================================
ITEM_MAX     =  14 - 1 ;max up tp 65500
PAGE_SIZE     =  10
PAGE_MAX      =  ITEM_MAX/PAGE_SIZE * PAGE_SIZE
;==================================================
Char_Arrow = $1F
ARROW_X_OFFSET         = $24 ;箭头横坐标
ARROW_Y_OFFSET         = $37 ;箭头纵坐标
SPRITES_ADDR           = $0400
SPRITES_PAGE           = SPRITES_ADDR / 256
;==================================================
;==================================================
Sound_Init             = $BF00
Sound_Play             = $8000
SOUND_OPEN             = 1
;==================================================
SOUNG_BGM              = 29
SOUNG_ITEM             = 37
SOUNG_PAGE             = 75
SOUND_ENTER            = 36
;==================================================
FADE_MODE_OUT          = 1
FADE_MODE_IN           = 2
FADE_SET_SPEED         = $10
BLINK_SPEED            = $18
;--------------------------------------------------
Select_Enable          = FC_PPU_Addr_H + 1
Fade_Enable            = Select_Enable + 1
Fade_Index             = Fade_Enable + 1
Fade_Speed             = Fade_Index + 1
Fade_Delay             = Fade_Speed + 1
;========================================
Rom_Index              = Fade_Speed + 2
CHR_Addr_L             = Rom_Index + $01
CHR_Addr_H             = CHR_Addr_L + $01
PRG_Addr               = CHR_Addr_H + $01
PRG_Size               = PRG_Addr + $01
CHR_Size               = PRG_Size + $01
MIR_Addr               = CHR_Size + $01
;==================================================
SEL_PROCESS_SIZE       = SelectGameLength - SelectGame
Sel_Process_Addr       = $0500
;==================================================

;Reset中断
ResetProgram:
 CLD
 SEI
 LDX #$FF
 TXS
 LDA #$00
 STA $2000
 STA $2001
 STA $E000
 LDA #$80
 STA $A001
 LDX #$02
ResetDelayA:
 BIT $2002
 BPL ResetDelayA
ResetDelayB:
 BIT $2002
 BMI ResetDelayB
 DEX
 BNE ResetDelayA
 
 JSR PaletteClear
 JSR VramClear
 JSR AttributeSet

 LDA #MENU_INDEX
 JSR GetRomPort
 LDX #$00
MenuInitSet:
 LDA CHR_Addr_L
 STA $6000
 LDA PRG_Addr
 ASL
 STA $6000
 LDA CHR_Addr_H
 ASL
 ASL
 ASL
 ASL
 ORA CHR_Size
 STA $6000
 LDA PRG_Size
 STA $6000
 INX
 BNE MenuInitSet
 
 LDA #$06
 STA $8000
 LDA #$00
 STA $8001
 LDA #$07
 STA $8000
 LDA #$01
 STA $8001
 
 LDA #$0F
 STA $4015
 LDA #$C0
 STA $4017

RamClear:
 LDA #$00
 STA $00
 STA $01
 LDX #$08
 LDY #$00
RamClearWrite:
 STA ($00),Y
 INY
 BNE RamClearWrite
 INC $01
 DEX
 BNE RamClearWrite

 ;JSR PaletteSet
 
 LDX #$00
 JSR SetPalette
 
 JSR SpriteClear

 LDA #$01
 STA Select_Enable
 
 
 LDA #$10
 STA Button_Buf
 
 LDA #$1E
 STA FC_PPU_Status
 LDA #$80
 STA $2000
 
 JSR WriteTitle
 
Wait_TitleFinish:
 LDA FC_PPU_Buffer
 BNE Wait_TitleFinish
 
 JSR UpdatePageEnable
 
Wait_PageFinish:
 LDA FC_PPU_Buffer
 BNE Wait_PageFinish
 
 LDA #$02
 STA Fade_Enable
Wait_FadeFinish:
 LDA Fade_Index
 CMP #$02
 BNE Wait_FadeFinish
 
 .IF SOUND_OPEN
 LDA #SOUNG_BGM - 1
 JSR Sound_Init
 .ENDIF

MainLoop:
 JMP MainLoop
 
;==================================================
;清空PPU内存
VramClear:
 LDA #$20
 STA $2006
 LDA #$00
 STA $2006
 LDY #$10
 LDA #$00
 TAX
NameTableClearBeg:
 STA $2007
 INX
 BNE NameTableClearBeg
 DEY
 BNE NameTableClearBeg
 RTS

;==================================================
WritePalette:
 LDA #$3F
 STA $2006
 LDA #$00
 STA $2006
 LDX #$00
WritePaletteBeg:
 LDA FC_PPU_Palette,X
 STA $2007
 INX
 CPX #$20
 BCC WritePaletteBeg
 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
 

;==================================================
;保存旧选择索引
SaveOldSelect:
 LDA Page_Cur_L
 STA Page_Old_L
 LDA Page_Cur_H
 STA Page_Old_H
 LDA Sel_Cur_L
 STA Sel_Old_L
 LDA Sel_Cur_H
 STA Sel_Old_H
 RTS

;==============================
;是否递减索引时页面索引改变
IsPageChangeByDecItem:
 LDA Sel_Cur_L
 CMP Page_Cur_L
 BNE IsPageChangeByDecItemEnd
 SEC
 RTS
IsPageChangeByDecItemEnd:
 CLC
 RTS

;==============================
;是否递增索引时页面索引改变
IsPageChangeByIncItem:
 LDA Page_Cur_L
 CLC
 ADC #PAGE_SIZE
 SEC
 SBC #$01
 CMP Sel_Cur_L
 BNE IsPageChangeByIncItemEnd
 SEC
 RTS
IsPageChangeByIncItemEnd:
 CLC
 RTS

;==============================
;是否最小索引
IsMinItem:
 LDA Sel_Cur_L
 ORA Sel_Cur_H
 BEQ IsMinItemEnd
 CLC
 RTS
IsMinItemEnd:
 SEC
 RTS

;==============================
;是否最小索引页
IsMinPage:
 LDA Page_Cur_L
 ORA Page_Cur_H
 BEQ IsMinPageEnd
 CLC
 RTS
IsMinPageEnd:
 SEC
 RTS

;==============================
;是否最大索引
IsMaxItem:
 LDA Sel_Cur_H
 CMP #>ITEM_MAX
 BNE IsMaxItemEnd
 LDA Sel_Cur_L
 CMP #<ITEM_MAX
 BNE IsMaxItemEnd
 SEC
 RTS
IsMaxItemEnd:
 CLC
 RTS

;==============================
;是否最大索引页
IsMaxPage:
 LDA Page_Cur_H
 CMP #>PAGE_MAX
 BNE IsMaxItemEnd
 LDA Page_Cur_L
 CMP #<PAGE_MAX
 BNE IsMaxPageEnd
 SEC
 RTS
IsMaxPageEnd:
 CLC
 RTS

;==============================
;递减选择索引
DecSelItem:
 LDA Sel_Cur_L
 SEC
 SBC #$01
 STA Sel_Cur_L
 BCS DecSelItemEnd
 DEC Sel_Cur_H
DecSelItemEnd:
 RTS
 
;==============================
;递减选择索引页
DecSelPage:
 LDA Page_Cur_L
 SEC
 SBC #PAGE_SIZE
 STA Page_Cur_L
 BCS DecSelPageEnd
 DEC Page_Cur_H
DecSelPageEnd:
 RTS
 
;==============================
;递增选择索引
IncSelItem:
 LDA Sel_Cur_L
 CLC
 ADC #$01
 STA Sel_Cur_L
 BCC IncSelItemEnd
 INC Sel_Cur_H
IncSelItemEnd:
 RTS

;==============================
;递增选择索引页
IncSelPage:
 LDA Page_Cur_L
 CLC
 ADC #PAGE_SIZE
 STA Page_Cur_L
 BCC IncSelPageEnd
 INC Page_Cur_H
IncSelPageEnd:
 RTS

;==============================
;递增页索引
DecPageIndex
 LDA Page_Cur_L
 SEC
 SBC #PAGE_SIZE
 STA Page_Cur_L
 BCS DecPageIndexEnd
 DEC Page_Cur_H
DecPageIndexEnd:
 JSR UpdatePageEnable
 RTS
 
;==============================
;递增页索引
IncPageIndex:
 LDA Page_Cur_L
 CLC
 ADC #PAGE_SIZE
 STA Page_Cur_L
 BCC IncPageIndexEnd
 INC Page_Cur_H
IncPageIndexEnd:
 JSR UpdatePageEnable
 RTS

;==============================
;设置最小页
SetMinPage:
 LDA #$00
 STA Page_Cur_L
 STA Page_Cur_H
 JSR UpdatePageEnable
 RTS
 
;==============================
;设置最大页
SetMaxPage:
 LDA #<PAGE_MAX
 STA Page_Cur_L
 LDA #>PAGE_MAX
 STA Page_Cur_H
 JSR UpdatePageEnable
 RTS
 
;==============================
;设置最小索引
SetMinItem:
 LDA #$00
 STA Sel_Cur_L
 STA Sel_Cur_H
 RTS

;==============================
;设置最大索引
SetMaxItem:
 LDA #<ITEM_MAX
 STA Sel_Cur_L
 LDA #>ITEM_MAX
 STA Sel_Cur_H
 RTS

;==============================
;换页时递减选择索引
DecSelItemByPage:
 JSR GetItemOffset
 JSR DecSelPage
 JSR SetItemOffset
DecSelItemByPageEnd:
 JSR UpdatePageEnable
 RTS
 
;==============================
;换页时递增选择索引
IncSelItemByPage:
 JSR GetItemOffset
 JSR IncSelPage
 JSR SetItemOffset
IncSelItemByPageEnd:
 JSR UpdatePageEnable
 RTS

;=============================
;索引偏移获取
GetItemOffset
 LDA Sel_Cur_L
 SEC
 SBC Page_Cur_L
 STA Sel_Data_L
 LDA Sel_Cur_H
 SBC Page_Cur_H
 STA Sel_Data_H
 RTS
 
;=============================
;索引偏移设置
SetItemOffset:
 LDA Sel_Data_L
 CLC
 ADC Page_Cur_L
 STA Sel_Cur_L
 LDA Sel_Data_H
 ADC Page_Cur_H
 STA Sel_Cur_H
SetItemOffsetCheck:
 LDA Sel_Cur_H
 CMP #>ITEM_MAX
 BCC SetItemOffsetEnd
 BNE SetItemOffsetMax
 LDA Sel_Cur_L
 CMP #<ITEM_MAX
 BCC SetItemOffsetEnd
 BEQ SetItemOffsetEnd
SetItemOffsetMax:
 JSR SetMaxItem
SetItemOffsetEnd:
 RTS
 
;==============================
;选择上一个索引
SelectPreItem:
 JSR SaveOldSelect
 JSR IsMinItem
 BCS SelectPreItemSetMaxPage
 JSR IsPageChangeByDecItem
 BCC SelectPreItemNoSavePage
 JSR DecPageIndex
SelectPreItemNoSavePage:
 JSR DecSelItem
 RTS
SelectPreItemSetMaxPage:
 JSR SetMaxPage
 JSR SetMaxItem
 RTS
 
;==============================
;选择下一个索引
SelectNextItem:
 JSR SaveOldSelect
 JSR IsMaxItem
 BCS SelectNextItemSetMinPage
 JSR IsPageChangeByIncItem
 BCC SelectNextItemNoSavePage
 JSR IncPageIndex
SelectNextItemNoSavePage
 JSR IncSelItem
 RTS
SelectNextItemSetMinPage
 JSR SetMinPage
 JSR SetMinItem
 RTS

;==============================
;选择上一个页索引
SelectPrePage:
 JSR SaveOldSelect
 JSR IsMinPage
 BCS SelectPrePageSetMaxPage
 JSR DecSelItemByPage
 RTS
SelectPrePageSetMaxPage:
 JSR GetItemOffset
 JSR SetMaxPage
 JSR SetItemOffset
 RTS
 
;==============================
;选择下一个页索引
SelectNextPage:
 JSR SaveOldSelect
 JSR IsMaxPage
 BCS SelectNextPageSetMinPage
 JSR IncSelItemByPage
 RTS
SelectNextPageSetMinPage:
 JSR GetItemOffset
 JSR SetMinPage
 JSR SetItemOffset
 RTS

;==================================================
;按键处理
ButtonProcess:
 JSR ButtonScan
 LDA Button_Keep
 STA Button_Temp
 JSR ButtonScan
 LDA Button_Keep
 CMP Button_Temp
 BEQ ButtonGetOnce
 LDA Button_Buf
 STA Button_Keep
ButtonGetOnce:
 TAY
 EOR Button_Buf
 AND Button_Keep
 STA Button_Once
 STY Button_Buf
 JSR ButtonDelay
 RTS
;==================================================
;按键扫描
ButtonScan:
 LDX #$01
 STX $4016
 DEX
 STX $4016
 LDY #$08
ButtonValue:
 LDA $4016
 STA Button_Status
 LSR
 ORA Button_Status
 LSR
 ROL Button_Keep
 DEY
 BNE ButtonValue
 RTS
ButtonDelay:
 LDA Button_Keep
 AND #$EF
 BNE ButtonDelayBeg
 STA Button_Delay
 RTS
ButtonDelayBeg:
 INC Button_Delay
 LDA Button_Delay
 CMP # BUTTON_DELAY_MAX + BUTTON_DELAY_SPEED
 BCC ButtonDelayEnd
 LDA # BUTTON_DELAY_MAX
 STA Button_Delay
 LDA Button_Keep
 STA Button_Once
ButtonDelayEnd:
 RTS


;========================================
MODE_CNTL = $FB               ;行写入模式
MODE_CNTC = $FC               ;行清除模式
MODE_OVER = $FF                 ;结束标志
;----------------------------------------
FC_PPU_Process:                  ;PPU处理
 LDA FC_PPU_Buffer
 BEQ FC_PPU_Process_End
 JSR FC_PPU_Process_Beg
FC_PPU_Process_End:
 JSR WritePalette
 LDA #$00
 STA FC_PPU_Buffer
 STA $2006
 STA $2006
 STA $2005
 STA $2005
 LDA FC_PPU_Status
 STA $2001
 RTS

;----------------------------------------
FC_PPU_Process_Beg:             ;处理开始
 LDX FC_PPU_Cursor
 LDA #$00
 STA $2001
 STA FC_PPU_Buffer,X
 STA FC_PPU_Cursor
 LDX #$FF
;----------------------------------------
FC_PPU_Mode_Select:             ;模式选择
 INX
 LDA FC_PPU_Buffer,X
 CMP #MODE_CNTL
 BEQ FC_PPU_Mode_CountLine
 CMP #MODE_CNTC
 BEQ FC_PPU_Mode_CountClear
 RTS

;----------------------------------------
FC_PPU_Mode_CountLine:        ;行写入模式
 JSR FC_PPU_Set_Addr
 LDY FC_PPU_Buffer,X
FC_PPU_CountLine_Write:
 INX
 LDA FC_PPU_Buffer,X
 STA $2007
 DEY
 BNE FC_PPU_CountLine_Write
 JMP FC_PPU_Mode_Select
 
;----------------------------------------
FC_PPU_Mode_CountClear:       ;行清除模式
 JSR FC_PPU_Write_Addr
 LDY FC_PPU_Buffer,X
 LDA #$00
FC_PPU_CountClear_Write:
 STA $2007
 DEY
 BNE FC_PPU_CountClear_Write
 JMP FC_PPU_Mode_Select
 
;----------------------------------------
FC_PPU_Set_Addr:                ;写入地址
 INX
 LDA FC_PPU_Buffer,X
 STA FC_PPU_Addr_H
 STA $2006
 INX
 LDA FC_PPU_Buffer,X
 STA FC_PPU_Addr_L
 STA $2006
 INX
 RTS

;----------------------------------------
FC_PPU_Write_Addr:              ;写入地址
 INX
 LDA FC_PPU_Buffer,X
 STA $2006
 INX
 LDA FC_PPU_Buffer,X
 STA $2006
 INX
 RTS

;========================================
UpdatePageEnable:
 LDA #$01
 STA Item_Update
 LDA Page_Cur_L
 STA Item_Show_L
 LDA Page_Cur_H
 STA Item_Show_H
 LDA Page_Old_L
 STA Item_Clean_L
 LDA Page_Old_H
 STA Item_Clean_H
 LDA #$00
 STA Item_Update_Index
 RTS

;========================================
UpdatePageDisable:
 LDA #$00
 STA Item_Update
 RTS

;==============================
;是否最大索引页
IsOverMaxShowItem:
 LDA Item_Show_H
 CMP #>ITEM_MAX
 BCC IsOverMaxUpdateItemEnd
 BNE IsOverMaxShowItemSet
 LDA Item_Show_L
 CMP #<ITEM_MAX
 BCC IsOverMaxUpdateItemEnd
 BEQ IsOverMaxUpdateItemEnd
IsOverMaxShowItemSet:
 SEC
 RTS
IsOverMaxUpdateItemEnd:
 CLC
 RTS

;==============================
;是否最大索引页
IsOverMaxCleanItem:
 LDA Item_Clean_H
 CMP #>ITEM_MAX
 BCC IsOverMaxCleanItemEnd
 BNE IsOverMaxCleanItemSet
 LDA Item_Clean_L
 CMP #<ITEM_MAX
 BCC IsOverMaxCleanItemEnd
 BEQ IsOverMaxCleanItemEnd
IsOverMaxCleanItemSet:
 SEC
 RTS
IsOverMaxCleanItemEnd:
 CLC
 RTS

;========================================
UpdatePage:
 LDA Item_Update_Index
 CMP #PAGE_SIZE
 BCC UpdatePageInitBeg
 JSR UpdatePageDisable
 RTS
UpdatePageInitBeg:
 LDA #$00
 STA Item_Show_Cnt
UpdatePageBeg:
 JSR CleanOnceItem
 JSR WriteOnceItem
UpdatePageCheckClean:
 INC Item_Clean_L
 BNE UpdatePageCheckShow
 INC Item_Clean_H
UpdatePageCheckShow:
 INC Item_Show_L
 BNE UpdatePageItem
 INC Item_Show_H
UpdatePageItem:
 INC Item_Update_Index
 LDA Item_Update_Index
 CMP #PAGE_SIZE
 BCS UpdatePageEnd
 INC Item_Show_Cnt
 LDA Item_Show_Cnt
 CMP #ITEM_BUF_MAX
 BCC UpdatePageBeg
UpdatePageEnd:
 RTS

;==================================================
WriteOnceItem:
 JSR IsOverMaxShowItem
 BCC WriteOnceItemBeg
 RTS
WriteOnceItemBeg:
 LDA Item_Show_L
 CLC
 ADC #<ItemAddr_L
 STA FC_Data_L
 
 LDA Item_Show_H
 ADC #>ItemAddr_L
 STA FC_Data_H
 LDY #$00
 LDA (FC_Data_L),Y
 PHA
 
 LDA Item_Show_L
 CLC
 ADC #<ItemAddr_H
 STA FC_Data_L
 
 LDA Item_Show_H
 ADC #>ItemAddr_H
 STA FC_Data_H
 LDY #$00
 LDA (FC_Data_L),Y
 STA FC_Data_H
 PLA
 STA FC_Data_L

 LDX FC_PPU_Cursor
 LDA #MODE_CNTL
 STA FC_PPU_Buffer,X
 INX
 
 LDY Item_Update_Index
 LDA ItemShowPos_H,Y
 STA FC_PPU_Buffer,X
 INX
 LDA ItemShowPos_L,Y
 STA FC_PPU_Buffer,X
 INX
 
 LDY #$00
 LDA(FC_Data_L),Y
 STA FC_Data_Cnt
 STA FC_PPU_Buffer,X
 INX
 INY
WriteText:
 LDA(FC_Data_L),Y
 STA FC_PPU_Buffer,X
 INX
 INY
 DEC FC_Data_Cnt
 BNE WriteText
 STX FC_PPU_Cursor
 RTS

;==================================================
CleanOnceItem:
 JSR IsOverMaxCleanItem
 BCC CleanOnceItemBeg
 RTS
CleanOnceItemBeg:
 LDA Item_Clean_L
 CLC
 ADC #<ItemAddr_L
 STA FC_Data_L
 
 LDA Item_Clean_H
 ADC #>ItemAddr_L
 STA FC_Data_H
 LDY #$00
 LDA (FC_Data_L),Y
 PHA
 
 LDA Item_Clean_L
 CLC
 ADC #<ItemAddr_H
 STA FC_Data_L
 
 LDA Item_Clean_H
 ADC #>ItemAddr_H
 STA FC_Data_H
 LDY #$00
 LDA (FC_Data_L),Y
 STA FC_Data_H
 PLA
 STA FC_Data_L

 LDX FC_PPU_Cursor
 LDA #MODE_CNTC
 STA FC_PPU_Buffer,X
 INX
 
 LDY Item_Update_Index
 LDA ItemShowPos_H,Y
 STA FC_PPU_Buffer,X
 INX
 LDA ItemShowPos_L,Y
 STA FC_PPU_Buffer,X
 INX
 
 LDY #$00
 LDA(FC_Data_L),Y
 STA FC_PPU_Buffer,X
 INX
 STX FC_PPU_Cursor
CleanOnceItemEnd:
 RTS
 
 
;==================================================
;精灵清除
SpriteClear:
 LDX #$00
 LDA #$F8
SpriteClearWrite:
 STA SPRITES_ADDR,X
 INX
 BNE SpriteClearWrite
 RTS

;==================================================
;精灵设置
SpriteSet:
 LDA Sel_Cur_L
 SEC
 SBC Page_Cur_L
 ASL
 ASL
 ASL
 ASL
 CLC
 ADC #ARROW_Y_OFFSET
 STA SPRITES_ADDR
 LDA #Char_Arrow
 STA SPRITES_ADDR + 1
 LDA #$00
 STA SPRITES_ADDR + 2
 LDA #ARROW_X_OFFSET
 STA SPRITES_ADDR + 3
 RTS

;==================================================
;设置属性表
AttributeSet:
 LDA #$23
 STA $2006
 LDA #$C0
 STA $2006
 LDX #$00
AttributeSetWrite:
 LDA AttributeData,X
 STA $2007
 INX
 CPX #$40
 BCC AttributeSetWrite
 RTS

;==================================================
SelectItemSound:
 .IF SOUND_OPEN
 LDA #SOUNG_ITEM - 1
 JSR Sound_Init
 .ENDIF
 RTS
 
 
;==================================================
SelectPageSound:
 .IF SOUND_OPEN
 LDA #SOUNG_PAGE - 1
 JSR Sound_Init
 .ENDIF
 RTS
 
;==================================================
SelectEnterSound:
 .IF SOUND_OPEN
 LDA #SOUND_ENTER - 1
 JSR Sound_Init
 .ENDIF
 RTS
 
;==================================================
SelectStopSound:
 .IF SOUND_OPEN
 LDA #$01
 STA $0700
 .ENDIF
 RTS
 
;==================================================
SetPalette:
 LDA PaletteDataAddr_L,X
 STA FC_Data_L
 LDA PaletteDataAddr_H,X
 STA FC_Data_H
 LDY #$00
 LDX #$00
SetPaletteBeg:
 LDA (FC_Data_L),Y
 STA FC_PPU_Palette,X
 INY
 INX
 CPX #$20
 BCC SetPaletteBeg
 RTS


;==================================================
FadeShow:
 LDA Fade_Enable
 BEQ FadeShowEnd
FadeShowBeg:
 INC Fade_Speed
 LDA Fade_Speed
 CMP #FADE_SET_SPEED
 BCC FadeShowEnd
 LDA #$00
 STA Fade_Speed
 LDA Fade_Enable
 CMP #$02
 BEQ FadeShowIn
 CMP #$01
 BEQ FadeShowOut
FadeShowEnd:
 RTS
FadeShowOut:
 JSR FadeOut
 RTS
FadeShowIn:
 JSR FadeIn
 RTS

;==================================================
FadeIn:
 LDA Fade_Index
 CMP PaletteSize
 BCC FadeInBeg
 LDA #$00
 STA Fade_Index
FadeInBeg:
 LDX Fade_Index
 JSR SetPalette
 INC Fade_Index
 LDA Fade_Index
 CMP PaletteSize
 BEQ FadeInOver
 RTS
FadeInOver:
 LDA #$00
 STA Fade_Enable
 RTS

;==================================================
FadeOut:
 LDA Fade_Index
 CLC
 ADC #$01
 CMP PaletteSize
 BCC FadeOutBeg
 LDA PaletteSize
 SEC
 SBC #$01
 STA Fade_Index
FadeOutBeg:
 LDX Fade_Index
 JSR SetPalette
 DEC Fade_Index
 BMI FadeOutOver
 RTS
FadeOutOver:
 LDA #$00
 STA Fade_Index
 STA Fade_Enable
 RTS
 
;==================================================
BlinkColor:
 LDA Select_Enable
 BEQ BlinkColorEnd
 LDA Fade_Enable
 AND # FADE_MODE_IN | FADE_MODE_OUT
 BNE BlinkColorEnd
 INC Fade_Delay
 LDA Fade_Delay
 CMP #BLINK_SPEED
 BCC BlinkColorEnd
 LDA #$00
 STA Fade_Delay
 LDA Fade_Index
 CLC
 ADC #$01
 CMP BlinkSize
 BCC BlinkColorCheck
 LDA #$FF
 STA Fade_Index
BlinkColorCheck:
 INC Fade_Index
 LDX Fade_Index
 LDA BlinkOrder,X
 TAX
 LDA BlinkDataAddr_L,X
 STA FC_Data_L
 LDA BlinkDataAddr_H,X
 STA FC_Data_H
 LDY #$00
BlinkColorBeg:
 LDA (FC_Data_L),Y
 STA FC_PPU_Palette,Y
 INY
 CPY #$20
 BCC BlinkColorBeg
BlinkColorEnd:
 RTS

;==================================================
;选择索引
SelectItemIndex:
 LDA Select_Enable
 BEQ SelectItemIndexOver
 LDA Item_Update
 BEQ SelectPreItemIndex
 JSR UpdatePage
SelectItemIndexOver:
 RTS
SelectPreItemIndex:
 LDA Button_Once
 AND #$08
 BEQ SelectNextItemIndex
 JSR SelectItemSound
 JSR SelectPreItem
SelectNextItemIndex:
 LDA Button_Once
 AND #$24
 BEQ SelectPrePageIndex
 JSR SelectItemSound
 JSR SelectNextItem
SelectPrePageIndex:
 LDA Button_Once
 AND #$42
 BEQ SelectNextPageIndex
 JSR SelectPageSound
 JSR SelectPrePage
SelectNextPageIndex:
 LDA Button_Once
 AND #$81
 BEQ SelectItemIndexCheck
 JSR SelectPageSound
 JSR SelectNextPage
SelectItemIndexCheck:
 LDA Button_Once
 CMP #$10
 BNE SelectItemIndexEnd

 LDA #$00
 STA Select_Enable

 LDA #$01
 STA $0700
WaitSoundStop:
 LDA $0700
 BNE WaitSoundStop

 JSR SelectEnterSound
 
 LDA #$01
 STA Fade_Enable
 LDA PaletteSize
 STA Fade_Index
 LDA #$17
 STA Fade_Speed
Wait_FadeOutFinish:
 LDA Fade_Enable
 BNE Wait_FadeOutFinish
 
 LDA #$01
 STA $0700
Wait_SoundFinish
 LDA $0700
 BNE Wait_SoundFinish
 
 LDA #$00
 STA $2000
 STA $2001
 
WaitDelay:
 LDA $2002
 BPL WaitDelay
 JSR PaletteClear
 JSR VramClear
 
WaitDelay2:
 LDA $2002
 BPL WaitDelay2

 JMP RomSelect
SelectItemIndexEnd:
 RTS

;==================================================
GetRomPort:
 STA Rom_Index
 JSR GetPrgBankIndex
 JSR GetChrBankIndex
 JSR GetPrgSize
 JSR GetChrSize
 LDX Rom_Index
 LDA ROM_Mirroring,X
 STA MIR_Addr
 RTS
;----------------------------------------
WriteMultiPort:
 LDA CHR_Addr_L
 STA $6000
 LDA PRG_Addr
 ASL
 STA $6000
 LDA CHR_Addr_H
 ASL
 ASL
 ASL
 ASL
 ORA CHR_Size
 STA $6000
 LDA PRG_Size
 STA $6000
 RTS
;----------------------------------------
GetPrgBankIndex:
 LDA #$00
 STA PRG_Addr
 LDA Rom_Index
 BEQ GetPrgBankIndexEnd
 LDX #$00
GetPrgBankIndexBeg:
 LDA PRG_Addr
 CLC
 ADC ROM_PRG_Size,X
 STA PRG_Addr
 INX
 CPX Rom_Index
 BCC GetPrgBankIndexBeg
GetPrgBankIndexEnd:
 RTS 
;----------------------------------------
GetChrBankIndex:
 LDA #$00
 STA CHR_Addr_L
 STA CHR_Addr_H
 LDA Rom_Index
 BEQ GetChrBankIndexEnd
 LDX #$00
GetChrBankIndexBeg:
 LDA CHR_Addr_L
 CLC
 ADC ROM_CHR_Size,X
 STA CHR_Addr_L
 ADC CHR_Addr_H
 STA CHR_Addr_H
 INX
 CPX Rom_Index
 BCC GetChrBankIndexBeg
 LDX #$00
GetChrBankIndexSet:
 ASL CHR_Addr_L
 ROL CHR_Addr_H
 INX
 CPX #$03
 BCC GetChrBankIndexSet
GetChrBankIndexEnd:
 RTS 
;----------------------------------------
GetPrgSize:
 LDX Rom_Index
 LDA ROM_PRG_Size,X
 LDX #$00
GetPrgSizeBeg:
 CMP PRG_Size_Map,X
 BEQ GetPrgSizeSetEnd
 INX
 CPX #$06
 BCC GetPrgSizeBeg
GetPrgSizeSetEnd:
 LDA PRG_Size_Data,X
 STA PRG_Size
 RTS
;----------------------------------------
GetChrSize:
 LDX Rom_Index
 LDA ROM_CHR_Size,X
 LDX #$00
GetChrSizeBeg:
 CMP CHR_Size_Map,X
 BEQ GetChrSizeSetEnd
 INX
 CPX #$06
 BCC GetChrSizeBeg
GetChrSizeSetEnd:
 LDA CHR_Size_Data,X
 STA CHR_Size
 RTS

;==================================================
;节目选择
RomSelect:
 LDX #$00
RomSelectBeg:
 LDA SelectGame,X
 STA Sel_Process_Addr,X
 INX
 CPX #SEL_PROCESS_SIZE
 BCC RomSelectBeg
 LDX Sel_Cur_L
 LDA ROM_Order,X
 TAX
 CPX #MENU_INDEX
 BCC RomSelectSet
 INX
 LDA ROM_Order,X
 ;JMP MENU_RESET
RomSelectSet:
 JSR GetRomPort
RomSelfCheck:
 JMP Sel_Process_Addr

;==================================================
;节目选择处理
SelectGame:
 LDX #$00
SelectGameBeg:
 LDA CHR_Addr_L
 STA $6000
 LDA PRG_Addr
 ASL
 STA $6000
 LDA CHR_Addr_H
 ASL
 ASL
 ASL
 ASL
 ORA CHR_Size
 STA $6000
 LDA PRG_Size
 ORA #$C0
 STA $6000
 INX
 BNE SelectGameBeg
SelectGameSet:
 LDA $2002
 BPL SelectGameSet
 LDA #$00
 STA $2006
 STA $2006
 LDA MIR_Addr
 STA $A000
 JMP ($FFFC)
SelectGameLength:
 
;==================================================
;属性表数据
AttributeData:
 .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 .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
 
;==================================================
;调色板数据
PaletteData:
 .DB $0F,$0F,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$0F,$0F,$0F
 .DB $0F,$0F,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 
PaletteData2:
 .DB $0F,$04,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$07,$20,$20
 .DB $0F,$01,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F

PaletteData3:
 .DB $0F,$14,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$17,$20,$20
 .DB $0F,$11,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 
PaletteData4:
 .DB $0F,$24,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$27,$20,$20
 .DB $0F,$21,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 

PaletteDataAddr_L:
 .DB <PaletteData, <PaletteData2, <PaletteData3, <PaletteData4
PaletteDataAddr_H:
 .DB >PaletteData, >PaletteData2, >PaletteData3, >PaletteData4

PaletteSize:
 .DB 4
 
BlinkData1:
 .DB $0F,$24,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$27,$20,$20
 .DB $0F,$21,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 
BlinkData2:
 .DB $0F,$14,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$27,$20,$20
 .DB $0F,$11,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F

BlinkData3:
 .DB $0F,$04,$2A,$2A,$0F,$20,$25,$25,$0F,$22,$21,$21,$0F,$27,$20,$20
 .DB $0F,$01,$16,$16,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
 
 
BlinkDataAddr_L:
 .DB <BlinkData1, <BlinkData2, <BlinkData3
 
BlinkDataAddr_H:
 .DB >BlinkData1, >BlinkData2, >BlinkData3
 
BlinkOrder:
 .DB 0,1,0,1,2,1
 
BlinkSize:
 .DB 6
;==================================================
ItemShowPos_L:
 .db $E6,$26,$66,$A6,$E6,$26,$66,$A6,$E6,$26,$66,$A6
ItemShowPos_H:
 .db $20,$21,$21,$21,$21,$22,$22,$22,$22,$23,$23,$23

;==================================================
ItemAddr:
ItemAddr_L:
 .db <Item_001,<Item_002,<Item_003,<Item_004,<Item_005,<Item_006,<Item_007,<Item_008,<Item_009,<Item_010
 .db <Item_011,<Item_012,<Item_013,<Item_014
ItemAddr_H:
 .db >Item_001,>Item_002,>Item_003,>Item_004,>Item_005,>Item_006,>Item_007,>Item_008,>Item_009,>Item_010
 .db >Item_011,>Item_012,>Item_013,>Item_014

;========================================
CHR_Size_Map:
 .DB $01,$02,$04,$08,$10,$20
CHR_Size_Data:
 .DB $0A,$0B,$0C,$0D,$0E,$0F
;----------------------------------------
PRG_Size_Map:
 .DB $01,$02,$04,$08,$10,$20
PRG_Size_Data:
 .DB $3E,$3C,$38,$30,$20,$00
;========================================
ROM_PRG_Size:
 .DB $08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08
ROM_CHR_Size:
 .DB $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10
;镜像 01:水平 00:垂直
ROM_Mirroring:
 .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
;选择序号索引
ROM_Order:
 .DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F

WriteTitle:
 LDX FC_PPU_Cursor
 
 LDA #MODE_CNTL
 STA FC_PPU_Buffer,X
 INX
 
 LDA #$20
 STA FC_PPU_Buffer,X
 INX
 LDA #$88
 STA FC_PPU_Buffer,X
 INX
 
 LDY #$00
 LDA TitleText,Y
 STA FC_PPU_Buffer,X
 STA FC_Data_Cnt
 INX
 INY
WriteTitleBeg:
 LDA TitleText,Y
 STA FC_PPU_Buffer,X
 INX
 INY
 DEC FC_Data_Cnt
 BNE WriteTitleBeg
 STX FC_PPU_Cursor
 RTS

;==================================================
TitleText:
 .STR "FC GAME 14 IN 1"
 
;==================================================
ItemText:
Item_001 .STR "01.CONTRA"
Item_002 .STR "02.SUPER CONTRA"
Item_003 .STR "03.DOUBLE DRAGON 2"
Item_004 .STR "04.MIGHTY FINAL FIGHT"
Item_005 .STR "05.NINJA GAIDEN 2"
Item_006 .STR "06.NINJA GAIDEN 3"
Item_007 .STR "07.TOURNAMENT FIGHTERS"
Item_008 .STR "08.KAGE"
Item_009 .STR "09.RAF WORLD"
Item_010 .STR "10.FINAL MISSION"
Item_011 .STR "11.SNOW BROS"
Item_012 .STR "12.SAINT SEIYA 2"
Item_013 .STR "13.ADVENTURE ISLAND 2"
Item_014 .STR "14.ADVENTURE ISLAND 3"
;==================================================
;Nmi中断
NmiProgram:
 PHA
 TXA
 PHA
 TYA
 PHA
 LDA $2002
 JSR FC_PPU_Process
 LDA #SPRITES_PAGE
 STA $4014
 LDA #$80
 STA $2000
 JSR ButtonProcess
 JSR FadeShow
 JSR BlinkColor
 JSR SelectItemIndex
 JSR SpriteSet
 
 .IF SOUND_OPEN
 JSR Sound_Play
 .ENDIF
 
 PLA
 TAY
 PLA
 TAX
 PLA

;==================================================
;Irq中断
IrqProgram:
 RTI

 .ORG $FFFA
 .WORD NmiProgram
 .WORD ResetProgram
 .WORD IrqProgram

rom demo(4096KB):
http://flamecyclone.ys168.com/
menu demo(256KB):
[FC][分页菜单重置14合1][菜单].zip
(21.19 KiB) Downloaded 39 times
[FC][分页菜单重置14合1][菜单]-0.png
[FC][分页菜单重置14合1][菜单]-0.png (2.18 KiB) Viewed 1156 times
[FC][分页菜单重置14合1][菜单]-1.png
[FC][分页菜单重置14合1][菜单]-1.png (1.23 KiB) Viewed 1156 times

Post Reply