From dd476901a5a519a228777659faff3bb58c592043 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Mon, 7 Nov 2016 13:53:19 +0100 Subject: [PATCH] XXFILE source code and documentation. --- doc/README.md | 1 + doc/_info_/xxfile.info | 166 +++ src/sysen1/xxfile.mta224 | 2696 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 2863 insertions(+) create mode 100755 doc/_info_/xxfile.info create mode 100755 src/sysen1/xxfile.mta224 diff --git a/doc/README.md b/doc/README.md index 03fb1716..bebdf0fa 100644 --- a/doc/README.md +++ b/doc/README.md @@ -15,6 +15,7 @@ - CRTSTY: [manual](info/crtsty.39) - FIND: [manual](info/find.13) - DIRED: [manual](_info_/dired.info), [commands](_info_/dired.order) +- XXFILE: [manual](_info_/xxfile.info) ### Programming diff --git a/doc/_info_/xxfile.info b/doc/_info_/xxfile.info new file mode 100755 index 00000000..bcec965f --- /dev/null +++ b/doc/_info_/xxfile.info @@ -0,0 +1,166 @@ +XXFILø£E  XXFILE is a program which is similar in concept to the XFILE +command of ddt: one has a file of commands which is executed +frequently. The distinction is that XXFILE command files can pass +control of the tty around from place to place, a property which the +xfile command does not possess. + XXFILE operates by opening a STY, logging it in, and feeding +the command file(s) through it. Thus, as far as the programs being run +are concerned, it is exactly as if they were receiving input from the +tty. Input is supplied (with one exception) when the program on the +other end requests it, at which time XXFILE sends characters from the +file until it has sent an interrupt or activation character. Output +(including echoing, since the connection is full-duplex) may be directed +to the tty, to a file, or to the bit bucket; regardless of that, it is +possible to specify various strings (initially '*ERROR*', '?U?', and +'??') which will cause an error when encountered in the output. Errors +may also be generated when a fatal error is encountered. + When errors are encountered, the file being executed is +suspended and input is taken from the tty (except see the 'E' switch +under JCL). In this case, the connection is similar to that supplied by +SUPDUP. It is also possible to start tty input manually during the +execution of a file, or to specify that tty input begin in the command +file itself--xxfile commands may be included in the command file, where +they are treated exactly as if they were entered from the tty. + + Note that when XXFILE starts it sets its ..SAFE variable to -1: +attempts to kill one, or to log out while it is running, will provoke +the --Kill Protected Job-- query from DDT. + +JCL: + Three things may be specified on the jcl line, in any order: +switches, the output file, and the input files. Switches are letters +preceded by a '/'; there are currently three switches: +E: If this switch was set, and an error is encountered while XXFILE is + running disowned (has no console), then it will print any error + messages to the output file (if one exists) and logout. Normally, + it will attempt to use the TTY, thereby hanging up. +P: If this switch is set, the terminal seen by the programs you're + running is just a printing console, rather than whatever you're + running on. +S: If set, XXFILE will keep trying if it gets a DEVICE FULL error when + it tries to open its STY. In particular, it will try every ten + seconds for an hour before it gives up. This is primarily useful + for jobs running under BATCHN on DM, for example, since the user may + not be around to make a STY available. +The output file (which defaults to the bit bucket) is a file name +followed by '_'; the default name is ; >. Input files may +be either file names, separated by commas, or text strings, which are +treated as files. Text strings should be enclosed in square brackets; +control characters may be included by using ; the +characters '^' and ']' may be quoted with ctrl-Q. Thus: +:xxfile tty:_[:muddle^m]taa;foo bar,taa;zork feep[] +will direct output to the tty; input will be +:muddle +followed by the contents of foo bar and zork feep, followed by . + If no sname is provided for input files, your sname is assumed; +defaults are sticky from one input file to the next. + + Before any of the jcl line is executed, the following string is +sent: +0U:GAG 0 +This logs the tty in, and causes :sends to be refused. The tty is also +put in refuse mode. When the jcl line has finished executing, 0U is +sent to log the tty out. + +Commands + Commands may be included in files to be executed or typed in +from the tty. In either case, they are of the form +. If +a command requires a command line, it must be terminated in the file +with . The intercept character is initially ctrl-^. + When commands are typed from the tty, erases the last +character, ctrl-W erases the last word, and ctrl-X, ctrl-U, and ctrl-@ +erase the entire command line. Attempts to rubout past the beginning of +the command line abort the command. +Commands currently implemented are: +A--Abort the current input source. The current file or text field is + flushed, and execution proceeds with the next part of the jcl line. +B--Begin tty input. Suspend execution of the current file, and accept + input from the tty until an 'S' command is given. This command is + executed implicitly when an error is detected and when the 'H' + command is given. +C--Change output file. Takes the new output file as a command line. + The current output file is closed, and output is directed to the + specified location. +D--Return to ddt (like ctrl-Z). +E--Error strings. Takes 0-n error strings, separated by commas, as a + command line. Initially the error strings are '*ERROR*', '?U?', and + '??'. Checking for errors may be disabled simply by giving this + command with a null command line. +F--Force input. Characters until the next 'F' command will be jammed + down the throat of the running job, whether it wants them or not. + Some jobs (PUB, for example) do not explicitly request input, but + read it at interrupt level. This command is for them. +H--Halt job. Sends ctrl-Z immediately, then does a 'B' command. +I--Set intercept character. Takes the new character on a command line, + as the first character. Note that this must be a control character + of some sort, so it will interrupt when typed. +J--Undo an 'R' command. +P--Proceed xxfile. +Q--Quit xxfile. +R--Remain in this job. All input must go to the current job until a 'j' + command is executed. This allows fatal errors (ioc's which aren't + handled, for example) to be detected. When the input source is the + tty, such checking is suppressed. +S--Stop tty input. Revert to the current input file. +T--Set ctrl-T character. See 'Job status'. +V--Valret string. This reads a line from the current input source, and + does a .value of it. Control characters (cr, for example) may be + included by giving uparrow followed by the normal character: ctrl-M + as uparrow (^) followed by M. +?--Give brief command summary. + + The intercept character may be sent by quoting it with the +intercept character. The ctrl-T character is only noticed when typed on +the tty; it may be sent by quoting with the intercept character also. +Rubout is a null command. + +The tty + Unless the P switch is set in the jcl line, the tty your jobs +see will be a software tty very similar to the one you are using--the +major difference is that the screen is slightly smaller. The P switch +causes the tty to be the default sty, which is a printing terminal 72 +columns wide. + When the input source is the tty, or output is to the tty, all +abnormal output from XXFILE is printed in a two-line echo area, to +preserve the display of output from the program. It also tries to keep +the cursor on your tty in phase with the cursor on your job's tty. + +TTY input + When the input source is the tty, XXFILE enters super-image +input mode, meaning that ctrl-Z and ctrl-_ are treated as normal input +characters. Should you need to get out of xxfile, the D command may be +used; also, ctrl-Z and ctrl-_ may be typed as commands, since +super-image input is turned off in the command reader. + Since the foreign tty is similar to your own, rubouts and such +will be handled correctly. It is, in fact, possible to run real-time +teco through xxfile, though I know of no good reason for doing so. + +Job status + Ctrl-T typed from the tty causes a brief summary of your job's +status to be printed, either in the echo area (if XXFILE is using the +tty for output) or on the next line. The summary includes: +Tnn mm jname sname status % timusd %RD lastout +Where: +Tnn is the tty your jobs are running on. +mm is the index of the job currently having the tty. +jname is its jname +sname is its sname +status is like PEEK's: WALK, RUN, FLY, &c, or the reason the job is not + currently running. This may be preceded by '=>', '<=', or '<=>'; + these mean, respectively, that XXFILE is currently sending characters + to your job, receiving characters from it, or both. +% is the percentage of the system your job is getting +timusd is the amount of cpu time it has used so far. +%RD is the percentage of the current input file that has been used. +lastout is the first 10 or 15 characters of the last group sent to the + job. If the job is a ddt, which activates on every character, this + will only be one character, the last one sent; if it is a muddle, it + may be an entire form. + +Cautions + MUDDLEs, at least, are known to hang up occasionally when +talking to a sty. As nearly as I can determine, this is a timing +problem in the system. You can win, usually, by entering tty input mode +(the 'B' command), typing ctrl-Z, ctrl-P, and P, then leaving tty input +(the 'S' command). \ No newline at end of file diff --git a/src/sysen1/xxfile.mta224 b/src/sysen1/xxfile.mta224 new file mode 100755 index 00000000..a9b9be78 --- /dev/null +++ b/src/sysen1/xxfile.mta224 @@ -0,0 +1,2696 @@ +TITLE NX + +O=0 +A=1 +B=2 +C=3 +D=4 +E=5 +F=6 +G=7 + +T=15 ; CONTAINS NUMBER OF STY +U=16 ; USER INDEX, USED IN STATUS CODE +P=17 + +.xcref O,A,B,C,D,E,F,G,P + +DSKI==0 ; FILE INPUT +OUTCHN==1 ; NON-INTERACTIVE OUTPUT +TTYI==2 ; TTY INPUT +TTYO==3 ; TTY OUTPUT +ECHO==4 ; ECHO AREA OUTPUT (COMMANDS) +STYI==5 ; STY INPUT +STYO==6 ; STY OUTPUT + +; DEVICE CODES USED +SNTTY==1 +SNTDS==2 +SNSTY==25 + +; BLOCKS ON INPUT CHAIN +OUTBLK==6 ; LENGTH OF BLOCK +OUTNXT==0 ; NEXT BLOCK ON CHAIN +OUTTYP==1 ; TYPE +OUTLEN==2 ; LENGTH +OUTPTR==3 ; BYTE POINTER +OUTTLN==4 ; TOTAL LENGTH OF SOURCE +OUTRED==5 ; NUMBER OF CHARS READ SO FAR + +; TYPES FOR BLOCKS +$TFILE==1 +$TTEXT==2 + +; OFFSETS INTO FILE NAME BLOCKS +DEV==0 +SNM==1 +FN1==2 +FN2==3 + +; OFFSETS INTO ERROR STRING BLOCKS +ERRBLK==5 ; LENGTH OF BLOCK +ENEXT==0 ; NEXT BLOCK IN CHAIN OR 0 +EMATCH==1 ; NEXT CHAR TO BE MATCHED +EMATLN==2 ; # OF CHARACTERS LEFT TO MATCH +ESTRING==3 ; BEGINNING OF STRING +ELENGTH==4 ; LENGTH OF STRING + +; DECREMENT BYTE POINTER +DEFINE DBP AC + ADD AC,[70000,,] + TLNE AC,400000 + ADD AC,[347777,,-1] +TERMIN + +LOC 40 + 0 + JSR UUOH + -TSINTL,,TSINT +LOC 100 + +UUOERR==1 ; WE WANT AN ERROR UUO +.INSRT TAA;UUOS > + +; BLOCKS +PDLLEN==200 +PDL: BLOCK PDLLEN +INBLEN==50 +INPBUF: BLOCK INBLEN +INPBU1: BLOCK INBLEN +DBUFLN==50 +DSKBUF: BLOCK DBUFLN +JCLBUF: BLOCK 50 +TTYBUF: BLOCK 50 +STTBUF: BLOCK 50 ; BUFFER FOR STATUS LINE + +; VARIABLES +XUNAME: 0 +SNAME: 0 +HSNAME: 0 +FILFIL: 0 ; BLOCK FOR PARSING INPUT FILE NAMES + 0 + 0 + 0 +FILFDF: SIXBIT /DSK/ + 0 + 0 + SIXBIT />/ +OUTFIL: SIXBIT /NUL/ + SIXBIT /HUDINI/ + 0 + SIXBIT />/ +OUTFDF: SIXBIT /NUL/ + SIXBIT /HUDINI/ + 0 + SIXBIT />/ +CDEFAU: 0 +SYSVER: 0 ; VERSION OF SYSTEM INITIALIZED IN +IERRST: 0 ; LIKE ERRSTK, FOR INPUT FAILURE ERRORS +ERRSTK: 0 ; IF NON-ZERO, SET P TO THIS AND DO + ; .CALL DISMIS AFTER ERROR +STIFLG: 0 ; IF -1, READING FROM STY +STOFLG: 0 ; IF -1, WRITING TO STY +LSTLEN: 0 +LSTPTR: 0 +LSTTMP: 0 +LSTOLN==4 +LSTOUT: BLOCK LSTOLN +LSTBUF: BLOCK 2*LSTOLN ; STUFF FOR CTRL-T +ESCAPE: ^^ ; ESCAPE CHARACTER +CTRLT: ^T ; STATUS CHARACTER +PRSW: 0 ; IF -1, LEAVE STY AS PRINTING TERMINAL +COMGLN: 0 ; FIRST ARG TO COMND--GET LINE +COMPRT: 0 ; SECOND ARG--PRINT CRAP +ECHOQ: 0 ; -1 IF ECHO AREA SET UP +TTYQ: 0 ; -1 IF TTY OPEN +TTYOPT: 0 ; TTY OPTION WORD FOR OUR TTY +TOERS: 0 ; SET FROM TTYOPT BY GETLIN +ECCPOS: 0 ; SET BY GETLIN--USED FOR FLUSHING ENTIRE LINE +CTTST1: 0 +CTTST2: 0 +CTTSTS: 0 ; CURRENT TTYGET SETTINGS +SIIFLG: 0 ; USED TO CAUSE RESUMPTION OF SII AFTER COMMAND +NTTST1: 030202,,020202 ; NORMAL CASE IS TO INTERRUPT ONLY ON +NTTST2: 030202,,020202 ; CTRLS, ACTIVATE ON EVERYTHING +TTTST1: 030303,,030303 ; WHEN IN TTY INPUT, EVERYTHING INTERRUPTS +TTTST2: 030303,,030303 +STYST1: 0 +STYST2: 0 ; TTYSTn WORDS FOR STY +STHIGH: 0 ; HEIGHT OF STY SCREEN +STVPOS: -1 ; VERTICAL POSITION (ONLY IF OUTPUT TO FILE) +STHPOS: 0 ; HORIZONTAL POSITION +INPSRC: 0 ; POINTER TO CHAIN OF INPUT BLOCKS +JOBFRC: 0 ; IF NON-ZERO, # OF JOB ALL INPUT MUST GO TO +FILOPQ: 0 ; FILE SPECIFIED BY CURRENT BLOCK IS OPEN +CTRLM: 0 ; LAST CHAR 'SENT' WAS CTRL-M +FORCSW: 0 ; IF -1, OUTPUT SHOULD BE FORCED +FORCTM: 0 ; USED IN SNDCOM FOR SPECIAL HACK W/ FORCE SWITCH +LSTBLK: 0 + 0 + 4 + 440700,,[ASCII /0U/] ; LAST BLOCK TO BE SENT--LOG OUT + 4 + 0 + +CINPLN: 0 ; # CHARACTERS GOBBLED FROM STYI +DSKOUT: 0 ; OUTPUT TO NORMAL DEVICE (OUTCHN) +TTYSRC: 0 ; READING FROM TTY, SO PRINT THERE +DSKCHN: 0 ; OUTCHAN IS TTY-TYPE (0) OR DSK (-1) +NULOUT: -1 ; NO OUTPUT CHANNEL (INCLUDING TTY) +NOCNSL: 0 ; SET -1 BY ERROR UUO IF NO CONSOLE WHEN RUNS +CNSFLS: 0 ; IF E SWITCH--DIE IF ERROR AND NO TTY +STYTRY: 0 ; IF 0, TRY MANY TIMES TO OPEN STY WHEN DEV FULL +ERESET: 0 ; SET BY SENDIT--RESET ALL ERROR STRINGS +ERRORS: DEFER1 ; INITIALLY LOOK FOR *ERROR* AND ?U? +DEFER1: DEFER2 + 440700,,[ASCII /*ERROR*/] + 7 + 440700,,[ASCII /*ERROR*/] + 7 +DEFER2: DEFER3 + 440700,,[ASCIZ /?U?/] + 3 + 440700,,[ASCIZ /?U?/] + 3 +DEFER3: 0 + 440700,,[ASCII /??/] + 2 + 440700,,[ASCII /??/] + 2 + +START: MOVE P,[-PDLLEN,,PDL-1] + .RSYSI A, + CAME A,SYSVER + PUSHJ P,INIT + PUSHJ P,TTYOP1 ; OPEN TTY FOR READING, SET UP OPTION WORD,... + PUSHJ P,JCLHAK + PUSHJ P,STYOPN ; SET UP STY, CAUSE IT TO ASK FOR INPUT + MOVE B,[200000,,A] + MOVEI A,300. ; EVERY FIVE SECONDS + .REALT B, + JFCL ; PROBABLY NEVER SKIPS WITH THIS CALL... + JFCL + .HANG + +TTYSU: .SOPTIO,,A + .SMSK2,,[<1_TTYO>\<1_TTYI>\<1_STYO>\<1_STYI>] + .RXUNAM,,XUNAME + .RSNAME,,SNAME + .RHSNA,,HSNAME +TTYSUS: TTYSU-.,,TTYSU + +TTYOP1: SETZM TTYQ + .SUSET [.ROPTIO,,A] + TLNE A,OPTDDT + .VALUE [ASCIZ \..SAFE/-1 +P\] + TLO A, + MOVE B,TTYSUS + .SUSET B ; SET UP MASKS, READ XUNAME, SNAME, SET OPTION + MOVE B,SNAME + MOVEM B,SNM+FILFDF + MOVEM B,FN1+OUTFDF + MOVE B,HSNAME + MOVEM B,SNM+OUTFDF ; DEFAULT OUTPUT DIRECTORY + .SUSET [.RCNSL,,A] + JUMPL A,CPOPJ ; IF CNSL IS <0, IN A DAEMON'S TREE, SO FLUSH + SETOM TTYQ ; WE HAVE TTY + .CALL [SETZ + SIXBIT /OPEN/ + [.UAI,,TTYI] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE %LSFIL + .CALL [SETZ + SIXBIT /OPEN/ + [.UAO+%TJPP2+%TJMOR,,ECHO] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE %LSFIL + .CALL [SETZ + SIXBIT /CNSGET/ + MOVEI TTYI + MOVEM + MOVEM + MOVEM + MOVEM + SETZM TTYOPT] ; READ TTY OPTION WORD + .LOSE %LSSYS + .CALL [SETZ + SIXBIT /TTYGET/ + MOVEI TTYI + MOVEM A + MOVEM A + SETZM CTTSTS] + .LOSE %LSSYS + MOVE A,NTTST1 + MOVEM A,CTTST1 + MOVE A,NTTST2 + MOVEM A,CTTST2 + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYI + NTTST1 + SETZ NTTST2] ; SET UP TTY INTERRUPTS + .LOSE %LSSYS + POPJ P, + +SUBTTL STY INITIALIZATION +; OPEN STY, SET UP BITS TO BE SOMETHING LIKE OURS. WHEN DONE, CAUSE +; INTERRUPT ON STYO SO WE'LL BE LOGGED IN AND ALL. +STYOPN: PUSH P,A +STYOPC: .CALL [SETZ + SIXBIT /OPEN/ + [<10\.UAI>,,STYI] ; DON'T HANG ON INPUT + [SIXBIT /STY/] + [SIXBIT /STY/] + [SIXBIT /STY/] + SETZB A] ; ERROR CODE + JRST STYLOS + .CALL [SETZ + SIXBIT /OPEN/ + [.UAO,,STYO] ; HANG ON OUTPUT + [SIXBIT /STY/] + [SIXBIT /STY/] + SETZ [SIXBIT /STY/]] + .LOSE %LSFIL + .CALL [SETZ + SIXBIT /RFNAME/ + MOVEI STYO + SETZM A] ; 'Snn + .LOSE %LSSYS + LDB T,[300600,,A] + SUBI T,20 + IMULI T,10 + LDB A,[220600,,A] + ADDI T,-20(A) + ADD T,NFSTTY ; GET TTY NUMBER WE GOT + PUSHJ P,STYSET + SKIPE NULOUT + JRST PROCED + SKIPN TTYSRC ; CAN'T :PROCED IF TTY INPUT + SKIPN DSKCHN ; OR NON-DISK OUTPUT + JRST STYOP1 +PROCED: SKIPE TTYQ ; IF NO TTY, DON'T :PROCED + .VALUE [ASCIZ /:PROCED +/] +STYOP1: .SUSET [.SIIFPIR,,[<1_STYO>]] ; CAUSE IT TO ASK FOR INPUT + .SUSET [.SMASK,,[%PIRLT\%PIATY]] ; ENABLE WORD ONE INTERRUPTS + POP P,A + POPJ P, + +; HERE IF LOSSAGE OPENING STY +STYLOS: SKIPE STYTRY + SOSG STYTRY +STYLS1: .CALL [SETZ + SIXBIT /LOSE/ + [STYOPC,,%LSFIL] + SETZI STYOPC] ; REPORT LOSSAGE + CAIE A,%EFLDV ; ONLY IF DEVICE FULL ERROR + JRST STYLS1 + MOVEI A,<10.*30.> + .SLEEP A, + JRST STYOPC ; TRY AGAIN + +; SET UP STY'S BITS +STYSET: PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,E + SKIPE TTYQ ; IF NO TTY, THEN PRINTING TERMINAL + SKIPE PRSW ; OR IF USER GAVE /P SWITCH + JRST STYSE1 + MOVE A,TTYOPT + TRO A,%TPTEL ; TREAT CRLF AS CR (TELNET PROTOCOL) + MOVEI C,0 + DPB C,[$TPPLF,,A] ; NO PADDING OF LINE FEEDS + DPB C,[$TPPCR,,A] ; NO PADDING OF CR + DPB C,[$TPPTB,,A] ; NO PADDING OF TABS + TDZ A,[%TOMOR\%TORAW\%TOHDX,,%TPCBS\%TPORS] + .CALL [SETZ + SIXBIT /RSSIZE/ + MOVEI TTYI + MOVEM D + SETZM E] + .LOSE %LSSYS ; GET SCREEN SIZE OF THIS + CAIG D,60. + SUBI D,2 + MOVEM D,STHIGH ; HEIGHT OF STY'S SCREEN + SUBI E,1 ; ALLOW FOR ! COLUMN + MOVE C,[-STYBLN,,STYBLK] + .CALL [SETZ + SIXBIT /TTYVAR/ + MOVEI STYO + SETZ C] + .LOSE %LSSYS + .CALL [SETZ + SIXBIT /SCPOS/ + MOVEI STYO + MOVEI 0 + SETZI 0] + .LOSE %LSSYS + .CALL [SETZ + SIXBIT /TTYGET/ + MOVEI STYO + MOVEM B + MOVEM C + SETZM A] + .LOSE %LSSYS + TLO A,%TSMOR ; TURN OFF MORE HACKING + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI STYO + B + C + SETZ A] + .LOSE %LSSYS +STYSTO: .CALL [SETZ + SIXBIT /TTYVAR/ + MOVEI STYO + [SIXBIT /TTYCOM/] + MOVEI O + SETZ [TLO %TCRFS]] + .LOSE %LSSYS ; SET UP REFUSE MODE + POP P,E + POP P,D + POP P,C + POP P,B + POP P,A + POPJ P, +STYSE1: .CALL [SETZ + SIXBIT /TTYVAR/ + MOVEI STYO + [SIXBIT /TTYOPT/] + MOVEI O + SETZ [TRO %TPTEL]] ; JUST TURN ON TELNET PROTOCOL AND FLUSH + .LOSE %LSSYS + JRST STYSTO +STYBLK: SIXBIT /TCTYP/ + MOVEI O,%TNSFW ; SOFTWARE TTY + SIXBIT /TTYOPT/ + MOVE O,A ; SET TTYOPT APPROPRIATELY + SIXBIT /HEIGHT/ + MOVE O,D ; SCREEN HEIGHT + SIXBIT /WIDTH/ + MOVE O,E ; SCREEN WIDTH +STYBLN==.-STYBLK + +SUBTTL STY OUTPUT + +; SHIPS BITS OUT TO THE STY. PRINTS UNTIL HAS SENT ACTIVATION OR INTERRUPT +; CHARACTER; THE PRINTING MAY BE BROKEN BY THE OCCURRENCE OF CARRIAGE RETURNS +; (WHICH GET TURNED INTO JUST CR INSTEAD OF CRLF), COMMANDS, AND SUCH. +; DATA STRUCTURE IS A LINKED LIST: +; OUTTYP ; TYPE OF INPUT SOURCE--FILE, STRING IN JCL, ETC. +; OUTNXT ; NEXT BLOCK OR 0 +; OUTLEN ; # OF CHARACTERS AVAILABLE HERE +; OUTPTR ; BYTE POINTER TO NEXT AVAILABLE CHARACTER + +; THE ROUTINE FOR DETERMINING WHETHER A CHARACTER IS AN ACTIVATION/INTERRUPT +; CHAR IS STOLEN MORE OR LESS DIRECTLY FROM THE SYSTEM. + +SNDSTR: PUSH P,O + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + PUSH P,U + .CALL [SETZ + SIXBIT /TTYGET/ + MOVEI STYO + MOVEM STYST1 + SETZM STYST2] + .LOSE %LSSYS ; GET THE BITS FOR THE TTY + .CALL [SETZ + SIXBIT /STYGET/ + MOVEI STYO + MOVEM B + MOVEM B ; OWNER OF TTY + MOVEM C + SETZM C] ; STY STATUS + .LOSE %LSSYS + SKIPN A,JOBFRC ; CHECKING JOB HACK? + JRST SNCONS + CAME A,B ; SAME JOB? + ERROR [ASCIZ /Job changed when not allowed./] +; THE FOLLOWING IS MAINLY FOR PUB, GOD HELP IT. +SNCONS: TLNE C,400000 + JRST SNCONT ; WANTS INPUT, SO GO + AOJE B,SNCONT ; NOT LOGGED IN YET, SO FEED IT THE CTRL-Z + MOVEI U,-1(B) + IMUL U,LUBLK + MOVE A,@UPC + TLNE A,%PCUSR + JRST SNDOUT ; IN USER MODE, SO DOESN'T REALLY CARE + MOVE A,@LSUUO + CAME A,[.HANG] ; PUB WOULD BE IN .HANG IF IT WANTED INPUT + JRST SNDOUT ; LAST UUO NOT HANG, SO NOT WAITING FOR ANYTHING +SNCONT: PUSHJ P,SNSTRT ; INITIALIZE O AND F +SNDLOP: PUSHJ P,SNGCHR ; PICK UP A CHAR IN A + CAMN A,ESCAPE ; COMMAND STARTER? + JRST SNDCOM ; GO PROCESS A COMMAND +SNDLP1: ADDI O,1 ; # CHARS TO SEND + SKIPE CTRLM + JRST [SETZM CTRLM ; IF LAST WAS CTRLM, CTRL-J IS NO-OP + CAIE A,^J + JRST .+1 + MOVEI B,0 + JRST SNDACT] + CAIN A,^M + SETOM CTRLM + PUSHJ P,GETGRP ; GET TYPE OF CHAR IN B, CLOBBERING C & D +SNDACT: TRNN B,%TGACT+%TGINT ; ACTIVATES OR INTERRUPTS? + JRST SNDLOP ; NO, GO DO THE NEXT ONE + PUSHJ P,SENDIT ; DO THE SEND--COUNT IN O, BPTR IN OUTPTR(E) + SKIPE FORCSW ; FORCING? + JRST SNDLOP ; GO SEND SOME MORE +SNDOUT: POP P,U + POP P,F + POP P,E + POP P,D + POP P,C + POP P,B + POP P,A + POP P,O + POPJ P, + +; INTERFACE FOR COMMANDS IN FILE +SNDCOM: PUSHJ P,SENDIT ; SEND OUT WHAT WE HAVE + PUSHJ P,SNSTRT ; RESET O AND F + PUSHJ P,SNGCHR ; GET COMMAND INTO A + MOVEM F,OUTPTR(E) ; SAVE F AWAY + SETZM FORCTM ; SAVE STATE OF FORCSW + SKIPE FORCSW + SETOM FORCTM + SKIPE ECHOQ ; ECHO AREA EXISTS? + JRST [OCTLP ECHO,"C ; CLEAR + OASC ECHO,[ASCIZ /Command: /] + JRST .+1] + PUSHJ P,COMND + PUSHJ P,SNGLIN ; INSTRUCTION TO GET A LINE + PUSHJ P,SNGPRT ; INSTRUCTION TO DO OUTPUT + JRST SNDOUT ; FLUSH FROM HERE IF COMND DIDN'T SKIP + SKIPN FORCTM ; WAS FORCSW FORMERLY ON? + JRST SNCONT ; NO, RETURN TO LOOP + SKIPE FORCSW ; DID ITS STATE JUST CHANGE? + JRST SNCONT ; NO, RETURN TO LOOP + JRST SNDOUT ; YES, FLUSH IMMEDIATE + +; ROUTINE TO GET A LINE OF TEXT FOR THE COMMAND READER. RETURN LENGTH +; IN A, POINTER IN B. ALWAYS SKIPS +SNGLIN: PUSH P,O + PUSH P,C + PUSH P,E + PUSH P,F + PUSHJ P,SNSTRT ; SET UP O AND F + MOVE B,[440700,,TTYBUF] +SNGLLP: PUSHJ P,SNGCHR + CAIN A,^M + JRST SNGLCR ; ENCOUNTERED CR + IDPB A,B + AOJA O,SNGLLP ; GET THE NEXT CHAR +SNGLCR: MOVEI A,0 + IDPB A,B ; MAKE IT ASCIZ + PUSHJ P,SNGCHR ; THROW AWAY THE LINEFEED + MOVEM F,OUTPTR(E) ; AND UPDATE THE CURRENT SOURCE + MOVEI A,TTYBUF + PUSHJ P,SNGPRT ; PRINT IF APPROPRIATE + MOVE A,O + MOVE B,[440700,,TTYBUF] + POP P,F + POP P,E + POP P,C + POP P,O + AOS (P) + POPJ P, + +; CALL WITH POINTER TO ASCIZ IN A, DUMP OUTPUT TO SUITABLE PLACE. +SNGPRT: SKIPN ECHOQ + POPJ P, + OASC ECHO,(A) + POPJ P, + +; INITIALIZE O, E, AND F FOR SENDING ROUTINE +SNSTRT: SKIPN E,INPSRC + ERROR [ASCIZ /Requesting input when none available./] + MOVEI O,0 + MOVE F,OUTPTR(E) + POPJ P, + +; GET A CHARACTER FROM THE INPUT SOURCE INTO A. SEND CURRENT STUFF IF +; HAVE TO CHANGE INPUT SOURCE. +SNGCHR: SOSGE OUTLEN(E) ; ANY LEFT IN THIS SOURCE? + JRST SNGMOR ; NO, GET MORE + ILDB A,F + AOS OUTRED(E) + POPJ P, +SNGMOR: PUSHJ P,SENDIT ; SEND OUT CURRENT STUFF + MOVE A,OUTTYP(E) ; TYPE + CAIE A,$TFILE ; A FILE? + JRST SNGNXT ; NO, SO GET NEXT ONE + SKIPN FILOPQ ; IS THE FILE OPEN? + JRST SNGNXT ; NO + PUSHJ P,FILNXT + MOVEM C,OUTPTR(E) + MOVEM B,OUTLEN(E) +SNGCON: PUSHJ P,SNSTRT + JRST SNGCHR ; TRY IT NOW + +; HERE IF THE CURRENT SOURCE IS EXHAUSTED. +SNGNXT: PUSH P,B + PUSH P,C +SNGNX1: SKIPN A,OUTNXT(E) + JRST SNGTOT ; NOTHING HERE + MOVE B,OUTTYP(A) + CAIE B,$TFILE ; FILE? + JRST [MOVE B,OUTLEN(A) + MOVEM B,OUTTLN(A) ; SET UP TOTAL LENGTH FOR TEXT + JRST SNGTOT] + PUSHJ P,FILOPN ; TRY TO OPEN IT + ERROR 1,(A) ; LOST + .CALL [SETZ + SIXBIT /FILLEN/ + MOVEI DSKI + SETZM OUTTLN(A)] + .LOSE %LSSYS + PUSHJ P,FILNXT + MOVEM C,OUTPTR(A) + MOVEM B,OUTLEN(A) +SNGTOT: MOVEM A,INPSRC + POP P,C + POP P,B + JRST SNGCON ; TRY AGAIN + +; HERE TO SHIP A STRING OUT. LENGTH IS IN O, BPTR IS IN OUTPTR(E). +; ALSO UPDATES OUTPTR(E), WHICH WILL CONTAIN THE CONTENTS OF F WHEN +; WE'RE DONE. STORES SOME STUFF IN LSTOUT AND LSTLEN FOR CTRL-T. +SENDIT: EXCH F,OUTPTR(E) + JUMPE O,CPOPJ + PUSH P,A + PUSH P,B + MOVE A,F + TLNN A,760000 + ADDI A,1 + HRLS A + HRRI A,LSTOUT + BLT A,LSTOUT+LSTOLN-1 ; BLT 3 WORDS + MOVE A,F + HRRI A,LSTOUT + MOVEM A,LSTPTR ; SAVE BPTR + MOVEM O,LSTLEN ; AND LENGTH + POP P,B + POP P,A + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI STYO + F + SETZ O] + .LOSE %LSSYS + SETOM ERESET ; ERROR STRINGS WILL BE RESET + POPJ P, + +SUBTTL FILE HACKERS + +; OPEN FILE DESCRIBED IN (A): LENGTH OF NAME IS OUTLEN(A), POINTER IS OUTPTR(A). +; SKIP IF FILE EXISTS. +FILOPN: PUSH P,A + PUSH P,B + SETZM FN1+FILFIL + SETZM FN2+FILFIL + MOVE B,OUTLEN(A) + MOVE A,OUTPTR(A) + PUSHJ P,FILPRS + FILFDF,,FILFIL + .CALL [SETZ + SIXBIT /OPEN/ + [.UAI,,DSKI] + DEV+FILFIL + FN1+FILFIL + FN2+FILFIL + SETZ SNM+FILFIL] + JRST FILPOP + AOS -2(P) + SETOM FILOPQ ; HAVE SOMETHING OPEN +FILPOP: POP P,B + POP P,A +CPOPJ: POPJ P, + +; PARSE A FILE NAME. POINTER IS IN A, LENGTH IN B, BLOCK TO USE IS +; @(P) + +FILPRS: PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + MOVEI E,0 + MOVE F,@-4(P) + HLRM F,CDEFAU + SETZM DEV(F) + SETZM SNM(F) + SETZM FN1(F) + SETZM FN2(F) ; ZERO THE SLOTS + AOS -4(P) +FILOLP: MOVE C,[440600,,E] +FILOL1: ILDB D,A + CAIN D,": + JRST [JUMPE E,FILOLE ; DON'T STORE NULL NAME + MOVEM E,DEV(F) + MOVEI E,0 + JRST FILOLE] + CAIN D,"; + JRST [JUMPE E,FILOLE + MOVEM E,SNM(F) + MOVEI E,0 + JRST FILOLE] + CAIE D,40 + CAIN D,^I + JRST FILFLD + CAIN D,^J + JRST FILFLD + TLNN C,770000 ; WORD ALREADY FULL? + JRST FILOLE ; IGNORE THIS CHAR + SUBI D,40 + CAIL D,100 + SUBI D,40 + IDPB D,C ; STUFF IT IN + SOJG B,FILOL1 +FILOUT: PUSHJ P,FILFL1 +; FILL IN THE DEFAULTS AND SUCH + MOVE E,CDEFAU + HRLI E,-4 +FILDEF: PUSHJ P,DEFHAK + ADDI F,1 + AOBJN E,FILDEF + POP P,F + POP P,E + POP P,D + POP P,C + POPJ P, +FILOLE: SOJLE B,FILOUT ; RAN OUT OF CHARACTERS + JRST FILOLP +DEFHAK: SKIPE (F) ; NEED SOMETHING FROM DEFAULT + JRST [MOVE C,(F) + MOVEM C,(E) + POPJ P,] + MOVE C,(E) + MOVEM C,(F) + POPJ P, + +; HERE WITH EITHER FN1 OR FN2 IN E +FILFL1: JUMPE E,CPOPJ + PUSH P,A + SKIPN FN1(F) + JRST [MOVEM E,FN1(F) + JRST FILFL2] + MOVEM E,FN2(F) +FILFL2: MOVEI E,0 + POP P,A + POPJ P, + +; HERE WITH FN1 OR FN2 IN E, TERMINATED BY SPACE OR SOMETHING +FILFLD: PUSHJ P,FILFL1 + JRST FILOLE + + +; COME HERE TO OPEN FILE PARSED INTO OUTFIL, SET PARAMETERS APPROPRIATELY. + +OUTHCK: PUSH P,A + PUSH P,B + .CALL [SETZ ; DO THE OPEN + SIXBIT /OPEN/ + [.UAO,,OUTCHN] + DEV+OUTFIL + FN1+OUTFIL + FN2+OUTFIL + SETZ SNM+OUTFIL] + .LOSE %LSFIL +OUTHAK: .STATUS OUTCHN,A + JUMPE A,[SETZM DSKCHN ; OUTCHAN DOESN'T LOOK LIKE DSK + SETZM DSKOUT ; DOESN'T EXIST + SKIPN TTYSRC + SETOM NULOUT ; IF INPUT ISN'T FROM TTY, THERE'S NO OUTPUT + JRST OUTHCO] + SETOM DSKCHN + ANDI A,77 ; ISOLATE DEVICE + CAIE A,SNTTY + CAIN A,SNTDS ; TTY AND DISPLAY TTY AREN'T DISK-LIKE + SETZM DSKCHN + CAIN A,SNSTY + SETZM DSKCHN ; NOR IS STY + SETZM NULOUT + SETOM DSKOUT + SKIPN TTYQ ; HAVE WE OPENED TTY? + JRST OUTHCO ; NO, SO DON'T DO SCML + MOVEI B,2 + CAIE A,SNTDS + MOVEI B,0 + .CALL [SETZ ; SET UP ECHO AREA IF OUTPUT IS TO DISPLAY TTY + SIXBIT /SCML/ + MOVEI ECHO + SETZ B] + .LOSE %LSSYS + MOVEM B,ECHOQ ; B IS 0 IF THERE'S NO ECHO AREA +OUTHCO: POP P,B + POP P,A + POPJ P, + +; HERE TO SET ALL THE SWITCHES WITHOUT OPENING THE CHANNEL +OUTHC1: PUSH P,A + PUSH P,B + JRST OUTHAK + + +; GET BUFFER AT LEAST PARTIALLY FULL OF CRUFT. SKIP IF ANYTHING. CLOSE +; DSKI IF THROUGH WITH IT, AND CLEAR FLAG. RETURN LENGTH OF BUFFER IN B, +; POINTER IN C. +FILNXT: SKIPN FILOPQ + JRST CPOPJ ; FLUSH IMMEDIATE + MOVEI B,5*DBUFLN + MOVE C,[010700,,DSKBUF-1] ; SO FLUSHING OF PADDING WILL WORK RIGHT + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI DSKI + C + SETZ B] + .LOSE %LSSYS + JUMPE B,FILNXO ; FULL BUFFER + .CLOSE DSKI, ; DIDN'T GET BUFFER FULL, SO DONE + SETZM FILOPQ + PUSH P,A ; ADJUST FOR PADDING + PUSH P,D + MOVEI D,4 +PADLOP: LDB A,C + CAIN A,C + JRST [DBP C ; BACK UP THE BPTR + ADDI B,1 ; AOSING HERE SOSES LATER + SOJG D,PADLOP + JRST .+1] + POP P,D + POP P,A +FILNXO: SUBI B,5*DBUFLN + MOVNS B ; GET # CHARS + JUMPE B,CPOPJ ; NONE HERE + MOVE C,[440700,,DSKBUF] + POPJ P, + +SUBTTL GET CHARACTER GROUP + +; GETS BYTE IN B, GROUP NUMBER IN C, BYTE POINTER IN D; TAKES CHAR IN A +; USED BY SNDSTR +GETGRP: PUSH P,E + PUSH P,A + MOVE B,A + IDIVI B,5 + POP P,A + LDB C,GRPBPT(C) ; GET GROUP BITS + MOVEI D,STYST1 + CAIL C,6 + JRST GETGR2 + LDB E,[301400,,SBTBL(C)] ; LOAD LH OF BYTE PTR +GETGR1: DPB E,[301400,,D] ; MAKE TTYST1 OR TTYST2 APPROPRIATE BYTE POINTER + LDB B,D + POP P,E + POPJ P, + +GETGR2: LDB E,[301400,,SBTBL-6(C)] + MOVEI D,STYST2 + JRST GETGR1 + +SBTBL: 360600,, + 300600,, + 220600,, + 140600,, + 060600,, + 000600,, + +DEFINE GGRPTB A,B,C,D,E +A_29.+B_22.+C_15.+D_8+E_1 +TERMIN + +GRPTBL: GGRPTB 0,0,0,0,0 + GGRPTB 0,0,6,13,7 + GGRPTB 7,0,0,11,0 + GGRPTB 0,0,0,0,6 + GGRPTB 0,0,0,0,0 + GGRPTB 0,0,10,0,0 + GGRPTB 0,0,13,3,3 + GGRPTB 3,3,3,3,3 + GGRPTB 5,5,4,4,3 + GGRPTB 4,3,4,2,2 + GGRPTB 2,2,2,2,2 + GGRPTB 2,2,2,3,3 + GGRPTB 5,4,5,3,3 + REPEAT 5,GGRPTB 1,1,1,1,1 + GGRPTB 1,5,3,5,4 + GGRPTB 4,3,1,1,1 + REPEAT 4,GGRPTB 1,1,1,1,1 + GGRPTB 1,1,1,5,3 + GGRPTB 5,3,12,0,0 + +GRPBPT: 350700,,GRPTBL(B) + 260700,,GRPTBL(B) + 170700,,GRPTBL(B) + 100700,,GRPTBL(B) + 010700,,GRPTBL(B) + +SUBTTL STY INPUT + +; COME HERE TO GOBBLE CHARACTERS FROM THE STY INPUT CHANNEL AND +; SEND THEM TO THE APPROPRIATE OUTPUT DEVICE(S). NOTE THAT THE +; STY'S TTY IS A SOFTWARE TTY, SO WE READ IN 8-BIT BYTES AND CONVERT +; WHERE REQUIRED. READ UNTIL OUT OF CHARACTERS. + +RECSTR: PUSH P,O + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + MOVE C,[440700,,INPBU1] + MOVEI D,5*INBLEN +RECNXT: MOVEI B,0 ; SO RECGET WILL READ +RECLOP: PUSHJ P,RECGET ; GET A CHAR + JRST RECPRT ; NONE LEFT + SKIPE NULOUT ; THROW AWAY SOME INPUT + JRST RECLPP + CAILE O,177 ; ASCII? + JRST RECDSP ; HACK FOR DISPLAY CODES + AOS STHPOS ; UPDATE HORIZONTAL POSITION +RECLPP: PUSHJ P,RECPUT ; STUFF INTO OUTPUT, PRINT IF FULL + JRST RECLOP ; GET THE NEXT ONE + +RECPRT: SKIPE NULOUT + JRST RECPR1 ; NUL OUTPUT, SO FLUSH + PUSHJ P,RECBUO ; PRINT BUFFER TO APPROPRIATE PLACES +RECPR1: MOVE B,CINPLN + CAIL B,4*INBLEN + JRST RECNXT ; GOT FULL BUFFER, SO TRY AGAIN +RECOUT: POP P,D + POP P,C + POP P,B + POP P,A + POP P,O + POPJ P, + + +; READ CHARS FROM STY. RETURN # READ IN B, POINTER TO INPBUF IN A +RECDOR: MOVE A,[440800,,INPBUF] + MOVEI B,4*INBLEN + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI STYI + A + SETZ B] + .LOSE %LSSYS + SUBI B,4*INBLEN + MOVNS B ; # CHARS READ + MOVE A,[440800,,INPBUF] + POPJ P, + +; GET A CHARACTER FROM STY BUFFER. CURRENT LENGTH IN B, POINTER IN A. +; SKIP IF SUCCESSFUL. +RECGET: JUMPE B,RECMOR +RECGT1: ILDB O,A + SOJA B,POPJ1 ; SOS COUNT, RETURN +RECMOR: PUSHJ P,RECDOR ; READ A BUFFER FULL + JUMPE B,CPOPJ ; NONE LEFT + MOVEM B,CINPLN + JRST RECGT1 +POPJ1: AOS (P) ; SKIP IF GOT A CHAR + POPJ P, + +; SOME ROUTINES MAY COME HERE IF RECGET DOESN'T SKIP, TO SEE IF THE LOSSAGE +; IS TRANSIENT. ALGORITHM IS SUBJECT TO CHANGE WITHOUT NOTICE. +INPERR: MOVEI O,30. + .SLEEP O, ; SLEEP FOR A SECOND, TO LET THINGS SETTLE + PUSHJ P,RECGET ; CAN WE WIN IMMEDIATE? + JRST RECER1 + POPJ P, ; YES, RETURN +RECER1: PUSH P,A + PUSH P,B + .CALL [SETZ + SIXBIT /STYGET/ + MOVEI STYO + MOVEM A + MOVEM A + MOVEM A + MOVEM A + SETZM B] + .LOSE %LSSYS + JUMPL A,RETRY1 ; JUMP IF OUTPUT CLAIMS TO BE AVAILABLE + TLNN B,200000 ; SKIP IF OUTPUT BUFFER HAS ROOM + JRST RETRY2 ; NO ROOM? +; OUTUT BUFFER HAS ROOM, NO OUTPUT AVAILABLE. WE ARE REALLY CHOMPING. + POP P,B + POP P,A + PUSHJ P,RECGET ; LAST CHANCE + CAIA + POPJ P, ; WON, SOMEHOW + ERROR 2,[ASCIZ /Ran out of chars during cursor positioning command./] + .VALUE ; SORRY, AS. + POPJ P, +; HERE IF OUTPUT IS AVAILABLE (GOSPEL ACCORDING TO STYGET) +RETRY1: TLNN B,200000 ; ROOM IN OUTPUT BUFFER? + JRST [POP P,B + POP P,A + PUSHJ P,RECGET + CAIA + POPJ P, + ERROR 2,[ASCIZ /Chars here, no room in buffer, but I can't get any?/] + .VALUE + POPJ P,] + POP P,B + POP P,A + PUSHJ P,RECGET ; GET IT + CAIA + POPJ P, ; GOT IT + ERROR 2,[ASCIZ /STYGET says chars here when there aren't any./] + .VALUE + POPJ P, +; HERE IF NO ROOM IN OUTPUT BUFFER, BUT NO CHARS AVAILABLE +RETRY2: POP P,B + POP P,A + PUSHJ P,RECGET + CAIA + POPJ P, ; GOT OUTPUT ANYWAY + ERROR 2,[ASCIZ /No room in buffer, but no chars available./] + .VALUE + POPJ P, + + +; PUT CHARACTER IN O INTO OUTPUT BUFFER (IN C). PRINT BUFFER IF BECOMES FULL +; (COUNT IS IN D) AND DON'T SKIP; +; RECPUT CHECKS FOR ERRORS, RECPU1 DOESN'T +RECPU1: PUSH P,A + IDPB O,C + SETOM ERESET + SOJG D,POPAJ + JRST RECPPR +RECPUT: PUSH P,A + IDPB O,C + SUBI D,1 + SKIPE A,ERRORS ; ERRORS TO LOOK FOR? + PUSHJ P,RECERR + JUMPG D,POPAJ +RECPPR: PUSHJ P,RECBUO ; GO PRINT BUFFER + MOVE C,[440700,,INPBU1] + MOVEI D,5*INBLEN +POPAJ: POP P,A + POPJ P, + +; HERE TO CHECK FOR ERROR STRINGS +RECERR: SKIPE TTYSRC + POPJ P, ; DON'T CHECK IF TTY INPUT + SKIPE ERESET + PUSHJ P,RECRST ; RESET EVERYBODY + SETZM ERESET + PUSH P,B +RECELP: SKIPG EMATLN(A) + JRST RECELE ; ALREADY MATCHED? + ILDB B,EMATCH(A) + CAIN O,(B) + JRST [SOSE EMATLN(A) ; ALL OUT? + JRST RECELE ; NO + PUSHJ P,RECBUO + MOVE C,[440700,,INPBU1] + MOVEI D,5*INBLEN + ERROR [ASCIZ /ERROR string found./] + JRST .+1] + MOVE B,ESTRING(A) + MOVEM B,EMATCH(A) ; RESET, SINCE DIDN'T MATCH + MOVE B,ELENGTH(A) + MOVEM B,EMATLN(A) +RECELE: SKIPE A,ENEXT(A) + JRST RECELP ; GO TO NEXT + POP P,B + POPJ P, + +; RESET ALL ERROR BLOCKS +RECRST: PUSH P,B +RECRSL: MOVE B,ESTRING(A) + MOVEM B,EMATCH(A) + MOVE B,ELENGTH(A) + MOVEM B,EMATLN(A) + SKIPE A,ENEXT(A) + JRST RECRSL + MOVE A,ERRORS + POP P,B + POPJ P, + +; HERE TO PRINT OUTPUT BUFFER TO SUITABLE PLACES. # OF CHARACTERS LEFT +; IS IN D. MAY CLOBBER C AND D. +RECBUO: SKIPE NULOUT + POPJ P, ; NO OUTPUT, SO FLUSH + SUBI D,5*INBLEN + MOVNS D ; # CHARACTERS + JUMPE D,CPOPJ + PUSH P,D + SKIPN DSKOUT ; NORMAL OUTPUT? + JRST TTYCHK + SKIPE TTYSRC + JRST [SKIPN DSKCHN ; IF INPUT FROM TTY, MAY NOT WANT TO OUTPUT + JRST TTYCHK + JRST .+1] + MOVE C,[440700,,INPBU1] + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI OUTCHN + MOVSI %TJDIS + C + SETZ D] + .LOSE %LSSYS +TTYCHK: POP P,D + SKIPN TTYSRC ; IN TTY INPUT? + POPJ P, + MOVE C,[440700,,INPBU1] + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI TTYO + MOVSI %TJDIS ; DISPLAY MODE + C + SETZ D] + .LOSE %LSSYS + POPJ P, + +; JRST HERE TO TURN DISPLAY CODE INTO SUITABLE CHARACTERS FOR OUTPUT. +; IF DOES PRINTING, JRSTS TO RECPR1, ELSE TO RECLOP. +; CHARACTER IS IN O; A, B, C,D MUST NOT BE TOUCHED. +RECDSP: TRZ O,200 + ASH O,1 ; MULTIPLY BY 2 + ADDI O,DSPTBL+1 + ADD O,DSKCHN ; OUTPUT TO DISK? (VAL IS 0 OR -1) + PUSH P,E + SKIPL E,@O ; IF TABLE ENTRY < 0, POINTER TO ASCIZ STRING + JRST [PUSHJ P,(E) + JRST RECDOT] + HRLI E,440700 +RECDLP: ILDB O,E + JUMPE O,RECDOT + PUSHJ P,RECPU1 ; DON'T CHECK FOR ERROR STRINGS + AOS STHPOS ; UPDATE HORIZONTAL POSITION + JRST RECDLP +RECDOT: POP P,E + JRST RECLOP + +; SPECIAL ROUTINES FOR HAIRY CRAP + +; %TDMOV, FOLLOWED BY %TDMVO, FOR TTY OUTPUT +RTDMOV: PUSHJ P,RECGET + PUSHJ P,INPERR + PUSHJ P,RECGET ; OLD POSITION + PUSHJ P,INPERR +RTDMVO: MOVEI E,"V + PUSHJ P,CP1ARG + MOVEI E,"H + PUSHJ P,CP1ARG + POPJ P, + +CP1ARG: MOVEI O,^P ; TAKES LETTER IN A, PUTS ^P + PUSHJ P,RECPU1 ; IN STRING, WHERE IS 8+next input char + MOVEI O,(E) + PUSHJ P,RECPU1 + PUSHJ P,RECGET + PUSHJ P,INPERR + ADDI O,10 + PUSHJ P,RECPU1 + POPJ P, + +; %TDMOV &C FOR FILE OUTPUT +RTDMVD: PUSH P,F + MOVE F,STVPOS + MOVE E,STHPOS + JRST RTDMV1 +RTDMOD: PUSH P,F + PUSHJ P,RECGET ; OLD VERTICAL POS + PUSHJ P,INPERR + MOVE F,O + PUSHJ P,RECGET ; OLD HORIZONTAL POS + PUSHJ P,INPERR + MOVE E,O +RTDMV1: PUSHJ P,RECGET ; NEW VERTICAL POS + PUSHJ P,INPERR + MOVEM O,STVPOS + SUBM O,F ; CHANGE IN VERTICAL POS + CAIGE F,0 + ADD F,STHIGH ; IF <0, ADD HEIGHT + JUMPE F,RTDMVH + CAILE F,3 + MOVEI F,3 ; LEAVE US NOT BE RIDICULOUS + MOVEI E,0 ; SINCE DOING CR'S, HPOS WILL BE ZERO +RTDCRL: MOVEI O,^M + PUSHJ P,RECPU1 + MOVEI O,^J + PUSHJ P,RECPU1 + SOJG F,RTDCRL ; STUFF OUT SUITABLE CRLFS +RTDMVH: PUSHJ P,RECGET ; NEW HORIZONTAL POS + PUSHJ P,INPERR + MOVEM O,STHPOS + CAIG O,(E) ; > THAN OLD? + JRST RTDMDN ; NO, LEAVE + SUBM O,E +RTDSPL: MOVEI O,40 + PUSHJ P,RECPU1 + SOJG E,RTDSPL +RTDMDN: POP P,F + POPJ P, + +; CRLF FOR FILE OUTPUT +RTDNWL: MOVEI O,^M + PUSHJ P,RECPU1 + MOVEI O,^J + PUSHJ P,RECPU1 + AOS E,STVPOS + CAIL E,STHIGH + SETOM STVPOS ; ZERO VERTICAL POSITION ON WRAPAROUND + SETZM STHPOS + POPJ P, + +RTDCLR: SETOM STVPOS ; SO VERTICAL POSITION WORKS + PUSHJ P,RTDNWL + POPJ P, + +; %TDNOP, %TDMV1, %TDMTF, %TDMTN, %TDBS, %TDLF, %TDRCR, %TDORS, %TDQOT +RTDNOP: POPJ P, + +; %TDILP, %TDDLP, %TDICP, %TDDCP +RTDILP: MOVEI E,"[ ; INSERT LINE + JRST RTDXXX +RTDDLP: MOVEI E,"\ + JRST RTDXXX +RTDICP: MOVEI E,"^ + JRST RTDXXX +RTDDCP: MOVEI E,"_ +RTDXXX: PUSHJ P,RECGET ; GET NUMBER TO DO + PUSHJ P,INPERR + JUMPLE O,CPOPJ + PUSH P,F + MOVE F,O +RTDXXL: MOVEI O,^P + PUSHJ P,RECPU1 + MOVE O,E + PUSHJ P,RECPU1 + SOJG F,RTDXXL + POP P,F + POPJ P, + +; TABLE FOR DISPLAY CODES +DSPTBL: RTDMOD + RTDMOV ; %TDMOV--200 + RTDNOP + RTDNOP ; %TDMV1--201 + RTDNOP + SETZ [ASCIZ /E/] ; %TDEOF--202 + RTDNOP + SETZ [ASCIZ /L/] ; %TDEOL--203 + RTDNOP + SETZ [ASCIZ /K/] ; %TDDLF--204 + RTDNOP + RTDNOP ; %TDMTF--205 + RTDNOP + RTDNOP ; %TDMTN--206 + RTDNWL + SETZ [ASCIZ / +/] ; %TDCRL--207 + RTDNOP + RTDNOP ; %TDNOP--210 + RTDNOP + RTDNOP ; %TDBS--211 + RTDNOP + RTDNOP ; %TDLF--212 + RTDNOP + RTDNOP ; %TDRCR--213 + RTDNOP + RTDNOP ; %TDORS--214 + RTDNOP + RTDNOP ; %TDQOT--215 + SETZ [ASCIZ / /] + SETZ [ASCIZ /F/] ; %TDFS--216 + RTDMVD + RTDMVO ; %TDMVO--217 + RTDNWL + SETZ [ASCIZ /C/] ; %TDCLR--220 + SETZ [ASCIZ //] + SETZ [ASCIZ //] ; %TDBEL--221 + RTDNOP + RTDNOP ; %TDINT--222 + RTDILP + RTDILP ; %TDILP--223 + RTDDLP + RTDDLP ; %TDDLP--224 + RTDICP + RTDICP ; %TDICP--225 + RTDDCP + RTDDCP ; %TDDCP--226 + RTDNOP + RTDNOP ; %TDBOW--227 + RTDNOP + RTDNOP ; %TDRST--230 + +SUBTTL JCL PARSER + +JCLHAK: .SUSET [.ROPTIO,,A] + TLNE A,OPTCMD + .BREAK 12,[..RJCL,,JCLBUF] + IBLOCK C,OUTBLK ; GET AN INITIAL BLOCK + MOVEM C,INPSRC + PUSHJ P,JCLFST ; GET STRING foo0U:GAG 0 + MOVEM A,OUTLEN(C) + MOVEM B,OUTPTR(C) + MOVE A,[440700,,JCLBUF] + PUSH P,A +JCLLP1: MOVEI B,0 +JCLLOP: MOVEM A,(P) + ILDB O,A + CAIE O,40 + CAIN O,^I + JRST JCLLOP + CAIA +JCLLNX: ILDB O,A + CAIE O,"/ + CAIN O,"[ + JRST JCLFLD ; END A FILE NAME + CAIE O,", + CAIN O,"\ + JRST JCLFLD + CAIE O,^C + CAIN O,^M + JRST JCLFLD + JUMPE O,JCLFLD + CAIN O,"_ + JRST JCOUTF ; OUTPUT FILE + AOJA B,JCLLNX +JCLFLD: JUMPE B,JCLFL1 + IBLOCK D,OUTBLK + MOVEM D,OUTNXT(C) ; CHAIN BLOCKS + MOVEM B,OUTLEN(D) + POP P,OUTPTR(D) + MOVEI B,$TFILE + MOVEM B,OUTTYP(D) + MOVE C,D + MOVEI B,0 + PUSH P,A +JCLFL1: CAIE O,^C + CAIN O,^M + JRST JCLDON + JUMPE O,JCLDON + CAIN O,", + JRST JCLLOP + CAIN O,"\ + JRST JCLTTY + CAIN O,"[ + JRST JCLTXT + CAIN O,"/ + JRST JCLSW + .VALUE +JCLTTY: IBLOCK D,OUTBLK + MOVEI B,$TTEXT + MOVEM B,OUTTYP(D) + MOVE B,[440700,,[ASCII /B/]] + MOVEM B,OUTPTR(D) + MOVEI B,2 + MOVEM B,OUTLEN(D) + MOVEM D,OUTNXT(C) + MOVE C,D + MOVEI B,0 + JRST JCLLOP +JCLSW: ILDB O,A + CAIE O,"P + CAIN O,"p + SETOM PRSW ; SUPPRESS FANCY HACKING W/ STY + CAIE O,"E + CAIN O,"e + SETOM CNSFLS ; DIE IF ERROR WITH NO TTY + CAIE O,"S + CAIN O,"s + JRST [MOVEI O,360. ; TRY 360. TIMES TO OPEN (EVERY 10 SEC) + MOVEM O,STYTRY + JRST JCLLOP] + JRST JCLLOP +JCLTXT: PUSH P,C + MOVEM A,-1(P) + MOVNI B,1 + PUSHJ P,STRGET ; NEW BPTR IN A, LEN IN B, PTR IN C + IBLOCK D,OUTBLK ; POINTER FOR CROCK + MOVEM C,OUTPTR(D) + MOVEM B,OUTLEN(D) + MOVEI B,$TTEXT + MOVEM B,OUTTYP(D) + POP P,C + MOVEM D,OUTNXT(C) + MOVE C,D + JRST JCLLP1 +JCLDON: MOVEI A,LSTBLK + MOVEM A,OUTNXT(C) ; LSTBLK HAS STUFF TO LOG OUT + POP P,A + POPJ P, + +; CONS UP STRING TO LOG IN, SAY :GAG 0. RETURN LENGTH IN A, PTR IN B. +JCLFST: PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + IBLOCK B,4 ; MAXIMUM LENGTH IS 17. CHARS + HRLI B,440700 + PUSH P,B + MOVEI A,1 + MOVEI C,^Z + IDPB C,B ; STUFF OUT CTRL-Z + MOVE C,XUNAME + MOVE D,[440600,,C] +JCLUNM: TLNN D,770000 + JRST JCLFS1 + ILDB E,D + JUMPE E,JCLFS1 + ADDI E,40 + IDPB E,B + AOJA A,JCLUNM +JCLFS1: MOVE C,[440700,,[ASCIZ /0U:GAG 0 +/]] +JCLFLP: ILDB D,C + JUMPE D,JCLFS2 + IDPB D,B + AOJA A,JCLFLP +JCLFS2: POP P,B + POP P,F + POP P,E + POP P,D + POP P,C + POPJ P, + +; OUTPUT FILE SPECIFICATION. LENGTH OF FILE SPEC IS IN B, POINTER +; TO FIRST CHAR IS (P). A MUST BE RESTORED, B ZEROED BEFORE RETURN. + +JCOUTF: EXCH A,(P) + JUMPE B,JCOUTO + MOVE O,[SIXBIT /DSK/] + MOVEM O,DEV+OUTFDF + PUSHJ P,FILPRS ; PARSE A FILE NAME + OUTFDF,,OUTFIL ; INTO BLOCK STARTING HERE + PUSHJ P,OUTHCK ; SET PARAMETERS + MOVEI B,0 +JCOUTO: MOVE A,(P) + JRST JCLLOP + +; TAKE A STRING WITH '^foo' FOR CONTROL CHARACTERS, COPY IT SOMEPLACE +; AND SUBSTITUTE REAL CHARS. TAKES POINTER TO STRING IN A, -1 IN B +; IF ']' IS TERMINATOR FOR STRING. IF B >0, IT'S CHAR COUNT OF STRING. +; RETURNS UPDATED POINTER IN A, LENGTH IN B, STRING POINTER IN C. + +STRGET: PUSH P,O + PUSH P,D + PUSH P,E + PUSH P,F + PUSH P,A ; SAVE ARGS + PUSH P,B + MOVEI B,0 ; ACCUMULATE CHAR COUNT + MOVE C,(P) +STRLP1: ILDB O,A + CAIN O,"] + JUMPL C,STRLE1 + CAIN O,"^ + JRST [IBP A + SOJA C,STRLD] ; EAT NEXT CHAR + CAIN O,^Q + JRST [SUBI C,1 + ILDB O,A + JRST .+1] +STRLD: ADDI B,1 + JUMPL C,STRLP1 ; IF C<0, ONLY ] TERMINATES + SOJG C,STRLP1 +; # CHARS IS IN B, STRING PTR IS -1(P), TERM CONDITION IS (P) +STRLE1: PUSH P,B + ADDI B,1 ; MAKE SURE HAVE A CHAR AT END SO ASCIZ + IDIVI B,5 + JUMPE C,.+2 + ADDI B,1 + IBLOCK B,(B) ; STORAGE FOR STRING + HRLI B,440700 + PUSH P,B + MOVE C,-2(P) ; GET TERMINATING CONDITION BACK + MOVE A,-3(P) ; GET STRING BACK +STRLP2: ILDB O,A + CAIN O,"] + JUMPL C,STRLE2 + CAIN O,"^ + JRST STRCTL + CAIN O,^Q + JRST [SUBI C,1 + ILDB O,A + JRST .+1] +STRDEP: IDPB O,B + JUMPL C,STRLP2 + SOJG C,STRLP2 +STRLE2: POP P,C ; NEW STRING + POP P,B ; LENGTH + SUB P,[2,,2] + POP P,F + POP P,E + POP P,D + POP P,O + POPJ P, +; HACKERY FOR CTRL CHARS +STRCTL: SUBI C,1 + ILDB O,A + CAIN O,"? + JRST [MOVEI O,177 + JRST STRDEP] + CAIL O,100 + SUBI O,100 + CAIL O,40 + SUBI O,40 + JRST STRDEP + +SUBTTL COMMAND PARSER + +; CALL COMND WITH A CHARACTER IN A (INDICATING WHICH COMMAND WE HAVE) +; AND TWO ARGUMENTS FOLLOWING THE CALL: THE FIRST IS AN INSTRUCTION +; USED TO GET A LINE OF TEXT (FOR COMMANDS WHICH TAKE THAT), RETURNING +; THE LENGTH IN A AND AN ILDB POINTER TO THE FIRST CHAR IN B; THE SECOND IS +; USED TO DO PRINTING, BY HAVING THE ADDRESS OF THE FIRST WORD OF AN +; ASCIZ STRING STUFFED INTO A--THUS OASC WILL NOT WORK. +; WHEN CALLED FROM SNDSTR, THE TWO ARGS ARE PUSHJ P,SNGLIN AND PUSHJ P,SNGPRT; +; WHEN CALLED FROM THE TTY INTERRUPT HANDLER, THEY ARE PUSHJ P,GETLIN +; AND PUSHJ P,TTYPRT. +; ROUTINES SKIP IF COMND SHOULD SKIP. FAILURE TO SKIP INDICATES THAT +; THE ROUTINE CALLING COMND SHOULD PROBABLY FLUSH IMMEDIATE (AS, FOR +; EXAMPLE, WHEN SNDSTR CALLS IT WITH THE 'B' COMMAND). +COMND: PUSH P,B + PUSH P,C + PUSH P,D + MOVE B,@-3(P) ; PICK UP FIRST ARG + MOVEM B,COMGLN + AOS -3(P) + MOVE B,@-3(P) + MOVEM B,COMPRT + AOS -3(P) + CAIN A,177 ; NULL COMMAND + JRST COMEXO ; EXIT VIA SKIP + CAME A,CTRLT ; QUOTED CTRL-T? + CAMN A,ESCAPE ; QUOTED ESCAPE? + JRST [.IOT STYO,A + JRST COMEXO] + CAIN A,"? + JRST COMINF ; PRINT INFO ON COMMANDS + CAIL A,"A + CAIL A,"z + JRST COMERR ; ILLEGAL COMMAND + CAIL A,"a + SUBI A,40 + CAILE A,"Z + JRST COMERR ; ILLEGAL COMMAND + SUBI A,"A + ASH A,1 + PUSHJ P,PRCOM ; PRINT COMMAND DESC + PUSHJ P,@COMTBL(A) ; EXECUTE COMMAND + CAIA ; COMMAND ROUTINES SKIP IF COMND SHOULD +COMEXO: AOS -3(P) ; STUFF THE CHARACTER OUT, WHATEVER IT WAS +COMEXD: POP P,D + POP P,C + POP P,B + POPJ P, + +; PRINT COMMAND DESCRIPTION +PRCOM: PUSH P,A + MOVE A,COMTBL+1(A) + XCT COMPRT ; DO THE PRINT + POP P,A + POPJ P, + +; PRINT BRIEF DESCRIPTION OF COMMANDS TO CONVENIENT PLACE +COMINF: SKIPE TTYSRC + JRST COMIN0 + .CALL [SETZ + SIXBIT /OPEN/ + [.UAO,,TTYO] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE %LSFIL +COMIN0: OCTLP TTYO,"T + OCTLP TTYO,"L + OASCR TTYO,COMDSC ; PRINT DESCRIPTION + SKIPE TTYSRC + JRST COMEXO + .CLOSE TTYO, + JRST COMEXO + +COMDSC: ASCIZ \Commands: +The intercept character is initially ctrl-^. Some commands may + request a line of text; in a file, this must be terminated by + crlf. From the tty, ctrl-Z and ctrl-_ may be given normally to + the 'Command:' prompt, since super-image input is turned off. + Send escape character out on sty. +A Abort input source--flush current file/string +B Begin tty input. The state of the current file is saved. +C Change output file. Takes line containing new output file. +D DDT. Return to ddt. +E Error strings. Which output strings cause an error. May be + several, separated by commas. +F Force input. Text through the next 'F' command will be fed to + receiving job whether it wants it or not. Useful for PUB &c. +H Halt job. Sends control-Z out, begins tty input. +I Intercept character. Takes line containing new intercept. +J Undoes effect of 'R' command. +P Proced XXFILE. +Q Quit XXFILE. +R Remain in job. All input must go to the job which currently has + the tty, until a 'J' command has been given. Ignored if input + from tty. +S Stop tty input. Returns to whatever the source was before. +T Ctrl-T character. Takes line containing replacement for ^T. +V Valret string. Takes line and valrets it. Control characters, + including crlf, may be included by typing as -char: + crlf--^M. +Line editor: erases a char; ctrl-W a word; ctrl-U, ctrl-X, + and ctrl-@ erase the entire line. Carriage return terminates. + Attempts to rubout past the beginning of the line abort the + command.\ + + +; DISPATCH TABLE FOR COMMANDS +COMTBL: CABORT ; A--ABORT CURRENT INPUT SOURCE + [ASCIZ /Abort input source/] + CTTYB ; B--BEGIN TTY INPUT + [ASCIZ /Begin tty input/] + CCHANG ; C--CHANGE OUTPUT FILE (TAKES A LINE) + [ASCIZ /Change output file/] + CDDT ; D--RETURN TO SUPERIOR + [ASCIZ /DDT/] + CERROR ; E--SET ERROR STRINGS (TAKES A LINE) + [ASCIZ /Error strings/] + CFORCE ; F--FORCE INPUT + [ASCIZ /Force input/] + COMER1 ; G + [ASCIZ /Illegal command/] + CHALT ; H--HALT JOB + [ASCIZ /Halt job/] + CINTER ; I--SET INTERCEPT CHARACTER (TAKES A LINE) + [ASCIZ /Set intercept character/] + CNREMA ; J + [ASCIZ /Job may change/] + COMER1 ; K + [ASCIZ /Illegal command/] + COMER1 ; L + [ASCIZ /Illegal command/] + COMER1 ; M + [ASCIZ /Illegal command/] + COMER1 ; N + [ASCIZ /Illegal command/] + COMER1 ; O + [ASCIZ /Illegal command/] + CPROCE ; P--PROCED SELF + [ASCIZ /Proceed/] + CQUIT ; Q--QUIT + [ASCIZ /Quit/] + CREMAN ; R--DON'T CHANGE JOBS UNTIL J COMMAND + [ASCIZ /Remain in this job/] + CTTYE ; S--STOP TTY INPUT + [ASCIZ /Stop TTY input/] + CCTRLT ; T + [ASCIZ /'Ctrl-T' character/] + COMER1 ; U + [ASCIZ /Illegal command/] + CVALUE ; V + [ASCIZ /Valret string/] + COMER1 ; W + [ASCIZ /Illegal command/] + COMER1 ; X + [ASCIZ /Illegal command/] + COMER1 ; Y + [ASCIZ /Illegal command/] + COMER1 ; Z + [ASCIZ /Illegal command/] + +; COMMANDS. ROUTINES MAY USE A, B, C, AND D WITHOUT PUSHING THEM. +; IF THE ROUTINE SKIPS, IT SHOULD PUT A CHARACTER IN A TO BE THE NEXT +; ONE SENT TO THE JOB. ROUTINES SHOULD USUALLY SKIP RETURN. + +; ILLEGAL COMMAND +COMER1: JRST POPJ1 +COMERR: OASC ECHO,[ASCIZ /Illegal command/] + JRST COMEXO + +; ABORT CURRENT INPUT SOURCE--'A' COMMAND +CABORT: SKIPN A,INPSRC ; IS THERE ONE? + JRST POPJ1 + SKIPN B,OUTNXT(A) ; CAN'T ABORT THE LAST ONE + JRST POPJ1 + MOVEM B,INPSRC + JRST POPJ1 + +; START TTY INPUT--'B' COMMAND +CTTYB: SKIPE TTYSRC ; ALREADY STARTED? + JRST POPJ1 ; YES, SO FLUSH + PUSHJ P,SETTTY ; SET IT UP + OASC TTYO,[ASCIZ /Begin TTY input: /] + POPJ P, ; DON'T SKIP + +; CHANGE OUTPUT FILE--'C' COMMAND +CCHANG: PUSHJ P,CPRMPT ; PRINT A PROMPT + XCT COMGLN ; GET A LINE INTO A AND B + JRST POPJ1 + JUMPE A,CCHFLS ; 0-LENGTH INPUT-->FLUSH OUTPUT CHANNEL + EXCH A,B ; SHUFFLE THE AC'S + PUSHJ P,FILPRS + OUTFDF,,OUTFIL ; PARSE THE NAME INTO OUTFIL + PUSHJ P,OUTHCK ; SET EVERYTHING UP PROPERLY + JRST POPJ1 +CCHFLS: .CLOSE OUTCHN, + PUSHJ P,OUTHC1 ; HACK ALL THE SWITCHES + JRST POPJ1 + +; PRINT A PROMPT. +CPRMPT: MOVEI A,[ASCIZ /: /] + XCT COMPRT + POPJ P, + +; DDT--'D' COMMAND +CDDT: .SUSET [.SIPIRQC,,[%PIC.Z]] + JRST POPJ1 + +; SET ERROR STRINGS--'E' COMMAND +CERROR: PUSHJ P,CPRMPT ; PRINT A PROMPT + XCT COMGLN ; GET NEW ONES + JRST POPJ1 ; IF DOESN'T SKIP, IGNORE IT + SETZM ERRORS + JUMPE A,POPJ1 + PUSH P,E ; GET AN EXTRA AC + PUSH P,B ; SAVE BPTR +CERLST: MOVEI C,0 +CERLOP: ILDB D,B + CAIN D,", + SOJA A,CERMAK ; UPDATE COUNT AND MAKE THE NEW BLOCK + CAIN D,^Q ; QUOTE CHARACTER? + JRST [ILDB D,B ; GOBBLE THE NEXT CHAR + SOJG A,CERLOP ; AND DON'T UPDATE THE COUNT + JRST CERMAK] + ADDI C,1 ; LENGTH OF STRING + SOJG A,CERLOP +; MAKE A NEW ERROR BLOCK. LENGTH OF STRING IS IN C, POINTER TO FIRST +; CHAR IS (P). +CERMAK: JUMPE C,CERMAE ; NO NULL STRINGS ALLOWED + IBLOCK E,ERRBLK ; GET AN ERROR BLOCK + MOVE D,ERRORS + MOVEM D,ENEXT(E) + MOVEM E,ERRORS ; SPLICE IT INTO CHAIN + MOVEM C,EMATLN(E) + MOVEM C,ELENGTH(E) ; SET UP LENGTHS + IDIVI C,5 + SKIPE D + ADDI C,1 ; # WORDS NEEDED FOR STRING + IBLOCK C,(C) ; GET STORAGE FOR IT + HRLI C,440700 + MOVEM C,EMATCH(E) + MOVEM C,ESTRING(E) ; STUFF OUT BPTRS + EXCH B,(P) ; GET POINTER TO FIRST CHAR + MOVE E,ELENGTH(E) ; GET LENGTH +CERCLP: ILDB D,B + CAIN D,^Q + ILDB D,B + IDPB D,C ; STUFF THE CHARACTER OUT + SOJG E,CERCLP + MOVE B,(P) +CERMAE: JUMPN A,CERLST ; IF CHARS LEFT, GO GET THE NEXT ONE + POP P,B + POP P,E + JRST POPJ1 + +; TOGGLE STATE OF OUTPUT FORCING--'F' COMMAND +CFORCE: SETCMM FORCSW + JRST POPJ1 + +; HALT JOB--'H' COMMAND +CHALT: .IOT STYO,[^Z] + PUSHJ P,CTTYB + POPJ P, + JRST POPJ1 + +; SET INTERCEPT CHARACTER--'I' COMMAND +CINTER: PUSHJ P,CPRMPT + XCT COMGLN ; GET A LINE OF INPUT + JFCL + JUMPE A,POPJ1 ; NULL INPUT + ILDB A,B + MOVEM A,ESCAPE ; NEW INTERCEPT + JRST POPJ1 + +; UNDO EFFECTS OF 'R' COMMAND--'J' COMMAND +CNREMA: SETZM JOBFRC ; JUST CLEAR THE FLAG + JRST POPJ1 + +; PROCED XXFILE--'P' COMMAND +CPROCE: .VALUE [ASCIZ /:PROCED +J/] + JRST POPJ1 + +; QUIT--'Q' COMMAND +CQUIT: .SUSET [.ROPTIO,,A] + TLNE A,OPTDDT + .VALUE [ASCIZ \..SAFE/0 +P\] + .CLOSE OUTCHN, + .CLOSE STYI, + .CLOSE STYO, + .LOGOUT 1, + +; FORCE INPUT TO GO TO THE CURRENT JOB UNTIL 'J' COMMAND--'R' COMMAND +CREMAN: .CALL [SETZ + SIXBIT /STYGET/ + MOVEI STYO + MOVEM A + SETZM A] + .LOSE %LSSYS + JUMPL A,CPOPJ ; NOBODY HAS THE STY + MOVEM A,JOBFRC ; OTHERWISE, A HAS THE INDEX + JRST POPJ1 + +; STOP TTY INPUT--'S' COMMAND +CTTYE: SKIPN TTYSRC + JRST POPJ1 ; NOT IN TTY INPUT + PUSHJ P,RSTTTY ; FROB ALL THE SWITCHES AND CHANNELS AND SUCH + .CALL [SETZ + SIXBIT /STYGET/ + MOVEI STYO + MOVEM A + MOVEM A ; JOB OWNING TTY + MOVEM B + SETZM B] ; WAITING FOR CHARS? (BIT 1.1) + .LOSE %LSSYS ; READ STATUS OF TTY + JUMPL A,CTTYST + TLNN B,400000 ; SEE IF TTY WANTS CHARS + POPJ P, ; NOPE +CTTYST: .SUSET [.SIIFPIR,,[<1_STYO>]] ; CAUSE THE INTERRUPT + POPJ P, + +; SET CTRL-T CHARACTER--'T' COMMAND +CCTRLT: PUSHJ P,CPRMPT + XCT COMGLN + JFCL + JUMPE A,POPJ1 + ILDB A,B + MOVEM A,CTRLT + JRST POPJ1 + +; VALRET STRING--'V' COMMAND +CVALUE: PUSHJ P,CPRMPT ; PRINT PROMPT + XCT COMGLN ; GET A LINE + JRST POPJ1 + JUMPE A,POPJ1 + EXCH A,B + PUSHJ P,STRGET ; GET STRING INTO B AND C + HRRZS C + .VALUE (C) + JRST POPJ1 + +SUBTTL TTY INTERACTIONS + +; COME HERE TO SET THINGS UP FOR TTY INTERACTIONS--APPROPRIATE TTYSETS, +; MOVING OF CURSOR, SETTING UP OF ECHO AREA (IF IT DOESN'T ALREADY EXIST), +; AND SO ON. UNFORTUNATELY, ALL CHARACTERS INTERRUPT IN THIS MODE. +; REQUIREMENTS: THIS WILL OFTEN FALL IN THE MIDDLE OF A FILE, SO IT +; MIGHT BE NICE IF EVERYTHING WERE CONSISTENT. WHEN THE 'B' COMMAND IS +; GIVEN FROM A FILE, IT WILL BE; WHEN GIVEN FROM THE TTY, WE WIN ONLY +; BECAUSE TTYI INTERRUPTS ARE DEFERRED BY STYO INTERRUPTS. + +SETTTY: PUSH P,A + PUSH P,B + PUSH P,C + .SUSET [.SAMSK2,,[<1_STYO>]] ; DISABLE STYO INTERRUPTS + .SUSET [.SIDF2,,[<1_TTYI>]] ; DEFER TTY INTERRUPTS (IF NOT ALREADY) + .SUSET [.SAIFPI,,[<1_STYO>]] ; AND FLUSH ANY PENDING STY INTERRUPTS + MOVE A,TTTST1 + MOVEM A,CTTST1 + MOVE A,TTTST2 + MOVEM A,CTTST2 + MOVE A,CTTSTS + TLO A,%TSSII + MOVEM A,CTTSTS + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYI + TTTST1 + TTTST2 + SETZ A] ; ENABLE INTERRUPTS, SUPER-IMAGE INPUT + .LOSE %LSSYS + SKIPN ECHOQ ; DOES ECHO AREA EXIST? + JRST [MOVEI A,2 + .CALL [SETZ + SIXBIT /SCML/ + MOVEI TTYI + SETZ A] + .LOSE %LSSYS + MOVEM A,ECHOQ + JRST .+1] ; TURN IT ON + .CALL [SETZ + SIXBIT /OPEN/ + [.UAO,,TTYO] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE %LSFIL ; OPEN TTY FOR NORMAL OUTPUT + SETOM TTYSRC ; SET FLAG SO RECBUO WILL USE THIS + SETZM NULOUT ; THERE IS SOME OUTPUT CHANNEL + .CALL [SETZ + SIXBIT /TTYGET/ + MOVEI STYO + MOVEM A + MOVEM B + SETZM C] + .LOSE %LSSYS + TLO C,%TSMOR + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI STYO + A + B + SETZ C] + .LOSE %LSSYS + .CALL [SETZ + SIXBIT /TTYVAR/ + MOVEI STYO + [SIXBIT /TTYOPT/] + MOVEI 0 + SETZ [TLO %TOMOR]] + .LOSE %LSSYS ; TURN ON MORE HACKING IN OTHER JOB + .CALL [SETZ + SIXBIT /RCPOS/ + MOVEI STYO + SETZM A] + .LOSE %LSSYS + HLRZ B,A + HRRZS A + OVPOS TTYO,(B) + OHPOS TTYO,(A) ; MOVE CURSOR TO CORRESPOND WITH IMAGE + OCTLP TTYO,"L ; FLUSH TO END OF LINE + SKIPN DSKOUT ; IS THERE ANOTHER OUTPUT CHANNEL OPEN? + JRST SETTTO + SKIPN DSKCHN ; IS IT DISK-STYLE? + SETZM DSKOUT ; NO, SO FLUSH IT--DON'T WANT TWO TTYO CHANNELS +SETTTO: SETZM DSKCHN ; DO OUTPUT FOR TTY, NOT FOR DSK + POP P,C + POP P,B + POP P,A + POPJ P, + +; INVERT SETTTY. +RSTTTY: PUSH P,A + PUSH P,B + PUSH P,C + MOVE A,NTTST1 + MOVEM A,CTTST1 + MOVE A,NTTST2 + MOVEM A,CTTST2 + MOVE A,CTTSTS + TLZ A,%TSSII + MOVEM A,CTTSTS ; TURN OFF SUPER-IMAGE INPUT + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYI + NTTST1 + NTTST2 + SETZ A] + .LOSE %LSSYS + SETZM TTYSRC + PUSHJ P,OUTHC1 ; SET OUTPUT FLAGS CORRECTLY + .CLOSE TTYO, + .CALL [SETZ + SIXBIT /TTYGET/ + MOVEI STYO + MOVEM A + MOVEM B + SETZM C] + .LOSE %LSSYS + TLZ C,%TSMOR + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI STYO + A + B + SETZ C] + .LOSE %LSSYS + .CALL [SETZ + SIXBIT /TTYVAR/ + MOVEI STYO + [SIXBIT /TTYOPT/] + MOVEI O + SETZ [TLZ %TOMOR]] + .LOSE %LSSYS + .SUSET [.SIMSK2,,[<1_STYO>]] ; RE-ENABLE STYO INTERRUPTS + POP P,C + POP P,B + POP P,A + POPJ P, + +; TTY INTERRUPT HANDLER +TTYINT: MOVEI O,TTYI ; O, A, B ALREADY PUSHED + .ITYIC O, ; GET THE CHAR IN O + .CALL DISMIS + CAME O,ESCAPE ; ESCAPE CHARACTER? + JRST TTYOTC ; NO, SEE IF WANT TO SHIP TO STY OR DO CTRL-T + .CALL [SETZ + SIXBIT /TTYFLS/ + MOVEI TTYI + ANDI 1] + .LOSE %LSSYS ; FLUSH STUFF TYPED AHEAD + PUSH P,C + SKIPN TTYSRC ; INPUT FROM TTY? + JRST TTYCOM + MOVE C,CTTSTS + TLZN C,%TSSII ; TURN OFF SUPER-IMAGE INPUT + JRST TTYCOM ; NOT ON, SO NO NEED + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYI + CTTST1 + CTTST2 + SETZ C] + .LOSE %LSSYS + MOVNI A,2 + MOVEM A,SIIFLG ; SET FLAG FOR REALTIME INTERRUPT +TTYCOM: PUSHJ P,ECINIT ; CLEAR/CR IN "ECHO AREA" + OASC ECHO,[ASCIZ /Command: /] +TTYGCM: .CALL TTYIOT ; READ THE COMMAND CHAR + .LOSE %LSSYS + SETZM SIIFLG ; CLEAR THE FLAG + MOVE A,O + PUSHJ P,COMND + PUSHJ P,GETLIN + PUSHJ P,TTYPRT + JFCL ; DOESN'T MATTER +TTYCFL: SKIPN TTYSRC + JRST TTYEND + MOVE A,CTTSTS + TLO A,%TSSII + MOVEM A,CTTSTS + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYI + CTTST1 + CTTST2 + SETZ A] + .LOSE %LSSYS ; TURN SII BACK ON +TTYEND: POP P,C + .CALL DISMIS ; AND FLUSH +; COME HERE TO SEE IF CHAR WANTS TO GO OUT TO STY +TTYOTC: .CALL [SETZ + SIXBIT /TTYFLS/ + MOVEI TTYI + ANDI 1] + .LOSE %LSSYS + CAMN O,CTRLT ; CONTROL T? + JRST TTYCTT + SKIPN TTYSRC ; INPUT IS TTY? + .CALL DISMIS ; NO + .IOT STYO,O ; YES, SO SHIP IT. + .CALL DISMIS + +; NORMAL IOT FOR READ CHARS FROM TTY (INTO O, AS IT TURNS OUT) +TTYIOT: SETZ + SIXBIT /IOT/ + MOVEI TTYI + MOVSI %TIECH+%TIINT+%TIACT + SETZ O ; READ NO MATTER WHAT + +; ROUTINE TO CLEAR ECHO AREA IF IT EXISTS, OTHERWISE PRINT CR +ECINIT: SKIPE ECHOQ + JRST [OCTLP ECHO,"C ; CLEAR THE ECHO AREA IF IT EXISTS + POPJ P,] + OASCR ECHO,[0] + POPJ P, + +SUBTTL JOB STATUS + +; HERE TO DISPLAY STATUS OF JOB AT OTHER END OF STY. WHEN DONE, +; JUST DO .CALL DISMIS +TTYCTT: PUSHJ P,ECINIT ; WILL GO IN ECHO AREA + .SUSET [.SADF2,,[<1_STYO>]] ; ALLOW STYO INTERRUPTS HERE + PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + PUSH P,U + MOVEI E,0 + MOVE F,[440700,,STTBUF] ; INITIALIZE AC'S FOR UUOS + OASCB E,"T + OOCTA E,T ; PRINT 'Tnn' + HRRZ U,@TTYSTS ; PICK UP THE USER INDEX (TTYSTS IS (T)) + CAIN U,777777 ; LOGGED OUT? + JRST [OASCA E,[ASCIZ / Logged out./] + JRST TTOTST] ; YES, FLUSH IMMEDIATE (ALMOST) + OASCB E,40 + MOVE A,U + IDIV A,LUBLK + OOCTA E,A ; USER INDEX + OASCB E,40 + OSIXA E,@JNAME + OASCB E,40 + OSIXA E,@USYSNM ; JNAME AND SNAME + OASCB E,40 + SKIPN STIFLG ; ARE WE GETTING INPUT? + JRST TTSTOF + OASCA E,[ASCIZ /<=/] +TTSTOF: SKIPN STOFLG ; ARE WE SENDING STUFF? + JRST TTSTST + SKIPN STIFLG + OASCB E,"= + OASCB E,"> +; PRINT STATUS OF JOB +TTSTST: PUSHJ P,JSTATU ; GROSS ROUTINE RIPPED OFF FROM WHOIML + OASCB E,40 + MOVE A,@JTMU + ADDI A,9830. + IDIVI A,19661. ; MAGICALLY PRODUCES % + ODECA E,A + OASCA E,[ASCIZ /% /] + MOVE A,@UTRNTM ; TIME USED + MOVEI C,0 + IDIVI A,25000. ; IN 10TH'S + IDIVI A,36000. ; HOURS + JUMPE A,UTRNT1 ; DON'T PRINT IF 0 + ODECA E,A + OASCB E,": + MOVNI C,1 ; SET FLAG +UTRNT1: MOVE A,B + IDIVI A,600. ; MINUTES + JUMPN C,[CAIGE A,10. + OASCB E,"0 + ODECA E,A + JRST UTRNT2] + JUMPE A,UTRNT3 + MOVNI C,1 + ODECA E,A +UTRNT2: OASCB E,": +UTRNT3: MOVE A,B + IDIVI A,10. ; SECONDS + JUMPN C,[CAIGE A,10. + OASCB E,"0 + JRST .+1] + ODECA E,A + OASCB E,". + ODECA E,B + OASCB E,40 +TTOTST: .SUSET [.SIDF2,,[<1_STYO>]] + SKIPN A,INPSRC + JRST [MOVEI B,100. ; READ EVERYTHING + JRST PERCRD] + MOVE B,OUTRED(A) + IMULI B,100. + IDIV B,OUTTLN(A) ; % OF CURRENT SOURCE READ +PERCRD: ODECA E,B + OASCA E,[ASCIZ /%RD /] + MOVE F,[440700,,STTBUF] + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI ECHO + F + SETZ E] + .LOSE %LSSYS + SKIPN B,LSTLEN + JRST TTSTOT + MOVE A,LSTPTR ; POINTER TO SAVED STUFF + LDB C,[360600,,A] + IDIVI C,7 ; # OF CHARS IN FIRST WORD + ADDI C,*5 ; MAX # OF CHARS WE HAVE + CAIL B,(C) + MOVEI B,(C) ; IF LESS THAN # SAVED, USE IT + ILDB C,A + CAIE C,^J + JRST [DBP A + JRST LSLNF] ; FLUSH LEADING CTRL-J + SUBI B,1 +LSLNF: MOVEM B,LSTTMP + MOVE C,[440700,,LSTBUF] +LSLOOP: ILDB O,A ; PICK UP CHAR + CAILE O,^Z + JRST LSLOPE + ADDI O,100 + MOVEI D,"^ + IDPB D,C + AOS LSTTMP +LSLOPE: IDPB O,C + SOJG B,LSLOOP + MOVE A,[440700,,LSTBUF] + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI ECHO + A + SETZ LSTTMP] + .LOSE %LSSYS +TTSTOT: POP P,U + POP P,F + POP P,E + POP P,D + POP P,C + .CALL DISMIS ; ALL DONE + +; HACK TO PRINT STATUS OF JOB WHOSE INDEX IS IN U, STOLEN FROM WHOIML +JSTATU: MOVEI A,0 + SKIPN @PICLR + MOVEI A,"* ; HACKING INTERRUPT + SKIPN @IDF1 + SKIPE @IDF2 + MOVEI A,"* ; HACKING INTERRUPT + SKIPGE B,@USWST + MOVEI A,"_ ; DESIRED OUT + SKIPGE @USWSCD + MOVEI A,"> ; SWAP-BLOCKED + SKIPE A + OASCB E,(A) + SKIPE A,@USTP ; RUNNING? + JRST JRUN1 + SKIPE @FLSINS ; BLOCKED? + JRST JHAIR + MOVE B,@UPC + TLNN B,%PCUSR ; USER MODE? + JRST JEHAIR ; EXEC MODE + MOVE A,@JTMU + ADDI A,9830. + IDIVI A,19661. + MOVEI B,6 + CAIGE A,2 + JRST [MOVE B,A + JRST JRUNST] + CAIG A,10. + JRST [MOVEI B,2 + JRST JRUNST] + CAIG A,49. + JRST [MOVEI B,3 + JRST JRUNST] + CAIG A,79. + JRST [MOVEI B,4 + JRST JRUNST] + CAIG A,89. + MOVEI B,5 +JRUNST: OASCA E,@RUNTBL(B) + +JSTAT2: SKIPN A,@RPCL ; RPCLSR'ING? + POPJ P, + SKIPL A + OASCB E,"> + SKIPG A + OASCB E,"< + ANDI A,-1 + IDIV A,LUBLK + OOCTA E,A + POPJ P, + +; NOT RUNNING. USTP IS IN A +JRUN1: LSHC A,-30. + OOCTA E,A ; LEFT TWO DIGITS OF USTP + OASCB E,"! + LSH B,-6 + OOCTA E,B + JRST JSTAT2 ; GO CHECK FOR PCLSR-ING + +; NON-ZERO FLSINS. USWST IS IN B +JHAIR: TLNN B,200000 + JRST HAIR + MOVE A,[SIXBIT /IPAGE/] + TLNN B,10000 + MOVE A,[SIXBIT /PAGE/] + OSIXA E,A + JRST JSTAT2 + +; IN EXEC MODE, FOLLOWED BY HAIR FOR SYS CALLS. +JEHAIR: OASCB E,"+ +HAIR: SKIPGE A,@SV40 + JRST IOTUUO + LSH A,-27. + CAIG A,47 ; SKIP IF TOO BIG FOR SYS UUO + CAIGE A,40 ; SKIP IF SYS UUO + SKIPA A,[SIXBIT /UUO/] ; USER UUO + XCT UUOTB-40(A) ; DISPATCH/PICK UP MNEMONIC +HAIR1: OSIXA E,A + JRST JSTAT2 + +IOTUUO: LDB A,[270300,,A] + MOVE A,UIOTAB(A) + JRST HAIR1 + +UIOTAB: IRPS A,,[BLKI DATAI BLKO DATAO CONO CONI CONSZ CONSO] + SIXBIT /A/ + TERMIN + +UUOTB: JRST AIOT ; IOT + MOVE A,[SIXBIT /OPEN/] + JRST AOPER ; .OPER + JRST ACALL ; .CALL + MOVE A,[SIXBIT /USET/] + MOVE A,[SIXBIT /BREAK/] + MOVE A,[SIXBIT /STATUS/] + MOVE A,[SIXBIT /ACCESS/] + +AIOT: LDB C,[270400,,@SV40] ; .IOT, GET AC + MOVEI D,0 +AIOT1: MOVEI A,@IOCHNM + ADD A,U + HRRZ C,(A) + PUSHJ P,AIOTNM + JRST JSTAT2 + +AIOTNM: MOVEI B,(C) + HLL A,@CLSTB + TLNN A,100040 + JRST AIOTN1 + HLRZ C,(A) + SKIPA A,@JBDEV +AIOTN1: HLLZ A,@DCHSTB + OSIXA E,A + MOVEI C,(B) + MOVE O,@IOTTB + TLNE O,400000 + JRST [OASCB E,"B + JRST AIOTN2] + CAMN D,[SIXBIT /SIOT/] + JRST [OASCB E,"S + JRST AIOTN2] +AIOTN2: MOVEI C,"I + TLNE O,200000 + MOVEI C,"O + OASCB E,(C) + POPJ P, + +; HACK .CALL +ACALL: LDB C,[270400,,@SV40] ; AC + JUMPE C,ACALLO + OSIX @CALSXB + JRST JSTAT2 + +ACALLO: MOVE C,@LSCALL + CAME C,[SIXBIT /SIOT/] + CAMN C,[SIXBIT /IOT/] + JRST ACALL1 + OSIXA E,@LSCALL + JRST JSTAT2 + +ACALL1: SKIPE C,@UUAC + MOVE D,@LSCALL + JRST AIOT1 + +; HACK .OPER +AOPER: HRRZ C,@SV40 + MOVE A,CALSXB + SUB A,OPRSXB + CAML C,A + MOVEI C,0 + OSIXA E,@OPRSXB + JRST JSTAT2 + +RUNTBL: [ASCIZ /MULTIX/] + [ASCIZ /TENEX/] + [ASCIZ /WALK/] + [ASCIZ /RUN/] + [ASCIZ /FLY/] + [ASCIZ /ZOOM/] + [ASCIZ /WARP/] + +SUBTTL TTY READER + +; ROUTINE FOR PRINTING WHEN IN COMMAND READER FROM TTY +; CALLED WITH ADDRESS OF ASCIZ IN A. +TTYPRT: OASC ECHO,(A) + POPJ P, + +; ROUTINE TO READ A LINE FROM TTY FOR COMMAND READER +; RETURN LENGTH OF LINE IN A, POINTER TO IT IN B. +; SKIPS USUALLY, FAILING ONLY IF RUBOUT TYPED WHEN BUFFER EMPTY +; (TO ALLOW USER TO ABORT). +GETLIN: PUSH P,C + PUSH P,D + MOVE C,TTYOPT + SETZM TOERS + TLNE C,%TOERS + SETOM TOERS ; SET UP FOR ERASURE IF POSSIBLE + .CALL [SETZ + SIXBIT /RCPOS/ + MOVEI ECHO + MOVEM C + SETZM ECCPOS] + .LOSE %LSSYS ; SAVE CURRENT CURSOR POSITION +GETRST: MOVEI A,0 + MOVE B,[440700,,TTYBUF] +GETLOP: .CALL TTYIOT ; READ A CHARACTER INTO C + .LOSE %LSSYS + CAIN O,177 ; RUBOUT? + JRST RUBOUT + CAIN O,^W ; WORD FLUSH? + JRST WDFLUS + CAIE O,^X + CAIN O,^U + JRST LNFLUS ; FLUSH WHOLE LINE + JUMPE O,LNFLUS + CAIE O,^L + CAIN O,^D + JRST BREDIS ; REDISPLAY BUFFER + CAIE O,^M + .IOT ECHO,O ; ECHO THE CHARACTER--EXCEPT CTRL-M + CAIN O,^Q ; QUOTE CHARACTER + JRST QUOTER +GETPUT: CAIN O,^M + JRST GETLO1 ; DONE + IDPB O,B ; STUFF INTO BUFFER + AOJA A,GETLOP ; GET THE NEXT ONE +GETLO1: AOS -2(P) ; SKIP--> USE THIS DATA +GETLOT: OASC ECHO,[ASCIZ / [CR]/] + MOVE B,[440700,,TTYBUF] + POP P,D + POP P,C + POPJ P, + +; QUOTE A CHAR +QUOTER: .CALL TTYIOT ; READ THE CHAR + .LOSE %LSSYS + SKIPN TOERS + JRST QUOTOT ; NOTHING SPECIAL + OCTLP ECHO,"X + OCTLP ECHO,"X ; FLUSH THE ^Q +QUOTOT: .IOT ECHO,O + JRST GETPUT + +; FLUSH THE WHOLE LINE +LNFLUS: SKIPN TOERS ; ON A DISPLAY? + JRST [OASCR [ASCIZ /XXX?/] + JRST GETRST] + PUSHJ P,RSTPOS ; RESTORE CURSOR POSITION + OCTLP ECHO,"E ; CLEAR TO END OF FILE + JRST GETRST + +; RESTORE CURSOR POSITION TO ORIGINAL +RSTPOS: SKIPN TOERS + POPJ P, + PUSH P,A + HLRZ A,ECCPOS + OVPOS ECHO,(A) + HRRZ A,ECCPOS + OHPOS ECHO,(A) + POP P,A + POPJ P, + +; REDISPLAY BUFFER +BREDIS: PUSHJ P,RSTPOS + OCTLP ECHO,"E + PUSH P,A + PUSH P,B + MOVE B,[440700,,TTYBUF] + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI ECHO + B + SETZ A] + .LOSE %LSSYS + POP P,B + POP P,A + POPJ P, + +RUBOUT: JUMPE A,GETLOT ; FLUSH IF RUBOUT WHEN BUFFER EMPTY + PUSHJ P,DORUB ; DO THE RUBOUT, GET CHAR KILLED INTO C + JRST GETLOP ; AND RETURN + +DORUB: SUBI A,1 + LDB C,B ; PICK UP CHAR BEING FLUSHED + DBP B ; UPDATE POINTER + SKIPN TOERS + JRST RUBECH ; IF CAN'T ERASE, ECHO + OCTLP ECHO,"X ; ERASE ONE + CAIN C," ; ALTMODE IS ONLY ONE LONG + POPJ P, + CAIE C,177 + CAIGE C,40 + OCTLP ECHO,"X ; ERASE ANOTHER, SOMETIMES + POPJ P, +RUBECH: .IOT ECHO,C + POPJ P, + +; FLUSH A WORD +WDFLUS: JUMPE A,GETLOT ; FLUSH IMMEDIATE +WDLP1: PUSHJ P,DORUB ; FLUSH A CHAR + PUSHJ P,BREAK ; WAS IT A BREAK? + JUMPN A,WDFLU1 ; NO, AND THERE ARE CHARACTERS LEFT + JUMPN A,WDLP1 ; YES, FLUSH ANOTHER + JRST GETLOP ; ALL DONE +WDFLU1: PUSHJ P,DORUB + PUSHJ P,BREAK + JUMPN A,WDFLU1 ; KEEP FLUSHING UNTIL BREAK ENCOUNTERED + JRST GETLOP +; IS CHAR IN C A BREAK? +BREAK: CAIE C,"? + CAIN C,". + JRST BREAKW + CAIE C,"! + CAIN C,", + JRST BREAKW + CAIE C,40 + CAIN C,^I + JRST BREAKW + CAIE C,"- + CAIN C,^J +BREAKW: AOS (P) + POPJ P, + +SUBTTL INTERRUPTS + +; INTERRUPT TABLE +ACPUSH==400003 ; PUSH O,A,B, + DEBUGGING VARIABLES +TSINT: ACPUSH,,P ; P IS AC STACK + %PIATY ? 0 ? %PIRLT\%PIATY ? <1_TTYI>\<1_STYO>\<1_STYI> ? TSATTY + 0 ? <1_TTYO> ? 0 ? <1_STYI>\<1_STYO> ? [.CALL DISMIS] + 0 ? <1_STYI> ? 0 ? <1_STYO>\<1_STYI> ? TSSTYI + 0 ? <1_STYO> ? %PIRLT ? <1_TTYI>\<1_STYO> ? TSSTYO + 0 ? <1_TTYI> ? 0 ? <1_TTYI>\<1_STYO> ? TTYINT + %PIRLT ? 0 ? %PIRLT\%PIATY ? 0 ? TSRLT +TSINTL==.-TSINT + +TSRLT: AOSE SIIFLG ; NEED TO TURN SII BACK ON? + JRST TSRLT1 + SKIPN TTYSRC + JRST TSRLT2 + HRRZ A,-6(P) ; PICK UP OLD PC + CAIE A,TTYGCM ; HANGING IN IOT? + JRST [SETOM SIIFLG + JRST TSRLT1] ; NOPE + MOVEI A,TTYCFL + HRRM A,-6(P) ; CAUSE DISMISS TO RIGHT PLACE +TSRLT1: SKIPE TTYSRC + .CALL DISMIS +TSRLT2: SKIPE @INPSRC ; LAST INPUT BLOCK? + .CALL DISMIS + .CALL [SETZ + SIXBIT /STYGET/ + MOVEI STYO + MOVEM A + MOVEM A + MOVEM B + SETZM B] + .CALL DISMIS ; PROBABLY DON'T HAVE IT YET + JUMPL A,CQUIT ; FLUSH IF LOGGED OUT + TLNN B,400000 ; DOES HACKER WANT INPUT? + .CALL DISMIS + .SUSET [.SIIFPIR,,[<1_STYO>]] ; GIVE HIM SOME + .CALL DISMIS + +; ATTY INTERRUPT +TSATTY: MOVE O,-6(P) ; PICK UP THE PC + TLNE O,%PC1PR ; BEING SINGLE-STEPPED, SO FLUSH + .CALL DISMIS + SKIPE TTYSRC ; INPUT FROM TTY? + JRST TSATY1 ; YES, SO HAVE WORK TO DO + SKIPN DSKOUT ; OUTPUT SOMEWHERE? + .CALL DISMIS ; NO + SKIPE DSKCHN ; AND TO TTY-LIKE DEVICE? + .CALL DISMIS + SKIPE NULOUT + .CALL DISMIS +TSATY1: .CALL [SETZ + SIXBIT /RCPOS/ + MOVEI STYO + SETZM A] + .LOSE %LSSYS + HLRZ B,A ; GET VERTICAL POS + HRRZS A + SKIPN TTYSRC + JRST [OVPOS OUTCHN,(B) + OHPOS OUTCHN,(A) + OCTLP OUTCHN,"L ; CLEAR TO END OF LINE + JRST TSATTO] + OVPOS TTYO,(B) + OHPOS TTYO,(A) + OCTLP TTYO,"L + MOVE A,CTTSTS + TLO A,%TSSII + MOVEM A,CTTSTS + .CALL [SETZ + SIXBIT /TTYSET/ + MOVEI TTYO + CTTST1 + CTTST2 + SETZ A] + .LOSE %LSSYS +TSATTO: .CALL DISMIS + +TSSTYI: MOVEM P,IERRST ; SAVE STACK FOR RETURNS + SETOM STIFLG + PUSHJ P,RECSTR + SETZM IERRST + SETZM STIFLG + .CALL DISMIS +DISMIS: SETZ + SIXBIT /DISMIS/ + MOVSI ACPUSH + SETZ P + +TSSTYO: MOVE O,ERRSTK + MOVEM P,ERRSTK + PUSH P,O + SETOM STOFLG + PUSHJ P,SNDSTR + SETZM STOFLG + POP P,ERRSTK + .CALL DISMIS + +SUBTTL ERROR UUO + +; COME HERE FROM UUO HANDLER. O-E HAVE BEEN PUSHED, EFFECTIVE +; ADDRESS IS IN UUOE, CONTENTS OF EFF ADDR IN UUOE, AC IN E. +UERROR: .SUSET [.SPICLR,,[0]] ; NO INTERRUPTS + SETZM NOCNSL + SKIPL CNSFLS ; SWITCH SET? + JRST UERRGO + .SUSET [.RCNSL,,A] ; CONSOLE? + SKIPL A + JRST UERRGO + SETOM NOCNSL + .SUSET [.RIOS+OUTCHN,,A] + JUMPN A,UERRGT + .CALL [SETZ + SIXBIT /OPEN/ + [.UAO,,OUTCHN] + [SIXBIT /NUL/] + [SIXBIT /NUL/] + SETZ [SIXBIT /NUL/]] + .LOSE %LSFIL +UERRGT: .IOPUSH OUTCHN, + .IOPOP ECHO, ; WHAT A HACK + OASCR ECHO,[0] +UERRGO: SETOM ERESET ; CAUSE ERROR STRINGS TO BE RESET NEXT TIME + MOVE A,UUOE(P) ; SAVE EFFECTIVE ADDRESS + CAIE E,2 ; IF INPUT ERROR, DON'T GO TO TTY INPUT + SKIPGE NOCNSL ; SIMILARLY IF NOCNSL + JRST UERRO0 + SKIPN TTYSRC + PUSHJ P,SETTTY ; SET UP TTY INPUT +UERRO0: SKIPL NOCNSL + OCTLP ECHO,"C + SOJE E,UERFIL ; FILE-TYPE ERROR + SOJE E,UERINP ; INPUT FAILURE +UERRO1: OASC ECHO,[ASCIZ /ERROR: /] + OASC ECHO,(A) +UERROT: SKIPN ERRSTK + JRST UERREX + SKIPGE NOCNSL + JRST CQUIT ; FLUSH + MOVE P,ERRSTK ; HAVE A PLACE TO DISMISS TO + .CALL DISMIS ; WILL RESET .PICLR +UERREX: .SUSET [.SPICLR,,[-1]] + SKIPGE NOCNSL + JRST CQUIT + JRST UUORET +UERFIL: OASC ECHO,[ASCIZ /ERROR: /] + MOVEM A,INPSRC ; ADVANCE THE POINTER + MOVE B,OUTPTR(A) + MOVE C,OUTLEN(A) + .CALL [SETZ + SIXBIT /SIOT/ + MOVEI ECHO + B + SETZ C] + .LOSE %LSSYS + OASC ECHO,[ASCIZ / not found./] + SETZM OUTLEN(A) + JRST UERROT +UERINP: OASC ECHO,[ASCIZ /ERROR: /] + OASC ECHO,(A) ; PRINT THE MSG + SKIPN IERRST + JRST UERREX + MOVE P,IERRST + SKIPGE NOCNSL + JRST CQUIT + .CALL DISMIS ; AND AWAY WE GO + +SUBTTL INITIALIZATION + +; CALL WITH SYSTEM VERSION IN A +INIT: MOVEM A,SYSVER + MOVE A,[-200,,200] + MOVEI B,0 + .CALL [SETZ + SIXBIT /CORBLK/ + MOVEI %CBRED + MOVEI %JSELF + A + MOVEI %JSABS + SETZ B] + .LOSE %LSSYS ; CONS UP SYSTEM + MOVE A,USRVAR ; USER VARIABLES + PUSHJ P,DOEVAL + IOR B,[U,,400000] ; WILL ALL BE VAL+400000(U) + MOVE A,SYSCON ; CONSTANTS + PUSHJ P,DOEVAL + JFCL + MOVE A,SYSTBL + PUSHJ P,DOEVAL + IOR B,[C,,400000] ; VAL+400000(C) + MOVE A,TTYVAR + PUSHJ P,DOEVAL + IOR B,[T,,400000] + .SUSET [.ROPTIO,,A] + TLNE A,OPTDDT ; ONLY DUMP IF UNDER DDT + .VALUE [ASCIZ / :PDUMP SYS2;TS XXFILE +P/] + POPJ P, + +DOEVAL: MOVE B,(A) + .EVAL B, + .VALUE + XCT @(P) + MOVEM B,1(A) + ADD A,[2,,2] + JUMPL A,DOEVAL + AOS (P) + POPJ P, + +; CRUFT TO EVAL +USRVRS: IRPS X,,[JNAME:USYSNM:JTMU:UTRNTM:PICLR:IDF1:IDF2:USWST: +USWSCD:USTP:FLSINS:UPC:LSUUO:RPCL:SV40:LSCALL:UUAC] + SQUOZE 0,X +X: 0 + TERMIN +USRVAR: USRVRS-.,,USRVRS + +SYSCNS: IRPS X,,[LUBLK:NFSTTY] + SQUOZE 0,X +X: 0 + TERMIN +SYSCON: SYSCNS-.,,SYSCNS + +SYSTBS: IRPS X,,[IOCHNM:CLSTB:DCHSTB:IOTTB:JBDEV:CALSXB:OPRSXB] + SQUOZE 0,X +X: 0 + TERMIN +SYSTBL: SYSTBS-.,,SYSTBS + +TTYVRS: IRPS X,,[TTYSTS] + SQUOZE 0,X +X: 0 + TERMIN +TTYVAR: TTYVRS-.,,TTYVRS + + +CONSTA +VARIAB +FREBOT: .+2 +FRETOP: <<./2000>+1>*2000 +END START \ No newline at end of file