Google
 

Trailing-Edge - PDP-10 Archives - BB-H311D-RM - monitor-sources/ttphdv.mac
There are 8 other files named ttphdv.mac in the archive. Click here to see a list.
; UPD ID= 4900, SNARK:<6.MONITOR>TTPHDV.MAC.91,   8-Oct-84 05:07:38 by TBOYLE
;TCO 6.2238 - handle speed setting properly.
; UPD ID= 4844, SNARK:<6.MONITOR>TTPHDV.MAC.90,  17-Sep-84 11:38:42 by PURRETTA
;Update copyright notice
; UPD ID= 4178, SNARK:<6.MONITOR>TTPHDV.MAC.89,   7-May-84 13:32:27 by LOMARTIRE
;More TCO 6.2047 - Fix all possible cases of PI 6 NOSKED/OKSKED from TTYDED
; UPD ID= 3397, SNARK:<6.MONITOR>TTPHDV.MAC.88,   3-Jan-84 10:38:46 by PRATT
;TCO 6.1796 - Create TTNTM1, sets/clears TTNTS in fe only.
; UPD ID= 2854, SNARK:<6.MONITOR>TTPHDV.MAC.87,  22-Aug-83 08:56:51 by GRANT
;TCO 6.1784 - In TTSETH, fix logic which sets TTNPM
; UPD ID= 2686, SNARK:<6.MONITOR>TTPHDV.MAC.86,   8-Jul-83 17:42:41 by WEAVER
;TCO 6.1718 - Fix code so LOCAL AUTOBAUD lines don't get the REMOTE bit set
;	when the speed is recieved from the FE
; UPD ID= 2343, SNARK:<6.MONITOR>TTPHDV.MAC.85,  26-Apr-83 07:37:45 by WEAVER
;TCO 6.1600 - Allow LOCAL lines to be set as autobaud
; UPD ID= 2293, SNARK:<6.MONITOR>TTPHDV.MAC.84,  16-Apr-83 19:16:56 by PAETZOLD
;TCO 6.1557 - TCP Merge
; UPD ID= 2039, SNARK:<6.MONITOR>TTPHDV.MAC.83,  20-Mar-83 12:46:39 by HALL
;TCO 6.1502 - Allow resident free space in extended section
;	Use one-word global byte pointers to point to sendall buffer and
;		I/O buffers, which must be in section 0 for the DTE.
;	Convert one-word global to one-word local before handing to DTESRV
;	Change handling of end of I/O buffers, and definition of WRPMSK,
;		to reflect use of one-word globals
;	In FNDEND, use ADJBP to decrement byte pointer instead of previous hack
; UPD ID= 1985, SNARK:<6.MONITOR>TTPHDV.MAC.82,  14-Mar-83 08:48:34 by HALL
;TCO 6.1502 - Allow resident free space in extended section
;	Add EA.ENT to TTDTRM
; UPD ID= 1970, SNARK:<6.MONITOR>TTPHDV.MAC.81,  10-Mar-83 19:11:06 by HALL
;TCO 6.1502 - Allow resident free space in extended section
;	Add EA.ENT to TTYINT,TTSPST,TTYDON,TTYDLU,TTYHGU,TTYSLA,IDCTY,
;		DTESTO,DFNDL1
; UPD ID= 1945, SNARK:<6.MONITOR>TTPHDV.MAC.80,   9-Mar-83 10:16:58 by HALL
;TCO 6.1502 - Allow resident free space in extended section
;	Change call to ASGRSB to set RS%SE0
; UPD ID= 1735, SNARK:<6.MONITOR>TTPHDV.MAC.79,   1-Feb-83 18:20:35 by WEAVER
;TCO 6.1485 - Fix TCO 6.1480, put TT%XFF in dynamic storage block.
; UPD ID= 1714, SNARK:<6.MONITOR>TTPHDV.MAC.78,  28-Jan-83 10:56:17 by MURPHY
;More 6.1390 - Add dummy symbol if no FE code.
; UPD ID= 1711, SNARK:<6.MONITOR>TTPHDV.MAC.77,  27-Jan-83 22:58:02 by WEAVER
;TCO 6.1480 - Only send XOFF/XON status to front-end if TTXFF (XOFF FORCE)
;is set.
; UPD ID= 1572, SNARK:<6.MONITOR>TTPHDV.MAC.76,  27-Dec-82 08:30:12 by GRANT
;TCO 6.1426 - When closing an NVT connection, don't undo TTPRM if the line
; is an MCB TTY or the CTY
; UPD ID= 1533, SNARK:<6.MONITOR>TTPHDV.MAC.75,  14-Dec-82 09:55:48 by MURPHY
;TCO 5.1.1114 - Index needed at SNDXN2+8L to fix XOFF/XON for incoming chars.
; UPD ID= 1489, SNARK:<6.MONITOR>TTPHDV.MAC.74,  30-Nov-82 11:45:34 by WEAVER
;TCO 6.1393 - Use Break Through Write to send XONs and XOFFs to a line
; UPD ID= 1485, SNARK:<6.MONITOR>TTPHDV.MAC.73,  29-Nov-82 13:36:14 by MURPHY
;TCO 6.1390 - Shut off 20F line if more than 2 noise characters in 1 second.
; UPD ID= 1332, SNARK:<6.MONITOR>TTPHDV.MAC.72,  13-Oct-82 07:04:19 by GRANT
;More of previous edit - fix bug in TNTCLS's debugging code
; UPD ID= 1312, SNARK:<6.MONITOR>TTPHDV.MAC.71,   9-Oct-82 10:28:22 by GRANT
;TCO 5.1.1089 - Rewrite TNTCLS, save link IDs rather than LL block addresses
; UPD ID= 1086, SNARK:<6.MONITOR>TTPHDV.MAC.70,  16-Aug-82 14:31:44 by MURPHY
;TCO 6.1202 - Pass proper arg to TTCBF9 at TINET3.
; UPD ID= 994, SNARK:<6.MONITOR>TTPHDV.MAC.69,  18-Jul-82 13:52:18 by MURPHY
;TCO 5.1.1048 - Add TTCLSH to clear "set host" state when closing LL.
; UPD ID= 991, SNARK:<6.MONITOR>TTPHDV.MAC.68,  18-Jul-82 13:30:31 by MURPHY
;TCO 5.1.1047 - Put NOSKED before call to TNTCLS to interlock ULLCZQ.
; UPD ID= 990, SNARK:<6.MONITOR>TTPHDV.MAC.67,  18-Jul-82 13:28:02 by MURPHY
;TCO 5.1.1046 - Check TTNUS before call to TNUREC.
; UPD ID= 970, SNARK:<6.MONITOR>TTPHDV.MAC.66,  30-Jun-82 08:55:45 by GRANT
;TCO 5.1.1038 - Remove CALL SQIACK in DECnet NVT processor
; UPD ID= 851, SNARK:<6.MONITOR>TTPHDV.MAC.65,   6-Jun-82 13:29:44 by MURPHY
;TCO 6.1147 - Move bugdefs from BUGS.MAC to here and put them in-line.
; UPD ID= 819, SNARK:<6.MONITOR>TTPHDV.MAC.64,   3-Jun-82 07:42:18 by GRANT
;TCO 6.1154 - Fix failure return from CALL SNDCHK in MCSTRO.
;Change comment in CHKLLT.
; UPD ID= 800, SNARK:<6.MONITOR>TTPHDV.MAC.63,   1-Jun-82 08:31:46 by GRANT
;TCO 6.1148 - Remove code which breaks DECnet connection when a character is
;received on a line on which there is no job
; UPD ID= 771, SNARK:<6.MONITOR>TTPHDV.MAC.62,  19-May-82 17:20:19 by MILLER
;TCO 6.1066 AGAIN. Make RSP output work in secondary protocol
; UPD ID= 505, SNARK:<6.MONITOR>TTPHDV.MAC.61,  16-Mar-82 07:01:10 by MILLER
; UPD ID= 476, SNARK:<6.MONITOR>TTPHDV.MAC.60,  13-Mar-82 14:49:59 by MILLER
;TCO 6.1066 AGAIN. Add some of the RSP support code
; UPD ID= 458, SNARK:<6.MONITOR>TTPHDV.MAC.59,  11-Mar-82 11:47:06 by MILLER
;TCO 6.1066. Make MCSRV internal
; UPD ID= 328, SNARK:<6.MONITOR>TTPHDV.MAC.58,  19-Jan-82 15:23:21 by MURPHY
;TCO 5.1688 - report TTYSTP only once per line
; UPD ID= 150, SNARK:<6.MONITOR>TTPHDV.MAC.57,  21-Oct-81 12:14:07 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

;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  1976, 1984.
;ALL RIGHTS RESERVED.


  IFN .MCFLG,<			;INCLUDE ONLY UNDER MASTER FLAG
	SUBTTL DECNET NETWORK TERMINAL DEPENDENT CODE
	RESCD
	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 SIGNIFICANT EVENTS OCCUR.
;ACCEPTS:	T1/  LL BLOCK ADDRESS
;RETURNS:	+1

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?
	IFSKP.
	  SETZRO TTNPM,(T2)	;NO
	ELSE.
	  SETONE TTNPM,(T2)	;YES
	ENDIF.
	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
	CAIE T1,TT.MCB		;STILL MCB?
	JRST [	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
	NOSKD1			;NO SCHEDULING
	CALL TNTCLS		;PUT LL ON RELEASE QUEUE
	CHNOFF DLSCHN		;TURN OF CHANNEL
	CALL TTCOB5		;FLUSH OUTPUT (DOES CHNON AND OKSKD1)
	SETZRO TTOTP,(T2)	;CLEAR ACTIVE
	SETZRO TTHLL,(T2)
	SETZRO TTPRM,(T2)	;BLOCK NO LONGER PERMANENT
	RET

;Clear user state - called if LL being closed.
; T1/ LL
;	CALL TTCLSH
;Return +1 always.

TTCLSH::LOAD T2,LLTTY,(T1)	;GET LINE NUMBER
	CALL STADYN
	 RET			;ALREADY GONE
	SETZRO TTULL,(T2)	;CLEAR EVERYTHING
	SETZRO TTNUS,(T2)
	CALL CTYMCB		;CTY OR MCB LINE?
	IFSKP.
	   SETZRO TTPRM,(T2)	;NO, BLOCK NO LONGER PERMANENT
	ENDIF.
	RET
;CLOSE NET USER CONNECTION
; T2/ DYNAMIC PTR

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

;CLOSE NVT
;ACCEPTS:	T1/ LL
;		T2/ TDB
;RETURNS:	+1
;PRESERVES T2

TNTCLS:	LOAD T3,LLLNK,(T1)	;GET THE LINK ID
   IFN CZQDBG,<			;IF DEBUG
	MOVEM T2,@CZQPTR	;SAVE TTY BLK
	HRLM T3,@CZQPTR		;SAVE LL ID
	AOS T4,CZQPTR		;INCR THE POINTER
	CAIL T4,CZQBF+LCZQBF	;AT END OF BFR?
	MOVEI T4,CZQBF		;YES, WRAP
	HRRM T4,CZQPTR		;UPDATE THE POINTER
   >
	SETZRO LLTTA,(T1)	;TTY NO LONGER ACTIVE ON THIS LL
	SETZ T1,		;MAKE AOBJN
	HRLI T1,-NTTMCB		; WORD
	SKIPE ULLCZQ(T1)	;THIS ENTRY FREE?
	AOBJN T1,.-1		;NO
	MOVEM T3,ULLCZQ(T1)	;YES, PUT IN LINK ID FOR NSPTSK
	RET			;DONE
;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
	 JRST [	UNLOCK LLLLCK	;COULDN'T
		JRST MCSOZ]
	UNLOCK LLLLCK
MCSO1:	LOAD T3,LLSTA,(LL)	;CHECK LL STATE
	CAIE T3,LLSRUN		;RUNNING?
	JRST [	CALL REQNS	;FORCE INPUT CHECK, WILL DO SHUTDOWN
		JRST MCSOX]
	CALL SNDCHK		;CAN SEND ANOTHER SEG ON THIS LL?
	IFNSK.			;NOT NOW
	   SKIPG TTOCT(TDB)	;OUTPUT READY TO GO?
	   JRST MCSOX		;NO, GO AWAY
	   JRST MCSOQ		;YES, SET TTSOQ BIT
	ENDIF.
	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
	 JRST [	MOVE T1,MB	;NOTHING TO GO, RELEASE BLOCK
		CALL RELRES
		JRST MCSOX]
	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
	 JRST [	UNLOCK LLLLCK	;COULDN'T
		CALL REQNS	;TRY AGAIN LATER
		JRST TTUSY]
	UNLOCK LLLLCK
TTUS3:	LOAD T3,LLSTA,(LL)	;CHECK LL STATE
	CAIE T3,LLSRUN		;RUNNING?
	JRST [	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
	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
	 JRST [	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 CONFIGURATION-DEPENDENT CODE IN STG

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
	JE TTNUS,(T2),TNET3	;JUMP IF NO LONGER IN NET USER STATE
	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
	CAIGE T3,2(T4)		;ROOM FOR ANOTHER?
	JRST [	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
	 JRST [	LOAD T1,TTUEC,(T2) ;LL GONE, SIMULATE ESCAPE CHAR
		CALL TTCHID
		 NOP
		RET]
	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

   REPEAT 0,<
;THIS CODE EXISTED FOR THE CONVENIENCE OF VMS USERS;  IT ALLOWED THEM TO
;TYPE ANY CHARACTER TO BREAK THE NETWORK CONNECTION AFTER LOGGING OUT OF TOPS-20.
;OTHERWISE, THEY HAVE TO TYPE ^P AND EXIT FROM THEIR PROGRAM WHICH MAKES THE
;CONNECTION.  IT WAS LATER DISCOVERED THAT THIS PRODUCES AN INCONSISTENCY IN
;TOPS-20'S HANDLING OF LINES ON WHICH THERE IS NO JOB.  CG
	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.
   >				;END REPEAT 0
	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
	MOVE T2,Q2		;GET DYNAMIC PTR
	CALL TTCBF9		;CLEAR OUTBUF
	CALL TTYDED		;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
	CAIE T3,LLSRUN		;RUNNING?
	JRST [	MOVE T1,LL	;NO
		CALL BLKULK	;UNLOCK LL
		MOVE T2,TDB	;RESTORE AC
		RET]		;RETURN FAIL
	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?
	JRST [	SETONE LLFIM,(LL) ;YES
		JRST .+1]
	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
MCTYIZ:	LOAD T3,LLLSC,(LL)	;SEE IF FLOW COUNT TO BE SENT
	CAIGE T3,MAXSG1-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.(HLT,NOMCCD,TTYSRV,SOFT,<TTYSRV: ROUTINE CALLED FOR LINE TYPE NOT SUPPORTED>,,<

Cause:	Control passed to a routine not present in this monitor configuration.

Action:	See if TTNUS flag on for relevant line.  Examine stack for path.

>)
  >

  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
	TMNE TTOTP,(D)	;OUTPUT IN PROGRESS?
	JRST [	EXCH D,TTCBSV	;YES. GET BACK ORIGINAL ARGUMENT
		CALL DTEFLO	;YES, FLUSH DTE REQUESTS
		JRST TTCBF5]
	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:
	TRVAR <LINENO>
	MOVEM T2,LINENO		;SAVE LINE NUMBER
	SKIPN FEFLG		;IN PRIMARY PROTOCOL?
	RET			;NO. IGNORE IT THEN
	ACVAR <W1,SSBFR>
	UMOVE W1,2		;GET FLAGS
	NOINT			;PREVENT INTS
	BLCAL. ASGRSB,<[4],[.RESP3],[RS%SE0!.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

;THE LAW OF SPEED SETTING: 

; (1) IF MO%AUT=0 AND A LINE IS NOT REMOTE NOR AUTOBAUD, THEN SET TTSPWD
;	AND ALSO SET SAVED SPEED IF ANY. THE SAVED SPEED IS ACTUALLY ONLY
;	USED WHEN THE LINE IS GOING MO%RMT.
; (2) IN THE OTHER CASES, IF MO%AUT=0 THEN SET TTSPWD ONLY IF THERE IS
;	A DYNAMIC DATA BLOCK. THIS COVERS THE CASE OF PRESERVING LINE
;	SPEED WHEN A LINE IS REMOTE ONLY AND LEAVING SPEED ALONE IF
;	A LINE IS AUTOSPEED AND NO DYNAMIC DATA EXISTS. WE SET THE SPEED
;	IN THE FRONT-END IN THE REMOTE CASE.
; (3) OTHER CASES ARE MO%AUT=1, SPEEDS ARE IGNORED IN THIS CASE.

	TXNE W1,MO%AUT		;IS MO%AUT ZERO?
	IFSKP.
	  TMNE TT%AUT+TT%FEM,TTSTAT(B) ;YES, IS LINE NOT REMOTE NOR AUTO?
	  IFSKP.
	    MOVEM D,TTSPWD(B)	;YES, SET SPEED
	    CALL STADYN		;(T2/T2) IS THERE DYNAMIC DATA?
	    ANSKP.		;IF NOT, PROCEED WITH SPEED SETTING
	    MOVEM D,TTSVPD(B)	;YES, SET SAVED SPEED
	    ENDIF.
				;HERE FOR OTHER CASES WHERE MO%AUT=0

	  MOVE B,LINENO		;GET LINENO BACK
	  CALL STADY		;IS THERE DYNAMIC DATA
	  ANSKP.		;NO, DON'T CHANGE SPEED OF AUTOSPEED LINE
	  MOVE B,LINENO		;GET LINENO BACK
	  MOVEM D,TTSPWD(B)	;SET SPEED
	  ENDIF.

	MOVE B,LINENO		;GET LINENO BACK
	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?
	JRST [	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
		SETONE TTFEM,(B) ;SAY IS REMOTE
		JRST .+1]	;GO SET SPEED ANYWAY
	TXNE W1,MO%AUT		;WANT "AUTO" SPEED?
	JRST [	MOVX D,SC%OPR!SC%WHL ;YES. SEE IF PRIVILEGED
		TDNN D,CAPENB	;IS IT?
		JRST TTSSP3	;NO. ERROR
		SETONE TTAUT,(B) ;SET INDICATOR
		TRO A,(1B3)	;SET BIT IN MESSAGE TO FE
		JRST TTSSP5]	;AND PROCEED
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

;TELL 20F TO ALLOW OR NOT ALLOW SENDALLS, BUT DON'T SAVE TTNTS
TTNTM1:	SKIPN FEFLG		;IN PRIMARY PROTOCOL?
	RET			;NO. IGNORE IT THEN
	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
	JE TTXFF,(B),R		;IF NOT FORCING STATUS TO FE, RETURN
	SETZRO TTXFF,(B)	;CLEAR THE BIT
	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
	JE TTXFF,(B),R		;IF NOT FORCING STATUS TO FE, RETURN
	SETZRO TTXFF,(B)	;CLEAR THE BIT
	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
	SKIPG TTACTL(B)		;LINE ACTIVE?
	JRST SNDXO3		;NO, SEND NOTHING
	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,[.DFBKW,,.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
	CONSO PI,77000		;SKIP NOSKED IF NOT AT PI LEVEL 7
	NOSKD1			;PREVENT SCHEDULER INTERRUPTION
	CHNOFF DLSCHN		;AND DTE INTERRUPTS
	LOAD A,TTFBB,(B)	;GET NUMBER CHARS IN TTBBUF
	SKIPG TTACTL(B)		;ACTIVE LINE?
	JRST SNDXN1		;NO, SEND NOTHING.
	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,[.DFBKW,,.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
	CONSO PI,77000		;SKIP OKSKED IF NOT AT PI LEVEL 7
	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.(INF,TTYSTP,TTYSRV,HARD,<TTYSRV - LINE HAS BEEN SHUT OFF BECAUSE OF EXCESSIVE INPUT RATE>,<<T2,LINE>>,<

Cause:	A terminal line on RSX20F is generating input at an excessive
	rate.  It is being shut off for 3 seconds by having its input
	speed set to 0.

Diagnosis: This can result from a noisy line which has a high input
	baud rate.  If an EIA line, it may be too long and so
	picks up electrical noise.  This problem can be prevented
	by eliminating the noise or reducing the input speed.

>)
	ENDIF.
	SETONE TTSHU,(B)	;NOTE LINE SHUT OFF
	MOVEI C,TTTOBL		;C/THE ROUTINE TO CALL
	MOVEI A,^D5000		;5 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
;NOISY LINE CHECK IN TTCHI.  CALLED WHEN CHARACTER TAKEN FROM BIGBUF
;FOR INACTIVE LINE THAT WILL ECHO BELL.
; T2/ LINE NUMBER

TTCHNL:	JN TTSHU,(T2),R		;DONE IF LINE ALREADY SHUT OFF
	LOAD T1,TTNOI,(T2)	;SEE IF NOISY LINE--NOISE CHARACTER COUNT
	CAIL T1,3		;ALREADY SAW 3?
	RET			;YES, ENOUGH ALREADY.
	ADDI T1,1		;BUMP NOISE COUNT
	STOR T1,TTNOI,(T2)
	CAIE T1,1		;FIRST ONE?
	RET			;NO
	MOVEI T1,^D1000		;YES, QUEUE A CHECK FOR ONE SECOND
	MOVEI T3,CKNOIS
	CALL TTQAD
	RET

;CHECK OF POSSIBLY NOISY LINE AFTER 1 SECOND
; T2/ LINE NUMBER

CKNOIS:	LOAD T1,TTNOI,(T2)	;SEE HOW MANY IN LAST SECOND
	CAILE T1,2		;MORE THAN 2?
	CALL STPLNF		;YES, SHUT OFF LINE
	SETZRO TTNOI,(T2)	;CLEAR COUNT, START FRESH
	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
	 JRST [	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
	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::EA.ENT
	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
	TDNN C,WRPMSK		;AT LAST WORD IN THIS BUFFER?
	JRST [	LDB A,[POINT 6,C,5] ;LOOK AT P,S FIELD OF BYTE POINTER
		CAIE A,73	;POINTING TO LAST BYTE?
		JRST .+1	;NO.
		HRRZ A,C	;YES. GET ADDRESS OF CURRENT WORD
		HRR C,1-TTSIZ(A) ;POINT TO NEXT BUFFER IN CHAIN
		JRST .+1]
	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 DTEQBP
	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?
	JRST [	LDB D,[POINT 6,C,5]
		CAIN D,73
		RET
		JRST .+1]
	ILDB D,C		;GET NEXT BYTE
	TRNE D,TTOESC		;ESCAPE CHARACTER?
	JRST [	MOVNI D,1
		ADJBP D,C
		MOVEM D,C
		RET]
;	JRST [	ADD C,[^D9B5]	;DECREMENT BYTE POINTER
;		TLNE C,(40B5)	;WENT INTO PREVIOUS WORD?
;		SUB C,[44B5+1]	;YES. CORRECT IT
;		RET]		;AND RETURN
	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::EA.ENT
	CALL GETLIN		;GET INTERNAL LINE NUMBER
	 RET			;INVALID
	TRNN C,(1B2)		;IS IT REMOTE?
	JRST TTSPS0		;NO, CHECK AUTO
	SETONE TTFEM,(B)	;YES, INDICATE REMOTE
TTSPS0:	TRNN C,(1B3)		;IS IT AUTO?
	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::EA.ENT
	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::EA.ENT
	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::EA.ENT
	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::EA.ENT
	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::	EA.ENT
	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.

;Convert byte pointer before calling DTEQ.

;	CALL DTEQBP

;ACCEPTS USUAL ARGUMENTS FOR DTEQ, WITH BYTE POINTER IN T4

;RETURNS +1: ALWAYS
;	T4/ CONVERTED BYTE POINTER

;ASSUMES BYTE POINTER IS ONE-WORD GLOBAL TO SECTION 0, WITH 9-BIT BYTE SIZE

DTEQBP:	ACVAR <W1>
	LDB W1,[POINT 6,T4,5]	;GET P,S FIELD
	SUBI W1,67		;NORMALIZE TO LOWEST VALUE
	CAILE W1,4		;CAN'T BE MORE THAN 4
	MOVEI W1,4		;SO FORCE IT
	HRL T4,OWG9(W1)		;MAKE A ONE-WORD LOCAL OUT OF IT
	RET
	ENDAV.			;END ACVAR

RSI OWG9,<441100,331100,221100,111100,001100>
;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::EA.ENT
	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
	CAIN T4,MSGLEN		;IS THIS A MESSAGE-LENGTH BLOCK?
	RET			;YES. NO MORE INITIALIZATION
	MOVE T3,TTSPWD(T2)	;GET SPEED WORD
	MOVEM T3,TTSVPD(T1)	;SAVE IN SAVED SPEED WORD
	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:	EA.ENT
	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::EA.ENT
	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.(INF,DLDEF,TTYSRV,HARD,<LOGICAL NAME DEFINE FAILED FOR FE CTY>,,<

Cause:	This BUG is not documented yet.

Action:

>)
	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

CKNOIS:
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:	CAME T3,CTYLNO
	JRST [	SKIPE DZLNCT	;IF NO DZ LINES MUST RETURN
		SKIPN FEFLG	;SECONDARY PROTOCOL?
		RET
		JRST DZPRNC]	;NOT CTY BUT PRIMARY PROTOCOL
	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
	CAMN T2,KLILNO		;KLINIK?
	JRST [	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
	CAMN T2,KLILNO		;KLINIK?
	JRST [	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.(HLT,DZCLRB,TTYSRV,hard,<UNABLE TO RESET DZ11>,,<

Cause:	This BUGHLT can only occur on the 2020.

	The DZCLR bit is written to the DZ to cause the DZ to clear.  Then
	the code loops, continually checking the DZCLR bit, waiting for
	it to come on, which signals that the DZ has cleared.

	The loop counts up to 2**18, under the assumption that this is
	ample time for the DZ to clear.  If the DZCLR bit does not come on
	after the 2**18 runs out, the DZCLRB BUGHLT occurs.
>) ]
	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.(CHK,DZLINT,TTYSRV,HARD,<DZ11 LOST INTERRUPT ENABLE>,<<T2,D>>,<

Cause:	This BUG is not documented yet.

Action:

Data:

>)
		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.(CHK,DZOVER,TTYSRV,HARD,<DZ11 SILO OVERRUN>,<<T1,D>>,<

Cause:	This BUG is not documented yet.

Action:

Data:

>)
	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?
	JRST [	MOVX T3,SC%OPR!SC%WHL	;CHECK CAPBILITIES
		TDNN T3,CAPENB
		JRST DZSSP1		;NO CAPABILITIES FORGET IT
		SETONE TTFEM,(T2)	;SET ONCE ONLY FLAG
		JRST .+1]
	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:
  >
   IFN KCFLG,<			;IF ON THE 2080

	SUBTTL RSP TERMINALS SUPPORT ROUTINES

;Post interrupt done. Called from RSP module
;	T2/ Line number

CLSTRI::CALL STADYN		;GET DYNAMIC DATA ADDRESS
	IFNSK. <JUMPLE T2,R>	;IF NO MORE TO DO, ALL DONE
;	CALLRET CLSTRO		;DO OUTPUT

;Routine to generate some output for an RSP line
;	T2/ Dynamic data address

CLSTRO:	CALL TTSND		;SEE IF WE HAVE ANY BYTES AT ALL
	 RET			;NO MORE
	SKIPE FEFLG		;IN PRIMARY OR SECONDARY?
	IFSKP.
	 DYNST T3		;GET LINE NUMBER
	 CAME T3,CTYLNO		;IS IT THE CTY?
	 RET			;NO. IGNORE
	 CALLRET CNBOUT		;YES. SEND IT
	ENDIF.
	SETONE TTOTP,(T2)	;WE DO. SAY ACTIVE
	MOVE T3,T1		;COPY FIRST BYTE
	DYNST T1		;GET LINE NUMBER FOR RSP
	CALL CNTTOR		;GET RSP LINE NUMBER
	BLCAL. (CNSEND,<T1,T2,<.,CLSTR0>>) ;DO IT
	RET			;AND DONE

;COROUTINE OF ABOVE. CALLED FROM RSP TO GET NEXT BYTE.
;	T2/ DYNAMIC DATA ADDRESS

CLSTR0:	SKIPE T1,T3		;ALREADY HAVE IT?
	IFNSK.
	 SETZM T3		;YES
	 RETSKP			;RETURN IT
	ENDIF.
	CALL TTSND		;NO. GET ONE
	IFNSK.
	 SETONE TTOTP,(T2)	;NO MORE. KEEP IT ACTIVE
	 RET			;AND DONE
	ENDIF.
	RETSKP			;RETURN THE BYTE
;Routine to handle assigning and deassigning of lines.

;Line being assigned.
;	T2/ dynamic data address

TTSETR:	SAVET			;SAVE ALL TEMPS
	DYNST T1		;GET INTERNAL NUMBER
	CALL CNTTOR		;GET RSP LINE NUMBER
	CALLRET CNLASS		;MAKE SURE ALL IS OK

;Line being deassinged.
;	T2/ dynamic data

RSPDET:	SAVET			;SAVE ALL TEMPS
	DYNST T1
	CALL CNTTOR
	CALLRET CNDEAS		;CHECK IT OUT


;Clear output buffer for a line
;	T2/ dynamic data

RPCOBF:	SAVET			;SAVE ALL TEMPS
	DYNST T1		;GET LINE NUMBER
	CALL CNTTOR		;GET RSP LINE
	CALLRET CNCOBF		;DO IT.
;Enable/disable XON/XOFF for a console line

;	T2/ DYNAMIC DATA

RSPEXF: SAVET			;SAVE ALL T'S
	DYNST T1		;GET LINE NUMBER
	CALL CNTTOR		;GET RSP LINE NUMBER
	TMNN TT%PGM,TTFLGS(T2)	;IS IT ON OR OFF
	TDZA T2,T2		;OFF
	MOVEI T2,1		;ON
	CALLRET CNXONF		;DO IT

   >	;IFN KCFLG

;END OF ALL TTYSRV MODULES

	TNXEND
	END