From a1930b76d90a94f548361796e74edf28518155ca Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 11:01:04 -0500 Subject: [PATCH 1/8] renamed sh.s to pbsh.s --- src/other/sh.s | 434 ------------------------------------------------- 1 file changed, 434 deletions(-) delete mode 100644 src/other/sh.s diff --git a/src/other/sh.s b/src/other/sh.s deleted file mode 100644 index 87d4f44..0000000 --- a/src/other/sh.s +++ /dev/null @@ -1,434 +0,0 @@ -" -*-fundamental-*- -" sh -- a shell -" started by p budne 3/4/2016 -" with code from cat.s, init.s, and looking at the v1 (pdp-11) shell - -" XXX cat.s seems to write error output on fd 8 - -start: -" XXX take command line argument (script file to open), suppress prompt?? -" NOTE!!! v0 init.s doesn't set up the argv at the top of memory, -" so the v0 shell may not have taken command line arguments!!! -" if non-interactive, "dzm prompt", jump to newcom - -interactive: - -1 - sys intrp " make shell uninterruptable - sys getuid - sma " <0? - jmp newline " no, a mundane - lac hash " yes: superuser - dac prompt " change prompt - -newline: - lac d1; sys write; prompt; 1 " output prompt -newcom: - dzm char " clear saved char - dzm infile " clear input redirect file name - dzm outfile " clear output redirect file name - lac iopt " reset output pointer - dac opt - dac nextarg - -" reset high memory - dzm argc " clear arg count - lac argcptr - dac argptr - dzm argv0 " clear out argv0 for chdir comparison - dzm argv0+1 - dzm argv0+2 - -newarg: - -8 " save 8 chars - dac bcount - dzm redirect - - lac opt " save start for print (TEMP) - dac nextarg - - jms blank " skip whitespace - jms delim " newline? - jmp eol " yes - sad lt " input redirect? - jmp redirin - sad gt " output redirect? - jmp redirout - jmp 3f - -redirin: " saw < - dac redirect " flag redirect - lac infilep - dac opt - jmp newchar " v1 behavior? no whitespace eater - -redirout: " saw > - dac redirect " flag redirect - lac outfilep - dac opt - " v1 behavior? no whitespace eater! - " fall - -newchar: - jms getc - sad o40 " space? - jmp ws " yes - jms delim - jmp eoname -3: jms putc " save - isz bcount " loop unless full - jmp newchar - -" here after 8 chars: discard until terminator seen -discard: - jms getc - dac char - sad o4 - jmp eof - jms delim " end of line? - jmp eoname - sad o40 - jmp eoname - jmp discard - -" here with EOF in command: process command? -eof: - sys exit " quit, for now? - -" name ended (short) with whitespace or newline -" pad out last name to 8 with spaces -ws: - dac char " save terminator -1: lac o40 - jms putc " no: copy into argv - isz bcount " loop until full - jmp 1b - -" saw end of name -eoname: - dac char - lac redirect - sza - jmp 2f " last name was a redirect file, skip increment - - lac argc " increment argc - tad d4 - dac argc - lac nextarg - tad d4 " advance nextarg - dac nextarg - -2: - dzm redirect " clear redirect flag - lac nextarg - dac opt - - lac char - jms delim - jmp eol - - -maxargs - tad argc - sza - jmp newarg - -" too many args, (complain?). for now eat rest of line -4: jms getc - jms delim - skp - jmp 4b - lac d1; sys write; toomany; ltoomany - jmp newline - -" here at end of line -eol: - sad delimchar " save eol character - lac argc " check for empty command line - sna " get anything? - jmp 2f " no, go back for another - -" check for built-in "chdir" command - lac argv0 - sad chdirstr - skp - jmp 1f - lac argv0+1 - sad chdirstr+1 - skp - jmp 1f - lac argv0+2 - sad chdirstr+2 - jmp changedir - -1: -" comment these out to test "exec" - sys fork - jmp parent - -" here in child - lac d2; sys close " close fd 2 - sys unlink; exectemp " remove temp file - -" try to link binary from "system" directory to "exectemp" file -" sys link; system; argv0; exectemp -" spa -" jmp notsys -" sys open; exectemp; 0 -" spa -" jmp error -" sys unlink; exectemp -" jmp 1f -"notsys: " not found in "system" - - sys open; argv0; 0 " try cwd - spa - jmp cmderr - - cla " check for input redirection - sad infile - jmp 1f - sys close " close fd 0 - sys open; infile; 0 " open redirected - spa sna - jmp inerror - cla -1: sad outfile - jmp exec - lac d1; sys close " close fd 1 - lac o17 - sys creat; outfile " open output redirect - spa - jmp outerror - -" here to "exec" file open on fd 2, adapted from init.s -exec: - law boot-1 " Get source addr - dac 8 " set up index 8 (pre-increments) - law bootloc-1 " Copy "boot" code into high memory - dac 9 " set up index 9 (pre-increments) -1: lac 8 i - dac 9 i - isz bootcount " can only do this once! - jmp 1b - jmp bootloc " and then jump to the code - -" copied up to bootloc in high memory (below argc) -boot: - lac d2 " Load fd 2 (the opened executable) - lmq " Save the fd into MQ - sys read; userbase; userlen " read executable in - lacq " Get the fd back and close the file - sys close - jmp userbase " and jump to the beginning of the executable -bootlen=.-boot " length of bootstrap - -bootcount: -bootlen " isz loop count for bootstrap copy - -" error in child process: -inerror: " error opening input redirection - lac infilep - jmp error -outerror: " error opening new stdout (stdout closed!) - lac outfilep - skp -cmderr: " error opening command - lac argv0p -error: " error in child: filename pointer in AC - dac 1f " save filename to complain about - lac d1; sys write; 1: 0; 4 - lac d1; sys write; qmnl; 1 - lac d2; sys close - sys exit - -" chdir command: executed in shell process -changedir: -" XXX check if argc == 4 (no directories) and complain?? - lac argv0p - skp -1: lac 0f " increment argvp - tad d4 - sad 0f - -4 " decrement argc - tad argc - dac argc - sna " done? - jmp 2f " yes: join parent code - sys chdir; 0:0 - sma " error? - jmp 1b " no: look for another directory - -" chdir call failed - lac 0b - dac 0f - lac d1; sys write; 0:0; 4 - lac d1; sys write; qmnl; 1 - jmp 2f " join parent code - -" here in parent, child pid in AC -parent: -" https://www.bell-labs.com/usr/dmr/www/hist.html -" The message facility was used as follows: the parent shell, after -" creating a process to execute a command, sent a message to the new -" process by smes; when the command terminated (assuming it did not -" try to read any messages) the shell's blocked smes call returned an -" error indication that the target process did not exist. Thus the -" shell's smes became, in effect, the equivalent of wait. - dac pid - lac delimchar - sad o46 " ampersand? - jmp newcom " yes: go back without wait - lac pid - sys smes " hang until child exits -2: lac delimchar - sad o73 " semi? - jmp newcom " yes: look for another command w/o prompt - jmp newline " no: output prompt - -" ================ -" subroutines - -" eat spaces -" v1 routine name: -blank: 0 -1: jms getc - sad o40 - jmp 1b - jmp blank i - -" give skip return if AC *NOT* a command delimiter -" v1 routine name: -delim: 0 - sad o12 " newline - jmp delim i - sad o46 " ampersand - jmp delim i - sad o73 " semi - jmp delim i - isz delim " ran the gauntlet: skip home - jmp delim i - -" from cat.s -getc: 0 - lac ipt " Load pointer to next word in the buffer - sad eipt - jmp 1f " end of the buffer, so read more - dac 2f " Save the pointer - add o400000 " flip MSB, increment pointer on overflow - dac ipt - ral " Move the msb into the link register - lac 2f i " Load the word from the buffer - szl " Skip if second character in word - lrss 9 " first char: shift down the top character - and o177 " Keep the lowest 7 bits - sna - jmp getc+1 " Skip a NUL characters and read another one - jmp getc i " Return the character from the subroutine - -1: - cla " Buffer is empty, read another 64 characters - sys read; ibuf; 64 - sna - jmp 1f " No characters were read in - tad iipt " Add the word count to the base of the buffer - dac eipt " and store in the end buffer pointer - lac iipt " Reset the ipt to the base of the buffer - dac ipt - jmp getc+1 " and loop back to get one character -1: - lac o4 " No character, return with ctrl-D - jmp getc i " return from subroutine - -putc: 0 - and o177 " Keep the lowest 7 bits and save into 2f+1 - dac 2f+1 - lac opt " Save the pointer to the empty buffer - dac 2f " position to 2f - add o400000 " Flip the msb and save back into opt - dac opt " This also has the effect of incrementing - " the opt pointer every second addition! - - spa " If the bit was set, we already have one - jmp 1f " character at 2f+1. If no previous character, - lac 2f i " merge the old and new character together - xor 2f+1 - jmp 3f " and go to the "save it in buffer" code -1: - lac 2f+1 " Move the character up into the top half - alss 9 -3: - dac 2f i " Save the word into the buffer - jmp putc i " No, so return (more room still in the buffer) - -2: 0;0 " Current input and output word pointers -ipt: 0 " Current input buffer base -eipt: 0 " Pointer to end of data read in input buffer -iipt: ibuf -ibuf: .=.+64 - -" literals -d1: 1 -d2: 2 -o4:d4: 4 -o12: 012 " newline -o17: 017 -o40: 040 " space -o46: 046 " ampersand -o73: 046 " semi -o74:lt: 074 " < -o76:gt: 076 " > -o177: 0177 " 7-bit (ASCII) mask -o400000: 0400000 " MSB - -hash: <#> " superuser prompt -qmnl: ;;; 040040 - -exectemp: - ;;; " temporary link for file being exec'ed - -chdirstr: - ;; " - -toomany: ; ;;;< a>;; " v1 prompt -pid: 0 " "other" pid -char: 0 " white space char -redirect: 0 " last file was a redirect (lt or gt) -bcount: 0 " byte counter for current filename -delimchar: 0 " character that terminated line - -iopt:argv0p: argv0 " initial value for nextarg, opt -nextarg: 0 " next slot in argv to fill -opt: 0 " "output pointer" (may point to in/outfile) - -infilep: infile -outfilep: outfile - -outfile: .=.+4 " buffer for output redirect file name -infile: .=.+4 " buffer for input redirect file name - -argcptr: argc - -" leave room for maxargs items of 4 words each -maxargs=8 - -userbase=010000 " user starts at 4K -argptr=017777 " last word points to argc + argv data -argc=argptr-maxargs-maxargs-maxargs-maxargs-1 " argc followed by argv - -" arguments in 4 word blocks follow argc -argv0=argc+1 - -" "bootstrap" (reads executable into userbase) JUST below argc -bootloc=argc-bootlen " location of bootstrap - -userlen=bootloc-userbase " max executable - From 1033fa24bf0ee283172c6860ab1b4e1e0e712746 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 16:12:55 -0500 Subject: [PATCH 2/8] update comment for TTY inter char (ALT MODE key?) --- src/sys/s7.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/s7.s b/src/sys/s7.s index 81034bb..27f1139 100644 --- a/src/sys/s7.s +++ b/src/sys/s7.s @@ -114,7 +114,7 @@ dsprestart: isz ttydelay krb " read keyboard buffer dac char " save in char - sad o375 " interrupt char ('}'?) + sad o375 " interrupt char (TTY ALT MODE?) jmp intrp1 " yes lac d1 jms putchar From a80e2afda78d266687512a0c8f1387d7a9ba36bc Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 16:13:42 -0500 Subject: [PATCH 3/8] update comments for "passone" (return one character from special device) --- src/sys/s3.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sys/s3.s b/src/sys/s3.s index 2947c11..45be20e 100644 --- a/src/sys/s3.s +++ b/src/sys/s3.s @@ -356,12 +356,12 @@ wppto: jms swap jmp wppto - " common exit for special file + " common exit for special file input passone: - sad o4000 - jmp okexit - dac u.base i - lac d1 + sad o4000 " CTRL/D? + jmp okexit " yes: return zero + dac u.base i " no: save for user + lac d1 " return 1 dac u.ac jmp sysexit From e18a74300e0a85dc07ec78f24d023c0558bcae2e Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 17:18:36 -0500 Subject: [PATCH 4/8] pbsh.s: add @/# handling from init.s --- src/other/pbsh.s | 250 +++++++++++++++++++++++++---------------------- 1 file changed, 131 insertions(+), 119 deletions(-) diff --git a/src/other/pbsh.s b/src/other/pbsh.s index 87d4f44..af7ea75 100644 --- a/src/other/pbsh.s +++ b/src/other/pbsh.s @@ -1,53 +1,73 @@ " -*-fundamental-*- -" sh -- a shell +" pbsh -- a shell " started by p budne 3/4/2016 -" with code from cat.s, init.s, and looking at the v1 (pdp-11) shell +" with code from init.s, cat.s and looking at the v1 (pdp-11) shell -" XXX cat.s seems to write error output on fd 8 +" In particular, the newline/newcom/newarg/newchar processing loop(s) +" are copied from the v1 shell: +" redirection must occur at the start of a name (after whitespace) -start: -" XXX take command line argument (script file to open), suppress prompt?? -" NOTE!!! v0 init.s doesn't set up the argv at the top of memory, -" so the v0 shell may not have taken command line arguments!!! -" if non-interactive, "dzm prompt", jump to newcom +" includes ';' and '&' (unknown if available in v0 shell) +" does NOT (yet) include quoting (backslash or single quote) +" no "globbing" (performed by /etc/glob in v1 shell) -interactive: - -1 +" v0 cat.s seems to write error output on fd 8, *BUT* shell doesn't +" know what device is on stdout (passed by init, and init doesn't pass +" fd 8), and there isn't a "dup" call, nor does init appear to be an +" "indirect" device like /dev/tty, nor does init make an equivalent link!! + +" Arguments for new processes are located at the end of memory. +" Location 17777 points to a word with the argument count (argc), +" followed by blocks of four words with (filename) arguments. +" Currently leave room for ONLY maxargs items. +maxargs=8 + +" v1 shell expects "-" as argument from init or login, will read +" filename passed as argument. *BUT* v0 init.s doesn't set up the +" argv at the top of memory, so the v0 shell may not have taken +" command line arguments!!! + + lac d1 sys intrp " make shell uninterruptable sys getuid sma " <0? - jmp newline " no, a mundane + jmp newline " no lac hash " yes: superuser dac prompt " change prompt newline: lac d1; sys write; prompt; 1 " output prompt + jms rline " read line into ibuf + lac iipt + dac ipt newcom: dzm char " clear saved char dzm infile " clear input redirect file name dzm outfile " clear output redirect file name - lac iopt " reset output pointer + lac iopt " reset output buffer pointer dac opt dac nextarg " reset high memory dzm argc " clear arg count - lac argcptr + lac argcptr " (re) set arg pointer dac argptr dzm argv0 " clear out argv0 for chdir comparison dzm argv0+1 dzm argv0+2 +" NOTE! behavior copied from v1 shell!!! +" "improvements" here may be non-historic!! newarg: -8 " save 8 chars dac bcount - dzm redirect + dzm redirect " clear redirect flag lac opt " save start for print (TEMP) dac nextarg jms blank " skip whitespace - jms delim " newline? + jms delim " command sep? jmp eol " yes sad lt " input redirect? jmp redirin @@ -59,19 +79,18 @@ redirin: " saw < dac redirect " flag redirect lac infilep dac opt - jmp newchar " v1 behavior? no whitespace eater + jmp newchar redirout: " saw > dac redirect " flag redirect lac outfilep dac opt - " v1 behavior? no whitespace eater! " fall newchar: jms getc sad o40 " space? - jmp ws " yes + jmp eoname " yes jms delim jmp eoname 3: jms putc " save @@ -81,22 +100,16 @@ newchar: " here after 8 chars: discard until terminator seen discard: jms getc - dac char - sad o4 - jmp eof jms delim " end of line? jmp eoname sad o40 jmp eoname jmp discard -" here with EOF in command: process command? -eof: - sys exit " quit, for now? - -" name ended (short) with whitespace or newline +" name ended (short) with whitespace or delim " pad out last name to 8 with spaces -ws: +" XXX check if ANYTHING read +eoname: dac char " save terminator 1: lac o40 jms putc " no: copy into argv @@ -104,9 +117,7 @@ ws: jmp 1b " saw end of name -eoname: - dac char - lac redirect +2: lac redirect sza jmp 2f " last name was a redirect file, skip increment @@ -126,10 +137,10 @@ eoname: jms delim jmp eol - -maxargs - tad argc - sza - jmp newarg + lac argc + sad maxargwords + skp + jmp newarg " too many args, (complain?). for now eat rest of line 4: jms getc @@ -160,69 +171,66 @@ eol: jmp changedir 1: -" comment these out to test "exec" +" comment these out to test "exec" w/o fork sys fork jmp parent -" here in child - lac d2; sys close " close fd 2 - sys unlink; exectemp " remove temp file + sys open; argv0; 0 " try cwd (no link required) + sma + jmp 1f + jmp cmderr -" try to link binary from "system" directory to "exectemp" file +" sys unlink; exectemp " remove old temp file, if any " sys link; system; argv0; exectemp " spa -" jmp notsys +" jmp cmderr " sys open; exectemp; 0 " spa -" jmp error +" jmp cmderr +" dac cmdfd " sys unlink; exectemp -" jmp 1f -"notsys: " not found in "system" - - sys open; argv0; 0 " try cwd - spa - jmp cmderr +" skp +1: dac cmdfd " save command file descriptor cla " check for input redirection - sad infile - jmp 1f + sad infile " input redirct? + jmp 1f " no sys close " close fd 0 sys open; infile; 0 " open redirected spa sna - jmp inerror + jmp inerror cla -1: sad outfile - jmp exec +1: sad outfile " output redirec? + jmp exec " no lac d1; sys close " close fd 1 - lac o17 - sys creat; outfile " open output redirect + lac o17; sys creat; outfile " open output redirect spa - jmp outerror + jmp outerror -" here to "exec" file open on fd 2, adapted from init.s +" here to "exec" file open on cmdfd, adapted from init.s exec: law boot-1 " Get source addr - dac 8 " set up index 8 (pre-increments) + dac 8 " set up index (pre-increments) law bootloc-1 " Copy "boot" code into high memory - dac 9 " set up index 9 (pre-increments) + dac 9 " set up index + -bootlen " isz loop count for bootstrap copy + dac bootcount 1: lac 8 i dac 9 i isz bootcount " can only do this once! jmp 1b + lac cmdfd " get fd for the executable + lmq " Save the fd into MQ jmp bootloc " and then jump to the code " copied up to bootloc in high memory (below argc) boot: - lac d2 " Load fd 2 (the opened executable) - lmq " Save the fd into MQ sys read; userbase; userlen " read executable in lacq " Get the fd back and close the file - sys close + sys close " close command file jmp userbase " and jump to the beginning of the executable bootlen=.-boot " length of bootstrap -bootcount: -bootlen " isz loop count for bootstrap copy - " error in child process: inerror: " error opening input redirection lac infilep @@ -236,7 +244,7 @@ error: " error in child: filename pointer in AC dac 1f " save filename to complain about lac d1; sys write; 1: 0; 4 lac d1; sys write; qmnl; 1 - lac d2; sys close + lac d2; sys close " close executable, if any sys exit " chdir command: executed in shell process @@ -306,46 +314,48 @@ delim: 0 isz delim " ran the gauntlet: skip home jmp delim i -" from cat.s +" get character from ibuf getc: 0 - lac ipt " Load pointer to next word in the buffer - sad eipt - jmp 1f " end of the buffer, so read more - dac 2f " Save the pointer - add o400000 " flip MSB, increment pointer on overflow - dac ipt - ral " Move the msb into the link register - lac 2f i " Load the word from the buffer - szl " Skip if second character in word - lrss 9 " first char: shift down the top character - and o177 " Keep the lowest 7 bits - sna - jmp getc+1 " Skip a NUL characters and read another one - jmp getc i " Return the character from the subroutine + lac ipt i " fetch char + isz ipt " increment pointer + jmp getc i +" from init.s rline: read line from tty into ibuf +" (store one character per word) +rline: 0 + law ibuf-1 " Store ibuf pointer in location 8 + dac 8 1: - cla " Buffer is empty, read another 64 characters - sys read; ibuf; 64 - sna - jmp 1f " No characters were read in - tad iipt " Add the word count to the base of the buffer - dac eipt " and store in the end buffer pointer - lac iipt " Reset the ipt to the base of the buffer - dac ipt - jmp getc+1 " and loop back to get one character -1: - lac o4 " No character, return with ctrl-D - jmp getc i " return from subroutine + cla; sys read; char; 1 " Read in one character from stdin + sna " read ok? + sys exit " EOF: quit + lac char + lrss 9 " Get it and shift down 9 bits + sad o100 " '@' (kill) character? + jmp rline+1 " yes: start from scratch + sad o43 " '#' (erase) character? + jmp 2f " yes: handle below + + dac 8 i " Store the character in the buffer + sad o12 " Newline? + jmp rline i " yes: return + jmp 1b " no: keep going +2: + law ibuf-1 " # handling. Do nothing if at start of the buffer + sad 8 + jmp 1b " and loop back + -1 + tad 8 " Otherwise, move the pointer in location 8 back one + dac 8 + jmp 1b " and loop back putc: 0 and o177 " Keep the lowest 7 bits and save into 2f+1 dac 2f+1 - lac opt " Save the pointer to the empty buffer - dac 2f " position to 2f - add o400000 " Flip the msb and save back into opt - dac opt " This also has the effect of incrementing - " the opt pointer every second addition! - + lac opt " get output buffer pos + dac 2f " save + add o400000 " Flip the msb (advance) and save back into opt + dac opt spa " If the bit was set, we already have one jmp 1f " character at 2f+1. If no previous character, lac 2f i " merge the old and new character together @@ -358,11 +368,7 @@ putc: 0 dac 2f i " Save the word into the buffer jmp putc i " No, so return (more room still in the buffer) -2: 0;0 " Current input and output word pointers -ipt: 0 " Current input buffer base -eipt: 0 " Pointer to end of data read in input buffer -iipt: ibuf -ibuf: .=.+64 +2: 0;0 " pointer, char " literals d1: 1 @@ -371,10 +377,12 @@ o4:d4: 4 o12: 012 " newline o17: 017 o40: 040 " space +o43: 043 " # o46: 046 " ampersand o73: 046 " semi o74:lt: 074 " < o76:gt: 076 " > +o100: 0100 " @ o177: 0177 " 7-bit (ASCII) mask o400000: 0400000 " MSB @@ -396,29 +404,34 @@ star: <*> " toomany: ; ;;;< a>;; " v1 prompt -pid: 0 " "other" pid -char: 0 " white space char -redirect: 0 " last file was a redirect (lt or gt) -bcount: 0 " byte counter for current filename -delimchar: 0 " character that terminated line - -iopt:argv0p: argv0 " initial value for nextarg, opt -nextarg: 0 " next slot in argv to fill -opt: 0 " "output pointer" (may point to in/outfile) +maxargwords: maxargs+maxargs+maxargs+maxargs +argcptr: argc infilep: infile outfilep: outfile +iipt: ibuf +iopt:argv0p: argv0 " initial value for nextarg, opt + +" ################ variables + +prompt: <@ 040 " v1 prompt! + +redirect: .=.+1 " last file was a redirect (lt or gt) +nextarg: .=.+1 " next slot in argv to fill +bcount: .=.+1 " byte counter for current filename +opt: .=.+1 " "output pointer" (may point to in/outfile or into argv) +delimchar: .=.+1 " character that terminated line +char: .=.+1 " char that terminated word + outfile: .=.+4 " buffer for output redirect file name infile: .=.+4 " buffer for input redirect file name +pid: .=.+1 " "other" pid +cmdfd: .=.+1 " fd for executable +bootcount: .=.+1 " loop count for "boot" copy -argcptr: argc - -" leave room for maxargs items of 4 words each -maxargs=8 +ipt: .=.+1 " input buf pointer +ibuf: " input line stored here, one character per word userbase=010000 " user starts at 4K argptr=017777 " last word points to argc + argv data @@ -431,4 +444,3 @@ argv0=argc+1 bootloc=argc-bootlen " location of bootstrap userlen=bootloc-userbase " max executable - From 38ff8aec09db5184a6cd6db5cbfc3d47c3bbf43f Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 17:27:31 -0500 Subject: [PATCH 5/8] a7out: changes for shell handle "ptr" format executable files tty read always returns only one character add shell-compatible "smes" behavior --- tools/a7out | 74 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/tools/a7out b/tools/a7out index ca0c398..a80f1a7 100755 --- a/tools/a7out +++ b/tools/a7out @@ -81,6 +81,18 @@ sub load_code { # Open up the PDP-7 executable file open( my $IN, "<", $filename ) || die("Unable to open $filename: $!\n"); + my $c = getc($IN); + seek $IN, 0, 0; + if ((ord($c) & 0300) == 0200) { # handle "binary paper tape" format + my $addr = 010000; # user programs loaded at 4K mark + while ($addr <= 017777) { + my $result = read_word($IN); + last if ($result == -1); + $Mem[$addr++] = $result; + } + close($IN); + return; + } while (<$IN>) { chomp; @@ -98,6 +110,18 @@ sub load_code { close($IN); } +### read a word from a file in paper tape binary format +### return -1 on EOF +sub read_word { + my $F = shift; + # Convert three bytes into one 18-bit word + return -1 if ( read( $F, my $three, 3 ) != 3 ); # Not enough bytes read + my ( $b1, $b2, $b3 ) = unpack( "CCC", $three ); + return ((($b1 & 077) << 12 ) | + (($b2 & 077) << 6 ) | + ($b3 & 077)); +} + ### Copy the arguments into the PDP-7 memory space, and build ### an array of pointers to these arguments. Build a pointer ### at MAXADDR that points at the array. @@ -711,16 +735,19 @@ sub sys_fork { return; } -# Smes system call. Because we fake rmes with wait(), -# there is no need for sms. When the child does -# sys exit, that's going to wake wait() up and do the -# rmes anyway. +# shell depends on smes hanging while child process exists +" https://www.bell-labs.com/usr/dmr/www/hist.html +" The message facility was used as follows: the parent shell, after +" creating a process to execute a command, sent a message to the new +" process by smes; when the command terminated (assuming it did not +" try to read any messages) the shell's blocked smes call returned an +" error indication that the target process did not exist. Thus the +" shell's smes became, in effect, the equivalent of wait. sub sys_smes { - - # For now, do nothing - dprintf("smes system call\n"); + waitpid($AC,0); + dprintf("smes returning error\n"); + $AC = -1; $PC += 1; - return; } # Rmes system call. We simply call wait and @@ -927,34 +954,35 @@ sub sys_read { # Read each word in my $FH = $FD[$fd]; $count = 0; - my $tty = -t $FH; + if (-t $FH) { # TTY? + my $char = getc($FH); # use Term::ReadKey for 'cbreak' mode?? + if (defined($char)) { + $Mem[$start] = ord($char) << 9; # only ever returns one char + $AC = 1; + } + else { + $AC = 0; # EOF + } + return; + } 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 & 077) << 6 ) | - ($b3 & 077)); + my $result = read_word($FH); + last if ($result == -1); + $Mem[$addr] = $result; $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 $word = ord($c1) << 9; - if ( !$tty || $c1 ne "\n") { - $c2 = getc($FH); - if (defined($c2)) { - $word |= ord($c2); - } - } + my $c2 = getc($FH); + $word |= ord($c2) if (defined($c2)); $Mem[$addr] = $word; $count++; - last if ($tty && (($c1 && ($c1 eq "\n")) || ($c2 &&($c2 eq "\n")))); } # ascii } From 5f735f6ba4c15531fafb15d73160475d485e8907 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 17:29:23 -0500 Subject: [PATCH 6/8] 3dump: handle 0200 bit set on all "frames" --- tools/3dump | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/3dump b/tools/3dump index 60bfe89..dfbf321 100755 --- a/tools/3dump +++ b/tools/3dump @@ -14,7 +14,7 @@ while (1) { my $result= read($IN, my $three, 3); last if ($result != 3); # Not enough bytes read my ($b1, $b2, $b3)= unpack("CCC", $three); - my $word= (($b1 & 077) << 12) | ($b2 << 6) | $b3; + my $word= (($b1 & 077) << 12) | (($b2 & 077) << 6) | ($b3 & 077); my $c1= ($word >> 9) & 0777; $c1= ($c1 < 0200) ? chr($c1) : " "; From b871c2214d3733fc6e06bda82fa89c87c429ac61 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 17:55:13 -0500 Subject: [PATCH 7/8] as.s: add missing line, found by Warren --- scans/as.s | 1 + 1 file changed, 1 insertion(+) diff --git a/scans/as.s b/scans/as.s index 6d2398f..78a7981 100644 --- a/scans/as.s +++ b/scans/as.s @@ -148,6 +148,7 @@ init: 0 dac fname -1 dac eofflg + jms nextfil jms ioinit dzm savchr dzm comflg From 9c8cc278a466de913c7fae0169da2f923f00ced4 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 7 Mar 2016 17:58:09 -0500 Subject: [PATCH 8/8] fix smes comment block (copied from pbsh.s) --- tools/a7out | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/a7out b/tools/a7out index a80f1a7..40dd796 100755 --- a/tools/a7out +++ b/tools/a7out @@ -736,13 +736,13 @@ sub sys_fork { } # shell depends on smes hanging while child process exists -" https://www.bell-labs.com/usr/dmr/www/hist.html -" The message facility was used as follows: the parent shell, after -" creating a process to execute a command, sent a message to the new -" process by smes; when the command terminated (assuming it did not -" try to read any messages) the shell's blocked smes call returned an -" error indication that the target process did not exist. Thus the -" shell's smes became, in effect, the equivalent of wait. +# https://www.bell-labs.com/usr/dmr/www/hist.html +# The message facility was used as follows: the parent shell, after +# creating a process to execute a command, sent a message to the new +# process by smes; when the command terminated (assuming it did not +# try to read any messages) the shell's blocked smes call returned an +# error indication that the target process did not exist. Thus the +# shell's smes became, in effect, the equivalent of wait. sub sys_smes { waitpid($AC,0); dprintf("smes returning error\n");