#!/usr/bin/perl -w # See http://www.precma.it/download/intelhex.pdf # # Written by Ian Jackson in November/December 2005. # I hereby waive my copyright in this file. - Ian Jackson 16.12.2005. # $Id$ use strict qw(refs vars); our ($lba,$sba,$loc,$eof,%once); $lba=$sba=0; sub once { my ($r) = @_; my ($o); $o= \$once{$_[0]}; if (!defined $$o) { $$o= $loc; return; } die sprintf("%s: %s: clash at 0x%x (1st)\n". "%s: %s: clash at 0x%x (2nd)\n", $0, $$o, $r, $0, $loc, $r); } sub bad ($) { my ($m)=@_; die "$0: $loc: $m\n"; } my ($drlo,$dri,$orgline,$la); while (<>) { $orgline= $_; $loc= "$ARGV:$."; chomp; # General Record Format, p5 s/^\:// or bad('no colon'); $_= lc $_; m/[^0-9a-f]/ and bad("bad char ".ord($&)); length() & 1 and bad('odd length'); s/..$//; # chop checksum (we don't check this) s/^..//; # chop reclen (we don't check this) if (s/^000001//) { # End of File, p11 $eof= $orgline; if ($lba) { $orgline= ":020000040000FA\n"; $lba=0; } elsif ($sba) { $orgline= ":020000020000FC\n"; $sba=0; } else { next; } } elsif (s/^000004(....)$//) { $lba= hex($1)<<16; } # Ext'd Linear Addr, p6 elsif (s/^000002(....)$//) { $sba= hex($1)<<4; } # Ext'd Seg. Addr., p7 elsif (s/^(....)00//) { # Data Record, p8 $drlo= hex $1; for ($dri=0; s/^..//; $dri++) { bad('both LBA and SBA') if $lba && $sba; if ($lba) { $la= ($lba+$drlo+$dri) & 0x0ffffffff; } elsif ($sba) { $la= $sba + (($drlo+$dri) & 0xffff); } else { $la= $drlo+$dri; } #print STDERR ">$lba|$sba|$drlo|$dri|$la|$_<\n"; once($la); } } elsif (s/^000005//) { once('start'); } # Start Linear Address, p9 elsif (s/^000003//) { once('start'); } # Start Segment Address, p10 else { bad('unknown record or bad record'); } print $orgline or die $!; } our ($lx,$ld); $lx= 0; $ld= ''; sub pf { my ($f) = shift @_; my ($s) = sprintf $f, @_; if ($s =~ m/^\s/ && length($ld.$s) > 70) { print STDERR $ld,"\n" or die $!; $ld= " "; } $ld.= $s; } sub pf_end () { print STDERR $ld,"\n" or die $!; } my ($ca,$a1); undef $la; foreach $ca (sort { $a <=> $b } keys %once) { next if defined($la) && $ca == ++$la; defined($la) and --$la != $a1 and pf("-%x", $la); pf(" %x", $ca); $la=$a1=$ca; } if (!defined($la)) { pf(" empty"); } elsif ($la != $a1) { pf("-%x", $la); } pf_end(); die "$0: no input files or missing EOF markers\n" unless defined $eof; print $eof or die $!;