📄 slfprg-gr.asm
字号:
ENDIF
IFDEF IRQOPTION
BIH VEC0 ; [for special case - if IRQ high, jump directly to real app.]
ENDIF
LDA SRSR ; fetch RESET status reg.
STA STSRSR ; store for later re-use
TSTA ; check is zero (this happens if RESET pulse is too short)
BEQ slfprg ; if so, jump to self programming
AND #%10000000 ; mask only POR RESET source
BEQ VEC0 ; any of these sources, go to self programming
IF VERSION = 1
slfprg: MOV #%00000001,CONFIG2
MOV #%10010001,CONFIG1
CLR PCTL
BSET 0,PCTL ; P = 0, E = 1
MOV #$01,PMSH
MOV #$C0,PMSL ; 3.6864 MHz
MOV #$C0,PMRS
MOV #$01,PMDS
BSET 5,PCTL ; TURN ON PLL
BSET 7,PBWC ; PUT IN AUTO BANDWIDTH MODE
LOOP: BRCLR 6,PBWC,LOOP ; WAIT FOR PLL TO LOCK
BSET 4,PCTL ; SELECT CGMVCLK TO DRIVE CGMOUT
BSET 6,SCC1 ; SCI enable
MOV #%00001100,SCC2 ; transmit & receive enable
CLR SCC3
MOV #%00010001,SCBR ; 9600Bd @ 3.68MHz
ENDIF
IF VERSION = 2 ; external clock settings
slfprg: MOV #%00000000,CONFIG2 ; external clk used as a SCI clock source
MOV #%00010001,CONFIG1 ; LVIPWRDisable, COPDisable
BSET 6,SCC1 ; SCI enable
MOV #%00001100,SCC2 ; transmit & receive enable
CLR SCC3
MOV #%00010000,SCBR ; 57600Bd @ 11.05927 MHz
ENDIF
IF (VERSION = 3) || (VERSION = 4) || (VERSION = 5)
slfprg: CLR CONFIG2 ; SCI clk = Xtal clk
IFDEF LVICOP
MOV #%10000000, CONFIG1 ; LVI enabled for 3.3V, COP enabled & short timeout
ELSE
MOV #%10010001, CONFIG1 ; COP disabled & LVI disabled
ENDIF
CLR PCTL ; clear PCTL first
MOV #%00000001, PCTL ; P = 0, E = 1
CLR PMSH
MOV #2,PMSL ; 16MHz fVCLK (N = 2), 2*8MHz (2*7.2MHz), BUS 4MHz (3.6MHz), suitable also for 3V systems
MOV #1,PMDS ; R = 1
IF (VERSION = 3) ; 8MHz
MOV #208,PMRS ; L = 208 (for E=1) = 16MHz (fVclk) = (208 * 2^1) * 38400 (fNOM)
ENDIF
IF (VERSION = 4) ; 7.2MHz
MOV #188,PMRS ; L = 188 (for E=1) = 14.4000MHz (fVclk) = (188 * 2^1) * 38400 (fNOM)
ENDIF
IF (VERSION = 5) ; 7.37MHz
MOV #192,PMRS ; L = 192 (for E=1) = 14.7456MHz (fVclk) = (192 * 2^1) * 38400 (fNOM)
ENDIF
BSET 7,PBWC ; PUT IN AUTO BANDWIDTH MODE first
BSET 5,PCTL ; TURN ON PLL
LOOP: BRCLR 6,PBWC,LOOP ; WAIT FOR PLL TO LOCK
BSET 4,PCTL ; SELECT CGMVCLK TO DRIVE CGMOUT
BSET 6,SCC1 ; SCI enable
MOV #%00001100,SCC2 ; transmit & receive enable
CLR SCC3
IF (VERSION = 3)
IFDEF HIGHSPEED
'ERROR -- not possible to have 38400Bd with 8MHz Xtal clock driving SCI module
ELSE
MOV #%00110000,SCBR ; 9600Bd @ 8MHz (PD=13 BD=1)
ENDIF
ENDIF
IF (VERSION = 4) || (VERSION = 5)
IFDEF HIGHSPEED
MOV #%00010000,SCBR ; 38400Bd @ 7.2(7.37)MHz (PD=3 BD=1) 37500Hz (2.3% off 38400) for 7.2MHz, 7.37MHz is sharp
ELSE
MOV #%00010010,SCBR ; 9600Bd @ 7.2(7.37)MHz (PD=3 BD=4) 9375Hz (2.3% off 9600) for 7.2MHz, 7.37MHz is sharp
ENDIF
ENDIF
ENDIF
LDA SCS1
MOV #ACK,SCDR
LDX #T100MS
L2: CLRA
L1: BRSET 5,SCS1,CAUGHT
IFDEF LVICOP
STA COPCTL
ENDIF
DBNZA L1
DBNZX L2
; timeout
ENDPRG_COM:
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
CAUGHT: ; CAUGHT IN SELF-PROGRAMMING?
BSR READ
CMPA #ACK
BNE ENDPRG_COM
MOV #SPEED,CPUSPD ; feed the speed
BCLR 6,CTRLBYT ; no mass erase
;*******************************************************************************************
; successful return from all write routines
SUCC:
LDA #ACK
BSR WRITE
;fall thru to background
;*******************************************************************************************
; BEGIN OF BACKGROUND COMMAND LOOP
BCKGND:
BSR READ
CBEQA #ERASE, ERASE_COM ; Erase command
CBEQA #WR_DATA, WR_DATA_COM ; Write (program) command
CBEQA #IDENT, IDENT_COM ; Ident command
IF RCS_ENA = 1
CBEQA #RD_DATA, RD_DATA_COM ; Read command
ENDIF
; if no valid command found (including Quit)
; generate reset too!
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
IDENT_COM: ; TRANSFER OF IDENTIFICATION STRING
MOV #ID_STRING1_END-ID_STRING1, LEN
LDHX #ID_STRING1
BSR WRITE_LOOP
LDA STSRSR ; first byte will be SRSR reg.
BSR WRITE
LDHX #PRI+1 ; next 6 are from private area
MOV #6,LEN
BSR WRITE_LOOP
LDA FLBPR
BSR WRITE ; last byte would be FLBPR, just for info
MOV #ID_STRING2_END-ID_STRING2, LEN
LDHX #ID_STRING2
BSR WRITE_LOOP
BRA BCKGND ; finish without ACK
;*******************************************************************************************
WRITE_LOOP: ; start address in HX, length in LEN
LDA ,X
BSR WRITE
AIX #1
DBNZ LEN, WRITE_LOOP
RTS
;*******************************************************************************************
IF RCS_ENA = 1
RD_DATA_COM:
BSR READ
STA ADRS
BSR READ
STA ADRS+1
BSR READ
STA LEN
LDHX ADRS
BSR WRITE_LOOP
BRA BCKGND ; finish without ACK
ENDIF
;*******************************************************************************************
READ:
IFDEF LVICOP
STA COPCTL
ENDIF
BRCLR 5,SCS1,READ
LDA SCDR
RTS
WRITE:
IFDEF LVICOP
STA COPCTL
ENDIF
BRCLR 6,SCS1,WRITE
STA SCDR
RTS
;*******************************************************************************************
ERASE_COM:
BSR READ
PSHA
PULH ; store to H:x
BSR READ
TAX ; store to h:X
JSR ERARNGE ; call ROM erase routine
BRA SUCC ; refer status back to PC
;*******************************************************************************************
WR_DATA_COM:
BSR READ
STA ADRS
BSR READ
STA ADRS+1
BSR READ
STA STAT
DECA
STA LEN
LDHX #DATA
WR_DATA_L1:
BSR READ
STA ,X
AIX #1
DBNZ STAT,WR_DATA_L1
; START OF SELF-PROGRAMMING
LDA ADRS+1
ADD LEN
STA LADDR+1
LDA ADRS
ADC #0
STA LADDR
LDHX ADRS
JSR PRGRNGE ; call ROM erase routine
JMP SUCC ; refer status back to PC
;*******************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -