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:
Warren Toomey
2016-02-26 06:19:27 +10:00
parent ed46793781
commit f9b8c8eeb2
3 changed files with 64 additions and 32 deletions
+21 -22
View File
@@ -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,24 +207,23 @@ sub sys_open {
# Convert this to a sensible ASCII filename
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);
# No filehandle, so it's an error
if (!defined($FH)) {
# 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) {
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);
$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
@@ -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;
+34 -2
View File
@@ -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
View File
@@ -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