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

📄 slfprg-s08gbgt.asm

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