Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0081/vtslve.mac
There is 1 other file named vtslve.mac in the archive. Click here to see a list.
	TITLE	VTSLVE	--  SLAVE PART OF VTTAM SYSTEM
	SUBTTL	SLAVE STORAGE AND CONSTANTS
	;TONY LAUCK	1 JUL 71

;A COPY OF VTSLVE RUNS FOR EACH VT05 TERMINAL CONNECTED TO VTTAM.
;THE TERMINAL IS DETERMINED BY ASSIGNING THE LOGICAL NAME "VTTERM".
;WHEN VTSLVE IS STARTED, IT ASKS FOR A NUMBER. THIS IS A DECIMAL
;NUMBER WHICH BECOMES THE NUMBER OF THE TERMINAL AS REFERENCED BY
;THE MASTER JOB.

;ACCUMULATORS
	F=0		;FLAGS
	A=1		;G.P. AC'S
	B=2
	C=3
	D=C+1
	T=5		;TEMPS
	T1=T+1
			;VARIABLES USED IN DUMPING CORE TO CRT
	LL=7		;LINES LEFT ON SCREEN
	CL=10		;CHARACTERS LEFT ON CURRENT LINE
	SL=11		;COUNT OF QUEUED LINES FOR TRAILING LINE SUPPR.
	SC=12		;COUNT OF QUEUED CHARS FOR TRAILING BLANK SUPPR.
	TT=13		;VTTAM TERMINAL NUMBER OF THIS JOB
	W=14		;AC HOLDING WAKE UUO ENABLE BITS
	H=15		;CURSOR POSITION HORIZ. 0 TO N
	V=16		;CURSOR POSITION VERT. 0 TO M
	P=17		;PUSH DOWN POINTER

;FLAGS IN ACCUMULATOR F
	;L.H.
	WINPF=1B0	;1 IF SLAVE WAITING FOR SHARED INPUT BUFFER



	PDLEN=20	;SIZE OF PUSH DOWN LIST

	SCRCOL=^D72	;COLUMNS PER LINE OF VT05
	SCRLIN=^D20	;LINES PER SCREEN OF VT05
	INTERN SCRCOL,SCRLIN	;FORCE THESE TO MATCH HISEG AND MASTER

	SCRCHR=SCRCOL*SCRLIN	;CHARACTERS PER SCREEN
	SCRWDS=<SCRCHR+5>/6	;WORDS PER SCREEN  (DISPLAY-6)
;SPECIAL VT05 CHARACTERS
;THESE MUST AGREE WITH SPCTAB.

	CH.FIL=1	;FILLER CHARACTER
	CH.HOM=35	;HOME UP
	CH.EOL=36	;ERASE TO END OF LINE
	CH.EOF=37	;ERASE TO END OF SCREEN
;HIGH SEGMENT LOCATIONS USED BY MASTER AND SLAVE FOR COMMUNICATION

	EXTERN	JOBTAB		;TABLE INDEXED BY TERMINAL # 
				; GIVING SLAVE MONITOR JOB #
	EXTERN	MAXTRM		;MAX NUMBER OF VTTAM TERMINALS
	EXTERN	STDAY		;DATE SYSTEM STARTED OR STOPPED
	EXTERN	STTIME		;STARTING TIME MASTER BEGAN OR STOPPED
				;START IF POS, STOP IF NEG.
	EXTERN	MJOBN		;JOB NUMBER OF MASTER
	EXTERN	SINFLG		;0 IF INPUT BUFFER FREE
				;ELSE TERM NO WHICH FILLED IT
	EXTERN	SINBF		;SHARED INPUT BUFFER
	EXTERN	SOUTRM		;0 IF OUTPUT BUFFER EMPTY
				; ELSE TERMINAL NUMBER OF DATA IN
				; SOUTBF
	EXTERN	SOUMOD		;TYPE OF OUTPUT REQUEST
				;-1 ERASE SCREEN, 0 FULL SCREEN, ELSE
				; WRITE LINE
	EXTERN	SOUTBF		;SHARED OUTPUT BUFFER
	EXTERN	QREQ		;CRITICAL SECTION SYNC COUNT
	EXTERN	QBITS		;SLAVE SYNC REQUEST BIT-TABLE
	EXTERN	AVLINP		;ASSIGNMENT WORD FOR SHARED INPUT BUFFER
	EXTERN	QININP		;PUTTER FOR QUEUE FOR INPUT BUFFER
	EXTERN	QBFINP		;QUEUE AREA FOR INPUT BUFFER
	EXTERN	QSTINP		;BYTE POINTER TO FIRST INPUT BUFFER
				; QUEUE ENTRY
	EXTERN	QFNINP		;BYTE POINTER TO LAST INPUT BUFFER
				; QUEUE ENTRY

;MONITOR STUFF
	EXTERN	JOBFF

	PTYCNF=22	;GETTAB ITEM FOR PTY DATA WORD
	CNFTBL=11	;GETTAB TABLE FOR PTY DATA WORD

	SPECLM=500	;SPECIAL TTY DATA MODE
			;USED WITH CRT TO CAUSE FULL CHAR SET
			;AND TRUE ECHOING OF INPUT CHARACTERS

	LINBIT=1B11	;INPUT AVAILABLE LINE MODE BIT FOR GETLCH
	CQBIT=1B16	;^Q BIT FOR GETLCH, SETLCH TTCALL'S
	WAKPRJ=1B17	;WAKE UUO ENABLED FOR PROJECT MATCH (HIBER UUO)
	WAKLN=1B13	;WAKE UP ON TTY LINE MODE ACTIVITY (HIBER UUO)

	OPDEF	PJRST	[JRST]		;PUSHJ POPJ CONVENTION



;SOFTWARE CHANNELS
	VTCHN=1			;VT05 I/O
;LOW SEGMENT STORAGE AREA

LOWZER:		;FIRST WORD TO ZERO IN INITIALIZAION

SAVFF:	BLOCK	1	;JOBFF SAVED HERE FOR BUFFER RECLAIMATION
VTIBF:	BLOCK	3	;CRT INPUT BUFFER HEADER
VTOBF:	BLOCK	3	;CRT OUTPUT BUFFER HEADER
TTYNUM:	BLOCK	1	;MONITOR TTY NO. OF VT05 SAVED HERE
PDL:	BLOCK	PDLEN	;PUSH DOWN LIST
QJOBN:	BLOCK	1	;OUR JOB NUMBER SAVED HERE
QWORD:	BLOCK	1	;WORD POINTER TO OUR QBIT ENTRY
QMASK:	BLOCK	1	;BIT MASK TO OUR QBIT ENTRY

;VT05 SCREEN IMAGE   NORMALLY A COPY OF DATA ON CRT
SCREEN:	BLOCK	SCRWDS


;HOLD BUFFER FOR SCREEN IMAGE
;USED WHEN ESC RECEIVED AND SHARED INPUT BUFFER IS FULL
HOLD:	BLOCK	SCRWDS

HIZER=.-1	;HIGHEST LOCATION TO ZERO ON INITIALIZATION
	SUBTTL	SLAVE ONCE ONLY CODE

;HERE ON STARTUP OF SLAVE JOB.
;USER MUST HAVE ASSIGNED DEVICE VTTERM TO THE VT05.
;USER MUST THEN TYPE IN DECIMAL TERMINAL NUMBER
;TO COMPLETE MAPPING OF MONITOR TTY NUMBER TO VTTAM NUMBER.

SGO:	RESET
	MOVEI	T,SEGBLK	;GET SHARED SEGMENT
	GETSEG	T,
	HALT	.		;COULDN'T GET SEGMENT
	MOVEI	T,0		;UNLOCK HISEG FOR WRITING
	SETUWP	T,
	HALT	.		;CAN'T UNLOCK HISEG
	SETZM	LOWZER		;ZERO SLAVE LOW CORE
	MOVE	T,[XWD LOWZER,LOWZER+1]
	BLT	T,HIZER
	MOVEI	0,0		;ZERO THE AC'S
	MOVEI	17,1
	BLT	17,17
	MOVE	P,[IOWD PDLEN,PDL]	;SET UP PUSH DOWN POINTER
	MOVE	T,JOBFF		;SAVE JOBFF FOR BUFFER RECLAIMATION
	MOVEM	T,SAVFF
	PUSHJ	P,TTYINI	;INIT THE VT05
	PUSHJ	P,GTT		;GET VTTAM UNIT NO. FROM OPERATOR
	JRST	SRESTB		;GO TO RESTART CODE

;CONTROL BLOCK FOR USE BY GETSEG UUO

SEGBLK:	SIXBIT	/DSK/		;GETSEG DEVICE
	SIXBIT	/VTTAM/		;FILE
	SIXBIT	/SHR/		;EXT
	0
	0			;PPN
	0
;SUBROUTINE TO GET VTTAM TERMINAL NUMBER FROM CONTROLLING TTY.
;CALLED ONCE ONLY WHEN SLAVE JOB IS STARTED.
;USER TYPES A DECIMAL NUMBER <CR> IN RESPONSE TO "*".
;VTTAM ACCEPTS THE NUMBER AND RESPONDS WITH "!".

GTT:	OUTSTR	[ASCIZ /*/]	;PROMPT USER
	MOVEI	TT,0		;ZERO NUMBER

;LOOP HERE TO CONVERT A DIGIT
GTT1:	INCHWL	T		;GET A CHARACTER
	CAIL	T,"0"		;CHECK FOR DIGIT
	CAILE	T,"9"
	JRST	GTT2		;IF NO MORE DIGITS
	IMULI	TT,^D10		; ELSE MULTIPLY BY 10
	ADDI	TT,-"0"(T)	; ADD IN DIGIT
	JRST	GTT1		; AND LOOP FOR MORE

;HERE WHEN NON-DIGIT RECEIVED. LOOP HERE TO GOBBLE UNTIL <LF> SEEN.
GTT2:	INCHWL	T		;GOBBLE CHARACTER
	CAIE	T,12		;IS IT LF?
	JRST	GTT2		;GOBBLE IF NOT
	JUMPLE	TT,GTT3		;CHECK LEGAILITY OF NUMBER
	CAILE	TT,MAXTRM
	JRST	GTT3		;BAD
	OUTSTR	[ASCIZ /!/]	;TELL OPERATOR WHEN HAPPY
	POPJ	P,		;RETURN WITH TT SET UP



;HERE WHEN NUMBER HAS OVERFLOWED, OR IS TOO LARGE FOR JOBTAB
GTT3:	OUTSTR	[ASCIZ /?
/]				;TELL OPERATOR HE LOST
	JRST	GTT		;LET HIM TRY AGAIN
	SUBTTL	SLAVE RESTART CODE

;HERE ON VTCLSE (OR IMPLIED CLOSE ON VTOPEN).
;OUTPUT THE CLOSE MESSAGE AND GO TO IDLE STATE.

SRESTA:	MOVE	P,[IOWD	PDLEN,PDL]	;RESET PDL TO TOP LEVEL
	PUSHJ	P,CMSG		;GIVE CLOSE MESSAGE

;HERE ON INITIAL START UP, OR ON CLOSE AFTER MESSAGE SENT OUT.
;WAIT FOR MASTER TO START UP.
SRESTB:	SETZM	JOBTAB(TT)	;TELL MASTER WE ARE IDLE
				; IN CASE HE IS WAITING FOR IT
	PUSHJ	P,MWAKE		;WAKE HIM IF HE IS AROUND AND ASLEEP
	PUSHJ	P,UQINIT	;SET UP HIBERNATE WAKE ENABLES

;LOOP HERE WAITING FOR MASTER TO START UP.
SRESB1:	SKIPLE	STTIME		;IS MASTER UP?
	JRST	SRESTC		;YES
	HIBER	W,		;NO, HIBERNATE
	HALT	.		;HIBER UUO FAILED
	JRST	SRESB1		;AWOKE. NOW SEE IF MASTER IS UP

;HERE ON STARTUP OR RESTART WHEN WE SAW MASTER WAS UP.
;THERE IS A RACE CONDITION BETWEEN SLAVE START-UP AND MASTER SHUT-DOWN.
SRESTC:	MOVE	T,QJOBN		;TELL MASTER OUR JOB NUMBER AND THEREBY
	MOVEM	T,JOBTAB(TT)	; WARN HIM WE ARE COMING UP.
	SKIPG	STTIME		;CHECK FOR "STARE-DOWN" CASE
	JRST	SRESTB		; IF WE LOST THE RACE, GO BACK TO IDLE
	PUSHJ	P,MWAKE		; ELSE WAKE MASTER
	PUSHJ	P,UQINIT	; SET UP OUR Q RESOURCE STUFF
	PUSHJ	P,OMSG		; SEND OUR OPEN MESSAGE
	JRST	SLOOP		; GO TO SLAVE MAIN LOOP
;SUBROUTINES TO SEND OPEN AND CLOSE MESSAGES TO VT05
;THESE INCLUDE TIME, DATE, TERMINAL NUMBER, VTTAM NUMBER, AND
;MONITOR JOB NUMBER.
;CALLED ON OPEN OR CLOSE FOR ALL TERMINALS.

;HERE TO OUTPUT OPEN MESSAGE.
OMSG:	PUSHJ	P,BLANK		;BLANK SCREEN IMAGE IN CORE
	PUSHJ	P,INLMES	;OPEN MESSAGE
	ASCIZ	/VTTAM OPENED AT /
	JRST	OCMSG		;TO COMMON CODE

;HERE TO OUTPUT CLOSE MESSAGE
CMSG:	PUSHJ	P,BLANK		;BLANK SCREEN IMAGE IN CORE
	PUSHJ	P,INLMES	;CLOSE MESSAGE
	ASCIZ	/VTTAM CLOSED AT /

;COMMON MESSAGE CODE
OCMSG:	MOVM	C,STTIME	;-TIME ON CLOSE
	IDIV	C,[^D60*^D60*^D1000]	;HOURS
	PUSHJ	P,OUT2D
	MOVEI	A,":"
	PUSHJ	P,OUTC
	MOVE	C,D		;MINUTES
	IDIVI	C,^D60*^D1000
	PUSHJ	P,OUT2D
	MOVEI	A,":"		;:
	PUSHJ	P,OUTC
	MOVE	C,D		;SECONDS
	IDIVI	C,^D1000
	PUSHJ	P,OUT2D

	PUSHJ	P,INLMES
	ASCIZ	/ ON /
	MOVE	C,STDAY		;DATE
	IDIVI	C,^D12*^D31	;COMPUTE YEAR
	ADDI	C,^D64
	PUSH	P,C		;SAVE YEAR
	MOVEI	C,^D31+1(D)	;MONTH (GET BACK TO 1 ORIGIN)
	IDIVI	C,^D31
	PUSHJ	P,OUT2D
	MOVE	C,D		;DAY
	PUSHJ	P,OUT2S
	POP	P,C		;YEAR
	PUSHJ	P,OUT2S
	MOVEI	V,3		;GO DOWN 3 LINES
	MOVEI	H,0
	PUSHJ	P,INLMES	;DEVICE
	ASCIZ	/DEVICE: /
	PUSHJ	P,TTYNO		;GET PHYSICAL DEVICE NAME TO D
	MOVE	C,[POINT 6,D]	;1 WORD SIXBIT OUTPUT FROM D
	MOVEI	CL,6
SIXTYL:	ILDB	A,C
	PUSHJ	P,OUTC6
	SOJG	CL,SIXTYL

	PUSHJ	P,INLMES	;TERMINAL NUMBER
	ASCIZ	/     VTTAM NO: /
	MOVE	C,TT
	PUSHJ	P,DECOUT

	PUSHJ	P,INLMES	;JOB NUMBER
	ASCIZ	/     JOB NO: /
	MOVE	C,QJOBN
	PUSHJ	P,DECOUT

	PUSHJ	P,HOMEUP	;HOME UP
	PUSHJ	P,DUMP		;WRITE SCREEN IMAGE
	PUSHJ	P,FLUSH		;FLUSH ANY TYPE-AHEAD
	PJRST	HOMEUP		;HOME UP AND RETURN
;SUBROUTINE TO OUTPUT A SLASH PLUS 2 DECIMAL DIGITS
OUT2S:	MOVEI	A,"/"		;DO SLASH
	PUSHJ	P,OUTC
				;AND FALL INTO OUT2D

;SUBROUTINE TO OUTPUT 2 DECIMAL DIGITS
OUT2D:	PUSH	P,D		;SAVE D
	IDIVI	C,^D10		;GET 2 DIGITS
	MOVEI	A,"0"(C)	;OUTPUT HI-ORDER
	PUSHJ	P,OUTC
	MOVEI	A,"0"(D)	;OUTPUT LOW-ORDER
	POP	P,D		; RESTORE D
	PJRST	OUTC		; AND RETURN

;SUBROUTINE TO OUTPUT IN-LINE ASCIZ MESSAGE
INLMES:	POP	P,D		;GET CALL ADDRESS
	HRLI	D,(POINT 7,)	;MAKE IT A BYTE POINTER
;LOOP HERE TO OUTPUT A CHARACTER
INLME1:	ILDB	A,D		;GET CHAR
	JUMPE	A,1(D)		;RETURN IF NULL
	PUSHJ	P,OUTC		;ELSE OUTPUT IT
	JRST	INLME1		; AND LOOP

;THE STANDARD RADIX 10. TYPER
DECOUT:	IDIVI	C,^D10		;DIVIDE BY TEN
	HRLM	D,(P)		;SAVE REMAINDER
	SKIPE	C		;ALL DIGITS FORMED?
	PUSHJ	P,DECOUT	;NO, SO RECURR
	HLRZ	C,(P)		;YES, UNWIND
	MOVEI	A,"0"(C)	;MAKE IT A DIGIT
	PJRST	OUTC		;OUTPUT IT AND RETURN UP A LEVEL
	SUBTTL	SLAVE MAIN LOOP

;LOOP HERE IN SLAVE LOOKING FOR WORK.
;HERE TO CHECK ALL POSSIBLE WORK THE SLAVE JOB DOES, DO IT IF NECESSARY,
;OR HIBERNATE IF NOT.

;NOTE: THE HIBERN ROUTINE WORRIES ABOUT SHUT-DOWN'S AND RESTARTS.

SLOOP:	TLNE	F,(WINPF)	;WERE WE WAITING FOR AN INPUT BUFFER?
	PUSHJ	P,TRYINP	;YES. TRY TO GET IT.
	JRST	SLOOP1		;CHECK OTHER WORK
	JRST	WON		;GOT BUFFER, GO USE IT

;HERE IN SLAVE LOOP WHEN INPUT BUFFER WAS BUSY, OR NOT NEEDED.
SLOOP1:	PUSHJ	P,CHKINP	;CHECK FOR VT05 INPUT
	JRST	SINPUT		; YES, GO HANDLE IT
				; NO, KEEP LOOKING FOR OTHER WORK.

;NOW CHECK FOR OUTPUT REQUEST BY MASTER
	CAMN	TT,SOUTRM	;IS OUTPUT BUFFER FULL OF STUFF FOR US?
	JRST	OUTPRO		;IF SO, GO HANDLE IT
				;NO

;HERE WHEN SLAVE HAS CHECKED FOR WORK AND FOUND NONE TO DO.
	PUSHJ	P,HIBERN	;CHECK FOR RESTARTS/SHUTDOWNS AND HIBERN
	JRST	SRESTA		;GO TO RESTART CODE
	JRST	SLOOP		;GO BACK TO SLAVE LOOP
	SUBTTL	SLAVE INPUT EDITING

;HERE WHEN SLAVE LOOP DETERMINED THERE ARE CHARACTERS IN THE VT05
; INPUT BUFFER. ALL CHARACTERS ARE PROCESSED, UPDATING SCREEN IMAGE
; IN CORE, EXCEPT FOR CHARACTERS THAT RESULT IN SPECIAL ACTION.

SINPUT:	IN	VTCHN,		;READ BUFFER
	JRST	SINPU1		;OK
	HALT	.		;IMPOSSIBLE TTY FILE STATUS

;HERE TO PROCESS EACH CHARACTER IN THE INPUT BUFFER, OR RETURN
; TO SLAVE LOOP IF NONE ARE LEFT.

SINPU1:	SOSGE	VTIBF+2		;COUNT BUFFERED CHARACTERS
	JRST	SLOOP		;IF NONE, GO BACK TO SLAVE LOOP
	ILDB	A,VTIBF+1	;GET CHARACTER
	JUMPE	A,SINPU1	;IGNORE NULLS
	CAIN	A,177		;MAKE RUBOUT'S 0
	MOVEI	A,0
	CAIGE	A,40		;IS IT A SPECIAL CHARACTER?
	JRST	SINP2		; YES
	PUSHJ	P,OUTC		; NO, STORE GRAPHIC CHARACTER
	JRST	SINPU1		;AND GO BACK FOR MORE

;HERE TO PROCESS A SPECIAL (CONTROL) CHARACTER RECEIVED
SINP2:	XCT	SPCTAB(A)	;DO FUNCTION
				;INSTRUCTION, PUSHJ, OR JRST
	JRST	SINPU1		;IF WE GET BACK HERE, GO BACK FOR MORE
;SPECIAL CHARACTER TABLE FOR INPUT PROCESSING
;THIS TABLE IS INDEXED BY CONTROL CHARACTER CODE (RUBOUT=0)
;ITS ENTRIES ARE XCT'ED TO CAUSE THE NECESSARY ACTION.

SPCTAB:	JRST	REWRIT	;	RUBOUT		REWRITE SCREEN
	JRST	ILLCH	; ^A			ILLEGAL
	JRST	ILLCH	; ^B			ILLEGAL
	JRST	RECCO	; ^C			TURN OF ^O, ILLEGAL
	JRST	ILLCH	; ^D			ILLEGAL
	JRST	ILLCH	; ^E	WRU		ILLEGAL
	JRST	ILLCH	; ^F			ILLEGAL
	JRST	ILLCH	; ^G	BEL		ILLEGAL
	PUSHJ P,CURLFT	; ^H	BACKSPACE	CURSOR LEFT, IF
			 ;			 NOT AT LEFT MARGIN
	JRST	ILLCH	; ^I	TAB		ILLEGAL
	PUSHJ P,LINFD	; ^J	LINE FEED	DOWN ONE, OR SCROLL
	PUSHJ P,CURDWN	; ^K	CURSOR DOWN	DOWN ONE, IF NOT AT
			 ;			 LAST LINE
	JRST	ILLCH	; ^L			ILLEGAL
	MOVEI	H,0	; ^M	RETURN		GO TO LEFT MARGIN
	JRST	ILLCH	; ^N			ILLEGAL
	JRST	RECCO	; ^O			TURN OFF ^O, ILLEGAL
	JRST	ILLCH	; ^P			ILLEGAL
	JRST	RECCQ	; ^Q	XON		TURN OFF TAPE MODE,
			 ;			 ILLEGAL
	JRST	ILLCH	; ^R			ILLEGAL
	JRST	ILLCH	; ^S	XOFF		ILLEGAL
	JRST	ILLCH	; ^T			ILLEGAL
	JRST	ILLCH	; ^U			ILLEGAL
	JRST	ILLCH	; ^V			ILLEGAL
	JRST	ILLCH	; ^W			ILLEGAL
	PUSHJ P,NXTPOS	; ^X	CURSOR RIGHT	RIGHT IF NOT AT 
			 ;			 RIGHT MARGIN
	PUSHJ P,CURLFT	; ^Y	CURSOR LEFT	LEFT IF NOT AT
			 ;			 LEFT MARGIN
	PUSHJ P,CURUP	; ^Z	CURSOR UP	UP IF NOT AT TOP LINE
	JRST	RESC	; ^[	ESC		ENTER TRANSACTION
	JRST	ILLCH	; ^\	HOME DOWN	ILLEGAL
	SETZB	H,V	; ^]	HOME UP		GO TO TOP LEFT
	PUSHJ P,REOL	; ^^	ERASE EOL	ERASE TO END OF LINE
	PUSHJ P,REOF	; ^_	ERASE EOF	ERASE TO END OF SCREEN
;HERE ON RECEIPT OF LINE FEED

LINFD:	CAIGE	V,SCRLIN-1		;ARE WE ON LAST LINE OF SCREEN?
	AOJA	V,CPOPJ			;IF NOT, COUNT V AND RETURN
					; ELSE FALL INTO SCROLL

;SUBROUINE TO SIMULATE SCROLLING.
;LINES 2 THROUGH M REPLACE 1 THROUGH M-1 AND LINE M
; IS BLANKED.

	LINWDS==SCRCOL/6		;WORDS PER LINE
	IFN <SCRCOL-<6*LINWDS>>,
		<PRINTX	NUMBER OF COLUMNS IS NOT A MULTIPLE OF 6>

SCROLL:	MOVE	T,[XWD SCREEN+LINWDS, SCREEN]	;BLT DOWN ONE LINE
	BLT	T,SCREEN+SCRWDS-LINWDS-1
	SETZM	SCREEN+SCRWDS-LINWDS		;BLANK LAST LINE
	MOVE	T,[XWD SCREEN+SCRWDS-LINWDS,SCREEN+SCRWDS-LINWDS+1]
	BLT	T,SCREEN+SCRWDS-1
	POPJ	P,			;RETURN


;HERE ON RECEIPT OF CURSOR DOWN
CURDWN:	CAIGE	V,SCRLIN-1		;ARE WE ON BOTTOM LINE?
	ADDI	V,1			;IF NOT, ADD 1 TO V
	POPJ	P,			;RETURN


;HERE ON RECEIPT OF CURSOR UP
CURUP:	JUMPE	V,CPOPJ			;RETURN IF ON TOP LINE
	SOJA	V,CPOPJ			; ELSE SUBTRACT ONE FROM V
					; AND RETURN



;HERE ON RECEIPT OF CURSOR LEFT
CURLFT:	JUMPE	H,CPOPJ			;RETURN IF AT LEFT MARGIN
	SOJA	H,CPOPJ			; ELSE SUBTRACT 1 FROM H
					; AND RETURN
;HERE ON RECEPT OF XON  (CONTROL Q)
RECCQ:	PUSHJ	P,OFFCQ			;TURN OFF SCNSER PAPER TAPE MODE
	JRST	ILLCH			; AND HANDLE AS ILLEGAL CHAR


;HERE ON RECEIPT OF A ^O OR ^C CHARACTER
RECCO:	PUSHJ	P,TTYINI		;TURN OFF CONTROL O MODE
					;FALL INTO ILLCH

;HERE ON RECEIPT OF AN ILLEGAL INPUT CHARACTER.
;RING BELL AND REWRITE USER'S SCREEN.
ILLCH:	MOVEI	T,7			;BEL
	PUSHJ	P,VTOUTC		;SEND IT
	JRST	REWRIT			;REWRITE SCREEN FROM CORE
;HERE ON RECEIPT OF AN ERASE END OF LINE (EOL) CHARACTER
REOL:	PUSHJ	P,MAKPTR		;MAKE BYTE POINTER
	MOVEI	A,0			;GET SIXBIT BLANK
	DPB	A,B			;STORE IT AT CURRENT POSITION
	HRREI	T,-<SCRCOL-1>(H)	; T = H - (SCRCOL-1)
	AOJG	T,CPOPJ			;COUNT ONE JUST CLEARED,
					; RETURN IF DONE
;LOOP HERE TO CLEAR CHARACTERS IN LINE IMAGE
REOL1:	IDPB	A,B			;CLEAR NEXT ONE
	AOJLE	T,REOL1			;COUNT. LOOP IF MORE
	POPJ	P,			; ELSE RETURN


;HERE ON ERASE EOF CHARACTER
REOF:	PUSHJ	P,MAKPTR		;GET BYTE POINTER TO CURRENT POS
	MOVEI	A,0			;GET A SIXBIT BLANK
;LOOP HERE CHECKING FOR BYTE POINTER AT 1ST BYTE OF A WORD
REOF1:	TLC	B,360000		;TEST POSITION FIELD FOR 36
	TLCN	B,360000
	JRST	REOF2			;IF 36, DONE
	DPB	A,B			; ELSE BLANK THIS ONE
	IBP	B			;GO TO NEXT BYTE
	JRST	REOF1			;AND LOOP

;HERE WHEN ANY PARTIAL WORD HAS BEEN BLANKED
REOF2:	HRRZ	B,B			;GET ADDRESS OF 1ST FULL WORD
					; TO BLANK
	CAIGE	B,SCREEN+SCRWDS		;BEYOND END ALREADY?
	SETZM	(B)			;IF NOT, ZERO 1ST WORD LEFT
	CAIL	B,SCREEN+SCRWDS-1	;MORE THAN 1 WORD TO ZERO?
	POPJ	P,			;IF NOT, RETURN
	HRLI	B,1(B)			;ELSE BLT ZEROS TO REST
	MOVS	B,B
	BLT	B,SCREEN+SCRWDS-1
	POPJ	P,			;RETURN
	SUBTTL SLAVE TRANSACTION PROCESSING

;HERE WHEN ESC RECIEVED.
;NOTE: CALLED BY JRST, NOT PUSHJ FOR CONDITIONAL RETURN.
RESC:	TLNN	F,(WINPF)	;WAS A PREVIOUS TRANSACTION HELD UP?
	CAMN	TT,SINFLG	; OR ARE WE ALREADY WAITING ON MASTER?
	JRST	ILLCH		;IF SO, ESC IS ILLEGAL
	PUSHJ	P,HOMEUP	;ACKNOWLEDGE OK RECEIPT WITH HOME UP
	PUSHJ	P,TRYINP	;TRY TO GET BUFFER RESOURCE
	JRST	RESC1		;JUMP IF FAILED
	MOVE	T,[XWD SCREEN,SINBF]	;WON. COPY TO SHARED INPUT BUF
	BLT	T,SINBF+SCRWDS-1
	SETOM	AVLINP		;PASS THE BUFFER TO THE MASTER
	MOVEM	TT,SINFLG	;TELL MASTER OUR NUMBER
	PUSHJ	P,MWAKE		;WAKE MASTER
	JRST	SINPU1		;GO BACK FOR MORE INPUT CHARACTERS

;HERE ON ESC WHEN NO PREVIOUS ENTRY FOR US, BUT BUFFER WAS BUSY
RESC1:	MOVE	T,[XWD SCREEN,HOLD]	;COPY SCREEN TO HOLD
	BLT	T,HOLD+SCRWDS-1
	JRST	SINPU1		;GO BACK FOR MORE CHARACTERS


;HERE WHEN WE GOT SHARED INPUT BUFFER AFTER A WAIT
WON:	MOVE	T,[XWD HOLD,SINBF]	;COPY HOLD TO SHARED BUFFER
	BLT	T,SINBF+SCRWDS-1
	SETOM	AVLINP		;PASS THE BUFFER TO THE MASTER
	MOVEM	TT,SINFLG	;TELL MASTER OUR NUMBER
	PUSHJ	P,MWAKE		;WAKE MASTER
	JRST	SLOOP		;GO BACK TO SLAVE LOOP
	SUBTTL	SLAVE OUTPUT PROCESSING

;HERE WHEN AN OUTPUT REQUEST BY THE MASTER WAS SEEN BY SLAVE

OUTPRO:	SKIPGE	T,SOUMOD	;CHECK MODE OF OUTPUT REQUEST
	JRST	OUTPR2		;-1 MEANS ERASE SCREEN
	JUMPG	T,OUTPR1	;.GT. 0 MEANS LINE MODE
				;ZERO MEANS WHOLE SCREEN

;HERE TO PROCESS WRITE SCREEN CALL
	PUSHJ	P,CPYSCR	;COPY SOUTBF TO SCREEN
	PUSHJ	P,OUTWAK	;FREE SHARED OUTPUT BUFFER & WAKE MASTER

;HERE ALSO ON INPUT TO REWRITE ENTIRE SCREEN
REWRIT:	PUSHJ	P,HOMEUP	;HOME UP CURSOR
	PUSHJ	P,DUMP		;DUMP SCREEN BUFFER TO VT05 TERMINAL
	JRST	OUTPR3		;DO FINAL STUFF

;HERE ON WRLIN CALL
OUTPR1:	PUSHJ	P,CPYLIN	;COPY 1 LINE TO SCREEN
	PUSHJ	P,OUTWAK	;FREE SHARED OUTPUT BUFFER & WAKE MASTER
	PUSHJ	P,HOME		;HOME UP CURSOR, BUT SAVE V
	PUSHJ	P,LINDMP	;DUMP LINE V TO VT05
	JRST	OUTPR3		;DO FINAL STUFF

;HERE TO PROCESS ERSCR CALL.
OUTPR2:	PUSHJ	P,OUTWAK	;FREE SHARED OUTPUT BUFFER & WAKE MASTER
	PUSHJ	P,HOMEUP	;HOME UP
	PUSHJ	P,EREOF		;CLEAR SCREEN
	PUSHJ	P,BLANK		;CLEAR SCREEN IMAGE IN CORE

;HERE ON ALL OUTPUT CALLS TO FINISH UP
;HERE ALSO ON COMPLETION OF REWRITING SCREEN ON INPUT
OUTPR3:	PUSHJ	P,FLUSH		;FLUSH INPUT STREAM TYPE-AHEADS
	PUSHJ	P,HOMEUP	;GIVE CURSOR BACK TO USER AT TOP
	JRST	SLOOP		;GO TO SLAVE'S MAIN LOOP
	SUBTTL	MISCELANEOUS SLAVE ROUTINES TO UPDATE SCREEN IMAGE

;SUBROUTINE TO COPY 1ST LINE IN SOUTBF TO SCREEN
;THE LINE NUMBER (1 ORIGIN) IS IN T

CPYLIN:	MOVEI	V,-1(T)		;GET V (0 ORIGIN)
	MOVEI	H,0		;START OF LINE
	MOVE	D,[POINT 6,SOUTBF]	;SET UP POINTER TO SHARED
					; OUTPUT BUFFER
	MOVEI	C,SCRCOL-1	;SET UP COUNT
	ILDB	A,D		;DO 1ST MOVE AS SPECIAL CASE
	PUSHJ	P,OUTC6		;STOW IT AND FORM BYTE POINTER
;LOOP HERE TO COPY 2ND THROUGH LAST CHARACTER OF LINE
CPYLI1:	ILDB	A,D		;GET CHARACTER FROM SOUTBF
	IDPB	A,B		;STOW CHAR IN SCREEN
	SOJG	C,CPYLI1	;COUNT AND LOOP UNTIL DONE
	POPJ	P,		;RETURN


;SUBROUTINE TO COPY ALL OF SOUTBF TO SCREEN
CPYSCR:	MOVE	T,[XWD SOUTBF,SCREEN]	;FORM BLT POINTER
	BLT	T,SCREEN+SCRWDS-1	;COPY IT
	POPJ	P,			;RETURN
;SUBROUTINE TO PUT AN ASCII CHARACTER IN A INTO BUFFER THEN
;ADVANCE TO NEXT POSITION, THEREBY SIMULATING ACTION OF VT05.
OUTC:	CAIL	A,140		;MAKE IT UPPER CASE
	SUBI	A,40
	SUBI	A,40		;MAKE IT SIXBIT
				;FALL INTO OUTC6

;SUBROUTINE TO PUT A SIXBIT CHARACTER IN A INTO BUFFER THEN
;ADVANCE TO NEXT POSITION, THEREBY SIMULATING ACTION OF VT05.
OUTC6:	PUSHJ	P,MAKPTR	;GET A BYTE POINTER BASED ON H AND V
	DPB	A,B		;STORE CHARACTER
				;FALL INTO NXTPOS

;SUBROUTINE TO ADVANCE CURSOR COUNTERS TO NEXT CHARACTER OF A LINE
NXTPOS:	CAIGE	H,SCRCOL-1	;AT END OF LINE?
	ADDI	H,1		;IF NOT, GO TO NEXT COLUMN
	POPJ	P,		;RETURN

;SUBROUTINE TO FORM A 6 BIT ILDB BYTE POINTER TO START OF LINE V.
LINPTR:	SETOM	H		;SET H = -1 SO ILDB GETS 1ST CHAR
				;FALL INTO MAKPTR

;SUBROUTINE TO FORM A 6 BIT BYTE POINTER TO SCREEN (H,V)
MAKPTR:	MOVE	T,V		;COMPUTE T = V*SCRCOL + H + 6
	IMULI	T,SCRCOL
	ADDI	T,6(H)		;ADD 6 IN TO ENSURE T POSITIVE
	IDIVI	T,6		;DIVIDE T BY 6 TO GET WORD, POSITION
	MOVE	B,PTRTAB(T1)	;GET APPROPRIATE POINTER WORD
	ADD	B,T		;ADD IN WORD OFFSET
	POPJ	P,		;RETURN

;TABLE OF BYTE POINTERS TO SCREEN BASED ON POSITION OF BYTE IN A WORD
	JJ==5
PTRTAB:	REPEAT	6, <	POINT	6,SCREEN-1,JJ
			JJ==JJ+6		>
;SUBROUTINE TO BLANK SCREEN BUFFER AND RESET CURSOR COUNTERS
BLANK:	SETZM	SCREEN		;ZERO SCREEN
	MOVE	T,[XWD SCREEN,SCREEN+1]
	BLT	T,SCREEN+SCRWDS-1
	SETZB	H,V		;RESET CURSOR COUNTER
	POPJ	P,		;RETURN
	SUBTTL	VT05 I/O ROUTINES

;SUBROUTINE TO INITIALIZE STATE OF THE TERMINAL
;CALLED ON START UP AND UPON RECEIPT OF ^O
;THIS CODE INITS TTY, TURNS OFF ^O AND CLEARS INPUT BUFFER
TTYINI:	MOVE	T,SAVFF		;RESTORE JOBFF TO REUSE BUFFERS
	MOVEM	T,JOBFF
	INIT	VTCHN,SPECLM	;INIT TERMINAL IN F.C.S. TRUE ECHO MODE
	SIXBIT	/VTTERM/
	XWD	VTOBF,VTIBF
	JRST	TTYIN1		;INIT FAILED
	PUSHJ	P,TTYNO		;GET AND SAVE MONITOR TTY NO.
	INBUF	VTCHN,2		;SET UP BUFFERS
	OUTBUF	VTCHN,2
	PUSHJ	P,FILL1		;SEND A FILL TO TURN OFF  ^O
	PUSHJ	P,VTOUTC	;FORCE IT OUT
				;FALL INTO FLUSH


;SUBROUTINE TO FLUSH TERMINAL INPUT BUFFER OF ANY CHARACTERS
;NOT READ YET.
;CALLED INITIALLY AND WHEN NECESSARY TO SYNCHRONIZE TYPE-AHEAD.

;*** TEMPORARILY THE TERMINAL MUST BE THE CONTROLLING TTY ***
;*** CHANGE THIS WHEN SCNSER FIXED ***

FLUSH:	CLRBFI		;CLEAR CONTROLLING TTY AND HOPE ITS THE ONE
	POPJ	P,	;RETURN


;HERE WHEN INIT OF DEVICE VTTERM FAILED.
TTYIN1:	OUTSTR	[ASCIZ /? NO DEVICE VTTERM/ ] ;TELL OPER HE LOST
	EXIT		;RETURN TO MONITOR


;SUBROUTINE TO TURN OFF PAPER TAPE MODE
;CALLED WHEN ^Q RECEIVED

;*** TEMPORARILY THE TERMINAL MUST BE THE CONTROLLING TTY ***
;*** CHANGE THIS WHEN SCNSER FIXED ***

OFFCQ:	MOVE	A,TTYNUM	;MONITOR TTY NO
	GETLCH	A		;GET CURRENT CHARACTERISTICS
	TLZ	A,(CQBIT)	;TURN OFF ^Q BIT IN A
	SETLCH	A		;SET THE CHARACTERISTICS
	POPJ	P,		;RETURN
;SUBROUTINE TO CHECK IF THERE IS DATA TO INPUT FROM THE VT05.
;THE CHECK IS MADE IN LINE MODE.
;CALL	PUSHJ	P,CHKINP
;	RETURN IF INPUT
;	RETURN IF NO INPUT

CHKINP:	MOVE	A,TTYNUM	;MONITOR TTY NUMBER OF VT05
	GETLCH	A		;GET LINE CHARACTERISTICS
	TLNN	A,(LINBIT)	;HAS A LINE BEEN TYPED?
	AOS	(P)		;NO, SET UP SKIP
	POPJ	P,		;RETURN


;SUBROUTINE TO GET THE MONITOR TTY NUMBER OF VT05 TERMINAL
; AND STORE IT IN TTYNUM.
;THIS ROUTINE ALSO LEAVES THE PHYSICAL DEVICE NAME IN D.

;THIS KLUDGERY WILL DISAPPEAR IF SCNSER BECOMES REASONABLE
TTYNO:	MOVEI	D,VTCHN		;SOFTWARE CHANNEL
	DEVNAM	D,		;MAP IT TO PHYSICAL DEVICE NAME
	HALT	.		;DEVNAM FAILED
	CAMN	D,[SIXBIT /CTY/] ;IS IT THE CTY?
	JRST	TTYNO3		;IF CTY, DO SPECIAL CASE
	MOVE	B,[POINT 6,D,17] ;NO, GET BYTE POINTER TO XXX
	MOVEI	C,3		;SET LOOP COUNT = 3 CHARACTERS
	MOVEI	A,0		;CLEAR ACCUMULATOR
;LOOP HERE TO CONVERT "TTYXXX" FROM SIXBIT OCTAL TO A BINARY NUMBER
TTYNO1:	ILDB	T,B		;GET NEXT SIXBIT OCTAL DIGIT
	CAIL	T,"0"-40	;CHECK IT
	CAILE	T,"7"-40
	JRST	TTYNO2		;IF NOT A DIGIT, RETURN
	LSH	A,3		;IF A DIGIT, MULTIPLY BY 8
	ADDI	A,-<"0"-40>(T)	;ADD IN DIGIT
	SOJG	C,TTYNO1	;LOOP UNLESS SEEN 3
;(BACK) HERE TO STORE TTYNUM AND RETURN
TTYNO2:	MOVEM	A,TTYNUM	;STORE TTYNUM
	POPJ	P,		;RETURN

;HERE FOR SPECIAL CASE OF CTY
TTYNO3:	MOVE	A,[XWD PTYCNF,CNFTBL]	;GETTAB ARGUMENTS
	GETTAB	A,		;GET MONITOR PTY DATA
	HALT	.		;GETTAB FAILED
	HLRZ	A,A		;LEFT HALF IS NUMBER OF FIRST PTY
	SOJA	A,TTYNO2	;RETURN 1 LESS AS CTY LINE NUMBER
;MACRO FOR STANDARD SINGLE CHARACTER BUFFERED MODE OUTPUT
;AN OPEN SUBROUTINE IS USED WHERE USEFUL TO SAVE CPU
;TIME IN DUMP ROUTINE.

	DEFINE	VTOUTM (AC),
<	SOSG	VTOBF+2		;COUNT BUFFER. SPACE?
	PUSHJ	P,VOUTUU	;IF NEED MORE SPACE
	IDPB	AC,VTOBF+1	;STOW CHARACTER	       >

;SUBROUTINE TO OUTPUT CARRIAGE RETURN, LINE FEED TO VT05
CRLF:	MOVEI	T,15		;CR
	PUSHJ	P,VTOUTC	;SEND IT
				;FALL INTO LF

;SUBROUTINE TO OUTPUT LINE FEED TO VT05.
LF:	MOVEI	T,12		;LF
				;FALL INTO VTOUTC

;SUBROUTINE TO OUTPUT A CHARACTER FROM ACCUMULATOR T TO VT05
VTOUTC:	VTOUTM	T,		;DO THE STANDARD STUFF
	POPJ	P,		;RETURN


;SUBROUTINE TO HOME UP CURSOR AND RESET OUR CURSOR COUNTERS.
HOMEUP:	SETZB	H,V		;RESET OUR CURSOR COUNTERS
				;FALL INTO HOME

;SUBROUTINE TO POSITION VT05 TO HOME.
HOME:	MOVEI	T,CH.HOM	;GET A HOME-UP CHARACTER
	PUSHJ	P,VTOUTC	;OUTPUT IT
				;FALL INTO VOUTUU TO FORCE IT OUT

;SUBROUTINE TO DO AN OUTPUT UUO TO VT05
VOUTUU:	OUT	VTCHN,		;OUT UUO
	POPJ	P,		;RETURN IF OK
	HALT	.		;OUT UUO FAILED
;SUBROUTINE TO ERASE REST OF SCREEN (EOF)
EREOF:	MOVEI	T,CH.EOF	;PICK UP ERASE EOF CHARACTER
	JRST	EREOX		;GO SEND IT

;SUBROUTINE TO ERASE REST OF LINE (EOL)
EREOL:	MOVEI	T,CH.EOL	;PICK UP ERASE EOL CHARACTER

;HERE ON BOTH EREOF AND EREOL
EREOX:	PUSHJ	P,VTOUTC	;OUTPUT CHARACTER
				;FALL INTO FILL 4

;SUBROUTINES TO OUTPUT 4, 2, OR 1 FILLER CHARACTERS
FILL4:	PUSHJ	P,FILL2		;CALL FILL2, THEN FALL INTO FILL2
FILL2:	PUSHJ	P,FILL1		;CALL FILL1 THEN FALL INTO FILL1
FILL1:	MOVEI	T,CH.FILL	;PICK UP A FILLER CHARACTER
	PJRST	VTOUTC		;SEND IT AND RETURN
;SUBROUTINE TO DUMP THE CONTENTS OF SCREEN TO THE VT05.
;CALLED WHEN CURSOR IS AT TOP LEFT.
;UPON RETURN, CURSOR POSITION IS UNDEFINED.

;THIS ROUTINE MINIMIZES I/O BY SUPPRESSING TRAILING BLANKS ON EACH
;LINE, AND BY SUPPRESSING ANY BLANK LINES AT THE
;BOTTOM OF THE SCREEN.

;THIS ROUTINE IS OPTIMIZED TO REDUCE CPU TIME.

DUMP:	MOVEI	LL,SCRLIN	;INITIALIZE COUNT OF LINES LEFT
	MOVE	B,[POINT 6,SCREEN]	;BYTE POINTER TO SCREEN
	MOVEI	D," "		;ASCII BLANK
	MOVEI	SL,0		;CLEAR COUNT OF QUEUED BLANK LINES

;HERE WHEN PREVIOUS LINES (IF ANY) ARE PROCESSED.
;START PROCESSING NEW LINE.
DUMP1:	MOVEI	SC,0		;CLEAR COUNT OF QUEUED SPACES
	MOVEI	CL,SCRCOL	;INITIALIZE COLUMNS LEFT TO PROCESS

;LOOP THROUGH HERE SCANNING FOR FIRST NON-BLANK CHARACTER.
DUMP2:	ILDB	A,B		;GET NEXT CHARACTER IN LINE
	JUMPE	A,DUMP9		;QUEUE IT IF IT IS BLANK

;HERE WHEN FIRST NON-BLANK CHARACTER OF A LINE HAS BEEN FOUND
DUMP3:	JUMPG	SL,DUMP8	;IF THERE ARE QUEUED BLANK LINES,
				; EXPAND THEM

;HERE WHEN ALL PREVIOUSLY QUEUED BLANK LINES HAVE BEEN EXPANDED.
;LOOP THROUGH HERE ON EACH NON-BLANK CHARACTER OF A LINE.
DUMP4:	JUMPG	SC,DUMP10	;IF THERE ARE QUEUED BLANKS,
				; EXPAND ONE

;HERE WHEN NO BLANKS ARE QUEUED AND THERE IS A NON-BLANK CHARACTER
DUMP5:	ADDI	A,40		;CONVERT FROM SIXBIT TO ASCII
	VTOUTM	A,		;SEND IT TO THE VT05

;LOOP HERE TO SCAN NEXT CHARACTER IN A LINE
DUMP6:	SOJLE	CL,DUMP11	;COUNT LAST CHAR JUST DONE.
				; JUMP IF LINE IS DONE
	ILDB	A,B		;GET NEXT CHARACTER IN THE LINE
	JUMPN	A,DUMP4		;IF NOT BLANK, LOOP BACK TO PROCESS IT
	AOJA	SC,DUMP6	;IF BLANK, QUEUE IT AND SCAN NEXT CHAR
;HERE WHEN FIRST NON-BLANK CHARACTER OF A LINE WAS FOUND AND
; PREVIOUSLY BLANK LINES WERE QUEUED.
;THIS CODE EXPANDS ONE OF THOSE QUEUED LINES.
DUMP8:	PUSHJ	P,EREOL		;ERASE EOL
	PUSHJ	P,CRLF		;OUTPUT CR LF
	SOJA	SL,DUMP3	;GO BACK FOR NEXT

;HERE WHEN A LEADING BLANK WAS FOUND IN SCANNING A LINE
DUMP9:	ADDI	SC,1		;QUEUE THE BLANK
	SOJG	CL,DUMP2	;COUNT AND LOOP FOR NEXT ONE,
				; IF NOT AT END OF LINE
	ADDI	SL,1		;END OF LINE. ALL BLANKS. QUEUE LINE.
	SOJG	LL,DUMP1	;COUNT LINES LEFT AND GO BACK IF MORE
	PJRST	EREOF		; ELSE DONE. ERASE REST OF SCREEN


;HERE WHEN A NON-BLANK CHARACTER WAS FOUND
; AND THERE ARE SPACES TO EXPAND.
DUMP10:	VTOUTM	D,		;OUTPUT ONE BLANK
	SOJA	SC,DUMP4	;DEQUEUE IT AND GO BACK FOR NEXT ONE


;HERE WHEN COMPLETE NON-BLANK LINE HAS BEEN SCANNED
DUMP11:	JUMPE	SC,DUMP12	;TEST FOR QUEUED (TRAILING) BLANKS
	PUSHJ	P,EREOL		;IF SO, ERASE END OF LINE

;HERE WHEN A COMPLETE NON-BLANK LINE HAS BEEN PROCESSED,
DUMP12:	SOJLE	LL,DUMP13	;COUNT LINES DONE. JUMP IF FINISHED.
	PUSHJ	P,CRLF		;NOT DONE YET. OUTPUT CRLF.
	JRST	DUMP1		;AND GO SCAN NEXT LINE

;HERE WHEN ALL LINES HAVE BEEN PROCESSED
DUMP13:	JUMPE	SL,CPOPJ	;IF NO QUEUED BLANK LINES, RETURN
	PJRST	EREOF		; ELSE ERASE EOF AND RETURN
;SUBROUTINE TO POSITION THE CURSOR TO LINE V AND DUMP LINE V TO VT05.

;CALLED WHEN CURSOR IS AT TOP LEFT. UPON RETURN, CURSOR IS UNDEFINED.
;TRAILING BLANKS ARE SUPPRESSED TO SAVE I/O TIME.

LINDMP:	SKIPE	CL,V		;GET COUNT OF LINES TO SKIP. IS IT 0?

;LOOP HERE OUTPUTTING LINE FEEDS TO GET CURSOR TO LINE V.
LINDM1:	PUSHJ	P,LF		;SEND A LINE FEED (IF V NON-ZERO)
	SOJG	CL,LINDM1	;COUNT IT, AND LOOP IF MORE NEEDED

;HERE WHEN CURSOR POSITIONED TO START OF LINE V.
	PUSHJ	P,LINPTR	;GET ILDB POINTER TO START OF LINE V
	MOVEI	D," "		;PICK UP AN ASCII BLANK
	MOVEI	SC,0		;CLEAR COUNT OF QUEUED LINES.
	MOVEI	CL,SCRCOL	;INITIALIZE COUNT OF CHARS LEFT

;LOOP HERE SCANNING EACH CHARACTER IN LINE V.
LINDM2:	ILDB	T,B		;GET NEXT CHARACTER
	JUMPE	T,LINDM5	;IF BLANK, GO QUEUE IT

;(LOOP) HERE WHEN A NON-BLANK CHARACTER SEEN.
LINDM3:	JUMPG	SC,LINDM6	;IF ANY QUEUED BLANKS, UNWIND ONE

;HERE WHEN NON-BLANK CHARACTER SEEN AND NO QUEUED BLANKS ARE LEFT.
	ADDI	T,40		;CONVERT SIXBIT TO ASCII
	PUSHJ	P,VTOUTC	;SEND THE CHARACTER

;HERE WHEN A CHARACTER HAS BEEN PROCESSED.
LINDM4:	SOJG	CL,LINDM2	;IF MORE, GO DO THEM
	JUMPE	SC,CPOPJ	;IF NO QUEUED BLANKS, JUST RETURN
	PJRST	EREOL		; ELSE ERASE END OF LINE AND RETURN


;HERE WHEN A BLANK WAS SEEN.
LINDM5:	AOJA	SC,LINDM4	;QUEUE IT AND GO ON


;HERE WHEN A NON-BLANK CHARACTER WAS SEEN AND THERE ARE QUEUED BLANKS.
LINDM6:	VTOUTM	D,		;SEND A BLANK
	SOJA	SC,LINDM3	;COUNT IT DOWN, AND SEE IF MORE LEFT
	SUBTTL	SYNCRONIZATION AND QUEUING


;SUBROUTINES TO SYNCHRONIZE CRITICAL (SHORT) NON-REENTRANT SECTIONS.
;THESE ROUTINES MAY BE CALLED BY ANY JOB SHARING THE HIGH-SEGMENT.
;THE INTENTION IS TO USE THESE ROUTINES TO INTERLOCK ONLY A FEW
;INSTRUCTIONS OF A HIGHER LEVEL QUEUEING SYSTEM, IN MUCH THE MANNER
;THE MONITOR OCCASIONALLY USES CONO PI,PIOFF.
;THE QUEUING DISCIPLINE DEPENDS ONLY ON JOB NUMBER.
;IF THERE IS A CONFLICT THE LOSER(S) ARE BLOCKED, AND AWOKEN
;ACCORDING TO THE ABOVE DISCIPLINE.

;CAUTION: THIS CODE FAILS ON MULTI-PROCESSOR SYSTEMS USING DRUM-SPLIT!

;SUBROUTINE TO GET Q RESOURCE, WAITING IF NECESSARY.

GETQ:	MOVE	T,QMASK		;SET OUR REQUEST BIT
	IORM	T,@QWORD
	AOSN	QREQ		;TRY AND GRAB THE INTERLOCK
	ANDCAM	T,@QWORD	;WON, SO CLEAR REQUEST BIT

;LOOP THRU HERE WHILE WAITING FOR Q RESOURCE
GETQ1:	TDNN	T,@QWORD	;HAS OUR REQUEST BIT BEEN CLEARED?
	POPJ	P,		;YES, RETURN
	PUSHJ	P,HIBERN	;NO, WAIT UNTIL AWOKEN
	JRST	SRESTA		;ON A RESTART GO START OVER
	JRST	GETQ1		;OK, CHECK FOR SPURIOUS WAKES


;SUBROUTINE TO RELEASE Q RESOURCE, WAKING UP A WAITER, IF THERE IS ONE.

RELQ:	SOSGE	QREQ		;COUNT DOWN USE INTERLOCK
	POPJ	P,		;-1 MEANS NO WAITERS, RETURN
	MOVEI	C,3		;SET TO SCAN ALL QBITS WORDS

;LOOP THRU HERE TO SCAN QBITS LOOKING FOR A 1 BIT
RELQ1:	SKIPE	T,QBITS(C)	;SEE IF WORD IS ZERO
	JFFO	T,RELQ2		;NO, SO FIND FIRST ONE BIT
	SOJGE	C,RELQ1		;YES, TRY NEXT WORD UNLESS LAST
	HALT	.		;SHOULD NEVER HAPPEN

;HERE WHEN A WAITER HAS BEEN FOUND.
RELQ2:	MOVN	T1,T1		;CLEAR HIS REQUEST BIT
	MOVSI	T,400000
	LSH	T,(T1)
	ANDCAM	T,QBITS(C)
	IMULI	C,^D36		;GET HIS JOB NUMBER
	SUB	C,T1
	WAKE	C,		;AWAKEN HIM
	HALT	.		;WAKE SHOULD NEVER FAIL
	POPJ	P,		;RETURN
;SUBROUTINE TO TRY FOR INPUT BUFFER RESOURCE.
;NON-SKIP RETURN IF BUSY, WITH WINPF SET.
;SKIP RETURN IF ASSIGNED, WITH WINPF CLEARED.
;IF WINPF WAS SET WHEN CALLED, THIS ROUTINE ASSUMES REQUEST ALREADY
;WAS QUEUED UP AND MERELY CHECKS FOR SATISFACTION.

TRYINP:	TLNE	F,(WINPF)	;IS THIS THE FIRST TRY?
	JRST	TRYIN1		;NO, SO SKIP MAKING QUEUE ENTRY
	PUSHJ	P,GETQ		;YES. SYNCHRONIZE
	MOVE	T1,QJOBN	;GET OUR JOB NUMBER
	SKIPE	T,AVLINP	;IS INPUT BUFFER FREE
	CAMN	T,T1		; OR ASSIGNED TO ME?
	JRST	TRYIN3		;YES
	IDPB	T1,QININP	;NO, ENTER QUEUE
	MOVE	T,QSTINP	;SET QININP TO START IF AT END
	MOVE	T1,QFNINP
	CAMN	T1,QININP
	MOVEM	T,QININP
	PUSHJ	P,RELQ		;END OF CRITICAL SECTION
	JRST	TRYIN2		;SET WAIT FLAG AND GIVE LOSE RETURN

;HERE WHEN TRIED BEFORE AND LOST
TRYIN1:	MOVE	T,QJOBN		;IS INPUT BUFFER MINE YET?
	CAMN	T,AVLINP
	JRST	TRYIN4		;YES, WIN

;HERE TO SET WAITING FLAG AND GIVE LOSE (NON-SKIP) RETURN
TRYIN2:	TLO	F,(WINPF)	;SET WAITING FLAG
	POPJ	P,		;RETURN

;HERE ON SUCCESSFUL FIRST TRY TO RESERVE THE RESOURCE
TRYIN3:	MOVEM	T1,AVLINP	;ASSIGN INPUT BUFFER RESOURCE TO ME
	PUSHJ	P,RELQ		;END OF CRITICAL SECTION

;HERE WHEN RESOURCE SUCCESFULLY OBTAINED
TRYIN4:	TLZ	F,(WINPF)	;CLEAR WAITING FLAG
	JRST	CPOPJ1		;SKIP RETURN
;SUBROUTINE TO INITIALIZE EACH JOB'S QUEUE DATA

UQINIT:	PJOB	T,		;GET JOB NUMBER
	MOVEM	T,QJOBN		;SAVE IT
	WAKE	T,		;WAKE OURSELF UP
	HALT	.		;WAKE SHOULD NEVER FAIL
	IDIVI	T,^D36		;GET WORD AND BIT FOR THIS NUMBER
	ADDI	T,QBITS
	MOVEM	T,QWORD		;SAVE WORD ADDRESS
	MOVN	T1,T1
	MOVSI	T,400000
	LSH	T,(T1)
	MOVEM	T,QMASK		;BIT MASK
	ANDCAM	T,@QWORD	;CLEAR JOB'S REQUEST BIT
	TLZ	F,(WINPF)	;CLEAR FLAGS
	MOVSI	W,(WAKPRJ!WAKLN) ;SET UP HIBERNATE WAKE ENABLES
	HIBER	W,		;WAKE UP SAME PROJECT OR TTY LINE MODE
	HALT	.		;HIBER UUO FAILED
	POPJ	P,		;RETURN

;SUBROUTINE TO HIBERNATE UNTIL AWOKEN.
;ACCUMULATOR W MUST BE SET UP WITH ENABLE MASK.
;CALL	PUSHJ	P,HIBERN
;	ERROR RETURN
;	NORMAL RETURN

;THE NORMAL RETURN IS TAKEN UNLESS A VTCLSE IS PENDING.

HIBERN:	SKIPG	STTIME		;IS A CLOSE PENDING?
	POPJ	P,		;IF SO, NO-SKIP RETURN
	HIBER	W,		;HIBERNATE
	HALT	.		;HIBER UUO FAILED
	SKIPLE	STTIME		;CHECK AGAIN FOR A CLOSE
	AOS	(P)		;SET UP SKIP RETURN IF NO CLOSE PENDING
	POPJ	P,		;RETURN



;SUBROUTINE TO FREE SHARED OUTPUT BUFFER AND WAKE MASTER JOB.

OUTWAK:	SETZM	SOUTRM		;FREE SHARED OUTPUT BUFFER
				;FALL INTO MWAKE

;SUBROUTINE TO AWAKEN MASTER JOB
;CALLED BY SLAVE WHENEVER SERVICE IS NEEDED FROM THE MASTER.
;NOTE, MWAKE MUST BE CALLED AFTER THE COMMAND TO THE MASTER HAS BEEN
; SET UP.

MWAKE:	MOVE	T,MJOBN		;MASTER JOB NUMBER
	WAKE	T,
	JFCL			;IGNORE FAILURE. MASTER MAY BE GONE
	POPJ	P,		;RETURN
	SUBTTL	COMMON SUBROUTINE RETURNS

CPOPJ1:	AOSA	(P)	;SKIP RETURN
TPOPJ:	POP	P,T	;RESTORE T AND RETURN
CPOPJ:	POPJ	P,	;RETURN
	LIT
	END	SGO