<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Fri, 24 Feb 1989 21:25:03 GMT
From   : osu-cis!n8emr!uncle!oink!jep@tut.cis.ohio-state.edu (James E. Prior)
Subject: Intel hex (*.HEX) format questions

In article <1796@uop.edu> mrapple@uop.edu (Nick Sayer) writes:
<Anyone have some cold, hard facts concerning the Intel .HEX format?

More particularly, he asked about the "always zero" field, the use of
the :0000000000 record, and how checksums are calculated.

The :0000000000 record is peculiar to CP/M and isn't rigorous Intel Hex.  
Intel Hex stuff is commonly ended with a :00000001FF record.  Note the
exception to being "always zero".  The eighth and ninth characters of a
record specify the record type.  Type 1 means either end of hex, or
starting address.  There are some Intel programs that generate a non-zero
address for the last record, because they actually start execution 
somewhere.  Usually, hex files are just used for burning EPROMs, so the
starting address is irrelevant (hence 0).

<What happens when the address in the last line (with 0 length)
<is non-zero? Does that mean that the entry point is at the noted
<address or something?

Yup, it's the address to start execution at.  Strictly speaking, this 
should be 0100 for CP/M stuff.   The CP/M way of botching this record
makes concatenation of several hex files easier.

<What is the algorithm for computing the checksum? 

If you add up the value of ALL the bytes on the line, the least significant
byte should be zero.  I include some code fragments from a program that
reads intel hex files.  This isn't vaporous code, it is pulled from a real
working, tested program.  

/*****************************************************************************/

unsigned char input_checksum;

unsigned char get_byte()
{
   int c;
   unsigned char sum=0L;
   int n=2;

   while (n-->0) {
      if ((c=getchar())>='0' && c<='9')
         sum=0x10*sum+c-'0'+0x0;
      else if (c>='a' && c<='f')
         sum=0x10*sum+c-'a'+0xa;
      else if (c>='A' && c<='F')
         sum=0x10*sum+c-'A'+0xA;
      else if (c==EOF) {
         fprintf(stderr,"ERROR: Encountered EOF when expecting hexadecimal
digits in line #%d\n",line_number);
         exit(1);
      }
      else {
         fprintf(stderr,"ERROR: Encountered character '%c' when expecting
hexadecimal digits in line #%d\n",c,line_number);
         exit(1);
      }
   }

   input_checksum+=sum;

   return sum;
}

/******************************************************************************/

      if ((c=getchar())!=':') {
         if (c==EOF) {
            fprintf(stderr,"WARNING: Missing end record for input\n");
            fprintf(stderr,"Coping as best can\n");
            clean_up();
            exit(1);
         }
         else {
            fprintf(stderr,"ERROR: Encountered line (#%d) beginning with
character other than colon\n",line_number);
            exit(1);
         }
      }      

      input_checksum=0;

      data_length=get_byte();

      high_load_address=get_byte();
      low_load_address=get_byte();
      load_address=(high_load_address<<8) + low_load_address;

      record_type=get_byte();

      for (i=0;i<data_length;i++)
         input_buf[i]=get_byte();

      if (get_byte() , input_checksum!=0) {
         fprintf(stderr,"ERROR: Bad checksum in line #%d\n",line_number);
         exit(1);
      }

/******************************************************************************/

<Nick Sayer | mrapple@uop.edu | Packet Radio: N6QQQ @ WB6V-2

<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>