📄 slfprg-s08qg-softsci.asm
字号:
MOV #%00000000,ICSC2 ; bus divide :1, ie bus = 8MHz
; f(BUS)=f(ICGOUT)/2
LDA FSTAT
ORA #mFSTAT_FACCERR
STA FSTAT ; clear any FACCERR flag
LDA #(mFCDIV_PRDIV8 + 4) ; div by 8*(4+1) to fit into 150-200kHz Flash clock!
STA FCDIV
LDHX #SCITXTICK ; ONEBIT default value
STHX ONEBIT
IF RXDPUEN=1
LDA RXDPUE
ORA #(1<<RXDPIN)
STA RXDPUE ; pull-up RXD pin (if enabled)
ENDIF
TXDSET ; TxD pin idle
IF SINGLEWIRE=0
BSET TXDPIN,TXDDDR ; output for TXD
ENDIF
BCLR RXDPIN,RXDDDR ; input for RXD
; OPTIONAL DELAY - if your RS232 hardware is lazy, uncomment following delay
; CLRX
;DLY2: CLRA
;DLY1: NOP
;
; DBNZA DLY1
; DBNZX DLY2
;
LDA #ACK
JSR WRITE
LDX #T100MS
LL2: CLRA
LL1: BRRXDHI L1
DBNZA LL1
DBNZX LL2
; timeout - no data
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
L2: CLRA
L1: BRRXDLO CAUGHT ; hi-lo edge required (start bit)
DBNZA L1
DBNZX L2
; timeout - no data
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
CAUGHT: ; CAUGHT IN SELF-PROGRAMMING?
JSR SCIRXNOEDGE
CLRH
CLRX ; calibrate now
MONRXD2:
BRRXDHI MONRXD2
CHKRXD:
BRRXDHI BRKDONE ; (5) together 10 BUS clocks per loop
; we measure 10 bits time so at the
; and H:X will contain a correct BUS
; clock ticks for 1 bit time
AIX #1 ; (2) INCREMENT THE COUNTER
BRA CHKRXD ; (3) GO BACK AND CHECK SIGNAL AGAIN
BRKDONE:
STHX ONEBIT ; store it
;*******************************************************************************************
; successful return from all write routines
SUCC:
LDA #ACK ; send ACK
JSR WRITE
;fall thru to background
;*******************************************************************************************
; BEGIN OF BACKGROUND COMMAND LOOP
BCKGND:
JSR READ ; read command from PC
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:
JSR READ
STA ADRS
BSR READ
STA ADRS+1
BSR READ
STA LEN
LDHX ADRS
BSR WRITE_LOOP
BRA BCKGND ; finish without ACK
ENDIF
;*******************************************************************************************
ERASE_COM:
BSR READ
STA ADRS
BSR READ
STA ADRS+1
lda #(mFSTAT_FPVIOL+mFSTAT_FACCERR) ;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
jmp 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 #(mFSTAT_FPVIOL+mFSTAT_FACCERR) ;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
jmp DoOnStack ; execute prog code from stack RAM
;*******************************************************************************************
;*******************************************************************************************
WRITE:
PSHH ; (1B)
PSHX ; (1B)
LDHX ONEBIT ; (2B)
STHX TPMMOD ; (2B)
IF SINGLEWIRE=1
BSET TXDPIN,TXDDDR ; (2B) output for TXD
ENDIF
MOV #%00001000,TPMSC ; initialize prescalers, run the timer, select clock
STA TPMCNTH ; clear counter
SCITX0: BRCLR TPMSC_TOF,TPMSC,SCITX0 ; wait for TOF
MOV #10,BITS ; number of bits + 1 stop bit
BRA DATALOW ; jump to loop
SCITX2:
SEC ; set carry so stop bit is '1'
RORA ; rotate lowest bit
BCC DATALOW
TXDSET
SKIP2 ; skip next two bytes
DATALOW:
TXDCLR
BCLR TPMSC_TOF,TPMSC ; and clear TOF
SCITX1: BRCLR TPMSC_TOF,TPMSC,SCITX1 ; wait for TOF
DBNZ BITS,SCITX2 ; and loop for next bit
EPILOG:
CLR TPMSC ; stop timer
IF SINGLEWIRE=1
BCLR TXDPIN,TXDDDR ; (2B) input for TXD (shared with RXD)
ENDIF
PULX
PULH
RTS
;*******************************************************************************************
READ:
BRRXDLO READ ; (3B) loop until RXD high (idle)
SCIRXNOEDGE:
PSHH ; (1B)
PSHX ; (1B)
LDX ONEBIT ; (2B)
LDA ONEBIT+1 ; (2B)
LSRX ; (1B)
RORA ; (1B)
STX TPMMODH ; first TOF should occur just half bit
STA TPMMODL ; after the hi-lo edge (right in the middle of start bit)
SCIRX1:
BRRXDHI SCIRX1 ; loop until RXD low (wait for start bit)
MOV #%00001000,TPMSC ; initialize prescalers, run the timer, select clock
STA TPMCNTH ; clear counter
MOV #9,BITS ; number of bits + 1
SCIRX2: BRCLR TPMSC_TOF,TPMSC,SCIRX2 ; wait for TOF
LSRA ; shift data right (highest bit cleared)
BRRXDLO RXDLOW ; skip if RXD low
ORA #$80 ; set highest bit if RXD high
RXDLOW: LDHX ONEBIT
STHX TPMMODH
BCLR TPMSC_TOF,TPMSC ; and clear TOF
DBNZ BITS,SCIRX2 ; and loop for next bit
BRA EPILOG
;*******************************************************************************************
;*******************************************************************************************
ROM_2: SECTION
; 62 bytes
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)
DEFAULT_ROM: SECTION
;*******************************************************************************************
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 #mFSTAT_FCBEF ;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)
;*******************************************************************************************
ROM_2: SECTION
; 62 bytes
ProgSub:
lda FSTAT ;check FCBEF
and #mFSTAT_FCBEF ;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 #mFSTAT_FCBEF ;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)
DEFAULT_ROM: SECTION
;*******************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -