Google
 

Trailing-Edge - PDP-10 Archives - cuspmar86binsrc_2of2_bb-fp63a-sb - 10,7/opser/opser.mac
There are 4 other files named opser.mac in the archive. Click here to see a list.
;
;-----------------------------------------------------------------------
;
TITLE	OPSER - OPERATOR SERVICE PROGRAM - %5E(133)

SUBTTL	FRANK NATOLI/DAL/PFC/DAL/JE/RHR/CDO/CGN/DC/MRB 22-AUG-85


	SEARCH	UUOSYM




;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1984,1985,1986. ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.


;
;-----------------------------------------------------------------------
;
	IFNDEF FTAUTO,<FTAUTO==-1>	;AUTO COMMAND FILE PROCESSOR
	IFNDEF FTTLOG,<FTTLOG==-1>	;LOG OF TELETYPE ACTIVITY
	IFE    FTTLOG,<DSKOUT==CPOPJ>	;MAKE NO-OP OF CALLS
	IFNDEF PDLSIZ,<PDLSIZ==40>	;SIZE OF PUSHDOWN LIST
	IFNDEF HGHPTY,<HGHPTY==14>	;NBR OF SUBJOBS MINUS ONE
	IFNDEF SNOOZT,<SNOOZT==1>	;ST SLEEP TIME WHEN WAITING
	IFNDEF MOSTBF,<MOSTBF==^D30>	;MOST CONSEC BUFFERS FROM PTY
	IFNDEF CHANCE,<CHANCE==3>	;SECS WILL WAIT FOR PTY TO WAKE
	IFNDEF TYPTIM,<TYPTIM==^D45>	;SECS REQUIRED TO TYPE LINE
	IFNDEF MAXCTC,<MAXCTC==4>	;MAX NBR ^C'S TO WAKE JOB
	IFNDEF LINSIZ,<LINSIZ==^D134>	;MAX CHARS/LINE
	IFNDEF DSKSIZ,<DSKSIZ==203>	;ST SIZE OF DISK BUFFER
	IFNDEF PTYSIZ,<PTYSIZ==23>	;ST SIZE OF TTY BUFFER
	NPTLTH==-<HGHPTY+1>
;
;-----------------------------------------------------------------------
;
;VERSION NUMBERS

	VWHO==:0		;WHO LAST EDITED THIS FILE
	VOPSER==:5		;OPSER VERSION NUMBER
	VMINOR==:5		;MINOR VERSION NUMBER
	VEDIT==:133		;EDIT NUMBER

	.JBVER==:137

	LOC	.JBVER	;JOB VERSION
	BYTE	(3)VWHO(9)VOPSER(6)VMINOR(18)VEDIT
	RELOC
;
;-----------------------------------------------------------------------
;
	TWOSEG				;RE-ENTRANT HISEG
	RELOC 400000			;START HISEG HERE
;
;-----------------------------------------------------------------------
;

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1986.  ALL RIGHTS RESERVED.
\;END COPYRIGHT MACRO 

SUBTTL	EDIT HISTORY
;27)	MAKE AUTO FILE PROCESSING MORE RELIABLE WHEN USING TIME
;	OF DAY AUTO FILES.
;30)	INCLUDE THE FILE NAME OF THE TIME OF DAY AUTO FILE IN THE
;	OUTPUT FROM :WHAT
;31)	ADD 2 NEW FLAVORS OF TIME OF DAY AUTO FILE. THESE ARE
;	/>HHMM = RUN AT HH+24:MM IF IT IS ALREADY PAST HH:MM
;	/<HHMM = IGNORE IF IT IS ALREADY PAST HH:MM
;	[SPR 10-8981]
;32)	RACE CONDITION IN AUTO FILE PROCESSING CAUSED STRANGE
;	RESULTS. [SPR 10-8047]
;33)	ALLOW OPSER TO READ AUTO FILES WITH SEQUENCE NUMBERS
;	[SPR 10-9072]
;34)	ADD ":SCHED", ":TIME" AND ":WHERE" TO COMMAND TABLE.
;	ALSO ADD ":RES" AS AN ABBREVIATION FOR ":RESOURCES" AND
;	":W", ":WH" AND ":WHA" AS ABBREVIATIONS FOR ":WHAT"
;	[SPR 10-9072]
;35)	CLEAN UP DAEMON LOGIC FOR BOTH KSYS AND AUTO FILES.
;	[SPR 10-9072]
;36)	CORRECT A PROBLEM IN PTY HANDLING WHICH CAUSED ":SLOG"
;	TO TYPE THE LOGIN MESSAGE ON A BUSY SYSTEM.
;	[SPR 10-9072]
;37)	ALLOW :TTYTST TO WORK IN AN AUTO FILE
;	[SPR 10-9072]
;40)	MODIFY OPSER SO THAT CONTROL-C DOES NOT CHANGE THE
;	DEFAULT SUBJOB.
;	[SPR 10-10314]
;41)	:SL 10/251 DOES NOT WORK. DIAGNOSIS: OPSER THINKS 'L'
;	IS A VALID MONITOR COMMAND. CURE: ADD SLO TO THE
;	COMMAND TABLE.
;	[10-10315]
;42)	CAN CONTROL-C OUT OF OPSER IF KSYS IS PENDING. CURE: ADD
;	A WARNING TO :EXIT THAT A
;	KSYS IS PENDING.
;	[SPR 10-10403]
;43)	FIX KSYS TO KILL ALL THE USERS IT SHOULD KILL AND NEVER
;	HARM ANYONE ELSE.
;	[SPR 10-10403]
;44)	IMPROVE EDIT 30
;45)	EDITS 31 AND 35 INTERACT BADLY. FIX SO THAT "%SUPER..."
;	IS ONLY PRINTED IF THIS AUTO REQUEST IS SUPERSEDING
;	A PREVIOUS REQUEST
;46)	EDIT NEVER MADE
;47)	FIX EDIT 42
;50)	CONFORM TO THE STANDARD MESSAGE FORMAT
;51)	ELIMINATES LOST MESSAGES FOR :KSYS COMMAND
;	(THIS ERROR OCCURED WITH CERTAIN :KSYS ARGUMENTS)
;	AREAS AFFECTED: SETK1    SPR#10-12208
;52)	MAKE OPSER HANDLE ":SLOG<SPACE><CR-LF>" CORRECTLY
;53)	IN LOGIN CMMD, MAKE OPSER RETURN TO COMMAND MODE WHEN THE TTY
;	IS IN INPUT WAIT AND NOT NECESSARILY IN MONITOR MODE IN
;	THE CASE THAT A PASSWORD IS REQUIRED
;54)	MAKE ERROR MESSAGES COME OUT TO THE OPERATOR EVEN IF IN AUTO FILES
;55)	ALLOW MORE THAN ONE DEV TO BE ENTERED ON :RESTRICT AND :UNRESTRICT
;	 SPR#11915
;	 AREAS AFFECTED:DEVRST,DEVURS
;56)	MORE OF EDIT 32, FIX FOR RACE CONDITION WAS AN OVER KILL
;	SPR#13046
;57)	PREVENT KSYS FROM HAPPENING FOR ANYBODY BUT 'OPR'
;60)	FIX HALT IN KSYS CAUSED BY EDIT 43
;61)	ADD TIME VALUE TO HIBER FOR PTY ROUTINE: DUMPT
;62)	MORE OF EDIT 60
;63)	OPSER 5A(63) SENT TO FIELD TEST SEPTEMBER 1974
;64)	FIXES GENERATED BY FIELD TEST QARS
;		GUARANTEE HIBER TIME FOR KSYS AT IOENDM
;		WRONG HIBER MASK AT DUMPT1
;		INCLUDE "%" FOR :ERROR
;		RESET :ERROR AT THE PROPER TIME
;		ADD BITS TO BE CLEAR ON REENTER
;		ONLY PRINT "NEXT AUTO FILE" ON A :WHAT ALL
;		TERMINATE WAIT FOR OPR TYPEIN IF ^U'ED OR RUBBED OUT
;		:HELP COULD "?ILL UUO", FIX IT
;		GIVE "TOO FEW ARGS" ON ":SET<CR>"
;		ALWAYS TYPED "SUPERSEDING PREVIOUS AUTO FILE", SAY IT ONLY IF TRUE
;65)	"SAVER" IS A SON-OF-DAEMON, DON'T KSYS IT
;66)	ADD ":MONITOR" FOR EMERGENCY EXITS, ":MONITO" MUST BE TYPED TO BE EFFECTIVE
;	THE ":" AFTER THE DEVICE NAME ON ":RESTRICT" AND ":UNRESTRICT" IS OPTIONAL
;	AT "EWORLD", CLEAR KSYS PENDING, KSYS IS OVER
;	ADD "/VD:D" ON KSYS STRING FOR KJOB, KJOB DEFAULTS TO "/VD:R"
;	CORRECT A TYPO IN THE OPRCKJ CODE AT RPTY
;67)	OPSER 5A(67) RELEASED TO THE FIELD JANUARY 1975
;70)	BECOME VERSION 5B
;71)	USE THE CORRECT KJOB STRING IF ON A GALAXY-10 SYSTEM
;72)	USE A TIMER WHEN WAITING FOR A SUBJOB DURING AUTO FILES
;	SEE EDITS 32 AND 56
;73)	OPSER 5B(73) RELEASED TO THE FIELD AUGUST 1975
;74)	BECOME VERSION 5C
;75)	IPTY DOESN'T QUITE DO THE RIGHT THING IF THE ONLY FREE PTY'S ARE
;	BEYOND 'PTY77' ( LARGE MONITOR )
;76)	DO SOME WORK ON "KSYS" CODE, DON'T KILL ANY [1,2]
;	JOBS THAT MAY BE AROUND.  THEY ARE PROBABLY USEFUL AND NEW ONES
;	KEEP GETTING ADDED.  6.03 ADDED "FILDAE" AND "MIC"
;77)	EDIT NOT MADE
;100)	FORCE ERROR OUTPUT FROM LOGIN EVEN IF :SLOG
;	[SPR 10-17930]
;101)	EDITS 41 & 52 RE-DONE
;	[SPR 10-17891]
;102)	EDIT NOT MADE
;103)	"M -TEXT" (NOTE BLANK) CONFUSED OPSER. THIS IS ACTUALLY INPUT
;	TO THE LAST SUBJOB USED SINCE IT IS CLEARLY NOT IN COMMAND FORMAT.
;	ALSO "0 -" AND "00 -" PRODUCED DIFFERENT RESULTS, FIX THAT TOO
;	[SPR 10-20369]
;104)	OPSER SUPRESSES LEADING SPACES ON TYPIN TO SUBJOB
;	[SPR 10-21399]
;105)	:KSYS<SP><CR> CAUSES KSYS TO BE SET TO MIDNIGHT, NO CANCELLED
;106)	OPSER WAS A LITTLE SLOW RECOVERING FROM CONTROL-C'S.
;	[SPR 10-25520]
;107)	OPSER LEFT SUBJOBS RUNNING LOGIN WHEN LOGIN FAILED.
;	[SPR 10-24809]
;110)	WHEN :LOGIN FAILS WITH NO FREE SUBJOBS, THE CURRENT SUBJOB
;	REMAINS SET TO THE LAST SUBJOB USED BEFORE THE FAILED :LOGIN.
;	[SPR 10-24596]
;111)	OVERFLOW OCCURS WHILE CONVERTING THE SYSTEM UP TIME TO
;	MILLISECONDS IF THE SYSTEM HAS BEEN UP FOR 160
;	CONSECUTIVE HOURS OR LONGER.
;	[SPR 10-27243]
;112)	IF AN .ATO FILE HAS SEQUENCE NUMBERS, THE SEQUENCE NUMBER
;	WILL BE THROWN AWAY BUT THE BYTE COUNT IN THE BUFFER HEADER
;	DOESN'T ADJUST CORRECTLY.
;	[SPR 10-27401]
;113)	AT KSYS TIME OPSER FAILS TO KILL ALL THE JOBS.
;	[SPR 10-26985]
;114)	EDIT 113 DETACHED AND KSYS'ED BATCH JOBS, DON'T DO THAT
;115)	FOR INITIA STARTED OPSER ON NETWORK LINES, USE "nnnlll".ATO INSTEAD
;	OF "TTYxxx".ATO BECAUSE LINE NUMBERS ARE DYNAMIC.
;116)	RESERVED FOR DEC.
;117)	GETTAB FOR UPTIME IS WRONG FOR SMP, USES CPU0 UPTIME, GET SYSTEM UPTIME
;	INSTEAD
;120)	RESERVED FOR DEC.
;121)	REMOVE EDIT 107 DONT KILL SUBJOBS THAT FAILED ON LOGIN.
;	REMOVE ASCII 175 176 FROM BREAKLIST SPR 10-29319
;	15-APR-81 MRB
;122)	CHANGE STTYIN TO SKIP OVER TAB'S ALSO (SPR 10-30882, MRB 15-APR-81)
;123)	PROBLEM WITH THE :AUTO COMMAND USING THE TIME SWITCH.
;	NEEDED A SPACE AFTER WORD :AUTO AND BEFORE THE SLASH.
;	29-MAY-81 MRB	SPR# 10-31102 @COMDEC+1,TIMEAF+2.
;124)	UUOSYMIZED OPSER (ADDED STANDARD UUOSYM NAMES TO OPSER)
;	15-JUN-81 MRB	NO SPR
;125)	MAKE OPSER SOURCE PRETTY (NO SPR)
;	RESEQUENCED DISPATCH TABLE. ADDED ---- TO SEGMENT ROUTINES
;126)	CHANGE TO LOOK AT CONFIG TABLE RATHER THAN PID OF QUASAR
;	FOR PTY LOGOUTS. 25-NOV-81, MRB, 10-31685
;127)	CORRECT EDIT 126. AFTER LOOKING AT CONFIG STATUS WORD
;	CHECK THE PROPER BIT. 12-JAN-82, MRB, 10-#####
;130)	ADD CODE FOR KSYS MESSAGE. BECOME VERSION 17E.
;131)	ADD CODE TO CONVERT CONTROL E TO AN ESCAPE 
;	BEFORE SENDING IT TO THE SUBJOB.
;132	None.	BAH	2-Oct-84
;	Update copyrights.
;133)	None.	LEO 	22-Aug-85
;	Do Copyrights.
;
;[END REVISION HISTORY]
;
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;
;ACCUMULATORS

	F=0		;PROGRAM STATUS BITS
	T1=1		;SCRATCH
	T2=T1+1
	T3=T2+1
	T4=T3+1
	T5=T4+1
	PT2=7		;BYTE POINTER FOR KSYS MESSAGE
	LASU=10		;LAST SUBJOB USED
	W=11		;SUPER TEMP
	MJOB=12		;LOADED WITH JOBSTS ON CALL TO "ISJOB"
	CMD=13		;INPUT WORD
	SJB=14		;SUBJOB REFERENCE
	PT1=15		;BYTE POINTER
	DATA=16		;ASCII CHARACTER REGISTER
	P=17		;PUSHDOWN POINTER
;
;-----------------------------------------------------------------------
;
;ASCII CHARACTERS

	CTRLA==1	;^A
	CTRLB==2	;^B
	CTRLC==3	;^C
	EOT==4		;EOT (^D)
	CTRLE==5	;^E
	BELL==7		;BELL (^G)
	TAB==11		;HORIZONTAL TAB (^I)
	LF==12		;LINE FEED (^J)
	VT==13		;VERTICAL TAB (^K)
	FF==14		;FORM FEED (^L)
	CR==15		;CARRIAGE RETURN (^M)
	CTRLO==17	;^O
	CTRLZ==32	;^Z
	ALT==33		;STANDARD ALTMODE
	SP==40		;SPACE
	DEL==177	;DELETE
;
;-----------------------------------------------------------------------
;
;CHANNEL ASSIGNMENTS

	DEFINE GETCHN(SYM)<
	SYM==ZZ
	ZZ==ZZ-1
>
	ZZ==17

IFN FTAUTO,<GETCHN (AUTOC)>	; AND/OR ONE FOR THE AUTO FILE
IFN FTTLOG,<GETCHN (LOGC)>	; AND/OR ONE FOR THE LOG FILE


	IFG HGHPTY-ZZ,<
PRINTX	NOT ENOUGH IO CHANNELS
PRINTX	REASSEMBLE WITH SMALLER VALUE OF "HGHPTY"
	PASS2
	END
>
;
;-----------------------------------------------------------------------
;
;SUBJOB STATUS BITS (STORED IN SJBFLG TABLE)

	SHH==1B0	;SILENCE PTY
			; MUST BE SIGN BIT
	DALSHH==1B1	;SILENCE TILL JLOG&JB.UDI COME ON
	ERONLY==1B2	;ONLY PRINT ERROR LINES
	TSIL==1B3	;PUT EVERYTHING INTO DISK LOG
;
;-----------------------------------------------------------------------
;
;FLAG BITS (LH)

	BRK==1B18	;LAST CHARACTER INPUTTED FROM CONSOLE WAS
			; A BREAK CHARACTER - INPUT LINE DONE
			; MUST BE SIGN BIT
	LCR==1B19	;LAST CHAR FROM PTY WAS A CARRIAGE RETURN
	HEADR==1B20	;SET IF A HEADER HAS PEEN PUT ON A MESSAGE
	MSG==1B21	;SET WHEN SENDING TEXT TO SUBJOBS
	CMD1==1B22	;TEST UNIQUENESS OF COMMAND
	AUXQ==1B23	;ANOTHER BIT MEANING QUIET
	REPL==1B24	;LEADING STAR OR EXCLAM TYPED
	PTBSY==1B25	;SOME IO ACTION ON LAST PASS TO IOCHK
	NOREP==1B26	;MONITOR LIED ABOUT PTY HAVING OUTPUT READY
	SBOD==1B27	;SOMEONE RUNNING A JOB
	QUIET==1B28	;DO NOT SEND DATA TO TTY
	FREETB==1B29	;A FREE TAB WAS TYPED BY TABOUT
	WASCOM==CMD1	;LAST CALL TO SUBROUTINE WHATJB WAS TERMINATED
			; BY A COMMA, INDICATING THERE ARE MORE
			; REFERENCES LEFT
	SLEEPR==1B30	;FORCE SLEEP NOT HIBER
	MSH==1B31	;SET WITH MSGLEVEL
	CCLST==1B32	;CCL START
	TIMO1==1B33	;SOMEONE SITTING ON CONSOLE
;
;-----------------------------------------------------------------------
;
IFN FTAUTO,<AUTOM==1B34>	;AUTO MODE IN EFFECT
IFE FTAUTO,<AUTOM==0>		;ZERO IF AUTO CODE NOT ASSEMBLED
IFN FTTLOG,<OFILE==1B35>	;LOG FILE OPENED
IFE FTTLOG,<OFILE==0>		;ZERO IF LOG CODE NOT ASSEMBLED

	RENBIT==777777-OFILE-MSH
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	PROGRAM STARTUP
;
;-----------------------------------------------------------------------
;

REEN:	TLZ	F,RENBIT		;ZERO VARIOUS BITS
	JRST	SETUP			;AND REJOIN REGULAR CODE

OPSER:	TDZA	F,F			;ZERO & SKIP
	MOVSI	F,CCLST			;LOAD CCLST,,0

	RESET				;RESET THE WORLD
	SETZB	LASU,LOWBEG		;ZERO FIRST LOC OF STORAGE 
	MOVE	T1,[LOWBEG,,LOWBEG+1]	;LOAD BLT XWD
	BLT	T1,LOWEND		;BLT ZEROES TO END
	GETPPN	T1,			;GET OUT PPN
	  JFCL				;SILLY SKIP
	MOVEM	T1,MYPPN		;SAVE FOR LATER USES
	MOVE	T1,[%LDFFA]		;FIND OUT OPR PPN
	GETTAB	T1,			;GET IT
	  MOVE	T1,[1,,2]		;STANDARD DEFAULT
	MOVEM	T1,OPRPPN

	SETZ	T1,			;START WITH ZERO
	MOVE	T2,[%CNPTY]		;GET PTYOFS
	GETTAB	T2,			; FROM THE MONITOR
	  JRST	LOOP50			;DON'T KNOW
	HLRZ	T1,T2			;COPY INDEX
	MOVEM	T1,PTY0LN		;STORE PTYOFS
	SOJA	T1,END50		;STORE TCONLN
LOOP50:	GETLCH	T1			;GET CHARACTERISTICS
	TLNE	T1,(1B1)		;SKIP IF NOT CTY
	JRST	END50			;DONE
	MOVEI	T1,1(T1)		;INCR COUNT
	JRST	LOOP50			;KEEP GOING
END50:	HRRZM	T1,TCONLN		;STORE

	MOVEI	T1,REEN			;LOAD RE-ENTRY ADDRESS
	MOVEM	T1,.JBREN		;STORE IN .JBDATA
	MOVEI	T1,WARNTB		;GET INITIAL KSYS POINTER
	MOVEM	T1,WARNTM		;STORE FOR LATER
	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP PDL
	PUSHJ	P,CHKOPR		;MAKE SURE ITS "OPR"
	 JRST	SETUP			;SKIP KSYS
	MOVE	T1,[%NSKTM]		; GET THE TIME TO
	GETTAB	T1,			; :KSYS
	  SETZM	T1			;ZERO IF NONE
	JUMPLE	T1,SETUP		;JUMP IF :KSYS NOT SET
	MOVEM	T1,KSYNC		;STORE VALUE FOR TESTING
	PUSHJ	P,WARN			;WARN THE WORLD
SETUP:	TLO	F,BRK			;LAST CHAR A BREAK
	MOVE	P,[IOWD PDLSIZ,PDL]	;MAKE PUSHDOWN POINTER
	PUSHJ	P,JIFINI		;COMPUTE JIFFIES PER SECOND
	PUSHJ	P,INTINI		;SET UP FOR CONTROL C INTERCEPT
	SETO	T1,			;PUT -1 IN T1
	WAKE	T1,			;WAKE MYSELF
	  JFCL				;DON'T REALLY CARE
	MOVSI	T1,(HB.RIO!HB.RPT!HB.RTL)	;LOAD STANDARD HIBERNATE CODE
	HIBER	T1,			;STICK IN MONITOR
	  JFCL

	IFN	FTAUTO,<
	TLZN	F,CCLST			;SKIP IF CCL START
	JRST	MAIN			;NOT
	MOVEI	PT1,PACF		;POINT TO AUTO MESSAGES
	PUSHJ	P,MOUT			;STICK IN OUTPUT BUFFER
	MOVSI	T1,'SYS'		;LOAD INPUT DEVICE
	GETLIN	T2,			;LOAD TTY NAME
	MOVE	T3,[%CNOPR]		;GET THE NAME OF OPR
	GETTAB	T3,			; FROM THE MONITOR
	  JRST	LOCAL			;SHOULD NEVER HAPPEN
	CAMN	T2,T3			;ARE WE DEVOPR?
	MOVSI	T2,'OPR'		;YES--USE OPR.ATO
	MOVE	T3,T2			;COPY TTY NAME
	WHERE	T3,			;GET OUR STATION NUMBER
	  JRST	LOCAL			;DO NOT KNOW
	MOVE	T4,[SIXBIT /OPR0/]	;GET THE STATION NUMBER
	WHERE	T4,			; OF THE CENTRAL SITE
	  JRST	LOCAL			;ONLY REMOTE STATIONS
	CAMN	T3,T4			;ARE WE AT LOCAL STATION?
	JRST	LOCAL			;YES--USE OPR OR TTY
	LSHC	T3,-6			;SHIFT I OCTIT INTO T4
	LSH	T3,3			;SHIFT IN 3 ZEROS
	LSHC	T3,3			;GENERATE SIXBIT
	LSH	T3,3
	LSHC	T3,3
	ADDI	T3,202020		; ..
	TRNN	T3,570000		;TRIM OFF LEADING ZEROS
	LSH	T3,6
	TRNN	T3,570000		;LEADING ZERO
	LSH	T3,6			;YES--TRIM IT OFF
	HRLI	T3,'OPR'		;PREFIX WITH OPR
	MOVE	T4,T3			;COPY NAME OF OPR
	DEVNAM	T4,			;GET NAME OF OPR'S TTY
	  JRST	LOCAL			;SO CLOSE
	CAMN	T2,T4			;ARE WE OPRNN?
	JRST	[MOVE T2,T3		;YES, USE OPRNN NOT TTY115
		JRST LOCAL]		;AND GO FIND THE ATO FILE
	MOVE	T3,T2			;COPY "TTYXXX"
	GTNTN.	T3,			;CONVERT TO NODE AND LINE NUMBERS
	  JRST	LOCAL			;WHOOPS
	MOVEI	T4,2			;DO THIS TWICE
	ROT	T3,^D9			;GET RID OF HIGH BITS
	MOVEI	T5,3			;DO THIS THRICE
	LSH	T2,3			;MAKE SOME ROOM
	LSHC	T2,3			;BRING IN A DIGIT
	SOJG	T5,.-2			;FOR THREE DIGITS
	SOJG	T4,.-5			;FOR BOTH HALVES
	TDO	T2,[SIXBIT/000000/]	;MAKE SIXBIT OUT OF IT
LOCAL:	MOVSI	T3,'ATO'		;LOAD EXTENSION
	SETZ	T4,			;NO PPN
	PUSHJ	P,FAUTO			;SETUP AUTO FILE
>
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	GENERAL PROGRAM LOOP
;
;-----------------------------------------------------------------------
;

MAIN:	TLO	F,BRK			;SET BIT(S) TO START
	TLZ	F,QUIET!MSG!AUXQ	;CLEAR BIT(S) TO START
	SKPINL				;CLEAR ^O
	  JFCL				;DON'T CARE - JUST DO INPUT
	PUSHJ	P,STARTL		;START THE LINE

	IFN	FTAUTO,<
	TLNN	F,AUTOM			;SKIP IF IN AUTO MODE
	JRST	NO2			;NOT
	PUSHJ	P,IOCHK			;CHECK PTY'S
	TLNE	F,PTBSY			;TEST FOR PTY ACTIVITY
	JRST	MAIN			;YES--LOOP AGAIN
	PUSHJ	P,STARTL		;MAY NEED NEW * OR !
	JRST	TTWAIT			;GO PROCESS COMMAND
>
NO2:	SKPINC				;SKIP IF A CHAR IS AVAILABLE
	  JRST	IOENDM			;NONE - GO SCAN PTY'S
	SKPINL				;SKIP IF ENTIRE LINE TYPED
	  SKIPA				;SKIP
	JRST	TTWAIT			;THERE IS - GO READ IT
	TLOE	F,TIMO1			;SET CHECK BIT & SKIP IF ZERO
	JRST	IOENDM			;TWICE ON - DON'T COUNTDOWN
	MOVEI	T1,TYPTIM		;WAIT N SECONDS TO FINISH LINE
TIMOLA:	MOVEI	T2,1			;LOAD 1
	SLEEP	T2,			;SLEEP FOR A WHILE
	SKPINC				;SOMETHING STILL THERE
	  JRST	[PUSHJ P,CRLF		;ALIGN THE OUTPUT
		TLZ F,REPL!TIMO1	;CLEAR * OR ! GIVEN, TRY TIMOUT AGAIN
		JRST MAIN]		;AND START AGAIN
	SKPINL				;SKIP IF HE FINISHED THE LINE
	  SKIPA				;NO HE DIDN'T
	JRST	TTWAIT			;DONE - GO DIGEST
	SOJG	T1,TIMOLA		;COUNTDOWN
IOENDM:	PUSHJ	P,IOCHK			;GO CHECK PTY'S
	TLNE	F,PTBSY			;SKIP IF NO PTY ACTION
	JRST	MAIN			;SOME - GO LOOP
	MOVSI	T1,(HB.RIO!HB.RPT!HB.RTL)	;LOAD STANDARD HIBERNATE BITS
	SKIPN	KSYNC			;SKIP IF KSYS IS PENDING
	SKIPE	ATOTIM			;SKIP IF NO AUTO FILE PENDING
	HRRI	T1,^D50000		;SET UP HIBER TIME FOR AUTO FILE AND/OR KSYS
	MOVEI	T2,SNOOZT		; AND ST SLEEP TIME
	TLNN	F,SLEEPR		;SLEEP? 
	HIBER	T1,			;HIBERNATE
	  SLEEP	T2,			;GO TO SLEEP....
	PUSH	P,LASU			;SAVE THE DEFAULTS
	PUSH	P,SJB			; ..
	MOVE	T1,[%NSKTM]	;GET TIME TO KSYS
	SKIPE	KSYNC			;SKIP IF NO KSYS COMMAND
	GETTAB	T1,			; FROM THE MONITOR
	  SETZ	T1,			;NO GETTAB - LEAVE SYS ALONE
	JUMPE	T1,.+3			;DO NOT WARN IF COUNTER IS 0
	CAMG	T1,@WARNTM		;TIME TO GIVE A WARNING?
	PUSHJ	P,WARN			;YES--GIVE THE WARNING
	IFN	FTAUTO,<
	SKIPN	ATOTIM			;ANY DEFERED FILES
	JRST	MPOP			;NO--LOOP BACK FOR MORE
	PUSHJ	P,GETUPT		;GET UPTIME IN MS.
	CAMGE	T1,ATOTIM		;TIME TO RUN AN AUTO FILE?
	JRST	MPOP			;NO--LOOK FOR WORK
	TLNE	F,AUTOM			;SEE IF AUTO FILE GOING
	JRST	AUTBSY			;YES--DELAY
	MOVEI	PT1,PACF		;SAY AUOT FILE
	PUSHJ	P,MOUT			; SO OPR WILL KNOW
	MOVE	T5,[ATOT1,,T1]		;SET UP BLT POINTER
	BLT	T5,T5			;LOAD THE ACS
	SETZM	ATOTIM			;PREVENT A LOOP
	PUSHJ	P,FAUTO			;GIVE A FORCED AUTO
	PUSHJ	P,SETDA0		;PUT NEXT ENTRY IN CLOCK
	JRST	MPOP			;LOOP FOR MORE
;HERE IF TIME OF DAY AUTO FILE WANTS TO HAPPEN WHILE PROCESSING
; ANOTHER AUTO FILE.
AUTBSY:	MOVEI	CMD,^D30*^D1000	;SET A DELAY OF 30
	PUSHJ	P,SETDAE		; SECONDS AND RETRY
>
MPOP:	POP	P,SJB			;RESTORE DEFAULTS
	POP	P,LASU			; ..
	JRST	MAIN			;BACK TO WORK
	JRST	MAIN			;BACK TO WORK
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	COMMAND SCANNER
;
;-----------------------------------------------------------------------
;

TTWAIT:	TLZ	F,TIMO1			;ACKNOWLEDGE RECEPTION
	PUSHJ	P,STTYIN		;GET FIRST CHAR OF LINE
	JUMPL	F,MAIN			;JUST <CR>
	CAIN	DATA,";"		;SKIP IF NOT COMMENT
	JRST	MAIN			;IGNORE LINE
	CAIE	DATA,":"		;SKIP IF COMMAND TO ME
	JRST	NOTME			;NOT - JUMP AROUND
	PUSHJ	P,COMDEC		;GO INTERPRET
	  JRST	MAIN			;RECYCLE
	JRST	MAIN			;SAME

NOTME:	CAIN	DATA,"-"		;SKIP IF NOT DASH
	JRST	DEFAU1			;IT IS - GIVE DEFAULT
	CAIN	DATA,"#"		;IS THIS A MONITOR JOB
	JRST	MONJOB			;YES--SEE WHICH ONE

	PUSH	P,DATA			;SAVE FIRST CHAR
	PUSHJ	P,SIXIN			;GET FIRST SIXBIT WORD
	PUSHJ	P,RESCA1		; AND DO A RESCAN
	CAIE	DATA,"-"		;SKIP IF A DASH
	JRST	DEFAU2			;NOT DASH - SEND ENTIRE LINE
	POP	P,DATA			;RESTORE CHARACTER
	CAIN	DATA,"B"		;SKIP IF NOT ASCII B
	PUSHJ	P,CHKBAT		;GO SEE IF BATCON LIVES
	  JRST	NOT2			;SKIP CODE
	PUSH	P,DATA			;SAVE CHARACTER
	PUSHJ	P,STTYIN		;GET FIRST "B"
	PUSHJ	P,DECIN			;SEE IF DEC NBR FOLLOWING
	CAIN	DATA,"-"		;SKIP IF NOT
	JRST	HAVNBR			;WAS IN BN- FORMAT
	PUSHJ	P,RESCA1		;RESCAN
	PUSHJ	P,STTYIN		;SWALLOW THE "B"
	PUSHJ	P,SIXIN			;GET SIXBIT WORD
	MOVS	CMD,CMD			;SWAP HALVES
	CAIE	CMD,'ALL'		;SKIP IF "ALL" MNEMONIC
	CAIN	CMD,'AL '		; OR THIS CONTRACTION OF
	JRST	HAVNBR			;GOT IT
	CAIE	CMD,'A  '		;LAST POSSIBLE
	JRST	SOMELS			;WILD GOOSE CHASE
HAVNBR:	PUSHJ	P,RESCA1		;DO RESCAN
	POP	P,DATA			;CLEAR PDL
	HRRZ	LASU,SJB		;UPDATE LASU
	JRST	GOTNBR			;AND GO SEND LINE

SOMELS:	PUSHJ	P,RESCA1		;DO RESCAN
	POP	P,DATA			;CLEAR STACK & FALL THROUGH
NOT2:	CAIG	DATA,"9"		;SKIP IF NON-NUMERIC
	CAIGE	DATA,"0"		;SKIP IF NUMERIC
	JRST	ALPHA1			;BETTER BE ALPHABETIC
	PUSHJ	P,DECIN			;INPUT A DECIMAL NUMBER
	CAIE	DATA,"-"		;SKIP IF DASH IS DELIMITER
	JRST	MONJ.1			;NO DASH
	PUSHJ	P,SJBLIM		;CHECK LIMITS
	  JRST	MAIN			;BAD NUMBER - RESTART
	JRST	GOTNBR			;GO TO TRANSFER CODE

ALPHA1:	PUSHJ	P,SIXIN			;GET INPUT WORD
	CAIE	DATA,"-"		;DELIMITED BY A DASH
	JRST	MONJ.1			;NOPE, IS NOT A SUBJOB SPEC
	PUSHJ	P,FINMNE		;GO FIND MNEMONIC
	  JRST	MAIN			;RECYCLE ON ERROR
	JRST	GOTNBR			;GO PROCESS TEXT

MONJOB:	PUSHJ	P,DECIN			;GET THE NUMBER
	CAIN	DATA,"-"		;DELIMITED BY -
	JRST	FNDSJB			;YES--SET UP SJB.
MONJ.1:	PUSHJ	P,RESCA1		;NO--SEND AS TEXT
	JRST	DEFAU1			; TO LAST SUBJOB

FNDSJB:	SETO	T2,			;FLAG
	MOVEI	SJB,1B18		;ALL SUBJOBS
	PUSH	P,[LOOKMJ]		;SUBROUTINE
	PUSHJ	P,RUNSUB		;RUN ONCE FOR EACH SUBJOB
	JUMPL	T2,ERR1			;DO I KNOW HIM
	MOVE	SJB,T2			;YES--LOAD SJB
	JRST	SKIP1			;SEND THE LINE(S)

LOOKMJ:	PUSHJ	P,UJBSTS		;GET THE STATUS
	CAIN	CMD,(T1)		;SAME JOB NUMBER
	HRRZ	T2,SJB			;YES--COPY SUBJOB NUMBER
	POPJ	P,			;RETURN

DEFAU2:	POP	P,DATA			;RESTORE DATA
DEFAU1:	HRRZ	SJB,LASU		;LOAD WITH LAST REF
	CAIE	SJB,1000		;IS NO CUR SUBJOB FLAG SET?
	JRST GOTNBR			;NO
	PUSHJ	P,NOCUR			;YES,; GO MAKE AN ERROR MESSAGE
	JRST MAIN			; AND RETURN
;
;-----------------------------------------------------------------------
;
SUBTTL	SENDING TEXT TO SUBJOBS
;
;-----------------------------------------------------------------------
;

GOTNBR:	TRNN	SJB,1B18		;SKIP IF "ALL" USED
	JRST	JUST1			;SINGLE REFERENCE
	PUSHJ	P,CHKBAT		;SEE IF BATCON LIVES
	  JRST	SKIP1A			;DOESN'T - SKIP CODE
	MOVEI	PT1,[ASCIZ/ALL-/]	;SEND ALL- TO BATCON
	PUSHJ	P,PTMOUT		;SEND STRING
SKIP1A:	MOVNI	SJB,1			;RESTORE SJB
	JRST	SKIP1			;AND SKIP THIS CODE

JUST1:	TDNE	F,USE(SJB)		;SKIP IF SUBJOB FREE
	JRST	SKIP1			;INIT'ED - SKIP CODE
	PUSHJ	P,IPTY			;INITIALIZE A PTY
	  JRST	MAIN			;NO MORE PTY'S

SKIP1:	TLO	F,MSG			;DO NOT FORMAT INPUT LINE
	PUSHJ	P,TTYIN			;GET NEXT CHAR
	CAIN	DATA,"-"		;DOUBLE DASH? 
	JRST	MULN			;YES

TLOOP1:	PUSH	P,[PTYOUT]		;LOAD ADDR OF SUBROUTINE
	PUSHJ	P,RUNSUB		;GO EXEC IT
	JUMPL	F,FINONE		;EOL - FINISHED
	PUSHJ	P,TTYIN			;GET NEXT CHAR
	JRST	TLOOP1			;CIRCLE

MULN:	PUSHJ	P,STTYIN		;GET NEXT CHAR ON LINE
	JUMPL	F,ERR1			;NOT A BREAK CHAR, PLS
	PUSH	P,DATA			;SAVE ON PDL
TLOOP2:	PUSHJ	P,TTYIN			;GET NEXT CHAR
	CAMN	DATA,(P)		;MATCH?
	JRST	END2			;YES - EXIT FROM LOOP
	PUSH	P,[PTYOUT]		;PUSH ADDR OF ROUTINE
	PUSHJ	P,RUNSUB		;GO EXEC IT
	JRST	TLOOP2			;CIRCLE

END2:	POP	P,(P)			;RESTORE PDL
FINONE:	PUSH	P,[DUMPT]		;PUT ADDR ON STACK
	PUSHJ	P,RUNSUB		;GO EXEC IT
	JRST	MAIN			;CIRCLE

ERR1:	PUSHJ	P,CMDERR		;GO TYPE ERROR MESSAGE
	JRST	MAIN			;AND RESTART
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	COMMAND DECODER AND DISPATCHER
;
;-----------------------------------------------------------------------
;

COMDEC:	PUSHJ	P,SIXIN			;GO GET INPUT WORD
YES4:	TLZ	F,CMD1			;ZERO THIS BIT TO START
	MOVE	T1,CMD			;LOAD INPUT WORD
	SETO	T2,			;FILL WITH ONES
LOOP4:	LSH	T2,-6			;SHIFT RIGHT 6
	LSH	T1,6			;SHIFT LEFT 6
	JUMPN	T1,LOOP4		;JUMP IF MORE
	MOVSI	T1,-LSTSIZ		;MAKE AOBJN XWD
LOOP4A:	CAMN	CMD,COMLST(T1)		;SKIP IF NO MATCH
	JRST	FOUND			;PERFECT MATCH!
	MOVE	T3,COMLST(T1)		;LOAD IT UP
	TDZ	T3,T2			;MASK OUT UNUSED BITS
	CAME	CMD,T3			;SKIP IF IT NOW MATCHES
	JRST	NO4			;NOPE
	TLOE	F,CMD1			;SET AND SKIP IF FIRST TIME
	JRST	DUPLIC			;DUPLICATE COMMAND
	HRRZ	T4,T1			;REMEMBER INDEX HERE
NO4:	AOBJN	T1,LOOP4A		;SEARCH THROUGH TABLE
	TLNN	F,CMD1			;SKIP IF SOME MATCH
	JRST	CMDERR			;TYPE ERROR MESSAGE
	MOVE	T1,T4			;LOAD UP INDEX
FOUND:	TLZ	T1,-1			;ZERO LH
	ROT	T1,-1			;DIVIDE BY 2 AND SAVE REMAINDER
	MOVE	T2,DSPTBL(T1)		;LOAD XWD DISPATCH ADDR
	JUMPL	T1,(T2)			;GO DISPATCH
	MOVS	T2,T2			;SWAP HALVES
	JRST	(T2)			;GO EXEC

PANIC:	CAMN	CMD,[SIXBIT/MONITO/]	; ":MONITO" MUST BE TYPED COMPLETELY
	  JRST	PANIC1			;IT WAS, DO EMERGENCY EXIT
DUPLIC:	JSP	PT1,MOUT
	ASCIZ	/?OPRCNU Command not unique
/

;-----------------------------------------------------------------------
;	Command Dispatch Table (alphabeticaly)
;-----------------------------------------------------------------------
;
	DEFINE	NAMES<

	IFN FTAUTO,<
	X AUTO,AUTO		;AUTO FILE COMMAND
>
	IFN FTTLOG,<
	X CLOSE,CLOSED		;CLOSE LOG FILE
>
	IFN FTAUTO,<
	X CONTINUE,CONT		;CONTINUE AUTO FILE
>
	X CURRENT,CURS		;TYPE CURRENT SUBJOB
	X DAYTIME,RESCO1	;DAYTIME COMMAND
	X DEFINE,SJNAM		;DEFINE MNEMONICS
	X DEVICE,DEVREQ		;GET A DEVICE
	X ERROR,SETERR		;ONLY ERROR LINES
	X EXIT,FINISH		;EXIT TO MONITOR
	X FREE,FREENO		;NEXT FREE SUBJOB
	X HELP,HELP		;BRIEF EXPLANATION OF OPSER
	X JCONT,RESCO1		;5S03 FORCED CONTINUE
	X K,KILL		;LOGOUT SUBJOB
	X KILL,KILL		;LOGOUT SUBJOB
	X KJOB,KILL		;SAME AS KILL
	X KSYS,KSYS		;STOP THE SYSTEM
	X LOGIN,LOGIN		;RUN LOGIN
	X MONITO,PANIC		;PANIC EXIT
	X MSGLVL,SETLEV		;SET MESSAGE LENGTH
	X QUEUE,RESCO1		;RUN QUEUE CUSP
	X RES,RESCO1		;ABBREV. FOR RESOURCES
	X RESOURCES,RESCO1	;TYPE SYSTEM RESOURCES
	X RESTRICT,DEVRST	;RESTRICT DEVICE
	X REVIVE,PTON		;LISTEN TO IT AGAIN
	X SCHED,RESCO1		;SCHED COMMAND
	X SEND,RESCO1		;SEND TTY COMMAND
	X SET,SETCMD		;SET COMMAND
	X SILENCE,PTOFF		;SILENCE PTY SUBJOB
	X SLOGIN,SLOGIN		;SILENT LOGIN (SETS DALSHH BIT)
	X STOP,SETMON		;PUT IN MONITOR MODE
	X SYSTAT,RESCO1		;RUN SYSTAT CUSP
	X TIME,RESCO1		;TIME COMMAND

	IFN FTTLOG,<
	X TLOG,TLOG		;ENTER LOG FILE
>
	X TSILENCE,TPTOFF	;SAME AS SILENCE BUT LEAVE LOG ON
	X TTYTST,TTYTST		;TEST OUT CONSOLE
	X UNRESTRICT,DEVURS	;UNRESTRICT DEVICE
	X W,WHAT		;WHAT COMMAND (ABBREVIATION)
	X WH,WHAT
	X WHAT,WHAT		;WHAT COMMAND
	X WHERE,RESCO1		;WHERE COMMAND
>

DEFINE	SNAMES<
	X RUN,SETRN		;'SET RUN CPUN'
	X LOGMAX,SETLOG		;'SET LOGMAX N'
	X BATMAX,SETBMX		;'SET BATMAX N'
	X BATMIN,SETBMN		;'SET BATMIN N'
	>
	DEFINE X(A,B)<
	<SIXBIT/A/>
>

COMLST:	NAMES

	LSTSIZ==.-COMLST	;HOW MANY COMMANDS THERE ARE

SETLST:	SNAMES

	SETSIZ==.-SETLST
;XWD DISPATCH TABLE MACRO

	DEFINE	X(A,B)<
	IFE	ZZ&1,<
	DEFINE	XX(C)<
	XWD	B,C
>>
	IFN	ZZ&1,<
	XX	B
>
	ZZ==ZZ+1
>
	ZZ==0

DSPTBL:	NAMES

	IFN	ZZ&1,<XX 0>

	ZZ==0

SETDSP:	SNAMES

	IFN	ZZ&1,<XX 0>
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:FREE - :TTYTST
;
;-----------------------------------------------------------------------
;

FREENO:	PUSHJ	P,FSUB			;GET NBR OF FIRST FREE SUB
	  POPJ	P,			;THERE WEREN'T ANY
	MOVEI	PT1,[ASCIZ/First free = /]
	PUSHJ	P,MOUT			;TYPE MESSAGE
	HRRZ	T1,SJB			;LOAD NBR
	PUSHJ	P,DECOUT		;TYPE IN DECIMAL
	JRST	CRLF			;END WITH RETURN



TTYTST:	PUSHJ	P,LOUD			;TURN ON TTY
	MOVEI	DATA,40			;START WITH OCTAL 40
	PUSHJ	P,TTYOUT		;TYPE CHAR
	CAIGE	DATA,77			;TYPE UP TO 77
	AOJA	DATA,.-2		;KEEP GOING
	PUSHJ	P,CRLF
	MOVEI	DATA,100		;NOW START WITH OCTAL 100
	PUSHJ	P,TTYOUT		;TYPE CHAR
	CAIGE	DATA,137		;GO UP TO OCTAL 137
	AOJA	DATA,.-2
	PUSHJ	P,CRLF
	MOVEI	DATA,140		;NOW START WITH 140
	PUSHJ	P,TTYOUT		;TYPE THAT
	CAIGE	DATA,174		;GO UP TO 174
	AOJA	DATA,.-2
	MOVEI	PT1,[BYTE(7)BELL,CR,LF]	;ASCIZ STRING
	JRST	MOUT			;TYPE ON CONSOLE
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:CURRENT - :MSGLEVEL
;
;-----------------------------------------------------------------------
;

CURS:	PUSHJ	P,LOUD			;TURN TTY BACK ON
	HRRZ	SJB,LASU
	CAIN	SJB,1000		;IS NO CUR SUBJOB FLAG SET?
	JRST	NOCUR			;YES, DO AN ERROR
	MOVEI	PT1,[ASCIZ/Current subjob = /]
	PUSHJ	P,MOUT
	HRRZ	SJB,LASU
	PUSHJ	P,PUTNAM
	JRST	CRLF



SETLEV:	JUMPL	F,TOOFEW		;MUST HAVE ARGUMENT
	PUSHJ	P,DECIN			;GET A NUMBER
	JUMPGE	F,CMDERR		;NO MORE PLEASE
	JUMPE	CMD,SETOK0		;ZERO IS ONE POSSIBILITY
	CAIE	CMD,1			;ONE IS THHE OTHER
	JRST	CMDERR			;TELL HIM THAT
	TLZA	F,MSH			;SHORT MESSAGES
SETOK0:	TLO	F,MSH			;LONG ONES
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:SILENCE - :REVIVE - :STOP - :KILL - :ERROR - :TSILENCE
;
;-----------------------------------------------------------------------
;

PTOFF:	PUSH	P,[PTSETB]		;PUSH ADDR OF ROUTINE
	PUSHJ	P,RUNSA			;GO EXEC
	POPJ	P,			;RETURN

PTSETB:	MOVSI	T1,(SHH)		;LOAD SILENCE BIT
	IORM	T1,SJBFLG(SJB)		;OR BIT IN
	POPJ	P,			;AND RETURN



PTON:	PUSH	P,[PTCLRB]		;PUSH ADDR OF ROUTINE
	PUSHJ	P,RUNSA			;GO EXEC
	POPJ	P,			;RETURN

PTCLRB:	MOVSI	T1,(SHH!ERONLY!TSIL)	;LOAD SILENCE BIT
	ANDCAM	T1,SJBFLG(SJB)		;CLEAR BIT FROM TABLE
	POPJ	P,			;AND RETURN



SETMON:	PUSH	P,[STOPJB]		;PUSH ADDR OF SUBR
	PUSHJ	P,RUNSA			;EXECUTE
	POPJ	P,			;RETURN



KILL:	PUSH	P,[RPTY]		;LOAD SUBR ADDR
	PUSHJ	P,RUNSA			;EXEC
	POPJ	P,



SETERR:	PUSH	P,[ERSET]		;PUSH ADDRESS OF SUBROUTINE
	PUSHJ	P,RUNSA			;RUN SUB FOR EACH ARG
	POPJ	P,			;RETURN

ERSET:	MOVSI	T1,(ERONLY)		;SAMBERG BIT
	IORM	T1,SJBFLG(SJB)		;TUNR IT ON
	POPJ	P,			;RETURN

TPTOFF:	PUSH	P,[PTSET2]
	PUSHJ	P,RUNSA
	POPJ	P,

PTSET2:	MOVSI	T1,(TSIL!SHH)
	IORM	T1,SJBFLG(SJB)
	POPJ	P,
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:SLOGIN & :LOGIN
;
;-----------------------------------------------------------------------
;

LOGIN:	TDZA	T1,T1			;NO FLAGS TO SET
SLOGIN:	MOVSI	T1,(DALSHH)		;LOAD SPECIAL SILENCE BIT
	PUSH	P,T1			;SAVE THE BIT
	PUSHJ	P,FSUB			;GO FIND A FREE SUBJOB
	 JRST	XPOPJ			;NONE AVAILABLE
	PUSHJ	P,IPTY			;NOW GET A FREE PTY
	 JRST	XPOPJ			;NONE THERE
	POP	P,T1			;RESTORE SLOG FLAG
	IORM	T1,SJBFLG(SJB)		;IOR INTO SUBJOB STATUS FLAGS
	JUMPL	F,LOGIN3		;END OF LINE, FALL INTO LOGIN
	PUSHJ	P,STTYIN		;GET THE NEXT CHARACTER
	JUMPL	F,LOGIN3		;END OF LINE, FALL INTO LOGIN
	PUSH	P,DATA			;SAVE FIRST CHARACTER OF PPN
	MOVEI	PT1,[ASCIZ/LOGIN /]	;GET LOGIN STRING
	PUSHJ	P,PTMOUT		;OUTPUT IT
	POP	P,DATA			;RESTORE THE CHARACTER
	PUSHJ	P,SLOOP2		;PPN REALLY THERE, SEND IT
	 JFCL				; RANDOM LOSSAGE
	JRST	LOGIN5			;WAIT, CHECK FOR END OF LOGIN

LOGIN3:	MOVEI	PT1,[ASCIZ/LOGIN /]	;LOAD ADDR OF STRING
	PUSHJ	P,PTMOUT		;SEND TO SUBJOB
	HLRZ	T1,MYPPN		;PUT PROJECT INTO RH OF T1
	PUSHJ	P,PTOCT			;TYPE AT SUBJOB
	MOVEI	DATA,"/"		;LOAD A SLASH
	PUSHJ	P,PTYOUT		;SEND CHAR
	HRRZ	T1,MYPPN		;LOAD PROGRAMMER NUMBER
	PUSHJ	P,PTOCT			;TYPE THAT
	MOVEI	DATA,CR			;LOAD RETURN
	PUSHJ	P,PTYOUT		;SEND THAT
	MOVEI	DATA,LF			;FINALLY A LINE FEED
	PUSHJ	P,PTYOUT		;BREAK CHAR FOR LINE

LOGIN5:	PUSHJ	P,LOOP10		;WAIT FOR END OF LOGIN
	MOVEI	PT1,[ASCIZ/?OPRJNL JOB DID NOT GET LOGGED IN
/]
	TDNE	F,USE(SJB)		;DID WE GIVE BACK THE PTY
	 TLNE	T1,(JB.ULI)		;NO, IS JOB LOGGED IN ( BIT FLIPPED)
	  JRST	MOUT			;DIDN'T MAKE IT FOR SOME REASON.
	POPJ	P,			;RETURN, JOB IS ALIVE AND WELL

PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:SYSTAT - :RESOURCES - :QUEUE - :SEND - :JCONT
;
;-----------------------------------------------------------------------
;

RESCO1:	PUSHJ	P,RESCOM		;DO RESCOM LIKE COMMAND
	  POPJ	P,			;NO BANANAS
LOOP10:	PUSHJ	P,GBUF			;GET REPLY
	PUSHJ	P,UJBSTS		;GET JOBSTS
	SETCA	T1,T1			;COMPLEMENT T1
	TLNE	T1,(JB.UDI)	;SKIP IF TTY IS IN INPUT WAIT
	JRST	LOOP10			;KEEP CIRCLING
	TLNN	T1,(JB.UML)		;IS THE JOB IN MONITOR MODE?
	TLNN	T1,(JB.ULI)		;YES, LOGGED IN?
	POPJ	P,0			;EITHER THE JOB IS LOGGED IN
					;OR IT IS NOT IN MONITOR MODE
					;HENCE, TO DO RELEASE PTY
	JRST	RPTYN			;RELEASE PTY


RESCOM:	PUSHJ	P,FSUB			;GET FIRST FREE SUBJOB
	  POPJ	P,			;FORGET IT
	PUSHJ	P,IPTY			;GET A PTY FOR IT
	  POPJ	P,			;NONE
	PUSHJ	P,RESCA1		;DO A RESCAN
SLOOP0:	PUSHJ	P,STTYIN		;SWALLOW THE COLON
SLOOP1:	PUSHJ	P,TTYIN			;GET NEXT CHAR
SLOOP2:	PUSHJ	P,PTYOUT		;SEND THE CHAR TO THE PTY
	JUMPGE	F,SLOOP1		;JUMP IF MORE TO COME
	AOS	(P)			;GIVE SKIP RETURN
	JRST	DUMPT			;SEND BUFFER
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:SET
;
;-----------------------------------------------------------------------
;

;SET COMMAND, SCAN FOR ARGUMENTS WE ARE TO HANDLE, THEN IF NONE,
;GO TO 'RESCO1' TO PASS COMMAND ON TO MONITOR.

SETCMD:	JUMPL	F,TOOFEW	;GIVE ERROR IF THAT WAS ALL
	PUSHJ	P,SIXIN		;MUST BE SOME MORE TYPEIN
	JUMPE	CMD,TOOFEW	;MUST HAVE ANOTHER ARGUMENT
	CAIE	DATA,SP		;MUST BE TERMINATED BY A SPACE
	JRST	CMDERR		;NOT GOOD TYPEIN
	TLZ	F,CMD1		;ZERO "FOUND A MATCH" BIT
	MOVE	T1,CMD		;GET ARGUMENT
	SETO	T2,		;SET T2 TO -1
SETCM1:	LSH	T2,-6		;THEN MAKE A MASK
	LSH	T1,6		; USING ONLY THE NUMBER OF
	JUMPN	T1,SETCM1	; CHARACTERS TYPED IN
	MOVSI	T1,-SETSIZ	;MAKE AN AOBJN WORD
SETCM2:	CAMN	CMD,SETLST(T1)	;SKIP IF NOT PERFECT MATCH
	JRST	SETCM4		;MATCH, GO SERVICE
	MOVE	T3,SETLST(T1)	;GET ENTRY ON TABLE
	TDZ	T3,T2		;USE ONLY NUMBER OF CHARACTERS TYPED IN
	CAME	CMD,T3		;PARTIAL MATCH?
	JRST	SETCM3		;NO, TRY NEXT
	TLOE	F,CMD1		;PARTIAL, ANY OTHERS?
	JRST	DUPLIC		;YES, TYPE ERROR MESSAGE
	HRRZ	T4,T1		;REMEMBER INDEX OF PARTIAL MATCH
SETCM3:	AOBJN	T1,SETCM2	;TRY NEXT ARGUMENT, IF ONE
	TLNN	F,CMD1		;FOUND A UNIQUE PARTIAL MATCH?
	JRST	RESCO1		;NO, PASS IT ON TO MONITOR
	MOVE	T1,T4		;YES, GET INDEX
SETCM4:	TLZ	T1,-1		;CLEAR LH OF T1
	ROT	T1,-1		;DEVIDE BY TWO
	MOVE	T2,SETDSP(T1)	;GET DISPATCH ENTRY
	JUMPL	T1,(T2)		;DISPATCH IF INDEX WAS ODD
	MOVS	T2,T2		;IF INDEX EVEN, DISPATCH ON LEFT HALF
	JRST	(T2)		;AND GO
;SET RUN, SET LOGMAX, SET BATMAX, SET BATMIN, ARE SIMULATED MONITOR
; SET COMMANDS IMPLEMENTED VIA APPROPRIATE PRIVILEDGED SETUUO'S.

SETRN:	JUMPL	F,TOOFEW	;NOT ENOUGH ARGUMENTS?
	PUSHJ	P,SIXIN		;GET NEXT ARGUMENT
	JUMPE	CMD,CMDERR	;NO NEXT ARGUMENT?
	SETZ	T1,		;CLEAR T1 IN CASE ONLY ONE ARGUMENT
	JUMPL	F,SETRN1	;COULD BE LAST ARGUMENT
	CAIE	DATA,SP		;OR MAYBE ONE FOLLOWS
	JRST	CMDERR		;BUT NO SPACE LOSES
	MOVE	T1,CMD		;SAVE ARGUMENT
	PUSHJ	P,SIXIN		;AND GET ANOTHER
	JUMPE	CMD,CMDERR	;MUST BE ONE
	JUMPGE	F,CMDERR	;AND ONLY ONE
SETRN1:	PUSHJ	P,SETCK0	;DECODE LAST ARGUMENT
	  JRST SETRN3		;NOT A VALID CPU NAME
	JUMPE	T1,SETRN4	;IF T1=0, COMMAND WAS "SET RUN CPXN"
	CAME	T1,[SIXBIT /NO/];WAS COMMAND "SET RUN NO CPXN"?
	JRST	SETRN2		;NO, TRY "ONLY"
	PUSHJ	P,SETMSK	;SET UP A MASK OF CURRENTLY RUNNING CPU'S
	ANDCM	T1,T3		;CLEAR OUT THIS CPU
	JRST	SETRN5		;AND ISSUE SETUUO

SETRN2:	CAME	T1,[SIXBIT /ONLY/];WAS "SET RUN ONLY CPXN"?
	JRST	CMDERR		;NO, ERROR
	MOVE	T1,T3		;YES, ONLY SET THIS ONE
	JRST	SETRN5

SETRN3:	CAME	CMD,[SIXBIT /ALL/];WAS COMMAND "SET RUN ALL"?
	JRST	CMDERR		;NO, ERROR
	MOVEI	T1,77		;MASK TO RUN ALL POSSIBLE CPU'S
	JRST	SETRN5

SETRN4:	PUSHJ	P,SETMSK	;GET MASK FOR RUNNING CPU'S
	IOR	T1,T3		;AND ADD THIS TO OTHERS
SETRN5:	SKIPN	T1		;WILL ANY BE RUNNABLE?
	JRST	NORUN		;NO, PRINT ERROR MESSAGE
	HRLI	T1,.STCRN	;GET SETUUO FUNCTION
	SETUUO	T1,		;AND SET NEW SPECIFICATION
	JRST	NOPRIV		;NOT LOGGED IN AS 1,2
	POPJ	P,		;AND RETURN
;SUBROUTINE TO MAKE A MASK OF ALL RUNNING CPU'S IN AC T1. T3 RESPECTED.

SETMSK:	SETZ	T1,		;CLEAR REGISTER TO BUILD MASK
	MOVEI	T4,1		;MASK FOR CPU0
	MOVE	T5,[-6,,RUNTBL] ;TABLE OF GETTAB ARGUMENTS
SETMS1:	MOVE	T2,(T5)		;GET AN ENTRY
	GETTAB	T2,		;GET RUNNABILITY WORD
	  TLO	T2,400000	;ERROR RETURN MEANS UNRUNNABLE
	SKIPL	T2		;SKIP IF CPU NOT RUNNING
	IOR	T1,T4		;IS RUNNING, LIGHT BIT
	LSH	T4,1		;MOVE TO NEXT CPU POSITION
	AOBJN	T5,SETMS1	;AND LOOK AT NEXT IF ANY
	POPJ	P,		;ALL THROUGH

;SUBROUTINE TO CHECK VALIDITY OF A PHYSICAL OR LOGICAL CPU NAME AND
;CREATE A BIT MASK TO BE USED FOR THE .STRUN SETUUO.
;CALL	MOVE	CMD,[CPU NAME]
;	PUSHJ	P,SETCK0
;	ERROR RETURN		;NOT A VALID NAME
;	NORMAL RETURN		;BIT MASK IN AC T3
;T1 RESPECTED

SETCK0:	HLLZ	T3,CMD		;GET LEFTMOST THREE CHARACTERS
	CAMN	T3,[SIXBIT /CPU/];LOGICAL NAME?
	JRST	SETCK2		;YES, MAKE MASK
	MOVE	T3,[-6,,PHYTBL]	;AOBJN WORD TO LIST OF GETTAB ARGUMENTS
SETCK1:	MOVE	T2,(T3)		;GET ARGUMENT
	GETTAB	T2,		;GET PHYSICAL NAME OF THIS CPU
	  SETZ	T2,		;NONE?
	CAME	T2,CMD		;THIS ONE?
	AOBJN	T3,SETCK1	;NO, TRY NEXT IF ANY
	JUMPGE	T3,CPOPJ	;NOT A VALID NAME?
SETCK2:	HRRZ	T4,CMD		;GET CPU NUMBER
	LSH	T4,-14		;RIGHT JUSTIFY IF
	SUBI	T4,20		;AND REDUCE TO BINARY
	CAIG	T4,5		;TOO LARGE A NUMBER?
	SKIPGE	T4		;NO, TOO SMALL?
	POPJ	P,		;NOT A LEGAL CPU NUMBER.
	MOVE	T3,PHYTBL(T4)	;GETTAB ARGUMENT FOR THIS CPU
	GETTAB	T3,		;GET PHYSICAL CPU NAME
	  POPJ	P,		;DOESN'T EXIST, ERROR
	MOVEI	T3,1		;MASK FOR CPU0
SETCK3:	SOJL	T4,CPOPJ1	;THIS CPU?
	LSH	T3,1		;NO, TRY NEXT
	JRST	SETCK3
;TABLE OF GETTAB ARGUMENTS FOR CPU'S

PHYTBL:	%CCPHY			;CPU0 DATA BLOCK CONSTANTS
	%CCPHY +2		;   1
	%CCPHY +4		;   2
	%CCPHY +6		;   3
	%CCPHY +10		;   4
RUNTBL:	%CVRUN			;CPU0 DATA BLOCK VARIABLES
	%CVRUN +2		;   1
	%CVRUN +4		;   2
	%CVRUN +6		;   3
	%CVRUN +10		;   4
SETLOG:	JUMPL	F,CMDERR	;MUST HAVE AN ARGUMENT
	PUSHJ	P,DECIN		;GET DECIMAL ARGUMENT
	JUMPGE	F,CMDERR	;ANY MORE IS AN ERROR
	HRLI	CMD,.STLMX	;GET SETUUO FUNCTION
	SETUUO	CMD,		;AND SET IT UP
	  JRST	SETBAD		;SOMETHING WRONG
	POPJ	P,

SETBMX:	JUMPL	F,CMDERR
	PUSHJ	P,DECIN
	JUMPGE	F,CMDERR
	HRLI	CMD,.STBMX
	SETUUO	CMD,
	  JRST	SETBAD
	POPJ	P,

SETBMN:	JUMPL	F,CMDERR
	PUSHJ	P,DECIN
	JUMPGE	F,CMDERR
	HRLI	CMD,.STBMN
	SETUUO	CMD,
	  JRST	SETBAD
	POPJ	P,
DEVRST:	JUMPL	F,TOOFEW	;NOT ENOUGH TEXT
	PUSHJ	P,SIXIN		;GET DEVICE NAME
	JUMPE	CMD,CMDERR	;NO DEVICE NAME?
	DVRST.	CMD,		;RESTRICT DEVICE
	  JRST	DEVERR		;ERROR RETURN, EITHER NON-EX OR NO PRIVS
	CAIE	DATA," "	;A SPACE
	CAIN	DATA,":"	;WAS THE COLON PROVIDED
	PUSHJ	P,STTYIN	;YES, GET NEXT CHAR
	CAIN	DATA,","	;SKIP IF MORE ARGS.
	 JRST	DEVRST		;GET NEXT ARG.
	POPJ	P,		;GOOD RETURN

DEVURS:	JUMPL	F,TOOFEW	;NOT ENOUGH TEXT?
	PUSHJ	P,SIXIN		;GET DEVICE NAME
	JUMPE	CMD,CMDERR	;NO DEVICE NAME?
	DVURS.	CMD,		;UNRESTRICT DEVICE
	  JRST	DEVERR		;ERROR
	CAIE	DATA," "	;A SPACE
	CAIN	DATA,":"	;WAS THE COLON PROVIDED
	PUSHJ	P,STTYIN	;YES, GET NEXT CHAR
	CAIN	DATA,","	;SKIP IF MORE ARGS.
	 JRST	DEVURS		;GET NEXT ARG.
	POPJ	P,		;GOOD RETURN


SETBAD:	SKIPA	T2,[CMDERR]	;IF PRIV THEN COMAND ERROR
DEVERR:	MOVEI	T2,NOBE		;IF PRIV THEN NO SUCH DEVICE
	MOVE	T1,MYPPN	;GET OUR PPN
	CAMN	T1,OPRPPN	;ARE WE OPR??
	  JRST	(T2)		;YES, MUST BE TYPO
	JRST	NOPRIV		;LOOSE
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:EXIT COMMAND
;
;-----------------------------------------------------------------------
;

FINISH:	TLZ	F,SBOD			;START WITH ZERO
	MOVSI	SJB,NPTLTH		;MAKE XWD PTR
FINISL:	TDNN	F,USE(SJB)		;SKIP IF IN USE
	JRST	NOFIN1
	PUSHJ	P,ISJOB			;SKIP IF JNA IS ON
	  JRST	NOFIN2			;FREE
	TLOE	F,SBOD			;SET & SKIP IF FIRST TIME
	JRST	MULTI			;SECOND OR THIRD
	MOVEI	PT1,[ASCIZ/?OPRJRO Job(s) running on /]
	PUSHJ	P,MOUT			;SEND THAT STRING
	SKIPA
MULTI:	PUSHJ	P,COMOUT		;TYPE A COMMA
	PUSHJ	P,PUTNAM		;AND THE SUBJOB NAME
	JRST	NOFIN1			;AND END LOOP
NOFIN2:	PUSHJ	P,RPTYN			;RELEASE PTY
NOFIN1:	AOBJN	SJB,FINISL		;LOOP FOR ALL SUBJOBS
	TLNN	F,SBOD			;SKIP IF SOMEBODY RUNNING
	JRST	FINIX			;NO--LOOK FOR KSYS
	JSP	PT1,MOUT
	ASCIZ	/
?OPRJRO Type ":KILL ALL" to kill the subjobs
/

FINIX:	MOVEI	PT1,[ASCIZ /%OPRKPN KSYS PENDING
/]
	SKIPE	KSYNC			;SKIP IF NO KSYS
	PUSHJ	P,MOUT			;TYPE THE MESSAGE
PANIC1:	EXIT	17,			;SAY DOT
	POPJ	P,0			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:KSYS COMMAND AND SYSTEM KILLER
;
;-----------------------------------------------------------------------
;

KSYS:	JUMPL	F,KNONE		;JUMP IF NO ARGUMENT
	PUSHJ	P,STTYIN	;GET A CHAR
	JUMPL	F,KNONE		;JUMP IF ONLY ARGUMENTS WERE BLANKS
	SETZ	SJB,		; AND CLEAR SJB
	CAIN	DATA,"+"	;WAS IT +HHMM
	JRST	GETKTM		;YES--GO READ TIME
	MSTIME	SJB,		;WHAT TIME IS IT NOW
	IDIVI	SJB,^D1000*^D60	;CONVET TO MINS
	PUSHJ	P,RDX60		;GET THE TIME
	  POPJ	P,		;ERROR
	CAILE	CMD,^D24*^D60	;MORE THAN 24 HRS.
	JRST	BADTIM		;YES--BAD TIME
	JRST	SETK		;LOCK IT IN
KNONE:	SETZB	CMD,T1		;CLEAR KSYS TIME 
	JRST	SETK1		;STORE THE TIME
GETKTM:	PUSHJ	P,RDX60W	;GET TIME TO KSYS
	  POPJ	P,		;ERROR
SETK:	SUB	CMD,SJB		;SUBTRACT TIME NOW
	SKIPGE	CMD		;IS IT POSITIVE
	ADDI	CMD,^D60*^D24	;NO--ADD A DAY
	CAIL	CMD,5		;AT LEAST FIVE MIN.
	JRST	SETK1		;YES--SKIP THE WARNING
	MOVEI	PT1,ATL5	;LOAD A WARNING
	PUSHJ	P,MOUT		;GIVE THE MESSAGE
	MOVEI	CMD,5		;NO--SLOW ERIC DOWN

SETK1:	SETZM	KSYFLG		;CLEAR THE KSYS MESSAGE FLAG
	JUMPL F,SETK2		;IF END OF LINE
	PUSHJ P,STTYIN		;GET NEXT NON-BLANK CHAR
	JUMPL F,SETK2		;IF END OF LINE
	CAIE DATA,42		;IS CHAR A QUOTE
	 JRST SETK2		; NOPE, NO MESSAGE
	MOVE PT2,[POINT 7,KSYMSG]; YEP, START READING MESSAGE
KMES0:	PUSHJ P,TTYIN		;  GET NEXT CHAR
	CAIE DATA,LF		;  IS IT A CR
	 JRST KMES1		;   NOPE, SKIP CODE
	MOVEI PT1,[ASCIZ/?OPRUTM Unterminated Message
/]				;   YEP,SET UP ERROR MESSAGE
	PUSHJ P,MOUT		;    SEND IT OUT
	POPJ P,			;    RETURN
KMES1:	CAIN DATA,42		;  IS CHAR END QUOTE?
	 JRST KMES2		;   YEP,SKIP CODE
	IDPB DATA,PT2		;   NOPE,STORE CHR IN MSG
	JRST KMES0		;    AND GET NEXT CHAR
KMES2:	SETOM KSYFLG		;   SET MESSAGE FLAG ON
	SETZ DATA,		;   MAKE A NULL
	IDPB DATA,PT2		;   FINISH ASCIZ STRING

SETK2:	PUSHJ	P,CHKOPR	;MAKE SURE ITS "OPR"
	 JRST	SETUER		;NOT-SKIP KSYS CODE
	HRLI	CMD,.STKSY	;SET UP FUNCTION
	SETUUO	CMD,		;SET KSYS
	  JRST	SETUER		;ERROR RETURN
	HRRZM	CMD,KSYNC	;SAVE FOR SYNC
	MOVEI	T1,WARNTB	;GET POINTER TO TABLE
	MOVEM	T1,WARNTM	;STORE AS WARN POINTER
	HRRZ	T1,CMD		;COPY TIME TO KSYS
	JUMPE	T1,SETDA0	;DO NOT WARN IF 0
	JRST	WARN		;PUT IN THE REQUEST
SETUER:	JSP	PT1,MOUT	;GIVE ERROR MESSAGE
	ASCIZ	/?OPRCST You can not stop timesharing
/
	RADIX	10
WARNTB:	EXP	480,240,120,60,30,15,8,4,2,1,0,-1
	RADIX	8
	EXP	400000000000	;SOMETHING VERY SMALL
WARN:	PUSH	P,T1			;SAVE T1 (MIN. TO KSYS)
	PUSHJ	P,FSUB			;FIND A FREE SUBJOB
	  JRST  XPOPJ			;NONE CLEAR STACK AND RETURN
	MOVEM	SJB,KSYPTY		;SAVE THE NAME OF THE SUBJOB
	PUSHJ	P,IPTY			;GO INIT A PTY.
	  JRST	XPOPJ			;NONE AROUND CLEAN UP AND RETURN
	POP	P,T4			;RESTORE T4
	AOS	WARNTM			;POINT TO NEXT TIME
	CAMG	T4,@WARNTM		;ONLY GIVE ONE MESSAGE
	JRST	.-2			; BUMP POINTER AGAIN
	JUMPLE	T4,EWORLD		;END THE WORLD
	CAMLE	T4,WARNTB	;TEST FOR TIME FOR FIRST MESSAGE
	JRST	SETDA0		;NO--JUST SET THE TIME
	MOVEI	PT1,[ASCIZ /SEND ALL OPSER: Timesharing ends in /]
	PUSHJ	P,PTMOUT		;SEND THE STRING
	PUSHJ	P,DECPTY		;DECMAL OUTPUT TO PTY
	MOVEI	PT1,[ASCIZ / min.
/]
	PUSHJ	P,PTMOUT		;SEND THE STRING
	PUSHJ	P,DUMPT			;DUMP THE BUFFER

WARN0:	MOVE	PT2,KSYFLG		;GET THE KSYS MESSAGE FLAG
	JUMPGE	PT2,WARN2		;JUMP IF NOT SET
	SETZM	KSYFLG			;CLEAR FOR NEXT TIME AND CONT
WARN1:	MOVEI	PT2,1			;SLOW DOWN FOR A SECOND
	SLEEP	PT2,			;     TAKE A NAP
	PUSHJ	P,UJBSTS		;GET PTY JOB STATS
	TLNN	T1,(JB.UDI)		;IS IT READY FOR MORE?
	 JRST	WARN1			; NO, GO CHECK AGAIN

	MOVEI	PT1,[ASCIZ /SEND ALL OPSER: /]
	PUSHJ	P,PTMOUT		;SEND THE STRING
	MOVEI	PT1,KSYMSG		;GET KSYS MESSAGE
	PUSHJ	P,PTMOUT		;AND SEND IT OUT
	MOVEI	PT1,[ASCIZ/
/]					;AND FOLLOW WITH A CR
	PUSHJ	P,PTMOUT		;SEND IT OUT
	PUSHJ	P,DUMPT			;DUMP THE BUFFER

WARN2:	JRST	SETDA0			;SET UP TIME TRAP

DECPTY:	IDIVI	T4,12			;DIVIDE BY 10
	PUSH	P,T5			;SAVE REMAINDER
	SKIPE	T4			;SKIP IF DONE
	PUSHJ	P,DECPTY		;LOOP FOR MORE
	POP	P,T1			;RESTORE A DIGIT
	MOVEI	DATA,60(T1)		;COPY AND CONVERT
	JRST	PTYOUT			;LOOP FOR MORE
CHKOPR:	GETLIN	PT1,			;FIND THIS LINE'S NAME
	MOVE	T1,[%CNOPR]
	GETTAB	T1,			;FIND TTY NAME
	 MOVSI	T1,'CTY'
	CAMN	T1,PT1			;IS IT "OPR"?
	 AOS	(P)			;YES-ABLE TO KSYS
	POPJ	P,			;NO-NO KSYS
;HERE TO KILL ALL THE USERS JOBS

EWORLD:	MOVEI	PT1,[ASCIZ /SEND ALL OPSER: TIMESHARING IS OVER!!
/]
	SETOM	LINO			; RESET LINO
	PUSHJ	P,PTMOUT		;SEND THE MESSAGE
	PUSHJ	P,DUMPT			;DUMP THE BUFER
	SETZM	KSYNC			;OVER, CLEAR PENDING
	MOVE	T4,[%CNSJN]		;FIND OUT HOW MANY JOBS IN THE SYSTEM
	GETTAB	T4,			;ASK THE MONITOR
	  MOVEI	T4,^D128		;NICE LOOKING DEFAULT
	MOVEM	T4,MAXJOB		; SAVE THE MAX # OF THE JOBS
	MOVEI	T4,-1(T4)		;DON'T COUNT THE NULL JOB, CLEAR LH
ELOOP:	MOVEI	T1,(T4)			;COPY JOB NUMBER
	TRMNO.	T1,			;GET TTY NUMBER
	  SKIPA				;LOST--SEE WHY
	JRST	ELOOP1			;WON--GET TTY BITS
	JUMPN	T1,ETRMNO		;NEED THE UUO
ELOOP2:	SKIPGE	LINO			;ORIGINAL JOB?
	JRST	.+3			;YES
	SETOM	LINO			;NO-RESET THE LINO
	MOVE	T4,JOBNO		;AND RESTORE THE JOB NUMBER
	SOJG	T4,ELOOP		;LOOK AT NEXT JOB
	JRST	KJOBS			;GO KILL DETACHED JOBS
ELOOP1:	MOVSI	T2,(T4)			;GET JOB NUMBER AGAIN
	HRRI	T2,.GTPPN		;TABLE JBTPPN
	GETTAB	T2,			;WHO IS THIS GUY
	  SETZ	T2,			;COME ON!!
	CAMN	T2,OPRPPN		;[SYSTEM OPSERATOR]
	  JRST	ELOOP2			;YES, LEAVE ALONE, WOULDN'T KILL
					;  IT LATER ANYWAY SO WHY DETACH
	MOVE	T2,T1			;COPY LINE NUMBER
	GETLCH	T2			;GET TTY BITS
	TLNE	T2,(1B0)		;A PTY?
	JRST	DETSJB			;YES
	TLNN	T2,(1B3!1B6)		;SKIP IF DATASET OR REMOTE
	JRST	ELOOP2			;LOOK AT NEXT JOB
ELOOP3:	SKIPL	LINO			;ORIGINAL JOB?
	MOVE	T1,LINO			;NO-GET THE ORIGINAL JOB'S LINE #
	HRLZ	T2,T1			;COPY LINE NUMBER
	TLZ	T2,(1B1)		;CLEAR IO INDEX BIT
	ATTACH	T2,			;DETACH THE JOB
	  JFCL				;WE TRIED
	JRST	ELOOP2			;LOOP FOR MORE JOBS

DETSJB:	SKIPGE	LINO			;ORIGINAL JOB?
	PUSHJ	P,SAVINF		;YES, SAVE IT'S LINE AND JOB #
	MOVSI	T2,(T4)			;GET THE JOB #
	HRRI	T2,.GTLIM		;FIND OUT THE JOB STATUS
	GETTAB	T2,			;ASK THE MONITOR
	  JRST	ELOOP2			;FAIL-GO ON TO NEXT JOB
	TLNN	T2,(1B10)		;IS IT A BATCH JOB?
	CTLJOB	T4,			;SEE IF THERE IS A CONTROLLING JOB
	  JRST	ELOOP2			;FAIL, GO ON TO NEXT JOB
	JUMPL	T4,ELOOP3		;NO CONTROLLING JOB.DETACH IT
	SOSGE	 ,JBCNT			;SEE IF IN A LOOP?
	JRST	ELOOP3			;YES, GO DETACH IT
	  JRST	ELOOP			;NO,CHECK CONTROLLING JOB
SAVINF:	MOVEM	T1,LINO			;SAVE LINE #
	MOVEM	T4,JOBNO		;SAVE JOB #
	MOVE	T2,MAXJOB		;GET MAX # OF JOBS
	MOVEM	T2,JBCNT		;SAVE IN IT
	POPJ	P,			;RETURN

ETRMNO:	JSP	PT1,MOUT		;TRMNO UUO FAILED
	ASCIZ	/?OPRTUF TRMNO. UUO FAILED -- KSYS ABORTED
/
;HERE TO MOP UP ALL DETACHED JOBS (EXCEPT DETACHED [1,2])

KJOBS:	PUSHJ	P,.+1			;DO TWICE FOR GOOD MEASURE
	MOVSI	T1,.GTTTY		;SAVE FIRST PTY
	MOVEM	T1,SAVKJB		;FOR LATER USE
KJOBGO:	PUSHJ	P,IOCHK			;EAT ANY OUTPUT FROM SUBJOBS
	MOVSI	SJB,NPTLTH		;BUILD AN AOBJN POINTER
KJOB.0:	TDNE	F,USE(SJB)		;IS THIS JOB IN USE
	 PUSHJ	P,ISJOB			;YES, IS THERE A JOB ATTACHED TO IT
	  JRST	KJOB.1			;FOUND A FREE ONE, USE IT FOR KSYS
	AOBJN	SJB,KJOB.0		;KEEP LOOKING
	MOVEI	SJB,^D10		;POSSIBLE RACE COMING UP
	SLEEP	SJB,			;SO TAKE A QUICK NAP
	MOVE	SJB,KSYPTY		;GET OUR FAVORITE PTY
KJOB.1:	PUSHJ	P,RPTYN			;RELEASE OLD PTY (MAY DETACH OLD JOB)
	PUSHJ	P,IPTY			;AND INIT A PTY ON IT
	  POPJ	P,			;NO MORE PTY'S
	PUSHJ	P,PTSET2		;SET :TSILENCE MODE
	MOVEI	T1,(SJB)		;GET THE CHAN
	DEVNAM	T1,			;GET THE FILE NAME
	  POPJ	P,			;PRIOR TO 5.03
	HRLZ	T1,T1			;COPY UNIT TO LEFT HALF
	MOVE	T2,[POINT 6,T1]		;SET A BYTE POINTER
	SETZ	T3,			;CLEAR RESULT
KSLP0:	ILDB	T4,T2			;LOAD A DIGIT
	JUMPE	T4,KSYS1		;DONE
	LSH	T3,3			;MULT BY 8
	ADDI	T3,-20(T4)		;ADD IN NEXT DIGIT
	JRST	KSLP0			;LOOP FOR MORE DIGITS
KSYS1:	ADD	T3,PTY0LN		;FIX FOR PTYOFS
	PUSH	P,T3			;SAVE ON STACK
	MOVE	T1,SAVKJB		;RESET OF CURRENT JOB NUMBER
KSLP1:	MOVS	T2,T1			;LH=JOB , RH=TTY TRANSLATE TABLE
	GETTAB	T2,			;GET DDB POINTER
	  JRST	KSYS2			;END OF TTY TRANSLATE TABLE
	SKIPN	T2			;SKIP IF DDB
	AOJA	T1,KSLP1		;ELSE LOOK AT NEXT JOB
	MOVSI	T3,(T1)			;GET JOB NUMBER
	HRRI	T3,.GTPPN		;GET THE PPN OF THE JOB
	GETTAB	T3,			;AND JBTPPN WORD
	  JRST	KSYS2			;SHOULD NEVER HAPPEN
	CAMN	T3,OPRPPN		;IS IT A DETACH OPER JOB
	  AOJA	T1,KSLP1		;YES, LEAVE IT ALONE

;DETACHED OPR JOBS ARE PROBABLY USEFUL AND DON'T WANT TO WIRE THE NAMES
;	INTO OPSER SINCE NEW ONES ARE ADDED.  "FILDAE" WAS ADDED IN 6.03.

;FALL ONTO NEXT PAGE FOR FINAL KILLING OF THE JOB
KSYS4:	PUSHJ	P,CHKATT		;SEE IF ATTACHED
	  SKIPA				;NO--GO KILL OFF
	AOJA	T1,KSLP1		;YES--REAL USER
	POP	P,T2			;RESTORE LINE NUMBER
	HRLZ	T2,T2			;PUT IN LEFT HALF
	HRR	T2,T1			;PUT JOB IN RH
	AOJA	T1,.+1			;ADVANCE TO NEXT JOB BEFORE STORING
	MOVEM	T1,SAVKJB		;SAVE SUBJOB NUMBER
	TLO	T2,(1B0)		;COMMAND LEVEL
	ATTACH	T2,			;ATTACH
	  JRST	KJOBGO			;WHOOPS!! START AGAIN
	PUSHJ	P,STOP.1		;SEND A FEW ^C'S
	  JFCL
	MOVEI	PT1,[ASCIZ \KJOB KSYS.LOG=/W/B/VD:D
\]
	MOVE	T1,[%CNST2]		;[126]SEE IF ON GALAXY-10
	GETTAB	T1,			;[126]GET 2ND CONFIG TABLE WORD
	  SETZ	T1,			;WHOOPS, NOT EVEN 6.02
	TRNE	T1,ST%GAL		;[127]IF BIT IS ZERO, NORMAL MPB
	  MOVEI	PT1,[ASCIZ\KJOB/BATCH/NOMESSAGES
\]
	PUSHJ	P,PTMOUT		;PUMP THE MESSAGE OVER
	JRST	KJOBGO			;LOOP FOR MORE JOBS
KSYS2:	POP	P,T1			;CLEAN UP PDL
	POPJ	P,			;RETURN

;CHECK TO SEE IF ATTACHED (ARGS T1=JOB # T2=ADDR. OF DDB)
; SKIP RETURNS IF ATTACHED

CHKATT:	HRRZ	T3,T1			;COPY JOB NO.
	TRMNO.	T3,			;GET LINE NUMBER
	  JRST	.+2			;UUO FAILED
	JRST	CPOPJ1			;HAS LINE # MUST BE
					; ATTACHED
	JUMPE	T3,CPOPJ		;UUO WORKED
					; ASSUME DETACHED
	MOVEI	T3,14(T2)		;OFFSET FROM START OF DDB TO LDB POINTER
					;OLD MONITOR
	PEEK	T3,			;GO LOOK AT CORE
	TRNE	T3,-1			;REAL LDB LINK
	AOS	(P)			;YES--WIN
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:CONTINUE COMMAND
;
;-----------------------------------------------------------------------
;

	IFN	FTAUTO,<
CONT:	MOVEI	T1,AUTOC
	DEVCHR	T1,
	JUMPE	T1,CNTCON
	TLO	F,AUTOM
	POPJ	P,
>
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:HELP COMMAND
;
;-----------------------------------------------------------------------
;

HELP:	JUMPGE	F,RESCO1	;IF ARGUMENT PASS TO MONITOR
	PUSH	P,SJB		;SAVE SUBJOB NUMBER
	PUSH	P,LASU		;SAVE LAST REFERENCE
	PUSHJ	P,FSUB		;FIND A FREE PTY
	  JRST	HELP.E		;NONE--CAN NOT HELP YOU
	PUSHJ	P,IPTY		;INIT A PTY
	  JRST	HELP.E		;OUT OF PTY'S
	MOVEI	PT1,[ASCIZ /HELP OPSER
/]
	PUSHJ	P,PTMOUT	;GIVE THE LINE TO THE PTY
	PUSHJ	P,DUMPT		;DO THE OUTPUT TO THE PTY
	PUSHJ	P,LOOP10	;GET THE TEXT
HELP.E:	POP	P,LASU		;RESTORE DEFAULTS
	POP	P,SJB		; ..
	POPJ	P,		;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:DEFINE COMMAND
;
;-----------------------------------------------------------------------
;

SJNAM:	JUMPL	F,TOOFEW		;MUST HAVE SOME ARGUMENTS
	PUSHJ	P,SIXIN			;GET SIXBIT WORD
	JUMPE	CMD,CMDERR		;NO NULLS ALLOWED
	CAIE	DATA,"="		;MUST END WITH EQUALS
	JRST	CMDERR			;ERROR
	CAMN	CMD,[SIXBIT /ALL/]	;ALL?
	JRST	NOALL			;YES--COMMAND ERROR
	LDB	T1,[POINT 6,CMD,5]	;GET FIRST CHAR.
	CAIL	T1,'A'			;LESS THAN A
	CAILE	T1,'Z'			;GREATER THAN Z
	JRST	CMDERR			;YES--COMMAND ERROR
	PUSH	P,CMD			;SAVE ON PDL
	PUSHJ	P,WHATJB		;GET SUBJOB REF
	  JRST	XPOPJ			;TYPO
	POP	P,CMD			;RESTORE CMD
	TRNE	SJB,1B18		;CANNOT USE ALL HERE
	JRST	NOALL			;TELL HIM
	TDNN	F,USE(SJB)		;MUST BE IN USE
	JRST	NOTACT			;NOT IN USE
	PUSHJ	P,ONLY1			;NO LIST ALLOWED
	MOVSI	T1,NPTLTH		;MAKE XWD PTR
	CAME	CMD,MNEMON(T1)		;SKIP IF DUPLICATE
	AOBJN	T1,.-1			;LOOP FOR ENTIRE TABLE
	JUMPGE	T1,STORE		;NO MATCH - GO STORE
	TLZ	T1,-1			;ZERO LH
	CAIN	T1,(SJB)		;SKIP IF NOT NEW ONE
	POPJ	P,			;RE-TYPE
	SETZM	MNEMON(T1)		;ZERO OLD LOC
	MOVEM	CMD,MNEMON(SJB)		;INSERT NEW ONE
	PUSHJ	P,DECOUT		;TYPE NUMBER
	JSP	PT1,MOUT		;AND THIS MESSAGE
	ASCIZ	/ Was mnemonic's old value
/
STORE:	MOVEM	CMD,MNEMON(SJB)		;STORE IN TABLE
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:WHAT COMMAND
;
;-----------------------------------------------------------------------
;

WHAT:	PUSH	P,[TSTAT]		;PUSH ADDR OF SUBR
	PUSHJ	P,RUNSA			;GO EXECUTE
	IFN	FTAUTO,<
	TRNE	SJB,1B18		;DON'T TYPE IF NOT :WHAT ALL
	SKIPN	T3,ATOTIM		;SKIP IF AUTO FILE PENDING
>
	POPJ	P,			;ELSE RETURN
	IFN	FTAUTO,<
	PUSHJ	P,LOUD			;TURN ON TTY
	MOVEI	PT1,[ASCIZ /Next auto file is: /] 
	PUSHJ	P,MOUT			;PRINT INTRO
	MOVE	T1,ATOT2		;FILE NAME
	PUSHJ	P,SIXBP			;PRINT IT
	MOVEI	PT1,[ASCIZ / AT /]	;ADDI IN NOISE WORD
	PUSHJ	P,MOUT			;PRINT IT
	PUSHJ	P,GETUPT		;GET THE UP TIME
	SUB	T3,T1			;GET THE DISTANCE AWAY
	MSTIME	T1,			;GET THE CURRENT TIME
	ADD	T1,T3			;GET TIME OF DAY
	IDIV	T1,[DEC 24*60*60*1000]	;MAKE MOD 1 DAY
	MOVE	T1,T2			;USE REMAINDER
	PUSH	P,[TTYOUT]		;OUTPUT TO TTYOUT
	PUSHJ	P,HAVTIM		;TYPE AS TIME
	JRST	CRLF			;GIVE A CRLF AND RETURN
>


TSTAT:	PUSHJ	P,LOUD			;TURN ON TTY
	PUSHJ	P,PUTNAM		;TYPE SUBJOB NAME
	PUSHJ	P,TABOUT		;AND A TAB

	PUSHJ	P,ISJOB			;SKIP WITH JNA ON - LOAD MJOB
	  JRST	NOTLOG			;CANNOT DO WITH JNA OFF
	HRRZ	T1,MJOB			;LOAD JOB NUMBER
	PUSHJ	P,DECOUT		;TYPE IT
	PUSHJ	P,TABOUT		;FOLLOWED BY A TAB

	HRLZ	T4,MJOB			;LOAD JOB INTO LH
	HRRI	T4,.GTPPN		;SET FOR PPN
	GETTAB	T4,			;GET FROM MONITOR
	  SETZ	T4,			;FUNNY ERROR RETURN
	SETZM	DGTCNT			;ZERO DIGIT COUNT
	HLRZ	T1,T4			;PUT PROJ# IN T1
	PUSHJ	P,OCTOUT		;TYPE THAT
	PUSHJ	P,COMOUT		;TYPE A COMMA
	HRRZ	T1,T4			;LOAD PROG# INTO T1
	PUSHJ	P,OCTOUT		;TYPE THAT
	PUSHJ	P,TABOUT		;SPACE OVER
	MOVE	T1,DGTCNT		;LOAD DIGIT COUNT
	CAIGE	T1,7			;SKIP IF MORE THAN 7
	PUSHJ	P,TABOUT		;TYPE ANOTHER TAB

	HRLZ	T1,MJOB			;PUT JOB IN LH
	HRRI	T1,.GTPRG		;GET PROGRAM NAME
	GETTAB	T1,			;FROM MONITOR
	  MOVE	T1,[SIXBIT/? ?????/]	;LOAD BONER RETURN
	PUSHJ	P,SIXBP			;PRINT THAT
	PUSHJ	P,TABOUT		;AND A TAB
	HRLZ	T2,MJOB			;PUT JOB IN LH
	HRRI	T2,.GTSTS		;GET JOB STATUS
	GETTAB	T2,			;FROM MONITOR
	  SETZ	T2,			;TAKE 0 FOR DEFAULT
	MOVEI	T1,'^C'			;LOAD DEFAULT ^C
	JUMPGE	T2,GOTSTA		;JUMP IF RUN BIT OFF
	LDB	T3,[POINT 5,T2,14]
	IDIVI	T3,3
	HRLZ	T1,T3			;PUT QUOTIENT IN LH
	HRRI	T1,.GTWSN		;SIXBIT JOB QUEUE CODES
	GETTAB	T1,			;FROM MONITOR
	  MOVE	T1,CTBL(T3)		;LOAD LEVEL-C DEFAULTS
	LDB	T1,PTRS(T4)		;GET APPROPRIATE 2 CHARS
	CAIE	T1,'SL'			;IS JOB IN SLEEP QUEUE?
	JRST	GOTSTA			;NO--PRINT STATE
	TRNN	T2,1B18		;(USED TO TELL HIBER FROM SLEEP)
					;CLOCK REQUEST?
	MOVEI	T1,'HB'			;NO--JOB IS HIBERING
GOTSTA:	ROT	T1,-^D12		;LEFT JUSTIFY
	PUSHJ	P,SIXBP			;TYPE SIXBIT
	TLNN	T2,2000			;SKIP IF LOWSEG IS SWAPPED OUT
	JRST	NOLSWP			;NOT
	PUSHJ	P,SPOUT			;TYPE A SPACE
	HRLZ	T2,MJOB			;PUT JOB IN LH
	HRRI	T2,.GTSWP		;SET UP FOR SWAPPER DATA
	GETTAB	T2,			;ASK MONITOR FOR IT
	  SETZ	T2,			;MYSTERIOUS NO
	MOVSI	T1,'SW '		;DEFAULT SW
	SKIPGE	T2			;SKIP IF NOT FRAGMENTED
	MOVSI	T1,'SF '		;REPLACE SW WITH SF
	PUSHJ	P,SIXBP			;TYPE STATE
NOLSWP:	PUSHJ	P,TABOUT		;TAB OVER
	HRRZ	T1,MJOB			;LOAD JOB NBR INTO T1
	RUNTIM	T1,			;GET MILLISEC RUNTIME
	PUSH	P,[TTYOUT]		;SEND TO TTY
	PUSHJ	P,HAVTIM		;TYPE ON CONSOLE THE TIME
	TLNN	F,MSH			;LONG MODE?
	JRST	CRLF			;CONCLUDE WITH CR-LF
	PUSHJ	P,TABOUT		;PUT OUT A TAB
	PUSHJ	P,UJBSTS		;GET THE JOB STATUS
	MOVE	T2,[ASCII .     .]	;SET UP A BLANK WORD
	TLNE	T1,(JB.ULI)		;LOGGED IN
	TLC	T2,(<"L"+" ">B6)	;YES--MAKE AN L
	TLNE	T1,(JB.UML)		;MONITOR MODE?
	TLC	T2,(<"M"+" ">B13)	;YES--MAKE AN M
	TLNE	T1,(JB.UDI)		;INPUT REQUEST?
	TLC	T2,15			;YES--MAKE AN H
	TLNE	T1,(JB.UOA)		;OUTPUT READY
	TRC	T2,<"O"+" ">B27		;YES--MAKE AN O
	TLNE	T1,(JB.UJC)		;IS THE PRIV BIT ON?
	TRC	T2,<"A"+" ">B34		;YES MAKE AN A
	TLNE	T2,1			;JB.UDI?
	TRO	T2,100000		;CONVERT H TO I
	MOVEI	PT1,T2
	SETZ	T3,			;MAKE A NULL
	PUSHJ	P,MOUT			;PRINT
	JRST	CRLF			;END WITH CRLF
PTRS:	POINT	12,T1,11
	POINT	12,T1,23
	POINT	12,T1,35


CTBL:	SIXBIT	.RNWSTS.
	SIXBIT	.STAUMQ.
	SIXBIT	.DADTDC.
	SIXBIT	.MTIOTT.
	SIXBIT	.SLNL^C.
	SIXBIT	.??????.
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:AUTO COMMAND
;
;-----------------------------------------------------------------------
;

	IFN	FTAUTO,<
AUTO:	PUSHJ	P,TIMEAF		;SEE IF TIME-OF-DAY FILE
	  POPJ	P,			;IT WAS ALL DONE.
	PUSHJ	P,GETSPC		;GET FILSPEC
	  POPJ	P,			;RETURN ON ERROR
FAUTO:	SKIPN	T1			;SKIP IF DEVICE TYPEIN
	MOVSI	T1,'DSK'		;GIVE HIM DISK
	MOVEM	T1,BLK3+1		;STORE IN OPEN BLOCK
	DEVCHR	T1,			;GET CHARACTERISTICS
	JUMPE	T1,NOBE			;JUMP IF NON-EXISTANT
	TLNN	T1,(DV.IN)			;SKIP IF INPUT DEVICE
	JRST	NOTIN			;NOT - FLAG HIM
	MOVEI	T1,AUTIB		;LOAD ADDR OF IBUF HDR
	MOVEM	T1,BLK3+2		;STORE IN OPEN BLOCK
	PUSHJ	P,AUTREL		;RELEASE OLD CHANNEL, IF ANY
	OPEN	AUTOC,BLK3		;OPEN NEW ONE
	  JRST	NOINTX			;SOMEONE ELSE HAS DEVICE
	TLO	F,AUTOM			;SET AUTO BIT
	PUSH	P,.JBFF			;PUT .JBFF ON PDL
	INBUF	AUTOC,3			;FILL TO 2K MARK IN LOWSEG
	POP	P,.JBFF			;RESTORE .JBFF
	MOVE	T1,BLK3+1		;GET BACK DEVNAM
	DEVCHR	T1,			;GET CHARS
	TLNN	T1,(DV.DIR)		;SKIP IF IT HAS A DIRECTORY
	POPJ	P,			;NONE - RETURN NOW
	SKIPN	T1,T2			;LOAD FILNAME INTO T1
	MOVE	T1,[SIXBIT/OPSER/]	;LOAD DEFAULT
	SKIPE	T2,T3			;SKIP IF NO EXT TYPED
	TRZA	T2,T2			;ZERO RH
	MOVSI	T2,'ATO'		;LOAD DEFAULT
	SETZ	T3,			;ZERO T3
	LOOKUP	AUTOC,T1		;TRY TO LOOKUP FILE
	  JRST	CNFND			;NO SOAP
	POPJ	P,			;OK - RETURN

CNFND:	PUSHJ	P,AUTREL		;RELEAS AUTO CHANNEL
	MOVEI	PT1,[ASCIZ/?OPRALF LOOKUP failure /]
	PUSHJ	P,MOUT			;TYPE REASON FOR FAILURE
	HRRZ	T1,T2			;LOAD ERROR CODE INTO T1
	PUSHJ	P,OCTOUT		;TYPE ON CONSOLE
	JRST	CRLF			;SUFFIX WITH CR-LF
AUTREL:	TLZ	F,AUTOM			;ZERO BIT
	RELEAS	AUTOC,			;RELEASE CHANNEL
	PUSH	P,T1			;SAVE T1
	HLRZ	T1,.JBSA		;GET ORIGINAL .JBFF
	TRO	T1,1777			;ROUND TO NEAREST K
	CORE	T1,			;RESET LOWSEG CORE
	  JFCL				;WHY I DON'T KNOW
	POP	P,T1			;RESTORE T1
	POPJ	P,			;RETURN


NOTIN:	JSP	PT1,MOUT
	ASCIZ	/?OPRANI Device cannot do input
/
;HERE TO DO TIME-OF-DAY AUTO FILES

TIMEAF:	JUMPL	F,CPOPJ1		;RETURN IF EOL
	PUSHJ	P,SAVACS		;SAVE THE ACS

;;[123] TIMEAF+1 INSERT 1 LINE, SPR 10-31102, MRB, 29-MAY-81
	CAIN	DATA," "		;[123]DONT GET ANOTHER CHARACTER
					;[123]UNLESS THE LAST ONE WAS A SPACE.

	PUSHJ	P,STTYIN		;GET NEXT NON-BLANK
	CAIE	DATA,"/"		;SWITCH?
	JRST	NOSWT			;NO--THEN NO SWITCH
	JUMPL	F,CPOPJ1		;TRANSFER IF EOL
	PUSHJ	P,TTYIN			;GO GET A CHAR
	CAIE	DATA,"+"		;TIME FROM NOW?
	JRST	TIMABS			;NO ABSOLUTE TIME
	PUSHJ	P,TTYIN			;GET A CHAR
	PUSHJ	P,TIMEX			;GET THE TIME
	  POPJ	P,			;SYNTAX ERROR
TIMSTR:	MOVEI	PT1,[ASCIZ/%OPRSPR superseding previous :AUTO request
/]
	SKIPE	ATOTIM			;ALREADY HAVE ONE
	  PUSHJ	P,MOUT			;YES, OUTPUT THE MESSAGE
	PUSHJ	P,SETDAE		;POKE DAEMON
	PUSHJ	P,GETSPC		;GET THE FILSPEC
	  POPJ	P,			;ERROR
	MOVE	CMD,[T1,,ATOT1]		;STORE THE AC'S BACK
	BLT	CMD,ATOT5		; UNTIL I NEED THEM
	POPJ	P,			;RETURN

TIMABS:	SETZM	T5			;CLEAR T5 FOR /HH:MM
	CAIN	DATA,076		;WAS LAST CHAR A RIGHT ANGLE
	AOJA	T5,TIMAB1		;YES--SET T5 PLUS AS FLAG
	CAIN	DATA,074		;WAS IT A LEFT ANGLE
	SETOM	T5			;YES--SET T5 MINUS AS FLAG
TIMAB1:	SKIPE	T5			;STANDARD FORMAT?
	PUSHJ	P,TTYIN			;NO--EAT THE BRACKET
	PUSHJ	P,TIMEX			;GET THE TIME
	  POPJ	P,			;SYNTAX ERROR
	MSTIME	T1,			;GET CURRENT TIME OF DAY
	SUB	CMD,T1			;GET MS TO WAIT
	JUMPGE	CMD,TIMSTR		;GO STORE THE TIME AND
					; SET UP TO RUN THE FILE
					; IF TIME IS NOT YET PAST.
	JUMPE	T5,CPOPJ1		;DO IT NOW IF NO < OR >
	JUMPL	T5,CPOPJ		;FLUSH IT IF RIGHT BRACKET
	ADD	CMD,[^D24*^D60*^D60*^D1000] ;ELSE ADD 24 HOURS
	JRST	TIMSTR			;GO STORE THE TIME

TIMEX:	PUSHJ	P,RDX60			;GET TIME OF DAY
	  POPJ	P,			;SYNATX ERROR
	IMULI	CMD,^D60000		;CONVERT TO MS
	JRST	CPOPJ1			;RETURN
NOSWT:	MOVEM	DATA,SAVCH		;STORE CHAR
	JRST	CPOPJ1			;RETURN
SETDAE:	PUSHJ	P,GETUPT		;GET THE UPTIME
	ADD	T1,CMD			;TIME TO GET UP
	MOVEM	T1,ATOTIM		;TIME TO GET UP
	JRST	SETDA1			;JUMP AROUND OTHER CODE
SETDA0:	SKIPN	CMD,ATOTIM		;GET :AUTO TIME & TEST
	JRST	SETDA1			; ZERO -- LOOK AT KSYS
	PUSHJ	P,GETUPT		;GET CURRENT UPTIME
	SUB	CMD,T1			;GET TIME TO GO
>
IFE FTAUTO,<
SETDA0:	MOVEI	CMD,0
>
SETDA1:	MOVE	T1,[%NSKTM]		;GET THE TIME
	GETTAB	T1,			; TO KSYS
	  SETZ	T1,			;FROM THE MONITOR
	SUB	T1,@WARNTM		;FIX FOR WARNINGS
	IMULI	T1,^D60000		;CONVERT TO SECONDS
	JUMPLE	T1,SETDA2		;IGNORE :KSYS IF .LE. 0
	SKIPLE	CMD			;IGNORE :AUTO IF .LE. 0
	CAMG	T1,CMD			;DOES END COME FIRST?
	MOVE	CMD,T1			;YES--SET THE SHORTER LIMIT
SETDA2:	JUMPLE	CMD,CPOPJ		;EXIT IF ZERO TIME LEFT
	ADDI	CMD,^D999		;ELSE ROUND UP 1 SECOND
	IDIVI	CMD,^D1000		;CONVERT TO SECONDS
	MOVE	T1,[2,,T2]		;2 WORDS IN T2 AND T3
	MOVEI	T2,.CLOCK		;FUNCTION
	MOVE	T3,CMD			;ARGUMENT
	DAEMON	T1,			;LINE UP FOR JD WAIT
	  JRST CHKDAE			;SEE WHAT WENT WRONG
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:DEVICE COMMAND
;
;-----------------------------------------------------------------------
;

DEVREQ:	JUMPL	F,TOOFEW		;MUST BE SOME MORE TYPEIN
	PUSHJ	P,SIXIN			;GET DEVNAM
	JUMPE	CMD,CMDERR		;NO NULLS
	CAIE	DATA,":"		;MUST END IN COLON
	JRST	CMDERR			;BOO-BOO
	MOVE	T1,CMD			;STORE IN T1
	PUSHJ	P,SIXIN			;GET DEVLOG
	CAIE	DATA,":"		;MUST END IN COLON
	JRST	CMDERR			;TELL HIM OF ERROR
	MOVE	T2,CMD			;LOAD INTO T2
	PUSHJ	P,WHATJB		;WHAT SUBJOB GETS DEVICE
	  POPJ	P,			;TYPO
	TRNE	SJB,1B18		;SKIP IF NOT ALL
	JRST	NOALL			;TELL HIM JUST ONE
	TDNN	F,USE(SJB)		;SKIP IF IN USE
	JRST	NOTACT			;NOT ACTIVE
	PUSHJ	P,ONLY1			;ACCEPT ONLY FIRST ARG
CHK20:	SKIPN	T3,T2			;LOAD LOGICAL NAME
	MOVE	T3,T1			;NO, TAKE PHYSICAL NAME
	DEVCHR	T3,			;GET CHARACTERISTICS
	TRNE	T3,DV.ASC		;SKIP IF ASSIGNED BY CONSOLE
	JRST	GOAHD3			;IT IS - DO REASSIGN
	PUSH	P,F			;SAVE FLAGS
	TLZ	F,AUTOM!QUIET!AUXQ	;TURN OFF ALL SILENCE FLAGS
	MOVEI	PT1,[ASCIZ/Type "ASSIGN /]
	PUSHJ	P,MOUT			;STICK INTO OUTPUT BUFFER
	PUSHJ	P,SIXBP			;PRINT PHYSICAL NAME
	JUMPE	T2,FINLX		;JUMP IF NO LOGICAL NAME
	PUSHJ	P,COLOUT		;TYPE A COLON
	EXCH	T1,T2			;PUT LOGICAL NAME IN T1
	PUSHJ	P,SIXBP			;TYPE THAT
	EXCH	T1,T2			;RESTORE AC'S
FINLX:	MOVEI	PT1,[ASCIZ/<cr>CONTINUE<cr>"/]
	PUSHJ	P,MOUT			;FINISH OFF MESSAGE
	POP	P,F			;RESTORE FLAGS
	EXIT	1,				;RETURN TO MONITOR
	JRST	CHK20			;LOOP

GOAHD3:	SKIPN	T4,T2			;PUT LOG NAME INTO T4
	MOVE	T4,T1			;NO LOG NAME - USE PHYSICAL NAME
	PUSHJ	P,UJBSTS		;GET JOBSTS
	HRRZ	T3,T1			;PUT JOB NUMBER INTO T3
	REASSI	T3,			;REASSIGN THE DEVICE
	POPJ	P,			;AND RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	:CLOSED - :TLOG
;
;-----------------------------------------------------------------------
;

	IFN	FTTLOG,<

CLOSED:	TLZ	F,OFILE			;ZERO FILE OPENED BIT
	RELEAS	LOGC,			;RELEASE LOG FILE
	POPJ	P,			;RETURN NOW

TLOG:	PUSHJ	P,CLOSED		;CLOSE LOG FILE
	PUSHJ	P,GETSPC		;GET FILSPEC
	  POPJ	P,			;ERROR RETURN
	SKIPN	T1			;SKIP IF DEVSPEC
	MOVSI	T1,'DSK'		;LOAD DEFAULT DISK
	MOVEM	T1,BLK3+1		;STORE IN OPEN BLOCK
	DEVCHR	T1,			;GET CHARACTERISTICS
	JUMPE	T1,NOBE			;IF NULL, NO SUCH DEV
	TLNN	T1,(DV.OUT)		;SKIP IF CAN DO OUTPUT
	JRST	NOTOUT			;CANNOT DO
	MOVEM	T1,LOGFIL		;STORE IN CORE
	MOVSI	T1,LOGOB		;LOAD ADDR OF OUTPUT BUF IN LH
	MOVEM	T1,BLK3+2		;STORE IN OPEN BLOCK
	OPEN	LOGC,BLK3		;OPEN DEVICE
	  JRST	NOINTX			;NOT AVAILABLE
	MOVEI	T1,LOGOBB		;LOAD ADDR OF BUFFERS
	EXCH	T1,.JBFF		;STICK IN .JBFF
	OUTBUF	LOGC,1			;ALWAYS 1 BUFFER
	MOVEM	T1,.JBFF		;RESTORE .JBFF
	SKIPN	T1,T2			;LOAD FILNAME IN T1
	MOVE	T1,[SIXBIT/OPSER/]	;THAT IS DEFAULT
	MOVEM	T1,LOGFIL+1		;STORE IN CORE
	SKIPE	T2,T3			;LOAD EXT INTO T2
	TRZA	T2,-1			;ZERO RH
	MOVSI	T2,'LOG'		;DEFAULT IS LOG
	MOVEM	T2,LOGFIL+2		;REMEMBER THAT TOO
	MOVEM	T4,LOGFIL+3		;STORE PPN
	PUSHJ	P,UPDATE		;ACCESS FILE
	  POPJ	P,			;FAILURE
	TLO	F,OFILE!QUIET		;ANNOUNCE OPENING WITH SILENCE
	SETOM	FRCLOG		;FORCE THIS STUFF OUT TO LOG
	MOVEI	PT1,[	BYTE(7)CR,FF,TAB,"O","P"
			ASCIZ/SER TRANSACTION LOG

	/]
	PUSHJ	P,MOUT
	MOVE	T3,[-5,,LOGNAM]		;POINTER TO GETTAB NUMBERS
	HRRZI	T2,.GTCNF		;SET UP TO GET SYSTEM NAME
TLOG1:	MOVE	T1,T2			;GET ARGUMENT
	GETTAB	T1,			;GET WORD OF NAME
	  SETZ	T1,			;ERROR RETURN = NULL
	MOVEM	T1,(T3)			;STORE IN BUFFER
	ADD	T2,[1,,0]		;NEXT WORD
	AOBJN	T3,TLOG1		;AND LOOK AT NEXT, IF ANY
	MOVEI	PT1,LOGNAM		;GET POINTER TO BUFFER
	PUSHJ	P,MOUT			;AND OUTPUT IT
	PUSHJ	P,TABOUT		;OUTPUT A TAB
	MOVE	T1,[%CNDT0]		;POINTER TO FIRST WORD OF SYSDAT
	GETTAB	T1,			;GET WORD
	  SETZ	T1,			;ERROR RETURN=NULL
	MOVEM	T1,LOGDAT		;PUT IN BUFFER
	MOVE	T1,[%CNDT1]
	GETTAB	T1,
	  SETZ	T1,
	MOVEM	T1,LOGDAT+1		;SECOND WORD OF DATE
	MOVEI	PT1,LOGDAT
	PUSHJ	P,MOUT
	PUSHJ	P,CRLF
	PUSHJ	P,CRLF
	DATE	T1,			;WHAT'S TODAYS DATE
	IDIVI	T1,^D31			;GET DAY-1 IN T2
	PUSH	P,T1			;SAVE QUOTIENT ON PDL
	MOVEI	T1,1(T2)		;LOAD DAY INTO T1
	PUSHJ	P,DECOUT		;TYPE IN DECIMAL
	POP	P,T1			;RESTORE QUOT
	IDIVI	T1,^D12			;LEAVE MONTH-1 IN T2
	PUSH	P,T1			;SAVE QUOT AGAIN
	MOVE	T1,MONTAB(T2)		;GET SIXBIT TYPOUT
	PUSHJ	P,SIXBP			;SEND THAT
	POP	P,T1			;GET YEAR BACK
	ADDI	T1,^D64			;SUM TO TODAY'S YEAR MOD 100
	PUSHJ	P,DECOUT		;TYPE IN DECIMAL
	PUSHJ	P,TABOUT		;TAB OVER
	PUSH	P,[EXP DSKOUT]		;PUSH ADDR OF ROUTINE
	PUSHJ	P,TIMOUT		;SEND THE CURRENT TIME
	MOVEI	PT1,[ASCIZ/	Job /]
	PUSHJ	P,MOUT			;SEND THAT
	PJOB	T1,			;GET MY JOB NUMBER
	PUSHJ	P,DECOUT		;TYPE IN DECIMAL
	MOVEI	PT1,[ASCIZ/	[/]
	PUSHJ	P,MOUT			;TYPE THAT
	HLRZ	T1,MYPPN		;PUT PROJ IN T1
	PUSHJ	P,OCTOUT		;TYPE IN OCTAL
	PUSHJ	P,COMOUT		;AND A COMMA
	HRRZ	T1,MYPPN		;NOW GET PROGRAMMER NUMBER
	PUSHJ	P,OCTOUT		;TYPE IN OCTAL
	MOVEI	PT1,[ASCIZ/]

/]
	PUSHJ	P,MOUT			;LIST CRLF
	SETZM	FRCLOG			;CLEAR FLAG
	POPJ	P,			;AND RETURN
;
;-----------------------------------------------------------------------
;
;SUBR TO PERFORM LOOKUP,ENTER,USETO SEQUENCE TO APPEND TO FILE

UPDATE:	MOVE	T1,LOGFIL+1		;RETRIEVE FILNAME
	MOVE	T2,LOGFIL+2		;AND EXTENSION
	SETZ	T3,			;ZILCH THAT OUT
	MOVE	T4,LOGFIL+3		;GET PPN
	MOVEI	T5,1			;LOAD DEFAULT USETO BLK
	LOOKUP	LOGC,T1			;TRY TO FIND FILE
	  JRST	DENTER			;NOT THERE - DO ENTER
	HLRE	T3,T4			;GET LENGTH IN T3
	JUMPGE	T3,GBLKN		;JUMP IF BLOCKS GIVEN
	IDIV	T3,[-<DSKSIZ-3>]	;COMPUTE NBR OF BLOCKS
	SKIPE	T4			;SKIP IF NO REMAINDER
	ADDI	T3,1			;WRITE AFTER PARTIALLY USED BLK
GBLKN:	MOVEI	T5,1(T3)		;LOAD LENGTH+1

DENTER:	MOVE	T1,LOGFIL+1		;RELOAD FILNAME
	MOVE	T2,LOGFIL+2		;AND EXTENSION
	SETZ	T3,			;ZERO OUT THAT
	MOVE	T4,LOGFIL+3		;RELOAD PPN
	ENTER	LOGC,T1			;ENTER FILE
	  JRST	NOENT			;CANNOT DO
	OUTPUT	LOGC,			;DO DUMMY LOGOUT
	USETO	LOGC,(T5)		;SELECT BLOCK
	JRST	CPOPJ1			;GIVE SKIP RETURN
NOENT:	PUSHJ	P,CLOSED		;FINISH OFF OLD ONE
	MOVEI	PT1,[ASCIZ/?OPRLEF ENTER failure /]
	PUSHJ	P,MOUT			;TYPE THAT
	PUSHJ	P,LOUD			;TURN ON THE OPERATOR
	HRRZ	T1,T2			;LOAD ERROR CODE INTO T1
	PUSHJ	P,OCTOUT		;AND TYPE IN OCTAL
	JSP	PT1,MOUT		;END WITH THIS MESSAGE
	ASCIZ	/ on LOG file
/


DSKOUT:	TLNN	F,OFILE			;SKIP IF FILE OPENED
	POPJ	P,			;IGNORE CHAR
	SOSLE	LOGOB+2			;SKIP IF BUFFER FULL
	JRST	PUTB9			;MORE ROOM
	PUSHJ	P,SAVACS		;SAVE REGISTERS
	CLOSE	LOGC,			;CLOSE FILE - RETAIN CHANNEL
	PUSHJ	P,UPDATE		;RE-OPEN FILE
	  POPJ	P,			;UNSUCCESSFUL
PUTB9:	IDPB	DATA,LOGOB+1		;STORE IN BUFFER
	POPJ	P,			;RETURN


NOTOUT:	JSP	PT1,MOUT		;TYPE MESSAGE
	ASCIZ	/?OPRDCO Device cannot do output
/
MONTAB:	SIXBIT	/-JAN-/
	SIXBIT	/-FEB-/
	SIXBIT	/-MAR-/
	SIXBIT	/-APR-/
	SIXBIT	/-MAY-/
	SIXBIT	/-JUN-/
	SIXBIT	/-JUL-/
	SIXBIT	/-AUG-/
	SIXBIT	/-SEP-/
	SIXBIT	/-OCT-/
	SIXBIT	/-NOV-/
	SIXBIT	/-DEC-/
>
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	SUBROUTINE TO GET A FILSPEC

;CALLED BY	PUSHJ	P,GETSPC
;		  ERROR
;		NORMAL
;
;ON SUCCESSFUL RETURN, REGISTERS T1 THRU T4 ARE LOADED AS FOLLOWS:
;	T1 = DEVICE SPEC
;	T2 = FILE NAME
;	T3 = EXTENSION
;	T4 = PPN
;IF NO TYPEIN WAS GIVEN FOR A CATEGORY, 0 IS RETURNED IN THE REGISTER

	IFN	FTTLOG!FTAUTO,<
GETSPC:	SETZB	T1,T2			;ZERO OUT ALL TO START
	SETZB	T3,T4
	JUMPL	F,CPOPJ1		;RETURN NOW IF DONE
	PUSHJ	P,SIXIN			;GET SIXBIT WORD
	CAIE	DATA,":"		;SKIP IF DEVICE SPEC
	JRST	NOTDEV			;I GUESS NOT
	MOVE	T1,CMD			;STICK IN APPROPRIATE AC
	PUSHJ	P,SIXIN			;GET NEXT WORD
NOTDEV:	MOVE	T2,CMD			;LOAD FILNAME
	JUMPL	F,CPOPJ1		;RETURN IF DONE
	CAIE	DATA,"."		;SKIP IF EXTENSION
	JRST	MBPPN			;NOPE - MAYBE A PPN
	PUSHJ	P,SIXIN			;LOAD THAT
	HLLO	T3,CMD			;LOAD EXT INTO AC
	JUMPL	F,CPOPJ1		;RETURN IF LINE DONE
MBPPN:	CAIE	DATA,"["		;SKIP IF START OF PPN
	JRST	BADFIL			;BAD FILSPEC
	PUSHJ	P,OCTIN			;GET FIRST NUMBER
	CAIN	DATA,","		;MUST END WITH COMMA
	TLNE	CMD,-1			;AND BE LESS THAN 777777
	JRST	BADFIL			;IT WASN'T
	HRLZ	T4,CMD			;STICK IN LH OF T4
	PUSHJ	P,OCTIN			;GET PROGRAMMER NUMBER
	CAIN	DATA,"]"		;CHECK FOR CLOSE BRACKET
	TLNE	CMD,-1			;AND LT 777777
	JRST	BADFIL			;TYPO
	HRRI	T4,(CMD)		;LOAD INTO RH OF T4
	PUSHJ	P,STTYIN		;GET NEXT NON-BLANK CHAR
	JUMPL	F,CPOPJ1		;IF BREAK CHAR, A.O.K.
BADFIL:	JSP	PT1,MOUT		;TYPE ANNOYING MESSAGE
	ASCIZ	/?OPRBFS Bad file spec
/
>
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	SUBROUTINES
;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSH	P,[ADDR]
;		PUSHJ	P,RUNSUB
;		ALWAYS RETURN
;
; RUNSUB WILL CALL THE SUBROUTINE AT ADDR, AND WILL PERFORM ALL
;MANIPULATIONS OF REGISTER SJB INCLUDING ACTIVITY CHECKS AND
;ALL EXPANSIONS.  IT ENDS BY POPPING THE RETURN PC ONTO THE
;PUSHED ARGUMENT AND POPJ'ING, SO THE CALLER SHOULD NOT DO A
;POP UPON RETURN TO CLEAR THE STACK

RUNSUB:	TRNN	SJB,1B18		;SKIP IF ALL
	JRST	RUNONE			;NOT ALL - JUST ONE ARG
	MOVSI	SJB,NPTLTH		;MAKE AOBJN WORD
RUNSU0:	TDNE	F,USE(SJB)		;SKIP IF THIS ONE'S FREE
	PUSHJ	P,@-1(P)		;PUSHJ TO SUBROUTINE
	  JFCL				;IGNORE ERRORS
	AOBJN	SJB,RUNSU0		;LOOP FOR ALL
	MOVNI	SJB,1			;MAKE ALL AGAIN
	JRST	APOPJ			;CLEAR PDL & RETURN

RUNONE:	TDNN	F,USE(SJB)		;SKIP IF IN USE
	JRST	RUNER1			;NOT - ERROR
	PUSHJ	P,@-1(P)		;CALL SUBROUTINE
	  JFCL				;DON'T CARE ABOUT ERRORS
	JRST	APOPJ			;CLEAR STACK & POPJ

RUNER1:	POP	P,-1(P)
	JRST	NOTACT
;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSH	P,[ADDR]
;		PUSHJ	P,RUNSA
;		ALWAYS RETURN
;
; RUNSA INTERPRETS SUBJOB LISTS IN COMMANDS AND CALLS SERIALLY
;THE SUBRROUTINE AT ADDR.  RUNSA ALSO CLEARS THE STACK OF THE
;PUSHED ARG BEFORE RETURNING.

RUNSA:	PUSHJ	P,WHATJB		;WHAT SUBJOB REF?
	  JRST	APOPJ			;CLEAR STACK AND RETURN
	PUSH	P,-1(P)			;PUT ADDR ON TOP OF STACK
	PUSHJ	P,RUNSUB		;AND CALL RUNSUB
	TLNE	F,WASCOM		;WAS LAST DELIMITER A COMMA
	JRST	RUNSA			;YES, GO GET NEXT ARG
	JRST	APOPJ			;NO, RETURN NOW



;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,CSTOP
;		  HERE IF STOPPED IN ^C
;		HERE IF NOT

CSTOP:	PUSHJ	P,UJBSTS		;GET JOBSTS
	SETCA	T1,T1			;COMPLEMENT RESULT
	TLNE	T1,(JB.UML!JB.UDI)	;SKIP IF BOTH WERE ON
	AOS	(P)			;NOT - INCR RETURN PC
	POPJ	P,			;RETURN
;
;-----------------------------------------------------------------------
;
;SUBROUTINE TO START A LINE

STARTL:	TLNE	F,REPL!AUTOM		;SKIP IF WE MUST
	POPJ	P,
	MOVEI	DATA,"*"
	MOVSI	SJB,NPTLTH		;LOAD AOBJN WORD
STAR1:	TDNN	F,USE(SJB)		;SKIP IF IN USE
	JRST	ESTAR1			;NOT
	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNN	T1,(JB.UDI)		;SKIP IF IN INPUT WAIT
	SKIPA	DATA,["!"]		;LOAD THAT CHAR
ESTAR1:	AOBJN	SJB,STAR1		;LOOP FOR ALL
	PUSHJ	P,TTYOUT		;TYPE IT
	TLO	F,REPL			;REMEMBER I DID
	POPJ	P,			;RETURN
;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSHJ	P,FSUB
;		  NO FREE SUBJOBS
;		HERE WITH NBR OF FREE SJB IN AC-SJB

FSUB:	MOVSI	SJB,NPTLTH		;MAKE AOBJN XWD
FLOOP1:	TDNE	F,USE(SJB)		;SKIP IF FREE
	AOBJN	SJB,FLOOP1		;LOOP FOR ALL
	JUMPGE	SJB,NOFREE		;JUMP IF ALL IN USE
	HRRZ	LASU,SJB		;LOAD AS DEFAULT
	JRST	CPOPJ1			;SKIP BACK



;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	CMD,NNNNN
;		PUSHJ	P,SJBLIM
;		  HERE IF C(CMD) IS NOT A VALID SJB NBR
;		HERE IF OK, WITH SJB LOADED UP FROM CMD

SJBLIM:	JUMPL	CMD,OUTBND		;NO NEGATIVE SJB
	CAILE	CMD,HGHPTY		;SKIP IF UNDER LIMIT
	  JRST	OUTBND			;NOT - PRINT ERROR MESSAGE
	MOVEI	SJB,(CMD)		;LOAD UP SJB
	MOVEI	LASU,(SJB)		;UPDATE LAST USED
	JRST	CPOPJ1			;SKIP BACK



;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSHJ	P,CHKBAT
;		  HERE IF NO BATCON AT USER LEVEL
;		HERE IF OPSER IS RUNNING ONE

CHKBAT:	MOVSI	T1,'B  '		;LOAD NECESSARY MNEMONIC
	MOVSI	SJB,NPTLTH		;MAKE XWD
	CAME	T1,MNEMON(SJB)		;SKIP IF MATCH
	AOBJN	SJB,.-1			;LOOP FOR ALL
	JUMPGE	SJB,CPOPJ		;RETURN IF NO MATCH
	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNE	T1,(JB.UML)		;SKIP IF NOT IN MONITOR MODE
	POPJ	P,			;NOPE
	MOVS	T1,T1			;PUT JOB NUMBER IN LH
	HRRI	T1,.GTPRG		;AND PROGRAM NAME INDEX IN RH
	GETTAB	T1,			;GET FROM MONITOR TABLE
	  POPJ	P,			;STRANGE ERROR
	CAMN	T1,[SIXBIT/BATCON/]	;ACCEPTED NAME FOR BATCH
	AOS	(P)			;GIVE SKIP RETURN
	POPJ	P,			;GO BACK TO CALLER
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVE	CMD,[SIXBIT/WORD/]
;		PUSHJ	P,FINMNE
;		  HERE IF WORD IS NOT IN MNEMONIC TABLE
;		HERE IF IT IS, WITH SJB LOADED
;
;IF C(CMD)=SIXBIT/ALL/, THE SKIP RETURN IS GIVEN WITH C(SJB)=-1

FINMNE:	JUMPE	CMD,NOMNE		;NO NULLS
	CAMN	CMD,[SIXBIT/ALL/]	;SKIP IF NOT ALL
	JRST	SETALL			;IT IS - SET REGISTERS
	MOVSI	SJB,NPTLTH		;MAKE XWD POINTER
	CAME	CMD,MNEMON(SJB)		;SKIP IF MATCH
	AOBJN	SJB,.-1			;LOOP FOR ALL
	JUMPGE	SJB,NOMNE		;JUMP IF NO MATCH AT ALL
	MOVEI	LASU,(SJB)		;UPDATE LAST USED
	JRST	CPOPJ1			;JUMP BACK WITH SKIP

SETALL:	MOVNI	SJB,1			;PUT -1 IN SJB
	TRNN	F,-1			;SKIP IF ANY ARE IN USE
	JRST	ALLFR			;ALL FREE - TELL HIM
	JRST	CPOPJ1			;SKIP BACK



;
;-----------------------------------------------------------------------
;
;CHECKING SUBJOBS FOR OUTPUT

IOCHK:	TLZ	F,PTBSY			;ZERO BIT TO START
	MOVSI	SJB,NPTLTH		;LOAD AOBJN XWD
IOCHK0:	TDNN	F,USE(SJB)		;SKIP IF IN USE
	JRST	ENDIO0			;NOT
	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNE	T1,(JB.UOA)		;SKIP IF OUTPUT IS NOT READY
	  JRST	ENDI.1			;IS SOME, TAKE IT
	TLNN	T1,(JB.UDI)		;JOB IN TI STATE
	  JRST	ENDIO0			;NO, CAN'T BE GONE YET
	JRST	ENDIO1			;YES, SEE IF IT STILL EXISTS
ENDI.1:	TLO	F,PTBSY			;SET FIND BIT
	PUSHJ	P,GBUF			;GO GET BUFFER(S)
ENDIO1:	PUSHJ	P,ISJOB			;SKIP IF JNA STILL SET
	  PUSHJ	P,RPTYN			;GO RELEAS
ENDIO0:	AOBJN	SJB,IOCHK0		;LOOP
	POPJ	P,			;RETURN
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,UJBSTS
;		ALWAYS RETURN
;
;REGISTER T1 IS LOADED WITH JOBSTS

UJBSTS:	MOVEI	T1,(SJB)		;LOAD SUBJOB TO CHECK
	JOBSTS	T1,			;CHECK IT
	  JFCL				;THAT SHOULDN'T HAPPEN
	POPJ	P,			;RETURN



;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,ISJOB
;		  HERE IF JNA OFF FOR THAT SUBJOB
;		HERE IF JNA ON, WITH MJOB LOADED WITH JOBSTS

ISJOB:	MOVE	MJOB,T1			;SAVE C(T1)
	PUSHJ	P,UJBSTS		;GET JOBSTS
	EXCH	MJOB,T1			;GET JOBSTS INTO MJOB
	JUMPL	MJOB,CPOPJ1		;SKIP IF JNA ON
	POPJ	P,			;REGULAR POPJ IF NOT
;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSHJ	P,WHATJB
;		  ERROR
;		NORMAL
;
;CALLED AT EOL SUBJOB REFERENCES

WHATJB:	TLZ	F,WASCOM		;IC'S
	MOVEI	SJB,(LASU)		;START WITH LAST USED
	CAIN 	SJB,1000		;NO CUR SUBJOB FLAG SET?
	JUMPL	F,NOCUR			;YES, ERROR RET IF NO INPUT
	JUMPL	F,CPOPJ1		;SKIP BACK IF NO INPUT
	PUSHJ	P,STTYIN		;GET FIRST NON-BLANK
	CAIN	SJB,1000		;NO CUR SUBJOB FLAG SET?
	JUMPL	F,NOCUR			;YES, ERROR RET IF NO INPUT
	JUMPL	F,CPOPJ1		;REPEAT EOL CHECK
	CAIG	DATA,"9"		;SKIP IF OVER ASCII-9
	CAIGE	DATA,"0"		;SKIP IF OVER ASCII-0
	JRST	ALPHA2			;ALPHABETIC
	PUSHJ	P,DECINZ		;GO GET DECIMAL NUMBER
	CAIN	DATA,","		;SKIP IF NOT TERMED BY COMMA
	TLOA	F,WASCOM		;COMMA - SET BIT
	JUMPGE	F,CMDERR		;IF NOT COMMA, MUST BE EOL
	JRST	SJBLIM			;GO CHECK LIMITS

ALPHA2:	PUSHJ	P,SIXINZ		;GET SIXBIT WORD
	CAIN	DATA,","		;DO ABOVE CHECK
	TLOA	F,WASCOM
	JUMPGE	F,CMDERR
	JRST	FINMNE			;SEARCH MNEMONIC TABLES
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	T1,NBR
;		PUSH	P,[EXP ADDR]
;		PUSHJ	P,TIMOUT
;		ALWAYS RETURN WITH STACK ADJUSTED
;
;TYPES TIME AS LOADED INTO T1 TO OUTPUT ROUTINE AT ADDR

TIMOUT:	MSTIME	T1,			;READ CLOCK
HAVTIM:	MOVEI	T3,3			;WILL TYPE NN:NN:NN
TIME1:	IDIV	T1,DIVTBL-1(T3)		;SPLIT DIGITS DOWN
	PUSH	P,T2			;SAVE REMAINDER
	IDIVI	T1,^D10			;SPLIT INTO 2 DIGITS
	MOVEI	DATA,"0"(T1)		;LOAD FIRST IN ASCII
	PUSHJ	P,@-2(P)		;GO SEND CHAR
	MOVEI	DATA,"0"(T2)		;LOAD SECOND
	PUSHJ	P,@-2(P)		;SEND THAT TOO
	POP	P,T1			;RESTORE REMAINDER
	SOJLE	T3,APOPJ		;JUMP IF DONE
	MOVEI	DATA,":"		;LOAD COLON
	PUSHJ	P,@-1(P)		;DISPATCH
	JRST	TIME1			;SEND THAT

DIVTBL:	DEC	1000,60*1000,60*60*1000
;CONTROL-C INTERCEPT LOGIC

;CALLED BY	PUSHJ	P,INTINI
;		RETURNS HERE WITH TRAP SET
INTINI:	SKIPE	.JBDDT##		;DEBUGGING OPSER?
	POPJ	P,			;YES, DO NOT SET UP ^C TRAP
	MOVEI	T1,INTBLK		;POINT TO INTERCEPT BLOCK
	MOVEM	T1,.JBINT##		;STORE FOR CONKLIN 
	MOVEI	T1,INTRPT		;POINTER TO INTERUPT BLOCK
	MOVEM	T1,INTBLK		;STORE AWAY
	MOVEI	T1,2			;CONTROL C
	MOVEM	T1,INTBLK+1
	SETZM	INTBLK+2		;CLEAR ENABLE FLAGS
	SETZM	INTBLK+3		; ..
	POPJ	P,			;RETURN

;
;-----------------------------------------------------------------------
;
;HERE FROM MONITOR ON A CONTROL-C

;NOW FOLLOWS THE NEW CONTROL/C INTERCEPT CODE, WHICH IS RE-ENTRANT
;AND SHOULD KEEP USERS FROM CONTROL/C'ING OUT OF OPSER ON A SLOW
;SYSTEM.
;
INTRPT:	SETZM	INTBLK+2		;JUST CLEAR THIS WORD, SINCE
					; WE DON'T USE IT AND IT TURNS
					; THE INTERCEPT OFF.
	TLZ	F,RENBIT		;CLEAR SOME BITS
	TLO	F,BRK			;MAKE PTY LOOK DONE
	MOVE	P,[IOWD PDLSIZ,PDL]	;RESET THE STACK
	CLRBFI				;CLEAR ANY TYPE-AHEAD.
	PUSHJ	P,FINISH		;SEE IF WE CAN :EXIT
	JRST	SETUP			;GO BACK AND LISTEN.
					; THE CODE AT SETUP WILL CALL
					; INTINI TO FINISH CLEANING UP
					; AFTER THE INTERCEPT.
;
;-----------------------------------------------------------------------
;
;GET THE UPTIME
;USES T1 AND T2 ANSWER IN T1

GETUPT:	MOVE	T1,[%CNSUP]		;GET SYSTEM UPTIME (7 SERIES)
	GETTAB	T1,			;GET IT
	 CAIA				;FAILED, MUST BE PRE 7 SERIES
	JRST	GETUP1			;GOT TIME, CONVERT IT
	MOVE	T1,[%NSUPT]		;THIS ROUTINE DOES
	GETTAB	T1,			; THE OBVIOUS THING
	  SETZ	T1,			; OF GETTING THE UPTIME
GETUP1:	MULI	T1,^D1000		;THEN CONVERTING TO
	DIV	T1,JIFSEC		;MILLISECONDS.
	POPJ	P,			;RETURN

;
;-----------------------------------------------------------------------
;
JIFINI:	MOVE	T1,[%CNSTS]	;COMPUTE THE NUMBER OF
	GETTAB	T1,			;JIFFIES PER SECOND
	  SETZ	T1,			; ..
	TLNN	T1,(1B6)		;IS THE 50 CYCLE BIT ON?
	SKIPA	T1,[^D60]		;NO--ASSUME 60
	MOVEI	T1,^D50			;YES--ASSUME 50
	MOVEM	T1,JIFSEC		;STORE AWAY
	POPJ	P,

;
;-----------------------------------------------------------------------
;
;SUBROUTINE TO TURN ON TTY OUTPUT
;CALLED BY	PUSHJ	P,LOUD
;		RETURN HERE
;BITS ARE RESTORED BY THE MATCHING POPJ. DO NOT CALL ANY TTY OR PTY
;INPUT ROUTINES WHILE STATUS BITS ARE MESSED UP.
LOUD:	MOVEM	F,SAVEF			;SAVE FLAGS
	TLZN	F,AUTOM!QUIET!AUXQ	;CLEAR SOME BITS
	POPJ	P,			;NONE SET-- JUST GO
	POP	P,(P)			;FIX STACK
	PUSHJ	P,@1(P)			;CALL SUBROUTINE
	  JFCL
	IOR	F,SAVEF			;TURN BITS BACK ON
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	TELETYPE IO SUBROUTINES
;
;-----------------------------------------------------------------------
;
SPOUT:	MOVEI	DATA,SP
	JRST	TTYOUT

COMOUT:	MOVEI	DATA,","
	JRST	TTYOUT

COLOUT:	MOVEI	DATA,":"
	JRST	TTYOUT

TABOUT:	MOVEI	DATA,TAB
	JRST	TTYOUT

TABOU1:	TLNE	F,AUXQ!QUIET!AUTOM	;ECHO TAB?
	JRST	DSKTAB			;FOR :TSILENCE 
	PUSH	P,DATA			;SAVE DATA
	MOVEI	DATA,TAB		;LOAD A TAB
	TLON	F,FREETB		;HAVE WE GIVEN A TAB
	PUSHJ	P,TTYOUT		;PRINT A TAB
	POP	P,DATA			;RESTORE CHAR.

;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	DATA,CHAR
;		PUSHJ	P,TTYOUT
;SUBR WILL ECHO TO LOG FILE

TTYOUT:	TLNE	F,AUTOM!QUIET!AUXQ	;SKIP IF BOTH OFF
	JRST	DSKTST			;FOR :TSILENCE
	PUSHJ	P,DSKOUT		;PUT IN LOG ALSO
	TLZ	F,REPL			;ZERO BIT
	OUTCHR	DATA			;SEND CHAR TO MONITOR
	POPJ	P,			;RETURN

	IFN	FTTLOG,<
DSKTAB:	MOVE	W,SJBFLG(SJB)		;GET FLAGS FOR SUBJOB
	TLNN	W,(TSIL)		;:TSILENCE MODE?
	POPJ	P,			;NO--RETURN
	PUSH	P,DATA			;SAVE CHAR
	MOVEI	DATA,TAB		;PICK UP TAB
	TLON	F,FREETB		;FLAG THE RAB AND GIVE JUST 1
	PUSHJ	P,DSKOUT		;TYPE THE TAB ON THE DISK
	POP	P,DATA			;RESTORE DATA
DSKTST:	SKIPE	FRCLOG		;DO WE WANT TO FORCE THIS INTO LOG?
	JRST	DSKOUT			;YES-- GO LOG IT
	MOVE	W,SJBFLG(SJB)		;GET SUBJOB FLAGS
	TLNN	W,(TSIL)		;:TSILENCE MODE?
	POPJ	P,			;NO--JRST RETURN
	JRST	DSKOUT			;YES--PUT ON DISK
>
	IFE	FTTLOG,<
DSKTAB:
DSKTST:	POPJ	P,
>
;
;-----------------------------------------------------------------------
;
;SUBR TO RETURN NEXT NON-BLANK CHAR

STTYIN:	PUSHJ	P,TTYIN			;GET NEXT CHAR
	CAIN	DATA,SP			;SKIP IF NON-SPACE
	JRST	STTYIN			;GO IGNORE
	CAIN	DATA,TAB		;[122]SKIP IF NON-TAB
	JRST	STTYIN			;[122]GO IGNORE
	POPJ	P,			;RETURN



;
;-----------------------------------------------------------------------
;
;SUBR TO RESCAN TO BEGINNING OF BUFFER

RESCA1:	TLZ	F,BRK			;ZERO BREAK BIT
	PUSH	P,[POINT 7,TTIBUF]	;PUSH ORIGINAL POINTER
	POP	P,TTIPTR		;POP BACK IN PTR SPOT
	POPJ	P,			;RETURN
;
;-----------------------------------------------------------------------
;
;SUBR TO GET NEXT CHAR FROM TTY INPUT BUFFER

TTYIN:	PUSHJ	P,SAVACS		;SAVE REGISTERS
	MOVE	DATA,SAVCH		;LOAD THE SAVED CHAR
	SETZM	SAVCH			;CLEAR THE SAVINGS ACCOUNT
	JUMPN	DATA,CPOPJ		;JUMP IF ANYTHING WAS SAVED
	TLZ	F,REPL			;ZERO BEG OF LINE FLAG
	JUMPGE	F,GETB3			;JUMP IF MORE CHARS LEFT

FILBUF:	MOVEI	T1,LINSIZ		;LOAD SIZE IN BYTES
	MOVE	PT1,[POINT 7,TTIBUF]	;LOAD POINTER TO BEG OF BUF
	MOVEM	PT1,TTIPTR		;STORE FOR LATER USE

FILL1:	SOJL	T1,TOOMCH		;JUMP IF LINE TO LARGE
	PUSHJ	P,GENIN			;LOAD A CHAR
	IDPB	DATA,PT1		;STORE IN BUFFER
	PUSHJ	P,ISBRK			;CHECK IF BREAK CHARACTER
	  JRST	ITIS			;IT IS ONE
	JRST	FILL1			;KEEP LOOPING

TOOMCH:	PUSHJ	P,GENIN			;GET NEXT CHAR
	PUSHJ	P,ISBRK			;CHECK FOR BREAK CHAR
	  SKIPA
	JRST	TOOMCH			;IGNORE ALL NON-BREAK
	MOVEI	PT1,[ASCIZ/?OPRLTL Input line too long
/]
	PUSHJ	P,MOUT			;YELL AND SCREAM AT HIM
	MOVSI	T1,(<LF>B6)		;LOAD LF & NULLS
	MOVEM	T1,TTIBUF		;STORE IN BUFFER
	JRST	GETB3			;PROCEDE

ITIS:	SETZ	DATA,			;MAKE MANY 0 BITS
	IDPB	DATA,PT1		;FORM WONDERFUL ASCIZ STRING
GETB3:	ILDB	DATA,TTIPTR		;GET FROM BUFFER
	JUMPE	DATA,FILBUF		;IGNORE NULLS
	TLO	F,BRK			;SET BREAK BIT
	PUSHJ	P,ISBRK			;SKIP IF NON-BREAK
	  POPJ	P,			;RETURN N

	TLZ	F,BRK			;NOT BREAK
	CAIN	DATA,CTRLA		;SKIP IF NOT ^A
	MOVEI	DATA,CTRLC		;TRANSLATE TO ^C
	CAIN	DATA,CTRLB		;SKIP IF NOT ^B
	MOVEI	DATA,CTRLO		;TRANSLATE TO ^O
	CAIN	DATA,CTRLE		;SKIP IF NOT ^E
	MOVEI	DATA,ALT		;CONVERT TO ESCAPE
	TLNE	F,MSG			;SKIP IF NOT PTY TEXT
	POPJ	P,			;OTHERWISE RETURN NOW

	CAIN	DATA,CR			;SKIP IF NOT CR
	JRST	GETB3			;IGNORE THEM
	CAIL	DATA,140		;SKIP IF UPPER CASE
	SUBI	DATA,40			;TRANSLATE TO UPPER
	CAIN	DATA,TAB		;SKIP IF NOT TAB
	MOVEI	DATA,SP			;MAKE INTO SPACE
	POPJ	P,			;RETURN WITH CHAR
GENIN:	IFN	FTAUTO,<
	TLNN	F,AUTOM			;SKIP IF WE'RE IN AUTO MODE
	JRST	GENIN1			;NOT--SKIP CODE
GENIN2:	SOSG	AUTIB+2			;DDECR COUNT & SKIP IF MORE LEFT
	IN	AUTOC,			;ADVANCE BUFFERS
	JRST	GENIN3			;SKIP THIS CODE
	PUSHJ	P,SAVACS		;SAVE ALL REGISTERS
	GETSTS	AUTOC,T1		;LOAD STATUS INTO T1
	PUSHJ	P,AUTREL		;RELEASE THE CHANNEL
	MOVEI	PT1,[ASCIZ/?OPRAFE AUTO file read error
/]
	TRNN	T1,IO.EOF		;SKIP IF END OF FILE
	PUSHJ	P,MOUT			;TYPE ON CONSOLE
	MOVE	DATA,BRKLST		;LOAD A BREAK CHAR
	JRST	DSKOUT			;SEND TO LOG FILE

GENIN4:	AOS	AUTIB+1			;POINT AT NEXT WORD
	MOVNI	DATA,6			;ADJUST COUNT OF CHARS
	ADDM	DATA,AUTIB+2		; LEFT IN BUFFER
GENIN3:	IBP	AUTIB+1			;POINT TO NEXT BYTE
	MOVE	DATA,@AUTIB+1		;GET NEXT INPUT WORD
	TRZE	DATA,1			;TEST FOR SEQUENCE #
	JRST	GENIN4			;STRIP IT OFF
	LDB	DATA,AUTIB+1		;GET NEXT DATA CHAR
	JUMPE	DATA,GENIN2		;JUMP IF NULL TO NEXT BYTE
	JRST	DSKOUT			;SEND TO LOG
>
GENIN1:	INCHRW	DATA			;LOAD A BYTE
	JUMPE	DATA,GENIN1		;IGNORE NULLS
	JRST	DSKOUT			;SEND TO LOG
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,PUTNAM
;		ALWAYS RETURN
;
;TYPES SUBJOB MNEMONIC, IF ONE, ELSE SUBJOB NUMBER IN DECIMAL

PUTNAM:	SKIPE	T1,MNEMON(SJB)		;LOAD T1 WITH MNEMONIC, IF ANY
	JRST	SIXBP			;TYPE SIXBIT
	MOVEI	T1,(SJB)		;LOAD SUBJOB NUMBER
	JRST	DECOUT			;TYPE IN DECIMAL



;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVE	T1,[SIXBIT/NAME/]
;		PUSHJ	P,SIXBP
;		ALWAYS RETURN
;
;TYPES WORD IN SIXBIT

SIXBP:	MOVE	PT1,[POINT 6,T1]	;LOAD POINTER
SIXBP1:	ILDB	DATA,PT1		;GET FIRST CHAR
	JUMPE	DATA,CPOPJ		;RETURN IF DONE
	ADDI	DATA,40			;MAKE ASCII OF SIXBIT
	PUSHJ	P,TTYOUT		;TYPE IT
	TLNE	PT1,770000		;SKIP IF PTR DONE
	JRST	SIXBP1			;NO - MORE BYTES TO GO
	POPJ	P,			;RETURN



;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	PT1,[ASCIZ/message/]
;		PUSHJ	P,MOUT
;		ALWAYS RETURN
;
;TYPES MESSAGE AT ADDRESS IN RH OF PT1

MOUT:	HRLI	PT1,440700		;MAKE ASCII POINTER
	MOVE	DATA,PT1		;COPY THE POINTER
	ILDB	DATA,DATA		;GET THE FIRST CHARACTER
	CAIN	DATA,"?"		;ERROR MESSAGE
	  PUSHJ	P,LOUD			;YES, FORCE OUTPUT TO THE OPERATOR
MOUT1:	ILDB	DATA,PT1		;LOAD FIRST BYTE
	JUMPE	DATA,CPOPJ		;RETURN IF NULL
	PUSHJ	P,TTYOUT		;TYPE CHAR
	JRST	MOUT1			;GO GET NEXT BYTE

;
;-----------------------------------------------------------------------
;
;SUBR TO TYPE RETURN-LINE-FEED

CRLF:	MOVEI	DATA,CR			;LOAD RETURN
	PUSHJ	P,TTYOUT		;TYPE THAT
	MOVEI	DATA,LF			;LOAD LINE FEED
	JRST	TTYOUT			;TYPE THAT

;
;-----------------------------------------------------------------------
;
;SUBR TO TYPE RETURN-FORM-FEED

CRFF:	MOVEI	DATA,CR			;LOAD RETURN
	PUSHJ	P,TTYOUT		;TYPE THAT
	MOVEI	DATA,FF			;LOAD FORM FEED
	JRST	TTYOUT			;TYPE THAT
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	T1,NBR
;		MOVEI	T3,RADIX
;		PUSHJ	P,NBROUT
;
;TYPES C(T1) IN RADIX IN T3
;CALL DECOUT FOR DECIMAL, OCTOUT FOR OCTAL

OCTOUT:	SKIPA	T3,[10]			;LOAD 10 IN RADIX REGISTER
DECOUT:	MOVEI	T3,^D10			;LOAD DECIMAL 10
NBROUT:	IDIVI	T1,(T3)			;DIVIDE BY RADIX
	HRLM	T2,(P)			;PUT REMAINDER ON PDL
	SKIPE	T1			;SKIP IF DONE
	PUSHJ	P,NBROUT		;KEEP GOING
	HLRZ	DATA,(P)		;RETRIEVE LAST DIGIT
	ADDI	DATA,"0"		;MAKE ASCII OF BINARY
	JRST	TTYOUT			;TYPE ON CONSOLE



;
;-----------------------------------------------------------------------
;
;CALLED BY	PUSHJ	P,SIXIN
;		ALWAYS RETURN
;
;INPUTS SIXBIT WORD FROM TTY
;DELIMITER IS FIRST NON-ALPHANUMERIC CHARACTER

SIXIN:	PUSHJ	P,STTYIN		;GET FIRST NON-BLANK CHAR
SIXINZ:	SETZ	CMD,			;START WITH ZERO
	MOVE	PT1,[POINT 6,CMD]	;LOAD POINTER
SIXI1:	CAIL	DATA,"0"		;SKIP IF TOO SMALL
	CAILE	DATA,"Z"		;FALL THROUGH IF TOO LARGE
	POPJ	P,			;RETURN
	CAILE	DATA,"9"		;SKIP IF NUMERIC
	CAIL	DATA,"A"		;SKIP IF NON-ALPHANUMERIC
	JRST	SIXI2			;GO DEPOSIT
	POPJ	P,			;RETURN
SIXI2:	SUBI	DATA,40			;CONVERT TO SIXBIT
	TLNE	PT1,770000		;SKIP IF POINTER DONE
	IDPB	DATA,PT1		;DEPOSIT INTO REGISTER
	PUSHJ	P,TTYIN			;FETCH NEXT CHAR
	JRST	SIXI1			;GET NEXT CHAR
;
;-----------------------------------------------------------------------
;
;SUBR TO INPUT DECIMAL NBR - RESULT IN REGISTER CMD

DECIN:	PUSHJ	P,STTYIN		;GET FIRST NON-BLANK
DECINZ:	SETZ	CMD,			;START WITH ZERO
DEC1:	CAIL	DATA,"0"		;SKIP IF TOO SMALL
	CAILE	DATA,"9"		;SKIP IF DECIMAL
	POPJ	P,			;RETURN
	IMULI	CMD,^D10		;MULTIPLY BY 10
	ADDI	CMD,-"0"(DATA)		;ADD DIGIT IN
	PUSHJ	P,TTYIN			;GET NEXT CHARACTER
	JRST	DEC1			;LOOP



;
;-----------------------------------------------------------------------
;
;SUBR TO INPUT OCTAL NBR - RESULT IN REGISTER CMD

OCTIN:	PUSHJ	P,STTYIN		;GET FIRST NON BLANK
OCTINZ:	SETZ	CMD,			;START WITH ZERO
OCT1:	CAIL	DATA,"0"		;SKIP IF TOO SMALL
	CAILE	DATA,"7"		;SKIP IF OCTAL
	POPJ	P,			;RETURN
	ASH	CMD,3			;MAKE ROOM FOR DIGIT
	TRO	CMD,-"0"(DATA)		;PUT DIGIT IN
	PUSHJ	P,TTYIN			;GET NEXT CHAR
	JRST	OCT1			;LOOP FOR NEXT
;
;-----------------------------------------------------------------------
;
;RDX60W -- INPUT A RADIX 60 NUMBER FROM COMMAND STRING
;RDX60  -- DITTO (CHARACTER ALREADY IN DATA)
;FORMATS ARE XXYYZZ OR XX:YY:ZZ
;CALL:	PUSHJ	P,RDX60/RDX60W
;	  RETURN IF COMMAND ERROR
;	RETURN WITH WORD IN CMD
;USES T1, T2, T3	UPDATES DATA (SEPARATOR)

RDX60W:	PUSHJ	P,TTYIN			;PRIME THE PUMP

RDX60:	MOVEI	T2,0			;PRESET TEMPORARY RESULT
RDX601:	IMULI	T2,^D100		;ADVANCE TO NEXT RESULT
	JUMPL	F,RDX605		;JUMP IF END OF LINE
	PUSHJ	P,DECINZ		;GET NEXT SUPER-DIGIT
	ADD	T2,CMD			;ADD TO ACCUMULATOR
	CAIE	DATA,":"		;SEE IF MORE TO COME
	JRST	RDX605			;NO--GO CONVERT RESULT
	TLNE	T2,(777B8)		;DON'T ALLOW OVERFLOW
	JRST	BADTIM			;ERROR IF TIME TOO LARGE
	CAIL	CMD,^D60		;DON'T ALLOW GARBAGE IN
	JRST	BADTIM			;ERROR IF DIGIT TOO LARGE
	JUMPL	F,RDX605		;JUMP IF EOL
	PUSHJ	P,TTYIN			;SKIP SEPARATOR
	JRST	RDX601			;LOOP BACK FOR MORE

RDX605:	MOVEI	CMD,0			;CLEAR RESULT
RDX606:	IDIVI	T2,^D100		;SEPARATE TYPEIN
	HRLM	T3,(P)			;STORE LEAST DIGIT AWAY
	SKIPE	T2			;SKIP IF ALL DONE
	PUSHJ	P,RDX606		;IF NOT, DO SOME MORE

	JFCL	17,.+1			;CLEAR OVERFLOW
	HLRZ	T1,(P)			;GET BACK HIGHEST DIGIT
	IMULI	CMD,^D60		;MAKE ROOM IN RESULT
	ADD	CMD,T1			;INCLUDE RESULT
	CAIL	T1,^D60			;SEE IF ERROR
	JRST	BADTIM			;COMPLAIN IF COMPONENT TOO BIG
	JRST	CPOPJ1			;RETURN

BADTIM:	JSP	PT1,MOUT		;COMMAND ERROR
	ASCIZ	/?OPRBTS  Bad time specified
/
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	DATA,CHAR
;		PUSHJ	P,ISBRK
;		  HERE IF BREAK CHAR
;		HERE IF NOT
;
;HARMS NO REGISTERS

ISBRK:	PUSH	P,T1			;SAVE T1
	MOVSI	T1,-BRKLTH		;MAKE XWD OF TBL LENGTH
	CAME	DATA,BRKLST(T1)		;MATCH?
	AOBJN	T1,.-1			;NO, CHECK NEXT ONE
	SKIPL	T1			;SKIP IF MATCH
	AOS	-1(P)			;SKIP RETURN
	POP	P,T1			;RESTORE T1
	POPJ	P,			;RETURN TO CALLER

BRKLST:	EXP	CTRLC,BELL,LF,VT,FF,CTRLZ,ALT	;[121],ALT175,ALT176

	BRKLTH==.-BRKLST
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	PTY IO ROUTINES

;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,IPTY
;		  ERROR
;		SUCCESS
;
;INITS FIRST FREE PTY ON CHANNEL=C(SJB)

IPTY:	SETZB	T2,BLK3			;CLEAR T2, WANT ASCII MODE
	SETO	T1,			;IN CASE GENERIC INIT FAILS
	JRST	ONMO.1			;TRY GENERIC FIRST
ONMORE:	MOVEI	T2,(T1)			;LOAD DIGIT
	CAILE	T2,777			;HIGHEST PTY NUMBER EVER
	  JRST	NOMOR			;WELL, THAT'S IT
	LSHC	T2,-6			;SPLIT DIGITS
	LSH	T2,3			;SHIFT HIGH ORDER LEFT BY 3
	LSHC	T2,3			;SHIFT DOUBLE BACK
	LSH	T2,3			;SHIFT HIGH ORDER LEFT BY 3
	LSHC	T2,3			;SHIFT DOUBLE BACK
	TRO	T2,202020		;MAKE 6BIT
	TRNN	T2,570000		;SKIP IF HIGH ORDER NOT 0
	LSH	T2,6			;SHIFT OUT OF XWD
	TRNN	T2,570000		;SKIP IF HIGH ORDER NOT 0
	LSH	T2,6			;SHIFT OUT OF XWD
ONMO.1:	HRLI	T2,'PTY'		;PUT PTY IN 6BIT IN LH
	MOVEM	T2,BLK3+1		;STORE IN OPEN BLOCK
	JUMPL	T1,ONMO.2		;SKIP IF GENERIC PTY TRY
	DEVCHR	T2,			;FIND OUT ABOUT THIS PTY
	JUMPE	T2,NOMOR		;OUT OF PTY'S IF NON-EXISTANT
	TLNE	T2,(DV.AVL)		;AVAILABLE TO US
	TRNE	T2,DV.ASP		;YES, BUT ALREADY INITED
	AOJA	T1,ONMORE		;TRY AGAIN
ONMO.2:	MOVEI	T2,PTBSIZ		;LOAD SIZE OF BLOCK
	IMULI	T2,(SJB)		;MULTIPLY BY SUBJOB OFFSET
	MOVEI	T3,PTBFS(T2)		;LOAD BUFFERS ADDR INTO T3
	HRLI	T2,PTOB(T2)		;PUT OUTPUT HDR ADDR IN LH
	ADDI	T2,PTIB			;MAKE INPUT HDR ADDR IN RH
	MOVEM	T2,BLK3+2		;STORE IN OPEN BLOCK
	MOVSI	T2,(SJB)		;PUT SUBJOB NBR IN LH
	LSH	T2,5			;SHIFT INTO AC POSITION
	MOVE	T4,T2			;SAVE FOR LATER USE
	IOR	T2,[OPEN BLK3]		;MAKE OPEN INSTRUCTION
	XCT	T2			;INIT PTY
	  AOJA	T1,ONMORE		;TRY NEXT PTY NUMBER

;FALL INTO ONMO.3 ON THE NEXT PAGE
ONMO.3:	TDO	F,USE(SJB)		;SET IN USE BIT
	EXCH	T3,.JBFF		;PUT BUFFER ADDR IN .JBFF
	MOVE	T1,T4			;LOAD SUBJOB IN AC POSITION
	IOR	T1,[OUTBUF 1]		;MAKE OUTBUF UUO
	XCT	T1			;DO IT
	MOVE	T1,T4			;LOAD SUBJOB AGAIN
	IOR	T1,[INBUF 1]		;MAKE INBUF UUO
	XCT	T1			;DO THAT
	MOVEM	T3,.JBFF		;RESTORE .JBFF
	MOVE	T1,T4			;RELOAD SUBJOB
	TLO	T1,(OUTPUT)		;MAKE OUTPUT UUO
	XCT	T1			;DO IT ONCE
	XCT	T1			;ONE MORE TIME
	MOVE	T1,T4			;LOAD AGAIN
	IOR	T1,[STATO IO.DER]	;CHECK FOR DEVICE ERROR
	XCT	T1			;SKIP IF SO
	JRST	CPOPJ1			;NONE - ALL IS FINE
	PUSHJ	P,RPTYN			;RELEASE PTY & SUBJOB
	JSP	PT1,MOUT		;TYPE MESSAGE
	ASCIZ	/?OPRNTD No more tty DDB's
/
;
;-----------------------------------------------------------------------
;
;CALLED BY	MOVEI	SJB,NNN
;		PUSHJ	P,STOPJB
;		  ERROR
;		JOB STOPPED IN ^C STATE

STOPJB:	PUSHJ	P,CSTOP			;SKIP IF NOT STOPPED ALREADY
	  JRST	CPOPJ1			;SKIP BACK IF DONE
STOP.1:	PUSH	P,[EXP MAXCTC]		;PUSH ON LIST
STOP1:	MOVEI	DATA,CTRLC		;LOAD ASCII ^C
	PUSH	P,F			;SAVE FLAGS
	TLZ	F,AUTOM			;CLEAR AUTO COMMAND FLAG
	PUSHJ	P,PTYOUT		;SEND TO SUBJOB
	POP	P,F			;RESTORE FLAGS
	PUSHJ	P,QGBUF			;GET REPLY
	PUSHJ	P,CSTOP			;SKIP IF NO SOAP
	  JRST	XPOPJ1			;DONE - SKIP BACK
	SOSL	(P)			;DECREMENT COUNT
	JRST	STOP1			;STILL TIME
	POP	P,(P)			;CLEAR STACK OF GARBAGE
	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNE	T1,(JB.UJC)		;SKIP IF NO JACCT
	JRST	STUCK			;ANNOUNCE STUCK IN JACCT
	MOVE	T1,[SIXBIT /OPRCMM/]
	PUSHJ	P,QMESG
	JSP	PT1,MOUT
	ASCIZ	/ cannot be put in monitor mode
/
STUCK:	MOVE	T1,[SIXBIT /OPRSWJ/]	;BUZZ WORD
	PUSHJ	P,QMESG			;TYPE IT
	JSP	PT1,MOUT
	ASCIZ	/ is stuck with JACCT on
/
;
;-----------------------------------------------------------------------
;
DUMPT:	MOVEI	T1,PTBSIZ		;GET UNIT SIZE OF PTY BLOCK
	IMULI	T1,(SJB)		;INCR TO THIS PTY'S BLOCK
	MOVE	T1,PTOB(T1)		;LOAD ADDR OF 2ND WORD OF BUFFER
	SKIPN	2(T1)			;SKIP IF ANY DATA IN BUFFER
	POPJ	P,			;RETURN TO CALLER

	IFN	FTAUTO,<
	MOVEI	T2,10			;GIVE IT 8 TRIES
DUMPT1:	TLNN	F,AUTOM			;SKIP IF IN AUTO MODE
	JRST	DUMPT2			;NOT -- GET FROM TTY
	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNE	T1,(JB.UDI)		;WANTS INPUT?
	JRST	DUMPT2			;YES IT DOES
	TLNE	T1,(JB.UOA)		;WANTS TO BARF?
	JRST	[PUSHJ P,GBUF		;TRANSFER THE DATA
		MOVEI T2,10		;START THE COUNT AGAIN AFTER OUTPUT
		 JRST  DUMPT1]		;LOOK FOR MORE
	PUSH	P,T1			;SAVE JOB NUMBER
	MOVEI	T1,SNOOZT		;STANDARD SLEEP TIME
	SLEEP	T1,			;WAIT FOR JOB READY
	POP	P,T1			;RESTORE THE JOB NUMBER
	HRLI	T1,(T1)			;PLACE JOB NUMBER IN LEFT HALF
	HRRI	T1,.GTRTD		;FIND OUT IF THE JOB IS HIBERNATING
	GETTAB	T1,			;FOR TTY INPUT READY
	  JRST	DUMPT2			;WHAT!!!
	TLNN	T1,(1B13!1B14)		;CHECK JOBS HIBER BITS
	  SOJG	T2,DUMPT1		;TRY AGAIN (NOT TOO MANY THOUGH)
>
DUMPT2:	MOVSI	T1,(SJB)		;PUT SUBJOB NBR IN LH
	LSH	T1,5			;SHIFT TO AC POSITION
	TLO	T1,(OUTPUT)		;MAKE OUTPUT UUO
	XCT	T1			;SEND BUFFER
	POPJ	P,			;RETURN



;
;-----------------------------------------------------------------------
;
PTMOUT:	HRLI	PT1,440700		;MAKE ASCII POINTER
PTMOU1:	ILDB	DATA,PT1		;GET A CHAR
	JUMPE	DATA,CPOPJ		;RETURN IF NULL
	PUSHJ	P,PTYOUT		;SEND TO PTY
	JRST	PTMOU1			;LOOP
PTOCT:	IDIVI	T1,8			;BREAK WORD DOWN
	HRLM	T2,(P)			;STORE DIGIT ON PDL
	SKIPE	T1			;SKIP IF DONE
	PUSHJ	P,PTOCT			;GO ON
	HLRZ	DATA,(P)		;RETRIEVE DIGIT
	ADDI	DATA,"0"		;MAKE ASCII OF BINARY

PTYOUT:	MOVEI	T1,PTBSIZ		;GET SIZE OF PTY BLOCK
	IMULI	T1,(SJB)		;COMPUTE OFFSET
	PUSH	P,T1			;SAVE ON PDL
	SOSG	PTOB+2(T1)		;DECR BYTE COUNT
	PUSHJ	P,DUMPT			;FORCE BUFFER
	POP	P,T1			;RESTORE POINTER ADDRESS
	IDPB	DATA,PTOB+1(T1)		;STORE BYTE
	PUSHJ	P,ISBRK			;CHECK IF BREAK CHAR
	  JRST	DUMPT			;IT IS--SEND BUFFER
	POPJ	P,			;RETURN
GBUF:	MOVE	T1,SJBFLG(SJB)		;NOW GET SJB STATUS
	TLNN	T1,(DALSHH)		;:SLOGIN IN PROGRESS?
	JRST	GBUF6			;NO--PROCEED
	PUSHJ	P,UJBSTS		;YES--GET THE JOB STATUS
	TLNN	T1,(JB.ULI)		;LOGGED IN?
	JRST	GBUF6			;NO--CONTINUE
	TLNN	T1,(JB.UOA)		;REAL OUTPUT?
	JRST	GBUF6		;NO--FREE CALL
	MOVSI	T1,(DALSHH)		;YES--CLEAR THE SILENCE BIT
	ANDCAB	T1,SJBFLG(SJB)		; AND RELOAD THE AC
GBUF6:	TLNN	T1,(SHH!DALSHH!ERONLY)	;SKIP IF ANY  BIT ON
	TLZA	F,QUIET			;ZERO BIT OUT
QGBUF:	TLOA	F,QUIET			;JUST SEND TO LOG FILE
	TLO	F,AUXQ			;TURN ON ANOTHER BIT
	SETZM	EAFLAG			;PRENTEND WE ARE NOT IN AUTO MODE
	TLZE	F,AUTOM			;ARE WE IN AUTO MODE?
	SETOM	EAFLAG			;YES--NOTE THAT FACT
	TLZ	F,HEADR			;GIVE A HEADER
	PUSH	P,[EXP MOSTBF]		;PUSH MAX NBR OF BUFFERS
	MOVEI	T1,PTBSIZ		;LOAD SIZE OF UNIT BLOCK
	IMULI	T1,(SJB)		;INCR TO THIS SUBJOB
	MOVEI	T2,PTIB+1(T1)		;LOAD BYTE POINTER ADDR INTO T2
	PUSH	P,T2			;STACK IT
	MOVEI	T1,PTIB+2(T1)		;LOAD BYTE COUNT ADDR INTO T2
	PUSH	P,T1			;STACK THAT TOO
	TLO	F,LCR!NOREP		;INITIAL FLAGS

GBUF1:	PUSH	P,[EXP CHANCE]		;STORE NBR OF TRIES
	SOSGE	-3(P)			;DECR COUNT & SKIP IF OK
	JRST	MCR			;HE LOSES

GBUF2:	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNN	T1,(JB.UOA)		;SKIP IF OUTPUT READY
	JRST	DECRL			;COUNTDOWN
	HRLZ	T1,SJB			;GET SJB NBR IN LH
	LSH	T1,5			;SHIFT TO AC POSITION
	TLO	T1,(INPUT)		;MAKE INPUT UUO
	XCT	T1			;EXECUTE IT
	SKIPG	@-1(P)			;SKIP IF BYTE COUNT POSITIVE
	JRST	DECRL			;FALSIE BITSY
GBUF4:	SOSL	@-1(P)			;SKIP IF BUFFER EMPTY
	JRST	GBUF5			;HOP OVER SOME CODE
	POP	P,(P)			;POP CHANCE OFF STACK
	JRST	GBUF1			;RESTART
GBUF5:	ILDB	DATA,@-2(P)		;GET BYTE
	JUMPE	DATA,GBUF4		;IGNORE NULLS
	CAIN	DATA,EOT		;AND ^D'S
	JRST	GBUF4			;......

	PUSHJ	P,ISBRK			;IS IT A BREAK CHAR?
	  JRST	NOCHNG			;YES--SKIP CODE
	TLNN	F,LCR			;SKIP IF LAST CHAR A CR
	JRST	END5			;HOP OVER SOME CODE
	CAIN	DATA,CR			;SKIP IF NOT ANOTHER CR
	JRST	GBUF4			;IT IS--IGNORE IT
	PUSH	P,DATA			;SAVE THE CHARACTER
	MOVEI	T1,BELL			;LOAD A BELL
	EXCH	DATA,T1			;PLACE IN RIGHT AC
	TLZ	F,FREETB		;CAUSE A TAB TO HAPPEN
	CAIE	T1,"%"
	CAIN	T1,"?"
	PUSHJ	P,CHKWRN		;SEND DING TO TTY
	POP	P,DATA			;RESTORE CHARACTER
END5:	CAIN	DATA,CR			;SKIP IF NOT CR
	TLOA	F,LCR			;A CR!
	TLZ	F,LCR			;ZILCH BIT
NOCHNG:	CAILE	DATA,41			;BIGGER THAN A SPACE
	PUSHJ	P,HEAD0			;YES--DO ALL GOOD THINGS
	PUSHJ	P,TABOU1		;SEND THE CHARACTOR
	CAIE	DATA,LF			;IS THIS A LINE FEED?
	JRST	GBUF4			;NO--GET THE NEXT ONE
	TLO	F,AUXQ			;YES--START BEING QUIET
	MOVE	DATA,SJBFLG(SJB)	;LOOK AT THE SUBJOB FLAGS
	TLNE	DATA,(ERONLY)		;WANT ONLY ERROR LINES
	  TLO	F,QUIET			;YES, RESET QUIET BIT
	JRST	GBUF4			;RESUME READING


DECRL:	SOSLE	(P)			;DECR COUNT
	JRST	TIMLFT			;TIME STILL LEFT
MCR:	SUB	P,[4,,4]		;DISHONESTLY POP 4 MJOBS
	PUSHJ	P,CRLF			;TYPE CR-LF
	TLZ	F,QUIET!AUXQ		;INSURE LOAD MODE BACK ON
	SKIPE	EAFLAG			;IN AUTO MODE?
	TLO	F,AUTOM			;YES--RELIGHT THE BIT
	POPJ	P,			;RETURN TO CALLER

TIMLFT:	PUSHJ	P,UJBSTS		;GET JOBSTS
	TLNE	T1,(JB.UDI)		;IS JB.UDI ON?
	JRST	GBUF2			;YES--BE DONE WITH IT
	MOVEI	T1,SNOOZT		;LOAD ONE
	SLEEP	T1,			;SLEEP FOR A WHILE
	JRST	GBUF2			;CONTINUE
RPTY:	PUSHJ	P,STOPJB		;STOP THAT JOB!
	  POPJ	P,			;LOSE
	PUSHJ	P,ISJOB			;SKIP IF JNA ON
	  JRST	RPTYN			;NOT--JUST RELEASE CHANNEL
	MOVEI	PT1,LGOMSG		;LOGOUT MESSAGE
	MOVE	T1,[%CNST2]		;[126]SEE IF ON GALAXY-10
	GETTAB	T1,			;[126]GET 2ND CONFIG TABLE WORD
	  SETZ	T1,			;WHOOPS, NOT EVEN 6.02
	TRNE	T1,ST%GAL		;[127]IF BIT IS ZERO, NORMAL MPB
	  MOVEI	PT1,GALMSG		;GET LOGOUT V100 STRING
	PUSHJ	P,PTMOUT		;SEND MESSAGE
RPTY.1:	PUSHJ	P,QGBUF			;GET REPLY
	PUSHJ	P,UJBSTS		;GET JOBSTS OF PTY
	JUMPGE	T1,RPTYN		;RETURN PTY IF JOB IS GONE
	TLNN	T1,(JB.UDI)		;WANT INPUT
	  JRST	RPTY.1			;NO, LOOK AGAIN
	MOVE	T1,[SIXBIT/OPRCKJ/]	;PREFIX
	PUSHJ	P,QMESG			;RING THE BELL, TYPE SUBJOB NUMBER
	JSP	PT1,MOUT		;TYPE STRING AND RETURN
	ASCIZ/ cannot be KJOB'ed
/

RPTYN:	SETZM	MNEMON(SJB)		;CLEAR MNEMONIC
	SETZM	SJBFLG(SJB)		;CLEAR FLAGS
	TDZ	F,USE(SJB)		;CLEAR IN USE FLAG
	MOVSI	T1,(SJB)		;LOAD INTO LH
	LSH	T1,5			;SHIFT INTO AC POSITION
	TLO	T1,(RELEAS)		;MAKE RELEASE UUO
	XCT	T1			;GET RID OF PTY
	POPJ	P,			;RETURN TO CALLER

LGOMSG:	ASCIZ	\DEASSI
KJOB OPRKJO.LOG=/W/B/Z:0/VD:P
\
GALMSG:	ASCIZ	\DEASSI
KJOB/BATCH/NOMESSAGES
\

CHKWRN:	TLZ	F,AUXQ			;CLEAR THE AUX FLAG
	PUSHJ	P,TTYOUT		;GIVE A DING
	TLO	F,AUXQ			;PUT THE BIT BACK ON
CHKERR:	MOVE	T2,SJBFLG(SJB)		;GET THE FLAGS
	TLNN	T2,(DALSHH)		;FORCE IF HERE DURING :SLOG
	TLNE	T2,(ERONLY)		;DOES HE WANT ERRORS
	TLZ	F,QUIET			;YES MAKE NOISE
	PUSHJ	P,HEAD0			;GIVE A HEADER
	JRST	TTYOUT			;GO PRINT
HEAD0:	TLZN	F,AUXQ			;ARE WE QUIET
	POPJ	P,			;NO WE WERE REVIVED
HEAD:	TLOE	F,HEADR			;HAVE WE GIVEN A HEADER
	POPJ	P,			;GAVE ONE
	PUSH	P,DATA			;SAVE DATA
	PUSH	P,[EXP TTYOUT]		;STORE ADDR OF OUTPUT ROUTINE
	PUSHJ	P,TIMOUT		;TYPE CURRENT TIME
	MOVEI	DATA,"("		;OPEN PARENS
	PUSHJ	P,TTYOUT		;SENT
	PUSHJ	P,PUTNAM		;NAME OF SUBJOB
	CAIN	LASU,(SJB)		;LAST IN LAST OUT?
	JRST	GBUF3			;YES--PROCEED
	MOVEI	DATA,"\"		;LOAD A BACKSLASH
	PUSHJ	P,TTYOUT		;SEND TO TTY
	EXCH	SJB,LASU		;GET RIGHT SUBJOB
	PUSHJ	P,PUTNAM		;SEND HIS NAME OUT
	EXCH	SJB,LASU		;GET OTHER ONE BACK
GBUF3:	MOVEI	PT1,[ASCIZ/)
/]
	PUSHJ	P,MOUT			;PRINT THE HEADER
	PUSHJ	P,TABOU1		;GIVE A TAB
	POP	P,DATA			;RESTORE DATA
	POPJ	P,			;RETURN
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	ERROR MESSAGE SUBROUTINES

QMESG:	PUSHJ	P,CRLF			;TYPE A CRLF
	MOVEI	DATA,"?"		;THEN A QM
	PUSHJ	P,TTYOUT
	PUSHJ	P,SIXBP			;THEN THE WORD
	MOVEI	PT1,[ASCIZ/ Subjob /]	;LOAD ADDR OF THAT MESG
	PUSHJ	P,MOUT			;TYPE ON CONSOLE
	JRST	PUTNAM			;TYPE ITS NAME

ALLFR:	HRRI	LASU,0			;MAKE LASU THE INITIAL VALUE.
	JSP	PT1,MOUT
	ASCIZ	/?OPRNAS No active subjobs
/
CMDERR:	JSP	PT1,MOUT
	ASCIZ	/?OPRCME Command error
/
NOALL:	JSP	PT1,MOUT
	ASCIZ	/?OPRCUA Cannot use all
/
NOBE:	JSP	PT1,MOUT
	ASCIZ	/?OPRNSD No such device
/



NOCUR:	JSP	PT1,MOUT
	ASCIZ	/?OPRNCS NO CURRENT SUBJOBS
/
NOFREE:	HRRI	LASU,1000		;SET NO CUR SUBJOBS FLAG
	JSP	PT1,MOUT
	ASCIZ	/?OPRNFS No free subjobs
/
NOINTX:	JSP	PT1,MOUT
	ASCIZ	/?OPRCOD cannot open device
/
NOMNE:	JSP	PT1,MOUT
	ASCIZ	/?OPRNSM No such mnemonic
/
NOMOR:	SKIPG	T1
	AOJA	T1,ONMORE
	JSP	PT1,MOUT
	ASCIZ	/?OPRNFP No free PTY's
/
NOTACT:	MOVE	T1,[SIXBIT /OPRSNA/]	;KEY WORD
	PUSHJ	P,QMESG
	JSP	PT1,MOUT
	ASCIZ	/ is not active
/
NOTLOG:	JSP	PT1,MOUT
	ASCIZ	/?OPRJNA No job number assigned
/
NORUN:	JSP	PT1,MOUT
	ASCIZ	/?OPRCPU No runnable CPU's in specification
/
NOPRIV:	JSP	PT1,MOUT
	ASCIZ	/?OPROOC OPR only command.
/
ONLY1:	TLNN	F,WASCOM
	POPJ	P,
	JSP	PT1,MOUT
	ASCIZ	/[Will only use first argument]
/
OUTBND:	JSP	PT1,MOUT
	ASCIZ	/?OPRNSS No such subjob
/
TOOFEW:	JSP	PT1,MOUT
	ASCIZ	/?OPRTFA Too few arguments
/
CHKDAE:	CAMN	T1,[2,,T2]
	JRST	NODAEM
	JSP	PT1,MOUT
	ASCIZ	/?OPRDUE DAEMON UUO Error
/

NODAEM:	PJOB	T1,
	WAKE	T1,
	  POPJ	P,
	TLO	F,SLEEPR
	JSP	PT1,MOUT
	ASCIZ	/%OPRDNR DAEMON not running
/

PACF:	ASCIZ	/[OPRPAF Processing auto command file]
/

ATL5:	ASCIZ	/%OPRFMM :KSYS has a minimum of 5 min.
/

CNTCON:	JSP	PT1,MOUT
	ASCIZ	/?OPRCON  Can't continue
/

PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	JUNK AREA

SAVACS:	EXCH	T1,(P)
	PUSH	P,T2
	PUSH	P,T3
	PUSH	P,T4
	PUSH	P,T5
	PUSH	P,PT1
	PUSHJ	P,(T1)
	  SKIPA
	AOS	-6(P)
	POP	P,PT1
POPALL:	POP	P,T5
	POP	P,T4
	POP	P,T3
	POP	P,T2
	POP	P,T1
	POPJ	P,


APOPJ1:	AOS	(P)
APOPJ:	POP	P,-1(P)
	POPJ	P,


XPOPJ1:	AOS	-1(P)
XPOPJ:	POP	P,(P)
	POPJ	P,


CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,



	ZZ==1
USE:	REPEAT	HGHPTY+1,<
	EXP	ZZ
	ZZ==ZZ_1
>
	XLIST	;LITERALS
	LIT
	LIST
PAGE
;
;-----------------------------------------------------------------------
;
SUBTTL	LOW SEGMENT BLOCKS

	RELOC				;SWITCH TO LOSEG

LOWBEG:

INTBLK:	BLOCK	4		;BLOCK FOR CORTROL-C TRAP
MAXJOB:	BLOCK	1		;MAX # OF JOBS
LINO:	BLOCK	1		;LINE #
JBCNT:	BLOCK	1		;JOB COUNT
JOBNO:	BLOCK	1		;JOB NUMBER
JIFSEC:	BLOCK	1		;JIFFIES PER SECOND
EAFLAG:	BLOCK	1		;AUTO MODE FLAG
SAVEF:	BLOCK	1		;SAVE AREA
KSYNC:	BLOCK	1		;SYNC FOR KSYS
KSYPTY:	BLOCK	1		;SUBJOB FOR KSYS
SAVKJB:	BLOCK	1		;SAVE GETTAB STUFF FOR KSYS
MYPPN:	BLOCK	1		;PPN OF OPSER
OPRPPN:	BLOCK	1		;PPN OF SYSTEM [OPR]
SAVCH:	BLOCK	1		;SAVED CHARACTOR
KSYFLG:	BLOCK	1		;KSYS MSG FLAG
KSYMSG:	BLOCK	LINSIZ/5	;KSYS MESSAGE BUFFER
WARNTM:	BLOCK	1		;@ TO WARNTB
BLK3:	BLOCK	3		;GENERAL OPEN BLOCK
PTY0LN:	BLOCK	1		;LINE NUMBER OF PTY0
DGTCNT:	BLOCK	1		;FOR COUNTING DIGITS
PDL:	BLOCK	PDLSIZ		;PUSHDOWN LIST
TCONLN:	BLOCK	1		;CTY LINE NUMBER
TTIBUF:	BLOCK	LINSIZ/5+1	;INPUT BUFFER
TTIPTR:	BLOCK	1		;POINTER TO IT

SJBFLG:	BLOCK	HGHPTY+1	;SUBJOB FLAGS
MNEMON:	BLOCK	HGHPTY+1	;FOR MNEMONICS


;***** DO NOT SEPARATE THE FOLLOWING *****
PTIB:	BLOCK	3		;INPUT BUFFER
PTOB:	BLOCK	3		;OUTPUT BUFFER
PTBFS:	BLOCK	PTYSIZ*2	;TWO OF THEM

	PTBSIZ==.-PTIB

	BLOCK	<3+3+PTYSIZ*2>*HGHPTY

;***** END OF DO NOT SEPARATE BLOCK *****
	IFN	FTTLOG,<

FRCLOG:	BLOCK	1		;SET NON-ZERO TO FORCE THINGS INTO THE LOG
LOGNAM:	BLOCK	5		;SYSTEM NAME FROM .GTCNF
LOGDAT:	BLOCK	2		;SYSTEM CREATION DATE FROM .GTCNF
LOGFIL:	BLOCK	4		;REMEMBER LOG FILE SPECS
LOGOB:	BLOCK	3		;BUFFER HEADER
LOGOBB:	BLOCK	DSKSIZ		;ONE BUFFER
>
	IFN	FTAUTO,<
AUTIB:	BLOCK	3		;BUFFER HEADER
ATOTIM:	BLOCK	1
ATOT1:	BLOCK	1
ATOT2:	BLOCK	1
ATOT3:	BLOCK	1
ATOT4:	BLOCK	1
ATOT5:	BLOCK	1
>


	LOWEND==.-1
	END	OPSER