4 # Real script begins here; the above ugliness should locate
7 # Quick & dirty perl hack to pack an Intel Hex format output file.
8 # Will consolidate lines up to $outChunk bytes per line.
12 # 16 bytes per line is default.
17 $pendingDataStart = 0;
18 $pendingDataCount = 0;
19 $lastExtendedOffset = 0;
23 if (/:([\dABCDEFabcdef]{2})([\dABCDEFabcdef]{4})(\d\d)(.*)([\dABCDEFabcdef]{2})/)
25 # $1 = record len; $2 = offset; $3 = record type; $4 = data; $5 = checksum.
27 $recordOffset = hex $2;
30 if ((length $4) % 2 == 1)
32 print STDERR "packihx: odd data length $4 in line $.\n";
35 if ((length $4) / 2 != $recordLen)
37 print STDERR "packihx: data len mismatch in line $.: $1 != len $4\n";
40 if (checksum("$1$2$3$4") != hex $5)
42 print STDERR "packihx: bad checksum in line $.: ";
43 printf STDERR "wanted %02X, got %s\n", checksum("$1$2$3$4"), $5;
49 # If this is an extended data offset record, and it
50 # matches the expected extended data offset, then
51 # we can simply discard it.
52 if (($3 == 4) && ($recordLen == 2))
54 my $extendedOffset = hex $4;
55 if ($extendedOffset == $lastExtendedOffset)
59 $lastExtendedOffset = $extendedOffset;
61 # Not a data record. Flush anything pending, then write this
64 $pendingDataStart = 0;
70 # If this isn't contigous with the last record,
71 # flush anything pending and start collecting anew.
72 if ($recordOffset != $nextOffset)
75 $pendingDataStart = $recordOffset;
76 $nextOffset = $pendingDataStart;
79 # Append this data onto the pending data.
81 $pendingDataCount += $recordLen;
82 $nextOffset += $recordLen;
84 # If we'va accumulated at least an outChunk
85 # worth of data, write it out.
86 while ($pendingDataCount >= $outChunk)
88 &write_pending_line($outChunk);
94 print STDERR "packihx: don't recognize line $.: $_";
102 # Write all buffered data.
103 sub flush_pending_data
105 while ($pendingDataCount > $outChunk)
107 &write_pending_line($outChunk);
109 if ($pendingDataCount)
111 &write_pending_line($pendingDataCount);
115 # Write a given number of bytes of buffered output.
116 sub write_pending_line
118 my $lineLen = shift(@_);
120 if ($lineLen > $pendingDataCount)
122 print STDERR "packihx: internal error: asked to write $lineLen bytes ";
123 print STDERR "with only $pendingDataCount bytes buffered.\n";
127 my $data = substr $pendingData, 0, $lineLen * 2;
128 my $toWrite = sprintf "%02X%04X00%s", $lineLen, $pendingDataStart, $data;
130 my $cks = checksum($toWrite);
132 printf ":%s%02X\n", $toWrite, $cks;
134 $pendingDataStart += $lineLen;
135 $pendingDataCount -= $lineLen;
136 $pendingData = substr $pendingData, $lineLen * 2;
139 # Generate a IHX checksum.
142 my $line = shift(@_);
146 while ($offset < length $line)
148 my $byte = substr $line, $offset, 2;
153 if ($offset != length $line)
155 print STDERR "packihx: checksum: got odd number of bytes... I hate that";