1 #!/usr/local/bin/perl -w
3 # Quick & dirty perl hack to pack an Intel Hex format output file.
4 # Will consolidate lines up to $outChunk bytes per line.
8 # 16 bytes per line is default.
13 $pendingDataStart = 0;
14 $pendingDataCount = 0;
15 $lastExtendedOffset = 0;
19 if (/:([\dABCDEFabcdef]{2})([\dABCDEFabcdef]{4})(\d\d)(.*)([\dABCDEFabcdef]{2})/)
21 # $1 = record len; $2 = offset; $3 = record type; $4 = data; $5 = checksum.
23 $recordOffset = hex $2;
26 if ((length $4) % 2 == 1)
28 print STDERR "packihx: odd data length $4 in line $.\n";
31 if ((length $4) / 2 != $recordLen)
33 print STDERR "packihx: data len mismatch in line $.: $1 != len $4\n";
36 if (checksum("$1$2$3$4") != hex $5)
38 print STDERR "packihx: bad checksum in line $.: ";
39 printf STDERR "wanted %02X, got %s\n", checksum("$1$2$3$4"), $5;
45 # If this is an extended data offset record, and it
46 # matches the expected extended data offset, then
47 # we can simply discard it.
48 if (($3 == 4) && ($recordLen == 2))
50 my $extendedOffset = hex $4;
51 if ($extendedOffset == $lastExtendedOffset)
55 $lastExtendedOffset = $extendedOffset;
57 # Not a data record. Flush anything pending, then write this
60 $pendingDataStart = 0;
66 # If this isn't contigous with the last record,
67 # flush anything pending and start collecting anew.
68 if ($recordOffset != $nextOffset)
71 $pendingDataStart = $recordOffset;
72 $nextOffset = $pendingDataStart;
75 # Append this data onto the pending data.
77 $pendingDataCount += $recordLen;
78 $nextOffset += $recordLen;
80 # If we'va accumulated at least an outChunk
81 # worth of data, write it out.
82 while ($pendingDataCount >= $outChunk)
84 &write_pending_line($outChunk);
90 print STDERR "packihx: don't recognize line $.: $_";
98 # Write all buffered data.
99 sub flush_pending_data
101 while ($pendingDataCount > $outChunk)
103 &write_pending_line($outChunk);
105 if ($pendingDataCount)
107 &write_pending_line($pendingDataCount);
111 # Write a given number of bytes of buffered output.
112 sub write_pending_line
114 my $lineLen = shift(@_);
116 if ($lineLen > $pendingDataCount)
118 print STDERR "packihx: internal error: asked to write $lineLen bytes ";
119 print STDERR "with only $pendingDataCount bytes buffered.\n";
123 my $data = substr $pendingData, 0, $lineLen * 2;
124 my $toWrite = sprintf "%02X%04X00%s", $lineLen, $pendingDataStart, $data;
126 my $cks = checksum($toWrite);
128 printf ":%s%02X\n", $toWrite, $cks;
130 $pendingDataStart += $lineLen;
131 $pendingDataCount -= $lineLen;
132 $pendingData = substr $pendingData, $lineLen * 2;
135 # Generate a IHX checksum.
138 my $line = shift(@_);
142 while ($offset < length $line)
144 my $byte = substr $line, $offset, 2;
149 if ($offset != length $line)
151 print STDERR "packihx: checksum: got odd number of bytes... I hate that";