#!/usr/bin/perl $REF = "standby.fpg"; # reference bitstream $LEN = 0x78dd0; # cut off trailing junk open(FILE, $REF) || die "$REF: $!"; $ref = substr(join("", ), 0, $LEN); close FILE; die "reference bitstream is too short" unless length $ref == $LEN; for (@ARGV) { open(FILE, $_) || die "$_: $!"; $c{$_} = substr(join("", ), 0, $LEN); close FILE; die "$_ is too short" unless length $c{$_} == $LEN; } # @@@ not quite perfect - we should extract the cycle numbers and sort by them for (sort keys %c) { $n = 0; @a = (); for ($i = 0; $i != $LEN; $i += 2) { next unless substr($ref, $i, 2) ne substr($c{$_}, $i, 2); $r = unpack("B*", substr($ref, $i, 2)); $c = unpack("B*", substr($c{$_}, $i, 2)); if (defined $s{$i}) { $s = " " x 26; } else { $s = sprintf("%05x ", $i); for ($j = 19; $j >= 0; $j--) { $s .= $i & (1 << $j) ? "1" : "_"; } } $s .= " | "; for ($j = 0; $j != 16; $j++) { $s .= " " if $j == 8; $s .= substr($r, $j, 1) ? substr($c, $j, 1) ? "1" : "0" : substr($c, $j, 1) ? die : "_"; # substr($c, $j, 1) ? "\033[7m \033[m" : "_"; } if ($i >= 0x10) { # count only fatal corruptions push(@a, $i); $n++; } else { $s .= " | $_\n"; } $s{$i} .= $s; } for $a (@a) { $s{$a} .= " | $_ ($n)\n"; } } for (sort { $a <=> $b } keys %s) { print $s{$_}; }