Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - mit/monitor/ttphdv.mac
There are 8 other files named ttphdv.mac in the archive. Click here to see a list.
;<BERLIN.M5>TTPHDV.MAC.2,  7-Sep-82 17:19:34, Edit by BERLIN
;1020 Shut off line for 60 seconds if really noisy
; UPD ID= 480, SNARK:<5.MONITOR>TTPHDV.MAC.4,  22-Feb-82 09:00:15 by PLATUKIS
;TCO 5.1734 - fix instruction at MCTYIZ+1 to properly use the FLOHLD constant
;in the same way NSPSRV does.
; UPD ID= 418, SNARK:<5.MONITOR>TTPHDV.MAC.3,  19-Jan-82 12:07:41 by MURPHY
;TCO 5.1688 - report TTYSTP only once per line
; UPD ID= 277, SNARK:<5.MONITOR>P3-TTPHDV.MAC.2,  21-Oct-81 11:41:33 by GRANT
;TCO 5.1594 - Move code from MCTYI2 and MCTYI3 into NSPSRV
; UPD ID= 193, SNARK:<5.MONITOR>TTPHDV.MAC.56,  17-Sep-81 13:19:49 by GRANT
;Reinstate the UPD ID=153 edit.  Also, it should say TCO 5.1490 no 5.1409
; UPD ID= 172, SNARK:<5.MONITOR>TTPHDV.MAC.55,  14-Sep-81 13:44:20 by GRANT
;Temporarily undo previous edit
; UPD ID= 153, SNARK:<5.MONITOR>TTPHDV.MAC.54,   8-Sep-81 17:31:11 by GRANT
;Needed for TCO 5.1490 - Remove segment number handling in MCTYI3
; UPD ID= 172, SNARK:<5.MONITOR>TTPHDV.MAC.55,  14-Sep-81 13:44:20 by GRANT
;Temporarily undo previous edit
; UPD ID= 153, SNARK:<5.MONITOR>TTPHDV.MAC.54,   8-Sep-81 17:31:11 by GRANT
;Needed for TCO 5.1409 - Remove segment number handling in MCTYI3
;Minor changes needed for handling LLOMSG queue in MCTYI3 and MCTYI2
; UPD ID= 138, SNARK:<5.MONITOR>TTPHDV.MAC.53,   2-Sep-81 16:38:01 by GRANT
;Eliminate cause of OKSKBG BUGHLT - in TNHCLS, NOSKED before calling TTCOB5
; UPD ID= 2307, SNARK:<5.MONITOR>TTPHDV.MAC.52,   8-Jul-81 11:20:59 by MURPHY
;CALL REQNS INSTEAD OF TNUSND FROM TTCHI
; UPD ID= 2295, SNARK:<5.MONITOR>TTPHDV.MAC.51,   6-Jul-81 13:50:54 by MURPHY
;DEBUG CODE TO RECORD DEAD LINKS
;PROCESS ALL INPUT IN TINET BEFORE QUITTING
; UPD ID= 2269, SNARK:<5.MONITOR>TTPHDV.MAC.50,  29-Jun-81 17:48:31 by MURPHY
;ANTX01
; UPD ID= 2190, SNARK:<5.MONITOR>TTPHDV.MAC.49,  11-Jun-81 15:59:54 by MURPHY
;CHANGE TQNx TO TMNx REFLECTING CHANGE IN MACSYM
;DITTO
; UPD ID= 1867, SNARK:<5.MONITOR>TTPHDV.MAC.45,  21-Apr-81 23:41:55 by MURPHY
;DITTO
; UPD ID= 1865, SNARK:<5.MONITOR>TTPHDV.MAC.44,  21-Apr-81 18:29:43 by MURPHY
;DITTO
; UPD ID= 1830, SNARK:<5.MONITOR>TTPHDV.MAC.43,  17-Apr-81 14:19:33 by MURPHY
;MAKE LINE SHUTOFF FOR 5 SECONDS INSTEAD OF 3
;REVISE SENDALL LOGIC
;REVISE STARTUP LOGIC
; UPD ID= 1752, SNARK:<5.MONITOR>TTPHDV.MAC.42,  20-Mar-81 13:32:21 by MURPHY
;Ditto
; UPD ID= 1745, SNARK:<5.MONITOR>TTPHDV.MAC.41,  19-Mar-81 23:11:04 by MURPHY
;Fix problems with line shut-off and XOFF/XON logic.
; UPD ID= 1663, SNARK:<5.MONITOR>TTPHDV.MAC.40,  11-Mar-81 16:30:30 by MURPHY
;Fix up some failures of DTEQ which were not handled
; UPD ID= 1554, SNARK:<5.MONITOR>TTPHDV.MAC.39,  11-Feb-81 17:33:25 by MURPHY
;MAKE SURE LINE GETS RESTARTED AFTER STOP BECAUSE INBFR OR TTBBUF FULL
; UPD ID= 1550, SNARK:<5.MONITOR>TTPHDV.MAC.38,  10-Feb-81 17:57:41 by MURPHY
;FIX XOFF DURING SYSTEM STARTUP PROBLEM
;CHANGE NAMES TO BLSUB., BLCAL.
;DITTO
; UPD ID= 1477, SNARK:<5.MONITOR>TTPHDV.MAC.35,  22-Jan-81 12:24:13 by MURPHY
;FIX TTQAD PROBLEMS
; UPD ID= 1377, SNARK:<5.MONITOR>TTPHDV.MAC.34,  22-Dec-80 18:25:37 by MURPHY
;<5.MONITOR>TTPHDV.MAC.33, 17-Dec-80 18:10:33, EDIT BY MURPHY
;TNUREC
; UPD ID= 1361, SNARK:<5.MONITOR>TTPHDV.MAC.32,  17-Dec-80 15:46:27 by MURPHY
;CHKLLT
;<5.MONITOR>TTPHDV.MAC.31, 12-Dec-80 11:11:34, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.30, 12-Dec-80 10:34:51, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.29, 12-Dec-80 10:23:26, EDIT BY MURPHY
;FLOW CONTROL
;<5.MONITOR>TTPHDV.MAC.28,  9-Dec-80 15:16:03, EDIT BY MURPHY
;CKMCOU
;<5.MONITOR>TTPHDV.MAC.27,  5-Dec-80 16:49:34, EDIT BY MURPHY
;VARIOUS MCB FIXES AND ENHANCEMENTS
;<5.MONITOR>TTPHDV.MAC.25, 24-Nov-80 16:46:49, EDIT BY MURPHY
;Requeue line if SQILS or SQIACK fails
;<5.MONITOR>TTPHDV.MAC.24, 21-Nov-80 18:29:16, EDIT BY MURPHY
;FLUSH LINK IF INPUT AND NO JOB
; UPD ID= 1301, SNARK:<5.MONITOR>TTPHDV.MAC.23,  19-Nov-80 17:05:35 by MURPHY
;LOCAL XON,XOFF OPTION FOR NVTS
; UPD ID= 1290, SNARK:<5.MONITOR>TTPHDV.MAC.22,  18-Nov-80 16:45:45 by MURPHY
;<5.MONITOR>TTPHDV.MAC.21, 31-Oct-80 17:37:34, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.20, 30-Oct-80 22:59:18, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.19, 21-Oct-80 12:10:07, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.18, 20-Oct-80 17:12:52, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.17, 20-Oct-80 14:40:25, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.16,  7-Oct-80 15:27:36, EDIT BY MURPHY
;<5.MONITOR>TTPHDV.MAC.15,  6-Oct-80 11:32:21, EDIT BY MURPHY
; UPD ID= 1126, SNARK:<5.MONITOR>TTPHDV.MAC.14,   5-Oct-80 15:02:40 by MURPHY
;DITTO
;<5.MONITOR>TTPHDV.MAC.13,  3-Oct-80 14:04:57, EDIT BY MURPHY
; UPD ID= 1120, SNARK:<5.MONITOR>TTPHDV.MAC.12,   3-Oct-80 12:21:22 by MURPHY
;DITTO
; UPD ID= 1113, SNARK:<5.MONITOR>TTPHDV.MAC.11,   3-Oct-80 01:00:51 by MURPHY
;NVT IMPROVEMENTS
; UPD ID= 1077, SNARK:<5.MONITOR>TTPHDV.MAC.10,   1-Oct-80 10:37:44 by MURPHY
;RELEVANT END STATEMENTS FOR STKVAR, ETC.
; UPD ID= 1063, SNARK:<5.MONITOR>TTPHDV.MAC.9,  30-Sep-80 10:16:58 by MURPHY
;DITTO
; UPD ID= 1057, SNARK:<5.MONITOR>TTPHDV.MAC.8,  26-Sep-80 12:13:03 by MURPHY
;MCB FIXES
; UPD ID= 944, SNARK:<5.MONITOR>TTPHDV.MAC.7,  20-Aug-80 20:09:15 by MURPHY
;MCB FIXES
; UPD ID= 925, SNARK:<5.MONITOR>TTPHDV.MAC.6,  20-Aug-80 10:21:12 by MURPHY
;INCLUDE MCB DEVICE
; UPD ID= 699, SNARK:<5.MONITOR>TTPHDV.MAC.5,  25-Jun-80 17:23:34 by MURPHY
;REMOVE TTDBEF REDUNDANT SUBROUTINE
;MERGE TTFEDV AND TTDZDV FILES INTO TTPHDV
;CHANGE DEVICE VECTORING
; UPD ID= 645, SNARK:<5.MONITOR>TTFEDV.MAC.4,  16-Jun-80 12:09:09 by MURPHY
;CLEAN UP VECTOR COMMENTS
; UPD ID= 443, SNARK:<5.MONITOR>TTFEDV.MAC.3,  15-Apr-80 09:41:02 by KONEN
;TCO 4.1.1143 -- Check for XOFF before storing character in big buff.
; UPD ID= 405, SNARK:<5.MONITOR>TTFEDV.MAC.2,   3-Apr-80 16:06:55 by HALL
;CHANGES TO WRITE-PROTECT THE RESIDENT MONITOR:
;	CHANGE ALL REFERENCES TO TT1LIN TO EXPECT A TABLE
;<4.1.MONITOR>TTFEDV.MAC.52, 16-Nov-79 11:29:17, EDIT BY MILLER
;ASGALL NOW SKIPS
;<4.MONITOR>TTFEDV.MAC.51,  1-Nov-79 17:15:09, EDIT BY MILLER
;Previous edit lines deleted
  IFN .MCFLG,<			;INCLUDE ONLY UNDER MASTER FLAG
	SUBTTL DECNET NETWORK TERMINAL DEPENDENT CODE
	SEARCH NSPPAR

;THIS MODULE IS NECESSARY TO SUPPORT THE NETWORK VIRTUAL TERMINALS (NVT)
;OVER DECNET.

;SPECIAL DEFINITIONS

TTMCLN==TTDDLN		;LENGTH FOR MC

DEFSTR TTHLL,TTDEV,35,18	;LOGICAL LINK FOR THIS LINE (HOST SIDE)

   IFN CZQDBG,<			;IF DEBUG CODE
RS CZQPTR,1			;PTR INTO TRACE BUFFER
LCZQBF==40			;LENGTH OF TRACE BUFFER
RS CZQBF,LCZQBF			;TRACE BUFFER
   >
;INITIATE NET ACTIVITY IF POSSIBLE.  CALLED FROM NSPSRV WHEN DATA MESSAGE
;OR ACK RECEIVED.
; T2/ TTY LINE NUMBER

CHKLLT::JE LLTTA,(T1),R		;RETURN IMMED IF NO TTY ON THIS LL
	SAVEAC <T2,T3,T4>
	LOAD T2,LLTTY,(T1)	;SEE IF CONNECTED TO A TTY
	SKIPG T2,TTACTL(T2)	;ACTIVE LINE NOW?
	RET			;NO, SHOULD ALREADY HAVE CLEANUP IN PROGRESS
	LOAD T3,TLTYP,(T2)	;GET TYPE
	CAIE T3,TT.MCB		;AN NVT?
	JRST CHKNV1		;NO
	JE TTOTP,(T2),CHKNV1	;OUTPUT ACTIVE?
	LOAD T3,TINTL,(T2)	;YES, POKE OUTPUT
	IDIVI T3,^D36
	MOVE T4,BITS(T4)
	IORM T4,TTSOQ(T3)
CHKNV1:	LOAD T3,TINTL,(T2)	;POKE
	IDIVI T3,^D36
	MOVE T4,BITS(T4)
	IORM T4,TNETRQ(T3)
	RET

;LOCAL ROUTINE TO REQUEST SUBSEQUENT SERVICE
; T2/ DYNAMIC PTR
; PRESERVED ALL ACS

REQNS:	SAVEAC <T3,T4>
	JRST CHKNV1		;GO SET THE BIT
;CONNECT TTY TO LL - "SET HOST" FUNCTION
; T1/ LL
; T2/ TTY LINE NUMBER
; T3/ FLAGS,,ESCAPE CHARACTER
; RETURN +1: FAILED, INVALID TTY LINE
;	+2: OK

TTSETH::CALL STADYN		;CHECK LINE, GET TDB
	 RET			;FAILED, LINE NG
	SETONE TTPRM,(T2)	;KEEP THIS BLOCK UNTIL LL RELEASED
	STOR T3,TTUEC,(T2)	;SAVE ESCAPE CHAR
	TXNE T3,SH%LPM		;"LOCAL" PAGE MODE?
	 IFNSK. < SETONE TTNPM,(T2) > ;YES, DON'T PASS XON, XOFF
	STOR T1,TTULL,(T2)	;SAVE LL
	SETONE TTNUS,(T2)	;SAY LINE IN NETUSER STATE
	LOAD T3,TINTL,(T2)	;GET LINE NUMBER
	STOR T3,LLTTY,(T1)	;MAKE LL POINT TO TTY TOO
	SETONE LLTTA,(T1)	;NOTE ACTIVE
	CALL REQNS		;REQUEST SERVICE
	RETSKP
;ASSIGN DECNET NVT, CONNECT IT TO LL
; T1/ LL
; RETURN +1: FAILED, NO LINES AVAILABLE
;	+2: SUCCESS

ASMCB::	SAVEQ
	MOVEM T1,Q2		;SAVE LL
	MOVE Q1,TT1LIN+TT.MCB	;GET FIRST MCB LINE
	NOSKED			;FIND LINE RACE FREE
ASMCB1:	LOAD T1,TTSTY,(Q1)	;GET LINE TYPE
	CAIN T1,TT.MCB		;STILL MCB?
	 IFSKP. <
		OKSKED		;NO, NO LINES LEFT
		RETBAD(ANTX01)
	 >
	MOVE T2,Q1
	CALL STADYN		;SEE IF LINE AVAILABLE
	 JUMPE T2,ASMCB2	;YES IF NO DATA BLOCK NOW ASSIGNED
ASMCB3:	AOJA Q1,ASMCB1		;STEP TO NEXT LINE

ASMCB2:	MOVE T2,Q1
	CALL TTYASC		;ASSIGN TDB
	 JRST ASMCB3		;COULDN'T, TRY ANOTHER LINE
	CALL STADYN		;SHOULD WORK NOW
	 JRST ASMCB3		;??
	SETONE TCJOB,(T2)	;INIT LINE
	SETONE TTPRM,(T2)	;KEEP TDB UNTIL LL RELEASED
	MOVE T1,Q2
	STOR T1,TTHLL,(T2)	;SAVE LL
	LOAD T3,TINTL,(T2)	;GET LINE NUMBER
	STOR T3,LLTTY,(T1)	;KEEP IN LL
	SETONE LLTTA,(T1)	;NOTE ACTIVE
	MOVEI T1,.CHCNC
	CALL TTCHID		;SEND CTRL-C TO START JOB
	 NOP
	OKSKED
	MOVE T1,Q1		;RETURN LINE NUMBER
	RETSKP
;CLEAR OUTPUT BUFFER - SEND ROTO-ROOTER DOWN LINE
; T2/ DYNAMIC PTR

MCCOBF:	RET

;SEND XON - SEND ALLOCATION TO ALLOW USER TO SEND MORE INPUT IF NECESSARY
; T2/ STATIC PTR (LINE NUMBER)

MCSXON:	RET

;SKIP IF OUTPUT BUFFER NOT EMPTY - CHECK FOR ALL ACKS, ETC.
; T2/ DYNAMIC PTR

MCSBEF:	RET

;SEE IF SENDALL SHOULD HAPPEN ON SPECIFIED LINE
; T2/ STATIC PTR (LINE NUMBER)
; RETURN +1: SKIP THIS LINE
; RETURN +2: T2/ LINE NUMBER = DO THIS LINE
;	T2/ -1 = SKIP ALL LINES OF THIS TYPE

MCCKSA:	SKIPG TTACTL(T2)	;LINE ACTIVE?
	RET			;NO, SKIP IT
	RETSKP

;HANGUP - BREAK CONNECTION, ETC.
; T2/ STATIC PTR (LINE NUMBER)

MCHNGU:	SAVEAC <T2>
	CALL STADYN
	 RET			;ALREADY GONE
	CALLRET TNHCLS		;FLUSH LL

;CHECK FOR OUTPUT POSSIBLE ON LINE
;OUTPUT NOT POSSIBLE IF LL HAS BEEN CLOSED
; T2/ DYNAMIC PTR
; RETURN +1: OUTPUT NOT POSSIBLE
; 	+2: OUTPUT OK

CKMCOU:	TMNN TTHLL,(T2)		;LL STILL THERE?
	RET			;NO
	RETSKP			;YES
;ENABLE/DISABLE XOFF HANDLING IN USER SIDE
; T2/ DYNAMIC PTR
; TTFLGS(T2)/ TT%PGM BIT - ON IF LINE IN PAGE MODE

MCEXF:	RET

;TURN LINE OFF ON RECEIPT OF XOFF
; T2/ DYNAMIC PTR

MCLNOF:	RET

;TURN LINE ON AGAIN AFTER XOFF

MCLNON:	RET

;CLOSE NET HOST CONNECTION
; T2/ TDB

TNHCLS:	LOAD T1,TTHLL,(T2)
	JUMPE T1,R		;IN CASE ALREADY GONE
	CALL TNTCLS		;PUT LL ON RELEASE QUEUE
	NOSKD1			;NO SCHEDULING
	CHNOFF DLSCHN		;TURN OF CHANNEL
	CALL TTCOB5		;FLUSH OUTPUT (DOES CHNON AND OKSKD1)
	SETZRO TTOTP,(T2)	;CLEAR ACTIVE
	SETZRO TTHLL,(T2)
	RET

;CLOSE NET USER CONNECTION
; T2/ DYNAMIC PTR

TNUCLS:	LOAD T1,TTULL,(T2)	;GET LL
	SETZRO TTULL,(T2)

;CLOSE NVT
; T1/ LL
; T2/ TDB

TNTCLS:
   IFN CZQDBG,<			;IF DEBUG
	MOVEM T2,@CZQPTR	;SAVE TTY BLK
	HRLM T1,@CZQPTR		;SAVE LL
	AOS CZQPTR
	MOVE T3,ULLCZQ
	MOVEM T3,@CZQPTR	;SAVE CURRENT QUEUE HDR
	AOS T3,CZQPTR
	CAIL T3,CZQBF+LCZQBF	;AT END OF BFR?
	MOVEI T3,CZQBF		;YES, WRAP
	HRRM T3,CZQPTR
   >
	SETZRO TTPRM,(T2)
	SETZRO LLTTA,(T1)	;TTY NO LONGER ACTIVE ON THIS LL
	MOVE T3,ULLCZQ		;GET CLOSE QUEUE
	STOR T3,LLTTY,(T1)	;PUT LL ON QUEUE FOR NSPTSK
	MOVEM T1,ULLCZQ
	RET
;SEND BYTES FROM TTY OUT BUFFER TO NET
; T2/ TTY DYNAMIC DATA BLOCK ADDRESS
; RETURN +2 TO PREVENT NORMAL OUTPUT START ACTION

MCSTRO:	ACVAR <LL,MB,TDB,W1,W2>	;LL - LOGICAL LINK BLOCK
				;MB - MESSAGE BUFFER
				;TDB - TERMINAL DATA BLOCK
				;W1, W2 - WORK REGS
	STKVAR <ST3>
	MOVEM T2,TDB		;SAVE TTY BLOCK ADR
	LOAD LL,TTHLL,(TDB)	;GET LGL LINK FOR THIS LINE
	JUMPE LL,RSKP		;PERHAPS GONE
	LOCK LLLLCK,<JRST MCSOZ> ;LOCK OR GIVE UP
	MOVE T1,LL
	CALL BLKLOK		;LOCK LL
	 IFNSK. <
		UNLOCK LLLLCK	;COULDN'T
		JRST MCSOZ
	 >
	UNLOCK LLLLCK
MCSO1:	LOAD T3,LLSTA,(LL)	;CHECK LL STATE
	CAIN T3,LLSRUN		;RUNNING?
	 IFSKP. <
		CALL REQNS	;FORCE INPUT CHECK, WILL DO SHUTDOWN
		JRST MCSOX
	 >
	CALL SNDCHK		;CAN SEND ANOTHER SEG ON THIS LL?
	 JRST MCSOX		;NO, NSP WILL NOTIFY WHEN OK AGAIN
	LOAD W2,LLSWG,(LL)	;GET SEG SIZE
	MOVEI T1,<<MSHDR+DTMLEN>*4+3>(W2) ;GET SIZE OF BLOCK NEEDED
	LSH T1,-2		;IN WORDS
	CALL GETRES		;GET MSG BLOCK
	 JRST MCSOQ		;CAN'T
	MOVEM T1,MB		;SAVE IT
	MOVE T2,TDB
	CALL TTSND		;SEE IF HAVE AT LEAST ONE CHAR TO GO
	 IFNSK.
		MOVE T1,MB	;NOTHING TO GO, RELEASE BLOCK
		CALL RELRES
		JRST MCSOX
	 ENDIF.
	SETONE TTOTP,(T2)	;NOTE OUTPUT ACTIVE
	MOVEM T1,ST3		;YES, SAVE IT
	MOVEI W1,MSHDR(MB)	;POINT TO DATA AREA
	HRLI W1,(POINT 8,0)
	MOVEM W1,LLBPTR(LL)	;SETUP POINTER FOR USE BY SUBROUTINES
	SETZM LLBPCT(LL)
	SETONE LLFEM,(LL)	;NOTE EOM NEEDED
	MOVE T1,LL
	SETZ T2,
	CALL MAKFLG		;SETUP FLAGS
	MOVE T3,MB
	SETZ T4,		;INITIAL COUNT
	CALL MAKMSG		;HEADER ITEMS
	MOVE T2,TDB		;SETUP FOR TTSND
	MOVE T1,ST3		;GET FIRST CHAR TO GO
MCSO2:	IDPB T1,LLBPTR(LL)	;STORE CHAR IN MSG
	AOS LLBPCT(LL)
	SOJLE W2,MCSO3		;COUNT CHARS, JUMP IF DONE
	CALL TTSND		;GET ANOTHER CHAR
	IFSKP.
	  SETONE TTOTP,(T2)
	  JRST MCSO2
	ENDIF.
	SETONE TTOTP,(T2)	;NO MORE OUTPUT, BUT KEEP FLAG SET UNTIL ACK
MCSO3:	MOVEI T3,MSDAT		;SAY THIS IS A DATA MSG
	STOR T3,MSTOM,(MB)
	LOAD T1,LLSWG,(LL)	;MAX SIZE
	SUB T1,W2		;LESS ANY NOT USED
	ADDI T1,2		;PLUS AN ARBITRARY NUMBER...
	STOR T1,MSDTC,(MB)	;SET ACTUAL SIZE
	DMOVE T1,LL		;PASS LL AND MB
	CALL SNDSEG		;SEND IT
	JRST MCSO1		;TRY FOR MORE

;HERE WHEN CAN'T SEND BECAUSE FLOW CONTROL OR NO RES FREE OR LOCK LOCKED

MCSOQ:	MOVE T1,LL
	CALL BLKULK		;UNLOCK LL
MCSOZ:	LOAD T2,TINTL,(TDB)	;GET LINE NUMBER
	IDIVI T2,^D36
	MOVE T3,BITS(T3)
	IORM T3,TTSOQ(T2)	;SET BIT TO CHECK LINE AGAIN
	RETSKP

;HERE WHEN NO MORE TO SEND

MCSOX:	MOVE T1,LL
	CALL BLKULK		;UNLOCK LL
	RETSKP

	ENDSV.			;END STKVAR
	ENDAV.			;END ACVAR
;NET USER - MOVE CHARS FROM TTY IN-BUFFER TO NET
; T2/ DYNAMIC PTR

TNUSND:	ACVAR <LL,MB,TDB,W1,W2>	;LL - LOGICAL LINK BLOCK
				;MB - MESSAGE BUFFER
				;TDB - TERMINAL DATA BLOCK
				;W1, W2 - WORK REGS
	STKVAR <ST3>
	MOVEM T2,TDB		;SAVE TTY BLOCK ADR
	LOAD LL,TTULL,(TDB)	;GET LGL LINK FOR THIS LINE
	LOCK LLLLCK,<JRST TTUSY> ;LOCK OR GIVE UP
	MOVE T1,LL
	CALL BLKLOK		;LOCK LL
	 IFNSK. <
		UNLOCK LLLLCK	;COULDN'T
		CALL REQNS	;TRY AGAIN LATER
		JRST TTUSY
	 >
	UNLOCK LLLLCK
TTUS3:	LOAD T3,LLSTA,(LL)	;CHECK LL STATE
	CAIN T3,LLSRUN		;RUNNING?
	 IFSKP.
		MOVE T1,LL	;NO, BEING CLOSED
		CALL BLKULK	;UNLOCK LL
		LOAD T1,TTUEC,(TDB) ;GET ESC CHAR
		MOVE T2,TDB
		CALL TTCHID	;GIVE IT AS INPUT
		 NOP
		RET		;DONE
	 ENDIF.
	SKIPLE TTICT(TDB)	;ANYTHING IN TTY BFR?
	CALL SNDCHK		;CAN SEND ANOTHER SEG ON THIS LL?
	 JRST TTUSX		;NO, NSP WILL NOTIFY WHEN OK AGAIN
	LOAD W2,LLSWG,(LL)	;GET SEG SIZE
	MOVEI T1,<<MSHDR+DTMLEN>*4+3>(W2) ;GET SIZE OF BLOCK NEEDED
	LSH T1,-2		;IN WORDS
	CALL GETRES		;GET MSG BLOCK
	 IFNSK. <
		MOVE T2,TDB
		CALL REQNS	;CAN'T, REQUEUE TO TRY AGAIN LATER
		JRST TTUSX
	 >
	MOVEM T1,MB		;SAVE IT
	MOVEI W1,MSHDR(MB)	;POINT TO DATA AREA
	HRLI W1,(POINT 8,0)
	MOVEM W1,LLBPTR(LL)	;SETUP POINTER FOR SUBROUTINES
	SETZM LLBPCT(LL)
	SETONE LLFEM,(LL)	;NOTE EOM NEEDED LATER
	MOVE T1,LL
	SETZ T2,
	CALL MAKFLG		;SETUP FLAGS - MAKFLG(T1,T2)
	MOVE T3,MB
	SETZ T4,		;INITIAL COUNT
	CALL MAKMSG		;HEADER ITEMS - MAKMSG(T1,T2,T3,T4)
	MOVE T2,TDB
TTUS1:	CALL GTTCI		;GET IT
	 JRST TTUS2		;NOTHING LEFT
	IDPB T1,LLBPTR(LL)	;PUT IN MSG
	AOS LLBPCT(LL)
	SOJG W2,TTUS1
TTUS2:	MOVEI T3,MSDAT		;SAY THIS IS A DATA MSG
	STOR T3,MSTOM,(MB)
	LOAD T1,LLSWG,(LL)	;MAX SIZE
	SUB T1,W2		;LESS ANY NOT USED
	ADDI T1,2		;PLUS AN ARBITRARY NUMBER...
	STOR T1,MSDTC,(MB)	;SET ACTUAL SIZE
	DMOVE T1,LL		;PASS LL AND MB
	CALL SNDSEG		;SEND IT
	JRST TTUS3		;TRY FOR MORE

TTUSX:	MOVE T1,LL
	CALL BLKULK		;UNLOCK LL
TTUSY:	MOVE T2,TDB		;RESTORE ARG
	RET

	ENDSV.			;END STKVAR
	ENDAV.			;END ACVAR
;PERIODIC ROUTINE TO PROCESS NET USER AND NET HOST LINES
;CALLED FROM END OF TTCH7

MCSRV:	SKIPL LLLLCK		;MASTER LOCK AVAILABLE?
	RET			;NO, TRY AGAIN LATER
	SAVEAC <Q1,Q2>
	MOVSI Q1,-NTSQWD	;SCAN BIT TABLE FOR NET-USER LINES
TNET2:	SKIPE T1,TNETRQ(Q1)
TNET4:	JFFO T1,TNET1		;JUMP IF ACTIVE LINE
	AOBJN Q1,TNET2
	RET

TNET1:	MOVE Q2,BITS(T2)	;SAVE BIT FOUND
	ANDCAM Q2,TNETRQ(Q1)	;CLEAR REQUEST
	HRRZ T3,Q1		;COMPUTE LINE NUMBER
	IMULI T3,^D36
	ADD T2,T3
	CALL STADY		;SEE IF ACTIVE
	 JRST TNET3
	CALL TINET		;SEE IF NVT INPUT
	JE TTNUS,(T2),TNET3	;JUMP IF NO LONGER IN NET USER STATE
	SKIPE TTICT(T2)		;NET USER INPUT?
	CALL TNUSND		;YES, TRY TO SEND IT
	CALL TNUREC		;SEE IF ANY NET USER OUTPUT RECEIVED
TNET3:	MOVN T1,Q2		;LOOK AT REST OF BIT WORD ONLY
	ANDCA T1,TNETRQ(Q1)
	JRST TNET4
;NET USER - RECEIVE OUTPUT FROM NETWORK IF POSSIBLE
; T2/ DYNAMIC PTR

TNUREC:	LOAD T4,TTULL,(T2)	;GET LL
	LOAD T4,LLSWG,(T4)	;GET MAX SIZE OF SEGMENT
	LOAD T3,TOMAX,(T2)	;GET OUTBUF SIZE
	CAIL T4,-2(T3)		;REASONABLE SEG SIZE?
	MOVEI T4,-2(T3)		;NO, ASSUME OUTBUF SIZE -2
	SUB T3,TTOCT(T2)	;COMPUTE REMAINING OUTBUF CAPACITY
	CAIL T3,2(T4)		;ROOM FOR ANOTHER?
	 IFSKP. < CALLRET REQNS > ;NO, REQUEST LATER SERVICE
	MOVEI T1,TCOU1		;ROUTINE TO PUT CHAR IN OUTPUT STREAM
	LOAD T3,TTULL,(T2)	;LOGICAL LINK
	CALL TTYFNT		;MOVE DATA FROM NET
	 IFNSK.
		LOAD T1,TTUEC,(T2) ;LL GONE, SIMULATE ESCAPE CHAR
		CALL TTCHID
		 NOP
		RET
	 ENDIF.
	JUMPN T1,TNUREC		;TRY AGAIN IF WE GOT SOMETHING
	RET
;MOVE DATA FROM NETWORK TO TTY INBFR IF POSSIBLE
; T2/ DYNAMIC PTR

TINET:	SAVEAC <T2,Q1,Q2>
	MOVEM T2,Q2		;SAVE DYNAMIC PTR
	LOAD Q1,TINTL,(T2)	;GET LINE NUMBER
	LOAD T1,TTSTY,(Q1)	;GET TYPE OF THIS LINE
	CAIE T1,TT.MCB		;STILL MCB?
	RET			;NO, DONE
TINET4:	LOAD T3,TTHLL,(T2)	;LOGICAL LINK
	JUMPE T3,TINET2		;IN CASE GONE

   REPEAT 0,<
;THIS CODE WILL PREVENT OVERFLOWING THE INPUT BUFFER.  UNFORTUNATELY,
;IT WILL ALSO PREVENT ^C ETC FROM BEING SEEN.  THEREFORE, IT CAN'T
;BE USED UNTIL WE HAVE AN NVT PROTOCOL THAT USES INTERRUPT MESSAGES
;TO GET AROUND BLOCKED-UP LL'S

	LOAD T4,TIMAX,(T2)	;COMPUTE SPACE IN INBFR
	SUB T4,TTICT(T2)
	LOAD T1,LLSWG,(T3)	;MAX SEGMENT SIZE
	CAMGE T4,T1		;ROOM FOR ANOTHER SEGMENT?
	JRST [	SETONE TTFWK,(T2) ;NO, WAKE UP ANY WAITING FORK
		SAVEAC <FX>
		CALL TTCH10
		 NOP
		CALLRET REQNS]	;RECHECK LINE SOON
   >				;END REPEAT 0
	MOVEI T1,TTCHID		;ROUTINE TO PUT CHARS IN INPUT STREAM
	CALL TTYFNT		;MOVE DATA FROM NET
	 JRST TINET3		;LL DIED
	LOAD T3,TCJOB,(T2)	;SEE IF JOB EXISTS
	CAIE T3,-1
	IFSKP.
	ANDN. T1		;NO, IF WE GOT SOMETHING,
	  JE TTBAC,(T2),TINET3	;CLOSE LINK IF NOT BECOMING ACTIVE
	ENDIF.
	JUMPN T1,TINET4		;YES, LOOP IF GOT ANYTHING THIS TIME
TINET2:	RET

TINET3:	CALL TNHCLS		;CLOSE NVT
	MOVE T2,Q1		;GET LINE NUMBER
	CALL NTYCOF		;DO CARRIER OFF EVENT
	LOAD T3,TCJOB,(Q2) 	;GET CONTROLLING JOB
	CAIE T3,-1		;IS ONE?
	JRST TINET2		;YES, DONE
	CALL TTCBF9		;CLEAR OUTBUF
	CALL TTYDE0		;DEALLOCATE DATA BLOCK
	 NOP
	JRST TINET2
;REMOVE SEGMENTS FROM ORDERED MESSAGE QUEUE AND MOVE DATA TO
;TTY BUFFERS
; T1/ ROUTINE TO DISPOSE OF CHARACTER
; T2/ TTY DYNAMIC BLOCK PTR
; T3/ LOGICAL LINK BLOCK
; RETURN +1: LINK NOT IN RUN STATE
;	+2: OK

TTYFNT::TRVAR <MSGCNT,MSGBYP>	;*USED BY SUBROUTINES HEREIN*
	ACVAR <LL,MB,TDB,W1,COR> ;LL - LOGICAL LINK BLOCK
				;MB - MESSAGE BFR
				;TDB - TERMINAL DATA BLOCK
				;W1 - COUNT OF ALLOCATION RELEASED
				;COR - CHARACTER OUT ROUTINE
	MOVEM T1,COR
	MOVEM T2,TDB		;SAVE TDB
	MOVEM T3,LL
	SETZ W1,		;INIT COUNT OF MESSAGES PROCESSED
	LOCK LLLLCK,<JRST MCTYIY> ;LOCK OR GIVE UP
	MOVE T1,LL
	CALL BLKLOK		;LOCK LL
	 JRST [	UNLOCK LLLLCK	;COULDN'T
		JRST MCTYIY]
	UNLOCK LLLLCK
	LOAD T3,LLSTA,(LL)	;CHECK LL STATE
	CAIN T3,LLSRUN		;RUNNING?
	 IFSKP.
		MOVE T1,LL	;NO
		CALL BLKULK	;UNLOCK LL
		MOVE T2,TDB	;RESTORE AC
		RET		;RETURN FAIL
	 ENDIF.
	SETZRO LLFIM,(LL)
MCTYI3:	MOVE T1,LL		;SET UP FOR CALL
	CALL TTGETS		;GET THE NEXT INCOMING SEGMENT
	 JRST MCTYI5		;NONE THERE
	MOVE MB,T2		;GET THE SEGMENT ADDRESS RETURNED
	LOAD T3,MSDTC,(MB)	;GET BYTE COUNT
	MOVEM T3,MSGCNT
	MOVE T3,MSBPTR(MB)	;AND PTR
	MOVEM T3,MSGBYP
	CALL GETTWO		;GET FLAGS
	 NOP
	TXNE T2,ACKIND		;ACK PIGGYBACKED HERE?
	CALL GETTWO		;YES, SKIP IT
	 NOP
	LOAD T2,MSMFL,(MB)
	TXNE T2,DATEOM		;END OF MSG?
	 IFSKP. < SETONE LLFIM,(LL) > ;YES
	JE LLIMS,(LL),MCTYI4	;JUMP IF NO MSG FLOW CTRL
	TMNE LLFIM,(LL)		;HAVE EOM?
MCTYI4:	AOS W1			;COUNT MESSAGE PROCESSED
MCTYI1:	MOVE T2,TDB		;PASS TDB
	SOSGE MSGCNT		;BYTE LEFT?
	JRST MCTYI2		;NO
	ILDB T1,MSGBYP		;YES, MOVE IT
	CALL 0(COR)		;CALL ROUTINE TO HANDLE CHARACTER
	 NOP			;IN CASE OF SKIP
	JRST MCTYI1

MCTYI2:	MOVE T1,LL		;SET UP
	MOVE T2,MB		; FOR CALL
	CALL TTREMS		;REMOVE SEGMENT FROM INCOMING MESSAGE QUEUE
	MOVE T1,MB		;RETRIEVE SEGMENT ADDRESS
	CALL RELRES		;RELEASE SPACE
	DECR LLDMT,(LL)		;COUNT MESSAGES NOW IN QUEUE
	JUMPE W1,MCTYI3		;TRY AGAIN IF NOT EOM
MCTYI5:	JUMPE W1,MCTYIZ		;DON'T ACK IF NOTHING PROCESSED
	OPSTRM <ADDM W1,>,LLLSC,(LL) ;UPDATE OUTGOING FLOW COUNT
	MOVE T1,LL
	CALL SQIACK		;SEND ACK IF NECESSARY
	 CALL [	MOVE T2,TDB	;IF FAILED, CHECK LINE AGAIN LATER
		CALLRET REQNS]
MCTYIZ:	LOAD T3,LLLSC,(LL)	;SEE IF FLOW COUNT TO BE SENT
	CAIG T3,FLOHLD	;ENOUGH TO BE WORTH SENDING?
	JRST MCTYIX		;NO
	MOVE T1,LL
	CALL SQILS		;SEND IT
	 CALL [	MOVE T2,TDB	;COULDN'T, REQUEUE
		CALLRET REQNS]
MCTYIX:	MOVE T1,LL
	CALL BLKULK		;UNLOCK LL
MCTYIY:	MOVE T1,W1		;RETURN ALLOC COUNT RELEASED
	MOVE T2,TDB		;AND TDB
	RETSKP

;GET TWO BYTE FIELD
;CLOBBERS T3, PRESERVES T4

GETTWO:	GETBYM (MSGCNT,MSGBYP,R)		;GET A BYTE, RETURN IF NONE
	LSHC T2,-10		;SAVE LOW ORDER BYTE
	GETBYM (MSGCNT,MSGBYP,R)		;GET NEXT ONE
	LSHC T2,10		;COMBINE BYTES
	RETSKP			;AND DONE

	ENDAV.			;END ACVAR
	ENDTV.			;END TRVAR
  >				;END IFN .MCFLG WAY BACK

  IFE .MCFLG,<

;ROUTINES THAT SHOULDN'T BE CALLED IF NO MCB CODE

CHKLLT::
TNUCLS:
REQNS:	BUG(NOMCCD)
  >
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

  IFN .FEFLG,<			;BULK OF FE CODE
	SUBTTL FRONT-END DEPENDENT CODE

;FRONT-END DEPENDENT CODE FOR TTYSRV
;THIS MODULE IS NECESSARY TO SUPPORT THE KL10 -DTE20 INTERFACE
;FOR TTYSRV.  IT DOES ALL THE DEVICE SPECIFIC FUNCTIONS AND
;PROCESSES DATA TO AND FROM THE FRONT END.


;DEFINITIONS FOR TTDEV FOR FE TYPE LINES

;DEFINITIONS FOR TT.FE LINE TYPE

DEFSTR TTFCT,TTDEV,27,8		;NUMBER BYTES IN FRONT END
DEFSTR TTFMC,TTDEV,35,8		;MAX BYTES IN FRONT END
SPCLIN==4			;HIGHEST SPECIAL LINE NUMBER

RS TOTFCT,1			;TOTAL BYTES IN FE
RS MAXFCT,1			;TOTAL CAPACITY OF FE
	COMMENT !		;FOR INFO ONLY, ACTUAL DEFS IN PROKL

;THE FRONT END FUNCTION CODES

.DFLCI==1			;LINE COUNT IS
.DFHSD==:3			;HERE IS STRING DATA
.DFHLC==:4			;HERE ARE LINE CHARACTERS
.DFRDS==:5			;REQUEST DEVICE STATUS
.DFSDO==:6			;SPECIAL DEVICE OPERATION
	.DFLPC==1		;LOAD PAGE COUNTER
.DFSTS==:7			;HERE IS DEVICE STATUS
.DFESD==:10			;ERROR ON DEVICE
.DFRTD==:11			;REQUEST TIME OF DAY
.DFHTD==:12			;HERE IS TIME OF DAY
.DFFDO==:13			;FLUSH OUTPUT (SENT TO 11 ONLY)
.DFSTA==:14			;SEND TO ALL (SENT TO 11 ONLY)
.DFLDU==:15			;A LINE DIALED UP (FROM 11 ONLY)
.DFLHU==:16			;A LINE HUNG UP OR LOGGED OUT
.DFLBE==:17			;LINE BUFFER BECAME EMPTY
.DFXOF==:20			;XOF COMMAND TO THE FE
.DFXON==:21			;XON COMMAND TO THE FE
.DFSPD==:22			;SET TTY LINE SPEED
.DFHLA==:23			;HERE IS LINE ALLOCATION
.DFHRW==:24			;HERE IS -11 RELOAD WORD
.DFACK==:25			;GO ACK ALL DEVICES AND UNITS
.DFTOL==:26			;TURN OFF/ON LINE
	.DFTLO==:0		;TURN IT OFF
	.DFTOO==:1		;TURN IT ON
.DFEDR==:27			;ENABLE/DISABLE DATASETS
.DFLTR==:30			;LOAD TRANSLATION RAM
.DFLVF==:31			;LOAD VFU
.DFMSG==:32			;SUPPRESS SYSTEM MESSAGES TO TTY
.DFKLS==:33			;SEND KLINIK DATA TO THE -11
.DFXEN==:34			;ENABLE XON (SENT TO 11 ONLY)
.DFBKW==:35			;BREAK-THROUGH WRITE
.DFDBN==:36			;DEBUG MODE ON
.DFDBF==:37			;DEBUG MODE OFF
	!

	RESCD
; CLEAR OUTPUT BUFFER ROUTINE

TTCOB4:	STKVAR <TTCBSV>
	MOVEM B,TTCBSV		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	MOVE D,B		;GET COPY OF LINE NUMBER
	MOVS C,B		;LINE NUMBER
	MOVEI B,.FEDLS		;GET DEVICE CODE
	MOVE A,MSTRDT		;MASTER DTE, NO POST
	CALL FIXARG		;GET PROPER ARGS
	EXCH D,TTCBSV		;GET BACK DYNAMIC DATA
	TMNN TTOTP,(D)	;OUTPUT IN PROGRESS?
	 IFSKP.
		EXCH D,TTCBSV	;YES. GET BACK ORIGINAL ARGUMENT
		CALL DTEFLO	;YES, FLUSH DTE REQUESTS
		JRST TTCBF5
	 ENDIF.
	EXCH D,TTCBSV		;GET BACK ORIGINAL ARGUMENT
TTCBF5:	MOVS D,C		;LINE NUMBER AS ARG
	SETZ C,
	HRLI B,.DFFDO		;FLUSH FUNCTION
	CALL DTEQI		;QUEUE IT UP
	MOVE B,TTCBSV		;GET BACK DYNAMIC DATA
	RET

	ENDSV.			;END STKVAR
	SWAPCD

; SET TERMINAL SPEED

TTSSP2:	SKIPN FEFLG		;IN PRIMARY PROTOCOL?
	RET			;NO. IGNORE IT THEN
	ACVAR <W1,SSBFR>
	UMOVE W1,2		;GET FLAGS
	TXNE W1,MO%AUT		;DECLARING AUTO SPEED?
	JRST [	TXNE W1,MO%RMT	;YES. ALSO WANT REMOTE?
		JRST .+1	;YES. PROCEED THEN
		RET]		;NO. ILLEGAL REQUEST
	NOINT			;PREVENT INTS
	BLCAL. ASGRSB,<[4],[.RESP3],[.RESTP]> ;GET A 4-WORD BLOCK
	 ITERR ()		;SHOULDN'T HAPPEN
	MOVEM A,SSBFR		;SAVE ADR OF BLOCK
	MOVE C,A
	HRLI C,(POINT 16,0)	;MAKE BYTE PTR
	UMOVE D,C		;GET USER'S ARGS
	HLRZ A,D		;GET INPUT SPEED
	TMNE TTAUT,(B)		;NOW AUTO?
	IFSKP. <
	  TMNN TTFEM,(B)>	;NO, ALREADY REMOTE?
	TXNE W1,MO%AUT		;NO. DECLARING AUTO?
	IFSKP. <
	  MOVEM D,TTSPWD(B)>	;SET THE NEW SPEED
	CALL TTEXFA		;SET XON/XOFF STATE
	IDPB A,C		;STORE INPUT
	IDPB D,C		;STORE OUTPUT SPEED
	MOVEI D,0(D)
	MOVEI A,1		;ASSUME ONE STOP BIT
	CAIG D,^D110		;LESS THAN OR EQUAL TO 110 BAUD?
	MOVEI A,2		;YES. USE 2 STOP BITS THEN
	TXNE W1,MO%RMT		;WANT REMOTE?
	 IFNSK.
		MOVX D,SC%OPR!SC%WHL ;YES. SEE IF PRIVILEGED
		TDNN D,CAPENB	;IS IT?
		JRST TTSSP3	;NO. ERROR
		TRO A,(1B2)	;SET HIGH ORDER BIT
		LOAD D,TTFEM,(B)
		SETONE TTFEM,(B) ;SAY IS REMOTE
		TXNE W1,MO%AUT	;WANT "AUTO" SPEED?
		JRST [	SETONE TTAUT,(B) ;SET INDICATOR
			TRO A,(1B3) ;SET BIT IN MESSAGE TO FE
			JRST TTSSP5] ;AND PROCEED
		JUMPE D,TTSSP5	;IF NOT NOW REMOTE, DECLARE SPEED
		UMOVE D,C	;YES. GET DEFAULT DECLARATION
		MOVEM D,TTSPWD(B) ;TO THE TABLE
	ENDIF.			;GO SET SPEED ANYWAY
TTSSP5:	IDPB A,C		;STORE THIS
	MOVE C,SSBFR		;REFRESH PTR
	HRLI C,(POINT 8,0)
	MOVE F,SSBFR		;PASS BUFFER ADDRESS FOR INTERRUPT
	BLCAL. TTDTEQ,<[SSPINT],[.DFSPD],[6],C>
TTSSP3:	OKINT			;ALLOW INTS AGAIN
	RET			;AND DONE

	ENDAV.			;END ACVAR

;HERE AT INTERRUPT LEVEL AFTER MSG SENT TO FE
; A/ UNIQUE CODE - ADR OF RESIDENT BFR

	RESCD

SSPINT:	CALL RELRES
	RET

	SWAPCD
; SET/RETURN DEVICE NON-TERMINAL STATUS

TTSNT1:	SKIPN FEFLG		;IN PRIMARY PROTOCOL?
	RET			;NO. IGNORE IT THEN
	STOR C,TTNTS,(B)	;SAVE NEW VALUE
	BLCAL. TTDTEQ,<[0],[.DFMSG],[0],C>
	RET			;AND DONE


;ENABLE/DISABLE XOFF RECOGNITION IN THE FRONT-END

	RESCD


TTEXFA:	SAVET			;SAVE REGISTERS
	CALL STADYN
	 RET			;NOT IMPORTANT
	JRST TTEXZ
	
TTEXF:	SKIPN FEFLG		;CHECK FOR PRIMARY PROTOCOL 
	RET			;NO. IGNORE IT THEN
	SAVET			;SAVE TEMPS
TTEXZ:	SETZ T4,0		;ASSUME CLEAR
	TMNE TT%PGM,TTFLGS(T2)
	SETO T4,0		;SET
	DYNST			;GET STATIC TTY NUMBER
	SKIPG TTACTL(T2)	;NORMALLY ACTIVE LINE?
	SETZ T4,		;NO, DISABLE FE XOFF
	BLCAL. TTDTEQ,<[0],[.DFXEN],[0],T4>
	RET

	SWAPCD
;TTMSG...

;CODE TO DO A SEND ALL FOR KL DTE20 CONFIGURATIONS

;TTMSSN FOR SINGLE LINE, TTMSAL FOR ALL LINES
; A/ BYTE PTR TO STRING
; B/ LINE NUMBER
; C/ COUNT OF BYTES IN STRING

TTMSAL:	SASUBR <MSBP,MSLN,MSCT>
	SKIPN FEFLG		;USING PRIMARY PROTOCOL?
	JRST [	CAME B,CTYLNO	;CTY?
		RET		;NO, FORGET IT
		RETSKP]		;DO IT
	SETOB B,MSLN		;NOTE ALL LINES
	HRLI B,.DFSTA		;ASSUME SEND ALL
	MOVSI A,DECSAL		;INTERRUPT LOCATION
	HRR A,MSTRDT
	HRRI B,.FEDLS		;THE LINE SCANNER
	CALL FIXARG		;GO CHECK FOR CTY,ETC.
	HRR C,MSCT		;THE COUNT
	MOVE D,MSBP		;THE POINTER
	TXO C,DTBYTM		;FORCE BYTE MODE SEND
	AOS SALCNT		;INCREMENT SENDALL COUNT
	CALL DTEQI		;GO SCHEDULE THE REQUEST
	RETSKP

	ENDSA.

;ROUTINE TO DO SENDALL FOR SINGLE LINE
; T2/ LINE NUMBER
; RETURN +1: DON'T DO THE LINE
; 	+2: OK TO DO, T2/ LINE NUMBER

TTMSSN:	SKIPN FEFLG		;PRIMARY PROTOCOL?
	CAMN T2,CTYLNO		;OR CTY?
	RETSKP			;YES, OK TO DO
	RET			;SKIP IT
	RESCD

;TELL FE TO RESUME SENDING TO TERMINAL

TTXON1:	SKIPN FEFLG		;IN PRIMARY PROTOCOL?
	RET			;NO .SKIP THE MESSAGE THEN
	MOVEI A,.DFXON		;FE XON FUNCTION
	SAVEAC <B>
	DYNST			;GET LINE NUMBER
	CALLRET SNDFNC		;TELL FE TO RESTART

;FRONT END LINE. TELL FRONT END TO STOP SENDING TO TERMINAL

TTCHI3:	SAVET			;SAVE TEMPS
	DYNST			;GET STAT ADDRESS
	MOVEI A,.DFXOF		;TELL FE TO STOP
	CALLRET SNDFNC		;DO IT

;ROUTINE TO SEND XOFF OR XON TO THE FRONT END
;ACCEPTS: A/ FUNCTION TO SEND
;	  B/ LINE NUMBER
;RETURNS:	+1 /COULD NOT SEND REQUEST
;		+2/ REQUEST SENT

SNDFNC:	SAVEAC <B>
	MOVSI C,0(B)		;PUT LINE NUMBER IN CORRECT PLACE
	MOVSI B,0(A)		;FUNCTION CODE
	HRRI B,.FEDLS		;ASSUME DLS
	CALL FIXARG		;GO FIX UP THE ARGS
	HLRZ D,C		;LINE NUMBER AS DATUM
	SETZM C			;DIRECT
	MOVE A,MSTRDT		;TO THE MASTER -11
	CALLRET DTEQI		;QUEUE TO DTE
;SEND XOFF TO DISCOURAGE FURTHER INPUT FROM TERMINAL

SNDXO2:	CONSZ PI,1B<^D20+DLSCHN> ;AT DTE PI LEVEL?
	JRST SNDXO1		;YES. GO TO IT
	NOSKD1			;PREVENT SCHEDULER INTERRUPTS
	CHNOFF DLSCHN		;AND DTE INTERRUPTS
SNDXO1:	SAVET
	JN TTFXO,(B),SNDXO3	;DO NOTHING IF PREVIOUS XOFF SENT
	SETONE TTFXO,(B)	;SAY X-ON  NEEDED
	MOVEI D,XOFFC		;THE CHARACTER
	SKIPGE CHITAB(D)	;PARITY NEEDED?
	TXO D,200		;YES. APPLY IT
	MOVE A,MSTRDT		;SEND TO THE MASTER
	MOVSI C,0(B)		;LINE NUMBER
	MOVE B,[.DFHLC,,.FEDLS]
	CALL FIXARG		;FIX UP THE ARGS
	CALL DTEQI		;GO SEND IT
SNDXO3:	CONSZ PI,1B<^D20+DLSCHN> ;AT DTE PI LEVEL?
	RET			;YES. ALL DONE THEN
	CHNON DLSCHN		;RESTORE THE CHANNEL
	OKSKD1			;AND THE SCHEDULER
	RET			;AND DONE
;SEND XON ONLY IF LINE IS MARKED AS NEEDING
;ONE, AND IT HAS NOT STORED TOO MANY CHARACTERS IN EITHER ITS
;INPUT BUFFER OR TTBBUF

SNDXN2:	JE TTFXO,(B),R		;IF NOT WAITING, RETURN
	JN TTSHU,(B),R		;DO NOTHING IF LINE TURNED OFF
	SAVET			;BE TRANSPARENT
	STKVAR <SNDXSV>
	MOVEM B,SNDXSV		;SAVE THE LINE NUMBER
	NOSKD1			;PREVENT SCHEDULER INTERRUPTION
	CHNOFF DLSCHN		;AND DTE INTERRUPTS
	LOAD A,TTFBB,(B)	;GET NUMBER CHARS IN TTBBUF
	SKIPG TTACTL		;ACTIVE LINE?
	JUMPG A,SNDXN1		;NO, COUNT MUST BE 0 FOR XON
	CAIL A,MXBBC1		;STILL TO MUCH IN BBUF?
	JRST SNDXN1		;YES, NO XON YET
	CALL STADY		;GET ADDRESS OF DYNAMIC DATA
	 JRST SNDXN3		;NOT ACTIVE. INPUT BUFFER CAN'T OVERFLOW
	MOVEI A,MINXON		;LEVEL AT WHICH TO START AGAIN
	CAMGE A,TTICT(B)	;IS INPUT BUFFER THIS FULL?
	JRST SNDXN1		;YES. DON'T SEND XON

;XON IS TO BE SENT. TELL DTE SERVICE

SNDXN3:	MOVE B,SNDXSV		;TURN IT ON IF NOT ACTIVE.
	MOVE A,MSTRDT		;TO THE MASTER
	MOVEI D,XONC		;THE CHARACTER
	SKIPGE CHITAB(D)	;PARITY NEEDED?
	TXO D,200		;YES. APPLY IT
	MOVSI C,0(B)
	MOVE B,[.DFHLC,,.FEDLS]
	CALL FIXARG
	CALL DTEQI		;GO SEND THE BYTE
	MOVE B,SNDXSV		;GET LINE NUMBER
	SETZRO TTFXO,(B)	;NO X-ON NEEDED NOW
SNDXN1:	MOVE B,SNDXSV		;RESTORE LINE NUMBER
	CHNON DLSCHN		;RESTORE DTE
	OKSKD1			;AND THE SHCEDULER
	RET			;AND DONE

	ENDSV.			;END STKVAR
;THIS IS A FRONT END LINE

TTHU2:	SAVET			;SAVE TEMPS
	MOVE A,MSTRDT		;MASTER -11, NO INT
	MOVS C,B
	MOVE B,[.DFLHU,,.FEDLS]	;HANG UP THIS LINE
	CALL FIXARG
	HLRZ D,C
	SETZ C,
	CALL DTEQI		;REQUEST THE HANGUP
	RET			;AND DONE
;CHECK INPUT RATE OF LINE
;LIMIT ITS STORAGE IN TTBBUF

BIGST2:	LOAD C,TTFBB,(B)	;GET COUNT OF CHARACTERS IN TTBBUF
	AOS C			;INCREASE IT
	CAIL C,MAXABC		;BEYOND BAD GUY CUTOFF?
	JRST STPLNF		;STOP LINE
	CAIG C,2		;CHECK FOR 2 IN BUFFER
	JRST BIGST4		;NO NOT THIS TIME
	SKIPG TTACTL(T2)	;YES CHECK TO SEE IF ACTIVE
	JRST STPLNF		;NO SHUT LINE DOWN IT IS ANOYING ME
BIGST4:	STOR C,TTFBB,(B)	;UPDATE COUNT OF CHARACTERS IN TTBBUF
	CAIGE C,MAXBBC		;MANY CHARS FOR THIS LINE?
	RETSKP			;NO, CONTINUE
	MOVE C,TTBIGC		;YES, BIGBUF GETTING FULL TOO?
	CAIL C,MAXABC-^D20
	CALL SNDXO2		;YES, SEND XOF
	RETSKP

;TELL FE TO STOP ACCEPTING INPUT ON LINE, I.E. BY SETTING INPUT
;SPEED TO 0.

STPLNF:	JN TTSHU,(B),R		;DO NOTHING IF LINE ALREADY OFF
	SAVEAC <T2>
	IFQE. TTWSO,(B)		;LINE HAS BEEN SHUT OFF BEFORE?
	  SETONE TTWSO,(B)	;NO, REPORT IT VIA BUGINF
	  BUG(TTYSTP,<<T2,LINE>>)
	ENDIF.
	SETONE TTSHU,(B)	;NOTE LINE SHUT OFF
	MOVEI C,TTTOBL		;C/THE ROUTINE TO CALL
;1020	MOVEI A,^D5000		;5 SECONDS
	MOVX A,^D1000*60	;1020 60 Seconds
	CALL TTQAD		;GO Q IT UP AND LOSE DATUM
	MOVSI C,0(B)		;THE LINE
	MOVE B,[.DFTOL,,.FEDLS]
	MOVE A,MSTRDT		;TO THE MASTER
	MOVEI D,.DFTLO		;TURN IT OFF
	CALL FIXARG
	CALL DTEQI		;OUTPUT IT
	RET
;THIS CODE IS USED TO START UP A LINE TRANSFER VIA THE DTE20.

TTFES1:	CALL TTSND		;GET ONE OUTPUT CHAR
	 RET			;BUFFER EMPTY
	SKIPE FEFLG		;USING PRIMARY PROTOCOL?
	IFSKP.
	  CALL [SAVEAC <B>	;NO
		DYNST		;GET LINE NUMBER
		CALLRET DTECHO]	;OUTPUT VIA SECONDARY
	   RET
	  SETONE TTOTP,(B)	;INDICATE LINE IS ACTIVE
	  RET			;AND DONE
	ENDIF.
	MOVE D,A		;THE CHARACTER
	SETONE TTOTP,(B)	;SAY LINE IS ACTIVE
	INCR TTFCT,(B)		;INCREASE COUNT OF BYTES IN -11
	AOS TOTFCT		;MAINTAIN TOTAL OF ALL LINES
	PUSH P,B		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	SETONE TTFPK,(B)	;SAY WAITING FOR TO -11 DONE
	MOVSI C,0(B)		;LINE NUMBER
	MOVE B,[.DFHLC,,.FEDLS]	;ARGS
	CALL FIXARG		;GET PROPER ARGS
	PUSH P,F
	SETZ F,			;JUST IN CASE
	CALL DTSNGL		;GO DO A SINGLE REQUEST
	 IFNSK.
		POP P,F		;FAILED. RESTORE FLAGS
		POP P,B		;RESTORE ADDRESS OF DYNAMIC DATA
		DECR TTFCT,(B)	;DECREMENT BYTES IN -11
		SOS TOTFCT
		CALL BAKTTO	;BACKUP TTY OUTPUT
		JRST INTRST	;GO SCHEDULE RETRY
	 ENDIF.
	POP P,F			;RESTORE FLAGS
	POP P,B			;ADDRESS OF DYNAMIC BLOCK
	RET			;AND DONE
;TTTOBL - ROUTINE CALLED FROM SCHEDULER TO TURN ON LINE AGAIN

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

TTTOBL:	JE TTSHU,(B),R		;IF ALREADY RESTARTED, DO NOTHING
	SETZRO TTSHU,(B)
	BLCAL. TTDTEQ,<[0],[.DFTOL],[0],[.DFTOO]>
				;TURN ON LINE
	CALLRET SNDXN2		;ASSUME AN X-ON IS NEEDED

; ENABLE/DISABLE TTY'S

FEDABL:	SETZ C,0		;SET LINE # (ALL)
	MOVE A,MSTRDT		;GET ID OF MASTER
	MOVE B,[.DFEDR,,.FEDH1]	;ENABLE/DISABLE DATASETS
	CALL DTEQI
	RET
	SUBTTL FRONT-END TERMINAL HANDLING
	RESCD			;MUST BE RESIDENT

;THIS ROUTINE IS CALLED FROM THE DTE20 INTERRUPT ROUITNE TO COMPLETE
;A TTY OUTPUT REQUEST. INPUT IS:
;	A/ UNIQUE CODE (SEE BELOW)
;	B/UNIT NUMBER
;	C/DEVICE CODE

;UNIQUE CODE IS 
;	(0,,COUNT)
;WHERE	COUNT IS THE NUMBER OF CHARACTERS SENT TO THE 11 IN SOME CALL TO
;		DTEQ THAT SPECIFIED TTYINT AS ITS RETURN ADDRESS
;	IF COUNT IS 0, THIS WAS A SINGLE CHARACTER (DTSNGL WAS CALLED)
;		AND BUFFER COUNTS HAVE ALREADY BEEN UPDATED
;	IF COUNT IS NON-ZERO, THIS WAS MULTIPLE CHARACTERS, AND THE BUFFER
;		COUNT MUST BE UPDATED

;AT THIS POINT, THE CHARACTERS HAVE BEEN SENT TO THE 11 BUT NOT ACKNOWLEDGED

TTYINT::PUSH P,A		;SAVE UNIQUE CODE
	MOVE A,C		;MOVE DEVICE TO A
	CALL GETLIN		;GET PROPER CODE
	 JRST [	POP P,A		;RESTORE CODE
		RET]		;AND GIVE UP
	SETZRO TTFPK,(B)	;CLEAR WAITING FOR -11
	POP P,A			;GET BACK UNIQUE CODE
	CALL STADY		;GET ADDRESS OF DYNAMIC DATA
	 RET			;RETURN IF BECOMING ACTIVE OR INACTIVE
	JUMPE A,TTYIN3		;HAVE A COUNT?

;MULTIPLE CHARACTERS WERE SENT. UPDATE COUNT OF CHARACTERS IN OUTPUT 
;BUFFER

	MOVEI C,0(A)		;NUMBER OF CHARACTERS SENT
	SUB C,TTOCT(B)		;COMPUTE NEW COUNT OF CHARACTERS IN BUFFER
	SKIPG C			;IF COUNT WENT NEGATIVE, DON'T STORE IT
	MOVNM C,TTOCT(B)	;STORE NEW COUNT
	OPSTRM <ADDM A,>,TTFCT,(B) ;UPDATE FE CHAR COUNT
	ADDM A,TOTFCT		;UPDATE TOTAL
	CALL CHKWRN		;SEE IF FORK WAKEUP NEEDED
	JRST TTYIN3		;SEE IF MORE OUTPUT
;TTYINT..
;CALLED FROM SCHEDULER PERIODIC TASK PROCESSOR TO START OUTPUT FOR A LINE
; T2/ DYNAMIC PTR
; RETURN +1 ALWAYS

FESTRO:	CHNOFF DLSCHN		;AVOID INTERRUPTS
	SKIPE FEFLG		;PRIMARY PROTOCOL RUNNING?
	IFSKP.
	 CALL TTFES1		;NO, HANDLED BY 1-CHAR CASE
	ELSE.
	 CALL TTYIN3		;DO THE WORK
	ENDIF.
	CHNON DLSCHN
	RETSKP			;NOTE NOTHING ELSE TO BE DONE

;CHARACTERS ARE IN OUTPUT BUFFER. CALL TTSND IF THERE IS ONLY ONE.
;OTHERWISE CALL DTEQ TO SEND THEM ALL

TTYIN3:	STKVAR <TTYVR1,TTYVR2>	;GET SOME SAVE CELLS
	CALL GETFMC		;GET LINE MAX ALLOCATION
	LOAD D,TTFCT,(B)	;GET COUNT OF CHARS IN FE
	CAML D,A		;ROOM FOR MORE?
	JRST [	SETONE TTOTP,(B) ;SAY LINE IS WAITING FOR UNBLOCK
		RET]		;AND GO DISMISS THIS INTERRUPT
	JN <TTFLO,TTSAL,TTHPO,TTSFG,TTRXF>,(T2),[ ;ANY SPECIAL FLAGS?
		CALLRET TTFES1]	;YES, HANDLED BY THE 1-CHAR CASE
	SKIPN C,TTOCT(B)	;ANY OUTPUT CHARACTERS?
	CALLRET TTFES1		;NO
	MOVE C,TTOOUT(B)	;GET POINTER
	HRRZ A,C
	TDNN C,WRPMSK		;NEED TO ADVANCE?
	HRR C,1-TTSIZ(A)	;YES. DO IT
	MOVE A,TTOCT(B)		;GET OUTPUT COUNT
	CALL CNTSET		;GO ADJUST COUNT
	MOVEM C,TTYVR1		;SAVE STARTING BYTE POINTER
	CALL FNDEND		;GO GET CHARACTERS
	MOVE D,TTYVR1		;GET BACK ORIGINAL BYTE POINTER
	TRNN A,777776		;AT LEAST TWO?
	CALLRET TTFES1		;NO. GO DO SINGLE CHARACTER
	SETONE TTOTP,(B)	;MAKE SURE THIS IS ON
	MOVEM C,TTOOUT(B)	;NEW OUTPUT POINTER
	SETZ F,			;OUTPUT BUFFER
	HRR F,A			;GET COUNT OF BYTES FOUND
	MOVSI A,TTYINT		;IT'S TTY
	HRR A,MSTRDT		;TO THE MASTER
	MOVEM B,TTYVR2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	SETONE TTFPK,(B)	;WAITING FRO TO -11 DONE
	MOVS C,B		;LINE NUMBER
	HRR C,F			;COUNT
	MOVE B,[.DFHSD,,.FEDLS]	;STRING DATA
	CALL FIXARG		;FIX UP THE ARGS
	CALL DTEQ		;QUEUE THE REQUEST
	 JRST RSCHED		;GO DO RESCHEDULE
	RET			;GO DISMISS THE INTERRUPT

;DTEQ FAILED. RESTORE COUNTS AND ARRANGE FOR SCHEDULER TO RESTART OUTPUT

RSCHED:	MOVE B,TTYVR2		;ADDRSS OF DYNAMIC DATA
	MOVE D,TTYVR1		;GET ORIGINAL BYTE POINTER
	MOVEM D,TTOOUT(B)	;RESTORE OUTPUT BYTE POINTER
INTRST:	DYNST			;B/ LINE NUMBER
	SETZRO <TTOTP,TTFPK>,(B) ;NOT WAITING FOR PACKET
	MOVEI A,^D100		;TRY AGAIN IN 100 MS.
	MOVEI C,TTSN10		;START UP AS SINGLE CHARACTER
	CALLRET TTQAD		;GO DO IT

	ENDSV.			;END STKVAR
;CNTSET - ROUTINE TO FIGURE OUT MAX COUNT ALLOWED IN STRING DATA FUNCTION
;INPUT:	A/ TTY BUFFER COUNT
;	B/ ADDRESS OF DYNAMIC DATA
;RETURNS +1 ALWAYS WITH: A/-MAX COUNT,,0

CNTSET:	SASUBR <CA,CB>
	CALL GETFMC		;GET MAX ALLOC FOR THIS LINE
	LOAD D,TTFCT,(B)	;CURRENT FRONT END COUNT
	SUB A,D			;COUNT ALLOWED TO SEND
	CAMLE A,CA		;CAN DO ALL?
	MOVE A,CA		;YES
	MOVN A,A		;FOR AOBJN
	HRLZM A,CA		;TO LH AND RETURN IT
	RET			;AND DONE

;GET MAX FE ALLOC FOR LINE.  DEPENDS ON SPEED OF LINE
; B/ DYN PTR
; RETURNS +1 ALWAYS,
;	A/ MAX BYTE COUNT

GETFMC:	SAVEAC <C>
	LOAD A,TTFMC,(B)	;GET NOMINAL MAX
	STALOD C,TTOSP,(B)	;GET LINE SPEED
	CAIE C,-1		;UNKNOWN?
	CAIGE C,^D1200		;OR LESS THAN 1200?
	JRST [	ASH A,-2	;YES, 1/4 ALLOC
		RET]
	CAIL C,^D9600		;FAST?
	IMULI A,2		;YES, DOUBLE ALLOC
	RET			;OTHERWISE, NORMAL ALLOC
;FNDEND - FIND END OF MESSAGE TO SEND TO TERMINAL

;ACCEPTS:
;	T1/ AOBJN POINTER TO STEP THROUGH OUTPUT BUFFER
;	T3/ POINTER FOR REMOVING CHARACTERS FROM OUTPUT BUFFER

;	CALL FNDEND

;RETURNS +1: ALWAYS,
;	T1/ UPDATED AOBJN PTR, RH CONTAINS NUMBER CHARS TO DO
;	T3/ UPDATED POINTER TO OUTPUT BUFFER

FNDEND:	TDNN C,WRPMSK		;TO THE NEXT?
	RET			;YES. DONE FOR NOW
	ILDB D,C		;GET NEXT BYTE
	TRNE D,TTOESC		;ESCAPE CHARACTER?
	 IFNSK.
		ADD C,[^D9B5]	;DECREMENT BYTE POINTER
		TLNE C,(40B5)	;WENT INTO PREVIOUS WORD?
		SUB C,[44B5+1]	;YES. CORRECT IT
		RET		;AND RETURN
	 ENDIF.
	AOBJN A,FNDEND		;NO. GET MORE
	RET			;ALL EXHAUSTED

;ROUTINE TO SET SPEED OF LINE FROM VALUES SENT BY -11
;ACCEPTS:
;	A/ DEVICE CODE
;	B/ UNIT NUMBER
;	C/ REMOTE INDICATOR
;	D/ INPUT,,OUTPUT

TTSPST::CALL GETLIN		;GET INTERNAL LINE NUMBER
	 RET			;INVALID
	JUMPE C,TTSPS1		;IF NOT REMOTE, JUMP OFF
	SETONE TTFEM,(B)	;IS REMOTE
	TRNN C,(1B3)		;IS IT AUTO ALSO?
	JRST TTSPS1		;NO.
	SETONE TTAUT,(B)	;YES. SET INDICATOR
TTSPS1:	MOVEM D,TTSPWD(B)	;STORE IT
	RET			;AND DONE
;ROUTINE TO HANDLE SIGNAL FROM A FE THAT ITS LINE BUFFER FOR
;A GIVEN LINE IS EMPTY. ACCEPTS:
;	A/ DEVICE CODE
;	B/LINE NUMBER

TTYDON::JUMPL B,DONALL		;IF NEG HE WANTS TO ACK THEM ALL
	CALL GETLIN
	 RET			;ILLEGAL LINE
	JN TTFPK,(B),R		;IF TO -11 DONE PENDING, GO AWAY
	CALL STADY		;GET ADDRESS OF DYNAMIC DATA
	 RET			;GONE
	LOAD C,TTFCT,(B)	;GET COUNT OUTSTANDING
	MOVN C,C
	ADDM C,TOTFCT		;REDUCE FE TOTAL
	SETZRO TTFCT,(B)	;CLEAR COUNT OF BYTES IN -11
	JE TTOTP,(B),R		;IS THIS LINE WAITING FOR THIS INT?
	CALLRET TTYIN3		;YES, CONTINUE OUTPUT TO THE LINE

;HERE WHEN FRONT END IS ACKING ALL UNITS

DONALL:	STKVAR <SAVEE>
	MOVSI C,NTTFE		;NUMBER OF FRONT END LINES
	MOVNS C			;MAKE AOBJN POINTER
DONAL1:	MOVEM C,SAVEE		;SAVE AOBJN POINTER
	MOVEI B,0(C)		;B/LINE NUMBER
	MOVEI A,.FEDLS		;ALL LINES ARE DLS
	CALL TTYDON		;GO ACK THIS GUY
	MOVE C,SAVEE
	AOBJN C,DONAL1		;DO ALL LINES
	MOVE B,CTYLNO		;GET CTY LINE NUMBER
	LOAD C,TTSTY,(B)	;GET LINE TYPE
	CAIE C,TT.FE		;FRONT END LINE?
	RET			;NO. DON'T ACK IT
	SKIPGE B,CTYUNT		;B/UNIT NUMBER FOR CTY
	RET			;NOT SET UP YET
	MOVEI A,.FEDLS		;A/ DEVICE .FEDLS
	CALLRET TTYDON		;GO ACK THE LINE

	ENDSV.			;END STKVAR
;ROUTINE TO HANDLE A DIAL UP SIGNAL FROM THE FE
;	A/DEVICE CODE
;	B/LINE NUMBER

TTYDLU::CALL GETLIN		;GET PROPER LINE NUMBER
	 RET			;ILLEGAL LINE
	MOVSI A,0(B)		;LINE NUMBER TO LH
	HRRI A,DLSCXF+CARONB	;INDICATE CARRIER ON
	CALLRET BIGSTO		;PUT IT IN BUFFER

;ROUTINE TO HANDLE HANG UP SIGNAL FROM FE
;	A/DEVICE CODE
;	B/LINE NUMBER

TTYHGU::CALL GETLIN		;GET LINE NUMBER
	 RET			;ILLEAGAL LINE
	MOVSI A,0(B)		;TO LH
	HRRI A,DLSCXF		;CARRIER TRANSITION
	CALLRET BIGSTO		;STORE IT

;DEFINE THE PROTOCOL TRANSFER VECTOR

TTYDTV::0			;NO STRING DATA
	TTYDON			;ACK
	0			;NO STATUS
	TTYSLA			;SET LINE ALLOCATION
	R			;NO ERROR REPORTING
	TTDTRM			;DETACH REMOTES ON RELOAD
;THIS ROUTINE IS CALLED FROM THE DTE INTERRUPT ROUTINE TO SET
;THE LINE ALLOCATION FOR A TTY LINE. ACCEPTS:
;	1/ DEVICE CODE
;	2/ ALLOCATION
;	3/ LINE NUMBER

TTYSLA::EXCH B,C		;GET ARGS IN PROPER PLACES
	CALL GETLIN		;GET INTERNAL LINE NUMBER
	 RET			;ILLEGAL LINE
	STOR C,TSFMC,(B)	;STORE NEW ALLOCATION
	RET			;AND DONE

;IDCTY - IDENTIFY THE CTY

;ACCEPTS:
;	T2/ UNIT NUMBER FOR THE CTY AS KNOWN BY THE FRONT END

;	CALL IDCTY

;RETURNS +1: ALWAYS

;CALLED FROM DTE SERVICE WHEN THE FRONT END SENDS OVER THE UNIT NUMBER
;WITHIN THE .FEDLS DEVICE THAT IT KNOWS AS THE CTY.  STORES:
;CTYUNT/ THE UNIT NUMBER
;CTYINT/ THE INTERNAL EQUIVALENT OF THAT (INTERNAL LINE NUMBER)

;THE CTY SHOULD ALWAYS BE ADDRESSED INTERNALLY BY CTYLNO, WHICH IS 
;SET UP BY TTINIT. CTYINT WILL CONTAIN THE INTERNAL
;EQUIVALENT OF THE LINE ON WHICH THE CTY IS PHYSICALLY LOCATED FOR THIS
;MONITOR LOAD. ADDRESSING THE LINE BY THIS NUMBER IS AN ERROR.
;IF CTYINT=CTYLNO, CTYINT IS SET TO -1 SO THAT NO LINE NUMBER WILL
;EVER MATCH IT

IDCTY::	SAVET
	PUSH P,T2		;SAVE UNIT NUMBER
	SETOM CTYUNT		;INDICATE CTY NOT KNOWN FOR GETLIN 
	MOVEI T1,.FEDLS		;T1/DEVICE
	CALL GETLIN		;GET THE INTERNAL EQUIVALENT
	 RET			;NOT A FRONT END LINE
	CAME T2,CTYLNO		;IS THIS ITS VALID INTERNAL LINE NUMBER?
	MOVEM T2,CTYINT		;NO. SAVE THIS AS ITS ALIAS
	POP P,CTYUNT		;SET UNIT NUMBER FOR CTY
	RET
;GETLIN - ROUTINE TO CONVERT DEVICE/LINE TO INTERNAL LINE NUMBER
;ACCEPTS:
;	A/DEVICE CODE (ONLY .FECTY OR .FEDLS)
;	B/LINE NUMBER
;RETURNS +1: FAILURE
;	 +2: SUCCESS,
;		T2/INTERNAL LINE NUMBER
;DOES NOT CLOBBER ANY REGISTERS EXCEPT B

GETLIN:	CAIN A,.FECTY		;THE CTY?
	JRST [	MOVE B,CTYLNO	;YES. USE INTERNAL NUMBER OF CTY
		RETSKP]		;AND RETURN WITH GOOD LINE

;THE DEVICE MUST BE .FEDLS

	CAMN B,CTYUNT		;THE UNIT NUMBER FOR THE CTY?
	JRST [	MOVE B,CTYLNO	;YES. GET INTERNAL LINE NUMBER FOR CTY
		RETSKP]
	CAIL B,NTTFE		;IS THE UNIT NUMBER WITHIN THE NUMBER
				; OF FRONT END LINES THAT WE KNOW ABOUT?
	RET			;NO. CAN'T BE A FRONT END LINE
	JUMPE B,GETLN1		;IF THE DL11, SKIP BIAS
	SUBI B,SPCLIN		;BIAS THE LINE
	SKIPG B			;NOW A GOOD T/S LINE NUMBER?
	ADDI B,NTTFE-1		;NO. WAS A SPECIAL. TRANSLATE THE LINE #
GETLN1:	ADD B,TT1LIN+TT.FE	;YES. ADD NUMBER OF FIRST F.E. LINE
	RETSKP			;RETURN SUCCESS


;FIXARG - ROUTINE TO DETERMINE PROPER DEVICE/LINE NUMBER FOR LINE ON RSX20F
;FRONT END

;ACCEPTS: RH B/ DEVICE (ONLY .FEDLS)
;	  LH C/ INTERNAL LINE NUMBER
;	CALL FIXARG
;RETURNS +1: ALWAYS,
;		RH B/ DEVICE AS KNOWN BY THE FRONT END
;		LH C/ UNIT AS KNOWN BY FRONT END

;CALLED IN PREPARATION FOR CALLING DTE SERVICE. LINE IS ASSUMED TO
;BE ON THE FRONT END

;NOTE: IF CALLED WITH -1, RETURNS IMMEDIATELY. THIS IS BECAUSE OF A
;FRONT-END BUG THAT REQUIRES RECEIVING -1 ON A SENDALL

FIXARG:	ACVAR <W1>		;GET SOME WORK REGISTERS
	JUMPL C,R		;IF UNIT .LE. 0, NO CHANGE
	HLRZ W1,C		;GET INTERNAL LINE NUMBER
	CAMN W1,CTYLNO		;THE CTY?
	JRST [	HRRI B,.FECTY	;YES. USE THE CTY
		HRLI C,0	;AND UNIT 0
		RET]
	SUB W1,TT1LIN+TT.FE	;GET LINE NUMBER WITHIN TYPE
	JUMPE W1,FIXAR1		;IF THE DL11, ALL DONE
	ADDI W1,SPCLIN		;NOT. BIAS THE LINE NUMBER
	CAILE W1,NTTFE-1	;A VALID T/S LINE?
	SUBI W1,NTTFE-1		;NO. ONE OF THE SPECIALS THEN
FIXAR1:	HRL C,W1		;RETURN IT IN LH OF C
	RET			;AND DONE

	ENDAV.			;END ACVAR
;LOCAL ROUTINE TO SIMPLIFY CALLS TO DTEQ - USES "BLISS" CALLING SEQUENCE
; T2/ LINE NUMBER
;	CALL <AA,AB,AC,AD>
; WHERE: (SEE DTESRV FOR FURTHER DETAILS)
;   AA - DRIVER INT LOC (ASSUME MASTER DTE)
;   AB - DTE FUNCTION (ASSUME .FEDLS)
;   AC - 0 ,, BYTE CNT (LH FILLED IN WITH LINE NUMBER)
;   AD - DATUM
;RETURN +1: ALWAYS
;  ALL ACS PRESERVED

TTDTEQ:	BLSUB. <AA,AB,AC,AD>
	SAVET
	HRLZ C,B
	HRLZ B,AB
	HRRI B,.FEDLS
	CALL FIXARG		;CONVERT LINE NUMBER
	HRLZ A,AA
	HRR A,MSTRDT
	HRR C,AC
	MOVE D,AD
	CALLRET DTEQI		;USE NON-SKIP VERSION OF DTEQ

	ENDBS.
;DTESTO - ROUTINE TO STORE A CHARACTER IN TTBBUF. CALLED AT INTERRUPT LEVEL
;FROM DTE SERVICE. DATA IS ALWAYS A CHARACTER AT THIS POINT.

;ACCEPTS:
;	T1/CHARACTER IN 8 BITS
;	T2/(0,, PHYSICAL LINE NUMBER)
;	T3/DEVICE TYPE

;RETURNS +1: ALWAYS

DTESTO::EXCH C,A		;TYPE TO A, CHAR TO C
	CALL GETLIN		;GET INTERNAL LINE NUMBER FOR THIS LINE
	 RET			;LINE NOT ON FRONT END
	MOVE A,C		;RESTORE CHARACTER
	CALLRET TTIDON		;GO STORE CHARACTER

;DEVICE DEPENDENT CODE FOR SOBE
;SKIP IF FE BUFFER NOT EMPTY

TTSBEF:	JN TTFCT,(T2),RSKP	;LOCAL RETURN SKIP IF NON-EMPTY
	RET			;EMPTY

;DEVICE DEPENDENT CODE FOR INIALIZING DYNAMIC STORAGE

TTSETF:	LOAD T3,TSFMC,(T2)	;GET FRONT END CHARACTER LIMIT FROM DYNAMIC
	STOR T3,TTFMC,(T1)	; AND COPY TO DYNAMIC
	RET
;ROUTINE CALLED FROM PROTOCOL HANDLER TO DETACH ALL REMOTE JOBS FOR
;A GIVEN DTE. ACCEPTS:
;	A/ DTE NUMBER (NOT USED)
;RETURNS	+1 ALWAYS

	SWAPCD			;IS SWAPPABLE
TTDTRM:	CAME A,MSTRDT		;IS THIS FOR THE MASTER DTE?
	RET			;NO. DON'T DO ANYTHING THEN
	SAVET			;SAVE ALL TEMP REGISTERS
	MOVSI B,NTTFE		;NUMBER OF FE LINES
	MOVNS B			;SET UP AOBJN POINTER
	HRR B,TT1LIN+TT.FE	;START WITH FIRST LINE AND LOOP THROUGH ALL
TTDTR1:	TMNE TTFEM,(B) ;IS THIS LINE REMOTE?
	CALL TTJBDT		;YES. DETACH IT THEN
	AOBJN B,TTDTR1		; DO ALL LINES
	MOVEI A,.SFRMT		;SEE IF REMOTE LOGINS NOW ALLOWED
	TMON			;GET VALUE
	XCT [	CALL DTRMDS	;NOW DISALLOWED
		CALL DTRMEN](B)	;NOW ALLOWED
	RET			;AND DONE
;ROUTINE TO DEFINE THE DL11W PSEUDO-CTY'S.
;PRIMARY PROTOCOL MUST BE RUNNING

DFNDL1::ACVAR <W1>		;GET A WORK REG
	STKVAR <<DFNDLS,2>,<DFNDS1,1>>	;A STRING
	MOVE T2,[ASCII /TTY/]	;GET BASE STRING
	MOVEM T2,DFNDLS		;SAVE IT
	MOVE T2,[ASCIZ /DL0/]	;GET DEFINITION STRING
	MOVEM T2,DFNDS1		;SAVE IT
	MOVE W1,[-<SPCLIN-1>,,SPCLIN-2] ;THE LINES TO DO
DFNDLL:	HRRZ T2,W1		;GET LINE NUMBER
	MOVEI T1,.FEDLS		;FOR THE DLS DEVICE
	CALL GETLIN		;GET ITS INTERNAL NUMBER
	 JRST DFNDLE		;?
	SETONE TTIGI,(T2)	;SET IGNORE
	MOVEI T1,DFNDLS		;GET ADDRESS OF BYTE ARRAY
	HRLI T1,(<POINT 7,0,20>) ;MAKE IT A STRING POINTER
	MOVEI T3,10		;GET AN OCTAL NUMBER
	NOUT			;PUT LINE NUMBER IN STRING
	 JFCL
	MOVEI T3,":"		;GET TERMINATOR
	IDPB T3,T1		;STORE COLON
	SETZM T3		;GET A NULL
	IDPB T3,T1		;TIE OFF STRING
	MOVX T1,<BYTE (7)0,0,1>
	ADDM T1,DFNDS1		;CHANGE LOGICAL NAME STRING
	MOVEI T1,.TTDES(T2)	;GET DEVICE DESIGNATOR IN T1
	MOVEI T2,.MOSNT		;SET NON-TERMINAL STATUS
	MOVEI T3,.MOSMN		;SUPPRESS SYSTEM MESSAGES
	MTOPR			;DO IT
	 ERJMP .+1		;PROCEED IF IT FAILS
	MOVX T1,.CLNSY		;CREATE SYSTEM LOGICAL NAME
	HRROI T2,DFNDS1		;THE LOGICAL NAME
	HRROI T3,DFNDLS		;THE DEFINITION
	CRLNM			;DO IT
DFNDLE:	 BUG (DLDEF)
	AOBJN W1,DFNDLL		;DO THEM ALL
	RET			;AND DOND

	ENDSV.			;END STKVAR
	ENDAV.			;END ACVAR

  >				;END IFN .FEFLG MANY PAGES BACK

  IFE .FEFLG,<
;DUMMY SYMBOLS

TTTOBL:
  >
  IFN .DZFLG,<			;BULK OF DZ CODE FOLLOWS
	SUBTTL DZ11 DEVICE DEPENDENT CODE FOR SM10


; DZ11 TTY SERVICE MODULE FOR SM10 CONFIGURATIONS

	EXTN <DZCHCT>		;SPECIAL "CLOCK" FOR PI CHECKS

;DEFINITIONS FOR TTDEV FOR DZ TYPE LINES

	RESCD

SCDTMZ==^D50			;TIME FOR RING CHECKS
DZTMCK==^D5000/SCDTMZ		;WHEN TO DO PI CHECK
DZCRDL==^D8000			;TIME DELAY FOR CARRIER HANGUP
;START OUTPUT FOR DZ LINE
;CALLED FROM SCHED PERIODIC PROCESSING
; T2/ DYN PTR
; RETURN +1 ALWAYS

DZSTRO:	CHNOFF DLSCHN
	CALL DZSND1		;START LINE
	CHNON DLSCHN
	RETSKP

; SEND CHARACTER TO LINE
; T2/ DYN PTR
; RETURN +1 ALWAYS

DZSND1:	LOAD T3,TINTL,(T2)	;GET LINE NUMBER
	CAME T3,KLILNO		;KLINIK?
	JRST NOTDZK		;NOT KLINIK
	JN KLIOVL,,R		;STILL BUSY
	JN TTXOC,(T2),DZXOC	;XON/OFF REQUESTED?
	CALL TTSND		;GET A CHAR
	 RET			;NONE THERE
	STOR T1,KLIOCH		;STORE OUTPUT CHARACTER
	SETONE KLIOVL		;SET VALID
	JRST CTYCOM		;AND DO COMMON STUFF

NOTDZK:	CAMN T3,CTYLNO
	 IFSKP.
		SKIPE DZLNCT	;IF NO DZ LINES MUST RETURN
		SKIPN FEFLG	;SECONDARY PROTOCOL?
		RET
		JRST DZPRNC	;NOT CTY BUT PRIMARY PROTOCOL
	 ENDIF.
	JN CTYOVL,,R
	JN TTXOC,(T2),DZXOC	;XON/OFF REQUIRED?
	CALL TTSND		;GET CHAR
	 RET			;NONE
	STOR T1,CTYOCH		;SET OUTPUT CHARACTER
	SETONE CTYOVL		;SET VALID CHARACTER AVAILABLE
CTYCOM:	CALL INTETY		;INTERRUPT 8080
	SETONE TTOTP,(T2)	;SET LINE ACTIVE
	RET			;RETURN

;START OUTPUT ON DZ LINE

DZPRNC:	SUB T2,DZLNOF		;SUBTRACT RESTRICTED LINES
	CAMLE T2,DZLNNO		;LEGAL?
	RET
	CALL GETEXL		;GET EXTERNAL PAGE INFO
	SETONE TTOTP,(T2)	;SET LINE ACTIVE
	BSIOB T1,DZTCR(T3)	;REQUEST INTERRUPT ON LINE
	RET
;SEND XON/XOFF ON CTY LINE

DZXOC:	JN TTFXF,(T2),DZPRXO	;DO XON
DZPRXF:	MOVEI T4,XOFFC		;GET XOFF CHARACTER
	SKIPA			;COMMON
DZPRXO:	MOVEI T4,XONC		;GET CHARACTER
	SKIPGE CHITAB(T4)	;PARITY NEEDED?
	TXO T4,200		;YES, APPLY IT
	SETZRO <TTXOC>,(T2)	;CLEAR FLAGS
	CAME T2,KLILNO		;KLINIK?
	 IFSKP. <
		STOR T4,KLIOCH	;YES STORE IN KLINIK BUFFER
		SETONE KLIOVL	;SET VALID CHARACTER
		JRST DZPRXA
	 >
	STOR T4,CTYOCH		;STORE CHARACTER IN 8080 BUFFER
	SETONE CTYOVL		;SET VALID CHARACTER
DZPRXA:	CALL INTETY		;INTERRUPT 8080
	SETONE TTOTP,(T2)	;SET LINE ACTIVE
	RET
DZBST:	LOAD T3,TTFBB,(T2)	;GET COUNT
	AOS T3			;INCREASE COUNT OF CHARACTERS IN TTBBUF
	CAIL T3,MAXABC		;OVER RUN?
	RET			;YES, FLUSH CHAR
	STOR T3,TTFBB,(T2)	;STORE COUNT
	CAIL T3,MAXBBC		;CHECK FOR MAX BEFORE SHUT OFF
	CALL DZSXOF		;SEND XOFF
	RETSKP			;STORE CHARACTER


DZSXOF:	SAVET
	MOVEI T4,XOFFC		;GET XOFF CHARACTER
	SETONE <TTXOC,TTFXO>,(T2) ;SET XOFF
	SETZRO TTFXF,(T2)
	JRST DZXCM		;GO TO COMMON STUFF

DZSXON:	JE TTFXO,(T2),R		;XON ONLY IF REQUIRED
	SAVET
	PUSH P,T2		;SAVE LINE NUMBER
	CALL STADYN		;CONVERT TO DYNAMIC
	 JRST DZNXN		;FORGET IT
	LOAD T4,TIMAX,(2)	;CAPACITY OF INPUT BUFFERS
	SUBI T4,MINCT1		;LESS AMOUNT BEFORE FORCED WAKEUP
	CAMG T4,TTICT(2)	;BUFFER NOW THAT FULL?
	JRST PB2		;YES, WAIT
	DYNST			;BACK TO STATIC ADDRESS
	SETONE <TTXOC,TTFXF>,(T2)	;SET XON REQUIRED
	SETZRO TTFXO,(T2)	;CLEAR OLD SWITCH
DZNXN:	MOVEI T4,XONC		;GET XON CHARACTER
	POP P,T2		;RESTORE LINE NUMBER
DZXCM:	SKIPGE CHITAB(T4)	;PARITY NEEDED?
	TXO T4,200		;YES, APPLY IT
	CHNOFF DLSCHN		;SET CHANNEL OFF
	CAME T2,KLILNO		;KLINIK?
	 IFSKP. <
		JN KLIOVL,,DZCXR	;CHECK TO SEE IF READY
		STOR T4,KLIOCH	;STORE CHARACTER
		SETONE KLIOVL	;SET VALID
		JRST DZXCM1
	 >
	CAME T2,CTYLNO		;CTY?
	JRST DZXDZ		;REAL DZ
	JN CTYOVL,,DZCXR	;CHECK TO SEE IF READY FOR A CHARACTER
	STOR T4,CTYOCH		;SET OUTPUT CHARACTER
	SETONE CTYOVL		;SET VALID
DZXCM1:	SETZRO TTXOC,(T2)	;CLEAR BOTH SINCE ALL IS DONE
	CALL INTETY		;INTERRUPT 8080
DZCXR:	CHNON DLSCHN		;TURN CHANNEL BACK ON
	RET			;AND RETURN

DZXDZ:	PUSH P,T2		;SAVE STATIC ADDRESS
	CALL STADYN		;FIND DYNAMIC STORAGE ADDRESS
	 JRST DZDZX		;NOT SETUP YET FORGET IT
	JN TTOTP,(T2),DZDZX	;QUIT IF BUSY (IT WILL GET CLEARED)
	CALL GETEXL		;FIND EXTERNAL PAGE ADDRESS
	SETONE TTOTP,(T2)	;SET LINE ACTIVE
	BSIOB T1,DZTCR(T3)	;REQUEST INTERRUPT
DZDZX:	CHNON DLSCHN
	JRST PB2		;AND QUIT
;DZINIT -- ROUTINE TO INITALIZE DZ11
;DZRSTR -- SAME ROUTINE TO RESTART DZ11

DZINIT:	SAVEAC <Q1,Q2,P1>	;SAVE AN AC
	SETZM CTYINT		;SET ALIAS (FOR NOW IT IS 0) FOR CTY
	MOVE T4,SMTEPT+DZUBN	;FIND THE TRAP VECTORS
	ADDI T4,DZ110V/4	;OFFSET TO INTERRUPT VECTORS
	MOVEI Q2,DZMAX		;FIND THE MAX DZ11
	MOVE T2,[XPCW DZRDIB]	;SET INTERRUPT BLOCK
	MOVE T3,[XPCW DZXINB]	;OUTPUT INTERRUPT BLOCK
	SETZB Q1,P1		;SET POINTER TO CORRECT BLOCK
DZIVLP:	MOVEM T2,0(T4)		;MAKE AN ENTRY IN THE INTERRUPT VECTOR BLOCK
	MOVEM T3,1(T4)		;GET OUTPUT INTERRUPT VECTOR
	ADDI T3,4		;FOUR WORDS PER INTERRUPT BLOCK
	ADDI T4,2		;POINT TO NEXT INTERRUPT BLOCK
	MOVE T1,[MSEC1,,DZRDIN]	;SET UP THE INTERRUPT BLOCK
	MOVEM T1,DZRDIB+3	;SET UP VECTOR ADDRESS
	SETZM DZRDIB+2		;SET FLAGS TO 0
	MOVE T1,[MSEC1,,DZTXIN]	;SET UP OUTPUT INTERRUPT BLOCK
	ADD T1,Q1		;POINT TO CORRECT INTERRUPT INST
	MOVEM T1,DZXINB+3(P1)
	SETZM DZXINB+2+(P1)	;SET FLAGS TO 0
	ADDI Q1,3		;3 INSTRUCTIONS PER LINE
	ADDI P1,4		;4 WORDS PER BLOCK
	SOJN Q2,DZIVLP		;LOOP UNTIL DONE
	MOVE T1,CTYINT		;GET CTY LINE NUMBER
	AOS T1			;MAKE KLINIK CTY+1
	MOVEM T1,KLILNO		;SAVE KLINIK LINE NUMBER
	RET

; RESTART CODE ALSO RUN FOR INITILIZATION IT SETS UP THE INTERRUPT ENABLES

DZRSTR:	SAVEP			;SAVE THE P'S
	MOVSI P1,-DZMAX		;MAXIMUM NUMBER OF DZ11'S TO HANDLE
	MOVE P2,[DZ11BA]	;GET BASE ADDRESS OF DZ11
DZINLP:	MOVE T1,P2		;ADDRESS OF DZ11
	CALL UBGOOD		;DOES IT EXIST ?
	 JRST DZNOUB		;NO
	MOVEI T1,DZCLR		;INIT THE DZ11
	WRIO T1,DZCSR(P2)	;RESET THE DZ
	MOVSI T2,1		;SET UP LOOP COUNT
DZCLRK:	SOJE T2,[BUG(DZCLRB)]
	TIOE T1,DZCSR(P2)	;WAIT FOR FINISH
	JRST DZCLRK
	MOVEI T1,DZRIEN+DZTIEN+DZMSCN ;SET INTERRUPT ENABLES AND SCANNER
	WRIO T1,DZCSR(P2)	;START DZ11
	ADDI P2,DZMNV		;ADD THE VECTOR SIZE
	AOBJN P1,DZINLP		;AND TRY THE NEXT ONE
DZNOUB:	HRRZM P1,DZLNCT		;SAVE NUMBER OF DZ11'S FOUND
	IMULI P1,10		;COUNT OF LINES
	HRRZM P1,DZLNNO
	MOVE T1,TT1LIN+TT.DZ
	ADDI T1,FELNS		;ADD IN PSEUDO LINES
	MOVEM T1,DZLNOF
	RET			;RETURN

; DZHU0 -- ROUTINE TO SCHEDULE A HANGUP

DZHU0:	SETZ T1,		;T1/ INDICATE DO IT IMMEDIATELY
	MOVEI T3,DZHU2		;T3/ ROUTINE TO HANGUP THE LINE
	CALL TTQAD		;SCHEDULE HANGUP AS SOON AS POSSIBLE
	RET


; DZHU2 -- ROUTINE TO DO A HANGUP

DZHU2:	JE TTFEM,(T2),R		;RETURN IF NO DATASET
	SAVET			;SAVE TEMP'S
	CALL GETEXA		;GET EXTERNAL ADDRESS
	BCIOB T1,DZLPR(T3)	;CLEAR LINE ENABLE
	BCIOB T1,DZDTR(T3)	;CLEAR CARRIER
	RET			;RETURN

;DZ7CX2 -- CARRIER ON


;DZCX2 -- CARRIER OFF

DZ7CX2:	SKIPA T3,[TTCON1]	;CARRIER ON
DZCX2:	MOVE T3,[TTCOF]		;CARRIER OFF
	MOVEI T1,DZCRDL		;8 SEC
	CALL TTQAD
	RET

;DZCH7D -- PIA CHECK TO SEE IF INTERRUPTS ENABLES HAVE BEEN LOST

DZCH7D:	MOVEI T1,SCDTMZ		;TIME FOR NEXT CHECK
	MOVEM T1,TTYTIM		;TELL SCHEDULER
	SOSLE DZCHCT		;TIME FOR PI CHECK?
	JRST DZRING		;NO. DO RING POLL ONLY THEN
	MOVEI T1,DZTMCK		;YES. SET UP NEXT TIME CHECK
	MOVEM T1,DZCHCT		;AND SET UP "CLOCK"
	CHNOFF DLSCHN		;TURN OFF DLS CHANNEL
	MOVE T1,DZLNCT		;GET LINE COUNTS
	JUMPE T1,DZCH7E		;IF NO DZ'S THEN NO CHECK
	MOVE T2,[DZ11BA]	;GET BASE ADDRESS
	MOVEI T3,DZRIEN!DZTIEN!DZMSCN
DZCH7L:	TION T3,DZCSR(T2)	;CHECK FOR ENABLES
	JRST [	BUG(DZLINT,<<T2,D>>)
		MOVEI T4,377	;SET ALL LINES TO INTERRUPT ASSUMING LOST ONE
		WRIOB T4,DZTCR(T2)
		BSIO T3,DZCSR(T2) ;SET INTERRUPT ENABLES AGAIN
		JRST .+1]
	ADDI T2,DZMNV		;LOOK AT NEXT DEVICE
	SOJN T1,DZCH7L		;TRY NEXT ONE
DZCH7E:	CHNON DLSCHN		;TURN ON CHANNEL

;NOW CHECK FOR RING ON ANY OF THE LINES

DZRING:	SKIPE DZLNCT		;IF NO DZ LINES FORGET IT
	SKIPGE T2,TT1LIN+TT.DZ	;GET FIRST LINE NUMBER
	RET			;NONE THERE
	MOVN T4,DZLNNO		;FIND COUNT OF LINES
	HRL T2,T4		;GET - NUMBER OF LINES
	ADDI T2,FELNS		;UPDATE FOR CTY AND KLINIK
DZRNG0:	JE TTFEM,(T2),DZRNG7	;NOT A REMOTE LINE - NO PROCESSING NECESSARY
	PUSH P,T2		;SAVE ARGS
	CALL GETEXA		;GET EXTERNAL PAGE ADDRESS
	TIONB T1,DZRNG(T3)	;CHECK FOR RING
	JRST NORNG		;NOT RING
	JN TTCON,(T2),[SETZRO TTCON,(T2) ;HANG UP IMMEDIATELY
		MOVEI T3,NTYCOF ;HANGUP ROUTINE
		SETZ T1,0	;DO ASAP
		CALL TTQAD
		JRST DZRRTN]	;IMPLIES NEW CALL
	BSIOB T1,DZDTR(T3)	;SET CARRIER ON
	JRST DZRSCO		;INDICATE CARRIER SET ON

DZRRTN:	POP P,T2
DZRNG7:	AOBJN T2,DZRNG0		;DO THEM ALL
	RET			;AND DONE

NORNG:	TIONB T1,DZCAR(T3)	;CHECK FOR CARRIER ON
	JRST CARNON		;CARRIER NOT ON
	JN TTCON,(T2),DZRRTN	;CARRIER  EXPECTED TO BE ON
DZRSCO:	SETONE TTCON,(T2)
	MOVE T3,[TTCON1]	;SET CARRIER ON
	MOVEI T1,DZCRDL		;8 SEC
	CALL TTQAD		;SCHEDULE IT
	JRST DZRRTN		;AND QUIT

CARNON:	JE TTCON,(T2),DZRRTN	;CARRIER NOT EXPECTED TO BE ON
	CALL STADYN		;ACTIVE?
	 JRST DZCAR1		;NOT ACTIVE AND QUIT BETTER KILL IT
	JN TTPRM,(T2),DZRRTN	;NOT PERM --WAIT
DZCAR1:	HRRZ 2,0(P)		;GET UNIT NUMBER BACK
	SETZRO TTCON,(T2)
	MOVE T3,[TTCOF]		;SET CARRIER OFF FLAG
	MOVEI T1,DZCRDL		;8 SEC
	CALL TTQAD		;SCHEDULE IT
	JRST DZRRTN		;AND QUIT
;READ INTERRUPT ROUTINE

DZRDIN: MOVEM P,DZSAVP		;SAVE A REGISTER
	MOVEI P,DZSVAC		;POINT TO AC SAVE AREA
	BLT P,DZSVAC+16		;SAVE AC'S
	MOVE P,DZPDL		;SET UP STACK
	MOVE Q1,DZLNCT		;FIND THE NUMBER OF LINES
	MOVE Q2,[DZ11BA]	;FIND FIRST EXTERNAL PAGE ADDRESS
	SKIPE FEFLG		;CHECK FOR PRIMARY PROTOCOL
	JRST DZINPP		;YES -- GO DUMP ALL DZ'S
DZCTRD:	RDIO T1,DZRBUF(Q2)	;READ A CHARACTER
	TRNE T1,DZRDVL		;VALID?
	JRST DZCTRD		;LOOP AND TRY FOR ANOTHER
DZNXCL:	SOJE Q1,DZRXIT		;CHECK TO SEE IF ALL DZS DONE
	ADDI Q2,DZMNV		;LOOK AT NEXT DZ TO DUMP ALL CHARACTERS
	MOVEI T1,DZRDVL		;IN THE BUFFERS TO STOP THEIR INTERRUPTING
	TIOE T1,DZRBUF(Q2)	;THIS WILL READ A CHARACTER AND DUMP IT
	JRST .-1		;THIS WILL CAUSE ALL CHARACTERS TO BE DUMPED
	JRST DZNXCL		;GO DO NEXT DZ

DZINPP:	MOVE P1,DZLNOF		;SET UP LINE NUMBER (MUST START AT 1
DZINPL:	RDIO T1,DZRBUF(Q2)	;GET A CHARACTER
	TRNN T1,DZRDVL		;VALID?
	JRST DZNXLN		;NO -- GO TO NEXT LINE
	TRNE T1,DZROVR		;OVER RUN
	BUG(DZOVER,<<T1,D>>)
	LOAD T2,DZTXLN,T1	;GET THE LINE NUMBER
	ADD T2,P1		;FIND ITS INTERNAL LINE NUMBER
	ANDI T1,377		;MASK TO CHARACTER ONLY
	CALL TTIDON		;GO PUT IN BUFFER
	JRST DZINPL		;GET ANOTHER CHARACTER

DZNXLN:	ADDI P1,10		;8 LINES PER DZ
	ADDI Q2,DZMNV		;LOOK AT NEXT DZ
	SOJN Q1,DZINPL		;CHECK TO SEE IF COUNT DONE
	JRST DZRXIT		;GO TO READ EXIT (DONE)


DZRXIT:	MOVSI P,DZSVAC		;RESTORE ACS
	BLT P,CX		;RESTORE
	MOVE P,DZSAVP		;RESTORE P
	XJEN DZRDIB		;RETURN
;INTERRUPT ROUTINE FOR THE CTY FOR THE KS10

DZCTIN::CLSB DLSCHN		;CLEAR CHANNEL INTERRUPT REQUEST
	MOVEM P,DZSAVP		;SAVE STACK REGISTER
	MOVEI P,DZSVAC		;POINT TO SC SAVE AREA
	BLT P,DZSVAC+16		;SAVE ACS
	MOVE P,DZPDL		;SET UP STACK
	JE KLIIVL,,DZNOKL	;CHECK FOR KLINIK INPUT
	LOAD T1,KLIICH		;GET THE CHARACTER
	MOVE T2,KLILNO		;GET LINE NUMBER
	SETZRO KLIIVL		;CLEAR VALID BIT
	CALL TTIDON		;OUTPUT CHARACTER
	CALL INTETY		;INTERRUPT EIGHTY EIGHTY
DZNOKL:	JN KLIOVL,,DZNXT	;OUTPUT VALID?
	MOVE T2,KLILNO		;YES GET LINE NUMBER
	CALL STADY		;GET DYN ADDR
	 JRST DZNXT		;TRY NEXT
	CALL DZSND1		;OUTPUT ANOTHER CHAR
DZNXT:	JE CTYIVL,,DZNOCT	;CHECK FOR CTY INPUT
	LOAD T1,CTYICH		;PICK UP THE CHACTER
	MOVE T2,CTYLNO		;GET THE CTY LINE NUMBER
	SETZRO CTYIVL		;CLEAR  CHARACTER IN BUFFER FLAG
	CALL TTIDON		;OUTPUT CHARACTER
	CALL INTETY		;INTERRUPT EIGHTY EIGHTY
DZNOCT:	JN CTYOVL,,DZNXIT	;NO CTY
	MOVE T2,CTYLNO		;GET LINE NUMBER
	CALL STADY		;CONVERT TO DYNAMIC STORAGE
	 JRST DZNXIT		;QUIT IF NO DYNAMIC STORAGE
	CALL DZSND1
DZNXIT:	MOVSI P,DZSVAC		;RESTORE
	BLT P,CX
	MOVE P,DZSAVP
	RET			;RETURN
DZPDL:	IOWD 40,DZISTK		;I/O STACK SIZE
RS (DZISTK,40)			;STACK FOR INTERRUPT SERVICE
RS (DZRDIB,4)			;INPUT INTERRUPT BLOCK
RS (DZXINB,4*^D8)		;INTERRUPT BLOCK FOR OUTPUT
RS (DZSVAC,17)			;SAVE AC FOR READ INTERRUPT
RS (DZSAVP,1)			;SAVE AC 17
RS (DZLNCT,1)			;COUNT OF DZ'S FOUND
RS (DZLNNO,1)			;COUNT OF LINES FOUND
RS (DZLNOF,1)			;OFFSET TO FIRST LINE NUMBER

; NOTE MUST HAVE ONE SET OF 3 INSTRUCTIONS PER DZ11!!!!!!
DZTXIN::DMOVEM P6,DZSVAC+P6	;SAVE REGISTERS
	SETZ P6,0		;POINTER TO WHICH LINE SET
	JRST DZCOMI		;GO TO COMMON INTERRUPT SERVICE
DZTXI1:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,10		;SECOND BLOCK OF 10
	JRST DZCOMI
DZTXI2:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,20
	JRST DZCOMI
DZTXI3:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,30
	JRST DZCOMI
DZTXI4:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,40
	JRST DZCOMI
DZTXI5:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,50
	JRST DZCOMI
DZTXI6:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,60
	JRST DZCOMI
DZTXI7:	DMOVEM P6,DZSVAC+P6
	MOVEI P6,70
;	JRST DZCOMI
;	..
	; ..
DZCOMI:	MOVEM P,DZSAVP		;SAVE A REGISTER
	DMOVEM T1,DZSVAC+T1
	DMOVEM T3,DZSVAC+T3
	DMOVEM Q1,DZSVAC+Q1
	MOVE P,DZPDL		;SET UP STACK SIZE
	MOVE Q2,[DZ11BA]	;GET BASE ADDRESS
	ADD Q2,P6		;POINT TO CORRECT ADDRESS
	LSH P6,-1		;FIND RETURN ADDRESS
	DMOVE T1,DZXINB(P6)	;GET RETURN PS/PC
	DMOVEM T1,DZXINB	;STORE IN COMMON RETURN
	LSH P6,1		;GET ADDRESS BACK
	ADD P6,DZLNOF		;SET UP LINE COUNT
DZTNXO:	RDIO T2,DZCSR(Q2)	;READ THE STATUS
	TRNN T2,DZTRDY		;CHECK FOR TRANSMIT DONN
	JRST DZTXIT		;NOT THIS DZ TRY NEXT ONE
	LDB T2,[POINT 3,T2,27]	;PICK UP LINE NUMBER
	MOVNS T2		;GET CORRECT BIT POSITION
	MOVE Q1,BITS+^D35(T2)	;SAVE LINE NUMBER
	MOVNS T2		;BACK THE WAY IT WAS
	ADD T2,P6		;MAKE ABSOLUTE NUMBER
	JN <TTXOC>,(T2),[
		CALL GETEXA
		CALL DZXOCA	;DO XON/XOF
		JRST DZTNXO]
	SKIPN T2,TTACTL(T2)	;NET DYNAMIC STORANE
	JRST DXTNEX		;IF NO BLOCK THIS IS AN EXTRNAEOUS INTERRUPT
	CALL TTSND		;DO TTY DONE
	 JRST DXTNEX		;BFR EMPTY
	SETONE TTOTP,(T2)	;SET OUTPUT ACTIVE
	WRIOB T1,DZTBUF(Q2)
	JRST DZTNXO

DXTNEX:	BCIOB Q1,DZTCR(Q2)  	;CLEAR THE ACTIVE BITS
	JRST DZTNXO		;TRY FOR ANOTHER
				;THIS WILL STOP INTERRUPTING DZ AND END OUTPUT

DZTXIT:	DMOVE T1,DZSVAC+T1
	DMOVE T3,DZSVAC+T3
	DMOVE Q1,DZSVAC+Q1
	DMOVE P6,DZSVAC+P6
	MOVE P,DZSAVP		;RESTORE AC
	XJEN DZXINB		;AND RETURN

;SEND XON/XOFF

DZXOCA:	JN TTFXO,(T2),DZDZXF	;XOFF?
DZDZXO:	MOVEI T4,XONC		;GET CHARACTER
	SKIPA			;COMMON ENTRY
DZDZXF:	MOVEI T4,XOFFC		;GET XOFF CHARACTER
	SKIPGE CHITAB(T4)	;PARITY NEEDED?
	TXO T4,200		;YES, APPLY IT
	SETZRO <TTXOC>,(T2)	;CLEAR FLAGS
	WRIOB T4,DZTBUF(T3)	;WRITE CHARACTER
	RET
; SENDALL
	SWAPCD

DZSNDL:	SKIPN FEFLG		;PRIMARY PROTOCOL?
	JRST [	SETO T2,	;NO, RETURN SKIP GROUP
		RETSKP]
	CAME T2,KLILNO
	CAMN T2,CTYINT		;CHECK FOR REAL CTY
	RET			;CAN'T DO THIS LINE
	SKIPGE TTSPWD(T2)	;SPEED SET?
	RET			;NO, SKIP LINE
	PUSH P,T2
	SUB T2,DZLNOF		;FIND IF LINE A LEGAL DZ LINE
	CAML T2,DZLNNO		;LGAL? (DZ'S +CTY)
	JRST [	ADD T2,DZLNOF	;PUT LINE NUMBER BACK
		CAME T2,KLILNO	;CHECK FOR KLINIK
		CAMN T2,CTYLNO	;CHECK FOR CTY
		JRST .+1	;YUP ALL OK TO DO SENDALL
		JRST PB2]	;NOPE QUIT
DZCTOK:	POP P,T2		;RESTORE LINE NUMBER
	RETSKP
; SET SPEED FOR A DZ11 LINE

DZSSP2:	UMOVE T4,2		;GET FLAGS
	TXNE T4,MO%AUT		;REQUESTING AUTO?
	RETBAD			;YES. CAN'T HAVE IT ON THIS DEVICE
	SKIPN DZLNCT		;IF NO DZ LINES CAN'T SET SPEED
	RET
	UMOVE T4,T3		;GET THE SPEED
	HLRZ T1,T4		;CHECK TO SEE BOTH HALF THE SAME
	CAME T2,KLILNO		;NOT KLINIK LINE NUMBER EITHER
	CAMN T2,CTYINT		;CHECK FOR CTY
	RET			;NOT LEGAL ON THIS MACHINE
	CAME T2,CTYLNO		;CHECK TO SEE IF CTY (CAN'T SET THAT ONE)
	CAIE T1,0(T4)		;IF NOT SAME THEN FORGET IT HARDWARE
	RET			;SUPPORTS INPUT/OUTPUT SAME
	NOINT			;SET NOINT
	CHNOFF DLSCHN		;TURN OFF CHANNEL WHILE PLAYING WITH LINE SPEEDS
	JN TTFEM,(T2),DZSSP1	;IF REMOTE DON'T SET PERM SPEED
	XCTU [SKIPGE 2]		;REMOTE REQUESTED?
	 IFNSK.
		MOVX T3,SC%OPR!SC%WHL	;CHECK CAPBILITIES
		TDNN T3,CAPENB
		JRST DZSSP1		;NO CAPABILITIES FORGET IT
		SETONE TTFEM,(T2)	;SET ONCE ONLY FLAG
	 ENDIF.
	JUMPE T4,[EXCH T4,TTSPWD(T2) ;TREAT SPEED ZERO SPECIALLY, PRESERVE
		  JRST DZSSP1]	; OUTPUT CHARACTERISTICS, TURN OFF INPUT
	MOVEM T4,TTSPWD(T2)	;SAVE TTY SPEED
DZSSP1:	HRRZS T4		;SET SPEED IN RIGHT HALF ONLY
	MOVEI T1,DZSPTB		;FIND POINTER TO TABLE POINTER
DZSPLP:	MOVE T3,0(T1)		;GET A TABLE ENTRY
	JUMPE T3,NOLNSP		;NO LINE SPEED FOUND
	CAIE T4,0(T3)		;CORRECT ENTRY?
	AOJA T1,DZSPLP		;NO -- TRY NEXT ONE
	HLRZ T4,T3		;GET LINE SPEED
	MOVE T3,T2		;GET LINE NUMBER
	SUB T3,DZLNOF		;SUBTRACT FRONT-END LINES
	CAML T3,DZLNNO		;CHECK TO SEE IF LEGAL LINE NUMBER
	JRST NOLNSP		;NOPE -- QUIT WHILE AHEAD
	ANDI T3,7		;MASK TO 3 BITS
	IOR T4,T3		;SET UNIT NUMBER
	CALL GETEXA		;GET THE EXTERNAL PAGE ADDRESS OF THIS DZ
	SKIPN TTSPWD(T2)	;SETTING SPEED TO ZERO?
	TRZ T4,DZ1RXO		;YES, FOR DZ HARDWARE TURN OFF RX CLOCK
	WRIO T4,DZLPR(T3)	;SET THE LINE PARAMETER REGISTER
NOLNSP:	CHNON DLSCHN		;ENABLE CHANNEL
	OKINT			;ENABLE INTERRUPTS
	RET			;RETURN

DZSPTB:	DZ1RXO+DZ1OPA+DZ8BIT+DZ2STP+0,,^D50
	DZ1RXO+DZ1OPA+DZ8BIT+DZ2STP+400,,^D75
	DZ1RXO+DZ1OPA+DZ8BIT+DZ2STP+1000,,^D110
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+1400,,^D134
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+2000,,^D150
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+2400,,^D300
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+3000,,^D600
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+3400,,^D1200
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+4000,,^D1800
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+4400,,^D2000
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+5000,,^D2400
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+5400,,^D3600
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+6000,,^D4800
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+6400,,^D7200
	DZ1RXO+DZ1OPA+DZ8BIT+DZ1STP+7000,,^D9600
	0,,0			;END OF TABLE
	RESCD
;GETEXA -- SUBROUTINE TO FIND THE EXTERNAL PAGE ADDRESS OF 
; THE SPECIFIED DZ11

; CALLING SEQUENCE:
; T2 -- LINE NUMBER
;
;	CALL GETLIN
; T1 -- LINE BIT POSITION (LINE 0=1B35 ETC)
; T3 -- EXTERNAL PAGE ADDRESS OF FIRST REGISTER FOR THIS DZ11
; RETURNS +1 ALWAYS

GETEXA:	PUSH P,T2		;SAVE LINE NUMBER
GETEX1:	SUB T2,DZLNOF		;BACKUP TO POINT TO REAL  NUMBER
	MOVE 3,2		;GET LINE NUMBER
	ANDI T3,777770		;MASK OF LOW ORDER 3 BITS (8 PER DZ)
	ADD T3,[DZ11BA]		;ADD DZ11 BASE ADDRESS
	MOVE T1,T2
	ANDI T1,7		;MASK OFF UNIT
	MOVNS T1
	MOVE T1,BITS+^D35(T1)
	POP P,T2		;RESTORE
	RET

;
;  GETEXL -- SUBROUTINE TO FIND EXTERNAL PAGE AND LINE NUMBER
;
;	CALLING SEQUENCE:
;	B -- DYNAMIC STORAGE ADDRESS
;	CALL GETEXL
;	RETURNS:
;	A -- LINE BIT POSITION (LINE 0=1B35 1,1B34 ETC)
;	C -- EXTERNAL PAGE ADDRESS OF THIS DZ11
;

GETEXL:	PUSH P,T2		;SAVE DYNAMIC ADDRESS
	DYNST			;GET LINE NUMBER
	CALLRET GETEX1		;GET EXTERNAL PAGE ADDRESS

  >				;END IFN .DZFLG MANY PAGES BACK

  IFE .DZFLG,<
;DUMMY SYMBOLS

DZHU2:
  >

;END OF ALL TTYSRV MODULES

	TNXEND
	END