home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE IHEX.ASM
- ;
- COMMENT *
- Created: 16-SEP-1988 Richard B. Johnson
- Purpose: Converts the contents of any file to an output
- string consisting of Intel Hexadecimal records. This is the format
- required by many PROM "burners". It also is a way to transfer a
- binary file to a remote computer when all that is available is
- "ASCII capture".
-
- The received data, once "cleaned up" using a word-processor to
- remove any extra characters at the beginning and end, may be changed
- back to binary using MS-DOS's DEBUG.
-
- Example:
- C:\> debug { Execute debug }
- - ntempfile.hex { Name the Intel-hex file.}
- - l { Load the file }
- - nnewfile.com { Name the output file }
- - w { Write output file contents }
- - q { Quit DEBUG }
-
- C:\> { Back to DOS }
-
- Usage:
- IHEX filename.typ (Output to screen)
- IHEX filename.typ> Outfile.typ (Output to a file)
- IHEX filename.typ> COM1: (Output to a modem)
-
- Revision history:
- *
- ;
- CR EQU 0AH
- LF EQU 0DH
- MS_DOS EQU 21H
- QUIT EQU 4C00H
- ;
- VERS STRUC
- DB 'V1.00'
- @VERS DB ' '
- VERS ENDS
- ;
- LINE1 STRUC
- DB 'PROGRAM EXCHANGE'
- @LEN1 DB ' '
- LINE1 ENDS
- ;
- LINE2 STRUC
- DB 'Intel Hex Converter '
- @LEN2 DB ' '
- LINE2 ENDS
- ;
- LINE3 STRUC
- DB 'Created 16-SEP-1988 Richard B. Johnson'
- @LEN3 DB ' '
- LINE3 ENDS
- ;
- PSEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:PSEG
- ORG 100H
- MAIN PROC NEAR
- MOV WORD PTR [CONS],2 ; Use STD error (no redirection)
- ;
- MOV DX,OFFSET PRP0 ; Pick up the logo
- CALL PROMPT ; Print to screen
- MOV SI,80H ; Where command line should be
- LODSB ; Get characters typed
- OR AL,AL
- JNZ PARSE0 ; Something was typed
- ERROR: MOV DX,OFFSET PRP4 ; Point to 'usage' prompt
- CALL PROMPT ; Print to screen
- JMP FINIS ; Exit
-
- PARSE0: CBW
- MOV CX,AX ; Character count
- PARSE1: LODSB ; Get byte
- CMP AL,' '
- JBE PARSE2
- JMP SHORT PARSE3
- PARSE2: LOOP PARSE1 ; Clear any spaces/tabs, etc
- PARSE3: JCXZ ERROR ; Ran out of characters
- DEC SI
- MOV DI,OFFSET FNAME ; Point to the filename
- REP MOVSB ; Move command line there
- MOV BYTE PTR [DI],0 ; Change CR to null
- MOV DX,OFFSET PRP1 ; Point to 'file'
- CALL PROMPT ; Print to screen
- MOV DX,OFFSET FNAME ; Point to the file name
- CALL PROMPT ; Print to screen
-
- MOV AX,WORD PTR [LOAD] ; Pick up load address
- MOV WORD PTR [ADDR],AX ; Load address of file
- CALL OPEN ; Open the file
- JNC PARSE4 ; Success
- MOV DX,OFFSET PRP3 ; Error, point to 'not found'
- CALL PROMPT ; Print to screen
- JMP FINIS ; Exit
- PARSE4: MOV DX,OFFSET PRP2 ; Point to 'has been opened'
- CALL PROMPT ; Print to screen
- MOV AH,1 ; Wait for console input
- INT MS_DOS
- MOV DX,OFFSET CRLF ; Next line.
- CALL PROMPT
- MOV WORD PTR [CONS],1 ; Change to STD output
- ;
- CONT: MOV SI,OFFSET BUFFER ; Where file data was put
- MOV DI,OFFSET SCR_BUF ; Output buffer
- CALL READ ; Read the file
- JZ DONE ; No bytes, end of the file
- PAGE0: SUB WORD PTR [BYTES],32 ; Number of bytes to convert
- JNC PAGE1 ; Not at end of read yet
- MOV AX,WORD PTR [BYTES] ; Get byte count
- ADD AX,32 ; Add back
- MOV BYTE PTR [LEN],AL ; Update the length
- CALL IHEX ; Finish string
- ;
- DONE: CALL EOF ; End of Intel hex record
- CALL CONOUT ; Output to screen
- CALL CLOSE ; Close the file
- JMP FINIS ; Exit
- ;
- PAGE1: CALL IHEX ; Convert line of Intel Hex
- CMP WORD PTR [BYTES],0 ; All bytes converted?
- JNZ PAGE0 ; No, Convert more
- CALL CONOUT ; Print results
- JMP SHORT CONT
- MAIN ENDP
- ;
- FINIS PROC NEAR
- MOV AX,QUIT
- INT MS_DOS
- FINIS ENDP
- ;
- ; Convert [LEN] bytes addressed by [SI] to Intel-Hex in [DI].
- ; Conversion address is in [ADDR]
- ;
- IHEX PROC NEAR
- MOV AL,':' ; Start with a colon
- STOSB ; Into buffer
- MOV AL,BYTE PTR [LEN] ; Get length of the string
- XOR BX,BX ; Zero checksup
- ADD BL,AL ; Checksum
- PUSH AX ; Save length
- CALL HEXB ; Convert to hex
- POP AX ; Restore length
- XOR AH,AH ; Zero high byte
- MOV CX,AX ; Use for a count
- MOV AX,WORD PTR [ADDR] ; Pick up the address
- ADD BL,AH ; Checksum
- ADD BL,AL
- CALL HEXW ; Convert to HEX
- MOV AL,0 ; Record type
- CALL HEXB
- IHEX0: LODSB ; Get byte
- ADD BL,AL ; Checksum
- CALL HEXB ; Convert to hex
- LOOP IHEX0 ; Continue for all bytes
- MOV AL,BL ; Get checksum
- NOT AL ; Twos compliment
- INC AL ; I don't know, its the rule
- CALL HEXB ; Convert to hex
- MOV AX,0A0DH ; CR/LF backwards
- STOSW
- MOV AL,BYTE PTR [LEN] ; Pick up length
- XOR AH,AH ; Zero high byte
- ADD WORD PTR [ADDR],AX ; Update the address
- RET
- IHEX ENDP
- ;
- ; Create Intel-hex end-of-file string.
- ;
- EOF PROC NEAR
- MOV BL,0 ; Checksum
- MOV AL,':'
- STOSB
- MOV AL,0 ; Zero length record
- CALL HEXB
- MOV AX,WORD PTR [LOAD] ; Get load address
- ADD BL,AH ; Checksum
- ADD BL,AL ; Checksum
- CALL HEXW ; Convert the word
- MOV AL,1 ; End of file record
- ADD BL,AL ; Checksum
- CALL HEXB ; Convert the byte
- MOV AL,BL ; Get checksum
- NOT AL
- INC AL
- CALL HEXB ; Put in checksum
- MOV AX,0A0DH ; CR/LF backwards
- STOSW
- MOV AL,'Z'-64 ; Control-Z
- STOSB
- RET
- EOF ENDP
- ;
- ; Write string in [SCR_BUF] to the output device. [DI] points one-
- ; byte past the last byte in the buffer.
- ;
- CONOUT PROC NEAR
- MOV DX,OFFSET SCR_BUF ; Screen buffer
- MOV CX,DI ; Last byte used
- SUB CX,DX ; First byte location
- MOV BX,1 ; Handle for console
- MOV AH,40H ; Write to file/device
- INT MS_DOS
- RET
- CONOUT ENDP
- ;
- ; Convert Word in AX to ASCII hex string indexed by DI. AX is destroyed.
- ;
- HEXW PROC NEAR ;CONVERT HEX WORD IN AX TO ASCII
- PUSH AX ;SAVE WORD
- MOV AL,AH
- CALL HEXB ;DISPLAY HEX BYTE
- POP AX ;GET WORD BACK AND FALL THROUGH
- ;
- ; Convert byte in AL to ASCII hex in string indexed by DI. AX is destroyed.
- ;
- HEXB PROC NEAR
- MOV AH,AL ;SAVE BYTE
- SAR AL,1
- SAR AL,1
- SAR AL,1
- SAR AL,1
- CALL HEX1
- MOV AL,AH ;GET STARTING BYTE
- HEX1: AND AL,0FH ;SAVE ONLY LOW FOUR BITS
- ADD AL,90H ;ADD BIAS
- DAA ;OLD INTEL TRICK
- ADC AL,40H
- DAA
- STOSB
- RET
- HEXB ENDP
- HEXW ENDP
- ;
- ; Write string addressed by [DI] to the console until a NULL is en-
- ; countered. First find the null.
- ;
- PROMPT PROC NEAR
- MOV DI,DX ; Start of string
- MOV CX,MAX ; Not more than this
- XOR AL,AL ; Byte to look for
- REPNZ SCASB ; Look for the byte
- MOV CX,DI ; One past where it was
- SUB CX,DX ; First byte of string
- DEC CX ; Back past the null
- MOV BX,WORD PTR [CONS] ; Handle for console
- MOV AH,40H ; Write to file/device
- INT MS_DOS
- RET
- PROMPT ENDP
- ;
- OPEN PROC NEAR
- MOV AX,3D20H ; Open for read/deny nothing
- MOV DX,OFFSET FNAME ; File name
- INT MS_DOS
- MOV WORD PTR [HANDLE],AX ; Save file access word
- RET
- OPEN ENDP
- ;
- CLOSE PROC NEAR
- MOV AX,3E00H ; Close file
- MOV BX,WORD PTR [HANDLE] ; Get file handle
- INT MS_DOS
- RET
- CLOSE ENDP
- ;
- READ PROC NEAR
- MOV AX,3F00H ; Read from file
- MOV CX,512 ; Bytes to read
- MOV DX,OFFSET BUFFER ; Where to put the date
- MOV BX,WORD PTR [HANDLE] ; File access handle
- INT MS_DOS
- MOV WORD PTR [BYTES],AX ; Save bytes read.
- OR AX,AX ; Check for zero bytes read
- RET
- READ ENDP
- ;
- PRP0 DB CR,LF
- DB (80 - @LEN1) /2 DUP (' ')
- LINE1 <>
- DB CR,LF
- DB (80 - (@LEN2+@VERS)) /2 DUP (' ')
- LINE2 <>
- VERS <>
- DB CR,LF
- DB (80 - @LEN3) /2 DUP (' ')
- LINE3 <>
- DB CR,LF,0
- PRP1 DB CR,LF,'File ',0
- PRP2 DB ' has been opened.'
- DB CR,LF,'Hit [Enter] to start data flow: ',0
- PRP3 DB ' not found. Aborting.',0
- PRP4 DB CR,LF,'Usage:'
- DB CR,LF,'IHEX filename.typ (Output to screen)'
- DB CR,LF,'IHEX filename.typ> Outfile.typ (Output to a file) '
- DB CR,LF,'IHEX filename.typ> COM1: (Output to a modem)'
- CRLF DB CR,LF,0
- MAX EQU $ - PRP4 ; Longest string
- FNAME DB 64 DUP (0)
- HANDLE DW ? ; File handle.
- CONS DW 1 ; Console handle.
- LOAD DW 100H ; Normal load address
- ADDR DW ? ; Running address
- BYTES DW ? ; Bytes read.
- LEN DB 32 ; String length
- SCR_BUF LABEL BYTE ; Output buffer
- BUFFER EQU $ + 4192
- ;
- PSEG ENDS
- END MAIN
-