📄 boot51.a51
字号:
; *************************
; * B O O T - 5 1 *
; *************************
;
; A Bootstrap Program for the MCS-51 Microcontroller Family
;
; Version 1.1 by W.W. Heinz 15. 12. 2002
;
;-----------------------------------------------------------------------
; File boot51.inc contains the customization data for the target system:
$INCLUDE(boot51.inc) ; (must be generated with the CUSTOMIZ program)
;ASCII characters:
BEL EQU 7 ;beep
BS EQU 8 ;backspace
CR EQU 13 ;carriage return
LF EQU 10 ;line feed
DEL EQU 07FH ;delete
CPROMPT EQU '>' ;command line prompt
UPROMPT EQU ':' ;upload prompt
DSEG AT 8 ;only register bank 0 is in use
STACK: DS 28H ;stack starts right behind bank 0
CMDLIN: DS 47H ;command line buffer
CMDMAX: DS 1 ;(last byte)
CSEG AT STARTADDR
;on boards, where the EPROM doesn't start at address 0000H,
;first of all a long jump into the EPROM area may be required
;to remap memory:
LJMP START
;on boards where the EPROM starts at address 0000H, the
;interrupt addresses should better be redirected to the
;area in extended RAM, where user programs start:
REPT 20
LJMP $-STARTADDR+USERPROGS
DS 5
ENDM
;Normally, 20 interrupt addresses should be enough.
;(The SIEMENS C517A has 17.)
;But you may insert some more, if required.
;(The Infineon C508 uses 20, but wastes 9 more!)
;this sign-on message is output after reset:
SIGNON: DB CR,LF,CR,LF
DB 'BOOT-51 V1.1'
DB ' '
DB 'Copyright (c) 2002 by W.W. Heinz'
DB CR,LF,0
START: ;start of bootstrap program
CALL INITBG ;initialize baudrate generator
MOV SCON,#072H ;UART mode 1, 8 bit, ignore garbage
CALL DELAY ;let the UART have some clocks ...
MOV DPTR,#SIGNON ;display sign-on message
CALL STRING
CALL INTERP ;call command line interpreter
MOV SP,#7 ;better set to reset value
PUSH DPL ;save start address of user program
PUSH DPH ;on stack
WARTEN: CALL CONOST ;wait until the UART is ready
JZ WARTEN ;for the next character to send,
CALL DELAY ;and the last bits have left the UART
CALL STOPBG ;stop baudrate generator
MOV DPTR,#0 ;set modified SFR to reset values:
CLR A ;(if possible)
MOV SCON,A
MOV B,A
MOV PSW,A
RET ;up'n away (and SP --> 7)
INTERP: ;command line interpreter
CALL RDCOMM ;read command
MOV R0,#CMDLIN ;command line start address
INTER1: MOV A,@R0 ;end of command line reached ?
JZ INTERP ;then read a new command
CALL UPCASE ;convert character to upper case
INC R0 ;point to next character
CJNE A,#' ',INTER2 ;is it a blank ?
JMP INTER1 ;then ignore it
INTER2: MOV R7,A ;save character
CALL NEWLIN ;new line
MOV A,R7 ;command character
CJNE A,#'U',INTER3 ;UPLOAD ?
CALL NIXMER ;check for end of line
JNZ INTER4 ;if no: input error
CALL LDHEXF ;read Intel-HEX file
JMP INTERP ;read a new command
INTER3: CJNE A,#'G',INTER4 ;GOTO ?
CALL EIN16 ;then read start address
JZ INTER5 ;continue if o.k.
INTER4: MOV R7,#ILLEGAL_COMMAND ;output error message otherwise
CALL ERROUT ;ausgeben
JMP INTERP ;and wait for a new command
INTER5: MOV DPL,R5 ;load GOTO address into DPTR
MOV DPH,R4 ;and return
RET
NIXMER: ;checks, whether there are only trailing blanks in
;the command line buffer starting from position R0.
;When this is the case, zero is returned in A, the next
;non-blank character otherwise with its position in R0.
MOV A,@R0 ;load next character
JZ NIXME1 ;if 0, end of line
CJNE A,#' ',NIXME1
INC R0 ;if blank, next character
JMP NIXMER
NIXME1: RET
RDCOMM: ;reads a command from the UART and stores it in the
;command line buffer at address CMDLIN in the internal
;RAM. The command line is terminated with a 0.
CALL NEWLIN ;new line
MOV A,#CPROMPT ;output prompt
CALL CONOUT
MOV R0,#CMDLIN ;address of command line buffer
RDCOM1: MOV @R0,#0 ;always terminate buffer with a 0
CALL CONIN ;read character
CJNE A,#CR,RDCOM2 ;if a CR has been input,
RET ;the command is complete
RDCOM2: CJNE A,#BS,RDCOM5 ;backspace ?
RDCOM3: CJNE R0,#CMDLIN,RDCOM4 ;buffer empty ?
JMP RDCOM1 ;then continue reading characters
RDCOM4: MOV DPTR,#BACKSP ;otherwise delete last character
CALL STRING
DEC R0
JMP RDCOM1
RDCOM5: CJNE A,#DEL,RDCOM6 ;delete ?
JMP RDCOM3 ;then delete last character, too
RDCOM6: MOV R2,A ;save character
CLR C ;is it a control character ?
SUBB A,#' '
JC RDCOM1 ;then better ignore it
MOV A,R2
SUBB A,#DEL ;is character >= 7F ?
JNC RDCOM1 ;then ignore it too
CJNE R0,#CMDMAX,RDCOM7 ;is buffer full ?
MOV A,#BEL ;then beep
CALL CONOUT
JMP RDCOM1 ;and wait for further characters
RDCOM7: MOV A,R2 ;echo character
CALL CONOUT
MOV A,R2 ;and append character to buffer
MOV @R0,A
INC R0 ;now its one more character
JMP RDCOM1 ;wait for input characters
BACKSP: DB BS,' ',BS,0 ;string to delete a character
LDHEXF: ;reads an Intel-Hex file from the UART and loads it
;to its start address in the external RAM.
;When something has gone wrong, LDHEXF continues
;reading characters until it has received nothing
;for about 5 seconds (depending on clock frequency),
;and sends a corresponding error message.
MOV A,#UPROMPT ;output upload prompt
CALL CONOUT
CALL UPLOAD ;load Intel-Hex file into external RAM
MOV R7,A ;save error code
JZ LDHEXM ;if no error, continue
LDHEX1: MOV R0,#HIGH(TIMEBASE) ;otherwise wait for some seconds,
MOV R1,#LOW(TIMEBASE) ;until no more characters are received
MOV R2,#0
LDHEX2: CALL CONIST ;character received ?
JZ LDHEX3 ;if not, continue
CALL CONIN ;otherwise read character,
JMP LDHEX1 ;and start from the beginning
LDHEX3: NOP
DJNZ R2,LDHEX2
DJNZ R1,LDHEX2
DJNZ R0,LDHEX2
LDHEXM: MOV A,R7 ;error code
JZ LDHEX4 ;if no error, continue
CALL ERRONL ;error message otherwise (code in R7)
LDHEX4: RET
ERRONL: ;outputs a new line and error message number R7.
MOV DPTR,#ERRSTN
SJMP ERROU1
ERROUT: ;outputs an error message with its number in R7.
MOV DPTR,#ERRSTL
ERROU1: CALL STRING
MOV DPTR,#ERRTAB ;address of table of error messages
MOV A,R7 ;error code
RL A ;calculate address of error message
MOVC A,@A+DPTR
XCH A,R7
RL A
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,R7
CALL STRING ;output message
MOV DPTR,#ERRSTR
CALL STRING
RET
;error codes:
ILLEGAL_COMMAND EQU 0
ILLEGAL_HEXDIGIT EQU 1
CHECKSUM_ERROR EQU 2
UNEXPECTED_CHAR EQU 3
ILLEGAL_RECORDID EQU 4
ERRTAB: ;Table of error messages
DW ILLCOM
DW ILLHEX
DW CKSERR
DW UNXCHR
DW ILLRID
;error messages:
ILLCOM: DB 'illegal command',0
ILLHEX: DB 'illegal hex digit',0
CKSERR: DB 'checksum error',0
UNXCHR: DB 'unexpected character',0
ILLRID: DB 'illegal record ID',0
ERRSTN: DB CR,LF
ERRSTL: DB '@@@@@ ',0
ERRSTR: DB ' @@@@@',0
UPLOAD: ;reads an Intel-Hex file from the UART and loads
;it to its start address in the external RAM.
;UPLOAD returns the following error codes in A:
;
; A = 0 hex file loaded correctly
; A = ILLEGAL_HEXDIGIT illegal hex digit
; A = CHECKSUM_ERROR checksum error
; A = UNEXPECTED_CHAR unexpected character
; A = ILLEGAL_RECORDID illegal record ID
;
;UPLOAD only changes registers A,B,DPTR,R0,R1,R2, and R7.
CALL CONIN ;read characters
CJNE A,#':',UPLOAD ;until a ":" is received
UPLOA0: MOV R1,#0 ;initialize checksum
CALL NEXTB ;convert next two characters to a byte
JC UPLOA4 ;if they are no hex digits, error
MOV R0,A ;save number of data bytes
CALL NEXTB ;record address, HI byte
JC UPLOA4 ;if no hex digits: error
MOV DPH,A ;save HI byte
CALL NEXTB ;record address, LO byte
JC UPLOA4 ;if no hex digits: error
MOV DPL,A ;save LO byte
CALL NEXTB ;record ID
JC UPLOA4 ;if no hex digits: error
MOV R2,A ;save record ID
MOV A,R0 ;number of data bytes
JZ UPLOA2 ;if 0, probably EOF record
UPLOA1: CALL NEXTB ;next data byte
JC UPLOA4 ;if no hex digits: error
MOVX @DPTR,A ;load it into external RAM
INC DPTR ;next byte
DJNZ R0,UPLOA1 ;until all data bytes are loaded
UPLOA2: CALL NEXTB ;checksum
JC UPLOA4 ;if no hex digits: error
MOV A,R1 ;checksum = 0 ?
JNZ UPLOA5 ;if no, checksum error
MOV A,R2 ;record ID
JNZ UPLOA3 ;if <> 0, probably EOF record
CALL CONIN ;read character
CJNE A,#CR,UPLOAU ;if no CR, may be UNIX style ASCII file
CALL CONIN ;read next character
CJNE A,#LF,UPLOA9 ;if no LF, may be ASCII upload with LF stripped
UPLOA8: CALL CONIN ;read next character
UPLOA9: CJNE A,#':',UPLOA6 ;if no ":", unexpected character
JMP UPLOA0 ;read next HEX record
UPLOAU: CJNE A,#LF,UPLOA6 ;if no LF, unexpected character
JMP UPLOA8
UPLOA3: CJNE A,#1,UPLOA7 ;if <> 1, illegal record ID
CALL CONIN ;read only final CR (RDCOMM ignores LF)
CLR A ;hex file loaded, o.k.
RET
UPLOA4: MOV A,#ILLEGAL_HEXDIGIT ;illegal hex digit
RET
UPLOA5: MOV A,#CHECKSUM_ERROR ;checksum error
RET
UPLOA6: MOV A,#UNEXPECTED_CHAR ;unexpected character
RET
UPLOA7: MOV A,#ILLEGAL_RECORDID ;illegal record ID
RET
NEXTB: ;reads one byte in ASCII-hex representation from
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -