From a2e8a187b27d23f84b088366815f623fc8b327f2 Mon Sep 17 00:00:00 2001 From: Warren Toomey Date: Tue, 1 Mar 2016 18:28:37 +1000 Subject: [PATCH] tools/a7out: I took out the code to pretend to deal with binary files, and I did a perltidy to reformat the code. --- tools/a7out | 200 ++++++++++++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 107 deletions(-) diff --git a/tools/a7out b/tools/a7out index ff7cf9e..ca577e8 100755 --- a/tools/a7out +++ b/tools/a7out @@ -37,7 +37,8 @@ while ( defined( $ARGV[0] ) && ( $ARGV[0] =~ m{^-} ) ) { # -d: debug mode if ( $ARGV[0] eq "-d" ) { - $debug = 1; shift(@ARGV); + $debug = 1; + shift(@ARGV); } # -b: set a breakpoint @@ -144,7 +145,7 @@ sub set_arguments { my $c1 = substr( $str, $i, 1 ) || ""; my $c2 = substr( $str, $i + 1, 1 ) || ""; - #printf("Saving %06o to %06o\n", (ord($c1) << 9 ) | ord($c2), $addr); + #printf("Saving %06o to %06o\n", (ord($c1) << 9 ) | ord($c2), $addr); $Mem[ $addr++ ] = ( ord($c1) << 9 ) | ord($c2); } } @@ -184,15 +185,15 @@ sub simulate { my $indaddr = ($indirect) ? $Mem[$addr] & MAXADDR : $addr; # If this is a breakpoint, stop now and get a user command - if ( defined( $Breakpoint{$PC} ) ) { - $singlestep = 1; - dprintf( "break at PC %06o\n", $PC ); - } + if ( defined( $Breakpoint{$PC} ) ) { + $singlestep = 1; + dprintf( "break at PC %06o\n", $PC ); + } get_user_command() if ($singlestep); dprintf( "PC %06o: ", $PC ); - #dprintf("PC %06o: instr %06o, op %03o, in %o, addr %06o indaddr %06o\n", - # $PC, $instruction, $opcode, $indirect, $addr, $indaddr ); + #dprintf("PC %06o: instr %06o, op %03o, in %o, addr %06o indaddr %06o\n", + # $PC, $instruction, $opcode, $indirect, $addr, $indaddr ); # Simulate the instruction. Each subroutine updates the $PC if ( defined( $Oplist{$opcode} ) ) { @@ -248,25 +249,17 @@ sub add { my ( $instruction, $addr, $indaddr ) = @_; dprintf( "add AC (value %06o) with addr %06o (%06o)\n", $AC, $indaddr, $Mem[$indaddr] ); -# $LINK = 0; -# $AC = $AC + $Mem[$indaddr]; -# if ( $AC & LINKMASK ) { -# $AC++; # End-around carry -# $LINK = LINKMASK; -# } -# $AC = $AC & MAXINT; -# + # This logic shamelessly borrowed from SimH # https://github.com/simh/simh/blob/master/PDP18B/pdp18b_cpu.c - my $sum= $AC + $Mem[$indaddr]; - if ($sum > MAXINT) { # end around carry - $sum = ($sum + 1) & MAXINT; + my $sum = $AC + $Mem[$indaddr]; + if ( $sum > MAXINT ) { # end around carry + $sum = ( $sum + 1 ) & MAXINT; } - if (((~$AC ^ $sum) & ($AC ^ $sum)) & SIGN) { # overflow? - $LINK= LINKMASK; # set link + if ( ( ( ~$AC ^ $sum ) & ( $AC ^ $sum ) ) & SIGN ) { # overflow? + $LINK = LINKMASK; # set link } - $AC= $sum; - + $AC = $sum; $PC++; } @@ -341,8 +334,8 @@ sub opr { } # law: load word into AC - my $indirect = ( $instruction >> 13 ) & 1; - if ( $indirect) { + my $indirect = ( $instruction >> 13 ) & 1; + if ($indirect) { dprintf( "law %06o into AC\n", $instruction ); $AC = $instruction; $PC++; @@ -350,94 +343,104 @@ sub opr { } # List of skip opcode names for the next section - my @skipop= ( '', 'sma', 'sza', 'sza sma', - 'snl', 'snl sma', 'snl sza', 'snl sza sma', - 'skp', 'spa', 'sna', 'sna spa', - 'szl', 'szl spa', 'szl sna', 'szl sna spa'); + my @skipop = ( + '', 'sma', 'sza', 'sza sma', + 'snl', 'snl sma', 'snl sza', 'snl sza sma', + 'skp', 'spa', 'sna', 'sna spa', + 'szl', 'szl spa', 'szl sna', 'szl sna spa' + ); # This logic shamelessly borrowed from SimH # https://github.com/simh/simh/blob/master/PDP18B/pdp18b_cpu.c - my $skip=0; - my $i= ($instruction >> 6) & 017; # decode IR<8:11> - dprintf("L.AC %d.%06o %s", ($LINK) ? 1 : 0, $AC, $skipop[$i]); + my $skip = 0; + my $i = ( $instruction >> 6 ) & 017; # decode IR<8:11> + dprintf( "L.AC %d.%06o %s", ($LINK) ? 1 : 0, $AC, $skipop[$i] ); - $skip=1 if (($i == 1) && ($AC & SIGN) != 0); # sma - $skip=1 if (($i == 2) && ($AC & MAXINT) == 0); # sza - $skip=1 if (($i == 3) && - ((($AC & MAXINT) == 0) || (($AC & SIGN) != 0))); # sza | sma - $skip=1 if (($i == 4) && ($LINK)); # snl - $skip=1 if (($i == 5) && ($LINK || ($AC >= SIGN))); # snl | sma - $skip=1 if (($i == 6) && ($LINK || ($AC == 0))); # snl | sza - $skip=1 if (($i == 7) && - ($LINK || ($AC >= SIGN) || ($AC == 0))); # snl | sza | sma - $skip=1 if ($i == 010); # skp - $skip=1 if (($i == 011) && (($AC & SIGN) == 0)); # spa - $skip=1 if (($i == 012) && (($AC & MAXINT) != 0)); # sna - $skip=1 if (($i == 013) && - (($AC & MAXINT) != 0) && (($AC & SIGN) == 0)); # sna & spa - $skip=1 if (($i == 014) && ($LINK == 0)); # szl - $skip=1 if (($i == 015) && ($LINK == 0) && ($AC < SIGN)); # szl & spa - $skip=1 if (($i == 016) && ($LINK == 0) && ($AC != 0)); # szl & sna - $skip=1 if (($i == 017) && - ($LINK == 0) && ($AC != 0) && ($AC != 0)); # szl & sna & spa + $skip = 1 if ( ( $i == 1 ) && ( $AC & SIGN ) != 0 ); # sma + $skip = 1 if ( ( $i == 2 ) && ( $AC & MAXINT ) == 0 ); # sza + $skip = 1 if ( ( $i == 3 ) + && ( ( ( $AC & MAXINT ) == 0 ) || ( ( $AC & SIGN ) != 0 ) ) ) + ; # sza | sma + $skip = 1 if ( ( $i == 4 ) && ($LINK) ); # snl + $skip = 1 if ( ( $i == 5 ) && ( $LINK || ( $AC >= SIGN ) ) ); # snl | sma + $skip = 1 if ( ( $i == 6 ) && ( $LINK || ( $AC == 0 ) ) ); # snl | sza + $skip = 1 if ( ( $i == 7 ) + && ( $LINK || ( $AC >= SIGN ) || ( $AC == 0 ) ) ); # snl | sza | sma + $skip = 1 if ( $i == 010 ); # skp + $skip = 1 if ( ( $i == 011 ) && ( ( $AC & SIGN ) == 0 ) ); # spa + $skip = 1 if ( ( $i == 012 ) && ( ( $AC & MAXINT ) != 0 ) ); # sna + $skip = 1 if ( ( $i == 013 ) + && ( ( $AC & MAXINT ) != 0 ) + && ( ( $AC & SIGN ) == 0 ) ); # sna & spa + $skip = 1 if ( ( $i == 014 ) && ( $LINK == 0 ) ); # szl + $skip = 1 + if ( ( $i == 015 ) && ( $LINK == 0 ) && ( $AC < SIGN ) ); # szl & spa + $skip = 1 + if ( ( $i == 016 ) && ( $LINK == 0 ) && ( $AC != 0 ) ); # szl & sna + $skip = 1 if ( ( $i == 017 ) + && ( $LINK == 0 ) + && ( $AC != 0 ) + && ( $AC != 0 ) ); # szl & sna & spa # Clear operations - if ($instruction & 010000) { # cla - dprintf(" cla"); $AC=0; + if ( $instruction & 010000 ) { # cla + dprintf(" cla"); $AC = 0; } - if ($instruction & 004000) { # cli - dprintf(" cli"); $LINK=0; + if ( $instruction & 004000 ) { # cli + dprintf(" cli"); $LINK = 0; } - if ($instruction & 000002) { # cmi - dprintf(" cmi"); $LINK= ($LINK) ? 0 : LINKMASK; + if ( $instruction & 000002 ) { # cmi + dprintf(" cmi"); + $LINK = ($LINK) ? 0 : LINKMASK; } - if ($instruction & 000001) { # cma - dprintf(" cma"); $AC= ($AC ^ MAXINT) & MAXINT; + if ( $instruction & 000001 ) { # cma + dprintf(" cma"); + $AC = ( $AC ^ MAXINT ) & MAXINT; } # Rotate instructions - $i= $instruction & 02030; + $i = $instruction & 02030; # Single rotate right - if ($i == 020) { - dprintf(" rar"); + if ( $i == 020 ) { + dprintf(" rar"); my $newlink = ( $AC & 1 ) ? LINKMASK : 0; $AC = ( $LINK | $AC ) >> 1; $LINK = $newlink; } # Double rotate right - if ($i == 02020) { - dprintf(" rtr"); - my $msb= ($AC & 1) << 17; + if ( $i == 02020 ) { + dprintf(" rtr"); + my $msb = ( $AC & 1 ) << 17; my $newlink = ( $AC & 2 ) ? LINKMASK : 0; - $AC = (( $LINK | $AC ) >> 2) | $msb; + $AC = ( ( $LINK | $AC ) >> 2 ) | $msb; $LINK = $newlink; } # Single rotate left - if ($i == 010) { - dprintf(" ral"); + if ( $i == 010 ) { + dprintf(" ral"); my $newlink = ( $AC & SIGN ) ? LINKMASK : 0; - my $lsb = $LINK ? 1 : 0; - $AC= (($AC << 1) | $lsb) & MAXINT; + my $lsb = $LINK ? 1 : 0; + $AC = ( ( $AC << 1 ) | $lsb ) & MAXINT; $LINK = $newlink; } # Double rotate left - if ($i == 02010) { - dprintf(" rtl"); + if ( $i == 02010 ) { + dprintf(" rtl"); my $newlink = ( $AC & 0200000 ) ? LINKMASK : 0; - my $lsb = ( $AC & SIGN ) ? 1 : 0; - my $twolsb = $LINK ? 2 : 0; - $AC= (($AC << 2) | $twolsb | $lsb) & MAXINT; + my $lsb = ( $AC & SIGN ) ? 1 : 0; + my $twolsb = $LINK ? 2 : 0; + $AC = ( ( $AC << 2 ) | $twolsb | $lsb ) & MAXINT; $LINK = $newlink; } # Impossible left and right rotates: 02030 or 00030. Do nothing! # Note: We didn't do the oas instruction above. - $PC+= 1 + $skip; + $PC += 1 + $skip; dprintf("\n"); return; } @@ -471,22 +474,20 @@ sub eae { $instruction &= EAEIMASK; if ( $instruction == 0660500 ) { # lrss: long right shift, signed - # We ignore the MQ as it's not - # used by any user-mode programs + # We ignore the MQ as it's not + # used by any user-mode programs dprintf( "lrss %06o AC step %d\n", $AC, $step ); # Save the AC's sign into LINK my $newlink = ( $AC << 1 ) & LINKMASK; - - $AC = (($LINK |$AC) >> $step) & MAXINT; - $LINK= $newlink; + $AC = ( ( $LINK | $AC ) >> $step ) & MAXINT; + $LINK = $newlink; $PC++; return; } if ( $instruction == 0660700 ) { # alss: long left shift, signed - # We don't fill the lsb with LINK yet + # We don't fill the lsb with LINK yet dprintf( "alss %06o AC step %d\n", $AC, $step ); - $AC = ( $AC << $step ) & MAXINT; $PC++; return; @@ -526,6 +527,7 @@ sub sys_close { # Open system call sub sys_open { + # Open seems to have 2 arguments: PC+1 is a pointer to the filename. # PC+2 seems to be 1 for write, 0 for read. # Some programs seem to have a third argument always set to 0. @@ -538,7 +540,7 @@ sub sys_open { my $filename = mem2arg($start); # Choose to open read-only or write-only - my $readorwrite= ($Mem[ $PC + 2 ]) ? ">" : "<"; + my $readorwrite = ( $Mem[ $PC + 2 ] ) ? ">" : "<"; dprintf( "open: base %06o, %s file %s\n", $start, $readorwrite, $filename ); # Bump up the PC @@ -595,22 +597,12 @@ sub sys_read { $count = 0; foreach my $addr ( $start .. $end ) { - # It's a terminal, so convert from ASCII - if ( -t $FH ) { - my $c1 = getc($FH); - last if ( !defined($c1) ); # No character, leave the loop - my $c2 = getc($FH) || ""; # No character, make it a NUL - $Mem[$addr] = - ( ord($c1) << 9 ) | ord($c2); # Pack both into one word - $count++; - } else { - # otherwise (for now) read in one line and convert to octal - my $line = <$FH>; - last if ( !defined($line) ); # No line, leave the loop - chomp($line); - $Mem[$addr] = oct($line) & MAXINT; - $count++; - } + my $c1 = getc($FH); + last if ( !defined($c1) ); # No character, leave the loop + my $c2 = getc($FH) || ""; # No character, make it a NUL + $Mem[$addr] = + ( ord($c1) << 9 ) | ord($c2); # Pack both into one word + $count++; } # No error @@ -647,13 +639,7 @@ sub sys_write { my $FH = $FD[$fd]; foreach my $addr ( $start .. $end ) { - # It's a terminal, so convert to ASCII - # otherwise (for now) print in octal - if ( -t $FH ) { - print( $FH word2ascii( $Mem[$addr] ) ); - } else { - printf( $FH "%06o\n", $Mem[$addr] ); - } + print( $FH word2ascii( $Mem[$addr] ) ); } # No error