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