[旋風][6502匯編][簡潔音樂播放器]

;[FC][簡潔音樂播放器][MMC3][20190119]
;FlameCyclone
;=============================================================
Sound_Init_Addr = $BFC8? ;音樂初始化地址
Sound_Play_Addr = $8000? ;音樂播放地址
Sound_Start = 01? ? ? ? ?;默認播放曲目
Sound_Sum = 38? ? ? ? ? ;音樂總曲目
;=============================================================
Title_Addr_H = $21
Title_Addr_L = $A0
Digit_Addr_H = $21
Digit_Addr_L = $EC
;=============================================================
RESET_ADDR = $F000? ? ;重置中斷指針
SP_CHR = $00? ? ? ? ? ;精靈圖形CHR索引
BG_CHR = $00? ? ? ? ? ;背景圖形CHR索引
;=============================================================
FC_PPU_Buffer = $0200? ? ? ? ? ? ? ;PPU緩沖地址
FC_PPU_Cursor = $02E0? ? ? ? ? ? ? ;當前PPU緩沖位置
FC_PPU_Status = FC_PPU_Cursor+$01? ;PPU顯示狀態(tài)
FC_PPU_Count? = FC_PPU_Cursor+$02? ;PPU數據計數
Sound_Index = FC_PPU_Cursor + $03? ;當前播放曲目
;=============================================================
Btn_Once = Sound_Index + 1? ? ? ;單次按鍵
Btn_Keep = Btn_Once + 1? ? ? ? ?;長按按鍵
Btn_Buffer = Btn_Once + 2? ? ? ?;按鍵緩沖
Btn_Value = Btn_Once + 3? ? ? ? ;按鍵取值
Btn_Temp = Btn_Once + 4? ? ? ? ?;按鍵臨時
Digit_1 = Btn_Temp + $01? ? ? ? ;轉換后的個位
Digit_10 = Digit_1+$01? ? ? ? ? ;轉換后的十位
Digit_100 = Digit_1+$02? ? ? ? ?;轉換后的百位
;=============================================================
CHAR_SPACE = $00? ? ? ? ? ?;空格字符索引
CHAR_DIGIT = $30? ? ? ? ? ?;數字字符起始
CHAR_PER = $2F? ? ? ? ? ? ?;字符'/'
;=============================================================
?.ORG RESET_ADDR
ProgramBegin:;程序開始
?SEI
?CLD
?LDA #$10
?STA $2000
?LDA #$00
?STA $2001
?STA $E000
?LDA #$80
?STA $A001
?LDA #$06
?STA $8000
?LDA #$01
?STA $8000
;-------------------------
TimeDelayA:;延時A
?BIT $2002
?BPL TimeDelayA
TimeDelayB:;延時B
?BIT $2002
?BMI TimeDelayB
;-------------------------
PaletteClear:;調色板清空
?LDA #$3F
?STA $2006
?LDA #$00
?STA $2006
?LDX #$00
?LDA #$0F
PaletteClear_Set:;
?STA $2007
?INX
?CPX #$20
?BCC PaletteClear_Set
RAM_Clear:;RAM清空
?LDX #$00
?LDA #$00
RAM_Clear_Set:
?STA $0100,X
?STA $0200,X
?INX
?BNE RAM_Clear_Set
?JSR Sound_RAM_Init
;-------------------------
?LDX #$FF
?TXS
;-------------------------
SetPpuPattern:;設置PPU圖形
?LDA #$00
?STA $A000
SetPpuPatternA:;設置上頁圖形2KB*2
?LDX #$00
?LDY #SP_CHR
?STX $8000
?STY $8001
?INX
?INY
?INY
?STX $8000
?STY $8001
?LDX #$02
?LDY #BG_CHR
SetPpuPatternB:;設置下頁圖形1KB*4
?STX $8000
?STY $8001
?INX
?INY
?CPX #$06
?BCC SetPpuPatternB
;-------------------------
ScreenInitialize:;屏幕初始化
?JSR PaletteSetup
?JSR PpuClear
?LDA #$0E
?STA FC_PPU_Status
?LDA #Sound_Start - 1
?STA Sound_Index
?JSR ShowTitle
?JSR ShowPlayOrder
?JSR Sound_Init
;==================================================
NMI_Loop:;NMI循環(huán)
?JSR NMI_Delay
?JMP NMI_Loop
;==================================================
NMI_Delay:;NMI延時
?BIT $2002
?BPL NMI_Delay
?JSR FC_PPU_Process
?JSR Sound_Play_Addr
?JSR ButtonProcess
?JSR ChangeSound
?RTS
?
;==================================================
PaletteSetup:;背景調色板設置
?LDA #$3F
?STA $2006
?LDA #$00
?STA $2006
?LDX #$00
PaletteSetup_Set:
?LDA Palette_Data,X
?STA $2007
?INX
?CPX #$10
?BCC PaletteSetup_Set
?RTS
;==================================================
PpuClear:;PPU清空
?LDA #$24
?STA $2006
?LDA #$00
?STA $2006
?LDX #$00
?LDY #$08
?LDA #CHAR_SPACE
PpuClear_Set:
?STA $2007
?INX
?BNE PpuClear_Set
?DEY
?BPL PpuClear_Set
?RTS
;========================================
HexToDec:;8位16進制轉10進制
?LDY #$00
DigitClear:
?STY Digit_100
?STY Digit_10
?STY Digit_1
?BCC Count_100
?INY
?SBC #100
Count_100:
?CMP #100
?BCC Set_100
?SBC #100
?INY
?BNE Count_100
Set_100:
?STY Digit_100
?LDY #$00
Count_10:
?CMP #10
?BCC Set_10
?SBC #10
?INY
?BNE Count_10
Set_10:
?STY Digit_10
Set_1:
?STA Digit_1
?RTS
;========================================
ShowTitle:;顯示標題
?LDY #$00
?LDX FC_PPU_Cursor
?LDA #MODE_CNTL
?STA FC_PPU_Buffer,X
?INX
?LDA #Title_Addr_H
?STA FC_PPU_Buffer,X
?INX
?LDA #$01
?STA FC_PPU_Count
?LDA Title_Text_Data,Y
?BIT FC_PPU_Count
?BEQ Align_Beg
?LDA Title_Text_Data,Y
?CLC
?ADC #$01
Align_Beg:
?LSR
?STA FC_PPU_Count
?LDA Title_Text_Data,Y
?CMP #$07
?BCS Align_End
?AND #$01
?BNE Align_End
?INC FC_PPU_Count
Align_End:?
?LDA #$10
?SEC
?SBC FC_PPU_Count
?CLC
?ADC #Title_Addr_L
?STA FC_PPU_Buffer,X
?INX
?
?LDA Title_Text_Data,Y
?STA FC_PPU_Count
?STA FC_PPU_Buffer,X
?INX
?INY
ShowTitle_Write:
?LDA Title_Text_Data,Y
?STA FC_PPU_Buffer,X
?INX
?INY
?DEC FC_PPU_Count
?BNE ShowTitle_Write
?STX FC_PPU_Cursor
?RTS
;========================================
ShowPlayOrder:;顯示播放曲目
?LDX FC_PPU_Cursor
?LDA #MODE_CNTL
?STA FC_PPU_Buffer,X
?INX
?LDA #Digit_Addr_H
?STA FC_PPU_Buffer,X
?INX
?LDA #Digit_Addr_L
?STA FC_PPU_Buffer,X
?INX
?LDA #$07
?STA FC_PPU_Buffer,X
?INX
?LDA Sound_Index
?CLC
?ADC #$01
?JSR SetDigits
?LDA #CHAR_PER
?STA FC_PPU_Buffer,X
?INX
?LDA #Sound_Sum - 1
?CLC
?ADC #$01
?JSR SetDigits
?STX FC_PPU_Cursor?
?RTS
;========================================
ChangeSound:;曲目變更
?LDA Btn_Once
?AND #$FF
?BEQ ChangeSound_End
ChangeToLast:
?LDA Btn_Once
?AND #$42
?BEQ ChangeToNext
?JSR PlayLastSound
ChangeToNext:
?LDA Btn_Once
?AND #$A1
?BEQ ChangeToLast10
?JSR PlayNextSound
ChangeToLast10:
?LDA Btn_Once
?CMP #$04
?BNE ChangeToNext10
?JSR PlayLast10Sound
ChangeToNext10:
?LDA Btn_Once
?CMP #$08
?BNE ChangeRePlay
?JSR PlayNext10Sound
ChangeRePlay:
?LDA Btn_Once
?CMP #$10
?BNE ChangeToShowSound
?JSR Sound_Init
ChangeToShowSound:
?JSR ShowPlayOrder
ChangeSound_End:
?RTS
;========================================
PlayLastSound:;上一曲
?LDA Sound_Index
?BEQ PlayLastSound_End
?DEC Sound_Index
?JSR Sound_Init
PlayLastSound_End:
?RTS
;----------------------------------------
PlayNextSound:;下一曲
?LDA Sound_Index
?CMP #Sound_Sum - 1
?BCS PlayNextSound_End
?INC Sound_Index
?JSR Sound_Init
PlayNextSound_End:
?RTS
;----------------------------------------
PlayLast10Sound:;上10曲
?LDA Sound_Index
?BEQ PlayLast10Sound_End
?SEC
?SBC #10
?BCS PlayLast10Sound_Beg
LimiteMin:
?LDA #00
PlayLast10Sound_Beg:
?STA Sound_Index
?JSR Sound_Init
PlayLast10Sound_End:
?RTS
;----------------------------------------
PlayNext10Sound:;下10曲
?LDA Sound_Index
?CMP #Sound_Sum - 1
?BCS PlayNext10Sound_End
?CLC
?ADC #10
?CMP #Sound_Sum - 1
?BCC PlayNext10Sound_Beg
LimiteMax:
?LDA #Sound_Sum - 1
PlayNext10Sound_Beg:
?STA Sound_Index
?JSR Sound_Init
PlayNext10Sound_End:
?RTS
;========================================
SetDigits:;寫入數字到PPU緩沖
?JSR HexToDec
?LDA Digit_100
?CLC
?ADC #CHAR_DIGIT
?STA FC_PPU_Buffer,X
?INX
?LDA Digit_10
?ADC #CHAR_DIGIT
?STA FC_PPU_Buffer,X
?INX
?LDA Digit_1
?ADC #CHAR_DIGIT
?STA FC_PPU_Buffer,X
?INX
?RTS
;========================================
Sound_RAM_Init:;初始化RAM
?LDX #$00
?LDA #$00
?STA $4015
Sound_Port_Set:
?STA $4000,X
?INX
?CPX #$14
?BCC Sound_Port_Set
?LDX #$00
?LDA #$00
Sound_RAM_Init_Set:
?STA $00,X
?STA $0300,X
?STA $0400,X
?STA $0500,X
?STA $0600,X
?STA $0700,X
?INX
?BNE Sound_RAM_Init_Set
?LDX #$00
?LDA #$00
Stack_Init_Set:
?STA $0100,X
?INX
?CPX #$C0
?BCC Stack_Init_Set
?LDA #$1F
?STA $4015
?RTS
;==================================================
Sound_Init:
?JSR Sound_RAM_Init
?LDA Sound_Index
?JSR Sound_Init_Addr
?RTS
;==================================================
MODE_CNTL = $FB? ;帶計數行寫入模式
MODE_CNTC = $FC? ;帶計數行清除模式
;--------------------------------------------------
FC_PPU_Process:;PPU處理
?LDA FC_PPU_Buffer
?BEQ FC_PPU_Process_End
?JSR FC_PPU_Process_Beg
FC_PPU_Process_End:
?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_Set_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 $2006
?INX
?LDA FC_PPU_Buffer,X
?STA $2006
?INX
?RTS
;=============================================================
ButtonProcess:;按鍵掃描
?JSR ButtonScan
?LDA Btn_Keep
?STA Btn_Temp
?JSR ButtonScan
?LDA Btn_Keep
?CMP Btn_Temp
?BEQ ButtonProcess_Set
?LDA Btn_Buffer
?STA Btn_Keep
ButtonProcess_Set:
?TAY
?EOR Btn_Buffer
?AND Btn_Keep
?STA Btn_Once
?STY Btn_Buffer
?RTS
;--------------------------------------------------
ButtonScan:
?LDX #$01
?STX $4016
?DEX
?STX $4016
?LDX #$08
ButtonScanValue:
?LDA $4016
?STA Btn_Value
?LSR
?ORA Btn_Value
?LSR
?ROL Btn_Keep
?DEX
?BNE ButtonScanValue
?RTS
;========================================
Palette_Data:;背景調色板數據
?.BYTE $0F,$24,$24,$24,$0F,$20,$20,$20,$0F,$27,$27,$27,$0F,$2C,$2C,$2C
Title_Text_Data:;標題文本數據
?.STR "RAF WORLD"
?
?.DCB $100,$FF