📄 main.asm
字号:
;===============================================================================
;IC Body: W588C020
;项目名:Fiber optic lamp
;功能:
; 2pcs Led for Eye (BP00,BP01)
; 4pcs Led for Mouth (BP02~BP05)
; Key: 1pc (BP10)
; Speaker:
; DAC mode
;播放两个声音,播放声音时,嘴形和眼睛要和声音同步。
;-------------------------------------------------------------------------------
;BP00控制睁眼,BP01控制眯眼。
;BP02控制闭嘴,BP03控制大嘴下,BP04控制小嘴下,BP05控制小嘴上。
;===============================================================================
CHIP W588
INCLUDE PGM_HEAD_588.INI
EXTERN FXF_ISR_DELAY_COUNT_DEFAULT
EXTERN STOP_TM_FXF_PROC
EXTERN INIT_TM_FXF_PROC
EXTERN VC_TMV_TABLE
EXTERN VC_TMC_TABLE
.ifdef FW_PWM_TIMER_TM0
EXTERN FW_PWM_TIMER_DOWNCOUNT
PUBLIC FW_TIMER_DWONCOUNT_RET
.endif
.ifdef FW_PWM_TIMER_TM1
EXTERN FW_PWM_TIMER_DOWNCOUNT
PUBLIC FW_TIMER_DWONCOUNT_RET
.endif
.ifdef FW_PWM_TIMER_TMG0
EXTERN FW_PWM_TIMER_DOWNCOUNT
PUBLIC FW_TIMER_DWONCOUNT_RET
.endif
.ifdef FW_PWM_TIMER_TMG1
EXTERN FW_PWM_TIMER_DOWNCOUNT
PUBLIC FW_TIMER_DWONCOUNT_RET
.endif
PUBLIC QUIT_LIB_ISR
;==========================================================================
; Initial For Main.asm Macro
;--------------------------------------------------------------------------
;==========================================================================
; DECLARE VARIABLES INSIDE THIS SECTION
; EXAMPLE => VAR1 DS 3
; VAR2 DS 1
;==========================================================================
USER_RAM: SECTION
gTime10ms DS 1 ; 时间标志
FTime10ms DS 1
gTime100ms DS 1
FTime100ms DS 1
gTime500ms DS 1
FTime500ms DS 1
gSTOP_Counter DS 1 ;STOP工作定时
FKEY_CHECK DS 1 ;键按下标志
gKEY_Times DS 1 ;记录键按下的次数
g1KEY_Filter DS 1
FKEY_Manage DS 1
gLED_FLASH500ms DS 1
;FTime1test DS 1 ;测试1秒用
ENDS
;=======================================================================
; WRITE PROGRAM CODES & TABLES INSIDE THIS SECTION
;==========================================================================
CODE: SECTION
;==================================================
FXF15_ISR:
LDA #02H
STA !EFC1 ;CLEAR EVF OF FXF15
;User can insert program from here
PLA
RTI
;=================================================================
;PORT ISR
;==================================================================
PORT_ISR:
PHA
LDA #01H
STA !EFC0
;User can insert program from here
PLA
RTI
;***************************************************************
; INTERRUPT SERVICE ROUTINES
; EVF0 = [XX SI_INT FXF_INT TMG_INT TM1_INT TM0_INT POR_INT]
;***************************************************************
IRQ_ISR:
PHA
LDA !IEF0
AND !EVF0
BIT #10H
BNE FXF_ISR ;1S2T
LDA !IEF1
AND !EVF1
BIT #02H
BEQ PLA_RTI
JMP FXF15_ISR
PLA_RTI:
PLA
RTI
;===============================================================
; SR_NAME: FXF13_ISR ;FXF13_ISR FOR MELODY
; INPUT : MS_DATA_ADDR ;OUTPUT : SP0AT, SP0BT
;===============================================================
FXF_ISR:
LDA #10H
STA !EFC0 ;CLEAR EVF OF FXF13
.IF(WITH_MS .EQ. 1).OR.(WITH_EVO .EQ. 1)
PHX
PHY
STORE_SW_CS
LDA !BANK
PHA
LDA !IEF1 ;DISABLE FXF15
PHA
STZ !IEF1
LDA !IEF0
PHA
AND #01001110B ;KEEP TMG/0/1 INTERRUPT ONLY
STA !IEF0
CLI ;ENABLE INTERRUPT
FXF13_ISR_PROC
;-------------------------------------------------------------------------
PUBLIC QUIT_LIB_FXF_ISR
QUIT_LIB_FXF_ISR:
SEI
PLA
AND #10110001B ;RESTORE IEF0 INTERRUPT
ORA !IEF0
STA !IEF0
QUIT_LIB_FXF_ISR_CONT
QUIT_LIB_FXF_ISR_END:
PLA ;RESTORE FXF15
STA !IEF1
PLA
STA !BANK
RELOAD_SW_CS
PLY
PLX
.ENDIF
PLA
RTI
;===============================================================
; SR_NAME: TIMERG1_ISR ;
;===============================================================
TMG1_ISR:
PHA
;User can insert program from here
LDA #01H
STA !WDTC
INC gTime10ms
LDA gTime10ms
CMP #0AH
BNE QUIT_TimerG_ISR
LDA #01H
STA FTime10ms
STZ gTime10ms
INC gTime100ms
LDA gTime100ms
CMP #0AH
BNE QUIT_TimerG_ISR
LDA #01H
STA FTime100ms
INC gLED_FLASH500ms
STZ gTime100ms
INC gTime500ms
LDA gTime500ms
CMP #10H
BNE QUIT_TimerG_ISR
LDA #01H
STA FTime500ms
STZ gTime500ms
QUIT_TimerG_ISR:
;.ifdef FW_PWM_TIMER_TMG1
; JMP FW_PWM_TIMER_DOWNCOUNT
;FW_TIMER_DWONCOUNT_RET:
;.endif
LDA #40H
STA !EFC0 ;CLEAR EVF OF TIMERG1
PLA
RTI
;===============================================================
; SR_NAME: TIMERG0_ISR ;
; INPUT : ISR0_NEXT_SYNTH_START ;OUTPUT : SP0CLT, SP0CT
;===============================================================
.IF (CHIPSERIES = 'W588D')
TMG0_ISR:
LIB_VS0_ISR:
LIB_VS0A_ISR:
PHA
LDA #08H
STA !EFC0 ;CLEAR EVF OF TIMERG
.ifdef FW_PWM_TIMER_TMG0
JMP FW_PWM_TIMER_DOWNCOUNT
FW_TIMER_DWONCOUNT_RET:
.endif
.IF (WITH_VS0A .EQ. 1H)
PHX
PHY
STORE_SW_CS
LDA !BANK
PHA
.IF (WITH_VOL_REDUCE .EQ. 1)
LDA #CHANNEL_VS0A
PHA
.ENDIF
JMP_CH1_ISR_ACTION
.ENDIF
PLA
RTI
.ENDIF
;===============================================================
; SR_NAME: TIMER0_ISR ;
; INPUT : ISR1_NEXT_SYNTH_START ;OUTPUT : SP0ALT, SP0AT
;===============================================================
TM0_ISR:
LIB_VS1_ISR:
LIB_VS1A_ISR:
PHA
LDA #02H
STA !EFC0 ;CLEAR EVF OF TIMERG
.ifdef FW_PWM_TIMER_TM0
JMP FW_PWM_TIMER_DOWNCOUNT
FW_TIMER_DWONCOUNT_RET:
.endif
.IF (WITH_VS1A .EQ. 1H)
PHX
PHY
STORE_SW_CS
LDA !BANK
PHA
.IF (WITH_VOL_REDUCE .EQ. 1)
LDA #CHANNEL_VS1A
PHA
.ENDIF
JMP_CH2_ISR_ACTION
.ENDIF
PLA
RTI
;===============================================================
; SR_NAME: TIMER2_ISR ;
; INPUT : ISR2_NEXT_SYNTH_START ;OUTPUT : SP0BLT, SP0BT
;===============================================================
TM1_ISR:
LIB_VS2_ISR:
LIB_VS2A_ISR:
PHA
LDA #04H
STA !EFC0 ;CLEAR EVF OF TIMER1
.ifdef FW_PWM_TIMER_TM1
JMP FW_PWM_TIMER_DOWNCOUNT
FW_TIMER_DWONCOUNT_RET:
.endif
.IF (WITH_VS2A .EQ. 1H)
PHX
PHY
STORE_SW_CS
LDA !BANK
PHA
.IF (WITH_VOL_REDUCE .EQ. 1)
LDA #CHANNEL_VS2A
PHA
.ENDIF
JMP_CH3_ISR_ACTION
.ENDIF
PLA
RTI
;===============================================================
; Quit Libary ISR Lable
;===============================================================
QUIT_LIB_ISR:
SP_VOLUME_REDUCE
PLA
STA !BANK
RELOAD_SW_CS
PLY
PLX
PLA
RTI
;===============================================
; Main program start here after resetting
;===============================================
MAIN_START:
SYSTEM_INIT_PROCEDURE_W588 ;SYSTEM INITIALIZATION PROCEDURE
SET_STACK_POINTER_TO STACK_END ;USER CAN CHANGE THE VALUE
CLEAR_RAM_FROM_00H_TO RAM_END ;USER CAN CHANGE THE VALUE
CLI
SPECIAL_REGISTERS_INIT
LDA #00H
STA BP0D ;设置BP0[5:0]为输出口,用于控制6个LED灯
LDA #1FH
STA BP1D ;设置BP1[0]为输入口,用于按键触发。
LDA #0FH
STA BP1EN_F
LDA #0FH
STA BP1EN_R ;设置BP1[0]口有电压跳变,将唤醒STOP模式
LDA IEF0
ORA #40H
STA IEF0
LDA #3CH
STA TMG1V ;设置1MS的TimerG1中断
LDA #05H
STA TMG1C ;TimerG1的时钟为Fsys/64,并激活TimerG1
;==============================================================
LDA #1H ;初始化键值;目的使按键只有两种状态(2、3)
STA gKEY_Times ;初始化为0,可以有三种状态(1、2、3)。
;==============================================================
MAIN_END:
S_Time10ms:
LDA FTime10ms
BIT #01H
BEQ S_Time100ms
STZ FTime10ms
LDA #01H
STA !WDTC
JSR MKEY_CHECK
S_Time100ms:
LDA FTime100ms
BIT #01H
BEQ S_Time500ms
STZ FTime100ms
JSR MKEY_Manage
S_Time500ms:
LDA FTime500ms
BIT #01H
BEQ SMAIN_END
STZ FTime500ms
INC gSTOP_Counter
LDA gSTOP_Counter
CMP #1EH
BCC SMAIN_END
STZ gSTOP_Counter
LDA #01H
STA STOP ;没有操作15s左右及进入STOP状态
STA EFC0
SMAIN_END:
JMP MAIN_END
;==========================================================================
;按键检测子程序,
;有键按下,FKEY_CHECK = 1,gKEY_Times加1,记录键按下的次数。
;==========================================================================
MKEY_CHECK:
LDA BP1
BIT #01H
BNE SKEY_END
LDA FKEY_CHECK
BNE SKEY_END
STZ gSTOP_Counter
INC g1KEY_Filter
LDA g1KEY_Filter
CMP #03H
BCC SKEY_END
STZ g1KEY_Filter
LDA #01H
STA FKEY_CHECK ;有键按下即为1。
INC gKEY_Times ;计数来分别是第几次按下键
BRA SKEY_END
SKEY_OFF:
; STZ FKEY_CHECK
STZ g1KEY_Filter
SKEY_END:
RTS
;==========================================================================
;按键处理子程序
;==========================================================================
MKEY_Manage:
LDA FKEY_CHECK
BEQ SKEY_Manage_END
LDA FKEY_Manage
BNE SKEY_Manage_END
LDA #01
STA FKEY_Manage
;------------------------------------
SKEY_3SEC:
LDA gKEY_Times
AND #03H
CMP #03H
BCC SKEY_2SEC
LDA #1H
STA gKEY_Times
PLAY Phrase2
JSR MCheck_sp2
BRA SKEY_Manage_END
SKEY_2SEC:
CMP #02H
BCC SKEY_1SEC
PLAY Phrase1
JSR MCheck_sp1
BRA SKEY_Manage_END
;*****************************************
SKEY_1SEC:
CMP #01H
BCC SKEY_Manage_END ;当前没用。
JSR MMouth_Close
;*****************************************
SKEY_Manage_END:
;-----------------------------------------
LDA BP1
BIT #01H
BEQ SKEY_MANA_RTS
LDA FKEY_Manage ;保证一次按下键,仅有效一次。
BEQ SKEY_MANA_RTS
STZ FKEY_Manage
STZ FKEY_CHECK
;-----------------------------------------
SKEY_MANA_RTS:
RTS
;============================================================================
;检测声音Phrase2是否播放完。
;============================================================================
MCheck_sp2:
STZ gLED_FLASH500ms
SPH2_BUSY_LOOP:
STZ gSTOP_Counter
LDA gLED_FLASH500ms
CMP #35
BCS SPH2_CLOSE
JSR MMouth_Big
BRA SPH2_END
SPH2_CLOSE:
LDA gLED_FLASH500ms
CMP #42
BCS SPH2_SMALL
JSR MMouth_Close
BRA SPH2_END
SPH2_SMALL:
LDA gLED_FLASH500ms
CMP #50
BCS SPH2_First
JSR MMouth_ROUND
BRA SPH2_END
SPH2_First:
LDA gLED_FLASH500ms
CMP #50
BCC SPH2_END
STZ gLED_FLASH500ms
;------------------------------
SPH2_END:
LDA #SP_BZ
AND <CH1_STATUS
BNE SPH2_BUSY_LOOP
JSR MLED_TURN_OFF
RTS
;==============================================================
;检测声音是否播放完。
;==============================================================
MCheck_sp:
SP_BUSY_LOOP:
; LDA #1
; STA !WDTC
LDA #SP_BZ
AND <CH1_STATUS
BNE SP_BUSY_LOOP
RTS
;==============================================================
;检测声音Phrase1是否播放完。
;==============================================================
MCheck_sp1:
STZ gLED_FLASH500ms
SPH1_BUSY_LOOP:
STZ gSTOP_Counter
LDA gLED_FLASH500ms
CMP #00
BNE SPH1_SMALL
SPH1_ROUND:
;------------------------------
JSR MMouth_ROUND ;圆口
;------------------------------
SPH1_SMALL:
LDA gLED_FLASH500ms
CMP #01
BNE SPH1_BIG
;------------------------------
JSR MMouth_SMALL ;小口
;------------------------------
SPH1_BIG:
LDA gLED_FLASH500ms
CMP #02
BNE SPH1_SM2
;------------------------------
JSR MMouth_Big ;大口
;------------------------------
SPH1_SM2:
LDA gLED_FLASH500ms
CMP #03
BNE SPH1_R2
;------------------------------
JSR MMouth_SMALL ;小口
;------------------------------
SPH1_R2:
LDA gLED_FLASH500ms
CMP #04
BNE SPH1_CLOSE
;------------------------------
JSR MMouth_ROUND ;圆口
;------------------------------
SPH1_CLOSE:
LDA gLED_FLASH500ms
CMP #05
BNE SPH1_First
;------------------------------
JSR MMouth_Close ;闭口
;------------------------------
SPH1_First:
LDA gLED_FLASH500ms
CMP #06
BCC SPH1_END
STZ gLED_FLASH500ms
SPH1_END:
LDA #SP_BZ
AND <CH1_STATUS
BNE SPH1_BUSY_LOOP
; JSR MMouth_Close
JSR MLED_TURN_OFF
RTS
;============================================================================
;嘴巴状态控制,BP02控制闭嘴(C),BP03控制大嘴下(D),BP04控制小嘴下(E),
; BP05控制小嘴上(F)
;嘴巴状态分为:闭嘴(C)、大嘴巴(C+D)、细嘴巴(C+E)、小嘴巴(E+F)
;BP00控制睁眼(A). BP01控制眯眼(B).
;==============================================================================
;闭嘴+睁眼 (A+C)1111,1010
;=================================
MMouth_Close:
LDA #FAH
STA BP0
RTS
;=================================
;大嘴巴+眯眼 (B+C+D)1111,0001
;=================================
MMouth_Big:
LDA #F1H
STA BP0
RTS
;=================================
;小嘴巴+睁眼(A+C+E)1110,1010
;=================================
MMouth_SMALL:
LDA #EAH
STA BP0
RTS
;=================================
;圆嘴巴+睁眼(A+E+F)1100,1110
;=================================
MMouth_ROUND:
LDA #CEH
STA BP0
RTS
;=================================
;圆嘴巴+睁眼(A+E+F)1100,1110
;=================================
MLED_TURN_OFF:
LDA #FFH
STA BP0
RTS
ENDS
;==========================================================================
; ASSIGN INTERRUPT VECTORS INSIDE THIS SECTION
;==========================================================================
VECTOR: SECTION
ORG 1000H
DW 0040H ;DO NOT REMOVE
DW 0000H ;DO NOT REMOVE
ORG 100EH
DW 0990H ;IV OF BRK
ORG 1010H
DW TM0_ISR ;TIMER 0 ISR ;DO NOT REMOVE
DW TM1_ISR ;TIMER 1 ISR ;DO NOT REMOVE
.IF (CHIPSERIES = 'W588D')
DW TMG0_ISR ;TIEMRG 0 ISR ;DO NOT REMOVE
.ELSE
DW 0000
.ENDIF
DW TMG1_ISR ;TIMERG 1 ISR
DW PORT_ISR ;DO NOT REMOVE
ORG 101AH
DW 0000H
DW MAIN_START ;IV OF RESET
DW IRQ_ISR ;IV OF IRQ
ORG 102EH
DW 0584H ;DO NOT REMOVE
ENDS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -