From cfafcad9634cbbc6c5f733e024cb31de553b83a9 Mon Sep 17 00:00:00 2001 From: Warren Toomey Date: Mon, 7 Mar 2016 16:17:57 +1000 Subject: [PATCH] a7 is updated with Phil's stdin reading patch. I've written a few more utilities and modified the v1 man pages for them. Fixed a typo (missing line) in src/cmd/as.s. --- Makefile | 7 +- man/ln.1 | 19 +++++ man/mv.1 | 19 +++++ man/stat.1 | 50 +++++++++++++ src/cmd/as.s | 1 + src/other/testmul.s | 11 +++ src/other/wktln.s | 41 ++++++++++ src/other/wktmv.s | 41 ++++++++++ src/other/wktstat.s | 179 ++++++++++++++++++++++++++++++++++++++++++++ tools/a7out | 77 +++++++++++++++---- 10 files changed, 427 insertions(+), 18 deletions(-) create mode 100644 man/ln.1 create mode 100644 man/mv.1 create mode 100644 man/stat.1 create mode 100644 src/other/testmul.s create mode 100644 src/other/wktln.s create mode 100644 src/other/wktmv.s create mode 100644 src/other/wktstat.s diff --git a/Makefile b/Makefile index 68dbff8..e37bffb 100644 --- a/Makefile +++ b/Makefile @@ -39,8 +39,11 @@ cmd: dirs # $(AS) $(ASARGS) -o $(CMDDIR)/init src/cmd/init.s others: - $(AS) $(ASARGS) -o $(CMDDIR)/ls src/other/wktls.s - $(AS) $(ASARGS) -o $(CMDDIR)/sh src/other/sh.s + $(AS) $(ASARGS) -o $(CMDDIR)/ls src/other/wktls.s + $(AS) $(ASARGS) -o $(CMDDIR)/sh src/other/sh.s + $(AS) $(ASARGS) -o $(CMDDIR)/stat src/other/wktstat.s + $(AS) $(ASARGS) -o $(CMDDIR)/mv src/other/wktmv.s + $(AS) $(ASARGS) -o $(CMDDIR)/ln src/other/wktln.s clean: rm -rf $(SYSDIR)/* diff --git a/man/ln.1 b/man/ln.1 new file mode 100644 index 0000000..bc81f4b --- /dev/null +++ b/man/ln.1 @@ -0,0 +1,19 @@ + 11/3/70 LN (I) + + +NAME ln -- link to a file + +SYNOPSIS ln name1 name2 + +DESCRIPTION ln adds another filename to the first filename + +FILES + +SEE ALSO + +DIAGNOSTICS "twofiles" - please provide two filenames + "? file" - unable to make the link + +BUGS + +OWNER wkt diff --git a/man/mv.1 b/man/mv.1 new file mode 100644 index 0000000..aa86651 --- /dev/null +++ b/man/mv.1 @@ -0,0 +1,19 @@ + 11/3/70 MV (I) + + +NAME mv -- move or rename a file + +SYNOPSIS mv name1 name2 + +DESCRIPTION mv changes the name of name with the rename system call. + +FILES + +SEE ALSO + +DIAGNOSTICS "twofiles" - please provide two filenames + "? file" - either unable to remove or create a file + +BUGS The second diagnostic is ambiguous. + +OWNER wkt diff --git a/man/stat.1 b/man/stat.1 new file mode 100644 index 0000000..a46f885 --- /dev/null +++ b/man/stat.1 @@ -0,0 +1,50 @@ + 11/3/70 STAT (I) + + +NAME stat - get file status + +SYNOPSIS stat name + +DESCRIPTION stat gives several kinds of information about one file: + files: + + access mode + number of links + owner + size in words + name + + All information is self-explanatory except the mode. The + mode is a five-character string whose characters mean the + following: + + 1 s: file is small (smaller than 4096 words) + l: file is large + d: file is a directory + + 2 r: owner can read + -: owner cannot read + + 3 w: owner can write + -: owner cannot write + + 4 r: non-owner can read + -: non-owner cannot read + + 5 w: non-owner can write + -: non-owner cannot write + + All numeric values are printed in octal + if he cannot be found in "/etc/uids" a number is given. + + +FILES + +SEE ALSO ls with the -l option gives the same information as stat, + except that it also shows the i-node number for each file. + +DIAGNOSTICS "name ?" for any error. "nofiles" if no file name is given. + +BUGS none + +OWNER wkt diff --git a/src/cmd/as.s b/src/cmd/as.s index 9382fac..7502663 100644 --- a/src/cmd/as.s +++ b/src/cmd/as.s @@ -148,6 +148,7 @@ init: 0 " common init for both passes dac fname " point to first file name -1 dac eofflg + jms nextfil jms ioinit dzm savchr " clear saved char dzm comflg " clear line comment flag diff --git a/src/other/testmul.s b/src/other/testmul.s new file mode 100644 index 0000000..82fcbbe --- /dev/null +++ b/src/other/testmul.s @@ -0,0 +1,11 @@ + lac d10 + cll " clear link + mul " mutiply by radix +num2: 10 + lacq + cll + idiv; 10 + nop + hlt + +d10: 10 diff --git a/src/other/wktln.s b/src/other/wktln.s new file mode 100644 index 0000000..3fdcc91 --- /dev/null +++ b/src/other/wktln.s @@ -0,0 +1,41 @@ +" Warren's version of mv. mv file1 file2 + +main: + + lac 017777 i " Load the pointer pointer in 017777 + sad d8 " to see if we have two + jmp nofiles " No arguments, stop now + lac 017777 " Move five words past the argument word count + tad d5 " so that AC points at the first argument + dac name1 " and save it + tad d4 " Then do the same for the second name + dac name2 + + sys link; name1:0; name2:0 " Link the file + spa + jmp badfile " Print out an error on failure + sys exit + + +nofiles: + lac d8 + sys write; 1f; 5 " Write "No files\n" to stderr + sys exit " and exit + +1: ; ;;; ;;; 040; ;; \&sys_seek, # 8 tell 9 => \&sys_close, - # 10 link + 10 => \&sys_link, 11 => \&sys_unlink, 12 => \&sys_setuid, - # 13 rename + 13 => \&sys_rename, 14 => \&sys_exit, 15 => \&sys_time, 16 => \&sys_intrp, @@ -647,6 +647,8 @@ sub sys_exit { # Getuid system call sub sys_getuid { $AC = $< & MAXINT; + # On PDP-7 Unix, the root user is user-id -1 + $AC= MAXINT if ($AC==0); dprintf( "getuid system call, uid %06o\n", $AC ); $PC += 1; return; @@ -656,7 +658,7 @@ sub sys_getuid { sub sys_setuid { # For now, do nothing - dprint("setuid system call\n"); + dprintf("setuid system call\n"); $PC += 1; return; } @@ -665,7 +667,7 @@ sub sys_setuid { sub sys_intrp { # For now, do nothing - dprint("intrp system call\n"); + dprintf("intrp system call\n"); $PC += 1; return; } @@ -891,7 +893,7 @@ sub sys_read { # That filehandle is not open, set an error -1 in octal if ( !defined( $FD[$fd] ) ) { - dprint("read: fd $fd is not open\n"); + dprintf("read: fd $fd is not open\n"); $AC = MAXINT; return; } @@ -899,26 +901,35 @@ sub sys_read { # Read each word in my $FH = $FD[$fd]; $count = 0; + my $tty = -t $FH; foreach my $addr ( $start .. $end ) { if ( $ISBINARY[$fd] ) { - # Convert three bytes into one 18-bit word my $result = read( $FH, my $three, 3 ); last if ( $result != 3 ); # Not enough bytes read my ( $b1, $b2, $b3 ) = unpack( "CCC", $three ); - $Mem[$addr] = ( ( $b1 & 077 ) << 12 ) | ( $b2 << 6 ) | $b3; + $Mem[$addr] = ((($b1 & 077) << 12 ) | + (($b2 & 077) << 6 ) | + ($b3 & 077)); + $count++; } else { # Convert two ASCII characters into one 18-bit word my $c1 = getc($FH); + my $c2; last if ( !defined($c1) ); # No character, leave the loop - my $c2 = getc($FH); # No character, make it a NUL - $c2 = "" if ( !defined($c2) ); - $Mem[$addr] = - ( ord($c1) << 9 ) | ord($c2); # Pack both into one word - } - $count++; + my $word = ord($c1) << 9; + if ( !$tty || $c1 ne "\n") { + $c2 = getc($FH); + if (defined($c2)) { + $word |= ord($c2); + } + } + $Mem[$addr] = $word; + $count++; + last if ($tty && ($c1 eq "\n") || ($c2 eq "\n")); + } # ascii } # No error @@ -946,7 +957,7 @@ sub sys_write { # That filehandle is not open, set an error -1 in octal if ( !defined( $FD[$fd] ) ) { - dprint("write: fd $fd is not open\n"); + dprintf("write: fd $fd is not open\n"); $AC = MAXINT; return; } @@ -1109,6 +1120,7 @@ sub sys_status { # 000004 owner write # 000002 user write # 000001 user write + # XXX: We don't seem to have the i-node number in this structure?! # Get the start address of the string # Convert this to a sensible ASCII filename @@ -1149,7 +1161,7 @@ sub sys_status { # Seek syscall sub sys_seek { # Seek takes three arguments: AC is the fd, PC+1 is a signed count - # and PC+1 is how to seek: 0=from start, 1=from curptr, 2=from end + # and PC+2 is how to seek: 0=from start, 1=from curptr, 2=from end # of file. Return AC=0 if OK, -1 on error. my $fd= $AC; my $FH= $FD[$fd]; @@ -1167,6 +1179,39 @@ sub sys_seek { return; } +# Rename syscall +sub sys_rename { + # Rename takes two arguments: PC+1 is the current filename and + # PC+2 is the new filename. Returns AC=0 on success, AC=-1 on error. + # + my $oldname = mem2arg($Mem[$PC+1]); + my $newname = mem2arg($Mem[$PC+2]); + dprintf( "rename file %s to %s\n", $oldname, $newname ); + my $result= rename($oldname, $newname); + + # Set the AC result + $AC= ($result)? 0: MAXINT; + $PC += 3; + return; +} + +# Link syscall +sub sys_link { + # Link takes two arguments: PC+1 is the current filename and + # PC+2 is the new filename. Returns AC=0 on success, AC=-1 on error. + # Yes, this is not strictly what PDP-7 Unix would have done. + # + my $oldname = mem2arg($Mem[$PC+1]); + my $newname = mem2arg($Mem[$PC+2]); + dprintf( "link file %s to %s\n", $oldname, $newname ); + my $result= link($oldname, $newname); + + # Set the AC result + $AC= ($result)? 0: MAXINT; + $PC += 3; + return; +} + # Convert an 18-bit word into a scalar which has three sixbit # values in three bytes. Set the msb in the first byte sub word2three {