#!/usr/bin/perl
#
# sdump: Dump the contents of a filesystem in SimH format
#
# (c) 2016 Warren Toomey, GPL3
#
use strict;
use warnings;
use Fcntl qw(:flock SEEK_SET);

### read a word from a file in SimH format
### return -1 on EOF
sub read_word {
    my $F = shift;
    # Convert four bytes into one 18-bit word
    return -1 if ( read( $F, my $four, 4 ) != 4 ); # Not enough bytes read
    my ( $b1, $b2, $b3, $b4 ) = unpack( "CCCC", $four );
    return (($b1 & 0xff)  |
            (($b2 & 0xff) << 8 ) |
            (($b3 & 0xff) << 16) |
            (($b4 & 0xff) << 24));
}

### Main program
die("Usage: $0 imagefile\n") if (@ARGV!=1);

open(my $IN, "<", $ARGV[0]) || die("Couldn't open $ARGV[0]: $!\n");

use constant NUMBLOCKS     => 8000;    # Number of blocks on a surface
use constant WORDSPERBLK   => 64;      # 64 words per block
use constant BYTESPERWORD  => 4;       # We encode each word into 4 bytes

# Skip the first surface
seek($IN, NUMBLOCKS*WORDSPERBLK*BYTESPERWORD, SEEK_SET) ||
				die("Cannot seek: $!\n");

foreach my $blocknum ( 0 .. NUMBLOCKS*2 - 1 ) {
    printf("Block %d (%06o)\n", $blocknum, $blocknum );
    foreach my $line ( 0 .. 7 ) {

	# Print out the words in octal
        foreach my $offset ( 0 .. 7 ) {
	    # Get a word
	    my $word= read_word($IN);
	    exit(0) if ($word==-1);
	    printf("%06o ", $word);
	}
	print("\n");
    }
    print("\n");
}
exit(0);
