[comp.os.cpm] Details of Intel Hex format

RALPH@UHHEPG.BITNET (09/25/87)

Date: 24-SEP-1987 22:47:39.34
From: Ralph Becker-Szendy RALPH AT UHHEPG
To:   BITNET::"info-cpm@simtel20.arpa",RALPH
Subj: Details of Intel Hex Format
Hi

i have a very stupid problem: for the first time in my life, i have to create
an Intel hex-file by hand (or rather by a program i wrote, and not by an
assembler or suchlike) to download it ionto an EPROM programmer.
Unfortunately, so far the EPROM programmer refused all my attempts, presumably
due to a format or checksum error in the hex file (it works fine otherwise);
it does beautifully work with other hex files.

Let my explain how one record in the hex-file i write looks like:
each byte is in hexadecimal, written as two (uppercase) ASCII characters.
- a colon ":"
- one byte # of data bytes, in my case "10"
- two bytes load adress, first high, then low byte
- one byte record type (always "00")
- 16 bytes of data
- one byte checksum.
- CR and LF
The checksum is calculated such that the sum of all bytes (including the
"10" and the two adress bytes) is a multiple of 256.

Is there anything wrong with this format ? If yes, what ??

Signed: confused

Ralph Becker-Szendy
University of Hawaii / High Energy Physics Group

UZ32112@BLIULG12.BITNET (Andre PIRARD) (09/29/87)

Here is an algorithm for Intel Hex files generation:

\ COMHEX: produce .HEX file out of .COM file

HEX

100 CONSTANT START \ input file starting address, 100 specific for CP/M & MSDOS
10 CONSTANT SLICE \ max number of bytes in one HEX line

VARIABLE CHECKSUM \ output record checksum
VARIABLE ADDRESS  \ running address

VARIABLE IFILE \ pointer to input file
VARIABLE OFILE \ pointer to output file

: ASK.FILENAME \ prompt-addr id-count pointer -- fname-addr fname-count fcba
   >R FCBSIZE RESERVE R@ !     \ get fcb storage, set pointer
   CR TYPE SPACE  QUERY "TOKEN \ issue prompt, input filename
   R> @ ;                      \ return filename and fcb address

: CLOSE.FILE \ pointer --
   @ CLOSE CLOSED?  FCBSIZE FREE ;

: PUT.CHAR \ char -- \ write one character to output file
   OFILE @ PUT ;

: PUT.BYTE \ byte -- \ write 2 hex digits, compute checksum
   DUP CHECKSUM -! 0 <# # # #> OFILE @ WRITE ;

: PUT.WORD \ word -- \ write 4 hex digits, compute checksum
   DUP -8 SHIFT PUT.BYTE   FF AND PUT.BYTE ;

: COMHEX \ main word
   HEX \ all stuff done in hexadecimal
   " INPUT FILE?:"  IFILE ASK.FILENAME OPENI OPEN? \ open input
   " OUTPUT FILE?:" OFILE ASK.FILENAME OPENO OPEN? \ and output
   CR
   START ADDRESS !            \ init address pointer
   BEGIN IFILE @ INDATA WHILE \ loop until at end-of-file
      ASCII : PUT.CHAR        \ record mark
      CHECKSUM OFF            \ new checksum for new record
      PAD SLICE IFILE @ READ  \ read up to SLICE bytes
      DUP PUT.BYTE            \ output byte count
      ADDRESS @ PUT.WORD      \ output bytes address
      0 PUT.BYTE              \ plus one more byte
      DUP ADDRESS +!          \ progress address
      PAD SWAP BOUNDS ?DO     \ loop for each byte read
         I C@ PUT.BYTE LOOP   \ and output it with checksum
      CHECKSUM @ PUT.BYTE     \ output checksum
      OFILE @ PUTEOR          \ put end-of-record mark
   REPEAT
   ASCII : PUT.CHAR  0 PUT.WORD \ add end-of-file record
    0 PUT.WORD  0 PUT.BYTE  OFILE @ PUTEOR
   OFILE @ PUTEOF             \ put end-of-file mark
   OFILE CLOSE.FILE
   IFILE CLOSE.FILE ;

DECIMAL