⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slfprgr-jk3.asm

📁 M68HC08及HCS08系列单片机bootloader引导程序源码/示例
💻 ASM
📖 第 1 页 / 共 2 页
字号:
    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 + -