tools/a7out: I refactored the indirect logic, much nicer now.

This commit is contained in:
Warren Toomey
2016-02-26 21:57:10 +10:00
parent a132327a8b
commit 9c8dbdea37
+24 -29
View File
@@ -147,14 +147,17 @@ sub simulate {
my $opcode = ( $instruction >> 12 ) & 074; my $opcode = ( $instruction >> 12 ) & 074;
my $indirect = ( $instruction >> 13 ) & 1; my $indirect = ( $instruction >> 13 ) & 1;
my $addr = $instruction & 017777; my $addr = $instruction & 017777;
# Work out what any indirect address would be
my $indaddr= ($indirect) ? $Mem[$addr] & 017777 : $addr;
printf( STDERR printf( STDERR
"PC %06o: instruction %08o, op %03o, ind %o, addr %06o\n", "PC %06o: instr %06o, op %03o, ind %o, addr %06o ind %06o\n",
$PC, $instruction, $opcode, $indirect, $addr ) $PC, $instruction, $opcode, $indirect, $addr, $indaddr )
if ($debug); if ($debug);
# Simulate the instruction. Each subroutine updates the $PC # Simulate the instruction. Each subroutine updates the $PC
if ( defined( $Oplist{$opcode} ) ) { if ( defined( $Oplist{$opcode} ) ) {
$Oplist{$opcode}->( $instruction, $indirect, $addr ); $Oplist{$opcode}->( $instruction, $addr, $indaddr );
} else { } else {
printf( STDERR "Unknown instruction 0%o at location 0%o\n", printf( STDERR "Unknown instruction 0%o at location 0%o\n",
$instruction, $PC ); $instruction, $PC );
@@ -166,53 +169,45 @@ sub simulate {
# Debug code: dump memory contents # Debug code: dump memory contents
sub dump_memory { sub dump_memory {
foreach my $i ( 0 .. 017777 ) { foreach my $i ( 0 .. 017777 ) {
printf( STDERR "%06o: %08o\n", $i, $Mem[$i] ) if ( $Mem[$i] != 0 ); printf( STDERR "%06o: %06o\n", $i, $Mem[$i] ) if ( $Mem[$i] != 0 );
} }
} }
# Load AC # Load AC
sub lac { sub lac {
my ( $instruction, $indirect, $addr ) = @_; my ( $instruction, $addr, $indaddr ) = @_;
printf( STDERR "PC %06o: lac %05o (value %08o) into AC\n", printf( STDERR "PC %06o: lac %05o (value %06o) into AC\n",
$PC, $addr, $Mem[$addr] ) $PC, $indaddr, $Mem[$indaddr] )
if ($debug); if ($debug);
$AC = ($indirect) ? $Mem[ $Mem[$addr] & 017777 ] : $Mem[$addr]; $AC = $Mem[$indaddr];
$PC++; $PC++;
} }
# Deposit AC # Deposit AC
sub dac { sub dac {
my ( $instruction, $indirect, $addr ) = @_; my ( $instruction, $addr, $indaddr ) = @_;
printf( STDERR "PC %06o: dac AC (value %08o) into %05o\n", printf( STDERR "PC %06o: dac AC (value %06o) into %05o\n",
$PC, $AC, $addr ) $PC, $AC, $indaddr )
if ($debug); if ($debug);
if ($indirect) { $Mem[$indaddr] = $AC;
$Mem[ $Mem[$addr] & 017777 ] = $PC;
} else {
$Mem[$addr] = $AC;
}
$PC++; $PC++;
} }
# Add to AC # Add to AC
sub tad { sub tad {
my ( $instruction, $indirect, $addr ) = @_; my ( $instruction, $addr, $indaddr ) = @_;
printf( STDERR "PC %06o: tac AC (value %08o) from addr %05o\n", printf( STDERR "PC %06o: tac AC (value %06o) from addr %05o\n",
$PC, $AC, $addr ) $PC, $AC, $indaddr )
if ($debug); if ($debug);
if ($indirect) { $AC+= $Mem[$indaddr];
$AC += $Mem[ $Mem[$addr] & 017777 ];
} else {
$AC+= $Mem[$addr];
}
$PC++; $PC++;
} }
# Jump # Jump
sub jmp { sub jmp {
my ( $instruction, $indirect, $addr ) = @_; my ( $instruction, $addr, $indaddr ) = @_;
printf( STDERR "PC %06o: jmp %06o\n", $PC, $addr ) if ($debug); printf( STDERR "PC %06o: jmp %06o\n", $PC, $indaddr ) if ($debug);
$PC = $addr; $PC = $indaddr;
} }
# Special instructions # Special instructions
@@ -242,13 +237,13 @@ sub special {
$PC += ( $AC == 0 ) ? 2 : 1; $PC += ( $AC == 0 ) ? 2 : 1;
return; return;
} }
printf( STDERR "PC %06o: unknown instruction %08o\n", $PC, $instruction ); printf( STDERR "PC %06o: unknown instruction %06o\n", $PC, $instruction );
exit(1); exit(1);
} }
# I/O transfer: used for system calls # I/O transfer: used for system calls
sub iot { sub iot {
my ( $instruction, $indirect, $addr ) = @_; my ( $instruction, $addr, $indaddr ) = @_;
# Syscalls that we can simulate # Syscalls that we can simulate
my %Syscallist = ( my %Syscallist = (