where : ibrtses delphi
Delphi - Intel Hex
disclaimer
the source code of this page may not appear correctly in certain browsers
due to special characters. Have a look at the source of this HTML page
with notepad instead
format
Intel Hex is a common format to store binaries to be loaded into EPROM for
CPU's. It is a readable textformat that is line oriented. A line is built as
':', rec len, address, rec type, [data], checksum
whereas :
':' is start of record = 0x3A
reclen is the number of databytes as 2 digit hex
address is 4 digit hex, where the data starts
rec type is '00' for normal data, '01' end of file, '02' extended adress
[data] is a data packet encoded as hex
checksum is the 2's complement of the sum over the record excl the ':' modulo 256 as hex
eg :
:1005AA00000102030405060708090A0B0C0D0E0F88
rec len = 0x10 = 16
address = 0x05AA
data = 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
checksum = 0x88 = 256 -sum(0x00+..+0x0F)= 256- 0x78
reading a line
it assumes a buffer big enough to store the data :
type mybuf=array[0..??]of byte;
var Buf:mybuf;
function readline(s:string; var Buf:mybuf):integer; // returns error code 0=ok
var ladr:integer;
csum,ndb,rtyp,data:byte;
t:shortstring;
begin
if s[1]=':' then begin
t:='$'+copy(s,2,2); // get length
ndb:=strtoint(t);
{$R-}csum:=csum+rl;{$R+}
t:='$'+copy(ss,4,4); // get address
ladr:=strtoint(t);
{$R-}csum:=csum+lo(ladr)+hi(ladr);{$R+}
t:='$'+copy(ss,8,2);
rtyp:=strtoint(t);
{$R-}csum:=csum+rtyp;{$R+}
case rtyp of
0:begin // datablock
bcount:=0;
while (bcount < ndb) do begin
t:='$'+copy(ss,10+2*bcount,2);
data:=strtoint(t);
{$R-}csum:=csum+data;{$R+}
Buf[ladr+bcount]:=data;
inc(bcount);
end;
t:='$'+copy(ss,10+2*bcount,2);
css:=strtoint(t);
end;
1:begin // end of file
t:='$'+copy(ss,10,2);
css:=strtoint(t);
result:=1;
end;
2:begin // extended segment address
...
end;
3:begin // start address record
...
end;
4:begin
...
end;
5:begin
...
end;
else result = -2; // no valid record
end; //case
// test checksum
{$R-}data:=css+csum;{$R+}
if (data<>0) then result:=-2; // checksum error
end
else result:=-0; // no record
end;
Writing a line
function writeline(adr,len:integer; var buf:mybuf):shortstring;
var i:integer;
csum:byte;
begin
csum:=0;
result:=':'+inttohex(len,2)+inttohex(adr,4);
{$R-} csum:=len+lo(adr)+hi(adr);{$R+}
for i:=0 to len-1 do begin
result:=result+inttohex(buf[adr+i],2);
{$R-}csum:=csum+buf[adr+i];{$R+}
end;
result:=result+inttohex(-csum,2);
end;
function write_eof(startadr:integer):shortstring;
var csum:byte;
begin
result:=':00'+inttohex(startadr,4)+'01';
csum:=hi(startadr)+lo(startadr)+1;
result:=inttohex(-csum,2);
end;
Use
use them as :
reading
memo1.lines.loadfromfile('myhex_file.hex');
i:=0;
res:=0;
stop:=false;
while (i <= memo1.lines.count-1)and(not stop) do begin
res:=readline(memo1.line[i],buf);
stop:=(res=1); // stop on end of file
end;
writing
memo1.clear;
adr:=0;
for i:=0 to ((usedbuf-1) div 16) do begin
memo1.lines.add(writeline(adr,16,mybuf));
adr:=adr+16;
end;
if (usedbuf>adr) then
memo1.lines.add(writeline(adr,(usedbuf mod 16),mybuf));
memo1.lines.add(write_eof(0));
notes
There are extended formats, and there is the chance that the EPROM
is not located at 0x0000, but at 0xF0000 or similar. A further
search on the web may reveal enhancements or solutions to other
problems.
Feedback is welcome
sponsored links
Delphi
home
last updated: 4.jan.00
Copyright (99,2000) Ing.Büro R.Tschaggelar