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

📄 slfprgr-trim-qb.asm

📁 M68HC08及HCS08系列单片机bootloader引导程序源码/示例
💻 ASM
字号:
;*********************************************************************
; HEADER_START
;
;  	   $File Name: slfprgR-trim-qb.asm$
;      Project:        Developper's HC08 Bootloader Slave
;      Description:    QB main bootloader file
;      Platform:       HC08
;      $Version: 6.0.3.0$
;      $Date: Feb-22-2006$ 
;      $Last Modified By: r30323$
;      Company:        Freescale Semiconductor
;      Security:       General Business
;
; =================================================================== 
; Copyright (c):      Freescale Semiconductor, 2004, All rights reserved.
;
; =================================================================== 
; THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY
; EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL FREESCALE OR
; ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
; OF THE POSSIBILITY OF SUCH DAMAGE.
; ===================================================================
;
; HEADER_END

    include "reg-qb.h"

RCS_ENA         EQU     0     		; READ COMMAND SUPPORTED?

  IFNE RCS_ENA
RCS             EQU     $80   		; READ COMMAND SUPPORTED
  ELSE
RCS             EQU     0     		; READ COMMAND unSUPPORTED
  ENDIF

VER_NUM         EQU     1     		; FC protocol version number


ERBLK_LEN	  	EQU	    64
WRBLK_LEN	    EQU	    32       

            IF SIZE = 4		; QB4
FLS_BEG		    EQU	    $EE00    ; specify memory limit!
IDENTS          MACRO
                DC.B    'QB4-t',0  ; QB4 string
                ENDM
            ENDIF

            IF SIZE = 8		; QB8
FLS_BEG		    EQU	    $DE00    ; specify memory limit!
IDENTS          MACRO
                DC.B    'QB8-t',0  ; QB8 string
                ENDM
            ENDIF
            
FLS_END		    EQU	    $FCC0       ; this is APL_VECT address (also from PRM file)
INT_VECT	    EQU	    $FFDE


FLBPRMASK     EQU     $C000       ; this is CPU specific FLBPR mask (i.e. bits that are always in the address)

SPEED         EQU     8			; 4 x f(BUS)

ROMSTART      EQU     $2800

GETBYTE       EQU     ROMSTART
RDVRRNG       EQU     ROMSTART+3
ERARNGE       EQU     ROMSTART+6 
PRGRNGE       EQU     ROMSTART+9
DELNUS        EQU     ROMSTART+12

RAMSTART      EQU     $80
CTRLBYT       EQU     RAMSTART+$08
CPUSPD        EQU     RAMSTART+$09
LADDR         EQU     RAMSTART+$0A
DATA          EQU     RAMSTART+$0C

TXDDDR        EQU     DDRB
TXDPORT       EQU     PTB
TXDBIT        EQU     5
RXDPORT       EQU     PTB
RXDBIT        EQU     4

;*******************************************************************************************

    XDEF    FLBPR	; external define for FLBPR

    XDEF    main
    XDEF    VEC1
    XDEF    VEC2
    XDEF    APL_VECT
    XDEF    VEC4
    XDEF    VEC5
    XDEF    VEC6
    XDEF    VEC7
    XDEF    VEC8
    XDEF    VEC9
    XDEF    VEC10
    XDEF    VEC11
    XDEF    VEC12
    XDEF    VEC13
    XDEF    VEC14
    XDEF    VEC15
    XDEF    VEC16


WR_DATA     EQU     'W'
RD_DATA     EQU     'R'
ENDPRG      EQU     'Q'
ERASE       EQU     'E'
ACK         EQU     $FC
IDENT       EQU     'I'

T100MS      EQU     255

ILOP      MACRO
            DC.B    $32             ; this is illegal operation code
          ENDM
;*******************************************************************************************
MY_ZEROPAGE:	SECTION  SHORT

ADRS:	  DS.W	  1
LEN:	  DS.B	  1
STAT:	  DS.B	  1
STSRSR: DS.B    1               ; storage for SRSR reg.

DEFAULT_RAM:    SECTION

;*******************************************************************************************
APL_VECT_ROM:	SECTION

APL_VECT:
PRIV:    DC.B    $80,0,0,0,0,0,0,0 ; 8 bytes reserved for bootloader's private use
        
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

;*******************************************************************************************
FLB_PROT_ROM:	SECTION
FLBPR:  DC.B    (FLS_END+ERBLK_LEN-FLBPRMASK)/ERBLK_LEN ; FLASH protection block start - MUST CHANGE ACCORDING TO MEMORY MAPPING

CODE_ROM:	SECTION 

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:

ID_STRING2:
	    IDENTS
ID_STRING2_END:

****************************************************************************************
FL1_PROT_ROM:	SECTION
; 29 bytes
main:	
        LDA     SRSR            ;[3] fetch RESET status reg.
        STA     STSRSR          ;[2] store for later re-use
        TSTA                    ;[1] check if zero (this happens if RESET pulse is too short)

        BEQ     slfprg          ;[2] if so, jump to self programming                
        AND     #%10000000      ;[2] mask only POR RESET source      
        BNE     slfprg          ;[2] any of these sources, go to self programming

		    LDA     PRIV    				;[3] fetch private OSCTRIM
        STA     OSCTRIM         ;[2] trim ICG now
        
		    JMP		  VEC0					  ;[3] jump to real application

slfprg: 
	      MOV	    #%10000001,CONFIG1  ;[3] COP disable, 
    	                              ;ESCI clock = CGMXCLK by default (via CONFIG2)
		    MOV		  #%00100000,OSCSC    ;[3] 12.8MHz Internal clock select
		
		    BRA		  page1					  ;[2]
FL0_PROT_ROM:	SECTION
; 14 bytes
page1:
        BSET    6,SCC1           ;[2] SCI enable
        MOV     #%00001100,SCC2  ;[3] transmit & receive enable
    	  MOV	    #%00010000,SCBR  ;[3] 9600Bd @ 12.8MHz CGMXCLK (:3)
    	  MOV	    #%10111110,SCPSC ;[3] 9600Bd @ 12.8MHz CGMXCLK (:(6+30/32))

    	  JMP		  page0					  ;[3]

CODE_ROM:	SECTION 
page0:
    	  CLR     SCC3					   ;[2] ctrl. reg
    	  LDA	    SCS1					  ;[2]
    	  MOV	    #ACK,SCDR				;[2] present ACK (we're here)

    	  LDX	    #T100MS
L2:	    CLRA
L1:	    BRSET	  5,SCS1,CAUGHT
    	  DBNZA	  L1
      	DBNZX	  L2

;       timeout
        ILOP          ; generate RESET by doing illegal operation
;*******************************************************************************************
CAUGHT:			; CAUGHT IN SELF-PROGRAMMING?
		    BSR     READ

        BCLR    6,SCC1          ; disable SCI

        JSR     ICGTRIM		      ; go & trim

        BSET    6,SCC1          ; SCI enable
        MOV     #%00001100,SCC2 ; transmit & receive enable
		
        MOV     #SPEED,CPUSPD   ; feed the speed
        CLR     CTRLBYT         ; no mass erase	(QB will probably neeed this byte cleared
                                ; competely as well as QC family)
;*******************************************************************************************
; 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
        MOV     #ID_STRING1_END-ID_STRING1, LEN
        LDHX    #ID_STRING1
        BSR     WRITE_LOOP
 
        LDA     OSCTRIM
        BSR     WRITE           ; next byte would be ICGTR, needed when no boot done!
  
        LDHX    #PRIV+1         ; next 7 are from private area
        MOV     #7,LEN
        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											; low in A as well
;*******************************************************************************************
WRITE:	
        BRCLR	  6,SCS1,WRITE
    	  STA	    SCDR
        RTS
READ:
        BRCLR	  5,SCS1,READ
    	  LDA	    SCDR
      	RTS
;*******************************************************************************************
ERASE_COM:
        BSR     GETADDR         ; read adr. and return in H:X
        
        ADD     ERBLK_LEN-1  		; low address in A, add erase block length
        STA     LADDR+1         ; store in LastAddress

        PSHH                    ; get high address
        PULA                    ; transfer to A
        STA     LADDR           ; and store to LastAddress
        
        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
        
        JMP     SUCC            ; refer status back to PC
;*******************************************************************************************
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
        NOP                     ; (1)
        NOP                     ; (1)
        NOP                     ; (1)
        BRA     CHKRXD          ; (3) GO BACK AND CHECK SIGNAL AGAIN
BRKDONE:
        PSHH
        PULA                    ; PUT HIGH BYTE IN ACC AND WORK WITH A:X
        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     OSCTRIM
OOR:
        RTS
;*******************************************************************************************
END  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -