Trailing-Edge
-
PDP-10 Archives
-
bb-d868e-bm_tops20_v41_2020_dist_1of2
-
4-1-sources/ptycon.mac
There are 31 other files named ptycon.mac in the archive. Click here to see a list.
; UPD ID= 18, FARK:<5-WORKING-SOURCES.UTILITIES>PTYCON.MAC.3, 5-May-82 13:15:16 by MOSER
;EDIT 15 - CHANGE EDIT NUMBER TO 15.
; UPD ID= 5, FARK:<5-WORKING-SOURCES.UTILITIES>PTYCON.MAC.2, 5-Apr-82 09:14:41 by DONAHUE
;Edit 8 - Release log file at exit so LPT files printed
;<5.UTILITIES>PTYCON.MAC.7, 28-Oct-81 15:34:11, EDIT BY GRANT
;Change major version to 5
; UPD ID= 23, SNARK:<5.UTILITIES>PTYCON.MAC.6, 13-Aug-81 09:40:16 by DONAHUE
;TCO 5.1452 - Log the filename to a GET command into the log file
; UPD ID= 20, SNARK:<5.UTILITIES>PTYCON.MAC.5, 6-Aug-81 15:27:30 by DONAHUE
;TCO 5.1445 - If <esc> terminates jobname in DEFINE command, wait for more input
; UPD ID= 1768, SNARK:<5.UTILITIES>PTYCON.MAC.4, 25-Mar-81 17:48:44 by GRANT
;Update Copyright
; UPD ID= 1500, SNARK:<5.UTILITIES>PTYCON.MAC.3, 26-Jan-81 16:53:59 by MURPHY
;UPDATE LOG FILE LESS OFTEN
;IMPLEMENT SAVE (INPUT TO FILE) COMMAND
; UPD ID= 997, SNARK:<5.UTILITIES>PTYCON.MAC.2, 11-Sep-80 10:55:07 by SCHMITT
;TCO 5.1143 - Replace DING fork with a TIMER mechanism for dinging terminal
; UPD ID= 379, SNARK:<4.1.UTILITIES>PTYCON.MAC.3, 26-Mar-80 15:49:52 by KONEN
;TCO 4.1.1125 -- Correct PTY buffers overlapping each other
; UPD ID= 243, SNARK:<4.1.UTILITIES>PTYCON.MAC.2, 4-Feb-80 14:53:28 by MURPHY
;PREVENT HANG WHEN HIGH OUTPUT RATE FROM SUBJOB ON 2020 (TIMING PROB)
;<4.UTILITIES>PTYCON.MAC.9, 24-Oct-79 15:38:07, EDIT BY ENGEL
;ADD CODE TO AT PTYOU3 TO CHECK FOR PTY BUFFER FULL. DO DIBE IF IT IS FULL.
;<4.UTILITIES>PTYCON.MAC.8, 9-Oct-79 17:12:38, Edit by SCHMITT
;TCO 4.2522 - Remove RLJFN after GET for push to EXEC and supporting changes
;<4.UTILITIES>PTYCON.MAC.7, 27-Sep-79 18:10:48, EDIT BY SCHMITT
;TCO 4.2497 - Cure ghost characters from appearing in PTY's input buffer
;<4.UTILITIES>PTYCON.MAC.6, 13-May-79 13:38:16, EDIT BY MILLER
;<4.UTILITIES>PTYCON.MAC.5, 12-May-79 13:12:46, EDIT BY MILLER
;<4.UTILITIES>PTYCON.MAC.4, 12-May-79 13:11:59, EDIT BY MILLER
;<4.UTILITIES>PTYCON.MAC.3, 12-May-79 13:09:56, EDIT BY MILLER
;MORE
;<4.UTILITIES>PTYCON.MAC.2, 11-May-79 15:45:23, EDIT BY MILLER
;MAKE VARIOUS FIXES TO INSURE THAT CHARACTERS TYPED ON THE TTY
; HAVE THE CORRECT PARITY.
;<4.UTILITIES>PTYCON.MAC.1, 12-Mar-79 14:13:24, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
TITLE PTYCON - CONTROLLER FOR JOBS ON PTY'S
SUBTTL PETER M. HURLEY APRIL 18,1974
SEARCH MONSYM,MACSYM
IFNDEF .PSECT,<
.DIRECT .XTABM>
SALL
; VERSION NUMBER DEFINITIONS
VMAJOR==5 ;MAJOR VERSION OF PTYCON
VMINOR==0 ;MINOR VERSION NUMBER
VEDIT==^D15 ;EDIT NUMBER
VWHO==0 ;GROUP WHO LAST EDITED PROGRAM (0=DEC DEVELOPMENT)
VPTYCN== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT
A=1 ;TEMPORARY AC, NOT SAVED BY SUBROUTINES
B=2 ;TEMP
C=3 ;TEMP
D=4 ;TEMP
E=5 ;TEMP
Q1=6 ;PRESERVED ACS, MUST BE SAVED
Q2=7 ;PRESERVED AC
Q3=10 ;PRESERVED AC
P1=11 ;PRESERVED AC
P2=12 ;PRESERVED AC
P3=13 ;PRESERVED AC
P4=14 ;PRESERVED AC
I=15 ;PRESERVED, HOLDS CURRENT SUBJOB INDEX
P=17 ;PUSH DOWN AC
MAXPTC==^D80 ;SIZE OF THE PTY BUFFER
PTYNCH==6 ;# OF INTERRUPT CHANNELS FOR PTY'S
PTYCHN==^D24 ;STARTING AT 24, 2 CHANNELS PER PTY
;FLAGS IN LEFT HALF OF PTYSTS
PTIGNF==1 ;IGNORE OUTPUT FROM THIS PTY
PTREFF==2 ;REFUSE OUTPUT FROM THIS PTY
STDECH=="X"-100 ;STANDARD ESCAPE CHARACTER
STDESC==1B<STDECH> ;CHANNEL MASK FOR ESCAPE CHARACTER
CNTRLO==1B15 ;CONTROL-O MASK
TABSIZ==13 ;WIDTH OF A TAB FOR THE WHAT COMMAND
DEFINE BUG(X,Y)<
JRST [PUSH P,A
HRROI A,[ASCIZ/
? UNEXPECTED PTYCON ERROR: Y
/]
PUSHJ P,TTSOUT
POP P,A
IFIDN <X> <HLT>,<HALTF>
JRST .+1]>
DEFINE ERRMES (MESSAGE)<
PUSHJ P,[MOVEI A,100 ;CLEAR TYPE AHEAD
CFIBF
PUSHJ P,CHKLM ;ON LEFT MARGIN?
PUSHJ P,CRLF ;NO, TYPE CR-LF
HRROI A,[ASCIZ/MESSAGE
/]
JRST TTSOUT]>
DEFINE WRNMES (MESSAGE)<
PUSHJ P,[PUSHJ P,CHKLM ;ON LEFT MARGIN?
PUSHJ P,CRLF ;NO, TYPE CR-LF
HRROI A,[ASCIZ/MESSAGE
/]
JRST TTSOUT]>
DEFINE SYSGET(X)<
MOVE A,[SIXBIT/X/]
SYSGT
HRRZM B,X>
;PROGRAM ENTRY VECTOR
ENTVEC: JRST PTYCON ;STARTING LOCATION
JRST PTYCON ;REENTER LOCATION
VPTYCN ;VERSION NUMBER
PTYCON: MOVE P,[IOWD PDLEN,PDL] ;SET UP STACK
SETZM PUSHF ;NOT PUSHED DOWN A LEVEL NOW
SETZM IOWATF ;INITIALIZE WAITING FOR INTERRUPT FLAG
MOVE A,[SIXBIT/PTYPAR/] ;GET # OF PTYS IN SYSTEM
SYSGT ;...
HRRZM A,FIRPTY ;STORE TTY CORRESPONDENCE FOR PTY'S
HLRZS A ;GET NUMBER OF PTY'S IN SYSTEM
MOVEM A,SYSPTY ;REMEMBER THE NUMBER OF PTY'S ON SYSTEM
CAILE A,MAXPTY ;TOO HIGH?
MOVEI A,MAXPTY ;YES
MOVEM A,NUMPTY ;REMEMBER # OF PTYS
SYSGET (TTYJOB) ;GET TABLE # OF GETAB ENTRIES
SYSGET (JOBPNM)
SYSGET (SNAMES)
SYSGET (JOBRT)
MOVE A,[STDESC] ;SET UP ENABLE MASK FOR SUBJOBS
SKIPN ESCMSK ;WAS ONE ALREADY SET UP?
MOVEM A,ESCMSK ;NO, USE THE STANDARD ONE
MOVE A,[STDESC+CNTRLO] ;GET ENABLE MASK FOR TERMINAL INTERRUPTS
SKIPN TIMASK ;HAS THIS BEEN SET UP ALREADY?
MOVEM A,TIMASK ;NO, SET IT TO BE STANDARD
MOVEI A,STDECH ;GET STD ESCAPE CHARACTER
SKIPN TRPCHR ;BEEN SET UP YET?
MOVEM A,TRPCHR ;NO, SET IT UP ON FIRST TIME THROUGH
MOVEI A,400000 ;SET UP CAPABILITIES OF JOB
RPCAP ;GET CURRENT CAPABILITIES
TLNN B,(1B0) ;CAN WE ENABLE CONTROL-C INTERCEPT?
BUG(HLT,<CANNOT ENABLE FOR CONTROL-C INTERCEPT>)
TLON C,(1B0) ;YES, THEN DO IT
EPCAP ;SET THIS ENABLE BIT
MOVEI A,400000 ;NOW INITIALIZE THE INTERRUPT SYSTEM
DIR ;FIRST TURN IT OFF
SETOM PICNT ;INITIALIZE LEVEL OF PIOFF'S
MOVE B,[LEVTAB,,CHNTAB] ;SET UP PI SYSTEM
SIR
HRLZ A,TRPCHR ;ENABLE ESCAPE CHARACTER
HRRI A,TRPCHN ;ON ITS OWN CHANNEL
ATI ;...
MOVEI A,400000 ;NOW ACTIVATE ALL DESIRED CHANNELS
MOVE B,ONCHNS
AIC
EIR ;ENABLE PI SYSTEM
MOVEI A,100 ;SET TERMINAL MODE WORD
GDSTS ;GET PARITY ADD BIT
ERCAL [ SETZM B
RET] ;NO PARITY
ANDX B,GD%PAR ;ISOLATE INTERESTING BIT
MOVEM B,ADDPAR ;REMEMBER IT
RFMOD ;GET CURRENT MODE
SKIPN SAVMOD ;WAS IT SAVED BEFORE?
MOVEM B,SAVMOD ;NO, THIS IS FIRST TIME THROUGH
MOVE B,SAVMOD ;GET ORIGINAL MODE
TRO B,17B23!3B29!1B31 ;SET BREAK ON EVERYTHING, ASCII, UPPER
SFMOD ;...
STPAR ;...
RFCOC ;GET ECHO MODES
TRZ C,3B19 ;MAKE ALTMODES NOT ECHO
SFCOC
GTTYP ;GET TERMINAL TYPE ...
MOVEM B,SAVTYP ; ... AND SAVE IT
MOVEI A,100
MOVEM A,TERJFN ;USE NON-BINARY CHANNEL FOR COMMAND PARSING.
MOVE A,BINTTY ;GET ANY PREVIOUS BINARY CHANNEL.
CLOSF ;CLOSE IT
JFCL ;FAILURE PROBABLY BECAUSE IT WAS NEVER OPEN.
MOVSI A,(GJ%SHT) ;PREPARE TO OPEN BINARY CHANNEL ON TTY.
HRROI B,[ASCIZ /TTY:/] ;THIS IS FOR PIPELINE FOR SUBJOBS.
GTJFN
BUG(HLT,<COULDN'T GET HANDLE ON TTY FOR BINARY CHANNEL>)
MOVEM A,BINTTY ;SAVE THE BINARY CHANNEL.
MOVE B,[100000,,OF%WR+OF%RD]
OPENF ;OPEN IT IN BINARY MODE (IMPLIED BY 8 BIT BYTESIZE)
BUG(HLT,<COULDN'T OPEN THE TTY IN BINARY FOR PTY COMMUNICATION>)
JRST COMLVL ;GO TO COMMAND LEVEL
;COMMAND LEVEL
COMLVL: MOVE P,[IOWD PDLEN,PDL] ;SET UP A FRESH PUSH DOWN LIST
SETZM IOWATF ;CLEAR WAITING FOR INTERRUPT FLAG
SETZM NOFLAG ;INITIALIZE NEGATE FLAG
SETZM IGNORF ;CLEAR IGNORE FLAG
SETOB I,LSTHDR ;ALWAYS CLEAR SUBJOB INDEX
MOVNI A,5 ;NOW GRAB ALL TERMINAL INTERRUPT CHARS
RTIW ;READ CURRENT
SKIPN SAVTIW ;WAS IT SAVED ALREADY?
MOVEM B,SAVTIW ;NO, SAVE IT FOR EXITING
MOVE B,TIMASK ;ONLY ESCAPE CHARACTER AND CONTROL-O
STIW ; ARE SPECIAL
PUSHJ P,CHKLM ;SEE IF AT START OF LINE
PUSHJ P,CRLF ;NO, TYPE CR-LF
HRROI A,[ASCIZ/PTYCON> /] ;GET PROMPT MESSAGE
PUSHJ P,TTSOUT ;TYPE OUT PROMPT
TIME ;GET REAL TIME
SKIPE RDJFN ;INPUT COMING FROM FILE?
CAML A,NXLOGC ;YES, TIME TO UPDATE LOG?
CALL [ ADDI A,^D60000 ;COMPUTE TIME FOR NEXT UPDATE
MOVEM A,NXLOGC
CALLRET LOGCLS] ;CLOSE AND REOPEN LOG FILE IN CASE CRASH
COM0: MOVE A,TERJFN ;SEE IF ANYTHING IN TTY INPUT BUFFER
SIBE
JRST COM0A ;YES, DON'T TYPE OUT ANYTHING FROM PTY'S
SETZM TOFLAG ;INITIALIZE TTY OUTPUT FLAG
PUSHJ P,PTOCHK ;SEE IF ANY OUTPUT FROM SUBJOBS READY
SKIPE TOFLAG ;WAS ANYTHING TYPED ON TTY?
JRST COMLVL ;YES, START OVER AGAIN
COM0A: PUSHJ P,COMINI ;INITIALIZE COMMAND BUFFER FOR RDTXT
COM1: MOVEI A,100 ;INITIALIZE MODE OF TTY
MOVE B,SAVMOD ;
TLZ B,(1B0) ;CLEAR CNTRL-O
SFMOD ;
MOVEI A,100
MOVEM A,TERJFN ;USE REGULAR TTY CHANNEL FOR COMMAND INPUT.
PUSHJ P,RDSTR ;GET A COMMAND FROM TTY
JRST CHKPTO ;INTERRUPT OCCURRED BEFORE DONE
PUSH P,A ;SAVE TERMINATOR CHARACTER
CAIE A,"!" ;A NEW FLAVOR COMMENT?
CAIN A,";" ;OR AN OLD FLAVOR COMMENT
JRST COMENT ;POSSIBLY
CAIN A,3 ;CONTROL-C?
JRST COMCC ;YES
CAIN A,"-" ;IS THIS A ONE LINER FOR SUBJOB?
JRST SINGLE ;YES, GO GET REST OF LINE TO BE SENT
MOVE A,STRING ;SEE IF THIS IS A NO COMMAND
CAME A,[ASCIZ/N/]
CAMN A,[ASCIZ/NO/]
JRST NOCOMM ;YES, GO PROCESS NO COMMAND
MOVEI A,COMTAB ;SEE IF THIS IS A KNOWN COMMAND
MOVE B,[POINT 7,STRING] ;GET START OF COMMAND BUFFER
PUSHJ P,TABLK ;LOOKUP THE COMMAND
JRST COM2 ;NOT A MATCH
HRRZ B,(A) ;SAVE ADDRESS OF TABLE ENTRY OF MATCH
POP P,A ;GET BACK TERMINATING CHAR
CAIN A,33 ;WAS THE TERMINATOR AN ALTMODE?
JRST COMALT ;YES, FINISH OUT STRING
JRST (B) ;CALL APPROPRIATE COMMAND ROUTINE
COM2: POP P,D ;GET BACK TERMINATOR
JUMPG B,COM3 ;UNIQUE SUBSET OF COMMAND?
CAIN D,12 ;NO, IS THIS A LINE FEED?
JRST COM4 ;YES, UNRECOGNIZED COMMAND
MOVE A,D ;GET TERMINTAOR
CAIE A,33 ;ALTMODE?
PUSHJ P,STOCHR ;NO, PUT IT IN THE BUFFER
MOVEI A,7 ;NO, RING BELL
PUSHJ P,TTBOUT
JRST COM1 ;AND GO BACK FOR MORE CHARACTERS
COM3: HRRZ B,(A) ;GET TABLE ADDRESS OF TABLE ENTRY
CAIE D,33 ;WAS TERMINATOR AN ALTMODE
JRST [MOVE A,D ;NO, IS THIS THE END OF A LINE
JRST (B)] ; AND CALL APPROPRIATE ROUTINE
COMALT: MOVE A,C ;FINISH OUT COMMAND AND NOISE WORDS
PUSH P,B ;SAVE ADDRESS OF ROUTINE TO CALL
PUSHJ P,TTSOUT ;SEND OUT REST OF COMMAND
MOVEI A," " ;TERMINATED WITH A SPACE
POPJ P, ;GO TO APPROPRIATE ROUTINE
NOCOMM: SKIPE NOFLAG ;ALREADY SEEN A NO COMMNAD?
JRST COMERR ;YES, THIS IS AN ERROR
POP P,A ;GET TERMINATOR
CAIN A,33 ;ALTMODE?
JRST [ MOVE B,STRING ;YES, FINISH IT OUT
CAMN B,[ASCIZ/N/]
SKIPA A,[POINT 7,[ASCIZ/O /]]
HRROI A,[ASCIZ/ /]
PUSHJ P,TTSOUT ;TYPE OUT THE REMAINDER OF THE FIELD
JRST NOCOM1]
CAIN A,12 ;LF?
JRST COMERR ;YES, ERROR
NOCOM1: SETOM NOFLAG ;SET FLAG TO SIGNAL COMMANDS
JRST COM0 ;GO GET NEXT COMMAND
STOCHR: SOSG COMCNT ;DECREMENT COUNT OF CHARS LEFT
JRST COMERR ;NO ROOM
IDPB A,COMBP ;STORE THE CHAR
MOVE B,COMBP ;AND FOLLOW IT WITH A NULL
MOVEI C,0
IDPB C,B
POPJ P,
COM4: MOVE A,COMCNT ;UNRECOGNIZED COMMAND
CAIN A,MAXSTC ;WAS IT A NULL COMMAND?
JRST COMLVL ;
COMERR: ERRMES (<? UNRECOGNIZED PTYCON COMMAND>)
JRST COMLVL ;AND RETURN TO COMMAND LEVEL
COMCC: PUSHJ P,CHKLOG ;SEE IF ANY JOBS LOGGED IN
JRST [ERRMES (<? TYPE "EXIT" TO EXIT FROM PTYCON!>)
JRST COMLVL] ;NO ACTIVE SUBJOBS
ERRMES (<? SUBJOBS ACTIVE, USE "PUSH" COMMAND!>)
JRST COMLVL
CHKLOG: MOVE E,PTYHGH ;GET HIGHEST PTY JOB
SETZ I, ;START AT NUMBER 0
CHKLG1: SKIPN PTYJFN(I) ;IS THERE A JOB ON THIS LINE?
JRST CHKLG2 ;NO, CHECK OTHER SUBJOBS
HRRZ A,PTYTTD(I) ;GET TTY DESIGNATOR
MOVE B,[-1,,D] ;GET LOGGED-IN DIR NUMBER
MOVEI C,.JIUNO
SETZ D, ;START WITH 0 DIR NUM
GETJI
SETZ D, ;ASSUME 0 IF FAILURE
JUMPN D,CPOPJ1 ;JOB IS LOGGED IN
CHKLG2: ADDI I,PTYLEN ;GO TO NEXT JOB
SOJGE E,CHKLG1 ;LOOP BACK FOR ALL SUBJOBS
POPJ P, ;NO ACTIVE JOBS
COMENT: MOVE B,COMCNT ;NULL STRING SO FAR?
CAIE B,MAXSTC ;...
JRST COMBEL ;NO, USER IS CONFUSED
POP P,A ;GET BACK ;
PUSHJ P,READLN ;GET A LINE
JRST COMLVL ; AND PROMPTLY FORGET IT
SINGLE: SKIPE STRING ;NULL NAME?
JRST SINGL0 ;NO
SKIPGE I,LSTCON ;GET LAST SUBJOB NUMBER IF ANY
JRST COMBEL ;ILLEGAL IF NONE
JRST SINGL1 ;GO USE THIS SUBJOB NUMBER
SINGL0: PUSHJ P,FNDPTY ;SET UP INDEX OF SUBJOB
JRST SINGL2 ;NOT DEFINED, CHECK "ALL"
SINGL1: MOVEM I,LSTCON ;SAVE LAST SINGLE SUBJOB #
POP P,A ;GET BACK TERMINATOR
PUSHJ P,READLN ;GO READ IN A WHOLE LINE OF TEXT
PUSHJ P,SNGOUT ;SEND IT OUT TO DESIRED SUBJOB
JRST COMLVL ; AND RETURN TO COMMAND LEVEL
SNGOUT: PUSHJ P,PTYFIL ;FIRST MAKE SURE OUTPUT BUFFER IS EMPTY
PUSH P,P1 ;SAVE PRESERVED AC
MOVE P1,[POINT 7,STRING]
SINLOP: ILDB A,P1 ;GET NEXT CHARACTER TO GO OUT
JUMPE A,SINLPD ;IF ZERO, THEN DONE
PUSHJ P,PTYOUT ;SEND IT OUT
JRST SINLOP ;LOOP FOR ALL CHARACTERS
SINLPD: POP P,P1 ;RESTORE PRESERVED AC
POPJ P, ;AND RETURN
SINGL2: MOVE A,STRING ;GET STRING
CAME A,[ASCIZ/ALL/] ;IS IT SPECIAL CASE "ALL"?
COMBEL: JRST [ POP P,(P) ;NO, GO RING BELL
MOVEI A,7
PUSHJ P,TTBOUT
JRST COM1] ;AND GET MORE CHARACTERS
POP P,A ;YES, NOW TYPE OUT TERMINATOR
PUSHJ P,READLN ;AND READ IN THE TEXT LINE TO BE SENT
PUSH P,P1 ;SAVE PRESERVED AC
MOVE P1,PTYHGH ;SET UP TO LOOP FOR ALL PTY'S
SETZ I, ;INITIALIZE INDEX
SNGALL: SKIPE PTYJFN(I) ;IS THERE A PTY INITIALIZED HERE?
PUSHJ P,SNGOUT ;YES, SEND OUT LINE
ADDI I,PTYLEN ;GO TO NEXT PTY
SOJGE P1,SNGALL ;LOOP FOR ALL LINES
POP P,P1 ;RESTORE PRESERVED AC
JRST COMLVL ;AND RETURN
READLN: PUSHJ P,COMINI ;INITIALIZE STRING
READL1: PUSHJ P,RDSTR ;GO READ IN A WORD
JRST READL1 ;IGNORE INTERRUPTS
IDPB A,COMBP ;STORE TERMINATOR
SOS COMCNT ;COUNT DOWN BYTE COUNTER
CAIE A,12 ;LF?
JRST READL1 ;NO, WAIT FOR TERMINATOR
MOVEI A,0 ;YES, END WITH A NULL
IDPB A,COMBP
POPJ P, ;AND RETURN
CHKPTO: MOVE A,COMCNT ;CHECK FOR TYPE OUT NECESSARY FROM PTYS
CAIE A,MAXSTC ;ANY CHARACTERS TYPED YET?
JRST COM1 ;YES, DON'T INTERRUPT USER
SETZM TOFLAG ;CLEAR OUTPUT FLAG
PUSHJ P,PTOCHK ;GO TYPE OUT OUTPUT FROM PTY'S
SKIPE TOFLAG ;WAS ANYTHING TYPED?
JRST COMLVL ;YES, GO TYPE PROMPT
JRST COM0 ;NO, DON'T TYPE PROMPT
COMINI: MOVE A,[POINT 7,STRING] ;INITIALIZE COMMAND STRING
MOVEM A,COMBP ;SET UP POINTER
MOVEI A,MAXSTC ; AND CHARACTER COUNT
MOVEM A,COMCNT
SETZM STRING ;ZERO BUFFER
MOVE A,[XWD STRING,STRING+1]
BLT A,STRING+STRNGL-1
POPJ P, ;AND RETURN
;COMMAND TABLE - MUST BE IN ALPHABETICAL ORDER
DEFINE COMAND<
CMND(<ACCEPT (OUTPUT FROM SUBJOBS) >,RECPTY,1)
CMND(<BELL (WHEN OUTPUT WAITING) >,BELL,1)
CMND(<CONNECT (TO SUBJOB) >,CONPTY,0)
CMND(<DEFINE (SUBJOB #) >,DEFPTY,0)
CMND(<DISCARD (OUTPUT FROM SUBJOB) >,IGNOR,1)
CMND(<EXIT (FROM PTYCON) >,EXIT,0)
CMND(<GET (COMMANDS FROM FILE) >,READ,0)
CMND(<HELP MESSAGE >,HELP,0)
CMND(<KILL (SUBJOB) >,KILL,0)
CMND(<LOG (OUTPUT TO FILE) >,LOG,1)
CMND(<PUSH (EXEC LEVEL) >,PUSHE,0)
CMND(<REDEFINE (PTYCON ESCAPE CHARACTER TO BE) >,CHANGE,0)
CMND(<REFUSE (OUTPUT FROM SUBJOBS) >,REFPTY,1)
CMND(<SAVE (INPUT IN FILE) >,SAVINP,1)
CMND(<SILENCE (ALL OUTPUT TO TERMINAL) >,SILNCE,1)
CMND(<WHAT (IS STATE OF SUBJOB) >,WHATPT,0)
>
DEFINE CMND(A,B,C)<
XWD [ASCIZ/A/],B>
COMTAB: XWD COMTBL-1,COMTBL
COMAND
COMTBL==.-COMTAB
DEFINE CMND(A,B,C)<
EXP C>
COMFLG: COMAND
HELP: SKIPE NOFLAG ;DO NOT ALLOW "NO HELP"
JRST COMERR
PUSHJ P,CRWAIT ;WAIT FOR TERMINATNG CR-LF
HRROI A,[ASCIZ/
THE DEFINED COMMANDS ARE:
/]
PUSHJ P,TTSOUT ;TYPE OUT HEADER
MOVSI C,1-COMTBL ;GET # OF ELEMENTS IN TABLE
HELPLP: HLRO A,COMTAB+1(C) ;GET POINTER TO COMMAND
PUSHJ P,TTSOUT ;TYPE IT OUT WITH ITS NOISE WORDS
PUSHJ P,HLPSTR ;PUT A "*" AFTER STRING IF NEEDED
PUSHJ P,CRLF ;END WITH A CRLF
AOBJN C,HELPLP ;LOOP FOR ALL COMMANDS
HRROI A,[ASCIZ/
"*" MEANS THE COMMAND CAN BE PRECEDED BY "NO" TO REVERSE ITS MEANING
THE ESCAPE CHARACTER TO RETURN TO COMMAND LEVEL IS: /]
PUSHJ P,TTSOUT
MOVE A,TRPCHR ;GET ESCAPE CHARACTER
PUSHJ P,TTBOUT ;TYPE IT OUT
JRST COMLVL ;DONE
HLPSTR: SKIPN COMFLG(C) ;IS THIS A COMMAND THAT TAKES "NO"?
POPJ P, ;NO
HRROI A,[ASCIZ/ */] ;YES, TYPE IT OUT
PUSHJ P,TTSOUT
POPJ P,
;TABLK - TABLE LOOKUP WITH ABBREVIATION RECOGNITION
;
;CALL:
; A/ TABLE ADDRESS
; B/ TEST STRING POINTER
; PUSHJ P, TABLK
;RETURN:
; +1 = FAILED, A/ ADR OF WHERE ENTRY WOULD BE IF IT WERE IN TABLE
; B/ -1 FOR NO MATCH AT ALL
; 0 FOR AMBIGUOUS
; +1 FOR UNIQUE ABREVIATION OF A DEFINED NAME
; C/ POINTER TO REMAINDER OF ABREVIATED NAME
; +2 = SUCCESS, A/ ADDRESS OF TABLE ENTRY WHICH MATCHED
;AC USAGE:
; A/ TEST STRING FROM CALL
; B/ STRING FROM TABLE
; C/ CLOBBERED BY STRCMP
; D/ " "
; Q1/ CURRENT TABLE INDEX
; Q2/ ADR OF TABLE(Q1)
; Q3/ SIZE OF TABLE
; P3/ INDEX INCREMENT FOR LOG SEARCH
TABLK: PUSH P,P3 ;SAVE PERMANENT ACS
PUSH P,Q1
PUSH P,Q2
PUSH P,Q3
HRLI A,Q1 ;CONSTRUCT TABADR(Q1)
AOS Q2,A ;LEAVE IT HERE
HLRZ Q1,-1(A) ;SET INITIAL INDEX TO SIZ/2
ASH Q1,-1
HLRZ P3,-1(A) ;INITIAL INCREMENT IS SIZE
MOVE Q3,P3 ;SAVE SIZE FOR RANGE CHECKS
PUSH P,B ;SAVE TEST STRING
JUMPE Q3,TABLKX ;IF NO ENTRIES IN TABLE, THEN NO MATCH
TABLK0: HLRZ B,@Q2 ;GET ADR OF STRING FROM TABLE
HRLI B,(POINT 7,0) ;MAKE BYTE PTR
MOVE A,0(P) ;TEST STRING
PUSHJ P,STRCMP ;COMPARE STRINGS
JRST TABLK1 ;NOT EXACTLY EQUAL
TABLKF: AOS -5(P) ;EXACTLY EQUAL, DOUBLE SKIP RETURN
TABLKM: TDZA B,B ;SET UP FOR AN AMBIGUOUS RETURN
TABLKX: SETO B, ;GIVE NO-MATCH CODE IN B
TABLKA: MOVEI A,@Q2 ;RETURN TABLE ADDRESS OF ENTRY
POP P,0(P)
POP P,Q3 ;RESTORE PERMANENT ACS
POP P,Q2
POP P,Q1
POP P,P3
POPJ P,
;STRING MAY HAVE BEEN UNEQUAL OR A SUBSET, SEE WHICH
TABLK1: JUMPN A,TABLKN ;UNEQUAL, GO SETUP NEXT PROBE
TABLK3: JUMPE Q1,TABLK2 ;IF NOW AT TOP OF TABLE, CHECK NO HIGHER
PUSH P,B ;SAVE POINTER TO REMAINDER OF STRING
MOVEI A,@Q2 ;CHECK PREVIOUS ENTRY, GET ITS ADDRESS
HLRZ B,-1(A) ;GET STRING ADDRESS
HRLI B,(POINT 7,0)
MOVE A,-1(P) ;GET ORIGINAL STRING AGAIN
PUSHJ P,STRCMP ;SEE ABOUT PREVIOUS ENTRY
JRST .+2
SOJA Q1,[POP P,B ;EXACTLY EQUAL, DONE
JRST TABLKF] ;...
JUMPG A,TBLK2B ;IF LESS, THEN HAVE FOUND HIGHEST SUBSET
POP P,0(P) ;POP AWAY UNDESIRED BASE STRING
SOJA Q1,TABLK3 ;STILL A SUBSET, CHECK PREVIOUS
;NOW POINTING AT HIGHEST ENTRY WHICH IS SUBSET. IF THERE IS AN EXACT
;MATCH, IT IS BEFORE ALL SUBSETS AND HAS ALREADY BEEN FOUND
TABLK2: PUSH P,B ;SAVE PTR TO REST OF BASE
TBLK2B: MOVEI A,@Q2 ;CHECK NEXT ENTRY FOR AMBIGUOUS
CAIL Q1,-1(Q3) ;IS THIS THE LAST ENTRY ALREADY?
JRST [POP P,C ;YES, THIS ENTRY IS DISTINCT
JRST TBLK2A] ;GO RETURN +1 IN B
HLRZ B,1(A)
HRLI B,(POINT 7,0)
MOVE A,-1(P)
PUSHJ P,STRCMP
JRST .+2
BUG(CHK,<TABLK2: TABLE NOT IN PROPER FORMAT>)
POP P,B
JUMPE A,TABLKM ;NEXT ENTRY NOT DISTINCT, GIVE AMBIGUOUS RETURN
MOVE C,B ;GET POINTER TO REST OF BASE STRING
TBLK2A: MOVEI B,1 ;SET UP FOR ABBREVIATION RETURN
JRST TABLKA ;GIVE NON-SKIP RETURN
;HERE WHEN PROBE NOT EQUAL
TABLKN: CAIG P3,1 ;INCREMENT NOW 1?
JRST [JUMPL A,TABLKX ;YES, NO MATCH FOUND
AOJA Q1,TABLKX] ;IF STRING GREATER, MAKE ADDR ONE MORE
ADDI P3,1 ;NEXT INC = <INC+1>/2
ASH P3,-1
JUMPG A,[ADD Q1,P3 ;IF LAST PROBE LOW, ADD INCREMENT
JRST TBLKN1] ;GO CHECK BOUNDS
SUB Q1,P3 ;LAST PROBE HIGH, SUBTRACT INCREMENT
TBLKN1: CAIL Q1,0(Q3) ;OVER THE TOP OF THE TABLE?
JRST [SETO A, ;YES, FAKE PROBE TO HIGH
JRST TABLKN] ;GO PROBE AGAIN
JUMPGE Q1,TABLK0 ;IF STILL WITHIN TABLE, GO PROBE
MOVEI A,1 ;BELOW TABLE, FAKE LOW PROBE
JRST TABLKN
;STRING COMPARE ROUTINE
;CALL:
; A/ TEST STRING POINTER
; B/ BASE STRING POINTER
; PUSHJ P,STRCMP
;RETURN:
; +1 = NOT EXACT MATCH, A GIVES STATUS:
; -1 = TEST STRING LESS THAN BASE STRING
; 0 = TEST STRING SUBSET OF BASE STRING
; +1 - TEST STRING GREATER THAN BASE STRING
; +2 = EXACT MATCH
STRCMP: ILDB C,A ;GET NEXT CHAR FROM EACH STRING
ILDB D,B
CAME C,D ;STILL EQUAL?
JRST STRC2 ;NO, GO SEE WHY
JUMPN C,STRCMP ;KEEP GOING IF NOT END OF STRING
AOS 0(P) ;STRINGS ENDED TOGETHER, EXACT MATCH
POPJ P,
STRC2: JUMPE C,[SETZ A, ;TEST STRING ENDED, IS A SUBSET
ADD B,[70000,,0] ;DECREMENT BYTE POINTER BY ONE BYTE
POPJ P,]
CAMG C,D ;STRINGS UNEQUAL
SKIPA A,[-1] ;TEST STRING LESS, RETURN -1
MOVEI A,1 ;TEST STRING GREATER, RETURN +1
POPJ P,
;ROUTINE TO GET A CHARACTER FROM TTY
TTYGET: SKIPE RDJFN ;READING FROM A FILE
JRST FILGET ;YES, GET CHARACTER FROM FILE INSTEAD
MOVE A,TERJFN ;SEE IF ANY CHARACTERS HAVE BEEN TYPED.
SIBE
JRST [ SETO B,
JRST TTGETR] ;YES
PUSH P,[TTGETR] ;SET UP TO ALLOW INTERRUPTS TO TAKE
SETOB B,IOWATF ;MARK THAT INTERRUPTS CAN TAKE
MOVE A,TERJFN ;PRIMARY INPUT OR BINARY CHANNEL
SKIPN WAKEF ;INTERRUPT PENDING ??
BIN ;NO, WAIT FOR ONE.
SETZM IOWATF ;CLEAR OK TO INTERRUPT FLAG.
MOVE A,B ;MOVE CHARACTER INTO A
ANDI A,177 ;TRUNCATE TO 7 BITS
POPJ P, ;GO TO TTGETR
TTGETR: SETZM WAKEF ;CLEAR WAKE UP FLAG
JUMPL B,TTGET7 ;JUMP IF NO CHARACTER HAS BEEN INPUT.
JRST CPOPJ1 ;EXIT.
TTGET7: MOVE A,TERJFN ;GET CHARACTER IF THERE IS ONE.
SIBE ;ANY CHARACTERS TYPED IN?
CAIA ;THERE ARE SOME.
POPJ P, ;NO, GIVE NO SKIP RETURN
MOVE A,TERJFN
BIN ;READ IN WAITING CHARACTER
ERJMP CPOPJ ;IF ERROR, RETURN FAILURE
MOVE A,B
ANDI A,177 ;TRUNCATE TO 7 BITS
JRST CPOPJ1
FILGET: HRRZ A,RDJFN ;GET JFN OF FILE BEING READ
BIN ;GET THE NEXT CHARACTER
CAIN B,"^" ;UPARROW?
PUSHJ P,[BIN ;YES, GET NEXT CHARACTER
CAIN B,"^" ;ANOTHER UPARROW?
POPJ P, ;YES, RETURN
CAIN B,"$" ;DOLLAR SIGN?
JRST [MOVEI B,33
POPJ P,] ;YES, MAKE IT AN ALTMODE
CAIL B,141 ;LOWER CASE?
CAILE B,172
SKIPA ;NO
SUBI B,40 ;YES, MAKE IT UPPER CASE
TRZ B,100 ;MAKE IT A CONTROL
POPJ P,]
CAIN B,.CHCRT ;CR?
JRST [ BIN ;YES, PEEK AT NEXT ONE
CAIN B,.CHLFD ;AN LF?
SKIPA B,TERJFN ;YES, RETURN CR IF BINARY, LF IF ASCII
BKJFN ;NO, PUT IT BACK AND RETURN CR
CAMN B,BINTTY
SKIPA B,[.CHCRT]
MOVEI B,.CHLFD
JRST .+1]
JUMPN B,[MOVE A,B ;DID WE GET A CHARACTER?
CAME A,TRPCHR ;YES, WAS IT THE ESCAPE CHARACTER
JRST CPOPJ1 ;NO, GIVE SUCCESSFUL RETURN
MOVEI A,"^" ;ECHO THE ESCAPE CHARACTER ON THE TTY
PUSHJ P,TTBOUT
MOVE A,TRPCHR ;GET THE TRAP CHARACTER
TRO A,100 ;MAKE IT INTO THE ASCII COUNTERPART
PUSHJ P,TTBOUT
JRST COMLVL] ;AND RETURN TO COMMAND LEVEL
GTSTS ;SEE IF EOF
TLNN B,(1B8) ;...
JRST FILGET ;NO, IGNORE NULLS
CLOSF ;YES, CLOSE THE FILE
JFCL
SETZM RDJFN ;CLEAR READING FLAG
SETZM SILNCF ;AND CLEAR SILENCE FLAG
JRST TTYGET ;GO GET CHARACTER FROM TTY
;ROUTINES TO TURN ON AND OFF PI SYSTEM
PIOFF: MOVEI A,400000
DIR ;DISABLE INTERRUPTS
AOS PICNT ;COUNT # OF TIMES DONE
POPJ P, ;AND RETURN
PION: SOSL PICNT ;NESTED?
POPJ P, ;YES, DON'T ENABLE
SETOM PICNT ;NO, OK TO TURN BACK ON
MOVEI A,400000
EIR ;TURN ON PI SYSTEM
POPJ P, ;AND RETURN
TRAP: CALL ASCTER ;GET ASCII TERMINAL SET UP
MOVEI A,"^" ;ECHO THE ESCAPE CHARACTER ON THE TTY
PUSHJ P,TTBOUT
MOVE A,TRPCHR ;GET THE TRAP CHARACTER
TRO A,100 ;MAKE IT INTO THE ASCII COUNTERPART
PUSHJ P,TTBOUT
PUSHJ P,CRLF ;TYPE CRLF FIRST
TRAP1: SKIPE A,RDJFN ;IS THIS AN ABORT OUT OF A GET COMMAND?
CLOSF ;YES, CLOSE THE GET FILE
JFCL
SETZM RDJFN ;STOP READING FROM FILE
SETZM IOWATF ;CLEAR OK TO INTERRUPT FLAG
MOVEI A,100 ;CLEAR TYPE AHEAD
CFIBF ; OF UNREAD JUNK
MOVEI A,PTYCON ;START FROM SCRATCH
MOVEM A,RETSAV ; AFTER DEBRK
DEBRK
PANIC: CALL ASCTER ;GET ASCII TERMINAL SET UP
BUG(CHK,<PANIC LEVEL INTERRUPT OCCURRED!>)
HRROI A,ERRSTR ;PUT MESSAGE INTO A STRING
HRLOI B,400000 ;AND REASON FOR PANIC
MOVEI C,0
ERSTR
JFCL
SKIPA A,[POINT 7,[ASCIZ/UNKNOWN ERROR CODE/]]
HRROI A,ERRSTR ;NOW OUTPUT THE MESSAGE
PUSHJ P,TTSOUT
MOVEI A,101
DOBE ;WAIT FOR IT TO GO OUT
JRST TRAP1 ; AND GO TO COMMAND LEVEL
;SET UP ASCII TERMINAL
ASCTER: MOVEI A,.PRIOU ;THE I.D. OF IT
MOVEM A,TERJFN ;SET IT
RET ;AND DONE
EXIT: PUSHJ P,CRWAIT ;WAIT FOR CONFIRMING CHAR
SKIPE NOFLAG ;DID USER SAY NO?
JRST COMERR ;YES, THIS IS AN ERROR
PUSHJ P,LOGCLS ;CLOSE THE LOG FILE IF ANY
PUSHJ P,CHKLOG ;SEE IF ANY ACTIVE SUBJOBS
JRST EXIT1 ;NONE, GO EXIT
HRROI A,[ASCIZ/CAUTION: EXITING MAY LOG OUT THE STILL ACTIVE SUBJOBS!
CONFIRM: (TYPE CONTROL-/]
PUSHJ P,TTSOUT
MOVE A,TRPCHR ;TYPE OUT THE ESCAPE CHAR
TRO A,100
PUSHJ P,TTBOUT
HRROI A,[ASCIZ/ TO GET BACK TO PTYCON) /]
PUSHJ P,TTSOUT ;ISSUE WARNING
MOVEI A,0
PUSHJ P,CRWAIT ;WAIT FOR ANOTHER CONFIRMING CR
EXIT1: CALL RSTTY ;[8] RESET TTY PARAMETERS
SKIPE A, LOGJFN ;[8] GET LOGJFN
CLOSF ;[8] CLOSE IT
JFCL ;[8] IGNORE ERROR
HALTF ;[8] STOP
CALL RSTTY ;[8] RESET TTY IF CONTINUED
SKIPN LOGJFN ;[8] WAS THERE A LOG FILE
JRST COMLVL ;[8] NO, CONTINUE
HRROI B,LOGBUF ;[8] GET NAME OF LAST LOG FILE
JRST LOG2 ;[8] OPEN IT
RSTTY: MOVEI A,.PRIIN ;[8] GET PRIMARY INPUT
RFMOD ;[8] GET STATE NOW
EXCH B,SAVMOD ;[8] SAVE STATE NOW, GET OLD STATE
SFMOD ;[8] RESET OLD STATE
STPAR ;[8] ...
RET ;[8]
CHKLM: SKIPLE LMFLAG ;AT LEFT MARGIN?
POPJ P, ;NO
MOVEI A,101
RFPOS ;SEE IF AT LEFT MARGIN
TRNN B,-1
JRST CPOPJ1 ;YES, SKIP RETURN
POPJ P, ;NO, GIVE NON-SKIP RETURN
CRLF: HRROI A,[ASCIZ/
/]
PUSHJ P,TTSOUT ;TYPE OUT CR-LF
SETZM LMFLAG ;RESET FLAG TO -1
POPJ P,
TTBOUT: EXCH A,LSTCHR ;GET LAST CHAR TYPED
CAIE A,15 ;CR?
SKIPA ;NO
CAME A,LSTCHR ;YES, IS THIS CHAR A CR ALSO?
SKIPA A,LSTCHR ;NO, THEN TYPE IT
POPJ P, ;YES, DONT TYPE TWO IN A ROW
CAILE A,37 ;DON'T INCREMENT COLUMN COUNTER FOR NON-PRINTING CHARACTERS.
AOS LMFLAG
CAIE A,12
CAIN A,15
SETZM LMFLAG ;RESET COUNTER FOR CARRIAGE RETURN.
SKIPE RDJFN ;READING FROM A FILE?
SKIPN SILNCF ;AND RIGGED FOR SILENT RUNNING?
SKIPE IGNORF ;NO, IGNORING THIS PTY?
JRST TTBLG0 ;YES
PUSH P,B ;DON'T CLOBBER B.
MOVE B,A ;PUT CHARACTER IN B.
MOVE A,TERJFN ;GET APPROPRIATE TTY CHANNEL (BINARY OR REGULAR)
BOUT ;TYPE THE CHARACTER.
MOVE A,B ;RESTORE A AS THE CHARACTER.
POP P,B ;AND WHATEVER WAS IN B.
CAIE A,7 ;BELL?
SETOM TOFLAG ;NO, SET TYPE OUT OCCURRED FLAG
JRST TTBLG0
TTBLOG: JUMPE A,CPOPJ ;DON'T LOG NULLS.
EXCH A,LSTCHR ;GET LAST CHAR TYPED
CAIE A,15 ;CR?
SKIPA ;NO
CAME A,LSTCHR ;YES, IS THIS CHAR A CR ALSO?
SKIPA A,LSTCHR ;NO, THEN TYPE IT
POPJ P, ;YES, DONT TYPE TWO IN A ROW
TTBLG0: SKIPN LOGJFN ;LOGGING THIS?
POPJ P, ;NO, RETURN
PUSH P,B ;SAVE ALL ACS
MOVE B,A ;GET CHAR
MOVE A,LOGJFN ;GET LOGGING JFN
CAIE B,33 ;DONT SEND ALTMODES TO FILE
BOUT ;SEND OUT CHAR
TTBLG1: MOVE A,B ;RESTORE ACS
POP P,B
POPJ P, ;RETURN
TTSOUT: PUSH P,TERJFN ;SAVE THE TTY CHANNEL.
PUSH P,A ;AND THE STRING POINTER.
MOVEI A,100 ;GET NON-BINARY CHANNEL FOR PRINTING THE MESSAGE.
MOVEM A,TERJFN ;SET UP THE NON-BINARY CHANNEL.
POP P,A ;RETRIEVE THE POINTER TO THE MESSAGE.
PUSHJ P,TTSOU1 ;PRINT IT.
POP P,TERJFN ;RESTORE THE TTY CHANNEL.
POPJ P,
TTSOU1: TLC A,-1 ;LEFT HALF = -1?
TLCN A,-1
HRLI A,(POINT 7,0) ;YES, SET UP BYTE POINTER
PUSH P,B ;SAVE ACS
MOVE B,A ;GET STRING POINTER OUT OF A
TTSOUL: ILDB A,B ;GET NEXT CHAR OF STRING
JUMPE A,TTSOUD ;IF NULL, THEN DONE
CALL TTBOUT ;TYPE OUT CHAR
JRST TTSOUL ;LOOP TILL NULL FOUND
TTSOUD: MOVE A,B ;RETURN UPDATED STRING POINTER IN A
POP P,B ;RESTORE ACS
POPJ P,
TTSLOG: SKIPN LOGJFN ;LOGGING?
POPJ P, ;NO
PUSH P,B ;DO NOT CLOBBER ACS
PUSH P,C
MOVEI C,0
MOVE B,A ;GET STRING POINTER
MOVE A,LOGJFN ;AND JFN OF LOG FILE
SOUT
MOVE A,B ;CLEAN UP ACS
POP P,C
POP P,B
POPJ P, ;AND RETURN
CRWAIT: CAIN A,12 ;LF?
POPJ P, ;YES, DONE
CRWAT0: PUSHJ P,TTYGET ;GET A CHARACTER
JRST CRWAT0 ;IGNORE INTERRUPTS
PUSHJ P,TTBLOG ;PUT THIS CHARACTER IN THE LOG FILE
CAIN A,12 ;LF YET?
POPJ P, ;YES, RETURN
CAIN A,"U"-100 ;CONTROL-U?
JRST CRWAT1 ;YES, ABORT COMMAND
CAIN A,15 ;CR
JRST CRWAT0 ;YES
MOVEI A,7 ;NO, RING BELL
PUSHJ P,TTBOUT
JRST CRWAT0 ;GO GET ANOTHER CHAR
CRWAT1: HRROI A,[ASCIZ/ XXX/] ;ECHO ABORT COMMAND
PUSHJ P,TTSOUT
JRST COMLVL ;AND GO TO COMMAND LEVEL
;ROUTINE TO CHANGE THE PTYCON ESCAPE CHARACTER
CHANGE: SKIPE NOFLAG ;NO IS NOT ALLOWED
JRST COMERR
PUSHJ P,COMINI ;INITIALIZE THE COMMAND BUFFER
PUSHJ P,RDSTR ;GET A FIELD
JRST .-1 ;DONT ALLOW INTERRUPTS
PUSH P,A ;SAVE THE TERMINATOR
PUSHJ P,CRWAIT ;THEN WAIT FOR CONFIRMATION
POP P,A ;GET BACK THE TERMINATOR
SKIPE STRING ;MAKE SURE NOTHING ELSE WAS TYPED
JRST CHNGIL
CAIE A,11 ;DONT ALLOW IT TO BE TAB
CAIL A,34 ;AND IT MUST BE A CONTROL CHARACTER
JRST CHNGIL ;ILLEGAL
CAIE A,"C"-100 ;NOT CONTROL-C
CAIN A,"O"-100 ;NOR CONTROL-O
JRST CHNGIL
CAIE A,33 ;NO ALTMODES
CAIN A,14 ;OR FORM FEEDS
JRST CHNGIL
CAIE A,12 ;LINE FEED
CAIN A,15 ;OR CARRIAGE RETURNS ARE ILLEGAL
JRST CHNGIL
EXCH A,TRPCHR ;GET OLD TRAP CHARACTER
DTI ;DEASSIGN IT
ERJMP .+1
MOVSI A,400000 ;NOW BUILD THE MASK
MOVN B,TRPCHR ;GET SHIFT COUNTER
LSH A,(B) ;GET MASK
MOVEM A,ESCMSK ;SAVE THIS MASK FOR SUBJOB LEVEL
IOR A,[CNTRLO] ;INCLUDE CONTROL-O ALSO
MOVEM A,TIMASK ;SAVE THE NEW MASK
JRST PTYCON ;GO SET THIS UP
CHNGIL: ERRMES (<? ILLEGAL PTYCON ESCAPE CHARACTER>)
JRST COMLVL
RECPTY: SKIPE NOFLAG ;USER TYPE NO?
JRST NOREC ;YES, TURN IT INTO REFUSE
NOREF: CAIN A,12 ;USER END WITH LF?
JRST RECPT3 ;YES, ASSUME ALL
RECPT0: PUSHJ P,GETSJB ;GET A SUBJOB NUMBER IN I
JRST RECPT5 ;NO MATCH, CHECK FOR NULL STRING
JRST RECPT1 ;USER SAID ALL
MOVSI B,PTREFF ;SET UP TO CLEAR REFUSE FLAG
ANDCAM B,PTYSTS(I) ;ALLOW TYPE OUT
CAIN A,"," ;WAS THE TERMINATOR A COMMA
JRST RECPTY ;NO, LOOP BACK FOR MORE ARGUMENTS
PUSHJ P,CRWAIT ;NO, WAIT FOR CR-LF
JRST COMLVL ;RETURN
RECPT1: PUSHJ P,CRWAIT ;WAIT FOR A CRLF
RECPT4: MOVE C,PTYHGH ;GET HIGHEST PTY NUMBER
MOVEI I,0 ;START WITH NUMBER 0
MOVSI B,PTREFF ;GET FLAG
RECPT2: ANDCAM B,PTYSTS(I) ;CLEAR REFUSE FLAG
ADDI I,PTYLEN ;STEP TO NEXT PTY
SOJGE C,RECPT2 ;LOOP BACK FOR ALL PTY'S
SETZM REFALL ;MARK THAT A ACCEPT ALL WAS DONE
JRST COMLVL ;ALL THROUGH
RECPT3: PUSH P,A ;SAVE TERMINATOR
HRROI A,[ASCIZ/ ALL/]
PUSHJ P,TTSOUT ;ECHO ALL
MOVEI A," " ;GET A SPACE FOR CRWAIT
POP P,B ;GET BACK TERMINATOR
CAIN B,33 ;ALTMODE?
PUSHJ P,CRWAIT ;YES, WAIT FOR A TERMINATOR
JRST RECPT4 ;GO DO ALL
RECPT5: MOVE B,COMCNT ;GET COUNT OF CHARACTERS IN BUFFER
CAIE B,MAXSTC ;IS THIS A NULL STRING?
JRST ILLSJB ;NO, THEN THIS IS AN ERROR
CAIE A,12 ;LF?
CAIN A,33 ; OR ALTMODE?
JRST RECPT3 ;YES, ASSUME ALL
MOVEI A,7 ;NO, RING BELL
PUSHJ P,TTBOUT
JRST RECPT0 ;AND TRY AGAIN
REFPTY: SKIPE NOFLAG ;DID USER TYPE NO?
JRST NOREF ;YES, TURN IT INTO AN ACCEPT
NOREC: CAIN A,12 ;USER END WITH LF?
JRST REFPT3 ;YES, GO ASSUME ALL
REFPT0: PUSHJ P,GETSJB ;GET SUBJOB NUMBER
JRST REFPT5 ;NO MATCH, CHECK FOR NULL STRING
JRST REFPT1 ;USER SAID "ALL"
MOVSI B,PTREFF ;GET REFUSE FLAG
IORM B,PTYSTS(I) ;SET REFUSE FLAG
CAIN A,"," ;WAS TERMINATOR A COMMA?
JRST REFPTY ;YES, GO GET ANOTHER ARG
PUSHJ P,CRWAIT ;WAIT FOR EOL
JRST COMLVL ;AND EXIT
REFPT1: PUSHJ P,CRWAIT ;WAIT FOR EOL
REFPT4: MOVE C,PTYHGH ;GET NUMBER OF PTYS OPEN
MOVEI I,0 ;START AT # 0
MOVSI B,PTREFF ;PREPARE TO SET FLAG
REFPT2: IORM B,PTYSTS(I) ;SET REFUSE FLAG
ADDI I,PTYLEN ;STEP TO NEXT PTY
SOJGE C,REFPT2 ;LOOP FOR ALL
SETOM REFALL ;REMEMBER REFUSE ALL COMMAND
JRST COMLVL ;ALL THROUGH
REFPT3: PUSH P,A ;SAVE TERMINATOR
HRROI A,[ASCIZ/ ALL/]
PUSHJ P,TTSOUT
MOVEI A," " ;GET A SPACE FOR CRWAIT
POP P,B ;GET BACK TERMINATOR
CAIN B,33 ;ALTMODE?
PUSHJ P,CRWAIT ;YES, WAIT FOR A TERMINATOR
JRST REFPT4 ;ASSUME ALL
REFPT5: MOVE B,COMCNT ;GET NUMBER OF CHARACTERS LEFT IN BUFFER
CAIE B,MAXSTC ;IS BUFFER EMPTY?
JRST ILLSJB ;NO, THIS IS AN ERROR
CAIE A,12 ;LF?
CAIN A,33 ; OR ALTMODE?
JRST REFPT3 ;YES, ASSUME ALL
MOVEI A,7 ;NO, RING BELL
PUSHJ P,TTBOUT
JRST REFPT0 ;AND TRY AGAIN
;ROUTINE TO DEFINE A PTY SUBJOB NAME
DEFPTY: SKIPE NOFLAG ;USER SAY NO?
JRST COMERR ;YES, ERROR
CAIN A,12 ;TERMINATOR A LF?
JRST TOOFEW ;YES, GO COMPLAIN
PUSHJ P,COMINI ;INITIALIZE COMMAND STRING
DEFPT1: PUSHJ P,RDSTR ;READ IN A WORD
JRST DEFPT1 ;DON'T ALLOW INTERRUPTS
CAIN A,12 ;LF?
JRST [MOVEI B,MAXSTC ;SEE IF SOMETHING WAS TYPED IN
CAMN B,COMCNT
JRST TOOFEW ;NEED AT LEAST ONE ARGUMENT
JRST .+1] ;OK
PUSH P,A ;SAVE TERMINATOR
CAIN A,33 ;WAS IT AN ALTMODE?
JRST DEFPTF ;YES, GET NEXT FREE PTY
DEFPT5: HRROI A,STRING ;READ THIS AS A NUMBER
MOVEI C,12 ;IN DECIMAL
NIN
DEFPT0: JRST [POP P,A ;NOT A VALID ARGUMENT
CAIE A,15 ;USER TYPE CR
CAIN A,12 ; OR LF?
JRST ILLSJB ;YES, ILLEGAL SUBJOB DESIGNATOR
MOVEI A,7 ;DING THE BELL
PUSHJ P,TTBOUT
JRST DEFPT1] ;AND GET MORE INPUT
SKIPL B ;WITHIN BOUNDS?
CAML B,NUMPTY
JRST DEFPT0 ;NO, RING BELL
DEFPT4: POP P,A ;GET BACK TERMINATOR
CAIN A,33 ;ENDED WITH AN ALTMODE?
JRST [HRROI A,[ASCIZ/ (AS) /]
PUSHJ P,TTSOUT ;YES, TYPE OUT NOISE WORDS
JRST DEFPT3]
DEFPT3: PUSH P,A ;SAVE TERMINATOR
CAML B,PTYHGH ;IS THIS A NEW HIGH
PUSHJ P,NEWHGH ;YES, SET UP NEW HIGH NUMBER
IMULI B,PTYLEN ;CALCULATE INDEX
MOVE I,B ;SET UP INDEX
PUSHJ P,COMINI ;PREPARE FOR SECOND ARG
POP P,A ;GET BACK TERMINATOR
PUSH P,P1 ;SAVE FLAG REGISTER
SETZ P1, ;INITIALIZE IT FOR NO MESSAGE
CAIN A,12 ;LF?
JRST DEFPT6 ;YES, GO INITIALIZE PTY
DEFPTR: PUSHJ P,RDSTR ;READ IN A WORD
JRST .-1 ;DON'T ALLOW INTERRUPTS
CAIN A,33 ;TERMINATOR AN ESCAPE?
JRST [ MOVEI A,7 ;YES,
PUSHJ P,TTBOUT ;SEND A BELL
JRST DEFPTR ] ;GET MORE INPUT
PUSH P,A ;SAVE TERMINATOR
PUSH P,I ;SAVE INDEX
MOVE A,COMCNT ;SEE IF THIS WAS A NULL FIELD
CAIE A,MAXSTC ;...
PUSHJ P,FNDPTY ;GO SEE IF NAME ALREADY EXISTS?
JRST DEFPT7 ;NO NAME IN USE
SETZM PTYNAM(I) ;YES, CLEAR NAME
SETO P1, ;MAKE MESSAGE COME OUT
DEFPT7: POP P,I ;GET BACK INDEX OF THIS SUBJOB
POP P,A ;GET BACK TERMINATOR
DEFPT6: MOVE B,STRING ;GET FIVE CHARACTER NAME
MOVEM B,PTYNAM(I) ;STORE NAME EVEN IF NULL
MOVEM I,LSTCON ;DEFINE IS SAME AS CONNECT
PUSH P,A ;SAVE TERMINATOR
SKIPN PTYJFN(I) ;IS PTY OPENED YET?
PUSHJ P,PTINIT ;NO, GO INITIALIZE IT
POP P,A ;GET TERMINATOR BACK
PUSHJ P,CRWAIT ;GO WAIT FOR EOL
SKIPE P1 ;WAS NAME ALREADY IN USE?
WRNMES (<% NAME ALREADY IN USE, REASSIGNED TO THIS SUBJOB>)
POP P,P1 ;RESTORE PERMANENT AC
JRST COMLVL ;AND RETURN
DEFPTF: MOVE C,COMCNT ;SEE IF A NULL STRING WAS TYPED
CAIE C,MAXSTC ;...
JRST DEFPT5 ;NO, GO INTERPRET STRING
MOVNI I,PTYLEN ;FIND FIRST FREE SUBJOB NUMBER
MOVE C,NUMPTY ;LOOP FOR ALL PTY'S
DEFPTL: ADDI I,PTYLEN ;GO TO NEXT SUBJOB
SKIPE PTYJFN(I) ;INITIALIZED?
SOJG C,DEFPTL ;YES, TRY NEXT ONE
JUMPLE C,DEFPT0 ;FOUND A FREE ONE?
PUSHJ P,TYPNUM ;YES, ECHO IT OUT
JRST DEFPT4 ;AND RETURN FOR NAME
TYPNUM: MOVEI B,(I) ;TYPE SUBJOB NUMBER FROM INDEX
IDIVI B,PTYLEN ;GET SUBJOB NUMBER
HRROI A,STRING ;PUT NUMBER IN STRING
MOVEI C,12 ;DECIMAL
NOUT ;TYPE OUT NUMBER
JFCL
HRROI A,STRING ;NOW TYPE IT
PUSHJ P,TTSOUT
POPJ P, ;AND RETURN
TOOFEW: ERRMES (<? TOO FEW ARGUMENTS!>)
JRST COMLVL
;ROUTINE TO CONNECT TO A PTY LINE
CONPTY: SKIPE NOFLAG ;USER SAY "NO"?
JRST COMERR ;YES, ERROR
PUSH P,A ;SAVE TERMINATOR
PUSHJ P,COMINI ;INIT COMMAND BUFFER
POP P,A ;GET BACK TERMINATOR
CAIN A,12 ;WAS IT A LF?
JRST CONPT4 ;YES, ASSUME LAST CONNECTED SUBJOB
CONPT0: PUSHJ P,RDSTR ;GET WORD
JRST CONPT0 ;IGNORE INTERRUPTS
CAIE A,12 ;LF?
CAIN A,33 ; OR ALTMODE?
JRST CONPT4 ;YES, SPECIAL CASE
CONPT5: PUSH P,A ;SAVE TERMINATOR
PUSHJ P,FNDPTY ;SEE IF LEGAL SUBJOB
JRST [POP P,A ;NO, RING BELL
CAIN A,12 ;USER END WITH LF?
JRST ILLSJB ;YES, ILLEGAL SUBJOB DESIGNATOR
MOVEI A,7
PUSHJ P,TTBOUT
JRST CONPT0] ;AND GO GET MORE CHARACTERS
CONPT3: POP P,A ;GET BACK TERMINATOR
PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
HRRZS I ;SET UP NEW INDEX
MOVEM I,LSTHDR ;AS NEW LAST CONNECTED TO SUBJOB
MOVEM I,LSTCON ;AND DONT TYPE OUT A HEADER
HRROI A,[ASCIZ/[CONNECTED TO SUBJOB /]
PUSHJ P,TTSOUT
PUSHJ P,TYPNAM ;TYPE SUBJOB NAME
HRROI A,[ASCIZ/]
/]
PUSHJ P,TTSOUT
PUSHJ P,PTYFIL ;READ IN ANY CHARACTERS IN BUFFER
PUSHJ P,PTOCHK ;TYPE OUT ANYTHING BUFFERED UP
JRST PTYLOP ;GO CONNECT
CONPT4: MOVE B,COMCNT ;NULL STRING?
CAIGE B,MAXSTC
JRST CONPT5 ;NO, SEE IF LEGAL SUBJOB NAME
CAIE A,15 ;YES, CR-LF?
CAIN A,12 ;
JRST CONPT6 ;YES, GET LAST CONNECTED SUBJOB
MOVEI A," " ;NO, SAVE SPACE AS TERMINATOR
PUSH P,A
MOVE I,LSTCON ;GET LAST SUBJOB CONNECTED TO
SKIPE C,PTYNAM(I) ;IS THERE A NAME DEFINED FOR IT
JRST CONPTN ;YES
PUSHJ P,TYPNUM ;NO, TYPE OUT THE NUMBER
JRST CONPT3 ; AND NOT THE NAME
CONPTN: HRROI A,C ;GET NAME
SETZ D,
PUSHJ P,TTSOUT ;TYPE IT OUT
JRST CONPT3
CONPT6: PUSH P,A
MOVE I,LSTCON ;GET LAST SUBJOB CONNECTED TO
JRST CONPT3
ILLSJB: ERRMES (<? ILLEGAL SUBJOB DESIGNATOR>)
JRST COMLVL
;ROUTINE TO SET UP I WITH PTY NUMBER
FNDPTY: SKIPN A,STRING ;NON NULL NAME?
POPJ P, ;NO, CANNOT FIND
MOVE C,PTYHGH ;GET MAX DEFINED PTY
SETZ I, ;START AT 0
FNDPT1: CAMN A,PTYNAM(I) ;A MATCH
JRST CPOPJ1 ;YES, THEN DONE
ADDI I,PTYLEN ;NO, TRY NEXT ONE
SOJGE C,FNDPT1 ;LOOP FOR ALL SUBJOBS
HRROI A,STRING ;DID NOT FIND ONE, SEE IF THIS IS A #
MOVEI C,12
NIN ;READ IN NUMBER
POPJ P, ;BAD
LDB C,A ;SEE IF ANY CHARACTERS AFTER NUMBER
JUMPN C,CPOPJ ;IF YES, THEN NOT SPECIFIING A NUMBER
CAML B,NUMPTY ;WITHIN BOUNDS?
POPJ P, ;NO, BAD
CAML B,PTYHGH ;NEW HIGH?
PUSHJ P,NEWHGH ;YES, SAVE IT
IMULI B,PTYLEN ;CALCULATE INDEX
MOVE I,B
JRST CPOPJ1 ;SUCCESS
NEWHGH: PUSH P,P1 ;SAVE A FEW ACS
PUSH P,P2
PUSH P,P3
MOVE P1,PTYHGH ;GET CURRENT HIGH
IMULI P1,PTYLEN ;GET INDEX
MOVE P2,B ;GET NEW HIGH
SUB P2,PTYHGH ;GET NUMBER OF JOBS NEEDING INITIALIZING
SETZ P3, ;START WITH 0 FOR STATUS
SKIPE REFALL ;REFUSING ALL?
TLO P3,PTREFF ;YES, SET BIT
SKIPE IGNALL ;IGNORING ALL?
TLO P3,PTIGNF ;YES
NEWHG1: ADDI P1,PTYLEN ;GO TO NEXT AREA
MOVEM P3,PTYSTS(P1) ;STORE INITIAL STATUS WORD
SOJG P2,NEWHG1 ;LOOP FOR ALL JOBS
MOVEM B,PTYHGH ;STORE NEW HIGH VALUE
POP P,P3 ;RESTORE ACS
POP P,P2
POP P,P1
POPJ P, ;AND RETURN
;ROUTINE TO READ IN A FIELD INTO STRING
RDSTR: SETOM LMFLAG ;MARK THAT RFPOS TO BE USED IN CHKLM
SKIPE RDJFN ;READING FROM FILE?
JRST RDSTRF ;YES
RDSTR3: PUSHJ P,TTYGET ;GET A CHARACTER FROM TTY
POPJ P, ;AN INTERRUPT OCCURED
CAIN A,15 ;WAS CHAR A CR?
JRST RDSTR3 ;YES, GET ANOTHER CHAR
RDSTR1: MOVEI A,100 ;BACK UP
BKJFN ;SO RDTXT CAN READ CHAR
JFCL ;******FIX THIS************
MOVE A,[100,,101] ;SET UP FOR RDTXT
MOVE B,COMBP ;BYTE POINTER
MOVE C,COMCNT ;COUNT
HRLI C,(RD%RND!RD%BRK!RD%PUN!RD%BEL!RD%CRF!RD%JFN!RD%BBG)
PUSH P,COMBP ;SAVE BYTE POINTER
MOVE D,[POINT 7,STRING] ;START OF STRING
RDTXT ;READ IN A WORD
BUG(HLT,<RDTXT JSYS FAILED>)
MOVEM B,COMBP ;STORE NEW BYTE POINTER
HRRZM C,COMCNT ;AND COUNT
TLNN C,(RD%BTM) ;TERMINATED WITH TERMINATOR?
JRST [MOVE A,COMCNT ;GET # OF CHARACTERS IN BUFFER
JUMPE A,RDSTRL ;IF FULL, GO GIVE ERROR MESSAGE
CAIN A,MAXSTC ;IS BUFFER EMPTY
JRST RDSTRD ;YES, GO RING BELL
POP P,A ;NO, ECHO CHARACTERS RECEIVED SO FAR
PUSHJ P,TTSLOG ;PUT CHARACTERS INTO LOG FILE
JRST RDSTR] ;AND GO GET MORE
LDB B,COMBP ;GET TERMINATOR
MOVEI A,0 ;STORE NULL IN BUFFER
DPB A,COMBP
POP P,A ;GET BACK POINTER TO UN ECHOED CHARS
PUSH P,B ;SAVE TERMINATOR
PUSHJ P,TTSLOG ;ECHO CHARACTERS INTO LOG FILE
MOVE A,COMBP ;BACK UP THE POINTER
BKJFN
JFCL
MOVEM A,COMBP ;STORE NEW POINTER
AOS COMCNT ;FREE UP A CHAR
POP P,A ;GET BACK TERMINATOR
PUSHJ P,TTBLOG ;AND LOG THE TERMINATOR CHARACTER
JRST CPOPJ1 ;AND GIVE SUCCESSFUL RETURN
RDSTRD: MOVEI A,100 ;GET BACK THE LAST CHAR TYPED
BKJFN
JRST COMLVL ;IF ERROR, GO START OVER
BIN ;GET CHAR BACK
ERJMP COMLVL
CAIN B,"U"-100 ;CONTROL-U?
JRST COMLVL ;YES, ABORT THE COMMAND
MOVEI A,7 ;RING BELL
CALL TTBOUT
POP P,(P) ;CLEAN UP THE STACK
JRST RDSTR ;AND LOOP BACK FOR MORE
RDSTRL: ERRMES (<? LINE TOO LONG>)
JRST COMLVL
RDSTRF: PUSHJ P,TTYGET ;GET NEXT CHARACTER FROM FILE
POPJ P, ;AN INTERRUPT OCCURRED
SKIPN RDJFN ;STILL READING FROM FILE?
JRST RDSTR1 ;NO, GO GET CHARS FROM TTY
CAIN A,12 ;LINE FEED?
JRST [ MOVEI A,15 ;YES, ECHO CR-LF
PUSHJ P,TTBOUT
MOVEI A,12 ;GET BACK THE LINE FEED
JRST .+1]
PUSHJ P,TTBOUT ;ECHO THE CHARACTER
CAIL A,"0" ;A NUMBER?
CAILE A,"9"
SKIPA ;NO
JRST RDSTR2 ;YES
CAIL A,"A" ;A LETTER?
CAILE A,"Z"
SKIPA ;NO
JRST RDSTR2 ;YES
CAIL A,141 ;A LOWER CASE LETTER?
CAILE A,172
JRST CPOPJ1 ;NO, END OF WORD
RDSTR2: IDPB A,COMBP ;STORE THIS ALPHANUMERIC CHAR
SOSLE COMCNT ;KEEP COUNT
JRST RDSTRF ;GET ANOTHER
JRST CPOPJ1 ;BUFFER IS FULL
;ROUTINE TO SET UP A READ FILE
READ: SKIPE NOFLAG ;USER SAY "NO"?
JRST COMERR ;YES, ERROR
SKIPE RDJFN ;READING ALREADY?
JRST [ PUSHJ P,CRWAIT ;WAIT FOR END OF LINE
ERRMES (<? DOING A "GET" WITHIN A "GET" IS ILLEGAL>)
JRST COMLVL]
MOVEI B,0 ;GET NAME OF FILE TO BE READ
CAIN A,12 ;TERMINATED WITH LF?
JRST READA ;YES, READ DEFAULT
MOVX A,GJ%OLD+GJ%CFM+GJ%XTN
MOVEM A,RDBLOK
READ1: MOVEI B,0 ;RESET B TO ZERO
READ2: MOVEI A,RDBLOK ;GET E-BLOCK FOR GTJFN
MOVE C,RDBLOK+.GJCPP ;SAVE POINTER TO THE FILENAME
GTJFN
JRST RDGTJF ;NO SUCH FILE
HRRZM A,RDJFN ;SAVE JFN
MOVE B,[7B5+1B19] ;NOW OPEN IT
OPENF
JRST RDOPNF ;FAILED
MOVE A,C ;GET FILENAME POINTER
PUSHJ P,TTSLOG ;LOG IT
JRST COMLVL ;RETURN
READA: MOVEI A," " ;TYPE OUT A SPACE
PUSHJ P,TTBOUT
MOVSI A,(1B2)
MOVEM A,RDBLOK
HRROI B,[BYTE (7) 33,15,12,0]
JRST READ2 ;GET DEFAULT JFN
RDBLOK: GJ%OLD+GJ%CFM+GJ%XTN
100,,101
0
0
-1,,[ASCIZ/PTYCON/]
-1,,[ASCIZ/ATO/]
0
0
0
G1%RND+2
-1,,GETBUF
200
RDOPNF: PUSH P,A
MOVE A,RDJFN ;RELEASE JFN
RLJFN
JFCL
SETZM RDJFN
POP P,A
RDGTJF: PUSHJ P,TYPERR ;AND TYPE ERROR MESSAGE
JRST COMLVL
SILNCE: PUSHJ P,CRWAIT ;WAIT FOR TERMINATOR
SETZM SILNCF ;INIT SILENCE FLAG
SKIPN NOFLAG ;WAS THIS A "NO SILENCE" REQUEST?
SETOM SILNCF ;NO, THEN SILENCE THE OUTPUT FROM GET
JRST COMLVL
; ROUTINE TO SET UP A LOG FILE
LOG: SKIPE NOFLAG ;USER SAY "NO"?
JRST NOLOG ;YES, GO TURN OFF LOGGING
MOVEI B,0 ;INITIALIZE FOR GTJFN OF LOG FILE
CAIN A,12 ;WAS COMMAND TERMINATED WITH LF?
JRST LOGA ;YES, GET DEFAULT
MOVSI A,(1B4!1B15) ;CONFIRMATION REQ'D & LONGER GTJFN CALL
MOVEM A,LOGBLK ;STORE FOR LONG FORM GTJFN
LOG1: MOVEI B,0 ;...
SKIPN RDJFN ;READING FROM A FILE?
JRST LOG2 ;NO
PUSHJ P,READLN ;YES, GET THE NAME TO USE
HRROI B,STRING ;USE THIS AS A MAIN STRING
LOG2: MOVEI A,LOGBLK ;GET E-BLOCK FOR GTJFN
GTJFN
JRST LGFAIL ;FAILED
LOG3: HRRZS A ;CLEAR LEFT HALF OF JFN
EXCH A,LOGJFN ;SAVE NEW LOGGING JFN
SKIPE A ;WAS THERE A JFN
CLOSF ;CLOSE THE OTHER ONE
JFCL
HRRZ A,LOGJFN ;GET BACK JFN
MOVE B,[7B5+1B20+1B22] ;APPEND MODE
OPENF
JRST LGOPNF ;OPEN FAILED
HRROI B,[ASCIZ/
************************************************************************
PTYCON LOG FILE /]
SETZ C,
SOUT ;SEND OUT HEADER
SETO B, ;NOW SEND OUT THE DATE
ODTIM
HRROI B,[ASCIZ/
/]
SOUT
JRST COMLVL ;AND RETURN
LOGA: MOVEI A," " ;SEPARATE COMMAND FROM DEFAULT NAME
PUSHJ P,TTBOUT
MOVSI A,(1B15) ;LONGER GTJFN CALL
MOVEM A,LOGBLK ;STORE FOR LONGER FORM GTJFN
HRROI B,[BYTE (7) 33,15,12,0]
JRST LOG2 ;GO GET DEFAULT JFN
LGOPNF: PUSH P,A ;SAVE ERROR CODE
MOVE A,LOGJFN ;GET JFN
RLJFN ;RELEASE IT
JFCL
SETZM LOGJFN ;CLEAR JFN WORD
POP P,A ;GET BACK ERROR
JRST RDGTJF ;GO TYPE OUT ERROR MESSAGE
LOGCLS: SKIPN LOGJFN ;IS THERE A LOG FILE OPEN
POPJ P, ;NO, RETURN
PUSHJ P,PIOFF ;DON'T ALLOW INTERRUPTS HERE
MOVE A,LOGJFN ;GET LOGGING JFN
HRLI A,(1B0) ;CLOSE IT BUT KEEP THE JFN
CLOSF
JRST LGCLSF ;HAD A PROBLEM, GO TYPE MESSAGE
HRRZ A,LOGJFN ;GET JFN AGAIN
MOVE B,[7B5+1B20+1B22] ;OPEN IT AGAIN IN APPEND MODE
OPENF
JRST LGCLSF ;FAILED
PUSHJ P,PION ;TURN PI'S BACK ON
POPJ P, ;RETURN
LGCLSF: PUSH P,A ;SAVE ERROR CODE
PUSHJ P,PION ;TURN INTERRUPTS BACK ON
POP P,A ;GET BACK ERROR CODE
JRST LGOPNF ;GO TYPE OUT ERROR MESSAGE
; GTJFN FAILED INITIALLY ON LOG FILE
LGFAIL: CAIN A,GJFX37 ;USER TYPE ^U TO DELETE TYPE-IN ?
JRST COMLVL ;YES, FEED HIM A NEW PROMPT
JRST RDGTJF ;FAILURE FOR OTHER REASONS
LOGBLK: 20000,,0 ;CONFIRMATION,,DEFAULT VERSION #
100,,101 ;PRIMARY TTY
0
0
-1,,[ASCIZ/PTYCON/]
-1,,[ASCIZ/LOG/]
BLOCK 3
G1%RND+2 ;# OF ADDITIONAL WORDS FOR LONGER GTJFN
-1,,LOGBUF ;RETURN BUFFER POINTER
200 ;BUFFER SIZE
NOLOG: PUSHJ P,CRWAIT ;WAIT FOR EOL
HRRZ A,LOGJFN ;GET JFN OF LOGGING DEVICE
JUMPE A,COMLVL ;IF NONE, DON'T CLOSE IT
CLOSF ;CLOSE IT
JRST LGOPNF ;BAD
SETZM LOGJFN ;CLEAR JFN WORD
JRST COMLVL ;ALL THROUGH
; ROUTINE TO SET UP A SAVE INPUT FILE
SAVINP: SKIPE NOFLAG ;USER SAY "NO"?
JRST NOSAVI ;YES, GO TURN OFF LOGGING
MOVEI B,0 ;INITIALIZE FOR GTJFN OF LOG FILE
CAIN A,12 ;WAS COMMAND TERMINATED WITH LF?
JRST SVIA ;YES, GET DEFAULT
MOVSI A,(1B4!1B15) ;CONFIRMATION REQ'D & LONGER GTJFN CALL
MOVEM A,SVIBLK ;STORE FOR LONG FORM GTJFN
SVI1: MOVEI B,0 ;...
SKIPN RDJFN ;READING FROM A FILE?
JRST SVI2 ;NO
PUSHJ P,READLN ;YES, GET THE NAME TO USE
HRROI B,STRING ;USE THIS AS A MAIN STRING
SVI2: MOVEI A,SVIBLK ;GET E-BLOCK FOR GTJFN
GTJFN
JRST SVIFAI ;FAILED
SVI3: HRRZS A ;CLEAR LEFT HALF OF JFN
EXCH A,SVIJFN ;SAVE NEW LOGGING JFN
SKIPE A ;WAS THERE A JFN
CLOSF ;CLOSE THE OTHER ONE
JFCL
HRRZ A,SVIJFN ;GET BACK JFN
MOVE B,[7B5+OF%WR] ;OPEN FOR WRITE
OPENF
JRST SVIPNF ;OPEN FAILED
HRROI B,[ASCIZ/
************************************************************************
PTYCON SAVED INPUT FILE /]
SETZ C,
SOUT ;SEND OUT HEADER
SETO B, ;NOW SEND OUT THE DATE
ODTIM
HRROI B,[ASCIZ/
/]
SOUT
JRST COMLVL ;AND RETURN
SVIA: MOVEI A," " ;SEPARATE COMMAND FROM DEFAULT NAME
PUSHJ P,TTBOUT
MOVSI A,(1B15) ;LONGER GTJFN CALL
MOVEM A,SVIBLK ;STORE FOR LONGER FORM GTJFN
HRROI B,[BYTE (7) 33,15,12,0]
JRST SVI2 ;GO GET DEFAULT JFN
SVIPNF: PUSH P,A ;SAVE ERROR CODE
MOVE A,SVIJFN ;GET JFN
RLJFN ;RELEASE IT
JFCL
SETZM SVIJFN ;CLEAR JFN WORD
POP P,A ;GET BACK ERROR
JRST RDGTJF ;GO TYPE OUT ERROR MESSAGE
SVILSF: PUSH P,A ;SAVE ERROR CODE
PUSHJ P,PION ;TURN INTERRUPTS BACK ON
POP P,A ;GET BACK ERROR CODE
JRST SVIPNF ;GO TYPE OUT ERROR MESSAGE
; GTJFN FAILED INITIALLY ON LOG FILE
SVIFAI: CAIN A,GJFX37 ;USER TYPE ^U TO DELETE TYPE-IN ?
JRST COMLVL ;YES, FEED HIM A NEW PROMPT
JRST RDGTJF ;FAILURE FOR OTHER REASONS
SVIBLK: 20000,,0 ;CONFIRMATION,,DEFAULT VERSION #
100,,101 ;PRIMARY TTY
0
0
-1,,[ASCIZ/SAVED-INPUT/]
-1,,[ASCIZ/TXT/]
BLOCK 3
G1%RND+2 ;# OF ADDITIONAL WORDS FOR LONGER GTJFN
-1,,LOGBUF ;RETURN BUFFER POINTER
200 ;BUFFER SIZE
NOSAVI: PUSHJ P,CRWAIT ;WAIT FOR EOL
HRRZ A,SVIJFN ;GET JFN OF LOGGING DEVICE
JUMPE A,COMLVL ;IF NONE, DON'T CLOSE IT
CLOSF ;CLOSE IT
JRST SVIPNF ;BAD
SETZM SVIJFN ;CLEAR JFN WORD
JRST COMLVL ;ALL THROUGH
;SAVE INPUT IN FILE IF ONE HAS BEEN SPECIFIED
LOGINP: SAVEAC <A,B,C>
SKIPN A,SVIJFN ;HAVE A JFN?
RET ;NO
CAIN B,.CHESC ;CHECK SPECIAL CHARACTERS, ESC
JRST [ MOVEI B,"^"
BOUT
MOVEI B,"$"
JRST SAVIP1]
CAIN B,.CHCRT ;CR
JRST [ BOUT ;PUT IN LF TOO
MOVEI B,.CHLFD
JRST SAVIP1]
CAIN B,.CHDEL ;A RUBOUT?
JRST [ BKJFN ;YES, TRY TO DELETE LAST CHAR FROM FILE
SKIPA A,SVIJFN ;COULDN'T, GET JFN BACK
RET ;OK, DON'T NEED TO PUT RUBOUT IN FILE
MOVEI B,.CHDEL ;MUST PUT RUBOUT IN FILE
JRST SAVIP1]
CAIGE B,40 ;PRINTING CHAR
CAIN B,.CHTAB ;OR TAB
JRST SAVIP1 ;YES, SEND AS IS
MOVE C,B ;CONTROL CHAR, SAVE IT
MOVEI B,"^"
BOUT ;SEND ESCAPE CHAR
MOVEI B,100(C) ;CONVERT CONTROL TO PRINTING EQUIV
SAVIP1: BOUT
RET
TYPERR: PUSH P,A ;TYPE ERROR
PUSHJ P,CHKLM ;AT LEFT MARGIN?
PUSHJ P,CRLF ;NO, TYPE CR-LF
HRROI A,ERRSTR ;PUT MESSAGE INTO A STRING
POP P,B
HRLI B,400000
SETZ C,
ERSTR ;TYPE ERROR
JFCL
SKIPA A,[POINT 7,[ASCIZ/UNKNOWN ERROR CODE/]]
HRROI A,ERRSTR
PUSHJ P,TTSOUT ;TYPE OUT STRING
POPJ P,
;ROUTINE TO KILL A JOB
KILL: SKIPE NOFLAG ;USER SAY "NO"?
JRST COMERR ;YES, ERROR
CAIE A,15 ;END WITH CR
CAIN A,12 ; OR LF?
JRST TOOFEW ;YES, NEED MORE ARGUMENTS
KILL1: PUSHJ P,GETSJB
JRST KILL3 ;NO MATCH, CHECK FOR NULL STRING
JRST KILL2 ;USER TYPED ALL
CAIN A,"," ;IS THIS A STRING OF ARGUMENTS?
JRST [PUSHJ P,TTBOUT ;YES, DO THIS ONE
PUSHJ P,KILJOB ;THEN GO BACK FOR MORE
JRST KILL1]
PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
PUSHJ P,KILJOB ;THEN KILL SPECIFIED JOB
JRST COMLVL ;GO TYPE OUT PROMPT
KILL2: PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
PUSH P,I ;SAVE SUBJOB INDEX
PUSH P,P1 ;AND PERMANENT ACS
MOVE P1,PTYHGH ;SET UP TO SCAN ALL SUBJOBS
MOVEI I,0 ;START AT 0
KILLLP: PUSHJ P,KILJOB ;KILL EACH ONE
ADDI I,PTYLEN ;GO TO NEXT SUBJOB
SOJGE P1,KILLLP ;LOOP FOR ALL SUBJOBS
POP P,P1 ;RESTORE PERMANENT ACS
POP P,I
JRST COMLVL ;GO BACK TO COMMAND LEVEL
KILL3: MOVE B,COMCNT ;SEE IF A NULL STRING WAS GIVEN
CAIE B,MAXSTC ;...
JRST ILLSJB ;NO, ERROR
CAIN A,12 ;YES, WAS IT ENDED WITH LF?
JRST COMLVL ;YES, END OF COMMAND
MOVEI A,7 ;...OTHERWISE RING BELL
PUSHJ P,TTBOUT ;...
JRST KILL1 ;AND TRY AGAIN
KILJOB: SKIPN A,PTYTTD(I) ;IS THERE A JOB STARTED HERE?
POPJ P, ;NO, DON'T KILL IT
HRLZS A ;GET TTY NUMBER
TLZ A,400000 ;TURN OFF TTY DESIGNATOR
HRR A,TTYJOB ;GET TTYJOB TABLE NUMBER FOR GETAB
GETAB ;GET JOB NUMBER ASSOCIATED WITH TTY
JRST KILJB1 ;FAILED
HLRES A
JUMPL A,KILJB1 ;IF -1 OR -2, THEN NO JOB
LGOUT ;LOG THIS JOB OUT
JRST [ HRROI A,[ASCIZ/COULD NOT KILL SUBJOB /]
PUSHJ P,TTSOUT
PUSHJ P,TYPNAM
PUSHJ P,CRLF
POPJ P,]
KILJB1: HRRZ A,PTYJFN(I) ;THEN RELEASE JFN
CLOSF
JFCL ;JOB WILL BECOME DETACHED
SETZM PTYTAB(I) ;MARK THAT JOB WAS KILLED
HRLI A,PTYTAB(I) ;CLEAR UP ALL TRACKS
HRRI A,PTYTAB+1(I)
BLT A,PTYTAB+PTYLEN-1(I)
POPJ P, ;AND RETURN
;ROUTINE TO READ IN A SUBJOB NUMBER OR NAME AND SET UP I
;CALL GETSJB
;RETURN +1 NO SUBJOB MATCH, BUT TERMINATOR SEEN (IN A)
; +2 USER SAID "ALL"
; +3 SUBJOB # IN I, TERMINATOR IN A
GETSJB: PUSHJ P,COMINI ;INITIALIZE COMMAND BUFFER
GTSJB1: PUSHJ P,RDSTR ;GO READ IN A STRING
JRST GTSJB1 ;NO INTERUPTIONS NOW
PUSH P,A ;SAVE TERMINATOR
PUSHJ P,FNDPTY ;SEE IF THIS WAS A LEGAL JOB #
JRST GTSJB2 ;NO
POP P,A ;LEAVE TERMINATOR IN A
JRST CPOPJ2 ;TAKE DOUBLE SKIP RETURN
GTSJB2: MOVE A,STRING ;NOW CHECK FOR "ALL"
CAME A,[ASCIZ/ALL/]
JRST [POP P,A ;NOT "ALL" SO GIVE ERROR RETURN
CAIN A,33
POPJ P, ;IF ALTMODE, RETURN
CAIN A,12
POPJ P, ;OR IF LF
MOVEI A,7 ;OTHERWISE RING BELL
PUSHJ P,TTBOUT
JRST GTSJB1] ;AND GO GET MORE FROM USER
POP P,A ;GET TERMINATOR
JRST CPOPJ1 ;GIVE SKIP RETURN FOR "ALL"
IGNOR: CAIN A,12 ;USER END WITH LF?
JRST TOOFEW ;YES, DEMAND SUBJOB
IGNOR0: PUSHJ P,GETSJB ;GET THE ARGUMENT
JRST IGNOR3 ;CR-LF OR ALTMODE
JRST IGNOR1 ;"ALL"
MOVSI B,PTIGNF ;USER GAVE A LEGAL SUBJOB #
MOVE C,[IORM B,PTYSTS(I)]
SKIPE NOFLAG ;DOES USER WANT TO SET OR CLEAR IT
MOVE C,[ANDCAM B,PTYSTS(I)]
XCT C ;SET OR CLEAR THE IGNORE FLAG
CAIN A,"," ;WAS THIS JUST ONE NAME IN A LIST?
JRST IGNOR0
PUSHJ P,CRWAIT ;NO, WAIT FOR CONFIRMATION
JRST COMLVL ;THEN RETURN TO COMMAND LEVEL
IGNOR1: PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
MOVSI B,PTIGNF ;SET UP TO SET OR CLEAR IGNORE BIT
MOVE C,[IORM B,PTYSTS(I)]
SKIPE NOFLAG ;IF USER SAID "NO", THEN CLEAR BIT
MOVE C,[ANDCAM B,PTYSTS(I)]
MOVE D,PTYHGH ;LOOP FOR ALL SUBJOBS
MOVEI I,0 ;STARTING AT 0
IGNOR2: XCT C ;SET OR CLEAR THE IGNORE BIT
ADDI I,PTYLEN ;STEP TO NEXT SUBJOB
SOJGE D,IGNOR2 ;LOOP BACK FOR ALL SUBJOBS
SETOM IGNALL ;SET IGNORE ALL FLAG
SKIPE NOFLAG ;WAS A NO TYPED?
SETZM IGNALL ;YES, CLEAR FLAG
JRST COMLVL ;THEN RETURN TO COMMAND LEVEL
IGNOR3: MOVE B,COMCNT ;SEE IF THIS WAS A NULL COMMAND
CAIE B,MAXSTC
JRST ILLSJB ;IF NOT, THEN THIS IS AN ERROR
CAIN A,12 ;DID THE USER TYPE LF?
JRST TOOFEW ;YES, GO COMPLAIN
MOVEI A,7 ;NO, THEN THIS IS AN ERROR, RING BELL
PUSHJ P,TTBOUT
JRST IGNOR0 ;GO GET ANOTHER SUBJOB NAME
;WHAT ROUTINE
WHATPT: SKIPE NOFLAG ;USER SAY "NO"?
JRST COMERR ;YES, ERROR
PUSH P,A ;SAVE TERMINATOR
PUSHJ P,COMINI ;START WITH A FRESH COMMAND BUFFER
POP P,A ;GET BACK TERMINATOR
CAIN A,12 ;WAS IT A LF?
JRST WHAT4 ;YES, DO "ALL"
WHAT1: PUSHJ P,RDSTR ;NO, GO GET A SUBJOB NAME
JRST WHAT1 ;NO INTERRUPTIONS
CAIE A,12 ;ENDED WITH LF?
CAIN A,33 ; OR ALTMODE?
JRST WHAT4 ;YES, CHECK FOR "ALL"
WHAT3: PUSH P,A ;SAVE TERMINATOR
PUSHJ P,FNDPTY ;SEE IF THIS WAS A LEGAL NAME
JRST WHAT2 ;NO
POP P,A ;GET BACK TERMINATOR
PUSHJ P,CRWAIT ;WAIT R CONFIRMATION
SETZM TOFLAG ;INITIALIZE TYPE OUT FLAG
SKIPN PTYJFN(I) ;DOES THIS JOB EXIST?
JRST [HRROI A,[ASCIZ/SUBJOB "/] ;NO
PUSHJ P,TTSOUT ;TYPE "SUBJOB X NOT IN USE"
PUSHJ P,TYPNUM ;TYPE #
HRROI A,[ASCIZ/" NOT IN USE./]
PUSHJ P,TTSOUT
JRST WATDON] ;AND EXIT
PUSHJ P,TYPSYS ;GO TYPE OUT SYSTAT FOR THIS JOB
JRST WATDON ;AND EXIT
WHAT2: MOVE A,STRING ;CHECK FOR "ALL"
CAME A,[ASCIZ/ALL/]
JRST [POP P,A ;NOT "ALL", RING BELL
CAIN A,12 ;WAS IT TERMINATED WITH LF?
JRST ILLSJB ;YES, TYPE OUT ERROR MESSAGE
MOVEI A,7
PUSHJ P,TTBOUT
JRST WHAT1] ;AND GO BACK FOR MORE
WHAT5: POP P,A ;GET BACK TERMINATOR
PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
PUSH P,P1 ;SAVE PERMANENT ACS
PUSH P,I
MOVEI I,0 ;START AT # 0
MOVE P1,PTYHGH ;AND LOOP FOR ALL JOBS
SETZM TOFLAG ;INIT TYPE OUT FLAG FOR "NONE ACTIVE"
WHATLP: PUSHJ P,TYPSYS ;GO TYPE SYSTAT FOR EACH JOB
ADDI I,PTYLEN ;STEP TO NEXT JOB
SOJGE P1,WHATLP ;LOOP BACK FOR ALL JOBS
POP P,I
POP P,P1
WATDON: SKIPE TOFLAG ;WAS ANYTHING TYPED
JRST COMLVL ;YES, THEN WE ARE THROUGH
HRROI A,[ASCIZ/NONE ACTIVE!/]
PUSHJ P,TTSOUT ;NO, TELL USER SOMETHING
JRST COMLVL ; AND RETURN TO COMLVL
WHAT4: MOVE B,COMCNT ;SEE IF THIS WAS A NULL STRING
CAIE B,MAXSTC
JRST WHAT3 ;NO, THEN ERROR
CAIE A,15 ;CR OR LF?
CAIN A,12
JRST WHAT4A ;YES
MOVEI A," " ;TYPE A SPACE
PUSH P,A ;SAVE THIS NEW TERMINATOR
HRROI A,[ASCIZ/ ALL/]
PUSHJ P,TTSOUT ;ECHO "ALL"
JRST WHAT5 ;THEN GO DO SYSTAT
WHAT4A: PUSH P,A
JRST WHAT5
;ROUTINE TO TYPE A SYSTAT OF JOB
TYPSYS: SKIPN PTYJFN(I) ;IS THERE A JOB HERE
POPJ P, ;NO, TYPE NOTHING
PUSHJ P,CHKLM ;SEE IF ON LEFT MARGIN
PUSHJ P,CRLF ;NO, PUT US THERE
PUSHJ P,TYPNAM ;START WITH NAME OF SUBJOB
PUSHJ P,TYPTAB ;TAB
HRLZ A,PTYTTD(I) ;NOW SEE IF LOGGED IN
TLZ A,400000
HRR A,TTYJOB ;GET TABLE # FOR GETAB
GETAB
JRST TYPSNJ ;FAILED!
HLRE B,A ;GET TSS JOB NUMBER
JUMPL B,TYPSNJ ;IF -1 OR -2, THEN NOT LOGGED IN
PUSH P,B ;SAVE JOB NUMBER
HRROI A,STRING ;PUT NUMBER IN STRING
MOVEI C,12
NOUT
JFCL
HRROI A,STRING ;NOW TYPE OUT NUMBER
PUSHJ P,TTSOUT ;SO NUMBER GETS IN LOG
PUSHJ P,TYPTAB
MOVE A,0(P) ;GET THE JOB NUMBER
MOVE B,[-JITBLN,,JITAB] ;GET INFO ABOUT THIS JOB
SETZ C,
GETJI
JRST TYPSY2 ;IF NONE, DONT TYPE ANY MORE
MOVE B,JITAB+.JIUNO ;GET USER NUMBER
JUMPE B,[PUSHJ P,TYPSN1 ;NOT LOGGED IN IF 0
JRST TYPSY1]
HRROI A,STRING ;OUTPUT NAME TO STRING
DIRST ;TYPE OUT LOGGED IN NAME
JFCL
HRROI A,STRING
PUSHJ P,TTSOUT ;NOW TYPE OUT NAME
PUSHJ P,TYPTAB
MOVE A,JITAB+.JIPNM ;GET PROGRAM NAME
PUSHJ P,TYPSIX ;TYPE IT OUT
TYPSY1: PUSHJ P,TYPTAB
HRRZ A,PTYJFN(I)
MOVEI B,25 ;NOW SEE IF LINE IS HUNGRY
MTOPR
HRROI A,[ASCIZ/RN/] ;ASSUME NOT HUNGRY
SKIPE B ;IS IT HUNGRY
HRROI A,[ASCIZ/TI/] ;YES
SKIPE PTYCNT(I) ;IF JOB HAS OUTPUT WAITING,
HRROI A,[ASCIZ/TO/] ; THEN ALWAYS SAY "TO"
PUSHJ P,TTSOUT ;TYPE OUT STATE
PUSHJ P,TYPSY3 ;TYPE OUT I OR R IF NECESSARY
PUSHJ P,TYPTAB
MOVE A,JITAB+.JIRT ;GET RUN TIME OF THE JOB
IDIVI A,^D1000 ;TURN IT INTO SECONDS
IDIVI A,^D60 ;GET SECONDS
PUSH P,B ;SAVE SECONDS
IDIVI A,^D60 ;GET MINUTES
PUSH P,B
PUSHJ P,TTDNUM ;TYPE OUT THE DECIMAL HOURS
MOVEI A,":" ;FOLLOWED BY ":"
PUSHJ P,TTBOUT
POP P,A ;GET MINUTES
PUSHJ P,TTDNUM
MOVEI A,":"
PUSHJ P,TTBOUT
POP P,A ;AND NOW DO THE SECONDS
PUSHJ P,TTDNUM
TYPSY2: POP P,(P)
POPJ P,
TYPSY3: SETZ A, ;NOW SEE IF BEING REFUSED OR IGNORED
MOVE D,PTYSTS(I)
TLNE D,PTREFF ;REFUSED FLAG SET?
HRROI A,[ASCIZ/(R)/] ;YES, SAY SO
TLNE D,PTIGNF ;LINE BEING IGNORED?
HRROI A,[ASCIZ/(D)/] ;YES, THIS OVERRIDES REFUSED FLAG
SKIPE A
PUSHJ P,TTSOUT ;PRINT OUT STATE IF ON
POPJ P, ;AND RETURN
TYPTAB: PUSH P,B ;SAVE ACS
MOVEI A,101 ;GET COLUMN COUNT
RFPOS
HRRZ A,B
IDIVI A,TABSIZ ;GET NUMBER OF SPACES TO TYPE
MOVNS B ;CALCULATE NUMBER REMAINING
ADDI B,TABSIZ
MOVEI A," " ;SIMULATE WITH SPACES
CALL TTBOUT
SOJG B,.-1
POP P,B ;RESTORE ACS
POPJ P,
TYPSNJ: HRROI A,[ASCIZ/NO JOB NUMBER ASSIGNED TI/]
PUSHJ P,TTSOUT
PUSHJ P,TYPSY3 ;TYPE OUT I OR R IF NECESSARY
POPJ P,
TYPSNL: POP P,(P)
TYPSN1: HRROI A,[ASCIZ/NOT LOGGED IN/]
PUSHJ P,TTSOUT
POPJ P,
TYPSIX: MOVE D,A ;SAVE ARG
MOVEI C,6 ;TYPE A MAX OF 6 CHARS
MOVE B,[POINT 6,D] ;SET UP BYTE POINTER
TYPSXL: ILDB A,B ;GET NEXT CHAR
ADDI A,40 ;CONVERT TO ASCII
PUSHJ P,TTBOUT ;TYPE IT OUT
SOJG C,TYPSXL ;LOOP FOR 6 CHARS
POPJ P,
TTDNUM: MOVEI C,12 ;DECIMAL OUTPUT
MOVE B,A ;GET CHARACTER
HRROI A,STRING ;GET ANSWER INTO A STRING
NOUT
BUG (CHK,<NOUT FAILED>)
HRROI A,STRING ;NOW OUTPUT THE ANSWER
PUSHJ P,TTSOUT
POPJ P,
;ROUTINE TO DO OUTPUT FROM PTY'S
PTOCHK: MOVE A,BINTTY
MOVEM A,TERJFN ;SET UP BINARY CHANNEL FOR PTY TO TTY PIPELINE.
;ALTERNATE ENTRY POINT FOR WHEN TTY IS KNOWN TO ALREADY BE IN BINARY MODE ...
PTOCK9:
HRRES I ;CLEAR LEFT HALF OF INDEX
MOVEM I,CURENT ;REMEMBER THIS JOB INDEX
JUMPL I,PTOCK0 ;IF -1, THEN NO SPECIFIC JOB NUMBER
PUSHJ P,PTYTP2 ;GO TYPE OUT TEXT FROM THIS LINE
POPJ P, ;TYPE IN WAS SEEN
PTOCK0: PUSH P,P2 ;NOW CHECK OTHER PTY'S
PUSH P,P1
PUSH P,I
SETZB I,P2 ;START AT 0
MOVE P1,PTYHGH ;AND DO ALL JOBS
PTOCK1: SKIPN PTYCNT(I) ;IS THERE ANYTHING WAITING ON THIS
JRST PTOCK2 ;NO, GO ON TO NEXT
MOVE A,PTYSTS(I) ;YES, GET STATUS
TLNE A,PTREFF ;BEING REFUSED?
TLNE A,PTIGNF ;AND NOT IGNORED?
SKIPA ;NO
JRST [PUSHJ P,DINGGO ;YES, START DING FORK UP
AOJA P2,PTOCK2] ;MARK THAT ONE WAS FOUND WAITING
PUSHJ P,PTYTYP ;TYPE OUT HEADER AND TEXT
JRST PTOCK3 ;TYPE IN IS NOW PENDING
PTOCK2: ADDI I,PTYLEN ;STEP TO NEXT JOB NUMBER
SOJGE P1,PTOCK1 ;LOOP BACK FOR ALL LINES
SKIPN P2 ;WERE ANY LINES WAITING
PUSHJ P,STDING ;NO, THEN STOP THE DINGING
PTOCK3: POP P,I ;RESTORE ACS
POP P,P1
POP P,P2
JUMPL I,CPOPJ ;IF NO CURRENT JOB, JUST RETURN
PUSHJ P,PTYTYP ;TYPE OUT NEW HEADER IF NECESSARY
JFCL
POPJ P, ;AND RETURN
PTYTYP: SETZM IGNORF ;INITIALIZE IGNORE FLAG
MOVE A,PTYSTS(I) ;GET PTY STATUS
TLNE A,PTIGNF ;IGNORING TYPE OUT?
SETOM IGNORF ;YES, MARK IT SUCH
HRRE A,I ;GET SUBJOB INDEX
CAMN A,LSTHDR ;SAME AS LAST HEADER TYPED?
JRST PTYTP2 ;YES, DON'T TYPE A HEADER
MOVEI A,101
DOBE ;WAIT FOR TTY TO BE QUIET
RFMOD ;NOW SEE IF CONTROL-O ON
TLZE B,(1B0)
SFMOD ;YES, CLEAR IT
CALL PIOFF ;PREVENT INTS
PUSH P,TERJFN ;SAVE PRESENT JFN STATE
CALL ASCTER ;GET ASCII TERMINAL
PUSHJ P,CHKLM ;SEE IF AT START OF A LINE
PUSHJ P,CRLF ;NO, GO TO LEFT MARGIN
HRROI A,[ASCIZ/**** /]
PUSHJ P,TTSOUT
PUSHJ P,TYPNAM ;TYPE JOB NAME
MOVEI A," "
PUSHJ P,TTBOUT
HRROI A,STRING
SETO B,
MOVSI C,(1B0)
ODTIM ;FOLLOWED BY THE DATE
HRROI A,STRING
PUSHJ P,TTSOUT ;AS A TIME STAMP
HRROI A,[ASCIZ/ ****
/]
PUSHJ P,TTSOUT ;END OF HEADER
POP P,TERJFN ;RESTORE TERM DESIGNATOR
CALL PION ;ENABLE INTS
SKIPN IGNORF ;IF BEING IGNORED, DON'T STORE I
HRREM I,LSTHDR ;REMEMBER THIS JOB INDEX
PTYTP2: HRRE C,I ;GET INDEX
SKIPGE CURENT ;AT COMMAND LEVEL?
JRST PTYTP7 ;YES, CHECK FOR TTY INPUT
CAME C,CURENT ;SEE IF THIS IS THE CURRENT JOB
JRST PTYTP5 ;NO
PTYTP7: MOVE A,TERJFN
SIBE ;ANY CHARACTERS IN INPUT BUFFER FOR TTY
JRST [SETZM IGNORF ;YES, THEN EXIT NOW
POPJ P,] ; SO THOSE CHARACTERS CAN BE SENT
PTYTP5: MOVSI B,PTIGNF ;IGNORING THIS LINE?
TDNE B,PTYSTS(I) ;...
JRST PTYTP6 ;YES
CAME C,LSTHDR ;IS A HEADER NEEDED?
JRST PTYTYP ;YES, GO TYPE IT
PTYTP6: PUSHJ P,PTYGET ;GET A CHARACTER FROM BUFFER
JRST PTYTP4 ;NO MORE LEFT
PTYTP3: MOVSI B,PTIGNF ;LINE BEING IGNORED?
TDNE B,PTYSTS(I)
CAMN I,CURENT ;AND NOT THE CURRENT JOB
JRST PTYTP8 ;NO, TYPE OUT CHARACTER
PUSHJ P,TTBLG0 ;YES, JUST LOG THE CHARACTER
JRST PTYTP2 ;LOOP BACK
PTYTP4: MOVEI A,101
DOBE ;WAIT FOR OUTPUT TO FINISH
PUSHJ P,PTYGET ;SEE IF ANY MORE CHARACTERS ARRIVED
JRST [SETZM IGNORF ;NO, ALL DONE
JRST CPOPJ1] ;RETURN SUCCESSFULLY
JRST PTYTP3 ;YES, GO TYPE THESE OUT
PTYTP8: PUSHJ P,TTBOUT ;TYPE THE CHARACTER
CAIN A,12 ;IS IT A LF?
JRST [MOVEI A,101
RFPOS ;YES, GET FILE POSITION
HRRZS B ;RESET CTRL-Q COUNTER
SFPOS ;
JRST .+1] ;CONTINUE
JRST PTYTP2 ;LOOP BACK FOR MORE
TYPNAM: SKIPN D,PTYNAM(I) ;IS THERE A NAME FOR THIS LINE?
JRST TYPNM1 ;NO, JUST USE NUMBER
SETZ E, ;YES, TYPE IT OUT
HRROI A,D
PUSHJ P,TTSOUT
MOVEI A,"(" ;THEN TYPE "(JOB NUMBER)"
PUSHJ P,TTBOUT
PUSHJ P,TYPNUM ;TYPE OUT JOB NUMBER
MOVEI A,")"
PUSHJ P,TTBOUT
POPJ P,
TYPNM1: HRRE B,I ;GET SUBJOB NUMBER
IDIVI B,PTYLEN ; FROM INDEX
HRROI A,STRING
MOVEI C,12
NOUT ;CONVERT IT TO ASCIZ
JFCL
HRROI A,STRING
PUSHJ P,TTSOUT ;TYPE OUT NUMBER
POPJ P,
DINGGO: SKIPN BELLF ;IS BELL DISABLED
SKIPE DINGON ; OR ALREADY ON?
POPJ P, ;YES, DO NOTHING
MOVEI A,.FHSLF ;GET OUR PROCESS HANDLE
MOVX B,1B<.DNGCH> ;GET DING CHANNEL
AIC ;ACTIVATE THE CHANNEL
IIC ;INITIATE THE INTERRUPT ROUTINE
SETOM DINGON ;AND MARK THAT IT IS ON
POPJ P,
STDING: MOVEI A,.FHSLF ;GET OUR PROCESS HANDLE
MOVX B,1B<.DNGCH> ;GET THE DING CHANNEL
DIC ;DEACTIVATE THE CHANNEL
SETZM DINGON ;MARK THAT IT IS STOPPED
POPJ P,
DING: CALL DING0 ;DO THE WORK
DEBRK ;AND DEBREAK FROM INTERRUPT
DING0: SAVEAC <A,B,C,I> ;SAVE THESE ACS
MOVEI I,0 ;CHECK ALL JOBS FOR CHARACTERS
MOVE A,PTYHGH
DINGLP: SKIPE PTYCNT(I) ;ANY WAITING
JRST DINGER ;YES
ADDI I,PTYLEN ;STEP TO NEXT LINE
SOJGE A,DINGLP ;LOOP FOR ALL JOBS
JRST DINGWT ;WAIT FOR 10 SECONDS
DINGER: MOVEI A,7 ;OUTPUT A BELL
PBOUT
DINGWT: MOVE A,[XWD .FHSLF,.TIMEL] ;ELAPSED TIME FOR OUR FORK
MOVEI B,^D10000 ;TEN SECONDS TILL NEXT INTERRUPT
MOVEI C,.DNGCH ;GENERATE IT ON THE DING CHANNEL
TIMER ;...
JFCL
RET ;AND DONE
NOPTYS: ERRMES (<? NO MORE PTY'S AVAILABLE!>)
JRST COMLVL
BELL: PUSHJ P,CRWAIT ;WAIT FOR TERMINATOR
SKIPN NOFLAG ; TO BE NEGATED?
TDZA A,A ;NO
SETO A, ;YES
MOVEM A,BELLF ;SAVE STATE OF BELL
PUSHJ P,STDING ;TURN OFF BELL TO START WITH
PUSHJ P,PTOCHK ;GO TURN IT ON OR OFF
JRST COMLVL ;RETURN
;MAIN LOOP FOR TALKING WITH A PTY
PTYLOP: SKIPN PTYJFN(I) ;IS THERE A PTY OPENED FOR THIS JOB
PUSHJ P,PTINIT ;NO, GO INIT ONE
MOVNI A,5 ;SET JUST ESCAPE CHAR AS INTERRUPT CHAR
MOVE B,ESCMSK ;GET ESCAPE MASK
STIW ;SO CONTROL-O IS PASSED DOWN
MOVE A,BINTTY ;SET UP BINARY CHANNEL.
MOVEM A,TERJFN
PTYLP0: MOVEI A,MAXPTC ;INIT THE PTY BUFFER COUNTER
MOVEM A,CHRCNT ;INITIALIZE THE COUNT OF CHARS SEEN
PTYLP1: MOVE A,TERJFN ;SEE IF ANY CHARACTERS ARE READY.
SIBE
JRST PTYLP3 ;YES, GO GET THE CHARACTER
SKIPE PTYCNT(I) ;ANYTHING TO TYPE OUT?
JRST PTYLP2 ;YES, GO TYPE IT
PTYLP3: PUSHJ P,TTYGET ;GET A CHARACTER FROM TTY
JRST PTYLP2 ;NONE THERE
SOS CHRCNT ;COUNT DOWN THE NUMBER OF CHARACTERS
PUSH P,A ;SAVE CHARACTER
PUSHJ P,PTYOUT ;TYPE IT OUT
POP P,A ;GET BACK CHARACTER
SKIPN RDJFN ;READING FROM A FILE?
JRST PTYLP0 ;NO, GET ALL INPUT FROM TTY FIRST
CAIE A,.CHLFD ;LF? OR
CAIN A,.CHCRT ;CR?
JRST PTYLP4 ;YES, GO READ IN ANY ECHOES
SKIPLE CHRCNT
JRST PTYLP1 ;IF PTY BUFFER NOT FULL, GO GET MORE
MOVEI A,^D20 ;BUFFER FULL, LET SUBJOB EAT THEM
DISMS
JRST PTYLP1 ;LOOP BACK
PTYLP4: MOVEI A,MAXPTC ;GET PTY BUFFER SIZE
MOVEM A,CHRCNT ;INITIALIZE CHARACTER COUNT
MOVE A,PTYJFN(I)
MOVX B,.MOPIH
MTOPR ;SEE IF TTY HUNGRY
JUMPN B,PTYLP2 ;GO DO MORE INPUT IF HUNGRY
PUSHJ P,PTYLP6 ;WAIT FOR TIME OR INTERRUPT
JRST [ PUSHJ P,PTOCK9 ;GOT INTERRUPT, CHECK OUTPUT
JRST PTYLP4]
HRRZ A,RDJFN
BIN ;PEEK AT NEXT FILE CHAR
ERJMP PTYLP4 ; IF ERROR, EOF. DON'T BKJFN
BKJFN
JFCL
CAIE B,"^" ;SOME SORT OF ESCAPE?
JRST PTYLP4 ;NO, RECHECK HUNGRY. OTHERWISE GET MORE INPUT
PTYLP2: PUSHJ P,PTOCK9 ;GO SEE IF ANYTHING TO BE ECHOED
JRST PTYLP1 ;LOOP BACK
;WAIT FOR 1 SECOND OR INTERRUPT
PTYLP6: SETOM IOWATF ;SET FLAG FOR INTERRUPT ROUTINE
SKIPE WAKEF ;INTERRUPT RECENTLY?
JRST [ SETZM IOWATF ;YES, RETURN IMMED
SETZM WAKEF ;CLEAR WAKE FLAG
POPJ P,]
MOVEI A,^D1000 ;ONE SECOND
DISMS ;NO, BLOCK
SETZM IOWATF ;CLEAR FLAG
JRST CPOPJ1
;PTY RELATED ROuTINES
;ROUTINE TO GET A PTY JFN
GETPTY: MOVN D,SYSPTY ;GET # OF PTYS IN SYSTEM
HRLZS D
GETPT1: MOVSI A,600013 ;GET PTY DESIGNATOR
HRRI A,(D) ;TRY TO GET NEXT PTY
DVCHR ;GET CHARACTERISTICS OF THIS PTY
TLNN B,(1B5) ;IS IT AVAILABLE?
JRST GETPT2 ;NO
MOVE B,A
HRROI A,DEVNAM ;TURN IT INTO AN ASCII STRING
DEVST
JRST GETPT2
MOVEI B,":" ;TERMINATED BY A COLON
IDPB B,A
MOVEI B,0
IDPB B,A ;ENDED WITH A 0 BYTE
MOVSI A,1 ;SHORT FORM GTJFN
HRROI B,DEVNAM
GTJFN
JRST GETPT2 ;NOT AVAILABLE
MOVE B,[10B5+1B19+1B20] ;NOW TRY TO OPEN IT
PUSH P,A
OPENF
JRST GETPT3 ;NOT AVAILABLE
POP P,A ;GET BACK JFN
ADD D,FIRPTY ;TURN PTY UNIT # INTO TTY #
TRO D,400000 ;MAKE IT A TTY DESIGNATOR
HRRZM D,PTYTTD(I) ;STORE TTY DESIGNATOR
HRRZM A,PTYJFN(I) ;STORE JFN ALSO
MOVEI A,101 ;REFER TO THE TERMINAL WE'RE ON.
GTTYP ;ASK THE SYSTEM WHAT TYPE WE ARE.
MOVE A,PTYTTD(I) ;REFERENCE THE PTY.
STTYP ;SET THE PTY TYPE TO THE SAME AS OURSELF.
CPOPJ1: AOS (P) ;GIVE OK RETURN
CPOPJ: POPJ P,
CPOPJ2: AOS (P) ;DOUBLE SKIP RETURN
JRST CPOPJ1
GETPT3: POP P,A ;GET BACK JFN
RLJFN ;AND RELEASE IT
JFCL
GETPT2: AOBJN D,GETPT1 ;TRY FOR ANOTHER PTY
POPJ P, ;NONE LEFT
;ROUTINE TO INITIALIZE A PTY LINE
PTINIT: PUSHJ P,GETPTY ;GO OPEN A PTY
JRST NOPTYS ;NONE LEFT
SETZM PTYCNT(I) ;INITIALIZE DATA BASE FOR THIS PTY
MOVEI A,(I) ;GET INDEX
IDIVI A,PTYLEN ;TURN IT INTO SUBJOB #
IMULI A,PTYBSZ ;GET START OF OUTPUT BUFFER AREA
ADDI A,PTYBUF
HRLI A,(POINT 8,0) ;SET UP BYTE POINTERS TO BUFFER
MOVEM A,PTYIBP(I)
MOVEM A,PTYGBP(I)
MOVEM A,PTYPBP(I)
ADDI A,PTYBSZ-1 ;NOW GET BYTE POINTER TO END OF BUFFER
HRLI A,(POINT 8,0,31)
MOVEM A,PTYEBP(I) ;FOR END CHECKING
HRRZ A,PTYJFN(I) ;NOW PUT PTY ON A CHANNEL
MOVEI B,(I)
IDIVI B,PTYLEN ;GET SUBJOB #
IDIVI B,PTYNCH ;MODULO CHANNEL NUMBER
ASH C,1 ;DIVIDE BY 2
HRLI B,PTYCHN(C) ;GET ACTUAL CHANNEL # FOR THIS PTY
TLO B,(1B0+1B1) ;WANT TO WAKE ON HUNGRY AND OUTPUT WAIT
HRRI B,24
MTOPR ;PUT PTY ON SOFTWARE CHANNEL
POPJ P,
;ROUTINE TO OUTPUT A CHARACTER TO A PTY
PTYOUT: PUSH P,A
SKIPN PTYJFN(I) ;IS THERE A JFN FOR THIS PTY?
PUSHJ P,PTINIT ;NO, GO GET ONE
PUSHJ P,PTYPRM ;DOES THIS LINE NEED PRIMING
JRST PTYOU0 ;YES
JRST PTYOU1 ;WAITING FOR ^C TO TAKE EFFECT
JRST PTYOU3 ;NO, GO TYPE OUT CHARACTER
PTYOU0: MOVE A,0(P) ;GET CHARACTER TO BE SENT
CAIN A,3 ;IS IT A CONTROL-C (ODD PARITY AS RECEIVED FROM TTY)
JRST PTYOU3 ;YES, JUST SEND IT DIRECTLY
HRRZ A,PTYJFN(I) ;GET JFN
MOVEI B,3 ;SEND A CONTROL-C TO PRIME LINE
BOUT
PTYOU1: MOVEI A,^D500 ; FOR CONTROL-C TO TAKE EFFECT
DISMS
PUSHJ P,PTYPRM ;SEE IF PRIMED YET?
JRST PTYOU0 ;NO, GO SEND CHARACTER ANYWAY
JRST PTYOU1 ;WAIT SOME MORE
PTYOU3: POP P,B ;ALL PRIMED, GET CHARACTER AGAIN
PTYOU4: HRRZ A,PTYJFN(I) ;GET PTY JFN
BOUT ;SEND OUT THE CHARACTER
ERJMP [PUSH P,A ;SAVE A
PUSH P,B ; AND B
MOVX A,.FHSLF ;GET THE LAST ERROR
GETER ;GET THE CODE
HRRZ B,B ;GET RID OF PROCESS HANDLE
CAIE B,IOX33 ;BUFFER FULL?
JRST [POP P,B ;NO - SOME OTHER ERROR
POP P,A
CALL TYPERR ;TELL USER ABOUT ERROR
JRST .+1] ;REJOIN THE PATH
POP P,B ;YES - RESTORE REGS
POP P,A
DIBE ;WAIT FOR BUFFER TO EMPTY
JRST PTYOU4] ;TRY AGAIN
CAIN B,"O"-100 ;CONTROL-O?
CALL PTYFLU ;YES, FLUSH INTERNAL BUFFER
CALL LOGINP ;SAVE INPUT MAYBE
EXCH B,PTYLCH(I) ;SAVE LAST CHARACTER
CAIE B,3 ;CONTROL-C AS LAST CHAR?
POPJ P, ;NO, THEN DONE
CAMN B,PTYLCH(I) ;IS THIS A CONTROL-C ALSO
CALL PTYFLU ;YES, FLUSH INTERNAL BUFFER
POPJ P,
PTYPRM: HRLZ A,PTYTTD(I) ;GET TTY #
HRR A,TTYJOB ;AND TABLE #
TLZ A,400000 ;CLEAR TTY DEV DESIGNATOR
GETAB ;GET JOB # FOR THIS TTY
JRST CPOPJ1 ;NOT LOGGED IN
JUMPGE A,CPOPJ2 ;POSITIVE MEANS ALREADY PRIMED.
TLC A,-1 ;SEE IF -1
TLCE A,-1
JRST CPOPJ1 ;-2 MEANS IN PROCESS OF GETTING JOB #
POPJ P, ;NEEDS PRIMING
;ROUTINE TO FILL A PTY BUFFER IF ANY ROOM
PTYFIL: SKIPN PTYJFN(I) ;GET JFN
POPJ P, ;NONE, RETURN
PUSHJ P,PIOFF ;TURN OFF PI SYSTEM
PTYFL0: MOVE A,PTYCNT(I) ;GET CHARACTER COUNT
CAIL A,PTYMXC ;BUFFER FULL?
JRST PTYFL1 ;YES, DONT GET ANY MORE
MOVE A,PTYTTD(I) ;GET DEVICE DESIGNATOR
SOBE ;ANY CHARACTERS WAITING
SKIPA ;YES
JRST PTYFL1 ;NO, ALL DONE
HRRZ A,PTYJFN(I) ;GET JFN AGAIN
BIN ;READ IN CHARACTER
MOVE A,B
PUSHJ P,PTYPUT ;STORE CHARACTER
JFCL
ANDI A,177
CAIN A,.CHLFD ;END OF A LINE?
JRST PTYFL1 ;YES, STOP HERE IN CASE SOMETHING ELSE TO DO
MOVE A,PTYSTS(I) ;GET CURRENT STATUS OF THIS PTY
TLNE A,PTIGNF ;OUTPUT BEING IGNORED?
JRST PTYFL0 ;YES, DONT START THE BELL
SKIPE PUSHF ;IS USER IN LOWER EXEC?
PUSHJ P,DINGGO ;YES, START DINGER
JRST PTYFL0 ;LOOP FOR REST OF CHARACTERS
PTYFL1: PUSHJ P,PION ;TURN INTERRUPTS BACK ON
POPJ P,
;ROUTINE TO STORE A CHARACTER INTO A PTY BUFFER
PTYPUT: MOVE B,PTYCNT(I) ;GET COUNT OF CHARS IN BUFFER
CAIL B,PTYMXC ;IS BUFFER FULL
POPJ P, ;YES, DONT OVERFILL IT
SKIPN ADDPAR ;ALLOW PARITY?
ANDI A,177 ;NO
IDPB A,PTYPBP(I) ;STORE CHARACTER
MOVE B,PTYPBP(I) ;GET NEW POINTER
CAMN B,PTYEBP(I) ;IS IT TIME TO WRAP AROUND?
MOVE B,PTYIBP(I) ;YES, WRAP IT AROUND TO BEGINING
MOVEM B,PTYPBP(I) ;STORE UPDATED POINTER
AOS PTYCNT(I) ;INCREMENT COUNT
JRST CPOPJ1 ;GIVE SUCCESSFUL RETURN
;ROUTINE TO GET A CHARACTER FROM THE PTY BUFFER
PTYGET: SKIPG PTYCNT(I) ;ANY CHARACTERS THERE
JRST PTYGT1 ;NO, CHECK FOR LOSSAGE
SOS PTYCNT(I) ;COUNT DOWN COUNT OF CHARS
ILDB A,PTYGBP(I) ;YES, GET THE CHARCTER
MOVE B,PTYGBP(I) ;SEE IF POINTER NEEDS WRAPPING AROUND
CAMN B,PTYEBP(I)
MOVE B,PTYIBP(I) ;YES, WRAP IT AROUND TO BEGINNING
MOVEM B,PTYGBP(I) ;STORE NEW POINTER
PUSH P,A ;SAVE CHARACTER
SKIPG PTYCNT(I) ;DECREMENT COUNT
PUSHJ P,PTYFIL ;IF NOW ZERO, GO TRY TO FILL IT
POP P,A ;GET BACK CHAR
JRST CPOPJ1 ;AND GIVE SUCCESSFUL RETURN
PTYGT1: MOVE B,PTYGBP(I) ;OUT OF SYNC?
CAMN B,PTYPBP(I)
POPJ P, ;NO
PUSH P,A ;POSSIBLY
PUSHJ P,PIOFF ;TOUCHY CODE
MOVE B,PTYPBP(I) ;GET OUTPUT POINTER
SKIPG PTYCNT(I) ;OUT OF SYNC REALLY?
MOVEM B,PTYGBP(I) ;YES, FIX THIS PROBLEM
PUSHJ P,PION ;ALL DONE
POP P,A
POPJ P,
;ROUTINE TO FLUSH OUTPUT FROM A PTY
PTYFLU: PUSH P,A
PUSHJ P,PIOFF ;TOUCHY CODE AGAIN
SETZM PTYCNT(I) ;GONE!
MOVE A,PTYPBP(I) ;SET UP BYTE POINTERS
MOVEM A,PTYGBP(I)
SETZM PTYLCH(I) ;CLEAR LAST CHAR ALSO
PUSHJ P,PION
POP P,A
POPJ P,
;PTY INTERRUPT LEVEL ROUTINES
DEFINE BLDCHN(A)<
PTYCH'A: PUSHJ P,ACSAVE
MOVEI I,A*PTYLEN
JRST PTYINT>
ZZ=0
REPEAT PTYNCH,<BLDCHN(\ZZ)
ZZ=ZZ+1>
PTYINT: SKIPE PTYJFN(I) ;IS THERE A JFN FOR THIS PTY?
PUSHJ P,PTYFIL ;YES, GO SEE IF IT HAS CHARACTERS READY
ADDI I,PTYNCH*PTYLEN ;STEP TO NEXT PTY IN THIS GROUP
MOVE A,PTYHGH ;GET HIGHEST PTY
IMULI A,PTYLEN ;CALCULATE ITS INDEX
CAMG I,A ;HAVE WE REACHED THE END YET?
JRST PTYINT ;NO, TRY THIS PTY
PUSHJ P,ACLOAD ;YES, RESTORE THE ACS
;TTY INPUT INTERRUPT COMES HERE TO WAKE UP MAIN LEVEL
SKIPE IOWATF ;IS LOWER LEVEL WAITING
POP P,RETSAV ;YES, WAKE IT UP
SETZM IOWATF ;CLEAR WAIT FLAG
SETOM WAKEF ;MARK THAT A WAKE HAPPENED
DEBRK ;AND DISMISS THE INTERRUPT
ACSAVE: EXCH A,0(P) ;SAVE A AND GET RETURN PC IN A
PUSH P,B ;SAVE B
PUSH P,C ;SAVE C
PUSH P,D ;SAVE D
PUSH P,I ;SAVE I
JRST (A) ;RETURN TO CALLER
ACLOAD: POP P,A ;LOAD AC A WITH RETURN ADDRESS
POP P,I ;RESTORE I
POP P,D ;RESTORE D, C, AND B
POP P,C
POP P,B
EXCH A,0(P) ;RESTORE A AND PUT RETURN ON STACK
POPJ P, ;RETURN TO CALLER
;ROUTINE TO PUSH DOWN TO A LOWER EXEC
PUSHE: PUSHJ P,CRWAIT ;WAIT FOR CONFIRMATION
SKIPE NOFLAG ;USER SAY "NO"?
JRST COMERR ;YES, ERROR
MOVSI A,(1B1) ;CREATE A LOWER FORK FOR EXEC
CFORK
JRST NOFORK
PUSH P,A ; SAVE PROCESS HANDLE
MOVSI A,(1B2!1B17) ;GET A JFN FOR THE EXEC
HRROI B,[ASCIZ/SYSTEM:EXEC.EXE/]
GTJFN
JRST NOEXEC ;NO EXEC FOUND
HRL A,0(P)
GET ;NOW GET THE EXEC INTO THE LOWER FORK
MOVEI A,.FHSLF ;DONT ALLOW LOWER FORK TO LOG OUT
RPCAP
TXZ B,SC%LOG
SETZ C, ;NO PRIVS ENABLED
MOVE A,0(P) ;GET LOWER FORK HANDLE
EPCAP ;SET ITS CAPABILITIES
MOVE A,TRPCHR
DTI ;DEACTIVATE INTERRUPT CHARACTER
MOVEI A,400000 ;TURN OFF THE TRAP CHANNEL
MOVE B,[1B<TRPCHN>] ;...
DIC
HRLI A,3 ;NOW PUT CONTROL-C ONTO CHANNEL
HRRI A,TRPCHN ;THIS PREVENTS A ^C FROM LEAVING PTYCON
ATI
MOVNI A,5
MOVE B,SAVTIW ;PUT TERMINAL INTERRUPT WORDS BACK
STIW
MOVEI A,100
MOVE B,SAVMOD ;SET UP ORIGINAL TTY MODE
SFMOD
STPAR
SETZM SAVMOD ;MODES MAY BE SET IN LOWER EXEC
SETO A, ;REMEMBER OUR NAME TO RESTORE IT LATER
MOVE B,[-2,,NAMES] ;GET BOTH NAMES
MOVEI C,.JISNM
GETJI
JFCL
POP P,A ;GET BACK FORK NUMBER
SETZ B,
SETOM PUSHF ;MARK THAT WE ARE PUSHED DOWN
SFRKV ;START THE EXEC
WFORK ;AND WAIT FOR IT TO HALT
SETZM PUSHF ;OUT OF EXEC
KFORK ;KILL THE LOWER FORK
PUSHE1: DMOVE A,NAMES
SETSN ;RESTORE NAME OF PROGRAM
JFCL
JRST PTYCON ;RESTART
NOEXEC: ERRMES (<? NO EXEC>)
POP P,A ; GET BACK PROCESS HANDLE
KFORK ; KILL IT
JFCL
JRST COMLVL
NOFORK: ERRMES (<? NO LOWER FORKS AVAILABLE>)
JRST PUSHE1
;STORAGE AREA DEFINITIONS
PTYBSZ==10000 ;SIZE OF BUFFER FOR EACH PTY
PTYBUF==400000 ;START OF PTY BUFFERS
PTYMXC==PTYBSZ*4 ;# OF CHARACTERS IN A BUFFER
MAXPTY==30 ;MAXIMUM NUMBER OF JOBS ALLOWED
DEFINE ALC (NAM,SIZ)<
NAM=LC
LC=LC+SIZ>
LC=300000 ;LOCAL STORAGE STARTS HERE
ALC ADDPAR,1 ;ADD PARITY BIT FOR REAL TERMINAL
ALC PICNT,1 ;# OF PIOFF'S DONE
ALC PTYHGH,1 ;HIGHEST SUBJOB IN USE
ALC IOWATF,1 ;WAITING FOR AN INTERRUPT
ALC WAKEF,1 ;AN INTERRUPT HAS HAPPENED
ALC FIRPTY,1 ;TTY NUMBER OF FIRST PTY
ALC NUMPTY,1 ;# OF PTY LINES AVAILABLE FOR PTYCON
ALC SYSPTY,1 ;NUMBER OF PTY'S IN SYSTEM
ALC TTYJOB,1 ;TABLE # OF TTYJOB FOR GETAB
ALC JOBPNM,1 ;GETAB TABLE # OF JOBNAM
ALC SNAMES,1 ;GETAB TABLE # OF SNAMES
ALC JOBRT,1 ;GETAB TABLE # OF JOBRT
ALC TIMASK,1 ;TERMINAL INTERRUPT MASK
ALC TRPCHR,1 ;TRAP CHARACTER TO GET BACK TO COMLVL
ALC ESCMSK,1 ;MASK FOR STIW WHEN AT SUBJOB LEVEL
ALC CHRCNT,1 ;COUNT OF CHARACTERS IN LINE SO FAR
ALC COMCNT,1 ;NUMBER OF CHARS LEFT IN COMMNAD BUF
ALC COMBP,1 ;POINTER TO NEXT CHAR IN COMAND BUFFER
ALC XJSYS,1 ;JSYS TO BE EXECUTED BY DO JSYS ROUTINE
ALC TERJFN,1 ;HOLDS TTY JFN CURRENTLY IN USE.
ALC BINTTY,1 ;JFN OF BINARY CHANNEL FOR TTY.
ALC SAVMOD,1 ;ORIGINAL TTY MODE
ALC SAVTYP,1 ;ORIGINAL TTY TYPE
ALC SAVTIW,1 ;ORIGINAL TERMINAL INTERRUPT WORD
ALC LSTCHR,1 ;LAST CHARACTER TYPED
ALC NOFLAG,1 ;IF SET, "NO" WAS TYPED
ALC IGNORF,1 ;IGNORING THIS LINE FLAG
ALC BELLF,1 ;DISABLE BELL FLAG
ALC SILNCF,1 ;-1 = TURN OF ECHOING OF GET COMMANDS
ALC LMFLAG,1 ;LEFT MARGIN FLAG
ALC REFALL,1 ;REFUSE ALL WAS TYPED
ALC IGNALL,1 ;IGNORE ALL WAS TYPED
ALC DINGON,1 ;DING FORK IS ON FLAG
ALC LSTHDR,1 ;INDEX OF LAST JOB A HEADER WAS TYPED
ALC LSTCON,1 ;LAST JOB CONNECTED TO
ALC NXLOGC,1 ;TIME FOR NEXT LOG FILE UPDATE
ALC RDJFN,1 ;JFN OF AUTO COMMAND FILE
ALC LOGJFN,1 ;JFN OF LOGGING FILE
ALC SVIJFN,1 ;JFN OF SAVE INPUT FILE
ALC CURENT,1 ;INDEX OF CURRENT JOB
ALC TOFLAG,1 ;SET TO -1 WHENEVER A CHAR IS TYPED
ALC PUSHF,1 ;SET TO -1 WHEN PUSHED DOWN TO EXEC
ALC NAMES,2 ;PROGRAM NAMES
ALC RETSAV,1 ;INTERRUPT PC
CNTRLC==3 ;CONTROL-C
CCMAX==4 ;MAX # OF ^C'S BEFORE TURNING OFF ^S
ALC CCCNT,1 ;COUNT OF ^C'S SEEN IN A ROW
ALC DEVNAM,2 ;ASCIZ DEVICE NAME OF PTY
JITBLN==.JIBAT+1 ;ROOM FOR UP TO JIBAT
ALC JITAB,JITBLN ;GETJI INFO FOR JOBS DURING "WHAT"
STRNGL==400
MAXSTC==STRNGL*5-1
ALC STRING,STRNGL ;TEMP STRING FOR BUILDING COMMANDS
ERRSTL==20
ALC ERRSTR,ERRSTL ;BLOCK FOR ERSTR STRINGS
PDLEN==30
ALC PDL,PDLEN ;STACK
ALC PTYTAB,0 ;PTY STORAGE AREA, MUST BE LAST SPACE ASSIGNED
PTYTTD==0+PTYTAB ;TTY DESIGNATOR
PTYJFN==1+PTYTAB ;JFN OF PTY
PTYCNT==2+PTYTAB ;COUNT OF CHARACTERS IN BUFFER
PTYIBP==3+PTYTAB ;INITIAL BUFFER POINTER
PTYEBP==4+PTYTAB ;END OF BUFFER POINTER
PTYPBP==5+PTYTAB ;PUTTER POINTER
PTYGBP==6+PTYTAB ;GETTER POINTER
PTYNAM==7+PTYTAB ;SUBJOB NAME (5 ASCII CHARACTERS)
PTYSTS==10+PTYTAB ;STATUS OF SUBJOB
PTYLCH==12+PTYTAB ;LAST CHAR SENT TO THIS SUBJOB
PTYLEN==13
.DNGCH==1 ;DING CHANNEL FROM TIMER INTERRUPT
LEVTAB: RETSAV ;PI LEVEL TABLE
0
0
CHNTAB: 0 ;0
1,,DING ;1
0 ;2
0 ;3
0 ;4
1,,TRAP ;5
TRPCHN==5
0 ;6
0 ;7
0 ;8
XWD 1,PANIC ;9 PDL OVERFLOW
0 ;10
XWD 1,PANIC ;11 - DATA ERROR
0 ;12
0 ;13
0 ;14
XWD 1,PANIC ;15 - ILLEGAL INSTRUCTION
XWD 1,PANIC ;16 - ILLEGAL MEM READ
XWD 1,PANIC ;17 - ILL MEM WRITE
XWD 1,PANIC ;18 - ILL MEM EXECUTE
0 ;19
XWD 1,PANIC ;20 - MACHINE SIZE EXCEEDED
0 ;21
0 ;22
0 ;23
DEFINE CHNBLD(A)<
XWD 1,PTYCH'A
XWD 1,PTYCH'A>
ZZ==0
REPEAT PTYNCH,<CHNBLD(\ZZ)
ZZ==ZZ+1>
ONCHNS: 1B<TRPCHN>+1B9+1B11+1B15+1B16+1B17+1B18+1B20+7777
LOGBUF: BLOCK 200 ;TEXT BUFFER FOR LOG COMMAND
GETBUF: BLOCK 200 ;BUFFER FOR GET COMMAND FILENAME
END <3,,ENTVEC>