📄 slfprgr-jk3.asm
字号:
IF RXDISIRQ = 1
IF SCIRXINV = 1
BIL \1 ; branch if RXD hi
ELSE
BIH \1 ; branch if RXD hi
ENDIF
ELSE ; RXD uses normal I/O pin
IF SCIRXINV = 1
BRCLR RXDPIN,RXDPORT,\1 ; branch if RXD hi
ELSE
BRSET RXDPIN,RXDPORT,\1 ; branch if RXD hi
ENDIF
ENDIF
ENDM
TXDCLR MACRO
IF SCITXINV = 1
BSET TXDPIN,TXDPORT ; clr bit
ELSE
BCLR TXDPIN,TXDPORT ; clr bit
ENDIF
ENDM
TXDSET MACRO
IF SCITXINV = 1
BCLR TXDPIN,TXDPORT ; set bit
ELSE
BSET TXDPIN,TXDPORT ; set bit
ENDIF
ENDM
TMOD EQU TMODH ; we use high address for storing all 16 bits at once
;*******************************************************************************************
MY_ZEROPAGE: SECTION SHORT
ONEBIT: DS.W 1
BITS: DS.B 1
ADRS: DS.W 1
LEN: DS.B 1
STAT: DS.B 1
STSRSR: DS.B 1 ; storage for SRSR reg.
;*******************************************************************************************
APL_VECT_ROM: SECTION
APL_VECT:
PRI: DC.W SCITXTICK
DC.W 0
DC.W 0
DC.W 0
VEC0: JMP main ; vector 0
VEC1: JMP main ; vector 1
VEC2: JMP main ; vector 2
VEC3: JMP main ; vector 3
VEC4: JMP main ; vector 4
VEC5: JMP main ; vector 5
VEC6: JMP main ; vector 6
VEC7: JMP main ; vector 7
VEC8: JMP main ; vector 8
VEC9: JMP main ; vector 9
VEC10: JMP main ; vector 10
VEC11: JMP main ; vector 11
VEC12: JMP main ; vector 12
VEC13: JMP main ; vector 13
VEC14: JMP main ; vector 14
VEC15: JMP main ; vector 15
VEC16: JMP main ; vector 16
CODE_ROM: SECTION
SCIAPI:
DC.W SCIINIT ; address of WRITE call
DC.W READ ; address of READ call
DC.W WRITE ; address of WRITE call
DC.W ONEBIT ; address of ONEBIT variable
FL1_PROT_ROM: SECTION
; 14 bytes
ID_STRING1:
DC.B VER_NUM | RCS ; version number & "Read command supported" flag
DC.W FLS_BEG ; START ADDRESS OF FLASH
DC.W FLS_END ; END ADDRESS OF FLASH
DC.W APL_VECT ; POINTER TO APPLICATION VECTOR TABLE
DC.W INT_VECT ; POINTER TO BEGINING OF FLASH INT. VECTORS
DC.W ERBLK_LEN ; ERASE BLCK LENGTH OF FLASH ALG.
DC.W WRBLK_LEN ; WRITE BLCK LENGTH OF FLASH ALG.
ID_STRING1_END:
CODE_ROM: SECTION
ID_STRING2:
IDENTS
ID_STRING2_END:
;*******************************************************************************************
main:
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
slfprg:
IF CONFIG2DEF = 0
CLR CONFIG2
ELSE
MOV #CONFIG2DEF,CONFIG2 ; from definition
ENDIF
MOV #%10000001,CONFIG1 ; COP disable
LDA #(FLS_END+ERBLK_LEN-FLBPRMASK)/32
STA FLBPR ; is in RAM!!
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)
IF RXDISIRQ = 0 ; RXDPORT & RXDPIN is defined (not IRQ)
BCLR RXDPIN,RXDDDR ; input for RXD
IF RXDPUEN = 1
BSET RXDPIN,RXDPUE
ENDIF
ENDIF
TXDSET
IF SINGLEWIRE=0
BSET TXDPIN,TXDDDR ; (2B) output for TXD
ENDIF
RTS
;*******************************************************************************************
CAUGHT: ; CAUGHT IN SELF-PROGRAMMING?
JSR SCIRXNOEDGE
IF CALENABLED = 1
CLRH
CLRX
MONRXD2:
BRRXDHI MONRXD2
CHKRXD:
BRRXDHI BRKDONE
IF RXDISIRQ = 1
NOP ; (1)
NOP ; (1)
ENDIF
AIX #1 ; (2) INCREMENT THE COUNTER
BRA CHKRXD ; (3) GO BACK AND CHECK SIGNAL AGAIN
BRKDONE:
STHX ONEBIT ; store it
TXA
LDX #$1a ; calculate speed
DIV
ELSE
LDA #16 ; <<< modify this if no calibration is required (BUS freq in MHz * 4)
ENDIF
STA 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
JSR 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
;*******************************************************************************************
FL2_PROT_ROM: SECTION
; 16 bytes
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
JMP page3 ; (3B) total 14 (of 14)
CODE_ROM: SECTION
page3:
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 + -