#!/usr/bin/perl
@rem = '
@echo off
c:\perl5\bin\perl %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
goto endofperl
@rem ' if @rem;

$max = 0;

#open(STDERR, ">log") || die "log: $!";
#
# Open the file in binary mode and read it in.
open(INPUT, $ARGV[0]) || die "$ARGV[0]: $!";
binmode(INPUT);
@core1 = (); $loc = $store = undef;
$sum = $add = $field = 0;
while (read(INPUT, $top, 1)) {
  $top = unpack("C", $top);
  next if $top == 0200;	# Leader or Trailer
  if (defined($store)) {
    $core1[$field*4096+$loc] = 0 unless defined $core1[$field*4096+$loc];
    $core1[$field*4096+$loc]++;
    $max = $field*4096+$loc unless $max > $field*4096+$loc;
    $store = undef;
    $loc = ($loc + 1) & 07777;
    $sum += $add;
    $fortran = 0;
  }
  if ($top & 0200) { # Better be field setting!
    die "$ARGV[0]: Invalid field setting" unless $top >= 0300;
    die "$ARGV[0]: Invalid field setting" if $top & 0007;
    $fortran = 1 if $top == 0340;
    $field = ($top & 070) >> 3;
    next;
  }
  if (defined($store)) {
    $core1[$field*4096+$loc] = 0 unless defined $core1[$field*4096+$loc];
    $core1[$field*4096+$loc]++;
    $max = $field*4096+$loc unless $max > $field*4096+$loc;
    $store = undef;
    $loc = ($loc + 1) & 07777;
    $sum += $add;
  }
  read(INPUT, $bot, 1) || die "$ARGV[0] read: $!";
  $bot = unpack("c", $bot);
  die "$ARGV[0]: ".$bot." not in bin format ". tell(INPUT) unless $bot <= 077;
  $word = ($top << 6) + $bot;
  $add = $top + $bot; # Update checksum
  if ($word > 07777) {
    #
    # Change location counter
    $loc = $word & 07777;
    $sum += $add;
  } else {
    die "$ARGV[0]: no location counter" unless defined($loc);
    $store = $word;
  }
}
close(INPUT);
if ($fortran) {
  warn "$ARGV[0]: 4K Fortran Binary\n" if $fortran;
  $sum += 0640; # 4K Fortran loader counts 0300 and 0340
}
$sum &= 07777;
warn "$ARGV[0]: Checksum is %04o, not %04o\n", $sum, $store if $sum != $store;
if ($fortran) {
  warn "$ARGV[0]: 4K Fortran Binary\n" if $fortran;
  $sum += 0640; # 4K Fortran loader counts 0300 and 0340
}

#
# Now print the map.
#
$status = 0;
print "Memory Map of $ARGV[0]\r\n";
for ($loc = 0; $loc <= $max; $loc += 0100) {
  print "\r\n" unless $loc % 0200;
  printf "%05o:", $loc;
  for ($off = 0; $off < 0100; $off++) {
    print "  " unless $off % 010;
    $core1[$loc+$off] = 0 unless defined $core1[$loc+$off];
    $core1[$loc+$off] = 9 unless $core1[$loc+$off] < 10;
    printf "%1d", $core1[$loc+$off];
  }
  print "\r\n";
}
exit $status;

__END__
:endofperl
