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:
+16
-17
@@ -86,9 +86,9 @@ sub simulate {
|
||||
my $opcode = ( $instruction >> 12 ) & 074;
|
||||
my $indirect = ( $instruction >> 13 ) & 1;
|
||||
my $addr = $instruction & 017777;
|
||||
printf( "PC %06o: instruction %08o, op %03o, ind %o, addr %06o\n",
|
||||
$PC, $instruction, $opcode, $indirect, $addr )
|
||||
if ($debug);
|
||||
#printf( "PC %06o: instruction %08o, op %03o, ind %o, addr %06o\n",
|
||||
# $PC, $instruction, $opcode, $indirect, $addr )
|
||||
# if ($debug);
|
||||
|
||||
# Simulate the instruction. Each subroutine updates the $PC
|
||||
if ( defined( $Oplist{$opcode} ) ) {
|
||||
@@ -163,14 +163,14 @@ sub iot {
|
||||
if ( defined( $Syscallist{$addr} ) ) {
|
||||
$Syscallist{$addr}->();
|
||||
} else {
|
||||
printf( "Unknown syscall %d at location 0%o\n", $addr, $PC );
|
||||
printf( "PC %06o: Unknown syscall %d\n", $PC, $addr );
|
||||
die("\n");
|
||||
}
|
||||
}
|
||||
|
||||
# Exit system call
|
||||
sub sys_exit {
|
||||
print("exit system call\n") if ($debug);
|
||||
printf("PC %06o: exit system call\n", $PC) if ($debug);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ sub sys_exit {
|
||||
sub sys_close {
|
||||
# AC is the file descriptor
|
||||
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
|
||||
$PC += 1;
|
||||
@@ -207,16 +207,10 @@ sub sys_open {
|
||||
|
||||
# Convert this to a sensible ASCII filename
|
||||
my $filename= mem2string($start);
|
||||
printf("open: file %s\n", $filename) if ($debug);
|
||||
|
||||
open(my $FH, "<", $filename);
|
||||
|
||||
# No filehandle, so it's an error
|
||||
if (!defined($FH)) {
|
||||
print("open failed: $!\n") if ($debug);
|
||||
$AC= 0777777; return;
|
||||
}
|
||||
printf("PC %06o: open: file %s\n", $PC, $filename) if ($debug);
|
||||
|
||||
# Open the file
|
||||
if (open(my $FH, "<", $filename)) {
|
||||
# Find a place in the @FD array to store this filehandle. 99 is arbitrary
|
||||
my $fd;
|
||||
foreach $fd (0 .. 99) {
|
||||
@@ -225,6 +219,11 @@ sub sys_open {
|
||||
}
|
||||
}
|
||||
$AC=$fd; return;
|
||||
} else {
|
||||
# No filehandle, so it's an error
|
||||
print("open failed: $!\n") if ($debug);
|
||||
$AC= 0777777; return;
|
||||
}
|
||||
}
|
||||
|
||||
# Read system call
|
||||
@@ -238,7 +237,7 @@ sub sys_read {
|
||||
my $start= $Mem[$PC+1];
|
||||
my $count= $Mem[$PC+2];
|
||||
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
|
||||
$PC += 3;
|
||||
@@ -284,7 +283,7 @@ sub sys_write {
|
||||
my $start= $Mem[$PC+1];
|
||||
my $count= $Mem[$PC+2];
|
||||
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
|
||||
$PC += 3;
|
||||
|
||||
@@ -26,8 +26,39 @@ my $stage = 1; # Pass one or pass two
|
||||
# Check the arguments
|
||||
die("Usage: $0 file1.s [file2.s ...]\n") if ( @ARGV < 1 );
|
||||
|
||||
# Start with the location counter at zero
|
||||
$Var{'.'} = 0;
|
||||
# Define the syscalls as variables so that
|
||||
# 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
|
||||
foreach my $file (@ARGV) {
|
||||
@@ -189,6 +220,7 @@ sub parse_expression {
|
||||
'i' => 0020000,
|
||||
'eae' => 0640000,
|
||||
'iot' => 0700000,
|
||||
'sys' => 0700000,
|
||||
'opr' => 0740000,
|
||||
'law' => 0760000,
|
||||
'lam' => 0777777,
|
||||
|
||||
+9
-8
@@ -7,16 +7,16 @@ main:
|
||||
lac in
|
||||
dac out
|
||||
|
||||
" The assembler doesn't know sys write, so iot 5 for now
|
||||
" Write hello to fd1 i.e stdout
|
||||
lac d1
|
||||
iot 5; hello; 7
|
||||
sys write; hello; 7
|
||||
|
||||
" 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!
|
||||
lac d0
|
||||
iot 4; buf; 5
|
||||
sys read; buf; 5
|
||||
|
||||
" Stop and dump memory, so you can see five words at location 0400
|
||||
" Comment out the hlt instruction to test close and exit
|
||||
@@ -24,10 +24,10 @@ main:
|
||||
|
||||
" close stdin
|
||||
lac d0
|
||||
iot 9
|
||||
sys close
|
||||
|
||||
" exit
|
||||
iot 14
|
||||
sys exit
|
||||
|
||||
" We should not get to the halt instruction
|
||||
hlt
|
||||
@@ -41,8 +41,6 @@ in: 023
|
||||
out: 0
|
||||
|
||||
" Hello, world\n, two ASCII chars per word
|
||||
d0: 0
|
||||
d1: 1
|
||||
hello: 0110145; 0154154; 0157054; 040; 0167157; 0162154; 0144012
|
||||
|
||||
" fred as a string, NUL terminated
|
||||
@@ -51,3 +49,6 @@ fred: 0146162; 0145144; 0
|
||||
" Input buffer for read
|
||||
. = 0400
|
||||
buf: 0
|
||||
|
||||
d0: 0
|
||||
d1: 1
|
||||
|
||||
Reference in New Issue
Block a user