📄 slfprgr-lb.asm
字号:
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
slfprg:
CLR CONFIG2 ; int. oscillator enable
MOV #%10000001,CONFIG1 ; COP disable
BSR SCIINIT ; call SCI init now :)
LDHX #SCITXTICK ; ONEBIT is rewritten to default value
STHX ONEBIT ; just for case the private area is erased
LDA #ACK
JSR WRITE
LDX #T100MS
LL2: CLRA
LL1: BRRXDHI L1
DBNZA LL1
DBNZX LL2
; timeout
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
L2: CLRA
L1: BRRXDLO CAUGHT
DBNZA L1
DBNZX L2
; timeout
ILOP ; generate RESET by doing illegal operation
;*******************************************************************************************
SCIINIT:
LDX PRI+1 ; [3B]
LDA PRI ; [3B]
PSHA ; [1B]
PULH ; [1B]
STHX ONEBIT ; (2B)
BCLR RXDPIN,RXDDDR ; input for RXD
BSET RXDPIN,RXDPUE
TXDSET
IF SINGLEWIRE=0
BSET TXDPIN,TXDDDR ; (2B) output for TXD
ENDIF
RTS
;*******************************************************************************************
CAUGHT: ; CAUGHT IN SELF-PROGRAMMING?
JSR SCIRXNOEDGE
CLRH
CLRX
MONRXD2:
BRRXDHI MONRXD2
CHKRXD:
BRRXDHI BRKDONE
AIX #1 ; (2) INCREMENT THE COUNTER
BRA CHKRXD ; (3) GO BACK AND CHECK SIGNAL AGAIN
BRKDONE:
STHX ONEBIT ; store it
MOV #SPEED, CPUSPD
CLR CTRLBYT ; no mass erase
;*******************************************************************************************
; successful return from all write routines
SUCC:
LDA #ACK
JSR 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
LDHX #ONEBIT ; next 8 are from RAM area (!)
MOV #8,LEN ; 8 is future priv area
BSR WRITE_LOOP
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
;*******************************************************************************************
GETADDR:
BSR READ
PSHA
PULH ; store to H:x
BSR READ
TAX ; store to h:X
RTS
;*******************************************************************************************
ERASE_COM:
BSR GETADDR ; read adr. and return in H:X
JSR ERARNGE ; call ROM erase routine
BRA SUCC ; refer status back to PC
;*******************************************************************************************
WR_DATA_COM:
BSR GETADDR ; read adr. and return in H:X
STHX ADRS
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
BRA SUCC ; refer status back to PC
;*******************************************************************************************
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 TMODH ; first TOF should occur just half bit
STA TMODL ; after the hi-lo edge (right in the middle of start bit)
SCIRX1:
BRRXDHI SCIRX1 ; loop until RXD low (wait for start bit)
MOV #%00010000,TSC ; initialize prescalers, reset & run the timer
MOV #9,BITS ; number of bits + 1
SCIRX2: BRCLR 7,TSC,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 TMOD
BCLR 7,TSC ; and clear TOF
DBNZ BITS,SCIRX2 ; and loop for next bit
BRA EPILOG
;*******************************************************************************************
WRITE:
PSHH ; (1B)
PSHX ; (1B)
LDHX ONEBIT ; (2B)
STHX TMOD ; (2B)
IF SINGLEWIRE=1
BSET TXDPIN,TXDDDR ; (2B) output for TXD
ENDIF
MOV #%00010000,TSC ; (3B) initialize prescalers, reset & run the timer
SCITX0: BRCLR 7,TSC,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 7,TSC ; and clear TOF
SCITX1: BRCLR 7,TSC,SCITX1 ; wait for TOF
DBNZ BITS,SCITX2 ; and loop for next bit
EPILOG:
MOV #%00110000,TSC ; stop & reset timer
IF SINGLEWIRE=1
BCLR TXDPIN,TXDDDR ; (2B) input for TXD (shared with RXD)
ENDIF
PULX
PULH
RTS
;*******************************************************************************************
SCI_PROT_ROM: SECTION
; 2 bytes
SCIAPIREF:
DC.W SCIAPI ; this address holds the start of SCI API table
; this is an address of READ call,
; WRITE call is 2 bytes higher
;*******************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -