; File: HEXLOAD.A51 Date: 01/20/94 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1994. */ ; /* All rights reserved. */ $ DATE(01-20-94) PW(105) PL(60) $ XREF CR EQU 0DH ; ASCII CODE FOR . LF EQU 0AH ; " " " . ; NOTE: The following registers are modified in this subroutine: ; ACC, P2, PCON, and R0, R1, & R2 of Register Bank 3. ; After the entire file is loaded, 'ERR' will be echoed if any errors ; were detected. PCON.3 will be set if an invalid character was ; received, and PCON.2 will be set if a checksum error was detected. ; ------------------------ READ HEX RECORD ---------------------------- ORG 7F00H PUSH PSW ORL PSW,#00011000B ; Select RB3 ANL PCON,#11110000B ; Clear flag bits SJMP GetHex ; Wait for either ':' (Start), ; CR, or LF. Ck_CR: CJNE A,#CR,Ck_LF ; Any other chars will set the SJMP WAIT ; error flag. Ck_LF: CJNE A,#LF,Ck_C SJMP WAIT Ck_C: CJNE A,#3,CharErr ; Check for SJMP OK CharErr:ORL PCON,#8 ; Set error flag CALL C_OUT SJMP WAIT GetHex: JNB TI,$ CLR TI MOV SBUF,#'>' ; Output pace character WAIT: CALL GetChar ; Wait to receive a character CJNE A,#':',Ck_CR ; Wait for start character ? CALL C_OUT SETB F0 ; --------- THE MAIN ENTRY POINT -------- MOV R2,#0 ; Start checksum CALL RdByte ; 1) Get record length MOV R0,A ; Save length CALL RdByte ; 2) Get high address MOV P2,A CALL RdByte ; 3) Get low address MOV R1,A CALL RdByte ; 4) Get record type JZ GetDat ; 0 if data, 1 if last record CLR F0 ; Clear flag GetDat: MOV A,R0 ; Check record length JZ IsEnd DataIn: CALL RdByte ; 5) Get a byte JNB F0,NoStor ; Store if data record WriteX: MOVX @R1,A ; Write the byte. INC R1 CJNE R1,#0,NoStor INC P2 ; Point to next byte NoStor: DJNZ R0,DataIn ; Get more bytes DEC R0 ; R0 = FF IsEnd: CALL RdByte ; Get checksum byte MOV A,R2 JZ ChkOK ORL PCON,#4 ChkOK: MOV A,#CR CALL C_OUT MOV A,R0 ; Will be FF for data record JNZ GetHex ; Read another record? MOV A,#0CH ; Now check for any errors ANL A,PCON JZ OK MOV A,#'E' CALL C_OUT MOV A,#'R' CALL C_OUT2 MOV A,#CR CALL C_OUT OK: POP PSW RET ; All done so return to BASIC GetChar:JNB RI,$ ; Character in SBUF ? MOV A,SBUF CLR RI CLR ACC.7 ; Clear parity bit RET RdByte: SETB PSW.1 ; Get 2 chars & make a 2 digit byte DoAgin: MOV R3,A CALL GetChar ; Get a single character CALL C_OUT ; Echo it CLR C SUBB A,#'0' JNC Do_1 ; Not a digit ? (<30H ?) ORL PCON,#8 ; Set error flag CLR F0 ; DO NOT store this record Do_1: SUBB A,#10 ; Test for A-F JC IsNmbr SUBB A,#7 ; Adjust for gap IsNmbr: ADD A,#10 ; Restore ANL A,#0FH JBC PSW.1,DoAgin ; 2nd time ? SWAP A ORL A,R3 SWAP A ; 2 digits in ACC XCH A,R2 ; Get Checksum ADD A,R2 ; Update it and XCH A,R2 ; get byte back. RET C_OUT2: CALL C_OUT ; Send the character twice. C_OUT: JNB TI,$ ; Wait til last character gone. CLR TI ; Clear interrupt flag. MOV SBUF,A ; Write out character. CJNE A,#CR,CONT ; If it was then follow with . JNB TI,$ CLR TI MOV SBUF,#LF ; Output linefeed. CONT: RET END ; Following is the HEX file derived from the assembled source ; file. This can be used for directly loading the program via ; MONITOR-51 and almost any terminal program. :107F0000C0D043D0185387F08017B40D02801AB444 :107F10000A028015B40302806A438708127FB98081 :107F2000083099FDC29975993E127F86B43ADB12EA :107F30007FB9D2D57A00127F90F8127F90F5A01207 :107F40007F90F9127F906002C2D5E86010127F9096 :107F500030D507F309B9000205A0D8F118127F90B7 :107F6000EA6003438704740D127FB9E870B3740CA0 :107F70005587600F7445127FB97452127FB6740D25 :107F8000127FB9D0D0223098FDE599C298C2E7227D :107F9000D2D1FBF186127FB9C394305005438708D4 :107FA000C2D5940A40029407240A540F10D1E3C4A6 :107FB0004BC4CA2ACA22127FB93099FDC299F599D9 :0C7FC000B40D083099FDC29975990A2291 :00000001FF