📄 slfprg-s08gbgt.asm
字号:
LOOP: BRCLR LOCK,ICGS1,LOOP ; wait until ICG stable
LDA FSTAT
ORA #mFACCERR
STA FSTAT ; clear any FACCERR flag
IFNDEF HISPEED
LDA #%00001101 ; div by 13 to fit into 150-200kHz Flash clock
ELSE
LDA #36 ; div by 36+1 to fit into 150-200kHz Flash clock
ENDIF
STA FCDIV
MOV #%00001100,SCC2 ; transmit & receive enable
CLR SCIBDH
IFNDEF HISPEED
MOV #16, SCIBDL ; BUS (2.4576M)/(16 * 16) = 9600Bd
ELSE
MOV #4, SCIBDL ; BUS (7.3728M)/(16 * 4) = 115200Bd
ENDIF
CLR SCC3
; OPTIONAL DELAY - if your RS232 hardware is lazy, uncomment following delay
; lazy means that probably RS232 receiver is not still ready to receive ACK from PC
; CLRX
;DLY2: CLRA
;DLY1: NOP
; DBNZA DLY1
; DBNZX DLY2
LDA SCS1
MOV #ACK,SCDR
LDX #T100MS
L2: CLRA
L1: BRSET RDRF,SCS1,CAUGHT
DBNZA L1
DBNZX L2
ILOP:
; timeout
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
CAUGHT: ; CAUGHT IN SELF-PROGRAMMING?
BSR READ
CLR SCC2 ; disable SCI
JSR ICGTRIM ; go & trim
MOV #%00001100,SCC2 ; transmit & receive enable
;*******************************************************************************************
; 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
LDA #(VER_NUM | RCS) ; version number & "Read command supported" flag
BSR WRITE
LDA SDIDH ; system device identification 1 register (high)
BSR WRITE
LDA SDIDL ; system device identification 1 register (low)
BSR WRITE
MOV #ID_STRING_END-ID_STRING, LEN
LDHX #ID_STRING
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
;*******************************************************************************************
WRITE:
BRCLR TC,SCS1,WRITE
STA SCDR
RTS
READ:
BRCLR RDRF,SCS1,READ
LDA SCDR
RTS
;*******************************************************************************************
ERASE_COM:
BSR READ
STA ADRS
BSR READ
STA ADRS+1
lda #(mFPVIOL+mFACCERR) ;mask
sta FSTAT ;abort any command and clear errors
mov #EraseSubSize, STAT ;length of flash erase routine to STAT
tsx
sthx STACK
ldhx #EraseSubEnd-1 ;point at last byte to move to stack
bra DoOnStack ;execute prog code from stack RAM
;*******************************************************************************************
WR_DATA_COM:
BSR READ
STA ADRS
BSR READ
STA ADRS+1
BSR READ
STA STAT
STA LEN
LDHX #DATA
STHX ADRR
WR_DATA_L1:
BSR READ
STA ,X
AIX #1
DBNZ STAT,WR_DATA_L1
lda #(mFPVIOL+mFACCERR) ;mask
sta FSTAT ;abort any command and clear errors
mov #ProgSubSize, STAT ;length of flash prog routine to STAT
tsx
sthx STACK
ldhx #ProgSubEnd-1 ;point at last byte to move to stack
; bra DoOnStack ;execute prog code from stack RAM
; fallthru to DoOnStack
;*******************************************************************************************
DoOnStack:
lda ,x ;read from flash
psha ;move onto stack
aix #-1 ;next byte to move
dbnz STAT, DoOnStack
tsx ;point to sub on stack
jmp ,x ;execute the sub on the stack (will return on it's own)
;*******************************************************************************************
EraseSub:
ldhx ADRS ;get flash address
sta 0,x ;write to flash; latch addr and data
lda #mPageErase ;get flash command
sta FCMD ;write the flash command
lda #mFCBEF ;mask to initiate command
sta FSTAT ;[pwpp] register command
nop ;[p] want min 4~ from w cycle to r
ChkDoneErase:
lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
bpl ChkDoneErase ;loop if FCCF = 0
ldhx STACK
txs
jmp SUCC ;refer status back to PC
EraseSubEnd:
EraseSubSize: equ (*-EraseSub)
;*******************************************************************************************
ProgSub:
lda FSTAT ;check FCBEF
and #mFCBEF ;mask it
beq ProgSub ;loop if not empty
ldhx ADRR
lda 0,x
aix #1
sthx ADRR
ldhx ADRS ;get flash address
sta 0,x ;write to flash; latch addr and data
aix #1
sthx ADRS
lda #mBurstProg ;get flash command
sta FCMD ;write the flash command
lda #mFCBEF ;mask to initiate command
sta FSTAT ;[pwpp] register command
dbnz LEN,ProgSub ;all bytes in a row?
ChkDoneProg:
lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
bpl ChkDoneProg ;loop if FCCF = 0
ldhx STACK
txs
jmp SUCC ;refer status back to PC
ProgSubEnd:
ProgSubSize: equ (*-ProgSub)
;*******************************************************************************************
ICGTRIM:
CLRX
CLRH
MONRXD:
BRSET RXDBIT,RXDPORT,MONRXD ; WAIT FOR BREAK SIGNAL TO START
CHKRXD:
BRSET RXDBIT,RXDPORT,BRKDONE ; (5) GET OUT OF LOOP IF BREAK IS OVER
AIX #1 ; (2) INCREMENT THE COUNTER
BRA CHKRXD ; (3) GO BACK AND CHECK SIGNAL AGAIN
BRKDONE:
PSHH
PULA ; PUT HIGH BYTE IN ACC AND WORK WITH A:X
IFDEF HISPEED
LSLA
ROLX
LSLA
ROLX ; mul by 4 since we're 4 times slower
ENDIF
TSTA ; IF MSB OF LOOP CYCLES = 0, THEN BREAK TAKES TOO
TXA ; FEW CYCLES THAN EXPECTED, SO TRIM BY SPEEDING
BEQ SLOW ; UP f OP .
FAST: CMP #$40 ; SEE IF BREAK IS WITHIN TOLERANCE
BGE OOR ; DON'T TRIM IF OUT OF RANGE
ASLA ; multiply by two to get right range
ADD #$80 ; BREAK LONGER THAN EXPECTED, SO SLOW DOWN f OP
BRA ICGDONE
SLOW: CMP #$C0 ; SEE IF BREAK IS WITHIN TOLERANCE
BLT OOR ; DON'T TRIM IF OUT OF RANGE
ASLA ; multiply by two to get right range
SUB #$80
ICGDONE:
STA ICGTRM
OOR:
RTS
;*******************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -