Google
 

Trailing-Edge - PDP-10 Archives - bb-k345a-sb - script.mac
There are 5 other files named script.mac in the archive. Click here to see a list.
TITLE	SCRIPT  --  FOLLOWS A SCRIPT ON N PSEUDO TTY'S -- V016
SUBTTL	TONY LAUCK/PFC/SML/CDO		2 FEB 79

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1977,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	VSCRIP==016
	VEDIT==102
	VUPDATE==0
	VCUSTOM==0
	MLON

	;GLOBAL AC'S
	F=0		;FLAGS
	I=1		;PROCESS NUMBER AND PTY SOFTWARE CHAN
	N=2		;HIGHEST PROCESS NUMBER
	T=3		;LAST TIME OF DAY (MS)
	X=4		; NEXT EVENT TIME
	A=15		;NUMBER OF ACTIVE PROCESSES
	D=16		;IMPURE AREA BASE ADDRESS
	P=17		;PUSH DOWN POINTER
	;THE FOLLOWING NAMES ARE USED BY THE APPEND ROUTINE
	$S=0		;STACK POINTER
	$B=1		;BASE OF THE STACK
	$F=2		; REFERENCES FORMALS AND LOCALS
	$V=3		;VALUE REGISTER



	;AC'S AVAILABLE FOR PROCESS USE
	AC1=5
	AC2=6
	AC3=7
	AC4=10

	T1=11
	T2=12
	T3=13
	T4=14



	;OPTIONS

	IFNDEF	DEBUG,<DEBUG==1>	;INCLUDE DEBUGGING HACKS
	IFNDEF	CYCLSW,<CYCLSW==1>	;CYCLE CHANGES
	IFNDEF	HUWSW,<HUWSW==0>	;HOLDUP CHANGES

	;FLAGS IN F   RIGHT HALF  USED GLOBALLY

	F.LF==1		;LINE FEED SEEN LAST
	F.XCM==2	; ! SEEN ONCE AT START OF LINE
	F.SCN==4	; ; SEEN IN COMMAND LINE (DOUBLE ; DURING SCRIPT LOADING)
	F.WCH==10	;RESET IF NO PROCESS TO BE WATCHED
	F.RSP==20	;RESET IF NO PROCESS TO BE LOGGED FOR RESPONSE TIMES
	F.ERR==40	;MONITOR OUTPUT FOR ERRORS
	F.TTMN==100	;THE MONITOR DEVICE IS A TTY
	F.LZR==200	;PRINT LEADING ZEROS IF SET
	F.SSY1==400	;SLEEP SYNC -- PROCESS WAITING FOR RESPONSE
	F.SSY2==1000	;SLEEP SYNC -- PROCESS WOKEN BY RESPONSE
	F.SSY3==2000	;SLEEP SYNC -- WOKE UP AT T .GE. X
	F.SCN1==4000	; ; SEEN (LOAD)
	F.PCN==10000	; % SEEN (LOAD)
	F.SLF==20000	;SUPPRESS NEXT CHAR IF LF (LOAD)
	F.MCR==4000	;MONITOR OUTPUT C.RET. LAST (RUNNING)
	F.MLF==10000	;MONITOR OUTPUT L.FEED LAST (RUNNING)
	F.CTO==20000	;RECIEVE COMMENTS TO OPERATOR
	F.JST==40000	;JOBSTS UUO AVAILABLE IN THIS MONITOR
	F.DBG==100000	;DEBUG OUTPUT REQUESTED
IFN CYCLSW,<
	F.CYC==400000	;CYCLE MODE
	F.DOZ==200000	;SIGNAL TO SLEEP UNTIL NEXT TIME MARK
>
IFN HUWSW,<
	F.HUW==400000	;HOLDUP MODE(RUNNING)
>

	;FLAGS IN F  LEFT HALF   USED TEMORARILY BY A PROCESS

	P.LF==1		;LINE FEED SEEN LAST
	P.XCM==2	; ! SEEN ONCE AT START OF LINE
	P.DSH==4	; - SEEN
	P.NIP==10	;NUMBER BEING DECODED
	P.NRD==20	;NUMBER READY
	P.NONG==40	;LETTER COMMAND CAN NOT USE NEG ARG
	P.ARR==100	; ^ SEEN IN COLUMN 1 OF TEXT LINE (SET FOR COL. 2 ONLY)
	P.ARRL==200	; ^ SEEN IN COLUMN 1 OF TEXT LINE (SET FOR ENTIRE LINE)
	P.FACT==400	;MULTIPLY NUMBER BY FACTOR
	P.CTO==1000	;COMMENT TO OPERATOR
	P.SPL==2000	;SPECIAL HANDLING CODES
	P.WCHALL==4000	;SET IF ALL LINES TO BE WATCHED
	P.RSPALL==10000	;SET IF ALL LINES TO BE LOGGED FOR RESPONSE TIMES
	P.MULT==20000	;SET IF IN "MULTI-SCRIPT" MODE
	F.OLD==20000	;SET IF AN OLD BATCH JOB IS USING SCRIPT
	F.DWCH==40000	;SET IF WATCHING ON DEVICE DSK

	;FLAGS IN PFLAGS(D)   R.H. PERMANANT FOR EACH PROCESS

	P.LMOD==1	;PASS CR LF TO USER IF CLEAR
	P.UMOD==2	;CONVERT # INTO UNIT NUMBER IF SET
	P.MSYN==4	;OUTPUT SENT TO PTY, NO CHARS BACK YET
	P.OLD==10	;SET IF PROCESS ALREADY ACTIVE
	P.INT==20	;INTERRUPT ^C'S WERE SENT
	P.SSY==40	;LOST PT WAKE LIKELY
	P.ERR==100	;CURRENTLY IN AN ERROR LINE
	P.NFIR==200	;NEXT CHARACTER RECIEVED WILL NOT BE THE FIRST IN A LINE
	P.NNEW==400	;NOT NEW LINE OF PROCESS MONITORING
	P.QOK==1000	;QUESTION MARK RESPONSE OK
	P.FINT==2000	;FORCED INTERRUPT REQUESTED
	P.WCH==4000	;SET IF THIS PROCESS IS TO BE WATCHED
	P.RSP==10000	;SET IF THIS PROCESS IS TO BE LOGGED FOR RESPONSE TIMES

	JOBVER==137
	INTERN	JOBVER
	EXTERN	.JBSA,.JBFF,.JBHRL,.JBREN

	TWOSEG
	LOC	JOBVER
	<VCUSTOM>B2+<VSCRIP>B11+<VUPDATE>B17+VEDIT
	RELOC	400000



	;TTCALL UUO'S
	OPDEF	OUTCHR [TTCALL 1,]	;OUTPUT A CHARACTER
	OPDEF	OUTSTR [TTCALL 3,]	;OUTPUT A STRING
	OPDEF	INCHWL [TTCALL 4,]	;INPUT A CHARACTER & WAIT (LINE MODE)
	OPDEF	SKPINL [TTCALL 14,]	;CHECK FOR TTY INPUT


	;TTY CHARACTERS

	CONTC==3		;^C
	BEL==7			;BELL
	HT==11			;TAB
	LF==12			;LINE FEED
	VT==13			;VERTICAL TAB
	FF==14			;FORM FEED
	CR==15			;CARRIAGE RETURN
	CONTZ==32		;^Z
	ALT33==33		;ALTMODES OF VARIOUS FLAVORS
	ALT175==175
	ALT176==176
	RUBOUT==177		;RUBOUT

	;CONSTANTS

	NMAX==^D511		;MAX NUMBER OF PTY'S USED BY ONE PGM
	ERRORS==740000		;MASK FOR I/O ERRORS
	BUFSIZ==1600		;MINIMUM BUFFER SIZE FOR SCRIPT
	MAXSLP==^D5000		;LONGEST SLEEP PERIOD IS 5 SECONDS

	;SOFTWARE CHANNELS

	SCHN==1			;USED TO READ IN SCRIPT
	LOGCHN==16		;USED TO LOG RESULTS
	MONCHN==17		;USED TO WATCH RESULTS ON DEVICE TTY


	;PTY STATUS BITS

	MONMOD==1000		;IN MONITOR MODE.
	DOINP==2000		;PTY WANTS TO HAVE INPUT UUO DONE
	DOOUT==4000		;PTY WANTS TO HAVE OUTPUT UUO DONE


	;JOB STATUS UUO DEFINITION

	OPDEF	JOBSTS	[CALLI 61]

	;BITS IN LH----RH HAS JOB NUMBER

	JSTJAC==10000		;JACCT SET
	JSTNCC==10000		;CONTROL C WILL BE TRAPPED
	JSTOUT==20000		;PTY WANTS TO HAVE OUTPUT UUO DONE
	JSTINP==40000		;PTY WANTS TO HAVE INPUT UUO DONE
	JSTMON==100000		;IN MONITOR MODE
	JSTLOG==200000		;LOGGED IN (NOT STARTED LOGOUT)
	JSTJNA==400000		;JOB NUMBER ASSIGNED


	;DEVCHR BITS

	DEVDIR==4		;LEFT HALF -- DEVICE HAS A DIRECTORY
	DEVTTY==10		;LEFT HALF -- DEVICE IS A TTY
	DEVAVL==40		;LEFT HALF -- DEVICE IS AVAILABLE TO US
	DEVINI==200000		;RIGHT HALF-- DEVICE IS INITTED
	DEVDSK==200000		;LEFT HALF -- DEVICE IS DSK

	;FILOP. STUFF

	OPDEF	FILOP.	[CALLI 155]
		.FOSAU==4	;SINGLE ACCESS UPDATE (OPEN)
		.FOINP==17	;INPUT
		.FOOUT==20	;OUTPUT
		.FOREL==23	;RELEASE


	;MACROS

	;DO(FOO) PERFORMS I/O OPERATION OVER THE CURRENT PTY
	;IF FOO IS NULL, THE OPERATION MUST ALREADY BE SETUP IN T4

	DEFINE	DO (A),<
	XLIST
	CAIGE	I,^D14			;;USE OLD UUOS FOR CHANNELS 0-15
	JRST	[MOVSI T4,(A)		;;GET OPCODE
		 DPB I,[POINT 4,T4,12]	;;INSERT CHANNEL NUMBER (0-15)
		 XCT T4			;;DO THE OPERATION
		 JRST .+7]		;;RESUME INLINE
	HRLZ	T4,CHNNUM(I)		;;GET CHANNEL NUMBER ASSIGNED
	HRRI	T4,.FO'A		;;APPEND FUNCTION
	MOVEM	T4,FOPTMP		;;SAVE IN A TEMP
	MOVE	T4,[1,,FOPTMP]		;;POINT TO IT
	FILOP.	T4,			;;EXECUTE THE FUNCTION
	  JFCL				;;FAILED, WHO CARES
	LIST
>

	;JOBST (FOO) PERFORMS A JOBSTATUS UUO TO AC FOO
	;THE JOB STATUS BLOCK IS UPDATED

	DEFINE	JOBST (A),<
	MOVE	A,CHNNUM(I)	;;GET CHANNEL NUMBER
	JOBSTS	A,		;;GET JOB STATUS FROM MONITOR
	  HALT	.+1		;;FAIL SO GIVE UP
	IFN	DEBUG,<IFE A-T1,<PUSHJ P,OUTSTS>>
	MOVEM	A,JOBSB(I)	;;REMEMBER FOR CONDITIONAL SLEEP UUO
>


	;PJRST IS USED INSTEAD OF PUSHJ, POPJ

	OPDEF	PJRST [JRST]

	SUBTTL	INITIALIZATION
BEGIN:	HLLZS	.JBREN		;CLEAR REENTER ADDRESS
	RESET			;RESET
	MOVEI	17,1		;ZERO AC'S
	SETZM	0
	BLT	17,17
	MOVE	T1,[XWD BLOW,BLOW+1]	;ZERO LOW CORE
	SETZM	BLOW
	BLT	T1,EZER-1

	MOVE	P,[IOWD PDLEN,PDLIST]	;SET UP PUSH DOWN LIST

	TRO	F,F.JST		;CHECK FOR JOB STATUS UUO
	SETO	T1,		;(ON JOB 1)
	JOBSTS	T1,
	  TRZ	F,F.JST		;NO--CLEAR FLAG

	SUBTTL	LOADING OF SCRIPT
	SKIPE	NAME		;SEE IF WE HAVE A SCRIPT LOADED
	JRST	NAMED		;YES
	OUTSTR	[ASCIZ /No script/]
	JRST	CHKSCP		;SEE IF USER WANTS TO LOAD?
NAMED:	OUTSTR	[ASCIZ /Script /]
	MOVE	T2,NAME		;TYPE FILE NAME
	PUSHJ	P,TYPSIX
	OUTSTR	[ASCIZ /./]
	MOVE	T2,NAME+1	;TYPE EXTENSION
	PUSHJ	P,TYPSIX
	SKIPE	T2,NAME+2	;TYPE VERSION
	OUTSTR	[ASCIZ /%/]
	PUSHJ	P,TYPSIX

CHKSCP:	OUTSTR	[ASCIZ / loaded
/]
	HRROI	T1,14		;SEE IF OUR HI-SEG IS SHARABLE
	GETTAB	T1,		;LOOK AT JBTSGN
	HALT	.+1		;ERROR IF NOT DEFINED
	SKIPE	NAME		;YES--SEE IF A SCRIPT ALREADY HERE
	JRST	ASKNUM		;YES--OK TO PROCEED
	JRST	ASKSCP		;NO, SO GET NAME FROM USER


ASKSCP:	MOVE	T1,.JBFF	;SAVE .JBFF
	MOVEM	T1,SVFF
	OUTSTR	[ASCIZ /Where to load a script? /]
	MOVSI	AC3,(SIXBIT /DSK/)	;YES,ASK FOR FILE
	MOVSI	AC2,(SIXBIT /SCP/)
	PUSHJ	P,GETFIL	;GET FILE ARGS
	  JRST	ASKNUM
	MOVEI	T1,1
	MOVE	T2,AC3		;DO OPEN
	MOVEI	T3,SBUF
	OPEN	SCHN,T1
	JRST	ASKSC2		;FAILED
	SETZM	AC3		;OK, DO LOOKUP
	LOOKUP	SCHN,AC1
	JRST	ASKSC3		;FAILED
	JRST	RSCRPT		;OK, READ IN SCRIPT


ASKSC2:	OUTSTR	NODEV		;COULDN'T GET DEVICE
	JRST	ASKSC4

ASKSC3:	OUTSTR	NOFIL		;COULDN'T LOOKUP FILE

ASKSC4:	MOVE	T1,SVFF		;RESTORE .JBFF
	MOVEM	T1,.JBFF
	RELEAS	SCHN,
	JRST	ASKSCP		;ASK OVER AGAIN

NODEV:	ASCIZ	/?No such device
/
NOFIL:	ASCIZ	/?File not found
/

RSCRPT:	MOVEI	T1,0		;UNLOCK HI SEG SO WE CAN READ IN SCRIPT
	SETUWP	T1,
	JRST	NOWRITE		;CAN'T
	MOVEM	T1,HIUWP	;OK, SAVE STATE OF WRITE PROTECT BIT
	MOVEM	AC1,NAME	;SAVE NAME OF SCRIPT
	HLLZM	AC2,NAME+1

	HRRZ	AC1,.JBHRL
	SUBI	AC1,BUFFER-1	;GET SIZE OF BUFFER IN HI SEG ABOVE PROGRAM
	IMULI	AC1,5
	SUBI	AC1,1		;REDUCE BY 1 FOR FINAL NULL CHARACTER FILL
	MOVE	AC2,[POINT 7,BUFFER]	;SET UP BYTE POINTER TO WRITE IN HI SEG
	SETZB	AC3,NAME+2	;CLEAR LINE COUNT AND VERSION
	MOVE	AC4,[POINT 6,NAME+2]
	TRO	F,F.LF		;SET UP LINE FEED FLAG FOR SCANNER

RSCRP1:	SOSG	SBUF+2		;COUNT -- IS THERE A CHAR?
	JRST	RSCRP5		;NO, GO DO INPUT
RSCRP2:	ILDB	T1,SBUF+1	;GET NEXT CHAR
	TRNN	F,F.LF		;SEE IF START OF NEW LINE
	JRST	RSCR2A		;NO
	LDB	T2,[POINT 6,SBUF+1,5]	;LOOK AT POINTER AND
	CAIE	T2,35		;SEE IF AT LEFT END OF WORD
	JRST	RSCR2A		;NO
	MOVE	T2,@SBUF+1	;GET WORD
	TRNN	T2,1		;SEE IF SEQUENCE
	JRST	RSCR2A		;NO
	AOS	SBUF+1		;YES--SKIP
	HRREI	T2,-6		;AND COUNT THE CHARS
	ADDB	T2,SBUF+2
	JUMPL	T2,RSCRP6	;IF NO MORE, BAD INPUT DATA
	ILDB	T1,SBUF+1	;AND GET THE NEXT CHAR
RSCR2A:	JUMPE	T1,RSCRP1	;IGNORE NULLS

	CAIN	T1,"!"
	JRST	RXCM		;DISPATCH IF "!"

	TRZ	F,F.LF		;NOT "!", CLEAR LINE FEED FLAG
	CAIN	T1,";"
	JRST	RSCOLN		;DISPATCH IF ";"
	CAIN	T1,CR
	JRST	RCR		;DISPATCH IF CARRIAGE RETURN
	CAIL	T1,LF
	CAILE	T1,FF
	TRZA	F,F.SLF		;NOT LF, CLEAR SUPPRESS BIT
	JRST	RLF		;DISPATCH IF LINE FEED

RSCRP3:	TRC	F,F.XCM+F.SCN
	TRCN	F,F.XCM+F.SCN	;IGNORE CHARACTERS IF WE HAVE COMMAND LINE & ";"
	JRST	RSCRPV
	SOJLE	AC1,RSCRP7	;COUNT BUFFER SPACE. IF LOW, GO EXPAND HI SEG
RSCRP4:	IDPB	T1,AC2		;STORE CHARACTER
	JRST	RSCRP1		;GO BACK FOR MORE

RSCRP5:	IN	SCHN,		;DO INPUT UUO ON SCRIPT FILE
	JRST	RSCRP2		;OK
	STATZ	SCHN,ERRORS	;ERRORS?
	JRST	RSCRP6		;YES

	MOVEM	AC3,NAME+3	;SAVE SCRIPT'S LINE COUNT
	MOVEI	T1,0		;NO, MUST BE EOF
	IDPB	T1,AC2		;STORE NULL CHARACTER
	HRLZ	T2,AC2		;RELEASE ANY UNUSED CORE SPACE
	SUBI	AC2,400000	;REMOVE HI-SEG START
	HRLM	AC2,.JBHRL	;UPDATE USEFUL LENGTH FOR THE SAVE
	CORE	T2,
	  HALT			;IF ALL IS WELL, WE SHOULD NEVER GET HERE
	MOVE	T1,HIUWP	;RESTORE HI SEG WRITE PROTECT STATUS
	SETUWP	T1,
	JFCL
	RELEAS	SCHN,		;RELEASE SOFTWARE CHANNEL USED TO READ IN
	MOVE	T1,SVFF		;RECLAIM BUFFER SPACE
	MOVEM	T1,.JBFF
	MOVE	T2,NAME		;TELL USER OF NAME
	PUSHJ	P,TYPSIX
	OUTSTR	[ASCIZ /./]
	MOVE	T2,NAME+1
	PUSHJ	P,TYPSIX
	SKIPE	T2,NAME+2
	OUTSTR	[ASCIZ /%/]
	PUSHJ	P,TYPSIX
	OUTSTR	[ASCIZ / loaded /]	;TELL USER
	MOVE	T1,NAME+3	;TYPE LINE COUNT
	PUSHJ	P,TYPDEC
	OUTSTR	[ASCIZ / lines
/]
	MOVE	T1,NAME		;UPDATE NAME FOR SYSTAT
	SETNAM	T1,
	EXIT	1,		;MONRET SO USER CAN SAVE
	JRST	ASKNUM


RSCRPV:	JUMPN	AC3,RSCRP1	;IGNORE IF NOT FIRST LINE
	CAIN	T1,"%"		;LOOK FOR THE % FOR VERSION
	TRCA	F,F.PCN
	TRNN	F,F.PCN		;SEE IF %-FLAG ON
	JRST	RSCRP1		;NO--RETURN
	CAIGE	T1,140		;CONVERT TO
	SUBI	T1,40		;SIXBIT
	TLNE	AC4,770000	;PROHIBIT OVERFLOW
	IDPB	T1,AC4		;SAVE VERSION
	JRST	RSCRP1		;AND OTHERWISE IGNORE

RSCRP6:	OUTSTR	[ASCIZ /?Error while reading script
/]
	JRST	RSCRP8

RSCRP7:	HRRZ	T2,.JBHRL	;EXPAND CORE. GET CURRENT HI SEG SIZE
	ADDI	T2,2000		;ADD A K
	HRLZS	T2
	CORE	T2,		;DO CORE UUO
	JRST	NOCORE		;FAILED
	ADDI	AC1,5*2000	;OK, INCREMENT CHARACTER COUNT OF SPARE
	JRST	RSCRP4		;GO ON WITH LOADING


NOCORE:	OUTSTR	[ASCIZ /?Not enough core available
/]

RSCRP8:	MOVE	T1,HIUWP	;RESTORE HI SEG UWP STATUS
	SETUWP	T1,
	JFCL
	EXIT			;RETURN TO MONITOR. USER LOST

NOWRIT:	OUTSTR	[ASCIZ /?Can not write in hiseg
/]
	EXIT			;RETURN TO MONITOR. USER LOST



RXCM:	TRZ	F,F.SLF		;CLEAR SUPPRESS LF BIT
	TRNE	F,F.LF		;ARE WE AT START OF LINE (OR SEEN ONE "!")
	TRCE	F,F.XCM		;YES, COMPLEMENT "!"FLAG, WAS IT CLEAR ALREADY?
	TRZ	F,F.LF		;NO, WE ARE NO LONGER AT START OF LINE
	JRST	RSCRP3		;GO ON. NOTICE THAT F.LF WILL BE CLEAR AND F. XCM SET


RSCOLN:	TRZ	F,F.SLF		;CLEAR SUPPRESS LF BIT
	TROE	F,F.SCN1	;SET FIRST SEMICOLON FLAG
	TRO	F,F.SCN		;ONLY IF WE ARE IN COMMAND LINE
	JRST	RSCRP3		;SET ";" FLAG TO SUPPRESS COMMENTS IF COMMAND LINE

RCR:	TRNE	F,F.SLF		;SEE IF LF BEING SUPPRESSED
	JRST	RSCRP1		;YES--IGNORE THIS CR
	TRC	F,F.SCN!F.XCM	;SEE IF AFTER COMMENT
	TRCE	F,F.SCN!F.XCM
	JRST	RCRR		;NO--JUST GO AHEAD
	PUSHJ	P,BACKUP	;YES--REMOVE THE ;
	LDB	T2,AC2		;SEE IF PRECEEDING !
	CAIE	T2,"!"
	JRST	RCRR		;NO--INCLUDE THE <CR>
	PUSHJ	P,BACKUP	;YES--REMOVE EXCLAMATION
	TRO	F,F.SLF		;SET TO REMOVE NEXT CHAR IF <LF>
	JRST	RSCRP1		;AND SUCK UP <CR>

RCRR:	TRZ	F,F.SCN!F.SCN1	;CLEAR ";" FLAG SO CR WILL ALWAYS BE LOCKED
	JRST	RSCRP3		;GO ON

RLF:	TRZ	F,F.XCM!F.SCN!F.SCN1	;NEW LINE, INITIALIZE FLAGS
	TRO	F,F.LF
	TRZE	F,F.SLF		;SEE IF SUPPRESSING LF
	AOJA	AC3,RSCRP1	;YES--JUST COUNT LINE
	AOJA	AC3,RSCRP3	;GO ON


BACKUP:	SOS	AC2		;BACK-UP STORE BYTE POINTER ONE SPACE
	IBP	AC2
	IBP	AC2
	IBP	AC2
	IBP	AC2
	POPJ	P,

	SUBTTL	INITIALIZE APPROPRIATE NUMBER OF PTY'S
ASKNUM:	MOVE	T1,.JBFF	;SAVE .JBFF
	MOVEM	T1,SVFF
	OUTSTR	[ASCIZ /HOW MANY JOBS TO BE RUN(1): /]
	PUSHJ	P,ASKDEC	;GET DECIMAL NUMBER
	  MOVEI	T1,1		;DEFAULT IS 1 JOB
	MOVE	T2,[151,,11]	;MAX NUMBER OF EXTENDED CHANNELS
	GETTAB	T2,		;GET IT FROM JMF
	  SETZ	T2,		;MUST BE 6.03
	ADDI	T2,^D14		;INCLUDE CHANNELS BELOW 20
	CAILE	T2,NMAX		;MORE THAN ASSEMBLED FOR
	MOVEI	T2,NMAX		;YES, USE THAT
	CAIG	T1,(T2)		;CHECK IT
	JUMPG	T1,ASKNU1	;OK
	OUTSTR	[ASCIZ /?Must be decimal 1 to /]
	MOVE	T1,T2		;GET MAX AGAIN
	PUSHJ	P,TYPDEC	;OUTPUT IT
	OUTSTR	[ASCIZ/
/]
	JRST	ASKNUM		;TRY AGAIN

ASKNU1:	MOVEI	N,-1(T1)	;HIGHEST SOFTWARE CHANNEL USED BY PTY'S
	SETZB	I,D		;CLEAR CHANNEL NUMBER, PROCESS ADDRESS OFFSET
	MOVE	AC4,[22,,11]	;GET NUMBER OF PTY'S IN CONFIG
	GETTAB	AC4,		;GET IT
	  MOVEI	AC4,1000	;ASSUME PTY'S 0-777
	HRRZM	AC4,PTYMAX	;STORE IT AWAY
	MOVEI	AC4,0		;CLEAR PTY UNIT NUMBER
	MOVEI	AC1,1		;ASCII LINE MODE FOR OPEN UUO

ASKNU3:	CAML	AC4,PTYMAX	;HAVE WE USED UP ALL PTY UNITS POSSIBLE?
	JRST	ASKNU6		;YES
	SETZ	T2,
	MOVE	T3,AC4		;NO. GET PTY UNIT IN SIXBIT
	IDIVI	T3,^D8
	MOVSI	AC2,(SIXBIT /PTY/)
	MOVE	AC3,[POINT 6,AC2,17]
	CAIG	T3,7		;3 DIGITS IN PTY?
	JRST	ASKN3A		;NO
	MOVE	T2,T3		;YES, GET 1ST DIGIT IN T2,
	IDIVI	T2,^D8		; 2ND DIGIT IN T3, (3RD ALREADY IN T4)
ASKN3A:	TRO	T2,20		;CONVERT ALL DIGITS TO SIXBIT
	TRO	T3,20
	TRO	T4,20
	CAILE	AC4,77		;MAKE SIXBIT NAME WITH NO LEADING 0
	IDPB	T2,AC3		;THIS DIGIT IF PTY >77
	CAILE	AC4,7
	IDPB	T3,AC3		;THIS DIGIT IF PTY >7
	IDPB	T4,AC3		;ALWAYS NEED THIS DIGIT
	SETZM	PTYUNT(D)
	MOVE	AC3,[POINT 6,PTYUNT(D)]
	CAILE	AC4,77		;NOW MAKE SIXBIT NAME WITH 1 LEADING 0
	IDPB	T2,AC3		; IF ONLY ONE DIGIT
	IDPB	T3,AC3
	IDPB	T4,AC3

	HRRZ	AC3,D		;SET UP BUFFER HEADER ADDRESSES IN IMPURE AREA
	HRLS	AC3
	ADD	AC3,[XWD PTYOBF,PTYIBF]	;DO OPEN UUO ON APPROPRIATE SOFTWARE CHANNEL
	CAIGE	I,^D14		;BELOW EXTENDED CHANNELS
	JRST	[HRRZM I,CHNNUM(I) ;YES, STORE CHANNEL NUMBER ANYWAY
		 MOVE T4,[OPEN AC1] ;GET OLD STYLE OPEN
		 DPB I,[POINT 4,T4,12] ;INSERT CHANNEL NUMBER
		 XCT T4		;DO THE OPEN
		   AOJA AC4,ASKNU3 ;FAILED, TRY ANOTHER PTY NUMBER
		 MOVE T4,[INBUF 1] ;GET AN INBUF FUNCTION
		 DPB I,[POINT 4,T4,12] ;INSERT CHANNEL NUMBER
		 XCT T4
		 MOVE T4,[OUTBUF 1] ;SAME FOR OUTBUF
		 DPB I,[POINT 4,T4,12] ;INSERT CHANNEL NUMBER
		 XCT T4
		 JRST ASKN3B]	;RESUME INLINE
	MOVEM	AC2,FOPOPN+2	;STORE PTYNNN
	MOVEM	AC3,FOPOPN+3	;STORE BUFFER HEADER INFO
	MOVSI	AC2,200000	;BIT FOR ASSIGN NEXT AVB CHANNEL
	HLLM	AC2,FOPOPN	;CLEAR OLD CHANNEL NUMBER
	MOVE	AC2,[5,,FOPOPN]	;POINT TO BLOCK
	FILOP.	AC2,		;OPEN THE PTY
	  AOJA	AC4,ASKNU3	;FAILED, TRY NEXT UNIT NUMBER
	HLRZ	AC2,FOPOPN	;GET CHANNEL ASSIGNED
	ANDI	AC2,777		;CLEAR BIT
	HRRZM	AC2,CHNNUM(I)	;AND SAVE IT AWAY

ASKN3B:	MOVEM	AC2,PTYNAM(D)	;SAVE PTY NAME IN SIXBIT
	HRRM	AC4,PTYUNT(D)	;SAVE PTY UNIT NUMBER IN BINARY
	DO	(OUTPUT)	;1ST OUTPUT TO INITIALIZE RING
	ADDI	D,IMPSIZ	;GO ON TO NEXT IMPURE AREA
	ADDI	AC4,1		;NEXT PTY UNIT
	CAMGE	I,N		;HAVE WE DONE ALL?
	AOJA	I,ASKNU3	;NO, COUNT CHANNEL NUMBER AND PROCEED
	JRST 	SETTMP		;YES, GO AHEAD

ASKNU6:	OUTSTR	[ASCIZ /?Not enough PTY's. Could only get /]
	MOVE	T1,I		;FIRST SUBJOB TO NOT GET A PTY
	PUSHJ	P,TYPDEC	;OUTPUT THAT
	OUTSTR	[ASCIZ/. Try over.
/]
	MOVE	I,N		;SET UP TO RELEASE ALL SO FAR


ASKNU7:	DO	(RELEAS)	;RELEASE CHANNEL
	SETZM	PTYNAM(D)	;CLEAR NAME
	SOJGE	I,ASKNU7	;DONE WITH ALL CHANNELS? LOOP IF NOT
	MOVE	T1,SVFF		;YES, RECLAIM BUFFERS
	MOVEM	T1,.JBFF
	JRST	ASKNUM		;ASK USER HOW MANY ONCE AGAIN

SETTMP:			;SET UP THE NAMES OF THE TEMPORARY WCH
			;AND RSP FILES TO BE SCPNNN
	MOVE	AC1,WCHFILE	;AC1_SIXBIT /SCP000/
	PJOB	AC2,		;GET JOB NO
	IDIVI	AC2,^D100	;GET FIRST DIGIT
	DPB	AC2,[POINT 3,AC1,23]
	IDIVI	AC3,^D10	;GET NEXT DIGIT
	DPB	AC3,[POINT 3,AC1,29]
	DPB	AC4,[POINT 3,AC1,35]
	MOVEM	AC1,WCHFILE	;STORE NAME
	MOVEM	AC1,RSPFILE	;STORE NAME
				;FALL INTO ASKMON

	SUBTTL	OPEN MONITOR CHANNEL IF DESIRED
ASKMON:	TRZ	F,F.WCH		;CLEAR MONITOR FLAG
	OUTSTR	[ASCIZ /WATCH HOW MANY JOBS(/]
	MOVEI	T1,1(N)		;T1_# OF JOBS TO BE RUN
	PUSHJ	P,DECOUT	;OUTPUT
	OUTSTR	[ASCIZ /): /]	;CLOSE PAREN
	PUSHJ	P,ASKDEC	;ASK HIM
	  MOVEI	T1,1(N)		;DEFAULT IS ALL JOBS
	MOVEM	T1,NOWATC	;SAVE NUMBER OF FIRST TO NOT WATCH
	JUMPE	T1,ASKLOG	;NO MONITERING
	MOVSI	AC3,(SIXBIT /DSK/)	;DEFAULT IS DSK
	MOVE	AC2,WCHMASTER+1	;DEFAULT EXT IS WCH
	MOVE	AC1,WCHMASTER	;SCRIPT.WCH FILE
	OUTSTR	[ASCIZ /WHERE(DSK:SCRIPT.WCH): /]
	PUSHJ	P,GETFIL	;GET USER'S ANSWER
	JRST	ASKMO4		;CARRIAGE RETURN,SO USE DEFAULTS

	MOVEM	AC1,WCHMASTER	;STORE NAME FOR LATER USE
	MOVEM	AC2,WCHMASTER+1	;STORE EXT FOR LATER USE
	MOVEM	AC3,WCHDEV	;SAVE DEVICE FOR LATER USE
	TRZ	F,F.TTMN	;SET TTMN ONLY IF DEVICE TTY IS A REAL TTY
	TLZ	F,F.DWCH
	MOVE	T1,AC3
	DEVCHR	T1,
	TLNE	T1,DEVDSK	;IS DEVICE DSK ?
	TLO	F,F.DWCH	;YES,SO SET FLAG
	TLNE	T1,DEVTTY
	TRO	F,F.TTMN

ASKMO4:	MOVEI	T1,1		;SETUP AND OPEN MON CHANNEL
	MOVE	T2,AC3		;DEVICE 
	MOVSI	T3,MONBUF
	TRO	F,F.WCH		;SET WATCH FLAG
	OPEN	MONCHN,T1
	JRST	ASKMO1		;FAILED TO GET DEVICE
	MOVE	AC1,WCHFILE	;NAME OF TMP WATCH FILE
	MOVE	AC2,WCHFILE+1	;EXT
	SETZB	AC3,AC4		;ZERO PROTECTION AND PPN
	ENTER	MONCHN,AC1
	JRST	ASKMO2		;FAILED
	JRST	ASKALL		;NEXT QUESTION

ASKMO1:	OUTSTR	NODEV
	JRST	ASKMON

ASKMO2:	OUTSTR	NOENT
	RELEASE	MONCHN,
	JRST	ASKMON

ASKMO3:	OUTSTR	[ASCIZ \?No device/file specified
\]
	JRST	ASKMON

NOENT:	ASCIZ	/?Can not enter file SCRIPT.WCH
/

ASKALL:	TLO	F,P.WCHALL	;ASK IF ALL LINES TO BE WATCHED
	OUTSTR	[ASCIZ /WATCH EACH LINE OF SCRIPT(Y,N): /]
	HRROI	AC1,40		;PUT -1,,40 IN AC1
	GETTAB	AC1,		;GETTAB TO SEE IF BATCH JOB
	SETZM	AC1		;GETTAB FAILED,SO HOPE IT'S A NEW SCRIPT
	TLNE	AC1,200		;IS IT A BATCH JOB ?
	JRST	BATCH		;YES,SO TEST IF NEW OR OLD DIALOGUE
	PUSHJ	P,ASKNYS	;NOT BATCH SO ASK THE USER
	TLZ	F,P.WCHALL	;NO , SO RESET THE FLAG
	JRST	ASKLOG		;YES,SO NEXT Q.


BATCH:	PUSHJ	P,TTYIN		;GET USER'S ANSWER
	PUSHJ	P,GETWRD	;GET SIXBIT FIELD
	CAIN	T3,(SIXBIT /N/)	;IS IT  "N" ?
	JRST	NEWBAT		;YES,SO THIS IS NEW BATCH
	CAIN	T3,(SIXBIT /NO/);IS IT "NO" ?
	JRST	NEWBAT		;YES,SO THIS IS NEW BATCH
	CAIN	T3,(SIXBIT /Y/)	;IS IT "Y" ?
	JRST	NEWBA1		;YES
	CAIN	T3,(SIXBIT /YES/)	;IS IT "YES" ?
	JRST	NEWBA1		;YES
		;NONE OF ABOVE.SO IT MUST BE AN OLD BATCH JOB
		;REPLYING TO AN OLD QUESTION :
		;"WHERE TO LOG RESPONSE TIMES ? "
		;OLD QUESTIONS WILL HAVE TO BE ASKED FOR THIS JOB
	TLO	F,F.OLD		;SET FLAG THAT THIS IS AN OLD JOB
	MOVE	AC1,RSPMASTER	;DEFAULT FILE NAME = SCRIPT
	MOVE	AC2,RSPMASTER+1	;DEFAULT EXT =RSP
	MOVSI	AC3,(SIXBIT /DSK/)	;DEFAULT DEVICE
	SETZM	AC4
	PUSHJ	P,GETFI0	;SNEAK IN GETFIL ROUTINE
	  JRST	NORSP		;<CR> WAS INPUT.SO NO RESP ASKED
	JUMPE	T3,NORSP	;* GETFI0 SEEMS TO ALWAYS SKIP, SO TEST
				; FOR NULL RESPONSE HERE
	MOVEM	AC1,RSPMASTER	;STORE USER'S FILE NAME
	MOVEM	AC2,RSPMASTER+1	;STORE EXT FOR FUTURE USE
	TRO	F,F.RSP		;SET FLAG THAT RESPONSE IS TO BE GATHERED
	TLO	F,P.RSPALL	; FOR ALL LINES
	MOVEI	T1,1(N)		;RESP FOR ALL JOBS
	MOVEM	T1,NOLOG
	MOVEI	T1,1		;ASCII LINE MODE
	MOVE	T2,AC3		;USER-SUPPLIED DEVICE NAME
	MOVSI	T3,LOGBUF	;OUTPUT BUFFER
	OPEN	LOGCHN,T1
	JRST	OPNFAL		;OPEN-FAIL
	MOVE	AC1,RSPFILE	;NAME OF THE TMP RESPONSE FILE
	MOVE	AC2,RSPFILE+1	;EXT
	SETZB	AC3,AC4
	ENTER	LOGCHN,AC1
	JRST	ENTFAL		;ENTER-FAIL
	JRST	REPEAT		;NEXT QUESTION

OPNFAL:	OUTSTR	[ASCIZ /CANNOT OPEN RSP FILE
/]
	JRST	NORSP
ENTFAL:	OUTSTR	[ASCIZ /CANNOT ENTER RSP FILE
/]
	JRST	NORSP

NORSP:	TRZ	F,F.RSP		;NO RESP TO BE GATHERED
	SETZM	NOLOG
	JRST	REPEAT		;NEXT Q.

NEWBAT:	TLZ	F,P.WCHALL	;DON'T WATCH ALL LINES
NEWBA1:	JRST	ASKLOG		;WATCH ALL LINES,NEXT Q.
	SUBTTL	OPEN LOG CHANNEL IF DESIRED
ASKLOG:	TRZ	F,F.RSP		;CLEAR LOG FLAG
	OUTSTR	[ASCIZ /RESPONSE TIME FOR HOW MANY JOBS(/]
	MOVEI	T1,1(N)		;T1_# OF JOBS TO BE RUN
	PUSHJ	P,DECOUT	;OUTPUT
	OUTSTR	[ASCIZ	/): /]	;CLOSE PAREN
	PUSHJ	P,ASKDEC	;ASK USER
	  MOVEI	T1,1(N)		;DEFAULT IS ALL JOBS
	MOVEM	T1,NOLOG	;NO. OF JOBS TO BE LOGGED
	JUMPE	T1,LOCK		;GO TO NEXT QUESTION IF 0
	
	SETZB	AC3,AC4		;ZERO PROTECTION AND PPN
	MOVE	AC2,RSPFILE+1	;EXT
	MOVE	AC1,RSPFILE	;NAME OF TMP RESP FILE
	TRO	F,F.RSP		;YES SO SET FLAG
	MOVEI	T1,1		;SET UP & OPEN LOG CHANNEL
	MOVSI	T2,(SIXBIT /DSK/)	;DEVICE DSK
	MOVSI	T3,LOGBUF
	OPEN	LOGCHN,T1
	JRST	ASKLO1		;FAILED TO GET DEVICE
	ENTER	LOGCHN,AC1
	JRST	ASKLO2		;FAILED
	JRST	ASKRSP		;OK SO NEXT QUESTION

ASKLO1:	OUTSTR	NODEV		;NO DEVICE
	JRST	ASKLOG		;TRY OVER

ASKLO2:	OUTSTR	[ASCIZ /CANNOT ENTER SCRIPT.RSP FILE	;COULDN'T ENTER FILE
/]
	RELEAS	LOGCHN,		;RELEASE DEVICE
	JRST	ASKLOG		;TRY OVER

ASKRSP:	OUTSTR	[ASCIZ /RESPONSE TIME FOR EACH LINE(Y,N): /]
	TLZ	F,P.RSPALL
	PUSHJ	P,ASKNYS
	JRST	LOCK		;NO,NEXT QUESTION
	TLO	F,P.RSPALL	;YES, SO FALL INTO LOCK

LOCK:	OUTSTR	[ASCIZ /LOCK IN CORE(N,Y): /]
	PUSHJ	P,ASKYNO
	JRST	REPEAT		;NO,SO NEXT Q.
	MOVEI	T1,[1,,1]	;CODE FOR LOC UUO
	CALLI	T1,60		;LOCK UUO
	OUTSTR	[ASCIZ /CANNOT LOCK.  PROCEEDING ANYWAY
/]
				;LOCK SUCCESSFUL

	SUBTTL	GET REPEAT COUNT AND DELAY FACTOR
REPEAT:	OUTSTR	[ASCIZ /REPEAT COUNT(1): /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,1		;DEFAULT IS 1
	MOVEM	T1,COUNTO	;SAVE AS OPERATOR COUNT


	OUTSTR	[ASCIZ /DELAY FACTOR(1): /]
	PUSHJ	P,ASKDEC
	  MOVEI	T1,1		;DEFAULT IS AS IN SCRIPT
	MOVEM	T1,DELFAC


	OUTSTR	[ASCIZ /STAGGER TIME(20(SEC)): /]
	PUSHJ	P,ASKDEC
	  SKIPA	T1,[-1]		;DEFAULT IS AS IN SCRIPT
	IMULI	T1,^D1000	;CONVERT TO M-SEC
	ADDI	T1,1		;GUARANTEE NON-ZERO
	MOVEM	T1,STAGO


	OUTSTR	[ASCIZ /SEE COMMENTS TO OPERATOR(Y,N): /]
	TRO	F,F.CTO
	PUSHJ	P,ASKNYS
	TRZ	F,F.CTO


	IFN	DEBUG,<
	TRNN	F,F.WCH		;SEE IF MONITORING
	JRST	WATCH		;NO--THEREFORE NO DEBUGGING FEATURES
	OUTSTR	[ASCIZ /DEBUG(N,Y): /]
	TRO	F,F.DBG
	PUSHJ	P,ASKYNO
	TRZ	F,F.DBG
>


WATCH:	OUTSTR	[ASCIZ /WATCH FOR ERRORS(Y,N): /]
	TRO	F,F.ERR
	PUSHJ	P,ASKNYS
	TRZ	F,F.ERR
	TLNE	F,F.OLD		;IS AN OLD BATCH JOB USING US ?
	JRST	INIT		;YES,SO DON'T ASK NEW QUESTIONS

IFN HUWSW,<
	TRZ	F,F.HUW		;NORMALLY OFF
	OUTSTR	[ASCIZ/HOLDUP AND WAIT (Y,N) :   /]
	PUSHJ	P,ASKYNO	;ASK
	JRST	NEXTTH		;NO
	TRO	F,F.HUW		;YES
	OUTSTR	[ASCIZ/FIRST WAIT AFTER LINE NUMBER:  /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,3		;TO PERMIT EVERYONE TO LOG IN
	MOVEM	T1,FSTLIN	;SAVE INITIAL LINE
	OUTSTR	[ASCIZ/OTHERS AT INTERVALS OF:  /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,3		;DEFAULT
	MOVEM	T1,WLINCR	;SAVE INCREMENT
	SETZM	DELFAC		;NO DELAY WHILE INITIALIZING
	JRST	INIT
NEXTTH:
>
IFN CYCLSW,<
CYCLE:	TRZ	F,F.CYC		;NORMALLY OFF
	OUTSTR	[ASCIZ /CYCLIC MODE(N,Y): /]
	PUSHJ	P,ASKYNO
	JRST	INIT		;NO CYCLE
	TRO	F,F.CYC		;SET CYCLE FLAG
	OUTSTR	[ASCIZ/THE TIME IS /]
	SETZB	T,T1
	MSTIME	T,
	PUSHJ	P,TYPTIM
	PUSHJ	P,TYPCRL
	OUTSTR	[ASCIZ /CYCLE INTERVAL IN MINUTES(10): /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,^D10		;DEFAULT IS 10 MINUTES
	IMULI	T1,^D60*^D1000	;CONVERT TO MILLISEC
	MOVEM	T1,INTERV	;SAVE INTERVAL
	OUTSTR	[ASCIZ /CYCLE COUNT(10): /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,10
	MOVEM	T1,CYCLCT
	OUTSTR	[ASCIZ /START RUN ON FIRST TIME MARK(N,Y): /]
	TRO	F,F.DOZ		;USUALLY YES
	PUSHJ	P,ASKYNO
	TRZ	F,F.DOZ		;NO,IMMEDIATELY
>
	JRST	INIT

	SUBTTL	PROCESS CONTROL
PRET:	MOVEM	T4,PCWORD(D)	;RETURN FROM PROCESS TO MAIN LOOP
	POPJ	P,		;JSP T4,PRET



;REENTER POINT -- KILL OFF JOBS WITH ALTERNATE SCRIPT
;THEN CLOSE MONITOR AND LOG FILES

REE:	MOVE	P,[IOWD PDLEN,PDLIST]	;RESTORE PUSH-DOWN LIST
	MOVEI	T,DEFAUR	;SET REENTER DEFAULTS
	MOVEM	T,DEFAUP
	MOVE	T,RNAME+3	;SET LINE COUNT
	MOVEM	T,SLNCNT
	TRZ	F,F.RSP		;STOP LOGGING
	SETZM	COUNTO		;CLEAR REPEAT COUNT
	SETZM	STAGO		;CLEAR STAGGER TIME
	PUSHJ	P,INITR		;GO RUN SCRIPT
	OUTSTR	[ASCIZ /
ALL JOBS TERMINATED/]

	TRNN	F,F.TTMN	;DON'T CLOSE IF TTY MONITOR

EXT:	PUSHJ	P,TOTRSP	;TOTAL UP AND AVERAGE THE RESPONSE DATA
	CLOSE	MONCHN,		;CLOSE MONITOR & LOG CHANNELS
	HLLZS	.JBREN		;CLEAR REENTER ADDRESS
	CLOSE	LOGCHN,
	MOVEM	F,SAVACS	;SAVE FLAGS FOR FUTURE USE
	HRRZI	$B,EZER		;BASE OF THE STACK
	HRLI	$S,-767		;LENGTH OF STACK
	HRRZI	$F,11($B)	;FORMALS REGISTER
	HRR	$S,$F		;SET UP STACK POINTER
	HRLZI	4,F.DWCH
	TDNE	4,SAVACS	;WAS WATCHING DEVICE DSK ?
	SKIPG	T1,NOWATC	;YES,BUT WAS ANYTHING WATCHED ?
	JRST	CLORSP		;NO,NO. SO DON'T APPEND
	PUSH	WCHMASTER+4	;PUSH POINTER TO MASTER-WCH FILE
	PUSH	WCHFILE+4	;PUSH POINTER TO NEW WCH FILE
	PUSH	[MONCHN]	;CHNL TO BE USED BY APPEND
	PUSH	[LOGCHN]	;CHNL TO BE USED BY APPEND
	PUSHJ	FILEAPPEND	;APPEND NEW FILE TO MASTER FILE
	SUB	$S,DSKI.L+15	;RESET STACK POINTER
CLORSP:	MOVE	T1,NOLOG	;# OF JOBS MEASURED
	JUMPE	T1,RES		;RESPONSE TIME FOR NO JOBS
	PUSH	RSPMASTER+4	;PUSH POINTER TO MASTER-RSP FILE
	PUSH	RSPFILE+4	;PUSH POINTER TO NEW RSP FILE
	PUSH	[MONCHN]
	PUSH	[LOGCHN]	;CHNL'S USED BY APPEND
	PUSHJ	FILEAPPEND	;APPEND NEW FILE TO MASTER FILE
	SUB	$S,DSKI.L+15	;RESET STACK POINTER
RES:	RESET			;RELEASE PTY'S ETC.
	EXIT			;RETURN TO MONITOR

INIT:	TIMER	T4,		;DETERMINE POWER FREQ
	MSTIME	T1,
	JUMPE	T4,INIT
	MOVEM	T1,TSTART	;ESTABLISH TIME ORIGIN

	IDIV	T1,T4		;MILLISECONDS/JIFFY
	CAIL	T1,^D18
	JRST	T50HZ

T60HZ:	MOVEI	T1,^D751	;751*60=4(MOD 4096)
	MOVEI	T2,^D16666
	JRST	TFUDG1

T50HZ:	MOVEI	T1,^D2130	;2130*50=4(MOD 4096)
	MOVEI	T2,^D20000

TFUDG1:	MOVEM	T1,MAGIC	;MAGIC NUMBER TO SLEEP 4 JIFFIES
	MOVEM	T2,USJIF	;MICROSECONDS PER JIFFY

	TRNN	F,F.RSP		;SEE IF RESPONSE TIME ENABLED
	JRST	STSCR		;NO
	MOVEI	AC1,SNEAK	;YES,PUT TITLE ON RESPONSE LOG
	PUSHJ	P,TITLE
	MOVEI	T2,TITMSR	;ADD DESCRIPTIVE JUNK
	PUSHJ	P,LSTSTR

	TRNN	F,F.WCH		;SEE IF MONITORING
	JRST	STSCR		;NO--GO START
	MOVEI	AC1,OUTMOT	;PUT TITLE ON MONITOR FILE
	TRNN	F,F.TTMN	;UNLESS TTY MONITOR
	PUSHJ	P,TITLE

STSCR:	OUTSTR	[ASCIZ /Starting
/]
	MOVEI	T,DEFAUL	;SET REGULAR DEFAULTS
	MOVEM	T,DEFAUP
	MOVE	T,NAME+3	;SET LINE COUNT
	MOVEM	T,SLNCNT
	TRO	F,F.MCR!F.MLF
	MOVEI	T,REE		;SET RE-ENTER ADDRESS
	HRRM	T,.JBREN
IFN CYCLSW,<
	TRNN	F,F.CYC		;CYCLE MODE?
	JRST	CYCLGO		;NO
	OUTSTR	[ASCIZ /NOW CCONT AND DETACH JOB FOR CYCLING
/]
	EXIT	1,		;RETURN SAVING STATE FOR CCONT
	TRZE	F,F.DOZ		;DELAY FIRST CYCLE TIL TIME MARK?
	PUSHJ	P,DOZE		;SLEEP TIL MARK
CYCLGO:
>
	MSTIME	T,		;RE-GET START TIME TO ENSURE CONSISTENCY IF POSSIBLE
	MOVEM	T,TSTART
	PUSHJ	P,INITR		;START SCRIPT
	OUTSTR	[ASCIZ /All jobs done/]
	JRST	EXT		;ALL DONE

INITR:	MSTIME	T,		;GET TIME OF DAY SINCE RUN STARTED
	SUB	T,TSTART
	SKIPGE	T		;KEEP POSITIVE IN CASE OF MIDNIGHT
	ADD	T,[^D24*^D60*^D60*^D1000]
	MOVE	X,T		;SET LIMIT ON WAKEUP TIME
	ADDI	X,MAXSLP
	PUSHJ	P,OPRET
	SETZB	I,D		;CLEAR CHANNEL NUMBER, PROCESS ADDRESS OFFSET
	SETZ	A,		;CLEAR COUNT OF ACTIVE PROCESSES
	CAILE	N,NMAX-1	;CHECK FOR REASONABLE N
	MOVEI	N,NMAX-1	;NO--SET TO MAX

IFN HUWSW,<
	TRNE	F,F.HUW		;HOLDUP MODE?
	MOVEM	N,RCTR		;YES, SAVE COUNT OF RUNNING JOBS
>
INIT1:	PUSHJ	P,PINI		;SET UP PROCESS
	ADDI	D,IMPSIZ	;NEXT IMPURE AREA
	CAMGE	I,N		;ARE WE DONE WITH ALL PROCESSES?
	AOJA	I,INIT1		;NO, NEXT ONE & LOOP

LOOP:	MSTIME	T,		;GET TIME OF DAY SINCE RUN STARTED
	SUB	T,TSTART
	SKIPGE	T		;KEEP POSITIVE IN CASE OF MIDNIGHT
	ADD	T,[^D24*^D60*^D60*^D1000]

	CAMGE	T,X		;DID WE WAKE UP EARLY
	TRZ	F,F.SSY3	;YES CLEAR LOST PTWAKE POSSIBLE

LOOP1:	PUSHJ	P,OPER		;GO CHECK UP ON THE OPERATOR
	SETZB	I,D		;CLEAR CHANNEL NUMBER, PROCESS ADDRESS OFFSET
	MOVE	X,T		;SET LIMIT ON WAKE UP TIME
	ADDI	X,MAXSLP

LOOP2:	PUSHJ	P,@PCWORD(D)	;DO THE PROCESS
	ADDI	D,IMPSIZ	;NEXT IMPURE AREA
	CAMGE	I,N		;ARE WE DONE WITH ALL PROCESSES?
	AOJA	I,LOOP2		;NO, NEXT ONE & LOOP

	JUMPE	A,CPOPJ		;ARE ANY PROCESSES ACTIVE? IF NOT WE ARE DONE.

	TRZ	F,F.SSY3	;CLEAR LOST PTWAKE POSSIBLE

IFN CYCLSW,<
	TRZE	F,F.DOZ		;TIME TO SLEEP TIL NEXT TIME MARK?
	TRNN	F,F.WCH+F.RSP	;SKIP IF NOT BOTH ZERO
	JRST	LOOP3		;DO NOT APPEND
		; THE APPEND ROUTINE BEGINS HERE
	CLOSE	MONCHN,
	CLOSE	LOGCHN,
	MOVEM	P,SAVACS+17	;SAVE ALL AC'S IN SAVACS TO SAVACS+17
	MOVEI	P,SAVACS
	BLT	P,SAVACS+16
	HRRZI	$B,EZER		;BASE OF THE STACK
	HRLI	$S,-767		;LENGTH OF STACK
	HRRZI	$F,11($B)	;FORMALS REGISTER
	HRR	$S,$F		;SET UP STACK POINTER
	HRLZI	4,F.DWCH
	TDNN	4,SAVACS	;WAS WATCHING DEVICE DSK ?
	JRST	APPRSP		;NO SO DON'T APPEND
	PUSH	WCHMASTER+4	;PUSH POINTER TO MASTER-WCH FILE
	PUSH	WCHFILE+4	;PUSH POINTER TO NEW WCH FILE
	PUSH	[MONCHN]	;CHNL TO BE USED BY APPEND
	PUSH	[LOGCHN]	;CHNL TO BE USED BY APPEND
	PUSHJ	FILEAPPEND	;APPEND NEW FIE TO MASTER FILE
	SUB	$S,DSKI.L+15	;RESET STACK POINTER
APPRSP:	PUSH	RSPMASTER+4	;PUSH POINTER TO MASTER-RSP FILE
	PUSH	RSPFILE+4	;PUSH POINTER TO NEW RSP FILE
	PUSH	[MONCHN]
	PUSH	[LOGCHN]	;CHNL'S USED BY APPEND
	PUSHJ	FILEAPPEND	;APPEND NEW FILE TO MASTER FILE
	SUB	$S,DSKI.L+15	;RESET STACK POINTER
	HRLZI	P,SAVACS
	BLT	P,P		;RESTORE AC'S
		; END OF APPEND BRANCH

		;REOPEN THE WCH AND RSP CHNLS
	TRNN	F,F.WCH		;WAS WATCHING ON ?
	JRST	LOOP4		;NO
	MOVEI	T1,1		;ASCII LINE MODE
	MOVE	T2,WCHDEV	;WATCHING DEVICE 
	MOVSI	T3,MONBUF	;OUTPUT BUFFER
	OPEN	MONCHN,T1
	JRST	LOOP5		;ERROR
	MOVE	AC1,WCHFILE	;NAME OF WCH FILE
	MOVE	AC2,WCHFILE+1	;EXT
	SETZB	AC3,AC4
	ENTER	MONCHN,AC1
	JRST	LOOP6		;ERROR

LOOP4:	TRNN	F,F.RSP		;WAS RSP FLAG ON ?
	JRST	LOOP7		;NO,SO DON'T OPEN RSP CHNL
	MOVEI	T1,1		;ASCII LINE MODE
	MOVE	T2,DSKI.L+14	;DEVICE DSK
	MOVSI	T3,LOGBUF	;OUTPUT BUFFER
	OPEN	LOGCHN,T1
	JRST 	LOOP5
	MOVE	AC1,RSPFILE	;NAME OF RSP FILE
	MOVE	AC2,RSPFILE+1	;EXT
	SETZB	AC3,AC4
	ENTER	LOGCHN,AC1
	JRST	LOOP8		;ERROR
LOOP7:	PUSHJ	P,DOZE		;SLEEP UNTIL NEXT TIME MARK
	JRST	LOOP3		;START AGAIN

LOOP5:	OUTSTR	[ASCIZ /CANNOT OPEN WATCHING  DEVICE/]
	CALLI	1,12		;EXIT

LOOP6:	OUTSTR	[ASCIZ /CANNOT ENTER WCH FILE/]
	CALLI	1,12		;EXIT

LOOP8:	OUTSTR	[ASCIZ /CANNOT ENTER RSP FILE/]
	CALLI	1,12		;EXIT

>
LOOP3:	TRC	F,F.SSY1+F.SSY2	;IS A PROCESS WAITING ON PTY & WAS ONE WOKEN UP
	TRZN	F,F.SSY1+F.SSY2
	JRST	LOOP		;YES, TRY IMMEDIATELY IN CASE HE IS FAST
	MSTIME	T,		;GET TIME OF DAY SINCE RUN STARTED
	SUB	T,TSTART
	SKIPGE	T		;KEEP POSITIVE IN CASE OF MIDNIGHT
	ADD	T,[^D24*^D60*^D60*^D1000]
	MOVE	T1,X		;GET EXCESS TILL WAKE UP TIME
	SUB	T1,T
	JUMPLE	T1,LOOP1	;NONE, SO DON'T SLEEP

	HRLI	T1,40		;HIBER CODE FOR PTY WAKE
	HIBER	T1,
	JRST	NOHBR		;HIBER UUO NOT WORKING
	JRST	LOOP		;GO RUN THROUGH PROCESS AGAIN

NOHBR:	
	IMULI	T1,^D1000	;WE SLEEP. GET TIME TO MICROSECONDS
	IDIV	T1,USJIF	;GET TIME TO JIFFIES
	TRO	T1,3		;ROUND UP TO MULTIPLE OF 4
	ADDI	T1,1
	ASH	T1,-2		;DIVIDE BY FOUR
	IMUL	T1,MAGIC	;MULTIPLY BY MAGIC NUMBER
	SLEEP	T1,		;SLEEP APPROPRIATE MULTIPLE OF 4 JIFFIES
	TRO	F,F.SSY3	;SET FLAG THAT LOST PT WAKE POSSIBLE

	JRST	LOOP		;GO,RUN THROUGH THE PROCESS AGAIN


	SUBTTL	PROCESS INITIALIZATION & START OF NEW SCRIPT LINE
PINI:	HRLZI	T1,CLPINI(D)	;INITIALIZE PROCESS
	HRRI	T1,CLPINI+1(D)	;ZERO IMPURE AREA
	SETZM	CLPINI(D)
	BLT	T1,LCPINI-1(D)

	AOS	A		;COUNT NUMBER ACTIVE
	MOVE	T,PTYNAM(D)	;CHECK NAME OF PTY
	JUMPE	T,RELPTY	;IF BLANK, GO RELEASE CHANNEL
	DEVCHR	T,		;CHECK AVAILABLITY
	TLNE	T,DEVAVL	;SEE IF AVAILABLE TO US
	TRNN	T,DEVINI	;SEE IF INITED
	JRST	RELPTY		;IF NO TO EITHER, RELEASE CHANNEL

	JSP	T4,PRET		;STOW PCWORD & RETURN TO CONTROL LOOP


BEGSCP:	SETZM	CLBEGS(D)	;CLEAR IMPURE AREA
	MOVEI	T1,DLBEGS(D)	;SET UP DEFAULTS
	HRL	T1,DEFAUP
	BLT	T1,LDBEGS-1(D)
	MOVE	T1,DELFAC	;APPLY DELAY FACTOR
	IMULM	T1,DELTI(D)
	IMULM	T1,DELTO(D)
	IMULM	T1,DELTR(D)
	IMULM	T1,DELTF(D)
	TLNN	F,P.WCHALL	;ALL LINES TO BE WATCHED?
	JRST	BEGSC1		;NO
	CAML	I,NOWATC	;YES,WATCH THIS PROCESS?
	JRST	BEGSC1		;NO, SO NEXT FLAG
	PUSHJ	P,OUTMO6	;YES,ENSURE START OF LINE
	MOVEI	T1,P.WCH
	IORM	T1,PFLAGS(D)	;SET FLAG TO WATCH THIS PROCESS

BEGSC1:	TLNN	F,P.RSPALL	;SEE IF RESP TIME FOR ALL LINES
	JRST	BEGSC2		;NO
	CAML	I,NOLOG		;SEE IF RESP TIME FOR THIS PROCESS
	JRST	BEGSC2		;NO
	MOVEI	T1,P.RSP
	IORM	T1,PFLAGS(D)	;YES, SO SET FLAG

BEGSC2:	IFN	DEBUG,<
	TRNN	F,F.JST		;SEE IF JOB STATUS UUO WORKS
	JRST	BEGLIN		;NO
	JOBST	(T1)		;GET STATUS FOR DEBUGGER
>
IFN HUWSW,<
	TRNN	F,F.HUW		;HOLDUP MODE?
	JRST	BEGLIN		;NO
	MOVE	T1,WLINCR	;GET HOLDUP LINE INCREMENT
	IMUL	T1,I		;MULTIPLY BY JOB INDEX
	ADD	T1,FSTLIN	;ADD INITIAL LINE
	MOVEM	T1,HLNCNT(I)	;SAVE LINE COUNT BEFORE HOLDUP
>

BEGLIN:	HRLZI	T1,CLBEGL(D)	;START LINE. CLEAR STATISTIC AREA
	HRRI	T1,CLBEGL+1(D)
	SETZM	CLBEGL(D)
	BLT	T1,LCBEGL-1(D)
	MOVEI	T1,P.MSYN!P.INT!P.SSY!P.QOK	;INITIALIZE FLAG BITS
	ANDCAM	T1,PFLAGS(D)
	MOVEI	T1,P.FINT	;SEE IF FORCED INTERRUPT REQUESTED
	TDNE	T1,PFLAGS(D)
	JRST	FINTRP		;YES--GO DO FORCED INTERRUPT

SSCRPL:	TLZ	F,P.XCM!P.DSH!P.NIP!P.NRD!P.NONG!P.ARR!P.ARRL!P.CTO
	TRZ	F,F.SCN
	TLO	F,P.LF
IFN CYCLSW,<
	TRNE	F,F.DOZ		;TIME TO SLEEP?
	JSP	T4,PRET		;YES,RETURN TO CONTROL LOOP TO DOZE
>
	MOVEI	T3,0		;ZERO NUMBER BEING SCANNED
	AOS	LINCNT(D)	;COUNT LINES PROCESSED

	;FALL INTO SSCRPT

	SUBTTL	SCRIPT TEXT PROCESSING
SSCRPT:	ILDB	T1,PSCRPT(D)	;GET CHARACTER
	JUMPE	T1,CKCNT	;IF NULL, AT END OF SCRIPT
	PUSH	P,T1
	PUSHJ	P,OUTMON	;MONITOR INPUT
	POP	P,T1
	TRNE	F,F.SCN		;SEE IF IN A COMMENT
	JRST	COMCMD		;YES--PROCESS
	TLNE	F,P.CTO		;SEE IF IN A COMMENT TO OPERATOR
	JRST	CTO		;YES

	CAIN	T1,"!"		;DISPATCH ON "!"
	JRST	EXPROC
	CAIN	T1,"^"		;DISPATCH ON"^"
	JRST	ARROW

	TLZ	F,P.LF		;NEITHER. SO CLEAR LF FLAG
	TLNN	F,P.XCM		;IS THIS COMMAND LINE?
	JRST	SCNTXT		;NO, GO HANDLE TEXT LINE

	CAIN	T1,";"		;CHECK FOR COMMENTS
	JRST	SCNCMD		;YES
	CAIN	T1,CR		;DISPATCH ON CR
	JRST	CRCMD
	CAIL	T1,LF		;DISPATCH ON LF
	CAILE	T1,FF
	JRST	.+2
	JRST	LFCMD

	CAIL	T1,"0"		;IS IT A DIGIT?
	CAILE	T1,"9"
	SKIPA
	JRST	NUMCMD		;YES
	CAIE	T1,HT		;IS IT A SPACE OR TAB?
	CAIN	T1," "
	JRST	STBCMD		;YES
	CAIN	T1,"-"		;DISPATCH ON "-"
	JRST	DSHCMD

	CAIL	T1,"A"+40	;CHECK FOR LOWER CASE
	CAILE	T1,"Z"+40
	JRST	.+2
	SUBI	T1,40

	PUSHJ	P,CKARG		;MUST BE A LETTER OR BAD. CLOSE OUT NUMBERS IN PROGRESS

	CAIN	T1,"W"		;START WATCHING?
	JRST	WCMD
	CAIN	T1,"D"		;W-MODE OFF?
	JRST	DCMD
	CAIN	T1,"P"		;START RECORDING PERFORMANCE ?
	JRST	PCMD
	CAIN	T1,"E"		;P-MODE OFF?
	JRST	ECMD
	CAIN	T1,"L"		;DISPATCH ON LETTERS THAT DON'T TAKE NUMBER ARGS
	JRST	LCMD
	CAIN	T1,"N"
	JRST	NCMD
	CAIN	T1,"U"
	JRST	UCMD
	CAIN	T1,"V"
	JRST	VCMD
	CAIN	T1,"Q"
	JRST	QCMD
	CAIN	T1,"M"
	JRST	MCMD		;MULTI-SCRIPT MODE
	CAIN	T1,"X"
	JRST	XCMD

	TLO	F,P.FACT
	MOVEI	T2,0		;CLEAR STORAGE ADDRESS FOR OTHER LETTERS
	CAIN	T1,"I"		;PICK UP STORAGE ADDRESS FOR LETTERS WITH +-ARGS
	MOVEI	T2,DELTI(D)
	CAIN	T1,"O"
	MOVEI	T2,DELTO(D)
	JUMPN	T2,LETTER	;GO HANDLE THESE

	TLO	F,P.NONG	;SET FLAG - NEGATIVE ARGS NOT ALLOWED
	CAIN	T1,"F"
	MOVEI	T2,DELTF(D)
	CAIN	T1,"R"
	MOVEI	T2,DELTR(D)
	SKIPN	T2		;IF NOT FOUND,
	TLZ	F,P.FACT	;CLEAR MULTIPLIER
	CAIN	T1,"C"		;PICK UP STORAGE ADDRESS FOR LETTERS WITH + ARGS
	MOVEI	T2,DELTC(D)
	CAIN	T1,"S"
	MOVEI	T2,DELTS(D)
	CAIN	T1,"T"
	MOVEI	T2,COUNT(D)

	JUMPN	T2,LETTER	;DID WE GET AN ADDRESS
	JRST	SYNERR		;NO, ILLEGAL CHARACTER. RETURN ERROR

SCNTXT:	CAIL	T1,LF		;TEXT LINE. DISPATCH ON LF
	CAILE	T1,FF
	JRST	.+2
	JRST	LFTXT
	CAIN	T1,CR		;DISPATCH ON CR
	JRST	CRTXT
	CAIN	T1,"#"		;DISPATCH ON "#"
	JRST	NUMTXT
	JRST	HVCHR		;PROCESS CHARACTER



EXPROC:	TLCN	F,P.LF+P.XCM	;"!" SEEN. CHECK START OF LINE, "!" FLAG, AND
	TLZA	F,P.LF+P.XCM
	TLNN	F,P.LF+P.XCM
	JRST	HVCHR		;RETURN CHAR IF TEXT LINE ("!" FLAG NOW CLEAR)
	TLON	F,P.LF
	JRST	SSCRPT		;EAT CHARACTER IF 1ST "!" IN LINE ("!" FLAG NOW SET)
	JRST	SYNERR		;ERROR IF "!" ELSEWHERE IN COMMAND LINE



ARROW:	TLOE	F,P.SPL		;"^" SEEN,SPECIAL HANDLING
	JRST	HVARR		;P.SPL WAS ALREADY SET
				;SO WE JUST HAVE AN ARROW
	TLNE	F,P.XCM		;YES. "!" ALREADY AT START OF LINE?
	JRST	SYNERR		;YES. "^" ILLEGAL IN COMMAND LINE
	TLO	F,P.ARR+P.ARRL+P.SPL	;SET "^" FLAG TO COMPLEMENT BIT 100
	JRST	SSCRPT		;GO PROCESS NEXT CHAR


LFTXT:	TLO	F,P.LF		;RESET FLAGS ON LINE FEED
	TLZN	F,P.ARRL	;BUT IF ^ LINE, DON'T SEND CR/LF

CRTXT:	TLNE	F,P.ARRL	;DON'T SEND CR ON A ^ LINE
	JRST	CRTXT1
	MOVEI	T2,P.LMOD	
	TDNN	T2,PFLAGS(D)	;ON CR OR LF SEE IF WE RETURN THEM
	JRST	HVCHR		;NO; MUST BE CR SO SEND IT TO PTY
CRTXT1:	TLNN	F,P.LF		;NO. L MODE WAS SET. LINE FEED?
	JRST	SSCRPT		;NO EAT CR & GO ON
	PUSHJ	P,OUTLOG	;OUTPUT LF ON RSP FILE
	JRST	HVLIN		;YES GO HANDLE COMPLETE TEXT LINE


NUMTXT:	MOVEI	T2,P.UMOD	;# IN TEXT. UMODE SET?
	TDNE	T2,PFLAGS(D)
	JRST	HVCHR		;NO, RETURN "#"
	MOVE	T3,[POINT 6,PTYUNT(D)]	;YES. PICK UP BYTE POINTER TO STRING OF SIXBIT DIGITS
NUMTX1:	ILDB	T1,T3		;GET DIGIT	
	JUMPE	T1,SSCRPT	;DONE, GET NEXT CHAR
	ADDI	T1,40		;CONVERT TO ASCII
	PUSHJ	P,SNDPTY	;SEND TO JOB
	JRST	NUMTX1		;LOOP FOR NEXT



DSHCMD:	TLON	F,P.DSH		;"-" SEEN IN COMMAND. SET FLAG
	TLNE	F,P.NIP+P.NRD	;LEGAL?
	JRST	SYNERR		;TWO "-" OR A "-" IN OR AFTER NUMBER ILLEGEL
	JRST	SSCRPT		;OK, GO SCAN NEXT CHAR.


NUMCMD:	TLNE	F,P.NRD		;DIGIT SEEN IN COMMAND. NUMBER ALREADY DONE?
	JRST	SYNERR		;YES. ILLEGAL
	TLON	F,P.NIP		;NO. SAY WE ARE IN MIDDLE OF NUMBER. WERE WE?
	MOVEI	T3,0		;NO. SO ZERO COUNT
	IMULI	T3,^D10		;RADIX CONVERSIONS - DECIMAL
	ADDI	T3,-"0"(T1)
	JRST	SSCRPT		;GO SCAN NEXT SCRIPT CHARACTER


STBCMD:	PUSHJ	P,CKARG		;SPACE OR TAB. CLOSE OUT NUMBER IN PROGRESS, IF ANY
	JRST	SSCRPT		;GO SCAN NEXT SCRIPT CHARACTER

WCMD:	TRNN	F,F.WCH		;WATCHING ANYTHING AT ALL ?
	JRST	CKNON		;NO , SO IGNORE
	CAML	I,NOWATC	;IS THIS PROCESS TO BE WATCHED ?
	JRST	CKNON		;NO,SO IGNORE
	MOVEI	T1,P.WCH	;YES,SO SET THE FLAG
	JRST	LUSET

DCMD:	TLNE	F,P.WCHALL	;SEE IF ALL LINES TO WATCH
	JRST	CKNON		;YES,IGNORE THIS COMMAND
	MOVEI	T1,P.WCH	;RESET WATCH FLAG
	JRST	NVCLR


PCMD:	TRNN	F,F.RSP		;RESP TIME FOR ANYTHING AT ALL ?
	JRST	CKNON		;NO,SO IGNORE
	CAML	I,NOLOG		;RESP TIME FOR THIS PROCESS ?
	JRST	CKNON		;NO,SO IGNORE
	MOVEI	T1,P.RSP	;YES,SO SET FLAG
	JRST	LUSET

ECMD:	TLNE	F,P.RSPALL	;SEE IF RESP TIME FOR ALL LINES
	JRST	CKNON		;YES,IGNORE THIS COMMAND
	MOVEI	T1,P.RSP	;RESET THE FLAG
	JRST	NVCLR


CRCMD:	ILDB	T1,PSCRPT(D)	;CR SEEN IN COMMAND LINE.
	PUSHJ	P,OUTMON	;MONITOR OUTPUT
	CAIL	T1,LF		;NEXT CHARACTER MUST BE LF
	CAILE	T1,FF
	JRST	SYNERR		;IF NOT AN ERROR.

LFCMD:	TLNE	F,P.NIP+P.NRD+P.DSH
	JRST	SYNERR		;LF SEEN IN COMMAND LINE. NUMBER LEFT OVER?
	JRST	SSCRPL		;GO SCAN NEXT LINE


SCNCMD:	TRO	F,F.SCN		;SEMI-COLON SEEN
	JRST	SSCRPT

COMCMD:	CAIL	T1,LF		;COMMENT LINE--CHECK FOR LF
	CAILE	T1,FF
	JRST	SSCRPT		;NO
	JRST	LFCMD		;YES

LCMD:	MOVEI	T1,P.LMOD	;L COMMAND. SET L MODE
	JRST	LUSET

NCMD:	MOVEI	T1,P.LMOD	;N COMMAND. CLEAR L MODE
	JRST	NVCLR

VCMD:	MOVEI	T1,P.UMOD	;V COMMAND. CLEAR U MODE

LUSET:	IORM	T1,PFLAGS(D)
	JRST	CKNON

UCMD:	MOVEI	T1,P.UMOD	;U COMMAND. SET U MODE

NVCLR:	ANDCAM	T1,PFLAGS(D)

CKNON:	TLNE	F,P.NRD		;WAS A NUMBER SUPPLIED BEFORE "L","N","U","V"?
	JRST	SYNERR		;YES, AN ERROR
	JRST	SSCRPT		;NO, GO SCAN NEXT SCRIPT CHARACTER


LETTER:	TLZE	F,P.NONG	;LETTER COMMAND. CHECK LEGALITY OF NEGATIVE NUMBERS
	JUMPL	T3,SYNERR
	MOVE	T1,T3
	TLZE	F,P.FACT	;SEE IF MULTIPLIER APPLICABLE
	IMUL	T1,DELFAC	;YES--INCLUDE IT
	MOVEM	T1,(T2)		;SET NUMBER INTO STORAGE LOCATION
	TLZ	F,P.NRD		;CLEAR NUMBER READY FLAG
	JRST	SSCRPT		;SCAN NEXT SCRIPT CHARACTER

QCMD:	TLZ	F,P.NRD
	JUMPE	T3,Q0CMD	;Q COMMAND.  IF 0 ARGUMENT, OPEN ENDED
	JUMPL	T3,SYNERR
	MOVEM	T3,QCOUNT(D)	;SAVE POSITIVE ARGUMENT
	JRST	SSCRPT

Q0CMD:	MOVEI	T1,P.QOK	;0Q COMMAND.  SET ERRORS OK
	JRST	LUSET

MCMD:	TLZ	F,P.NRD		;M COMMAND - ARG MEANS FEED THE FOLLOWING
	JUMPE	T3,M0CMD	; LINES ONLY TO PROCESS "ARG", 0 MEANS
	JUMPL	T3,SYNERR	; LEAVE MULTI - MODE
	SOS	T3		;SUBTRACT 1, PROCESS # IS 0 TO N INTERNALLY
	MOVEM	T3,PRONUM(D)	;SAVE ARG
	MOVEI	T1,P.MULT	;SET MULTI-MODE
	IORM	T1,PFLAGS(D)
	JRST	SSCRPT

M0CMD:	SETZM	PRONUM(D)	;CLEAR MULTI-MODE
	MOVEI	T1,P.MULT
	ANDCAM	T1,PFLAGS(D)
	JRST	SSCRPT

XCMD:	TLO	F,P.CTO		;X COMMAND.  START OF COMMENT TO OPERATOR
	TRNN	F,F.CTO
	JRST	CKNON
	OUTSTR	[ASCIZ /(/]
	PUSHJ	P,ERRMPF
	JRST	CKNON

CTO:	TRNE	F,F.CTO
	OUTCHR	T1		;CHARACTER WITHIN A COMMENT TO OPERATOR
	CAIE	T1,LF
	JRST	SSCRPT
	JRST	LFCMD

CKARG:	TLZE	F,P.NIP		;CHECK FOR NUMBER IN PROGRESS. CLEAR FLAG
	JRST	CKARG1		;YES
	TLNE	F,P.DSH		;NO, WAS "-" SEEN
	JRST	SYNERR		;YES. AN ERROR
	POPJ	P,		;NO, RETURN


CKARG1:	TLO	F,P.NRD		;NUMBER IS NOW READY
	TLZE	F,P.DSH		;CLEAR "-" FLAG
	MOVNS	T3		;COMPLEMENT SIGN IN CASE OF "-"
	POPJ	P,		;RETURN


SYNERR:	OUTSTR	[ASCIZ /
?Syntax error in script at line /]
	MOVE	T1,LINCNT(D)
	PUSHJ	P,TYPDEC
	OUTSTR	[ASCIZ / of process /]
	MOVEI	T1,1(I)
	PUSHJ	P,TYPDEC
	OUTSTR	[ASCIZ /
/]
	EXIT			;RETURN ON ERROR

CKCNT:	AOS	T1,NDONE(D)	;AT END OF SCRIPT. COUNT TIMES WE DID IT
	SKIPN	T2,COUNTO	;GET OPERATOR REQUESTED REPEAT COUNT
	MOVE	T2,COUNT(D)	;NONE REQUESTED--GET SCRIPT'S
	CAMGE	T1,T2		;ARE WE DONE?
	JRST	BEGSCP		;NO, START OVER AGAIN

IFN CYCLSW,<
	TRNN	F,F.CYC		;CYCLE SWITCH ON?
	JRST	RELPTY		;NO
	SOSG	T1,CYCLCT	;COUNT DOWN NUMBER OF CYCLES
	JRST	RELPTY		;DONE
	TRO	F,F.DOZ		;SET SLEEP FLAG
	JRST	BEGSCP		;START SCRIPT OVER AGAIN
>

RELPTY:	DO	(RELEAS)	;YES--RELEASE PTY
	SETZM	PTYNAM(D)	;FLAG THE RELEASE
	SETZM	JOBSB(I)	;CLEAR AREA IN JOB STATUS BLOCK
	SOS	A		;COUNT DOWN NUMBER OF ACTIVE PROCESSES
	JSP	T4,PRET		;RETURN TO CONTROL LOOP. SET PC TO POPJ
	POPJ	P,		;IDLE THIS PROCESS.
HVARR:	TLZ	F,P.ARR+P.ARRL+P.SPL	;"^^" SEEN, IGNORE SPECIAL HANDLING

HVCHR:	TLZE	F,P.SPL		;SEE IF SPECIAL HANDLING CODE BIT SET
	PUSHJ	P,SPECIAL
	PUSHJ	P,SNDPTY	;SEND IT TO THE JOB
	PUSHJ	P,OUTLOG	;OUTPUT ON RSP FILE
	TLNN	F,P.LF		;SEE IF WE ENDED A LINE
	JRST	SSCRPT		;NO, GO HANDLE NEXT CHARACTER

HVLIN:	SKIPG	NUMCHS(D)	;YES, WAS IT NULL?
	JRST	SYNERR		;IF SO, AN ERROR.
	MOVEI	T1,P.NFIR	;FLAG THAT NEXT RESPONSE COUNTS AS START OFLINE
	ANDCAM	T1,PFLAGS(D)
	MOVEI	T1,P.OLD	;WE HAVE A COMPLETE SCRIPT LINE
	TDNE	T1,PFLAGS(D)	;IS THIS 1ST LINE EVER?
	JRST	ADDIND		;NO
	IORM	T1,PFLAGS(D)	;YES, SET FLAG, NO LONGER VIRGIN
	SKIPN	T1,STAGO	;SEE IF OPERATOR SAID TO STAGGER
	MOVE	T1,DELTS(D)	;NO--USE STAGGER FROM SCRIPT
	IMUL	T1,I		;COMPUTE STAGGER INTERVAL AS INITIAL FREE TIME
	MOVEM	T1,FREE(D)

ADDIND:	SKIPL	T1,DELTI(D)	;INPUT DELAY OR RATE?
	JRST	ADDIN1		;DELAY
	IMUL	T1,NUMCHS(D)	;RATE. COMPUTE DELAY BASED ON NUMBER OF CHARACTERS
	MOVNS	T1

ADDIN1:	ADD	T1,FREE(D)	;TOTAL DELAY=FREE PLUS INPUT DELAY
	ADD	T1,T
	MOVEM	T1,TNEXT(D)	;SET EVENT TIME


IFN HUWSW,<
	TRNN	F,F.HUW		;HOLDUP MODE?
	JRST	OLOOP		;NO
	SOSLE	HLNCNT(I)	;DECREMENT LINE COUNT. DONE?
	JRST	OLOOP		;NO
	MOVSI	T1,377777	;SET UP INFINITY TIME
	MOVEM	T1,TNEXT(D)	;CAUSE WAIT FOREVER(HOLDING)
	SOSL	RCTR		;DECREMENT JOBS INITIALIZING. DONE?
	JRST	OLOOP		;NOT YET
	OUTSTR	[ASCIZ /JOBS WAITING. ENTER DELAY(SEC).  /]
	PUSHJ	P,ASKDEC
	MOVEI	T1,1		;DEFAULT IS 1 SEC.
	IMULI	T1,^D1000	;CONVERT TO MILLISEC
	MSTIME	T,		;GET THE TIME
	SUB	T,TSTART	;GET TIME FROM STARTUP
	SKIPGE	T
	ADD	T,[^D24*^D60*^D60*^D1000]
	ADD	T1,T		;SET UP WAKE TIME
	SETZM	DELFAC		;ZERO DELFAC
	AOS	DELFAC		;MAKE DELFAC=1
	SETZB	T2,T3
	TRZ	F,F.HUW		;TURN OFF FLAG-ALL NORMAL NOW
XLOOP:	MOVEM	T1,TNEXT(T3)	;SET UP WAKE TIME
	ADDI	T3,IMPSIZ	;INCREMENT INDEX
	CAMGE	T2,N		;DID LAST JOB?
	AOJA	T2,XLOOP	;NO INCREMENT AND LOOP BACK
>
OLOOP:	CAML	T,TNEXT(D)	;IS IT TIME YET TO SEND ON PTY?
	JRST	OUTLIN		;YES
	CAMLE	X,TNEXT(D)	;NO, UPDATE SKIP TIME IF .GT. EVENT TIME
	MOVE	X,TNEXT(D)
	JSP	T4,PRET		;RETURN TO PROCESS CONTROL (TO STOP)
	JRST	OLOOP		;LOOP

OUTLIN:	MOVE	T1,T		;IT IS TIME TO OUTPUT OVER PTY?
	SUB	T1,TNEXT(D)	;COMPUTE TYPE IN DELAY DUE TO POOR SCRIPT RESPONSE
	ADDM	T1,INPSKW(D)

	DO	(OUTPUT)	;DO OUTPUT UUO
	MOVEI	T1,P.MSYN	;CLEAR FLAG THAT PTY INPUT SEEN AFTER OUTPUT DONE
	ANDCAM	T1,PFLAGS(D)
	PUSHJ	P,CLOMON	;FLUSH MONITOR BUFFER IN CASE ITS A TTY & PROCESS 0

	MOVSI	T1,377777	;INFINITY TIME
	SKIPN	T2,DELTC(D)	;^C^C TIME OUT SPECIFIED?
	JRST	SINT1		;NO
	MOVE	T1,T2		;YES. PICK UP T + DELTC
	ADD	T1,T

SINT1:	MOVEM	T1,TINTR(D)	;STORE INTERRUPT TIME
	MOVEM	T,TSTLIN(D)	;STORE TIME WE STARTED LINE TO MEASURE RESPONSE
	MOVE	T1,JOBNO(D)	;GET STORED JOB NO
	RUNTIM	T1,		;GET RUNTIME FOR THE PTY JOB
	MOVEM	T1,TCPUST(D)	;STORE CPU TIME AT START OF LINE
	JRST	RLOOP		;GO WAIT FOR RESPONSE
SPECIAL: CAIN 	T1,"$"		;SEE IF ^$ IN SCRIPT
	JRST	OUTALT		;YES. OUTPUT ALTMODE
	CAIN	T1,"C"		;IS IT CONTROL-C ?
	JRST	CNTRL
;PUT HERE ALL OTHER CONTROL-CHARACTERS WHICH
;REQUIRE SUPRESSION OF CR,LF AT THE END OF LINE
	TRC	T1,100		;MAKE CONTROL-CHARACTER
	POPJ	P,

OUTALT:	MOVEI	T1,175		;ASCII OCTAL CODE FOR ALTMODE
	POPJ	P,

CNTRL:	TRC	T1,100
	TLO	F,P.ARRL	;SUPRESS CR,LF AT END OF LINE
	POPJ	P,


RLOOP1:	TRO	F,F.SSY1	;SET FLAG PROCESS WAITING FOR RESPONSE
	JSP	T4,PRET		;RETURN TO CONTROL LOOP (SLEEP)

RLOOP:	CAML	T,TINTR(D)	;IS IT INTERRUPT TIME?
	JRST	INTRPT		;YES
	CAMLE	X,TINTR(D)	;NO. UPDATE SLEEP TIME IF GT INTERRUPT TIME
	MOVE	X,TINTR(D)
	TRNN	F,F.JST		;SEE IF THIS MONITOR HAS JOBSTS
	HALT	.		;REALLY CANNOT WORK WITHOUT IT
RLOOPN:	JOBST	(T1)		;GET JOB STATUS
	TLNN	T1,JSTINP!JSTOUT	;SEE IF INPUT OR OUTPUT NEEDED
	JRST	RLOOP1		;NO--GO TO SLEEP
	TLNE	T1,JSTINP	;YES--SEE IF INPUT
	JRST	INLIN		;YES--GO GET IT
	MOVEI	T2,2
	TLNN	T1,JSTLOG	;SEE IF LOGGED IN
	SLEEP	T2,		;NO, SLEEP FOR A FEW SECONDS
	TLNN	T1,JSTLOG	;LOGGED IN ?
	JRST	LINDON		;NO,SO NO RUNTIME MEASUREMENTS
	HRRZS	T1,T1		;JOB NO IN RIGHT HALF
	MOVEM	T1,JOBNO(D)	;STORE JOB NO
	RUNTIM	T1,
	SUB	T1,TCPUST(D)	;SUBTRACT TIME AT START
	SKIPLE	T1		;DON'T ACCEPT -VE RUN TIME
	MOVEM	T1,TCPU(D)	;STORE CPU TIME FOR THIS LINE
				;YES--FALL INTO LINDON TO OUTPUT

LINDON:	TRO	F,F.SSY2	;READY FOR NEXT LINE. SET WOKEN UP FLAG
	MOVEI	T1,P.SSY	;SET LOST PT WAKE FLAG IF SLEPT TOO LONG
	TRNE	F,F.SSY3
	IORM	T1,PFLAGS(D)
	MOVE	T1,T		;TOTAL RESPONSE
	SUB	T1,TSTLIN(D)
	ADDB	T1,RESPON(D)
	SUB	T1,DELTR(D)	;COMPARE WITH LEGAL RESPONSE (NEG)
	SKIPLE	T1
	MOVEI	T1,0		;TOO LONG?
	SUB	T1,DELTF(D)	;YES. WAIT ONLY FREE TIME
	MOVNM	T1,FREE(D)	;TOTAL WAIT INCLUDES FREE TIME FROM SCRIPT
				;STORE FOR NEXT LINE INPUT DELAY.

	TRNN	F,F.RSP		;SEE IF RESP TIME FOR ANYTHING AT ALL ?
	JRST	LINDO1		;NO SO IGNORE
	MOVEI	T1,P.RSP	;SEE IF RESP TIME FOR THIS PROCESS
	TDNE	T1,PFLAGS(D)	
	PUSHJ	P,LOGRES	;YES. GO FORM UP LINE OF RESULTS
LINDO1:	TRNE	F,F.ERR		;NO,SEE IF ERROR MONITOR
	SKIPG	QCOUNT(D)	;YES--SEE IF TOO FEW QUESTION LINES BACK
	JRST	BEGLIN		;NO--GO HANDLE NEXT LINE.
	OUTSTR	[ASCIZ /??(/] ;YES--ISSUE PREFIX
	PUSHJ	P,ERRMPF
	OUTSTR	[ASCIZ /----too few errors----
/]
	JRST	BEGLIN		;GO HANDLE NEXT LINE

INLIN:	TRO	F,F.SSY2	;PTY HAS OUTPUT. SET WOKEN UP FLAG
	AOS	NUMOUT(D)	;COUNT BUFFERS
	MOVEI	T1,P.SSY	;SET LOST PTY TIME
	TRNE	F,F.SSY3
	IORM	T1,PFLAGS(D)
	MOVE	T1,T		;TOTAL REPONSE TIME
	SUB	T1,TSTLIN(D)
	ADDM	T1,RESPON(D)

	SKIPGE	T1,DELTO(D)	;OUTPUT DELAY OR RATE?
	JRST	ILIV		;RATE
	ADD	T1,T		;DELAY, GET NEXT EVENT TIME
	MOVEM	T1,TNEXT(D)

ILOPF:	CAML	T,TINTR(D)	;DELAY. INTERRUPT TIME?
	JRST	INTRPT		;YES
	CAML	T,TNEXT(D)	;END OF OUTPUT DELAY?
	JRST	ILOPFD		;YES
	CAMLE	X,TINTR(D)	;NO, UPDATE SLEEP TIME IF LESS THAN
	MOVE	X,TINTR(D)	; INTERRUPT OR EVENT TIME
	CAMLE	X,TNEXT(D)
	MOVE	X,TNEXT(D)
	JSP	T4,PRET		;RETURN TO CONTROL LOOP (SLEEP)
	JRST	ILOPF		;LOOP


ILIV:	PUSHJ	P,INPTY		;OUTPUT RATE. READ PTY
	IMUL	T3,DELTO(D)	;COMPUTE DELAY BASED ON NUMBER OF CHARS
	MOVNS	T3
	ADD	T3,T
	MOVEM	T3,TNEXT(D)	;GET NEXT EVENT TIME

ILOPV:	CAML	T,TINTR(D)	;INTERRUPT TIME?
	JRST	INTRPT		;YES
	CAML	T,TNEXT(D)	;END OF OUTPUT DELAY?
	JRST	ILOPVD
	CAMLE	X,TNEXT(D)	;YES
	MOVE	X,TNEXT(D)	;NO. UPDATE SLEEP TIME IF LESS THAN
	CAMLE	X,TINTR(D)	;INTERRUPT OR EVENT TIME
	MOVE	X,TINTR(D)
	JSP	T4,PRET		;RETURN TO CONTROL LOOP (SLEEP)
	JRST	ILOPV		;LOOP


ILOPFD:	PUSHJ	P,INPTY		;FIXED DELAY DONE. READ PTY

ILOPVD:	MOVE	T1,T		;RECORD DELAY IN OUTPUT DUE TO POOR SCRIPT RESPONSE
	SUB	T1,TNEXT(D)
	ADDM	T1,OUTSKW(D)
	MOVEM	T,TSTLIN(D)	;SET TIME WE GOT LINE TO MEASURE RESPONSE
	JRST	RLOOP		;GO WAIT FOR RESPONSE

FINTRP:	TRNN	F,F.JST		;FORCED INTERRUPT--SEE IF JOB STATUS UUO AVAILABLE
	JRST	INTRPT		;NO--PLOW AHEAD
	JOBST	(T1)		;YES--SEE IF A JOB THERE
	JUMPGE	T1,RELPTY	;NO--RELEASE PTY
	TLNN	T1,JSTINP	;YES--SEE IF IN INPUT NEEDED STATE
	JRST	INTRPT		;NO--SEND ^C^C AT IT
	TLNE	T1,JSTMON	;YES--SEE IF ALREADY AT MONITOR LEVEL
	AOS	PSCRPT(D)	;YES--BUMP SCRIPT BEYOND ^C
	MOVEI	T1,P.FINT	;MARK THAT WE HAVE PROCESSED INTERRUPT
	ANDCAM	T1,PFLAGS(D)
	JRST	LINDON		;GO ALLOW INPUT

INTRPT:	TRO	F,F.SSY2	;TIMED OUT. SET WOKEN UP FLAG
	MOVE	T1,T		;RECORD DELAY IN INTERRUPT DUE TO POOR SCRIPT RESPONSE
	SUB	T1,TINTR(D)
	ADDM	T1,INPSKW(D)

	MOVE	T1,TINTR(D)	;TOTAL RESPONSE TIME UP TO INTERRUPT POINT
	SUB	T1,TSTLIN(D)
	ADDM	T1,RESPON(D)
	MOVEM	T,TSTLIN(D)	;SET TIME WE STARTED HERE FOR FUTURE MEASUREMENTS

	MOVEI	T1,CONTC	;CONTROL C
	PUSHJ	P,SNDPTY	;SEND ONE TO JOB
	PUSHJ	P,SNDPTY	;SEND ANOTHER
	PUSHJ	P,OUTMON
	PUSHJ	P,OUTMON	;MONITOR CONTROL C'S IF PROCESS O
	PUSHJ	P,CLOMON	;FLUSH OUT MONITOR BUFFER IN CASE MONITORING ON TTY
	TRNN	F,F.JST		;SEE IF WE HAVE JOBSTS
	HALT	.		;REALLY CANNOT WORK WITHOUT IT
INTRP1:	DO	(OUTPUT)
	MOVSI	T1,377777
	MOVEM	T1,TINTR(D)	;SET INTERRUPT TIME TO INFINITY
	MOVEI	T1,P.MSYN!P.FINT!P.NNEW
	ANDCAM	T1,PFLAGS(D)	;CLEAR FLAG PTY DATA SEEN AFTER OUTPUT
	MOVEI	T1,P.INT
	IORM	T1,PFLAGS(D)	;SET FLAG THAT ^C^C'S DONE FOR LOG FILE
	AOS	PSCRPT(D)	;BUMP SCRIPT BEYOND ^C
	JRST	RLOOP		;GO WAIT FOR RESPONSE TO ^C^C

	SUBTTL	COMMUNICATE WITH THE JOB
	;ROUTINE TO SEND ONE CHARACTER TO THE PTY
	;CALL MOVE T1,CHARACTER
	;     PUSHJ P,SNDPTY
	;USES NO ACS.  MAINTAINS CHARACTER COUNT.

;MULTI-SCRIPT MODE ALLOWS CHARS TO BE SENT ONLY TO A SPECIFIC PROCESS.
;IF WE ARE IN MULTI-MODE ONLY SEND CHARS IF THEY ARE FOR THIS PROCESS.

SNDPTY:	AOS	NUMCHS(D)	;COUNT CHARACTERS SENT
	PUSH	P,T1		;SAVE T1
	MOVE	T1,PFLAGS(D)
	TRNN	T1,P.MULT	;ARE WE IN MULTI-MODE?
	JRST	SNDPTT		;NO, SEND THE CHAR
	CAME	I,PRONUM(D)	;YES, IS THIS CHAR FOR THIS PROCESS?
	JRST	T1POP		;NO, RESTORE T1 AND RETURN.
				;IF YES, SEND THE CHAR
SNDPTT:	POP	P,T1		;RESTORE T1
SNDPTC:	SOSG	PTYOBF+2(D)	;COUNT PTY OUTPUT SPACE
	JRST	SNDPTB		;IF NO SPACE LEFT
	IDPB	T1,PTYOBF+1(D)	;STORE CHARACTER
	POPJ	P,		;RETURN

SNDPTB:	DO	(OUTPUT)	;IF FULL, SEND IT TO JOB AND PROCEED
	JRST	SNDPTC

	;SUBROUTINE TO GET PTY INPUT (TTY OUTPUT)

INPTY:	MOVEI	T2,P.MSYN	;SUBROUTINE TO READ PTY.
	DO	(INPUT)		;DO INPUT UUO
	MOVE	T3,PTYIBF+2(D)	;ADD COUNT TO TOTAL CHAR RECEIVED
	ADDM	T3,NUMCHR(D)
	JUMPE	T3,NULBUF	;IGNORE BUFFERS WITH ZERO WORD COUNT
	TRNE	F,F.ERR!F.WCH	;SEE IF ERROR MONITORING OR WATCHING REQUESTED
	JRST	INPTY3		;YES--MUST EXAMINE ALL OUTPUT

INPTY1:	SOSGE	PTYIBF+2(D)	;NO. WE LOOK FOR NON NULL CHAR.
	JRST	NULBUF		;NOT FOUND
	ILDB	T1,PTYIBF+1(D)	;GET CHAR.
	JUMPE	T1,INPTY1	;LOOP IF NULL

	IORM	T2,PFLAGS(D)	;NON NULL SEEN. SET DATA SEEN AFTER OUTPUT FLAG
	POPJ	P,		;RETURN

INPTY3:	MOVEI	T4,P.WCH
	TDNN	T4,PFLAGS(D)	;SEE IF WATCH THIS PROCESS
	JRST	INPTY1		;NO
				;YES,SO FALL INTO IMPMON


INPMON:	SOSGE	PTYIBF+2(D)	;WE MONITOR
	JRST	INPTY2		;DONE?
	ILDB	T1,PTYIBF+1(D)	;NO. GET CHAR.
	JUMPE	T1,INPMON	;EAT NULLS
	PUSHJ	P,OUTMON	;MONITOR THE NON-NULL CHARACTER
	IORM	T2,PFLAGS(D)
	CAIN	T1,RUBOUT	;SEE IF RUBOUT
	JRST	INPMON		;YES--DON'T AFFECT MONITORING
	TRNE	F,F.ERR		;IS ERROR MONITOR REQUESTED?
	PUSHJ	P,ERRMON	;YES--GO TO ERROR MONITOR
	JRST	INPMON		;GO ON WITH NEXT CHARACTER


INPTY2:	TDNE	T2,PFLAGS(D)	;DONE. DID WE SEE ANY NON-NULLS?
	JRST	CLOMON		;YES GO FLUSH MONITOR BUFFER & RETURN


NULBUF:	MOVNS	T3		;ALL NULLS. FIX UP COUNT TO WHAT IT WAS
	ADDM	T3,NUMCHR(D)	;RESTORE T3 TO ZERO, NO CHARS WERE RECEIVED.
	MOVEI	T3,0
	POPJ	P,		;RETURN

	SUBTTL	TELETYPE I/O ROUTINES
	;SUBROUTINE TO GET "YES" OR "NO" ANSWER
	;CALL	PUSHJ P,ASKYNO
	;	NO RETURN
	;	YES RETURN

ASKYNO:	PUSHJ	P,TTYIN
	PUSHJ	P,GETWRD
	MOVEI	T1,0		;NO
ASKYN1:	JUMPE	T3,YNOK		; <CR> MEANS DEFAULT
	CAME	T3,[SIXBIT /N/]
	CAMN	T3,[SIXBIT /NO/]
	JRST	YNOK
	MOVEI	T1,1
	CAME	T3,[SIXBIT /Y/]
	CAMN	T3,[SIXBIT /YES/]
	JRST	YNOK

	OUTSTR	[ASCIZ /? Y or N, please
/]
	JRST	ASKYNO

YNOK:	JUMPN	T1,CPOPJ1
	POPJ	P,

;SAME AS ASKYNO, BUT DEFAULT IS YES.
;** NOTE ** THIS DOESN'T WORK IF WE GET TO "? Y OR N"

ASKNYS:	PUSHJ	P,TTYIN
	PUSHJ	P,GETWRD
	MOVEI	T1,1		;YES
	JRST	ASKYN1		;<CR> MEANS YES

	;SUBROUTINE TO RETURN POSITIVE DECIMAL INTEGER
	;CALL	PUSHJ P,ASKDEC
	;	NON-SKIP RETURN IF NULL (DEFAULT)  T1=0
	;	SKIP RETURN NUMBER IN T1

ASKDEC:	PUSHJ	P,TTYIN
	MOVEI	T1,0
	ILDB	T3,T2
	JUMPE	T3,CPOPJ

ASKDE1:	CAIL	T3,"0"
	CAILE	T3,"9"
	JRST	ASKDE2
	IMULI	T1,^D10
	ADDI	T1,-"0"(T3)
	ILDB	T3,T2
	JUMPN	T3,ASKDE1
	JRST	CPOPJ1

ASKDE2:	OUTSTR	[ASCIZ /?Positive decimal numbers please
/]
	JRST	ASKDEC



;SUBROUTINE TO GET AN OCTAL INTEGER
;MOVE T2, BYTE POINTER FOR INPUT
;PUSHJ P,GETOCT
;RETURN WITH FIELD IN T3
;BREAKS ARE ANY NON-OCTAL DIGIT, RETURNED IN T1

GETOCT:	SETZ	T3,
GETOC1:	ILDB	T1,T2		;GET NEXT CHAR
	CAIL	T1,"0"		;COMPARE IF OCTAL DIGIT
	CAILE	T1,"7"
	POPJ	P,		;NO--RETURN
	TLNE	T3,700000	;OK--CHECK FOR OVERFLOW
	POPJ	P,		;YES--RETURN
	ASH	T3,3		;MULT RESULT BY 8
	ADDI	T3,-"0"(T1)	;ADD IN THIS DIGIT
	JRST	GETOC1		;LOOP

	;SUBROUTINE TO RETURN DEVICE, FILE NAME & EXTENSION
	;SET UP DEFAULTS IN AC1,AC2, AC3
	;NON-SKIP RETURN IF NULL RESPONSE
	;UPON SKIP RETURN DEFAULTS OR VALUES IN AC1, AC2, AC3, AC4
	;AC1=FILE NAME, AC2=EXT, AC3=DEVICE, AC4=DIRECTORY

GETFIL:	SETZM	AC4		;CLEAR  DIRECTORY
	PUSHJ	P,TTYIN		;GET TTY LINE
	PUSHJ	P,GETWRD	;GET SIXBIT FIELD
GETFI0:	CAIE	T1,":"		;BREAK ":"?
	JRST	GETFI1		;NO
	JUMPE	T3,.+2		;NULL--LEAVE DEFAULT
	MOVE	AC3,T3		;GET DEVICE
	PUSHJ	P,GETWRD	;GET SIXBIT FIELD

GETFI1:	CAIN	T1,"."		;WAS BREAK "." ?
	JRST	GETFI5		;YES,GOT FILENAME
	CAIN	T1,"["		;NO,WAS IT "[" THEN ?
	JRST	GETFI5		;YES,GOT FILENAME
	CAIE	T1,00		;WAS IT <LF> ?
	JRST	GETFI2		;NONE OF ABOVE,LEAVE DEFAULT
	JUMPE	T3,.+2		;SKIP IF NULL;LEAVE DEFAULT
	MOVE	AC1,T3		;YES,GET FILENAME AND RETURN
	JRST	GETFI3		;SKIP RETURN
GETFI5:	JUMPE	T3,.+2		;NULL--LEAVE DEFAULT
	MOVE	AC1,T3		;SET FILE NAME
	PUSHJ	P,GETWRD	;GET SIXBIT FIELD
	TRNE	T3,-1
	JRST	GETFIX
	HLLZ	AC2,T3		;STORE EXT

GETFI2:	CAIE	T1,"["		;CHECK FOR DIRECTORY TYPED
	JRST	GETFI3		;NO--RETURN
	PUSHJ	P,GETOCT	;INPUT PROJECT NUMBER

	CAIN	T1,","		;MUST END WITH A COMMA
	CAILE	T3,377777	;MUST BE SMALL
	JRST	GETFIX		;NO--ERROR
	HRLZM	T3,AC4		;OK--SAVE
	PUSHJ	P,GETOCT	;INPUT PROGRAMMER NUMBER
	CAIN	T1,"]"		;MUST END WITH RIGHT BRACKET
	CAILE	T3,377777	;MUST BE SMALL
	JRST	GETFIX		;NO-- ERROR
	HRRM	T3,AC4		;OK--SAVE
	ILDB	T1,T2		;SUCK UP NEXT CHAR
GETFI3:	JUMPE	AC1,GETFIN	;FILE NAME IS REQUIRED IF DIRECTORY
GETFI4:	PUSHJ	P,ALPH
	JRST	CPOPJ1		;SKIP RETURN

GETFIX:	OUTSTR	[ASCIZ /?File format error--type dev:file.ext[p,pn]
/]
	JRST	GETFIL		;TRY AGAIN

GETFIN:	MOVE	T2,AC3		;NO FILE NAME--SEE IF DIRECTORY DEVICE
	DEVCHR	T2,		;ASK MONITOR
	TLNN	T2,DEVDIR
	JRST	GETFI4		;NO--LET IT PASS
	JRST	GETFIX		;YES--NAME REQUIRED

	;SUBROUTINE TO RETURN NEXT SIX BIT FIELD
	;MOVE T2, BYTE POINTER FOR INPUT
	;PUSH, P, GETWRD
	;RETURN WITH FIELD IN T3
	;BREAKS ARE NON-ALPHANUMERIC OR GT 6 CHARS

GETWRD:	MOVE	T4,[POINT 6,T3]
	MOVEI	T3,0

GETWR1:	ILDB	T1,T2
	PUSHJ	P,ALPH		;GET ALPHANUMERIC
	POPJ	P,		;BREAK FOUND
	TRC	T1,40
	TRNE	T3,77
	POPJ	P,		;RETURN IF GT 6 CHARS
	IDPB	T1,T4
	JRST	GETWR1


;SUBROUTINE TO CHECK CHARACTER
;RETURNS IF NON-ALPHANUMERIC
;SKIP-RETURNS IF ALPHA-NUMERIC
;ENTER WITH CHARACTER IN T1
;DISTURBS NO REGISTER

ALPH:	CAIL	T1,"0"
	CAILE	T1,"Z"
	POPJ	P,
	CAILE	T1,"9"
	CAIL	T1,"A"
	JRST	CPOPJ1
	POPJ	P,

	;SUBROUTINE TO GET COMMAND LINE
	;CALL PUSHJ P, TTYIN
	;RETURNS ASCIZ STRING. BYTE POINTER IN T2
	;EATS TABS, SPACES, CR, BREAK IS LF, VT, FF, ^Z, ALT, OR 81 RESULTANT CHARS

TTYIN:	MOVE	T2,[POINT 7,COMLIN]
	MOVEI	T3,20*5		;SET MAX LINE LENGTH

TTYIN1:	PUSHJ	P,TTYGET
	JRST	TTYIN2
	SOJL	T3,TTYIN2	;PROTECT LENGTH OF LINE
	IDPB	T1,T2
	JRST	TTYIN1

TTYIN2:	MOVEI	T1,0
	IDPB	T1,T2
	MOVE	T2,[POINT 7,COMLIN]
	POPJ	P,



	;SUBROUTINE TO GET NEXT TTY CHAR
	;CALL PUSH, P,TTYGET
	;     BREAK RETURN
	;     NO BREAK RETURN
	;EATS TABS, SPACES, CR, RUBOUT, BREAK IS LF

TTYGET:	INCHWL	T1
	JUMPE	T1,TTYGET
	CAIL	T1,"a"		;LOWER CASE
	CAILE	T1,"z"
	SKIPA
	SUBI	T1,40
	CAIE	T1,HT
	CAIN	T1," "
	JRST	TTYGET
	CAIE	T1,RUBOUT
	CAIN	T1,CR
	JRST	TTYGET
	CAIE	T1,CONTZ
	CAIN	T1,ALT33
	POPJ	P,
	CAIE	T1,ALT175
	CAIN	T1,ALT176
	POPJ	P,
	CAIL	T1,LF
	CAILE	T1,FF
CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,

	;SUBROUTINE TO TYPE-OUT A SIXBIT WORD
	;ENTERRED WITH T2=WORD
	;USES T1, T2

TYPSX1:	LSHC	T1,6		;GET NEXT CHARACTER
	ADDI	T1,40		;CONVERT TO ASCII
	OUTCHR	T1		;SEND TO TTY

TYPSIX:	MOVEI	T1,0		;CLEAR CHARACTER
	JUMPN	T2,TYPSX1	;LOOP UNTIL REST IS BLANK
	POPJ	P,		;RETURN


	;TYPE CARRIAGE RETURN-LINE FEED

TYPCRL:	OUTSTR	[ASCIZ /
/]
	POPJ	P,


	;TYPE DECIMAL OR OCTAL NUMBER
	;NUMBER IN T1; USES T1, T2, T3

TYPDEC:	MOVEI	T3,^D10
	JRST	TYPRDX
TYPOCT:	MOVEI	T3,10

TYPRDX:	IDIV	T1,T3
	HRLM	T2,(P)
	SKIPE	T1
	PUSHJ	P,TYPRDX
	HLRZ	T1,(P)
	ADDI	T1,"0"
	OUTCHR	T1
	POPJ	P,

	;TYPE OUT CURRENT TIME AS HH:MM:SS (TRUNCATED)
	;PRESERVES T=TIME
	;USES T1, T2, T3, T4

TYPTIM:	MOVE	T1,T		;GET TIME
	IDIVI	T1,^D1000	;CONVERT TO SECONDS
	IDIVI	T1,^D3600	;GET HOURS
	JUMPE	T1,TYPTI1	;SKIP IF 0 HOURS
	PUSHJ	P,TYPTWO	;OUTPUT HOURS
	OUTSTR	[ASCIZ /:/]
TYPTI1:	MOVE	T1,T2		;RETRIEVE MIN/SEC
	IDIVI	T1,^D60		;GET MINUTES
	PUSHJ	P,TYPTWO	;OUTPUT MINUTES
	OUTSTR	[ASCIZ /:/]
	MOVE	T1,T2		;RETRIEVE SEC
				;FALL INTO TYPTWO TO OUTPUT SECONDS

	;TYPE TWO DECIMAL DIGITS FROM T1
	;USES T3, T4

TYPTWO:	MOVE	T3,T1		;GET NUMBER
	IDIVI	T3,^D10		;GET TENS
	ADDI	T3,"0"		;CONVERT TO ASCII
	OUTCHR	T3
	ADDI	T4,"0"		;CONVERT UNITS TO ASCII
	OUTCHR	T4
	POPJ	P,

	SUBTTL	INTERACTIVE OPERATOR HANDLING
OPER:
OPRET:	POPJ	P,		;TEMP**********

	SUBTTL	OUTPUT HEADERS
	;SEND TITLE LINE TO A FILE
	;CALL:	MOVEI	AC1,OUTCHAR ROUTINE
	;	PUSHJ	P,TITLE
	;USES AC2-4, T1-2

TITLE:	TRZ	F,F.LZR		;SUPPRESS LEADING ZEROES
	MOVEI	T2,[ASCIZ /	S I M U L A T E D   S Y S T E M   R U N

	Monitor: /]
	PUSHJ	P,LSTSTR
	MOVSI	T2,-5		;OUTPUT SYSTEM NAME
TITLE1:	MOVEI	T1,11
	HRLI	T1,(T2)
	GETTAB	T1,
	  MOVEI	T1,0
	MOVEM	T1,CONFIG(T2)
	AOBJN	T2,TITLE1
	MOVEI	T2,CONFIG
	PUSHJ	P,LSTSTR
	MOVEI	T2,[ASCIZ /
	Script: /]
	PUSHJ	P,LSTSTR
	MOVE	T2,NAME
	PUSHJ	P,LSTSIX	;OUTPUT SCRIPT NAME.EXT%VER
	MOVEI	T1,"."
	PUSHJ	P,(AC1)
	MOVE	T2,NAME+1
	PUSHJ	P,LSTSIX
	MOVEI	T1,"%"
	SKIPE	T2,NAME+2
	PUSHJ	P,(AC1)
	PUSHJ	P,LSTSIX
	MOVEI	T2,[ASCIZ /    Number of Jobs: /]
	PUSHJ	P,LSTSTR
	MOVEI	AC3,1(N)
	PUSHJ	P,LSTNUM

	MOVEI	T2,[ASCIZ /
	Date: /]
	PUSHJ	P,LSTSTR
	DATE	AC2,
	IDIVI	AC2,^D31
	ADDI	AC3,1
	PUSHJ	P,LSTNUM	;OUTPUT DAY
	IDIVI	AC2,^D12
	MOVEI	T2,[ASCIZ /-Jan/
		    ASCIZ /-Feb/
		    ASCIZ /-Mar/
		    ASCIZ /-Apr/
		    ASCIZ /-May/
		    ASCIZ /-Jun/
		    ASCIZ /-Jul/
		    ASCIZ /-Aug/
		    ASCIZ /-Sep/
		    ASCIZ /-Oct/
		    ASCIZ /-Nov/
		    ASCIZ /-Dec/] (AC3)
	PUSHJ	P,LSTSTR	;OUTPUT MONTH
	MOVEI	T1,"-"
	PUSHJ	P,(AC1)
	MOVEI	AC3,^D64(AC2)
	PUSHJ	P,LSTNUM	;OUTPUT YEAR

	MOVEI	T2,[ASCIZ /    Time: /]
	PUSHJ	P,LSTSTR
	MOVE	AC2,TSTART
IFN CYCLSW,<
	TRNE	F,F.CYC
	MSTIME	AC2,
>
	IDIVI	AC2,^D1000
	CAIL	AC3,^D500
	ADDI	AC2,1
	IDIVI	AC2,^D3600
	EXCH	AC2,AC3
	PUSHJ	P,LSTNUM	;OUTPUT HOURS
	TRO	F,F.LZR		;PRINT LEADING ZEROES
	MOVEI	T1,":"
	PUSHJ	P,(AC1)
	IDIVI	AC2,^D60
	EXCH	AC2,AC3
	PUSHJ	P,LSTNUM	;OUTPUT MINUTES
	MOVEI	T1,":"
	PUSHJ	P,(AC1)
	MOVE	AC3,AC2
	PUSHJ	P,LSTNUM	;OUTPUT SECONDS

	MOVEI	T2,[ASCIZ /

/]
				;FALL INTO LSTSTR

	;LIST STRING TERMINATED BY NULL
	;CALL:	MOVEI	AC1,OUTCHAR ROUTINE
	;	MOVEI	T2,STRING
	;	PUSHJ	P,LSTSTR
	;USES T1,T2

LSTSTR:	TLOA	T2,440700	;CONVERT TO POINTER
LSTST1:	PUSHJ	P,(AC1)		;OUTPUT CHARACTER
	ILDB	T1,T2		;FETCH NEXT CHARACTER
	JUMPN	T1,LSTST1	;LOOP TO END
	POPJ	P,


	;LIST A TWO DIGIT DECIMAL NUMBER--WITH OPTIONAL SUPPRESSION
	;CALL:	MOVEI	AC3,NUMBER (0-99)
	;	MOVEI	AC1,OUTCHAR ROUTINE
	;	PUSHJ	P,LSTNUM
	;USES AC3-4,T1

LSTNUM:	IDIVI	AC3,^D10	;SEPARATE DIGITS
	MOVEI	T1,"0"(AC3)	;GET TENS
	TRNN	F,F.LZR		;UNLESS LEADING ZEROES REQUESTED
	CAIE	T1,"0"		;SUPPRESS FIRST ZERO
	PUSHJ	P,(AC1)		;OUTPUT
	MOVEI	T1,"0"(AC4)	;GET UNITS
	PJRST	(AC1)		;OUTPUT AND RETURN


	;LIST SIXBIT WORD
	;CALL:	MOVEI	AC1,OUTCHAR ROUTINE
	;	MOVE	T2,SIXBIT WORD
	;	PUSHJ	P,LSTSIX
	;USES T1,T2

LSTSX1:	LSHC	T1,6		;GET NEXT CHARACTER
	ADDI	T1,40		;CONVERT TO ASCII
	PUSHJ	P,(AC1)		;SEND IT TO FILE

LSTSIX:	MOVEI	T1,0		;CLEAR CHARACTER
	JUMPN	T2,LSTSX1	;LOOP IF NOT DONE
	POPJ	P,		;RETURN

TITMSR:	ASCIZ	/( * indicates job interrupted by ^C^C after timeout )
( + indicates response time may be lower than measured )

     Time  Job  Ch in   Out Buffers Cpu-time  Response  Delay in    Out

/
TOTMSG:	ASCIZ /
        Job    Time   CPU-Time  Response    Char in  Char out   Buffers  Delay in  Delay out  Lines
/
SUBTTL	MONITOR PROCESSES
	;MONITOR PROCESSES ON A DEVICE
	;EACH LINE SENT OR RECEIVED IS PRECEEDED BY THE PROCESS NUMBER

	;CALL:	MOVEI	T1,CHAR
	;	PUSHJ	P,OUTMON
	;USES T1,T4		PREFIXES NEW LINES

	;CALL:	MOVEI	T4,CHAR
	;	PUSHJ	P,OUTMO2
	;PRESERVES ACS		SUPPRESSES EXTRA <CR>,<LF>

	;CALL:	MOVEI	T4,CHAR
	;	PUSHJ	P,OUTMOC
	;PRESERVES ACS		JUST SENDS

	;CALL:	MOVEI	T1,CHAR
	;	PUSHJ	P,OUTMOT
	;SAME AS OUTMOC EXCEPT FROM T1, USES T4

OUTMON:	TRNN	F,F.WCH		;RETURN IF NOT WATCHING AT ALL
	POPJ	P,
	MOVEI	T4,P.WCH	
	TDNN	T4,PFLAGS(D)	;RETURN IF NOT WATCHING THIS PROCESS
	POPJ	P,
	PUSH	P,T1		;PRESERVE CHARACTER
	CAME	I,LASMON	;SEE IF SAME PROCESS AS LAST MONITORED
	PUSHJ	P,OUTMO6	;NO--PRETEND IT IS A NEW LINE
	POP	P,T1		;RESTORE CHARACTER
	MOVEM	I,LASMON	;REMEMBER THIS MONITORING

	CAIL	T1,LF		;SEE IF AT END OF A LINE YET
	CAILE	T1,FF		;LF, VT, FF
	JRST	.+2		;NO
	JRST	OUTMO6		;YES--SEND LINE FEED
	MOVEI	T4,P.NNEW	;SEE IF AT START OF A LINE
	AND	T4,PFLAGS(D)
	JUMPN	T4,OUTMO7	;NO--JUST TYPE CHARACTER
	MOVE	T4,NOWATC	;YES--SEE IF WATCHING MORE THAN ONE
	TRNN	T4,-2
	JRST	OUTMO7		;NO--JUST TYPE CHARACTER

	PUSH	P,T3
	MOVE	T3,I		;INDENT AS FCTN OF PROCESS
	LSH	T3,1		;2*I SPACES
	TRNE	F,F.TTMN	;EXCEPT IF TTY MONITOR
	MOVEI	T3,0		;DON'T
	MOVEI	T4," "
	PUSHJ	P,OUTMO2
	SOJGE	T3,.-1
	POP	P,T3		;RESTORE 

	MOVEI	T4,"("		;YES--PRECEED LINE BY (NN)
	PUSHJ	P,OUTMO2
	MOVEI	T4,^D10		;CHECK MAX NUMBER
	CAMLE	T4,NOWATC
	JRST	OUTMO9		;LESS THAN 10, DO 1 DIGIT #'S
	MOVEI	T4,"0"
	CAIL	I,^D9
	MOVEI	T4,"1"
	PUSHJ	P,OUTMO2
OUTMO9:	MOVEI	T4,"1"(I)
	CAILE	T4,"9"
	SUBI	T4,^D10
	PUSHJ	P,OUTMO2
	MOVEI	T4,")"
	PUSHJ	P,OUTMO2
	MOVEI	T4," "
	PUSHJ	P,OUTMO2
OUTMO7:	MOVEI	T4,P.NNEW	;FLAG MIDDLE OF LINE
	ORM	T4,PFLAGS(D)
	MOVE	T4,T1		;COPY CHAR

	CAIGE	T4,40		;CONTROL?
	JRST	OUTMO1		;YES

	CAIE	T4,ALT175	;NO. ALTMODES?
	CAIN	T4,ALT176
OUTMO5:	MOVEI	T4,"$"		;YES. PICK UP DOLLAR SIGN
	JRST	OUTMO2		;OUTPUT THE CHAR

OUTMO1:	CAIE	T4,BEL
	CAIN	T4,HT		;OK TO OUTPUT TAB,
	JRST	OUTMO2
	CAIN	T4,CR		;CARRIAGE RETURN
	JRST	OUTM10
	CAIN	T4,ALT33	;IS IT ALTMODE?
	JRST	OUTMO5		;IF SO, GO SEND "$"

	PUSH	P,T4		;SAVE CHAR
	MOVEI	T4,"^"		;OUTPUT "^"
	PUSHJ	P,OUTMO2	;RETURN CHAR
	POP	P,T4		;MAKE PRINTING
	TRC	T4,100

OUTMO2:	TRNN	F,F.WCH		;OUTPUT CHAR. IS WATCHING ENABLED AT ALL ?
	POPJ	P,		;NO, RETURN
	PUSH	P,T1		;SAVE T1
	MOVEI	T1,P.WCH
	TDNN	T1,PFLAGS(D)	;SEE IF WATCHING THIS PROCESS
	JRST	T1POP		;NO
	POP	P,T1		;YES,RESTORE T1 AND PROCEED
	CAIL	T4,LF		;SEE IF NEW LINE
	CAILE	T4,CR
	JRST	OUTMOC		;NO
	CAIN	T4,CR		;YES--SEE IF CRET
	TRNN	F,F.MCR		;YES--CHECK IF CRET LAST
	TRNE	F,F.MLF		;NO--SEE IF LF LAST
	POPJ	P,		;YES--IGNORE
OUTMOC:	SOSG	MONBUF+2	;YES, BUFFER SPACE?
	JRST	OUTMO4		;NO
OUTMO3:	IDPB	T4,MONBUF+1	;STORE CHAR
	TRZ	F,F.MCR!F.MLF
	CAIN	T4,CR		;SEE IF CRET SENT
	TRO	F,F.MCR
	CAIN	T4,LF		;SEE IF LFEED SENT
	TRO	F,F.MLF
	POPJ	P,		;RETURN

OUTMO4:	OUT	MONCHN,		;DO OUTPUT ON MONITOR DEVICE
	JRST	OUTMO3		;OK
	JRST	MONERR		;ERROR

	IFN	DEBUG,<
OUTM10:	TRNN	F,F.DBG		;SEE IF DEBUG MODE
	JRST	OUTMO8		;NO--JUST SEND <CR>
				;YES--SEND <CR><LF>
>

OUTMO6:	MOVEI	T4,CR		;GIVE A FREE CARRIAGE RETURN
	PUSHJ	P,OUTMO2
	MOVEI	T1,LF		;ISSUE AS A LINE FEED

	IFE	DEBUG,<OUTM10:>
OUTMO8:	MOVEI	T4,P.NNEW	;NEW LINE--SET FLAG
	ANDCAM	T4,PFLAGS(D)
	MOVE	T4,T1		;RESTORE CHARACTER
	JRST	OUTMO2		;GO OUTPUT IT


OUTMOT:	MOVE	T4,T1
	PJRST	OUTMOC

T1POP:	POP	P,T1		;RESTORE T1
	POPJ	P,		;RETURN

CLOMON:	CAML	I,NOWATC	;FLUSH BUFFERS IF PROCESS MONITORED
	POPJ	P,
	TRC	F,F.WCH+F.TTMN	;IF WE ARE MONITORING AND IF DEVICE TTY IS A TTY
	TRCN	F,F.WCH+F.TTMN
	OUT	MONCHN,
	POPJ	P,

MONERR:	OUTSTR	[ASCIZ /?Error on device. Monitoring stopped
/]
	CLOSE	MONCHN,		;CLOSE OUT MONITORING.
	TRZ	F,F.WCH		;CLEAR FLAG TO SURPRESS FUTURE MONITORING
	POPJ	P,		;RETURN


	;OUTPUT PTY STATUS
	;ENTERRED WITH PTY (JOBSTS) STATUS IN T1
	;USES T3,T4
	;IF MONITORING AND STATUS CHANGED, THEN SEND "[\NN\]"
	;WHERE NN IS THE HIGH SIXBITS FROM JOBSTS UUO

	IFN	DEBUG,<
OUTSTS:	MOVEI	T3,P.WCH
	TDNN	T3,PFLAGS(D)	;SEE IF WATCHING THIS PROCESS
	POPJ	P,		;NO,SO RETURN
	TRC	F,F.WCH!F.DBG
	TRCN	F,F.WCH!F.DBG	;SEE IF MONITORING AND DEBUGGING
	CAMN	T1,JOBSB(I)	;SEE IF DIFFERENT
	POPJ	P,		;RETURN IF NO TO EITHER
	PUSH	P,T1		;SAVE
	MOVEI	T1,"["		;SEND PREFIX
	PUSHJ	P,OUTMON
	MOVEI	T1,"\"
	PUSHJ	P,OUTMON
	LDB	T1,[POINT 3,(P),2]	;SEND STATUS BITS
	ADDI	T1,"0"
	PUSHJ	P,OUTMON
	LDB	T1,[POINT 3,(P),5]
	ADDI	T1,"0"
	PUSHJ	P,OUTMON
	MOVEI	T1,"\"		;SEND SUFFIX
	PUSHJ	P,OUTMON
	MOVEI	T1,"]"
	PUSHJ	P,OUTMON
	POP	P,T1		;RESTORE
	POPJ	P,
>

	SUBTTL	MONITOR JOB OUTPUT FOR ERRORS (LOG ON TTY)
	;SUBROUTINE TO MONITOR OUTPUT FOR ERRORS
	;ENTERRED FOR EACH NON-NULL, NON-RUBOUT CHARACTER RECIEVED
	;T1=CHARACTER,  ALTERS  T4
	;AN ERROR LINE IS DEFINED AS A LINE WHICH STARTS WITH
	;A "?".  START OF LINE IS THE FIRST NON-NULL OR RUBOUT
	;FOLLOWING A LF,VT,FF, OR TTY INPUT

ERRMON:	MOVE	T4,PFLAGS(D)	;GET PROCESS FLAGS
	CAIL	T1,LF		;CHECK FOR END-OF-LINE
	CAILE	T1,FF
	JRST	ERRMCH		;NO--PROCESS CHARACTER
	TRZE	T4,P.ERR	;YES--CLEAR ERROR LINE FLAG
	OUTCHR	[LF]		;IF END OF ERROR LINE, SEND LINE-FEED
	TRZ	T4,P.NFIR	;FLAG FOR START OF LINE
ERRMRT:	MOVEM	T4,PFLAGS(D)	;RESTORE FLAGS TO MEMORY
	POPJ	P,		;RETURN TO CALLER

ERRMCH:	TROE	T4,P.NFIR	;SEE IF FIRST CHARACTER--FLAG SUBSEQUENT
	JRST	ERRMNF		;NOT FIRST--SEE IF ALREADY AN ERROR LINE
	CAIN	T1,"?"		;FIRST--SEE IF ERROR LINE
	TRNE	T4,P.QOK	;YES--SEE IF ? IS UNEXPECTED
	JRST	ERRMRT		;NO--RESTORE FLAGS AND RETURN
	SOSL	QCOUNT(D)	;YES--SEE IF ANY PREDICTED
	JRST	ERRMRT		;YES--RESTORE FLAGS AND RETURN
	TRO	T4,P.ERR	;NO--FLAG THE LINE AS AN ERROR
	MOVEM	T4,PFLAGS(D)	;RESTORE FLAGS
	OUTSTR	[ASCIZ /?(/] ;TELL OPERATOR

ERRMPF:	PUSH	P,T1
	PUSH	P,T2
	PUSH	P,T3
	MOVEI	T1,1(I)		;GET JOB NUMBER
	PUSHJ	P,TYPDEC	;OUTPUT IT
	POP	P,T3
	POP	P,T2
	POP	P,T1
	OUTSTR	[ASCIZ /) /]	;SEND REST OF PREFIX
	POPJ	P,		;RETURN

ERRMNF:	TRNE	T4,P.ERR	;SEE IF ERROR LINE
	OUTCHR	T1		;SEND CHARACTER
	POPJ	P,		;RETURN

	SUBTTL	LOG RESULTS
	;SUBROUTINE TO SUM UP 1 LINE OF LOG FILE

LOGRES:	TRNN	F,F.RSP		;LOGGING ENABLED?
	POPJ	P,		;NO, GO AWAY
	MOVEI	T1,P.RSP	;FOR THIS PROCESS?
	TDNN	T1,PFLAGS(D)
	POPJ	P,		;NO, GO AWAY
	MOVE	T1,NUMCHS(D)	;YES, ACCUMULATE TOTALS
	ADDM	T1,TNMCHS(D)
	MOVE	T1,NUMCHR(D)
	ADDM	T1,TNMCHR(D)
	MOVE	T1,NUMOUT(D)
	ADDM	T1,TNMOUT(D)
	MOVE	T1,TCPU(D)
	ADDM	T1,TTCPU(D)
	MOVE	T1,RESPON(D)
	ADDM	T1,TRSPON(D)
	MOVE	T1,INPSKW(D)
	ADDM	T1,TINPSK(D)
	MOVE	T1,OUTSKW(D)
	ADDM	T1,TOUTSK(D)
	MOVE	T1,T
	MOVEM	T1,TTIME(D)
	MOVEI	T1," "		;BLANK OR * IF PROCESS WAS INTERRUPTED
	MOVEI	T2,P.INT
	TDNE	T2,PFLAGS(D)
	MOVEI	T1,"*"
	PUSHJ	P,OUTLOG

	MOVEI	T1," "		;+  IF PT WAKE MAY HAVE BEEN LOST
	MOVEI	T2,P.SSY
	TDNE	T2,PFLAGS(D)
	MOVEI	T1,"+"
	PUSHJ	P,OUTLOG

	MOVE	T1,T		;TIME
	PUSHJ	P,PSEC

	MOVEI	T1,1(I)		;PROCESS NUMBER
	MOVEI	T3,2
	PUSHJ	P,PINTEG

	MOVE	T1,NUMCHS(D)
	MOVEI	T3,3		;NUMBER CHARS WE SENT
	PUSHJ	P,PINTEG

	MOVE	T1,NUMCHR(D)	;NUMBER CHARS WE GOT BACK
	MOVEI	T3,5
	PUSHJ	P,PINTEG

	MOVE	T1,NUMOUT(D)	;NUMBER OF BUFFERS
	MOVEI	T3,4
	PUSHJ	P,PINTEG
	
	MOVE	T1,TCPU(D)	;CPU TIME FOR THE LINE
	PUSHJ	P,PSEC

	MOVE	T1,RESPON(D)	;RESPONSE TIME
	PUSHJ	P,PSEC

	MOVE	T1,INPSKW(D)	;DELAY IN OUR SENDING
	PUSHJ	P,PSEC

	MOVE	T1,OUTSKW(D)	;DELAY IN OUR OUTPUT
	PUSHJ	P,PSEC

	MOVEI	T1,CR		;CR LF
	PUSHJ	P,OUTLOG
	MOVEI	T1,LF
	JRST	 OUTLOG		;RETURN
;HERE TO PRINT JOB TOTALS AND AVERAGES, ACCUMULATE AND PRINT SCRIPT
; TOTALS AND AVERAGES  (FOR RESPONSE DATA)

TOTRSP:	TRNN	F,F.RSP		;LOGGING ENABLED?
	POPJ	P,		;NO, GO AWAY
	SETZB	D,I		;JOB 1
	MOVEI	T1,FF		;YES, PRINT FF, HEADERS
	PUSHJ	P,OUTLO3	;SNEAK PAST FORMFEED CHECK
	MOVEI	AC1,SNEAK	;SETUP TITLE PRINTER
	PUSHJ	P,TITLE
	MOVEI	T2,TOTMSG	;PRINT LINE HEADER
	PUSHJ	P,LSTSTR

TOTRS1:	CAML	I,NOLOG		;RESPONSE FOR THIS JOB?
	JRST	TOTSCP		;NO, GO PUT OUT TOTALS FOR THE SCRIPT
	MOVEI	T2,[ASCIZ /TOTAL   /]
	PUSHJ	P,LSTSTR
	MOVEI	T1,1(I)		;PROCESS NUMBER (JOB)
	MOVEI	T3,2
	PUSHJ	P,PINTEG
	MOVE	T1,TTIME(D)	;TOTAL TIME
	PUSHJ	P,PSEC
	MOVE	T1,TTCPU(D)	;CPU TIME
	ADDM	T1,TTTCPU	;ACCUMULATE SCRIPT TOTALS
	PUSHJ	P,PSEC
	MOVE	T1,TRSPON(D)	;RESPONSE TIME
	ADDM	T1,TTRSPN
	PUSHJ	P,PSEC
	MOVE	T1,TNMCHS(D)	;CHARS IN
	ADDM	T1,TTNCHS
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TNMCHR(D)	;CHARS OUT
	ADDM	T1,TTNCHR
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TNMOUT(D)	;BUFFERS
	ADDM	T1,TTNOUT
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TINPSK(D)	;INPUT DELAY
	ADDM	T1,TTINPS
	PUSHJ	P,PSEC
	MOVE	T1,TOUTSK(D)	;OUTPUT DELAY
	ADDM	T1,TTOUTS
	PUSHJ	P,PSEC
	MOVE	T1,LINCNT(D)	;LINES PROCESSED
	ADDM	T1,TTLNCT
	MOVEI	T3,6
	PUSHJ	P,PINTEG

;PRINT AVERAGES -- CALL AVERAG TO GET NUMBER/LINCNT,
; THEN CALL PSEC TO PRINT "NUMBERS" WITH 3 DECIMALS, DIVIDE
; BY 1000. AND CALL PSEC TO PRINT "TIMES".

	MOVEI	T2,[ASCIZ /
AVERAGE     /]
	PUSHJ	P,LSTSTR
	MOVE	T1,TTIME(D)	;TOTAL TIME FOR THIS JOB
	PUSHJ	P,AVERAG	;GET AVERAGE (#/LINCNT(D))
	IDIVI	T1,^D1000	;SCALE IT
	PUSHJ	P,PSEC		;PRINT IT
	MOVE	T1,TTCPU(D)	;CPU TIME
	PUSHJ	P,AVERAG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TRSPON(D)	;RESPONSE
	PUSHJ	P,AVERAG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TNMCHS(D)	;CHARS IN
	PUSHJ	P,AVERAG
	PUSHJ	P,PSEC		;ALREADY SCALED
	MOVE	T1,TNMCHR(D)	;CHARS OUT
	PUSHJ	P,AVERAG
	PUSHJ	P,PSEC
	MOVE	T1,TNMOUT(D)	;BUFFERS
	PUSHJ	P,AVERAG
	PUSHJ	P,PSEC
	MOVE	T1,TINPSK(D)	;INPUT DELAY
	PUSHJ	P,AVERAG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TOUTSK(D)	;OUTPUT DELAY
	PUSHJ	P,AVERAG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVEI	T1,CR
	PUSHJ	P,OUTLOG
	MOVEI	T1,LF
	PUSHJ	P,OUTLOG
	AOS	I		;BUMP FOR NEXT JOB
	ADDI	D,IMPSIZ
	JRST	TOTRS1		;GO DO NEXT JOB
;HERE TO PRINT TOTALS AND AVERAGES FOR THE ENTIRE SCRIPT

TOTSCP:	SETZB	I,D		;POINT TO JOB 1 SO PRINT ROUTINES WILL WORK
	MOVEI	T2,[ASCIZ /

SCRIPT
TOTAL   /]
	PUSHJ	P,LSTSTR
	MOVEI	T2,[ASCIZ /ALL /]
	PUSHJ	P,LSTSTR
	MOVE	T1,T		;TOTAL TIME
	PUSHJ	P,PSEC
	MOVE	T1,TTTCPU(D)	;CPU TIME
	PUSHJ	P,PSEC
	MOVE	T1,TTRSPN	;RESPONSE TIME
	PUSHJ	P,PSEC
	MOVE	T1,TTNCHS	;CHARS IN
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TTNCHR	;CHARS OUT
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TTNOUT	;BUFFERS
	MOVEI	T3,8
	PUSHJ	P,PINTEG
	MOVE	T1,TTINPS	;INPUT DELAY
	PUSHJ	P,PSEC
	MOVE	T1,TTOUTS	;OUTPUT DELAY
	PUSHJ	P,PSEC
	MOVE	T1,TTLNCT	;LINES PROCESSED
	MOVEI	T3,6
	PUSHJ	P,PINTEG

;PRINT AVERAGES -- CALL TAVERG TO GET NUMBER/TTLNCT,
; THEN CALL PSEC TO PRINT "NUMBERS" WITH 3 DECIMALS, DIVIDE
; BY 1000. AND CALL PSEC TO PRINT "TIMES".

	MOVEI	T2,[ASCIZ /
AVERAGE     /]
	PUSHJ	P,LSTSTR
	MOVE	T1,T		;TOTAL TIME FOR ENTIRE SCRIPT
	PUSHJ	P,TAVERG	;GET AVERAGE (#/TTLNCT)
	IDIVI	T1,^D1000	;SCALE IT
	PUSHJ	P,PSEC		;PRINT IT
	MOVE	T1,TTTCPU	;CPU TIME
	PUSHJ	P,TAVERG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TTRSPN	;RESPONSE
	PUSHJ	P,TAVERG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TTNCHS	;CHARS IN
	PUSHJ	P,TAVERG
	PUSHJ	P,PSEC		;ALREADY SCALED
	MOVE	T1,TTNCHR	;CHARS OUT
	PUSHJ	P,TAVERG
	PUSHJ	P,PSEC
	MOVE	T1,TTNOUT	;BUFFERS
	PUSHJ	P,TAVERG
	PUSHJ	P,PSEC
	MOVE	T1,TTINPS	;INPUT DELAY
	PUSHJ	P,TAVERG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVE	T1,TTOUTS	;OUTPUT DELAY
	PUSHJ	P,TAVERG
	IDIVI	T1,^D1000
	PUSHJ	P,PSEC
	MOVEI	T1,CR
	PUSHJ	P,OUTLOG
	MOVEI	T1,LF
	JRST	OUTLOG		;ALL PRINTED, GO CLOSE THE FILE
;COMPUTE AVERAGE, CALL WITH NUMBER IN T1,
; NUMBER GETS DIVIDED BY LINCNT(D)

AVERAG:	SKIPN	T1			;0?
	POPJ	P,			;YES, GO AWAY
	MULI	T1,^D1000		;SHIFT IT FOR 3 DECIMALS
	DIV	T1,LINCNT(D)		;DIVIDE BY NUMBER OF LINES
	SKIPGE	T2			;TEST REMAINDER FOR ROUNDING
	AOS	T1			;ROUND IT
	POPJ	P,


;COMPUTE AVERAGE FOR ENTIRE SCRIPT, CALL WITH NUMBER IN T1,
; NUMBER GETS DIVIDED BY TTLNCT

TAVERG:	SKIPN	T1			;0?
	POPJ	P,			;YES, GO AWAY
	MULI	T1,^D1000		;SHIFT IT FOR 3 DECIMALS
	DIV	T1,TTLNCT		;DIVIDE BY NUMBER OF LINES
	SKIPGE	T2			;TEST REMAINDER FOR ROUNDING
	AOS	T1			;ROUND IT
	POPJ	P,
	;PRINT INTEGER WITH LEADING BLANKS, PLUS 2 SPACES

PINTEG:	PUSHJ	P,DECPNB
	JRST	TWOSPC


	;PRINT F4.3 FORMAT TIME IN SECONDS

PSEC:	IDIVI	T1,^D1000	;GET SEC, MEC
	PUSH	P,T2		;SAVE MS
	MOVEI	T3,4		;SECONDS, LEADING BLANKS
	PUSHJ	P,DECPNB
	MOVEI	T1,"."		;"."
	PUSHJ	P,OUTLOG	;RESTORE MS
	POP	P,T1
	MOVEI	T3,3		;MILLISECONDS, LEADING ZEROS
	PUSHJ	P,DECPNZ

	;PRINT TWO SPACES

TWOSPC:	MOVEI	T1," "
	PUSHJ	P,OUTLOG
	JRST	OUTLOG

IFN CYCLSW,<
;SUBROUTINE TO SLEEP UNTIL NEXT TIME MARK:  0 MOD INTERVAL
;CALL:	PUSHJ	P,DOZE
;READS INTERVAL, USES T1,T2,T3.

DOZE:	MSTIME	T1,		;GET THE TIME
	IDIV	T1,INTERV	;COUNT INTERVALS AND GET RESIDUE
	SUB	T2,INTERV	;SUBTRACT RESIDUE
	MOVN	T1,T2		;MAKE WAIT POSITIVE
	HIBER	T1,
	SKIPA			;HIBER NOT WORKING
	POPJ	P,		;RETURN
	IDIVI	T1,^D60*^D1000	;MILLISEC IN ONE MINUTE
	JUMPE	T1,LNAP		;TO LNAP IF NOT A MINUTE
	MOVEI	T1,^D56		;SET 56 SECONDS IN AC
	SLEEP	T1,		;SLEEP ALMOST ONE MINUTE
	JRST	DOZE		;LOOP BACK
LNAP:	IMULI	T2,^D1000	;CONVERT TO MICROSEC
	IDIV	T2,USJIF	;CONVERT TO JIFFIES
	TRO	T2,3		;ROUND UP TO
	ADDI	T2,1		;MULTIPLE OF 4
	ASH	T2,-2		;DIVIDE BY 4
	IMUL	T2,MAGIC	;DIV BY MAGIC NUMBER
	SLEEP	T2,		;SLEEP A FEW MS
	POPJ	P,

>
	;ROUTINES TO PRINT DECIMAL INTEGERS
	;CALL MOVE T1, VALUE
	;     MOVE T3, NUMBER OF DIGITS
	;     PUSHJ P,DECPNZ OR DECPNB
	;DECPNZ IS FOR LEADING ZEROS, DECPNB LEADING BLANKS

DECPNZ:	TROA	F,F.LZR		;SET FLAG TO PRINT ZEROS

DECPNB:	TRZ	F,F.LZR		;CLEAR FLAG TO PRINT ZEROS

	IDIVI	T1,^D10		;1ST DIVIDE BY 10
	TROA	T2,200		;FOOL 1ST CHAR INTO BEING FUNNY "0"

DECPNT:	IDIVI	T1,^D10		;DIVIDE BY 10
	HRLM	T2,(P)		;SAVE RESULTS ON PDL
	SOJLE	T3,DECPN1
	PUSHJ	P,DECPNT	;RECURR UNTIL FIELD FULL
DECPN1:	HLRZ	T1,(P)		;PICK UP CHAR FROM PDL
	JUMPE	T1,DECPN2	;ZERO?
	TROA	F,F.LZR		;NO, SET FLAG TO PRINT ZEROS
DECPN2:	TRNE	F,F.LZR		;ZERO? ADD IN SPACE OR "0" APPROPRIATELY
	ADDI	T1,"0"-" "
	ADDI	T1," "


	;SUBROUTINE TO OUTPUT 1 CHAR ON LOG FILE
	;CALL	MOVE T1,CHARACTER
	;	PUSHJ P,OUTLOG

OUTLOG:	TRNN	F,F.RSP		;RETURN IF LOGGING NOT ENABLED
	POPJ	P,
	CAIN	T1,FF		;DON'T PUT FORMFEEDS IN RSP FILE
	POPJ	P,
OUTLO3:	PUSH	P,T2		;SAVE T2 (CALLED BY TOTRSP TO AVOID FF CHECK)
	MOVEI	T2,P.RSP
	TDNN	T2,PFLAGS(D)	;SEE IF RESP TIME FOR THIS PROCESS
	JRST	T2POP		;NO,SO RESTORE T2 AND RETURN
	POP	P,T2		;RESTORE T2 AND PROCEED
SNEAK:				;THIS ENTRY POINT IS USED ONLY BY TFUDG1 AND TOTRSP
				;  TO PUT TITLE ON RSP FILE
				; THIS SHOULD NOT BE USED ANYWHERE ELSE IN THE PROGRAM
	SOSG	LOGBUF+2	;SPACE?
	JRST	OUTLO2		;DO OUTPUT
OUTLO1:	IDPB	T1,LOGBUF+1	;STORE CHAR
	POPJ	P,		;RETURN

OUTLO2:	OUT	LOGCHN,		;DO OUTPUT
	JRST	OUTLO1		;OK, SO STORE CHAR

	OUTSTR	[ASCIZ /?Error on log device. Logging stopped.
/]
	CLOSE	LOGCHN,		;CLOSE LOG CHANNEL IF POSSIBLE
	TRZ	F,F.RSP		;INHIBIT FURTHER LOGGING
	POPJ	P,		;RETURN

T2POP:	POP	P,T2		;RESTORE T2
	POPJ	P,		;RETURN


	;SUBROUTINE TO OUTPUT A DECIMAL NUMBER
	;BETWEEN 0 AND 99
	;CALL	MOVE	T1,VALUE
	;	PUSHJ	P,DECOUT
	;USES T1 AND T2

DECOUT:	CAIGE	T1,12		;IS NUMBER .GE. 10
	JRST	ONED		;NO, SO ONLY ONE DIGIT
	IDIVI	T1,12		;DIVIDE BY 10
	ADDI	T1,"0"		;MAKE CHARACTER
	OUTCHR	T1		;OUTPUT
	MOVE	T1,T2
ONED:	ADDI	T1,"0"		;MAKE CHARACTER
	OUTCHR	T1
	POPJ	P,

;BLISS CODE STARTS HERE

WRITE::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-3($F)	;00001	0034	FORMAL
	HLRZ	05,DSKI.G+4(04)	;00002	
	SOSLE	06,2(05)	;00003	
	JRST	$S,L.1		;00004	
	LSH	04,27		;00005	
	ADD	04,DSKI.L+0	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
;BLISS-10 3(43)	6/14/73 15:54.15		SCRIO.BLI		PAGE 1-2

	TRNN	$V,1		;00013	0035
	JRST	$S,L.1		;00014	
	SETZ	$V,0		;00015	
	JRST	$S,L.2		;00016	
L.1:	MOVE	$V,-3($F)	;00017	0037	FORMAL
	HLRZ	10,DSKI.G+4($V)	;00020	
	MOVE	11,-2($F)	;00021		FORMAL
	IDPB	11,1(10)	;00022	
	MOVEI	$V,1		;00023	0040
L.2:	JRST	$S,.EXT.1	;00024		EXTERNAL

READ::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-2($F)	;00001	0046	FORMAL
	HRRZ	05,DSKI.G+4(04)	;00002	
	SOSLE	06,2(05)	;00003	
	JRST	$S,L.3		;00004	
	LSH	04,27		;00005	0050
	ADD	04,DSKI.L+1	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	TRNN	$V,1		;00013	0051
	JRST	$S,L.3		;00014	
	MOVE	10,-2($F)	;00015		FORMAL
	LSH	10,27		;00016	
	ADD	10,DSKI.L+2	;00017	
	MOVE	17,10		;00020	
	MOVEI	$V,1		;00021	
	XCT	$S,17		;00022	
	SETZ	$V,0		;00023	
	TRNN	$V,1		;00024	0052
	JRST	$S,L.4		;00025	
	SETO	$V,0		;00026	
	JRST	$S,L.5		;00027	
L.4:	MOVNI	$V,2		;00030	
	JRST	$S,L.5		;00031	0055
L.3:	MOVE	$V,-2($F)	;00032	0057	FORMAL
	HRRZ	10,DSKI.G+4($V)	;00033	
	ILDB	11,1(10)	;00034	
;BLISS-10 3(43)	6/14/73 15:54.16		SCRIO.BLI		PAGE 1-3

	MOVE	$V,11		;00035	0060
L.5:	JRST	$S,.EXT.1	;00036		EXTERNAL


;	0061    GLOBAL ROUTINE OUTSA(Z)=TTCALL(3,.Z);

OUTSA::

	JSP	12,.ENT.0	;00000		EXTERNAL
	MOVE	04,-2($F)	;00001		FORMAL
	TTCALL	$V,0(04)	;00002	
	JRST	$S,.EXT.0	;00003	0062	EXTERNAL


;	0062    GLOBAL ROUTINE OPEN(CHNL,STATUS,LDEV,BUF)=(BUFH[.CHNL]_.BUF;EXECUTE(MAKEOP(#50,.CHNL,STATUS<0,0>)));

OPEN::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-5($F)	;00001		FORMAL
	MOVE	05,-2($F)	;00002		FORMAL
	MOVEM	05,DSKI.G+4(04)	;00003	
	LSH	04,27		;00004	
	ADD	04,DSKI.L+3	;00005	
	ADDI	04,-4($F)	;00006		FORMAL
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	JRST	$S,.EXT.1	;00013	0063	EXTERNAL


;	0063    GLOBAL ROUTINE LOOKUP(CHNL,HEAD)=EXECUTE(MAKEOP(#76,.CHNL,HEAD<0,0,0,1>));

LOOKUP::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-3($F)	;00001		FORMAL
	LSH	04,27		;00002	
	HRRZI	05,-2($F)	;00003		FORMAL
	HRLI	05,20		;00004	
	ADD	04,5		;00005	
	ADD	04,DSKI.L+4	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	JRST	$S,.EXT.1	;00013	0064	EXTERNAL


;	0064    GLOBAL ROUTINE ENTER(CHNL,HEAD)=EXECUTE(MAKEOP(#77,.CHNL,HEAD<0,0,0,1>));

ENTER::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-3($F)	;00001		FORMAL
	LSH	04,27		;00002	
;BLISS-10 3(43)	6/14/73 15:54.17		SCRIO.BLI		PAGE 1-4

	HRRZI	05,-2($F)	;00003		FORMAL
	HRLI	05,20		;00004	
	ADD	04,5		;00005	
	ADD	04,DSKI.L+5	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	JRST	$S,.EXT.1	;00013	0065	EXTERNAL


;	0065    GLOBAL ROUTINE CLOSE(CHNL)=(EXECUTE(MAKEOP(#70,.CHNL,0));EXECUTE(MAKEOP(#71,.CHNL,0)));

CLOSE::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-2($F)	;00001		FORMAL
	LSH	04,27		;00002	
	ADD	04,DSKI.L+6	;00003	
	MOVE	17,4		;00004	
	MOVEI	$V,1		;00005	
	XCT	$S,17		;00006	
	SETZ	$V,0		;00007	
	MOVE	05,-2($F)	;00010		FORMAL
	LSH	05,27		;00011	
	ADD	05,DSKI.L+7	;00012	
	MOVE	17,5		;00013	
	MOVEI	$V,1		;00014	
	XCT	$S,17		;00015	
	SETZ	$V,0		;00016	
	JRST	$S,.EXT.1	;00017	0066	EXTERNAL


;	0066    GLOBAL ROUTINE USETI(CHNL,BNO)=(EXECUTE(MAKEOP(#74,.CHNL,BNO<0,0,0,1>)));

USETI::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-3($F)	;00001		FORMAL
	LSH	04,27		;00002	
	HRRZI	05,-2($F)	;00003		FORMAL
	HRLI	05,20		;00004	
	ADD	04,5		;00005	
	ADD	04,DSKI.L+10	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	JRST	$S,.EXT.1	;00013	0067	EXTERNAL


;	0067    GLOBAL ROUTINE USETO(CHNL,BNO)=(EXECUTE(MAKEOP(#75,.CHNL,BNO<0,0,0,1>)));
;	0070    
;BLISS-10 3(43)	6/14/73 15:54.18		SCRIO.BLI		PAGE 2-1

;	0071    

USETO::

	JSP	12,.ENT.1	;00000		EXTERNAL
	MOVE	04,-3($F)	;00001		FORMAL
	LSH	04,27		;00002	
	HRRZI	05,-2($F)	;00003		FORMAL
	HRLI	05,20		;00004	
	ADD	04,5		;00005	
	ADD	04,DSKI.L+11	;00006	
	MOVE	17,4		;00007	
	MOVEI	$V,1		;00010	
	XCT	$S,17		;00011	
	SETZ	$V,0		;00012	
	JRST	$S,.EXT.1	;00013	0070	EXTERNAL

;	0072    GLOBAL ROUTINE FILEAPPEND(TOFILE,FROMFILE,INCHNL,OUTCHNL)=
;	0073    BEGIN
;	0074    %<
;	0075    	THIS ROUTINE APPENDS THE FILE POINTED TO BY .FROMFILE
;	0076    	AT THE END OF THE FILE POINTED TO BY .TOFILE.
;	0077    	IT USES .INCHNL AND .OUTCHNL WHICH ARE SUPPLIED BY
;	0100    	THE CALLING PROGRAM IN ORDER TO AVOID CLASHES !
;	0101    
;	0102    >%
;	0103    
;	0104    
;	0105    LOCAL NAMETO[4],NAMEFROM[4],BLKPNTR,OBUFH[3],IBUFH[3];
;	0106    BIND
;	0107    OUTBUF=#65,
;	0110    RENAMEOP=#55,		!OP CODE FOR RENAME
;	0111    EOF=-1,			! READ RETURNS -1 ON EOF
;	0112    BLKSIZE=128,		! 128 WORDS IN A BLOCK
;	0113    TEMP=VREG,		! VALUE IS RETURNED IN VREG
;	0114    ASCIILINE=1;		! ASCII LINE MODE
;	0115    
;	0116    MACRO SETUPNAME(NAME,PNTR)=
;	0117    BEGIN
;	0120    	REGISTER QQ;
;	0121    	QQ<LEFTHALF>_PNTR<0,0>;
;	0122    	QQ<RIGHTHALF>_NAME<0,0>;
;	0123    	BLT(QQ,(NAME+3));
;	0124    END $,
;	0125    
;	0126    EGGSIT=CALLI(0,#12) $,	! EXIT FROM THE PROGRAM
;	0127    
;	0130    POSTVLH(Z)=(REGISTER QQW;
;	0131    	    QQW_-Z;
;	0132    	    HLRZS(QQW,QQW);
;	0133    	    .QQW
;	0134    	   ) $;		! THIS MACRO RETURNS THE POSITIVE OF THE LEFT HALF
;	0135    
;	0136    
;	0137    
;	0140    SETUPNAME(NAMETO,.TOFILE);	! SET UP THE BLOCK REQUIRED BY LOOKUP
;BLISS-10 3(43)	6/14/73 15:54.20		SCRIO.BLI		PAGE 2-2

;	0141    IF NOT OPEN(.OUTCHNL,ASCIILINE,SIXBIT 'DSK',OBUFH<0,0>^18+IBUFH<0,0>)
;	0142    	THEN ( MSG('CANNOT OPEN "TO" FILE ');EGGSIT);
;	0143    
;	0144    
;	0145    IF NOT LOOKUP(.OUTCHNL,NAMETO)
;	0146    	THEN  BEGIN		! "TO" FILE DOESN'T EXIST.
;	0147    				! SO JUST RENAME "FROM" FILE
;	0150    		SETUPNAME(NAMETO,.TOFILE);
;	0151    		SETUPNAME(NAMEFROM,.FROMFILE);
;	0152    		IF NOT LOOKUP(.OUTCHNL,NAMEFROM)
;	0153    		   THEN ( MSG('FILE "FROM" ALSO DOESN"T EXIST');
;	0154    			  EGGSIT
;	0155    			);
;	0156    		EXECUTE(MAKEOP(RENAMEOP,.OUTCHNL,NAMETO<0,0>));
;	0157    	      END
;	0160    	ELSE  BEGIN
;	0161    		BLKPNTR_(IF .(NAMETO+3) LEQ 0
;	0162    			   THEN POSTVLH(.(NAMETO+3))/BLKSIZE+1
;	0163    			   ELSE  .(NAMETO+3)<LEFTHALF>
;	0164    		        );
;	0165    		USETI(.OUTCHNL,.BLKPNTR);
;	0166    		SETUPNAME(NAMETO,.TOFILE);
;	0167    		IF NOT ENTER(.OUTCHNL,NAMETO)
;	0170    		   THEN (MSG('CANNOT ENTER "TO" FILE');EGGSIT);
;	0171    		USETO(.OUTCHNL,.BLKPNTR);
;	0172    		READ(.OUTCHNL) ;	! DO A READ TO POSITION FILE FOR USETO
;	0173    
;	0174    		SETUPNAME(NAMEFROM,.FROMFILE);
;	0175    		IF NOT OPEN(.INCHNL,ASCIILINE,SIXBIT 'DSK',IBUFH<0,0>)
;	0176    		   THEN (MSG('CANNOT OPEN "FROM" FILE');EGGSIT);
;	0177    		IF NOT LOOKUP(.INCHNL,NAMEFROM)
;	0200    		   THEN (MSG('CANNOT LOOKUP "FROM" FILE');EGGSIT);
;	0201    		WHILE (TEMP_READ(.INCHNL)) NEQ EOF
;	0202    		  DO  WRITE(.OUTCHNL,.TEMP);
;	0203    	      END;
;	0204    CLOSE(.OUTCHNL);
;	0205    CLOSE(.INCHNL);
;	0206    END;

FILEAPPEND::

	JSP	12,.ENT.1	;00000		EXTERNAL
	ADD	$S,DSKI.L+12	;00001	0074
	HRL	17,-5($F)	;00002	0106	FORMAL
	HRRI	17,2($F)	;00003		LOCAL
	BLT	17,5($F)	;00004		LOCAL
	PUSH	$S,-2($F)	;00005	0142	FORMAL
	PUSH	$S,DSKI.L+13	;00006	
	PUSH	$S,DSKI.L+14	;00007	
	HRLZI	$V,13($F)	;00010	0143	LOCAL
	ADDI	$V,16($F)	;00011		LOCAL
	PUSH	$S,3		;00012	
	PUSHJ	$S,OPEN		;00013	
	SUB	$S,DSKI.L+15	;00014	
	TRNE	$V,1		;00015	
	JRST	$S,L.6		;00016	
	PUSH	$S,DSKI.C+0	;00017	
	PUSHJ	$S,OUTSA	;00020	
;BLISS-10 3(43)	6/14/73 22:10.52		SCRIO.BLI		PAGE 2-3

	SUB	$S,DSKI.L+16	;00021	
	CALLI 	$S,12				;00022	
	JRST	$S,L.6		;00023	0144
L.6:	PUSH	$S,-2($F)	;00024		FORMAL
	HRRZI	04,2($F)	;00025	0147	LOCAL
	HRLI	04,4400		;00026	
	PUSH	$S,4		;00027	
	PUSHJ	$S,LOOKUP	;00030	
	SUB	$S,DSKI.L+17	;00031	
	TRNE	$V,1		;00032	
	JRST	$S,L.7		;00033	
	HRL	17,-5($F)	;00034	0150	FORMAL
	HRRI	17,2($F)	;00035		LOCAL
	BLT	17,5($F)	;00036		LOCAL
	HRL	17,-4($F)	;00037	0152	FORMAL
	HRRI	17,6($F)	;00040		LOCAL
	BLT	17,11($F)	;00041		LOCAL
	PUSH	$S,-2($F)	;00042	0153	FORMAL
	HRRZI	05,6($F)	;00043	0154	LOCAL
	HRLI	05,4400		;00044	
	PUSH	$S,5		;00045	
	PUSHJ	$S,LOOKUP	;00046	
	SUB	$S,DSKI.L+17	;00047	
	TRNN	$V,1		;00050	
	JRST	$S,L.10		;00051	
	MOVE	06,-2($F)	;00052		FORMAL
	LSH	06,27		;00053	
	ADD	06,DSKI.L+20	;00054	
	ADDI	06,2($F)	;00055		LOCAL
	MOVE	17,6		;00056	
	MOVEI	$V,1		;00057	
	XCT	$S,17		;00060	
	SETZ	$V,0		;00061	
	JRST	$S,L.10		;00062	0156
L.7:	SKIPLE	05,5($F)	;00063	0160	LOCAL
	JRST	$S,L.11		;00064	
	MOVN	17,5($F)	;00065		LOCAL
	HLRZS	17,17		;00066	
	MOVE	$V,17		;00067	
	ASH	$V,-7		;00070	0162
	AOJ	$V,0		;00071	
	JRST	$S,L.12		;00072	
L.11:	HLRZ	$V,5($F)	;00073		LOCAL
L.12:	MOVEM	$V,12($F)	;00074	0164	LOCAL
	PUSH	$S,-2($F)	;00075		FORMAL
	PUSH	$S,12($F)	;00076		LOCAL
	PUSHJ	$S,USETI	;00077	
	SUB	$S,DSKI.L+17	;00100	
	HRL	17,-5($F)	;00101	0165	FORMAL
	HRRI	17,2($F)	;00102		LOCAL
	BLT	17,5($F)	;00103		LOCAL
	PUSH	$S,-2($F)	;00104	0166	FORMAL
	HRRZI	07,2($F)	;00105	0167	LOCAL
	HRLI	07,4400		;00106	
	PUSH	$S,7		;00107	
	PUSHJ	$S,ENTER	;00110	
	SUB	$S,DSKI.L+17	;00111	
;BLISS-10 3(43)	6/14/73 22:10.52		SCRIO.BLI		PAGE 2-4

	TRNE	$V,1		;00112	
	JRST	$S,L.13		;00113	
	PUSH	$S,DSKI.C+1	;00114	
	PUSHJ	$S,OUTSA	;00115	
	SUB	$S,DSKI.L+16	;00116	
	CALLI 	$S,12				;00117	
	JRST	$S,L.13		;00120	0170
L.13:	PUSH	$S,-2($F)	;00121		FORMAL
	PUSH	$S,12($F)	;00122		LOCAL
	PUSHJ	$S,USETO	;00123	
	SUB	$S,DSKI.L+17	;00124	
	PUSH	$S,-2($F)	;00125	0171	FORMAL
	PUSHJ	$S,READ		;00126	
	SUB	$S,DSKI.L+16	;00127	
	HRL	17,-4($F)	;00130	0172	FORMAL
	HRRI	17,6($F)	;00131		LOCAL
	BLT	17,11($F)	;00132		LOCAL
	PUSH	$S,-3($F)	;00133	0174	FORMAL
	PUSH	$S,DSKI.L+13	;00134	
	PUSH	$S,DSKI.L+14	;00135	
	HRRZI	10,16($F)	;00136	0175	LOCAL
	PUSH	$S,10		;00137	
	PUSHJ	$S,OPEN		;00140	
	SUB	$S,DSKI.L+15	;00141	
	TRNE	$V,1		;00142	
	JRST	$S,L.14		;00143	
	PUSH	$S,DSKI.C+2	;00144	
	PUSHJ	$S,OUTSA	;00145	
	SUB	$S,DSKI.L+16	;00146	
	CALLI 	$S,12				;00147	
	JRST	$S,L.14		;00150	0176
L.14:	PUSH	$S,-3($F)	;00151		FORMAL
	HRRZI	11,6($F)	;00152	0177	LOCAL
	HRLI	11,4400		;00153	
	PUSH	$S,11		;00154	
	PUSHJ	$S,LOOKUP	;00155	
	SUB	$S,DSKI.L+17	;00156	
	TRNN	$V,1		;00157	
	JRST	$S,L.10		;00160	
L.15:	PUSH	$S,-3($F)	;00161		FORMAL
	PUSHJ	$S,READ		;00162	
	SUB	$S,DSKI.L+16	;00163	
	CAMN	$V,DSKI.L+21	;00164	0201
	JRST	$S,L.10		;00165	
	PUSH	$S,-2($F)	;00166		FORMAL
	PUSH	$S,3		;00167	
	PUSHJ	$S,WRITE	;00170	
	SUB	$S,DSKI.L+17	;00171	
	JRST	$S,L.15		;00172	0202
L.10:	PUSH	$S,-2($F)	;00173		FORMAL
	PUSHJ	$S,CLOSE	;00174	
	SUB	$S,DSKI.L+16	;00175	
	PUSH	$S,-3($F)	;00176	0204	FORMAL
	PUSHJ	$S,CLOSE	;00177	
	SUB	$S,DSKI.L+16	;00200	
	SETZ	$V,0		;00201	0205
	SUB	$S,DSKI.L+12	;00202	
;BLISS-10 3(43)	6/14/73 22:10.53		SCRIO.BLI		PAGE 2-5

	JRST	$S,.EXT.1	;00203	0206	EXTERNAL

;PLIT AREA

DSKI.P::
XWD	000000,000005	;00000
XWD	416031,647236	;00001
XWD	521011,750212	;00002
XWD	471004,252236	;00003
XWD	211010,644630	;00004
XWD	425000,000000	;00005
XWD	000000,000005	;00006
XWD	416031,647236	;00007
XWD	521010,547250	;00010
XWD	426444,021250	;00011
XWD	475044,043222	;00012
XWD	462120,000000	;00013
XWD	000000,000005	;00014
XWD	416031,647236	;00015
XWD	521011,750212	;00016
XWD	471004,243244	;00017
XWD	476324,220214	;00020
XWD	446310,500000	;00021


;CONSTANT POINTERS

DSKI.C::
XWD	004400,DSKI.P+1	;00000
XWD	004400,DSKI.P+7	;00001
XWD	004400,DSKI.P+15	;00002

;LITERALS
;BLISS-10 3(43)	6/14/73 22:10.54		SCRIO.BLI		PAGE 2-6


DSKI.L::

XWD	057000,000000	;00000
XWD	056000,000000	;00001
XWD	063000,740000	;00002
XWD	050000,000000	;00003
XWD	076000,000000	;00004
XWD	077000,000000	;00005
XWD	070000,000000	;00006
XWD	071000,000000	;00007
XWD	074000,000000	;00010
XWD	075000,000000	;00011
XWD	000017,000017	;00012
XWD	000000,000001	;00013
XWD	446353,000000	;00014
XWD	000004,000004	;00015
XWD	000001,000001	;00016
XWD	000002,000002	;00017
XWD	055000,000000	;00020
XWD	777777,777777	;00021

.ENT.0:: PUSH	$S,$F		;SET UP STACK POINTER AND FORMALS REGISTER

	HRRZ	$F,0
	JRST	$S,0(12)	;RETURN TO CALLING POINT

.ENT.1:: PUSH	$S,$F
	HRRZ	$F,0
	PUSH	$S,17		;SAVE REGISTER 17
	JRST	$S,0(12)	;RETURN TO CALLING POINT

.EXT.1:: POP	$S,17		;RESTORE REGISTER 17
.EXT.0:: POP	$S,$F		;RESTORE FORMALS REGISTER
	 POPJ	$S,0		;RETURN FROM SUBROUTINE

	SUBTTL	DEFAULT SCRIPT PARAMETERS
DEFAUL:			;DEFAULT VALUES (REGULAR)
	-^D300		;DELTI
	-^D100		;DELTO
	^D10000		;DELTR
	^D7000		;DELTF
	^D20000		;DELTS
	^D0		;PFLAGS
	POINT	7,BUFFER	;PSCRPT


DEFAUR:			;DEFAULT VALUES (REENTER)
	0		;DELTI
	0		;DELTO
	0		;DELTR
	0		;DELTF
	0		;DELTS
	P.FINT		;PFLAGS
	POINT	7,BUFFR		;PSCRPT



	;IMPURE DATA AREA

	RELOC

BLOW:

PTYNAM:	BLOCK	1		;SIX BIT PTY NAME
PTYUNT:	BLOCK	1		;PTY UNIT NUMBER:  LH IN SIXBIT, RH IN OCTAL
PTYIBF:	BLOCK	3		;INPUT BUFFER HEADER OF PTY
PTYOBF:	BLOCK	3		;OUTPUT BUFFER HEADER OF PTY
PCWORD:	BLOCK	1		;PC FOR PROCESS
PRONUM:	BLOCK	1		;PROCESS # FOR MULTI SCRIPT
JOBNO:	BLOCK 	1	;JOB NO FOR THIS PROCESS

CLPINI:			;CLEARED AT PROCESS INITIALIZATION
NDONE:	BLOCK	1		;NUMBER OF TIMES SCRIPT HAS BEEN COMPLETED
COUNT:	BLOCK	1		;NUMBER OF PASSES THROUGH THE SCRIPT
TNEXT:	BLOCK	1		;TIME TO WAKE UP AFTER SIMULATING SLOW TTY OR USER
TINTR:	BLOCK	1		;TIME TO INTERRUPT
TCPUST:	BLOCK	1		;CPU TIME AT START OF LINE
TSTLIN:	BLOCK	1		;TIME WAIT FOR RESPONSE BEGAN
FREE:	BLOCK	1		;FREE TIME LEFT FROM THE LAST LINE
LCPINI:

CLBEGL:			;CLEARED EACH LINE
NUMCHS:	BLOCK	1		;NUMBER CHARS SENT IN CURRENT LINE
NUMCHR:	BLOCK	1		;NUMBER CHARS RECEIVED IN CURRENT LINE
NUMOUT:	BLOCK	1		;NUMBER OF BUFFERS OF OUTPUT RECIEVED
TCPU:	BLOCK	1		;CPU TIME FOR THE LINE
RESPON:	BLOCK	1		;RESPONSE TIME (TOTAL COMPUTER DELAY)
INPSKW:	BLOCK	1		;SKEW DUE TO POOR RESONSE TO SCRIPT PROGRAM
OUTSKW:	BLOCK	1		;SKEW DUE TO POOR RESPONSE TO SCRIPT PROGRAM
QCOUNT:	BLOCK	1		;NUMBER OF ERRORS EXPECTED
DELTC:	BLOCK	1		;TIME-OUT BEFORE FORCED ^C'S
LCBEGL:

DLBEGS:			;RESET AT SCRIPT INITIALIZATION
DELTI:	BLOCK	1		;INPUT DELAY OR RATE
DELTO:	BLOCK	1		;OUTPUT DELAY OR RATE
DELTR:	BLOCK	1		;MAX RESPONSE TIME ALLOWABLE
DELTF:	BLOCK	1		;FREE TIME ALLOWED
DELTS:	BLOCK	1		;TIME JOBS TO BE STAGGERED AT START
PFLAGS:	BLOCK	1		;FLAG BITS FOR PROCESS
PSCRPT:	BLOCK	1		;POINTER TO SCRIPT
LDBEGS:

CLBEGS:			;CLEARED AT SCRIPT INITIALIZATION
LINCNT:	BLOCK	1		;NUMBER OF LINES PROCESSED
TNMCHS:	BLOCK	1		;NUMBER OF CHARS SENT FOR THIS JOB
TNMCHR:	BLOCK	1		;NUMBER OF CHARS RECEIVED FOR THIS JOB
TNMOUT:	BLOCK	1		;  "   BUFFERS SENT    "
TTCPU:	BLOCK	1		;TOTAL CPU FOR THIS JOB
TRSPON:	BLOCK	1		;TOTAL RESPONSE TIME  "
TINPSK:	BLOCK	1		;TOTAL INPUT SKEW
TOUTSK:	BLOCK	1		;TOTAL OUTPUT SKEW   "
TTIME:	BLOCK	1		;LAST (IE, TOTAL) TIME FOR THIS PROCESS
LCBEGS:

	IMPSIZ=.-BLOW
	BLOCK	<IMPSIZ*<NMAX-1>>	;FILL UP LOWSEG WITH TABLES FOR ALL JOBS
IFN CYCLSW,<
	PDLEN=30
>
	PDLEN=20
PDLIST:	BLOCK	PDLEN+1
LASTOP:	BLOCK	1		;TIME OF LAST CHECK FOR OPERATOR
SLNCNT:	BLOCK	1		;SCRIPT LINE COUNT
NOWATC:	BLOCK	1		;NUMBER OF JOBS TO BE WATCHED
NOLOG:	BLOCK	1		;NUMBER OF JOBS TO BE LOGGED FOR RESPONSE TINE
LASMON:	BLOCK	1		;NUMBER OF PROCESS LAST MONITORED
DEFAUP:	BLOCK	1		;ADDRESS OF DEFAULTS
COUNTO:	BLOCK	1		;REPEAT COUNT FROM OPERATOR
STAGO:	BLOCK	1		;STAGGER TIME REQUESTED BY OPERATOR
DELFAC:	BLOCK	1		;MULTIPLIER OF ALL DELAY COUNTS
TSTART:	BLOCK	1		;TIME PROGRAM STARTED
USJIF:	BLOCK	1		;MICROSECONDS PER JIFFY
MAGIC:	BLOCK	1		;MAGIC NUMBER TO SLEEP 4 JIFFIES
SVFF:	BLOCK	1		;JOBFF SAVED HERE
SBUF:	BLOCK	3		;BUFFER HEADER TO READ SCRIPT
MONBUF:	BLOCK	3		;BUFFER HEADER TO WATCH JOBS
LOGBUF:	BLOCK	3		;BUFFER HEADER TO LOG RESPONSES
HIUWP:	BLOCK	1		;STATE OF UWP FLAG SAVED HERE
COMLIN:	BLOCK	20		;TTY COMMAND BUFFER
JOBSB:	BLOCK	NMAX		;BLOCK WITH LAST JOB STATUS OF EACH CHANNEL
PTYMAX:	BLOCK	1		;HOLDS NUMBER OF PTYS IN SYSTEM
CHNNUM:	BLOCK	NMAX		;CHANNEL NUMBER FOR STREAM
CONFIG:	BLOCK	5		;HOLDS SYSTEM NAME
TTNCHS:	BLOCK	1		;TOTAL CHARS SENT FOR THIS SCRIPT
TTNCHR:	BLOCK	1		;TOTAL CHARS REC'VD ...
TTNOUT:	BLOCK	1		;TOTAL BUFFERS ...
TTTCPU:	BLOCK	1		;TOTAL CPU TIME ...
TTRSPN:	BLOCK	1		;TOTAL RESPONSE TIME ...
TTINPS:	BLOCK	1		;TOTAL INPUT DELAY ...
TTOUTS:	BLOCK	1		;TOTAL OUTPUT DELAY ...
TTLNCT:	BLOCK	1		;TOTAL LINE COUNT FOR THIS SCRIPT
IFN CYCLSW,<
INTERV:	BLOCK	1
CYCLCT:	BLOCK	1
>

IFN HUWSW,<
FSTLIN:	BLOCK	1		;FIRST SCRIPT  LINE TO HOLD UP
WLINCR:	BLOCK	1		;INCREMENT FOR EACH SCRIPT
RCTR:	BLOCK	1		;COUNT -1 OF SCRIPTS NOT YET HOLDING UP
HLNCNT:	BLOCK	NMAX		;LINES TO GO IN SCRIPT BEFORE HOLDING UP
>
EZER:			;END+1 OF AREA TO BE ZEROED
	BLOCK	100		;STACK FOR THE BLISS APPEND ROUTINE

SAVACS:	BLOCK	20		;AREA TO STORE AC'S TEMPORARILY
WCHDEV:	BLOCK	1		;DEVICE FOR WATCH FILE
WCHMASTER:	SIXBIT /SCRIPT/		; NAME OF THE MASTER WCH FILE
		SIXBIT /WCH/		; EXT OF MASTER WCH FILE
		0
		0
		4400000000+.-4		;POINTER TO MASTER WCH FILE

RSPMASTER:	SIXBIT /SCRIPT/		;NAME OF THE MASTER RSP FILE
		SIXBIT /RSP/		;EXT OF MASTER RSP FILE
		0
		0
		4400000000+.-4		;POINTER TO MASTER RSP FILE
WCHFILE:	SIXBIT /SCP000/		;NAME OF NEW WCH FILE
		SIXBIT /WCH/		;EXT OF NEW WCH FILE
		0
		0
		4400000000+.-4		;POINTER TO NEW WCH FILE

RSPFILE:	SIXBIT /SCP000/		;NAME OF NEW RSP FILE
		SIXBIT /RSP/		;EXT OF NEW RSP FILE
		0
		0
		4400000000+.-4		;POINTER TO NEW RSP FILE

;FILOP BLOCKS

FOPOPN:	200000,,.FOSAU		;ASSIGN CHANNEL,,SINGLE ACCESS UPDATE
	1			;ASCII LINE MODE FOR PTY
	0			;PTYNNN FILLED IN
	0			;OBUF,,IBUF FILLED IN
	1,,1			;1 BUFFER EACH WAY

FOPTMP:	BLOCK	1		;TEMP USED BY "DO" MACRO





DSKI.G::	BLOCK 24	;GLOBAL AREA FOR APPEND

PAT:	BLOCK	100		;PATCH AREA
ELOW:			;END+1 OF LOW SEGMENT

	RELOC
	;END IMPURE AREA
	XLIST	;LITERALS
	LIT
	LIST
	;HERE IS WHERE THE SCRIPT IS STORED IN HI SEGMENT

RNAME:	SIXBIT	/[KJOB]/
	SIXBIT	/SCP/
	SIXBIT	/004/
	5

NAME:	0		;FILE NAME OF SCRIPT
	0		;EXT OF SCRIPT
	0		;VERSION OF SCRIPT
	0		;LINE COUNT OF SCRIPT

IFNDEF TENEX, <
BUFFR:	ASCIZ	.^C^C
KJOB/F
!XTERMINATED
.
>

IFDEF TENEX,<
BUFFR:	ASCII  /^C ^C
/
ASCIZ / DEL *.*;*
	EXP
	LOGOUT
!XOUT
/
>
BUFFER:	BLOCK	BUFSIZ
	END	BEGIN