Changed as7 to allow sys open statements, rewrite write_test.s to
use this syntax, and fixed up a bug in sys_open in a7out.
This commit is contained in:
+21
-22
@@ -86,9 +86,9 @@ 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;
|
||||||
printf( "PC %06o: instruction %08o, op %03o, ind %o, addr %06o\n",
|
#printf( "PC %06o: instruction %08o, op %03o, ind %o, addr %06o\n",
|
||||||
$PC, $instruction, $opcode, $indirect, $addr )
|
# $PC, $instruction, $opcode, $indirect, $addr )
|
||||||
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} ) ) {
|
||||||
@@ -163,14 +163,14 @@ sub iot {
|
|||||||
if ( defined( $Syscallist{$addr} ) ) {
|
if ( defined( $Syscallist{$addr} ) ) {
|
||||||
$Syscallist{$addr}->();
|
$Syscallist{$addr}->();
|
||||||
} else {
|
} else {
|
||||||
printf( "Unknown syscall %d at location 0%o\n", $addr, $PC );
|
printf( "PC %06o: Unknown syscall %d\n", $PC, $addr );
|
||||||
die("\n");
|
die("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Exit system call
|
# Exit system call
|
||||||
sub sys_exit {
|
sub sys_exit {
|
||||||
print("exit system call\n") if ($debug);
|
printf("PC %06o: exit system call\n", $PC) if ($debug);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ sub sys_exit {
|
|||||||
sub sys_close {
|
sub sys_close {
|
||||||
# AC is the file descriptor
|
# AC is the file descriptor
|
||||||
my $fd= $AC;
|
my $fd= $AC;
|
||||||
print("close: closing fd $fd\n") if ($debug);
|
printf("PC %06o: close: closing fd %d\n", $PC, $fd) if ($debug);
|
||||||
|
|
||||||
# Bump up the PC
|
# Bump up the PC
|
||||||
$PC += 1;
|
$PC += 1;
|
||||||
@@ -207,24 +207,23 @@ sub sys_open {
|
|||||||
|
|
||||||
# Convert this to a sensible ASCII filename
|
# Convert this to a sensible ASCII filename
|
||||||
my $filename= mem2string($start);
|
my $filename= mem2string($start);
|
||||||
printf("open: file %s\n", $filename) if ($debug);
|
printf("PC %06o: open: file %s\n", $PC, $filename) if ($debug);
|
||||||
|
|
||||||
open(my $FH, "<", $filename);
|
# Open the file
|
||||||
|
if (open(my $FH, "<", $filename)) {
|
||||||
# No filehandle, so it's an error
|
# Find a place in the @FD array to store this filehandle. 99 is arbitrary
|
||||||
if (!defined($FH)) {
|
my $fd;
|
||||||
|
foreach $fd (0 .. 99) {
|
||||||
|
if (!defined($FD[$fd])) {
|
||||||
|
$FD[$fd]= $FH; last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$AC=$fd; return;
|
||||||
|
} else {
|
||||||
|
# No filehandle, so it's an error
|
||||||
print("open failed: $!\n") if ($debug);
|
print("open failed: $!\n") if ($debug);
|
||||||
$AC= 0777777; return;
|
$AC= 0777777; return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Find a place in the @FD array to store this filehandle. 99 is arbitrary
|
|
||||||
my $fd;
|
|
||||||
foreach $fd (0 .. 99) {
|
|
||||||
if (!defined($FD[$fd])) {
|
|
||||||
$FD[$fd]= $FH; last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$AC=$fd; return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read system call
|
# Read system call
|
||||||
@@ -238,7 +237,7 @@ sub sys_read {
|
|||||||
my $start= $Mem[$PC+1];
|
my $start= $Mem[$PC+1];
|
||||||
my $count= $Mem[$PC+2];
|
my $count= $Mem[$PC+2];
|
||||||
my $end= $start + $count -1;
|
my $end= $start + $count -1;
|
||||||
printf("read: %d words from %o from fd %d\n", $count, $start, $fd) if ($debug);
|
printf("PC %06o: read: %d words from %o from fd %d\n", $PC, $count, $start, $fd) if ($debug);
|
||||||
|
|
||||||
# Bump up the PC
|
# Bump up the PC
|
||||||
$PC += 3;
|
$PC += 3;
|
||||||
@@ -284,7 +283,7 @@ sub sys_write {
|
|||||||
my $start= $Mem[$PC+1];
|
my $start= $Mem[$PC+1];
|
||||||
my $count= $Mem[$PC+2];
|
my $count= $Mem[$PC+2];
|
||||||
my $end= $start + $count -1;
|
my $end= $start + $count -1;
|
||||||
printf("write: %d words from %o to fd %d\n", $count, $start, $fd) if ($debug);
|
printf("PC %06o: write: %d words from %o to fd %d\n", $PC, $count, $start, $fd) if ($debug);
|
||||||
|
|
||||||
# Bump up the PC
|
# Bump up the PC
|
||||||
$PC += 3;
|
$PC += 3;
|
||||||
|
|||||||
@@ -26,8 +26,39 @@ my $stage = 1; # Pass one or pass two
|
|||||||
# Check the arguments
|
# Check the arguments
|
||||||
die("Usage: $0 file1.s [file2.s ...]\n") if ( @ARGV < 1 );
|
die("Usage: $0 file1.s [file2.s ...]\n") if ( @ARGV < 1 );
|
||||||
|
|
||||||
# Start with the location counter at zero
|
# Define the syscalls as variables so that
|
||||||
$Var{'.'} = 0;
|
# I don't have to hand-code the logic below.
|
||||||
|
# Also, start with the location counter at zero
|
||||||
|
%Var= (
|
||||||
|
'.' => 0,
|
||||||
|
save => 1,
|
||||||
|
getuid => 2,
|
||||||
|
open => 3,
|
||||||
|
read => 4,
|
||||||
|
write => 5,
|
||||||
|
creat => 6,
|
||||||
|
seek => 7,
|
||||||
|
tell => 8,
|
||||||
|
close => 9,
|
||||||
|
link => 10,
|
||||||
|
unlink => 11,
|
||||||
|
setuid => 12,
|
||||||
|
rename => 13,
|
||||||
|
exit => 14,
|
||||||
|
time => 15,
|
||||||
|
intrp => 16,
|
||||||
|
chdir => 17,
|
||||||
|
chmod => 18,
|
||||||
|
chown => 19,
|
||||||
|
badcal => 20,
|
||||||
|
syslog => 21,
|
||||||
|
capt => 23,
|
||||||
|
rele => 24,
|
||||||
|
status => 25,
|
||||||
|
smes => 27,
|
||||||
|
rmes => 28,
|
||||||
|
fork => 29
|
||||||
|
);
|
||||||
|
|
||||||
# Parse all the files
|
# Parse all the files
|
||||||
foreach my $file (@ARGV) {
|
foreach my $file (@ARGV) {
|
||||||
@@ -189,6 +220,7 @@ sub parse_expression {
|
|||||||
'i' => 0020000,
|
'i' => 0020000,
|
||||||
'eae' => 0640000,
|
'eae' => 0640000,
|
||||||
'iot' => 0700000,
|
'iot' => 0700000,
|
||||||
|
'sys' => 0700000,
|
||||||
'opr' => 0740000,
|
'opr' => 0740000,
|
||||||
'law' => 0760000,
|
'law' => 0760000,
|
||||||
'lam' => 0777777,
|
'lam' => 0777777,
|
||||||
|
|||||||
+9
-8
@@ -7,16 +7,16 @@ main:
|
|||||||
lac in
|
lac in
|
||||||
dac out
|
dac out
|
||||||
|
|
||||||
" The assembler doesn't know sys write, so iot 5 for now
|
" Write hello to fd1 i.e stdout
|
||||||
lac d1
|
lac d1
|
||||||
iot 5; hello; 7
|
sys write; hello; 7
|
||||||
|
|
||||||
" open file fred
|
" open file fred
|
||||||
iot 3; fred; 0; 0
|
sys open; fred; 0; 0
|
||||||
|
|
||||||
" read 5 words into the buffer from stdin: type in 10 or more characters!
|
" read 5 words into the buffer from stdin: type in 10 or more characters!
|
||||||
lac d0
|
lac d0
|
||||||
iot 4; buf; 5
|
sys read; buf; 5
|
||||||
|
|
||||||
" Stop and dump memory, so you can see five words at location 0400
|
" Stop and dump memory, so you can see five words at location 0400
|
||||||
" Comment out the hlt instruction to test close and exit
|
" Comment out the hlt instruction to test close and exit
|
||||||
@@ -24,10 +24,10 @@ main:
|
|||||||
|
|
||||||
" close stdin
|
" close stdin
|
||||||
lac d0
|
lac d0
|
||||||
iot 9
|
sys close
|
||||||
|
|
||||||
" exit
|
" exit
|
||||||
iot 14
|
sys exit
|
||||||
|
|
||||||
" We should not get to the halt instruction
|
" We should not get to the halt instruction
|
||||||
hlt
|
hlt
|
||||||
@@ -41,8 +41,6 @@ in: 023
|
|||||||
out: 0
|
out: 0
|
||||||
|
|
||||||
" Hello, world\n, two ASCII chars per word
|
" Hello, world\n, two ASCII chars per word
|
||||||
d0: 0
|
|
||||||
d1: 1
|
|
||||||
hello: 0110145; 0154154; 0157054; 040; 0167157; 0162154; 0144012
|
hello: 0110145; 0154154; 0157054; 040; 0167157; 0162154; 0144012
|
||||||
|
|
||||||
" fred as a string, NUL terminated
|
" fred as a string, NUL terminated
|
||||||
@@ -51,3 +49,6 @@ fred: 0146162; 0145144; 0
|
|||||||
" Input buffer for read
|
" Input buffer for read
|
||||||
. = 0400
|
. = 0400
|
||||||
buf: 0
|
buf: 0
|
||||||
|
|
||||||
|
d0: 0
|
||||||
|
d1: 1
|
||||||
|
|||||||
Reference in New Issue
Block a user