Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93i-bb - 7,6/ap021/ptyser.x21
There are 3 other files named ptyser.x21 in the archive. Click here to see a list.
TITLE	PTYSER - PSEUDO-TELETYPE SERVICE ROUTINES V162
SUBTTL	R CLEMENTS/RCC/DAL	25-OCTOBER-88

	SEARCH	F,S,DEVPRM
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1988>


XP VPTYSR,162		;VERSION NUMBER FOR GLOB AND MAP

PTYSER::ENTRY	PTYSER	;DUMMY GLOBAL FOR PTY ROUTINES IN LIBRARY SEARCH
;PTY DEVICE-DEPENDENT IO STATUS BITS (RH DEVIOS)

XP IOPTW,4000	;OUTPUT WAIT (CONTROLLED JOB HAS DONE INPUT)
XP IOPTRE,2000	;PTY RESPONSE. CONTROLLED JOB HAS DONE OUTPUT
XP MONMOD,1000	;THE CONTROLLED TTY IS IN MONITOR COMMAND MODE
SUBTTL	AUTOCONFIGURE


;DRIVER CHARARCTERISTICS
;	PTY	= PTYCNF
;	PTY	= PSEUDO-TERMINALS
;	0	= MAXIMUM DEVICES IN SYSTEM
;	0	= KONTROLLER TYPE
;	0	= MAXIMUM DRIVES PER KONTROLLER
;	0	= HIGHEST DRIVE NUMBER ON KONTROLLER
;	MDSEC0	= SECTION FOR KDB/UDB
;	MDSEC0	= SECTION FOR DDB
DRVCHR	(PTY,PTY,0,0,0,0,MDSEC0,MDSEC0,<DR.XAD!DR.SFT>)

	 .ORG	DEVLEN
PTYLEN:!			;LENGTH OF PTY DDB
	 .ORG


	$LOW

PTYDDB:	DDBBEG	(PTY,PTYLEN)
	SETWRD	(DEVCHR,<STTYBF+1>)		;DEVCHR
	SETWRD	(DEVSER,<MCSEC0+PTYDSP>)	;DEVSER
	SETWRD	(DEVMOD,<DVIN!DVOUT,,<1_A>!<1_AL>>) ;DEVMOD
	SETWRD	(DEVTYP,<<.TYPTY*.TYEST>,,DEPEVM>) ;DEVTYP
	SETWRD	(DEVCPU,<707B8>)		;DEVCPU
	DDBEND
	$HIGH


EQUATE	(LOCAL,0,<PTYCKT,PTYKDB,PTYKLN,PTYUDB,PTYULN>)
EQUATE	(LOCAL,0,<PTYICD,PTYICL,PTYINT,PTYULB,PTYULP>)

PTXDSP:	DRVDSP	(PTY,,PTYDDB,PTYLEN,0)

	$HIGH
PTYCFG:	SKIPN	PTYTAB##	;ALREADY INITIALIZED?
	SKPCPU	(0)		;POLICY CPU?
	POPJ	P,		;THEN DO NOTHING
	JRST	PTYCF1		;DO ONCE-ONLY STUFF

	$INIT

PTYCF1:	PUSHJ	P,SAVE1##	;SAVE P1
	MOVSI	P1,-M.PTY##	;NUMBER OF DDBS TO BUILD

PTYCF2:	MOVSI	T1,'PTY'	;GENERIC NAME
	HRR	T1,P1		;UNIT NUMBER
	SETZ	T2,		;LOCAL DEVICE
	PUSHJ	P,AUTDDB##	;BUILD DDB AND LINK INTO CHAIN
	  POPJ	P,		;NO CORE??
	MOVEM	F,PTYTAB##(P1)	;SAVE ADDRESS
	AOBJN	P1,PTYCF2	;LOOP FOR ALL TTY DDBS
	MOVE	T1,[PTYOFS##,,M.PTY##] ;PTY PARAMETERS FOR BATCH
	MOVEM	T1,PTYPRM##	;SAVE IN GETTAB TABLE
	MOVE	T1,[-M.PTY##,,PTYTAB##] ;POINTER TO PTY TABLE
	MOVEM	T1,PTYPTR##	;SAVE IN GETTAB TABLE
	POPJ	P,		;RETURN

	$HIGH
	JRST	ECOD2##		;SPECIAL ERROR STATUS
	JRST	PTYINE		;INIT ENTRY
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;HUNG DEVICE. CAN'T HAPPEN. STOP JOB.
PTYDSP:	JRST	PTYREL		;RELEASE
	JRST	OUT##		;OUTPUT CLOSE
	JRST	PTYOUT		;OUTPUT UUO
	JRST	PTYIN		;INPUT UUO


;CODE CALLED ON A RELEASE OF PTY

PTYREL:	SE1ENT			;ENTER SECTION 1
	HRRZS	F		;CLEAR BITS FROM UUOCON
	PUSH	P,W		;SAVE FOR PTY DDB ADDR
	PUSH	P,P4		; AND PTY S
	PUSH	P,F		;SAVE DDB ADDRESS
	PUSHJ	P,PTSETL	;SET UP U TO LINKED TTY
IFN FTNET,<
	PUSHJ	P,VTMPRL##	;SEE IF THE PTY NEEDS DISCONNECTING
>
	PUSHJ	P,XMTCHR##	;READ A CHARACTER
	  SKIPA			;NONE LEFT
	JRST	.-2		;KEEP READING TILL EMPTY
	PUSHJ	P,CNCMOD##	;MAKE SURE AT COMMAND LEVEL
	PUSHJ	P,TSETBI##	;CLEAR TTY INPUT BUFFER
	HRRZ	F,LDBDDB##(U)	;GET TTY'S DDB ADDRESS
	JUMPE	F,PTYRL2	;DONE IF NO DDB ATTACHED
	PUSH	P,J		;SAVE J OVER PSISIG
	LDB	J,PJOBN##	;GET OWNER OF DDB (ATTACHED JOB)
	MOVE	T1,DEVMOD(F)	;NEED TO MAKE SURE JOB WILL DETACH
	TLNE	T1,TTYATC	;IS DDB CONTROLLING A JOB??
	SKIPN	J		;AND A VALID JOB?
	JRST	PTYRL1		;NO, DON'T CALL PSISER
	SIGNAL	C$DATT		;GIVE DETACHING JOB AN INTERRUPT
	  JFCL
PTYRL1:	POP	P,J		;RESTOR J FOR UUOCON
	PUSHJ	P,PTYDTC##	;YES. DETACH FROM IT
PTYRL2:	POP	P,F		;RESTORE PTY DDB
	PUSHJ	P,LDBCLR##
	PJRST	P2POPJ		;RESTORE AC'S AND RETURN
;INIT ENTRY TO "LOCATE" A PTY

PTYINE:	SE1ENT			;ENTER SECTION 1

IFN FTNET,<

	MOVE	J,.CPJOB##	;GET JOB NUMBER
	MOVE	T1,JBTLOC##(J)	;GET JOB LOCATION
	DPB	T1,PDVSTA##	;INSERT JOB LOCATION IN DEVICE LOC FIELD
>
	PUSHJ	P,PTSFSP	;SET/CLEAR FULL SCNSER PTY
	LDB	T1,LDPFSP##	;FULL-SCNSER-PTY BIT
	TRC	T1,1		;INVERT FOR OUR USES
	TRNN	M,A8		;IF NOT INITED FOR 8-BIT,
	TRO	T1,1		;THEN CAN'T DO IT
	DPB	T1,LDP7BT##	;SET LIL7BT ACCORDINGLY
	JRST	REGSIZ##	;RETURN WITH BUFFER LEN (FROM DDB)
;HERE ON AN OUTPUT UUO TO PTY. SEND CHARACTERS TO THE LINKED
;TTY. CONVERT LOWER CASE TO UPPER UNLESS USER HAS REQUESTED LC.


PTYOUT:	SE1ENT			;ENTER SECTION 1
	HRRZS	F		;CLEAR I/O DONE SO FAR BITS
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	MOVE	S,DEVIOS(F)	;GET DEVICE STATUS
	TLNE	S,IOBEG		;VIRGIN DEVICE?
	PUSHJ	P,PTYREL	;YES. CLEAR IT OUT.
	MOVSI	S,IOBEG		;CLEAR VIRGIN BIT
	ANDCAB	S,DEVIOS(F)	; ..
				;SAVE THESE AC'S JUST IN CASE
	PUSH	P,W		; UUOCON MIGHT WANT THEM
	PUSHJ	P,PTSETL	;SET UP U, P4
	HRRZ	P1,DEVOAD(F)	;USER VIRTUAL ADDRESS OF OUTPUT BUFFER
	HRRZ	T1,P1		;CHECK ADDRESSES OF OUTPUT BLOCK
	PUSHJ	P,BRNGE##	;MAKE SURE BUFFER IS ADDRESSABLE
	EXCTUX	<HRRZ P2,1(P1)>	;SIZE OF DATA AREA (WORDS) TO BE OUTPUT
	JUMPE	P2,PTYOU6	;SKIP THIS BUFFER IF EMPTY
	EXCTUX	<LDB T1,[POINT 17,(P1),17]>  ;GET TOTAL BUFFER SIZE
	MOVE	T4,P2		;SAVE BYTE/WORD COUNT
	TRNN	S,A8		;NOT IN 8-BIT MODE?
	TDZA	T4,T4		;YES, INDICATE USE WORD COUNT
	LSH	T1,2		;ELSE, FOUR BYTES PER WORD
	CAML	P2,T1		;DATA CONTAINED WITHIN BUFFER?
	JRST	PTYOUE		;NO, USER BLEW IT
	PUSHJ	P,SRLPTR	;GET BYTE COUNT AND POINTER
	SKIPE	T4		;WAS THERE AN EXACT BYTE COUNT?
	MOVE	P2,T4		;YES, USE IT INSTEAD
PTYOU3:	EXCTUX	<ILDB	T3,P1>	;GET CHARACTER FROM BUFFER OF CONTROL JOB
;	ANDI	T3,CK.CHR	;KEEP ONLY VALID CHARACTER BITS
	PUSHJ	P,SPCHEK##	;IS IT A SPECIAL CHARACTER?
	  JRST PTYOU4		;NO. GO CHECK ON LOWER CASE.
	TLNE	T1,CHRIA##	;UNLESS CC.NSA,
	JUMPE	T3,PTYOU5	;DON'T INCLUDE NULLS
PTYOU1:	PUSHJ	P,PTYPUT##	;PASS CHAR TO SCNSER
	  JRST PTYOUE		; TOO MANY CHARACTERS. ERROR.
PTYOU5:	SOJG	P2,PTYOU3	;LOOP IF MORE IN CONTROLLERS BUFFER
	PUSHJ	P,PTEXCH	;SWAP AC'S AROUND SO PTY'S IN DDB
PTYOU6:	PUSHJ	P,ADVBFE##	;ADVANCE CONTROLLER'S OUTPUT BUFFER
	  JFCL			;JUST SINGLE BUFFER
	MOVEI	S,IOPTW		;CLEAR INPUT WAIT BIT.
	ANDCAM	S,DEVIOS(F)	;IN PTY'S STATUS WORD
	MOVSI	S,IOFST		;SET FIRST-ITEM BIT
	IORB	S,DEVIOS(F)	; ..
	MOVE	T1,LDBDCH##(U)	;GET DEVICE BITS
	TLNE	T1,LDLCOM##	;CONTROLLED TTY AT TOP LEVEL?
	MOVEI	S,MONMOD	;YES. TELL CONTROLLER
	IORB	S,DEVIOS(F)	; ..
	JRST	WPOPJ##		;RESTORE W AND P4, RETURN TO UUOCON

PTYOU4:	MOVE	T2,LDBDCH##(U)	;GET DEVICE BITS
	TLNE	T2,LDLLCT##	;NO. USER WANT TRANSLATION?
	PUSHJ	P,PTBTCH	;AND IS THIS A FULL-SCNSER PTY?
	  JRST	PTYOU1		;LEAVE AS IS.
	LDB	T2,[POINT 7,T3,35] ;YES, GET TRANSLATABLE PORTION OF CHARACTER
	CAILE	T2,140		;IS CHARACTER UPPER CASE?
	TRC	T3,40		;YES. MAKE UPPER CASE
	JRST	PTYOU1		;RETURN TO LOOP

PTYOUE:	PUSHJ	P,PTEXCH	;POINT AT PTY, NOT TTY
	MOVEI	S,IOBKTL	;BLOCK-TOO-LARGE ERROR BIT
	IORB	S,DEVIOS(F)	;..
	JRST	PTYOU6		;STORE AND RETURN
;HERE ON AN INPUT UUO FOR PTY. GET CHARACTERS FROM LINKED
;TTY'S OUTPUT BUFFER, PASS THEM TO PTY CONTROL JOB


PTYIN:	SE1ENT			;ENTER SECTION 1
	HRRZS	F		;CLEAR I/O DONE SO FAR BITS
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	PUSH	P,W		; ..
	PUSHJ	P,PTSETL	;SET UP U AND P4
	MOVE	F,P4		;USE PTY'S DDB IN BUFFER OPERATIONS
	PUSH	P,U		;SAVE U OVER CALLS TO UUOCON
	HRRZ	T1,DEVIAD(F)	;INPUT BUFFER ADDRESS
	PUSHJ	P,BUFCLR##	;CLEAR USER'S BUFFER AND ADR CK
	  JRST ADRERR##		;NO GOOD. GIVE ERROR MSG
	HRRZ	P1,DEVIAD(F)	;USER VIRTUAL ADDRESS OF INPUT BUFFER
	EXCTUX	<LDB P2,[POINT 17,@P1,17]> ;BUFFER (DATA) SIZE, PLUS ONE
	SUBI	P2,1		;BUFFER SIZE IN WORDS, MINUS LINK
	POP	P,U		;RESTORE U
	MOVE	S,DEVIOS(F)	;GET I/O MODE
	PUSHJ	P,SRLPTR##	;GET BYTE POINTER & COUNT
	MOVSI	T1,LAL8BT##	;8-BIT TERMINAL BIT
	TRNN	S,A8		;ARE WE ABLE TO RECEIVE 8-BIT BYTES?
	ANDCAM	T1,LDBATR##(U)	;NO, THIS ISN'T AN 8-BIT TERMINAL
	PUSH	P,P2		;PRESERVE MAXIMUM BYTE COUNT

PTYIN2:	PUSHJ	P,XMTCHR##	;GET CHARACTER FROM SCNSER,IF ANY
	  JRST PTYIN1		;NONE THERE.
	EXCTUU	<IDPB	T3,P1>	;STORE IN CONTROLLER'S BUFFER
	SOJLE	P2,PTYIN1	;SEND BUFFER IF FULL
	PUSHJ	P,SPCHEK##	;GET SPECIAL CHAR BITS
	  JRST PTYIN2		;NOT SPECIAL, SO LOOP FOR MORE
	TLNN	T1,CHBRK##	;BREAK CHAR?
	  JRST PTYIN2		;NO, LOOP FOR MORE
	TRNN	W,AL!A8		;BUFFER ENDED BY BREAK CHAR? (W IS LOGICAL S)
	  JRST PTYIN2		;NO, LOOP FOR MORE
				;YES, SO SEND THIS BUFFER
PTYIN1:	PUSHJ	P,PTEXCH	;GET PTY DDB BACK IN AC DDB
	POP	P,T1		;GET BACK ORIGINAL MAX BYTE COUNT
	TRNN	S,A8		;BYTE COUNT IF 8-BIT
	SKIPA	P2,DEVIAD(F)	;NOT 8-BIT - BUFFER PTR IN P2
	SKIPA			;8-BIT - DON'T DESTROY BYTE COUNT
	JRST	PTYINC		;NOT 8-BIT--WORD COUNT
	MOVN	P1,P2		;COUNT OF BYTES LEFT
	ADD	P1,T1		;FROM MAX = COUNT OF BYTES DEPOSITED
	SKIPA	P2,DEVIAD(F)	;ALREADY HAVE COUNT IN P1
PTYINC:	SUBI	P1,1(P2)	;COMPUTE WORD COUNT FOR UUOCON
	EXCTUU	<HRRM P1,1(P2)>	;STORE WITH DATA IN RING
	PUSHJ	P,ADVBFF##	;ADVANCE INPUT BUFFER
	  JFCL			;BUT JUST SINGLE BUFFER FOR NOW
	MOVEI	S,IOPTRE	;CLEAR RESPONSE-WAITING BIT
	ANDCAB	S,DEVIOS(F)	;IN HIS DDB
	SKIPN	LDBECC##(U)	;CHECK ECHOS
	SKIPE	LDBFLP##(U)	; AND FILLERS
	MOVEI	S,IOPTRE	;ASK CONTROLLER TO READ SOME MORE
	SKIPG	LDBEOC##(U)	;ON ANY ECHO/FILL CHARACTERS
	SKIPLE	LDBTOC##(U)	;IS THAT RIGHT? ANY MORE?
	MOVEI	S,IOPTRE	;MORE THERE. PUT BIT BACK ON.
	IORB	S,DEVIOS(F)	; TO FORCE BATCH TO DO ANOTHER INPUT
	JRST	WPOPJ##		;RETURN FROM INPUT UUO
;ROUTINE TO FIND CONTROLLER OF THIS JOB, IF IT'S CONTROLLED BY A PTY

CTLJOB::CAMN	T1,[-1]		;WHAT JOB DOES HE WANT?
	MOVE	T1,J		;HIS OWN IF -1
	PUSHJ	P,LGLPRC##	;SUPPLIED JOB NUMBER LEGAL?
	  POPJ	P,0		;NO. ERROR RETURN
	HRRZ	F,TTYTAB##(T1)	;GET TTY DDB FOR THIS JOB
	PUSHJ	P,CTLJBD	;FIND CONTROLLING JOB
	PJRST	STOTC1##	;OK RETURN STORE VALUE IN USER'S AC


;SUBROUTINE TO FIND JOB NUMBER OF JOB CONTROLLING THIS TTY
;ARGS F=DDB OF TTY
;VALUE T1=JOB NUMBER OF CONTROLLING JOB IF JOB'S TTY IS A PTY OR -1
;IF T1 POS, F=CONTROL JOB'S PTY DDB
;	U=LDB ADDRESS
;PRESERVES T3 AND T4 (SEE SNDHED IN COMCON)

CTLJBD::JUMPE	F,CTLJB1	;IF DDB=0 GIVE -1 RETURN
	MOVE	U,DDBLDB##(F)	;IF DETACHED, JOB IS NOT CONTROLLED
				;FALL INTO CTLJBU


;SUBROUTINE TO FIND JOB NUMBER OF JOB CONTROLLING THIS LINE.
;ARGS U=ADDRESS OF LDB
;VALUE IS SAME AS CTLJBD

CTLJBU::JUMPE	U,CTLJB1
	SE1ENT			;ENTER SECTION 1
	LDB	T2,LDPLNO##	;GET UNIT NUMBER OF TTY
CTLJB::	SUBI	T2,PTYOFS##	;CONVERT TO LINKED PTY
	JUMPL	T2,CTLJB1	;IF NEGATIVE, ITS A REAL TTY
	CAIL	T2,M.PTY##	;IS IT A LEGAL PTY NUMBER (BETTER BE)
	JRST	CTLJB1		;NO-MUST BE ON REMOTE
	MOVE	F,PTYTAB##(T2)	;GET PTY DDB FOR THIS CONTROLLER
	LDB	T1,PJOBN##	;GET GUY WHO INITED IT
	POPJ	P,		;RETURN THIS TO USER

CTLJB1:	MOVNI	T1,1		;RETURN MINUS ONE IF NOT CONTROLLED BY PTY
	POPJ	P,		; ..

;STILL IN FTPTYUUO CONDITIONAL
;ROUTINE TO RETURN STATUS OF JOB REQUESTED, AND ITS PTY IF ANY

UJBSTS::MOVEI	U,0		;INITIALIZE AS A FLAG FOR BELOW
	JUMPL	T1,UJBST1	;ASKING FOR JOB OR PTY?
	PUSHJ	P,DVCNSG##	;SETUP F
	  POPJ	P,		;NONE-ERROR
UJBST0:	HRRZS	F		;ZERO LEFT HALF BITS
	LDB	T1,PDVTYP##  	;CHECK TO SEE IF ITS A PTY
	CAIE	T1,.TYPTY	; ..
	POPJ	P,0		;NOT. GIVE FAIL RETURN.
	LDB	T1,PUNIT##	;ITS A PTY. GET ITS NUMBER
	ADDI	T1,PTYOFS##	;CONVERT TO TTY NUMBER IT CONTROLS
	CAIL	T1,TTPLEN##	;A LEGAL TTY NUMBER (BETTER BE)
	POPJ	P,0		;SYSTEM FAILURE. GIVE ERR RET
	MOVE	U,LINTAB##(T1)	;GET LDB OF THE TTY
IFN FTNET,<
	SKIPGE	LDBREM##(U)	;IS TTY NETWORKED TO A REMOTE HOST?
	JRST	UJBNTS		;YES, FUDGE UP A RETURN VALUE
> ;END IFN FTNET
	HRRZ	F,LDBDDB##(U)	;NO, LOCAL TTY, FOLLOW TO ATTACHED TTY DDB
	SKIPE	T1,F		;IF NONE, CLEAR T1
	LDB	T1,PJOBN##	;GET JOB NUMBER OF CONTROLLED JOB
UJBST1:	MOVMS	J,T1		;GET POSITIVE, IF USER SUPPLIED -JOB NUMBER
	PUSHJ	P,LGLPR1##	;MAKE SURE ITS A LEGAL JOB NUMBER
	  POPJ	P,0		;NOT.
	AOS	0(P)		;OK. FROM HERE ON, GIVE GOOD RETURN
IFN FTMP,<
	JUMPE	J,.+3		;IF A REAL JOB,
	CAMN	J,COMJOB##	;TARGET JOB IN COMCON ON CPU0
				; SO THAT THESE BITS MIGHT BE CHANGING?
	PUSHJ	P,ONCPU0##	;YES, AVOID THE RACE
>
	PUSHJ	P,UJBSTX	;GET STATUS BITS
	PJRST	STOTAC##	;AND SUPPLY THEM TO THE USER


IFN FTNET,<
;HERE IF PTY'S TTY IS NETWORKED (.SET HOST) TO A REMOTE HOST

UJBNTS:	SETZ	T1,		;INITIAL COLLECTION OF STATUS BITS
	SKIPLE	LDBTOC(U)	;ANY OUTPUT CHARACTERS WAITING?
	TLO	T1,(JB.UOA)	;YES, LIGHT "OUTPUT AVAILABLE"
	SKIPN	LDBTIC##(U)	;ANY CHARACTERS IN INPUT BUFFER
	TLO	T1,(JB.UDI)	;YES, THEN ASSUME "DEMANDING INPUT"
	LDB	T2,LDPDRQ##	;ON SECOND THOUGHT, GET DATA REQUEST COUNT
	CAIG	T2,0		;IF THE REMOTE HAS NO DATA REQUESTS
	TLZ	T1,(JB.UDI)	;THEN CHANGE OUR MIND, DON'T "DEMAND INPUT"
	JRST	STOTC1		;SKIP RETURN JOBSTS BITS TO USER AC
> ;END IFN FTNET
;UJBSTX - DO THE WORK FOR JOBSTS CALLI

UJBSTX::SE1ENT			;ENTER SECTION 1
	MOVE	T2,JBTSTS##(J)	;GET BITS FROM JOB STATUS TABLE
	MOVEI	T1,0(J)		;CLEAR LH, GET JOB NUMBER
	TLNE	T2,RUN		;RUNNING?
	TLO	T1,(JB.URN)	;YES
	TLNE	T2,JNA		;MAKE SURE JOB EXISTS
	TLO	T1,(JB.UJA)	;JOB NUMBER ASSIGNED
	TLNE	T2,JLOG		;LOGGED IN?
	TLO	T1,(JB.ULI)	;YES.
	TLNE	T2,JACCT	;IN PRIVILEGED CUSP?
	TLO	T1,(JB.UJC)	;YES.
	JUMPN	U,UJBST2	;IF LINE KNOWN LINE, SKIP THIS PART
	HRRZ	F,TTYTAB##(J)	;NOW FIND TTY STATUS FOR THIS JOB
	JUMPE	F,CPOPJ##	;IF DETACHED, JUST STORE THIS
	MOVE	U,DDBLDB##(F)	;GET LDB ADDR
	JUMPE	U,CPOPJ##	;REDUNDANT DETACH CHECK
UJBST2:	PUSHJ	P,TOPSOP##	;SKIP IF OUTPUT PRESENT
	  CAIA			;NONE
	TLO	T1,(JB.UOA)	;YES, FLAG IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVE	T2,LDBDCH##(U)	;GET LINE BITS
	TLNN	T2,LDLCOM##	;AT COMMAND LEVEL?
	JRST	UJBSTU		;NO.
	TLO	T1,(JB.UML)	;FLAG MONITOR COMMAND LEVEL
	MOVE	T2,JBTSTS##(J)	;GET JOB STATUS BACK
	TLNN	T1,(JB.UOA)	;NO TI IF STILL ECHOING
	TRNE	T2,JDCON	;IS JOB IN DEVICE ERROR WAIT?
	JRST	UJBST6		;YES DON'T TELL CALLER ABOUT TI HERE

	TLNN	T2,CMWB		;IDLE?
	SKIPGE	LDBCOM##(U)	;AND NO COMMAND WAITING TO BE SEEN?
	JRST	UJBST6		;NOT IDLE, RETURN ANSWER TO CALLER
	JRST	UJBST3		;IDLE. FLAG IT.

UJBSTU:	JUMPE	F,UJBST6	;IF NO ATTACHED JOB, STORE THIS MUCH
	PUSHJ	P,ECCAVL##	;STILL CHARS TO ECHO?
	JRST	UJBST6		;YES - CAN'T BELIEVE JBTSTS
	MOVEI	T2,TTIUDI##	;USER INPUT WAKEUP CONDITION
	TDNN	T2,JBTRTD##(J)	;DEMANDING INPUT TO SATISFY CONDITIONS?
	JRST	UJBST5		;NO, SKIP THIS
	LDB	T2,PJBSTS##	;YES, GET JOB STATUS
	CAIE	T2,SLPQ##	;IS THE JOB ASLEEP?
	CAIN	T2,NAPQ##	;EVEN FOR A SHORT WHILE
	SKIPA	T2,JBTST2##(J)	;YES, GET MORE BITS TO TEST
	JRST	UJBST5		;NO, DON'T LIGHT HIBER BIT AFTER ALL
	TLNE	T2,(JS.HIB)	;MAKE SURE IT'S REALLY FOR HIBER
	TLO	T1,(JB.UHI)	;YES, HIBERING FOR INPUT
UJBST5:	MOVE	S,DEVIOS(F)	;GET TTY STATUS WORD
	TLNN	S,IOW		;IN A WAIT?
	JRST	UJBST6		;NO
	TLNN	S,TTYOUW##	;WAITING FOR INPUT?
	JRST	UJBST3		;YES
	TLO	T1,(JB.UTO)	;NO, OUTPUT, NOTE JOB IN 'TO' STATE
	JRST	UJBST6		;NO
UJBST3:
	MOVE	T2,LDBCOM##(U)	;IS THERE AN UNPROCESSED FORCED COMMAND
	TLNN	T2,LDBCMF##	;OUTSTANDING, DON'T LIGHT WAITING FOR INPUT
	TLO	T1,(JB.UDI)	;YES. FLAG IT

UJBST6:	MOVE	T2,LDBDCH(U)	;THE UBIQITUOUS DCH WORD AGAIN
	TLNE	T2,LDLFCS##	;FULL CHARACTER SET (TECO) MODE?
	TLO	T1,(JB.UFC)	;YES, NOTE THAT TOO.
	TLNE	T2,LDLBKA##	;BREAK ON ALL CHARACTERS?
	TLO	T1,(JB.UBK)	;YES, NOTE IT.
	TLNE	T2,LDLNEC##	;NO ECHO (DUE TO PROGRAM)?
	TLO	T1,(JB.UNE)	;YES, NOTE IT.
	MOVEI	T2,L1RCHP##	;THE TTY-CHARACTERISTICS-CHANGED-POKER BIT
	TDNE	T2,LDBBYT##(U)	;HAVE THE TERMINAL CHARACTERISTICS CHANGED?
	TLO	T1,(JB.UCC)	;YES, TELL HAPLESS USER
	ANDCAM	T2,LDBBYT##(U)	;AND CLEAR THE BIT IN ANY CASE
IFN FTMIC<
	SKIPE	T2,LDBMIC##(U)	;IS HE RUNNING UNDER MIC?
	TLNE	T2,LDLMCB##	;AND IS ^B FLAG SET
	JRST	UJBST4		;YES (THEN PRETEND MIC ISN'T THERE!)
	MOVE	T2,.CPJOB##	;WHO IS DOING THIS?
	MOVE	T2,JBTNAM##(T2)	;WHAT IS HIS NAME?
	CAMN	T2,[SIXBIT/MIC/] ;IS IT MIC?
	JRST	UJBST4		;YES, LEAVE STATUS ALONE
	TLZ	T1,(JB.UDI!JB.UHI) ;DON'T LET BATCON SEE TI FOR MIC UNDER BATCH
	MOVE	T2,LDBMIC##(U)	;GET MIC STATUS
	TLNE	T2,LDLRSY##	;IS HE SYNC'ED FOR RESPONSE STUFF?
	TLZ	T1,(JB.UOA)	;YES--DON'T LIGHT WAITING FOR OUTPUT
				; UNTIL MIC HAS SEEN IT
UJBST4:>  ;END FTMIC
	POPJ	P,0		;RETURN ANSWER TO CALLER
;ROUTINE TO CAUSE PTY CONTROL JOB TO START TAKING CHARACTERS
;FROM THE CONTROLLED TTY'S OUTPUT CHARACTER LIST. CALLED AT END
;OF VARIOUS TTY OUTPUT UUOS AND TTCALLS.


PTYPE::	PUSH	P,W		;SAVE AC'S IN CASE NEEDED
	PUSH	P,P4		; ..
	LDB	T1,LDPLNO##	;GET TTY LINE NUMBER
	HRRZ	P4,PTYTAB##-PTYOFS##(T1) ;GET PTY DDB ADDRESS
	MOVEI	W,IOPTRE	;RESPONSE BIT TO CONTROLLER
	IORB	W,DEVIOS(P4)	;SET IN CORE.
	PUSHJ	P,PTWAKE	;WAKE UP CONTROLLER
	JRST	P2POPJ		;RESTORE AC'S AND RETURN

;ROUTINE TO SEARCH CLOCK QUEUE FOR JOB CONTROLLING THIS PTY, TO SEE
;IF THAT JOB IS SLEEPING, AND IF SO TO REDUCE SLEEP TIME TO ONE TICK
;SO IT WILL WAKE UP AND START SERVICING THE PTY.
;
;CALL WITH P4 SET TO PTY'S DDB. CLOBBERS T1,T2,T3

PTWAKE:	PUSH	P,T3		;SAVE CHARACTER AC
	MOVE	T2,DEVIOS(P4)	;GET STATUS
	TRNN	T2,IOPTW	;PTY HUNGRY
	TDZA	T1,T1		;NO, NO BITS YET
	MOVEI	T1,IR.OUD	;YES, ASK FOR OUTPUT FROM CONTROLLER
	TRNE	T2,IOPTRE	;OUTPUT AVAILABLE
	TRO	T1,IR.IND	;YES, ASK CONTROLLER TO READ IT
	JUMPE	T1,PTWAK1	;IGNORE IF NO BITS
	EXCH	P4,F		;SAVE F, COPY DDB ADDRESS
	PUSHJ	P,PSIDVB##	;GENERATE AN INTERRUPT
	EXCH	P4,F		;RESTORE ACS
PTWAK1:	LDB	T1,PTYPJN ;GET CONTROLLING JOB'S JOB NUMBER
	MOVSI	T2,PTYWUE##	;IS THE CONTROL HIBERNATING ON PTY'S
	TDNE	T2,JBTRTD##(T1)	;WAKE JOB ONLY IF IT IS ENABLED FOR PTY WAKE
	PUSHJ	P,WAKPST##	;GO WAKE THIS CONTROLLER JOB
	JRST	T3POPJ##	;RESTORE CHARACTER AC AND RETURN

PTYPJN:	XWD	PJBNLH##+P4,DEVJOB	;COPY OF PJOBN WITH DIFFERENT XR.
;ROUTINES TO KEEP CONTROL JOB INFORMED OF TTY LINE'S STATUS, AND
;TO WAKE CONTROLLER IF APPROPRIATE.
;CALL FROM SCNSER WITH LINE SET TO TTY'S LDB


PTMNMD::SE1ENT			;ENTER SECTION 1
	PUSH	P,W		;SAVE THIS AC
	MOVEI	W,MONMOD!IOPTW	;LINKED TTY WENT TO MONITOR MODE
	JRST	PTYSET		;GO SET BIT

PTMNMZ::SE1ENT			;ENTER SECTION 1
	PUSH	P,W		;SAVE THIS AC
	HRROI	W,MONMOD	;JOB WENT TO USER MODE
	JRST	PTYSET		;GO CLEAR BIT

PTYOW::	SE1ENT			;ENTER SECTION 1
	PUSH	P,W		;SAVE THIS AC
	MOVEI	W,IOPTW		;CONTROLLED TTY IN INPUT WAIT.
PTYSET:	PUSH	P,P4		;SAVE AC POSSIBLY NEEDED ELSEWHERE
	LDB	P4,LDPLNO##	;GET LINE NUMBER OF CONTROLLED TTY
	HRRZ	P4,PTYTAB##-PTYOFS##(P4) ;GET PTY DDB
	TLZE	W,-1		;CLEARING OR SETTING BIT IN S WORD?
	ANDCAB	W,DEVIOS(P4)	;CLEARING.
	IORB	W,DEVIOS(P4)	;(SETTING)
	TRNE	W,IOPTW		;WANT TO WAKE CONTROLLER?
	PUSHJ	P,PTWAKE	;YES. DO SO.
P2POPJ:	POP	P,P4		;RESTORE AC'S
	JRST	WPOPJ##		;AND RETURN


;SUBROUTINE TO CHECK IF LINE IS A BATCH PTY OR NOT A FULL SCNSER PTY
; FOR THINGS LIKE AUTO PAUSE ON TTY PAGE N OR OUTPUT FILLERS
;	U = LDB
;	PUSHJ P,PTBTCH
;	  RETURN HERE IF A REGULAR OLD PTY
;	RETURN HERE IF IT ISN'T A PTY OR A NEW KIND

PTBTCH::SE1ENT			;ENTER SECTION 1
	PUSH	P,T1		;SAVE CALLERS
	MOVEI	T1,LDRPTY##	;PTY BIT
	TDNN	T1,LDBDCH##(U)	;IS THIS ONE AT ALL
	JRST	TPOPJ1##	;NO
	MOVSI	T1,LDLFSP##	;FULL SCNSER PTY BIT
	TDNN	T1,LDBTTW##(U)	;FULL CONTROL DESIRED
	JRST	TPOPJ##		;NO, DON'T CONFUSE OPSER
	LDB	T1,LDPLNO##	;GET LINE NUMBER FOR PTY
	HRRZ	T1,PTYTAB##-PTYOFS##(T1) ;GET PTY DDB
	MOVE	T1,DEVCHR(T1)	;GET PTY BITS
	TLNN	T1,DVDIBP	;THIS A BATCH JOB
	AOS	-1(P)		;NO
	JRST	TPOPJ##		;YES
;SUBROUTINE TO SWAP PTY AND TTY DDB AND S AC'S

PTEXCH:	EXCH	S,W		;SWAP THE STATUS ACS
	EXCH	F,P4		;SWAP THE DATA BLOCK AC'S
	POPJ	P,0		;AND RETURN

;SUBROUTINE TO SET UP AC LINE FOR A PTY UUO. CALL WITH DDB AT PTY'S DDB.
;P4 WILL GET DDB, LINE WILL GET LDB OF RELATED TTY.

PTSETL:	LDB	U,PUNIT##	;GET UNIT NUMBER OF THE PTY
	MOVE	U,LINTAB##+PTYOFS##(U) ;GET LDB ADDRESS
	MOVE	P4,F		;MAKE WAY FOR SCNSER TO USE DDB
	MOVE	W,S		;COPY CURRENT PTY STATUS FOR PTEXCH
	POPJ	P,0		;AND RETURN

;SUBROUTINE TO SET/CLEAR FULL SCNSER CONTROL

PTSFSP:	PUSH	P,W		;SAVE CALLERS
	PUSH	P,P4		;...
	PUSHJ	P,PTSETL	;FIND LDB
	MOVSI	P4,LDLFSP##	;FULL SCNSER PTY BIT
	ANDCAM	P4,LDBTTW##(U)	;ASSUME THIS IS AN OLD STYLE PTY
	MOVEI	W,DEPDEL	;UNLESS OPENED AS FULL SCNSER MODE
	TDNE	W,DEVSTA(F)	;WAS IT
	IORM	P4,LDBTTW##(U)	;YUP, LIGHT THE BIT
	JRST	P2POPJ		;RESTORE ACS AND RETURN
	SUBTTL	END OF PTY SERVICE ROUTINE

LIT

PTYEND:	END