#!/usr/bin/perl

$REF = "standby.fpg";	# reference bitstream
$LEN = 0x78dd0;		# cut off trailing junk

open(FILE, $REF) || die "$REF: $!";
$ref = substr(join("", <FILE>), 0, $LEN);
close FILE;

die "reference bitstream is too short" unless length $ref == $LEN;

for (@ARGV) {
	open(FILE, $_) || die "$_: $!";
	$c{$_} = substr(join("", <FILE>), 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;
	}
	$i = 0;
	for $a (@a) {
		$i++;
		$s{$a} .= " | $_ $i/$n\n";
	}
}

for (sort { $a <=> $b } keys %s) {
	print $s{$_};
}
