Google
 

Trailing-Edge - PDP-10 Archives - bb-m780a-sm - monitor-sources/ttysrv.mac
There are 50 other files named ttysrv.mac in the archive. Click here to see a list.
; UPD ID= 578, SNARK:<5.MONITOR>TTYSRV.MAC.73,  15-Apr-82 22:51:51 by PAETZOLD
;More TCO 5.1772 - Take out the AC reference of the JRST in TCOU6
; UPD ID= 570, SNARK:<5.MONITOR>TTYSRV.MAC.72,   6-Apr-82 15:44:41 by PAETZOLD
;TCO 5.1772 - Handle short blocks in TCOU6 and TCOU7
; UPD ID= 556, SNARK:<5.MONITOR>TTYSRV.MAC.71,  21-Mar-82 03:49:47 by PAETZOLD
;TCO 5.1767 - Make SALLI2 use LCKTT and ULKTT
; UPD ID= 494, SNARK:<5.MONITOR>TTYSRV.MAC.70,   3-Mar-82 01:24:11 by PAETZOLD
;More TCO 5.1691 - Make it better
; UPD ID= 450, SNARK:<5.MONITOR>TTYSRV.MAC.69,  29-Jan-82 15:55:06 by MILLER
;TCO 5.1678. FIX CODE AT TTYASO, TTYASC AND TTSETL TO HANDLE TTACTL BETTER
; UPD ID= 424, SNARK:<5.MONITOR>TTYSRV.MAC.68,  20-Jan-82 09:19:55 by PAETZOLD
;TCO 5.1691 - prevent Q1 and Q2 trashing in TTYQOC
; UPD ID= 417, SNARK:<5.MONITOR>TTYSRV.MAC.67,  19-Jan-82 12:05:45 by MURPHY
;TCO 5.1688 - report noisy line only once.
; UPD ID= 308, SNARK:<6.MONITOR>TTYSRV.MAC.66,  16-Jan-82 17:37:49 by MILLER
;TCO 5.1678. Add NOSKED to TTYDEA
; UPD ID= 397, SNARK:<5.MONITOR>TTYSRV.MAC.65,  14-Jan-82 04:19:21 by PAETZOLD
;More TCO 5.1665 - Fix problems with previous edit
; UPD ID= 392, SNARK:<5.MONITOR>TTYSRV.MAC.64,  12-Jan-82 21:33:19 by PAETZOLD
;TCO 5.1665 - Generate TTLOKB BUGHLT when TTLCK overdecrement detected
; detected in LCKTT, ULKTTY, and ULKTT
; UPD ID= 380, SNARK:<5.MONITOR>TTYSRV.MAC.63,   6-Jan-82 14:47:35 by PAETZOLD
;TCO 5.1655 - preserve C around the TDCALL in TTMS20
; UPD ID= 357, SNARK:<5.MONITOR>TTYSRV.MAC.62,  11-Dec-81 13:59:59 by PAETZOLD
;TCO 5.1635 - make sure we are NOINT at all times in STPAR even when we have to
;negotiate TELNET protocol options
; UPD ID= 338, SNARK:<5.MONITOR>TTYSRV.MAC.61,   3-Dec-81 10:46:24 by MURPHY
;TCO 5.1625 - Create job on CR and LF as well as ^C.
; UPD ID= 185, SNARK:<5.MONITOR>TTYSRV.MAC.60,  16-Sep-81 13:57:38 by MURPHY
;ditto
; UPD ID= 173, SNARK:<5.MONITOR>TTYSRV.MAC.59,  14-Sep-81 15:09:08 by MURPHY
;TCO 5.1507 - Allow TTMSG to single line by unpriv user.
; UPD ID= 118, SNARK:<5.MONITOR>TTYSRV.MAC.58,  24-Aug-81 15:12:49 by GRANT
;Change NLINES to NLINES-1 in TTDTPS for searching all TTY blocks
; UPD ID= 58, SNARK:<5.MONITOR>TTYSRV.MAC.57,  21-Jul-81 16:44:23 by GRANT
;TCO 5.1375 - Create ATACTT routine to be used by ATACH JSYS
; UPD ID= 42, SNARK:<5.MONITOR>TTYSRV.MAC.56,  17-Jul-81 16:12:17 by MURPHY
;REJECT SETTING OF ^S AS UNPAUSE CHARACTER (5.1390)
; UPD ID= 2306, SNARK:<5.MONITOR>TTYSRV.MAC.55,   8-Jul-81 11:18:42 by MURPHY
;MCB DEBUG CODE; CALL REQNS INSTEAD OF TNUSND
; UPD ID= 2296, SNARK:<5.MONITOR>TTYSRV.MAC.54,   6-Jul-81 13:51:21 by MURPHY
;MAKE TTYDE0 RESIDENT BECAUSE CALLED FROM SCHED (NVT SERVICE) NOW
; UPD ID= 2288, SNARK:<5.MONITOR>TTYSRV.MAC.53,   2-Jul-81 11:51:20 by PAETZOLD
;TCO 5.1392 - Make TTFLG1 and TT%SAL globals so IMPDV can use them
; UPD ID= 2189, SNARK:<5.MONITOR>TTYSRV.MAC.52,  11-Jun-81 15:58:32 by MURPHY
;CHANGE TQNx TO TMNx REFLECTING CHANGE IN MACSYM
; UPD ID= 2153, SNARK:<5.MONITOR>TTYSRV.MAC.51,   8-Jun-81 17:39:47 by MURPHY
;FIX BUG IN XON/XOFF; ADD TTYDEX ENTRY POINT
; UPD ID= 2091, SNARK:<5.MONITOR>TTYSRV.MAC.50,  27-May-81 16:09:50 by PAETZOLD
;More TCO 5.1349...make sure not nosked when we get to NVTCOB...IMPINS
;may block and cause an NSKDIS
; UPD ID= 2085, SNARK:<5.MONITOR>TTYSRV.MAC.49,  27-May-81 08:37:10 by PAETZOLD
;TCO 5.1349 Make sure SYNch gets sent for arpa NVT's when clearing output buffer
; UPD ID= 2073, SNARK:<5.MONITOR>TTYSRV.MAC.48,  25-May-81 11:32:56 by ZIMA
;TCO 5.1348 - Fix STPAR for noop conditions as documented.
; UPD ID= 2060, SNARK:<5.MONITOR>TTYSRV.MAC.47,  21-May-81 22:50:22 by ZIMA
;TCO 5.1342 - handle case of refusing links and all links are full.
; UPD ID= 2053, SNARK:<5.MONITOR>TTYSRV.MAC.46,  20-May-81 17:47:49 by MURPHY
;BE SURE TTPRM CLEARED AFTER SETHOST LINK CLOSED
; UPD ID= 2046, SNARK:<5.MONITOR>TTYSRV.MAC.45,  20-May-81 11:59:18 by MURPHY
;USER SETTABLE CHARACTERS FOR PAGE PAUSE AND UNPAUSE
;REMOVE TSALP AGAIN, MISC ^O CLEANUP
;<5.MONITOR>TTYSRV.MAC.42, 27-Apr-81 09:49:56, EDIT BY GRANT
;Double colons needed on TTPPCS and TTPPCR
; UPD ID= 1874, SNARK:<5.MONITOR>TTYSRV.MAC.40,  23-Apr-81 11:38:32 by HALL
;RESTORE TSALP DEFINITION THAT DAN REMOVED
; UPD ID= 1866, SNARK:<5.MONITOR>TTYSRV.MAC.37,  21-Apr-81 23:41:44 by MURPHY
;DITTO
; UPD ID= 1864, SNARK:<5.MONITOR>TTYSRV.MAC.36,  21-Apr-81 18:29:26 by MURPHY
;More fiddling with end-of-page
; UPD ID= 1829, SNARK:<5.MONITOR>TTYSRV.MAC.34,  17-Apr-81 14:19:17 by MURPHY
;Get sendall bfr from res free stg
;Different handling of control-O for speed.
; UPD ID= 1744, SNARK:<5.MONITOR>TTYSRV.MAC.33,  19-Mar-81 23:10:56 by MURPHY
;Fix problem with line turn-off and XOFF/XON logic.
; UPD ID= 1549, SNARK:<5.MONITOR>TTYSRV.MAC.32,  10-Feb-81 17:57:36 by MURPHY
;FIX XOFF DURING SYSTEM STARTUP PROBLEM
; UPD ID= 1490, SNARK:<5.MONITOR>TTYSRV.MAC.31,  26-Jan-81 10:58:14 by MURPHY
;FIX BUG(TTQADX)
; UPD ID= 1478, SNARK:<5.MONITOR>TTYSRV.MAC.30,  22-Jan-81 12:24:18 by MURPHY
;MAKE SPACE CONTINUE AFTER PAUSE ON END-OF-PAGE
;FIX TTQAD
;<5.MONITOR>TTYSRV.MAC.29, 17-Dec-80 15:27:57, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.28, 16-Dec-80 15:00:43, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.27, 12-Dec-80 10:36:56, EDIT BY MURPHY
;FLOW CONTROL CHANGE IN MCB NVT
;<5.MONITOR>TTYSRV.MAC.26,  9-Dec-80 15:08:18, EDIT BY MURPHY
;PREVENT HUNG LINES ON LOGOUT
;<5.MONITOR>TTYSRV.MAC.25, 21-Nov-80 14:57:22, EDIT BY MURPHY
; UPD ID= 1300, SNARK:<5.MONITOR>TTYSRV.MAC.24,  19-Nov-80 17:05:25 by MURPHY
;XON/XOFF OPTION FOR MCB NVT
; UPD ID= 1289, SNARK:<5.MONITOR>TTYSRV.MAC.23,  18-Nov-80 16:45:12 by MURPHY
;TIMEOUT ON TTMSG (SEND ALL)
;<5.MONITOR>TTYSRV.MAC.22, 20-Oct-80 14:46:43, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.21, 10-Oct-80 14:41:44, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.20,  8-Oct-80 15:13:22, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.19,  8-Oct-80 14:26:52, EDIT BY MURPHY
;<5.MONITOR>TTYSRV.MAC.18,  6-Oct-80 16:00:01, EDIT BY MURPHY
;FIX TTOMX, TTOCN DEFINITIONS
;<5.MONITOR>TTYSRV.MAC.17,  6-Oct-80 11:38:16, EDIT BY MURPHY
; UPD ID= 1125, SNARK:<5.MONITOR>TTYSRV.MAC.16,   5-Oct-80 15:02:35 by MURPHY
;DITTO
;<5.MONITOR>TTYSRV.MAC.15,  3-Oct-80 14:03:25, EDIT BY MURPHY
; UPD ID= 1112, SNARK:<5.MONITOR>TTYSRV.MAC.14,   3-Oct-80 01:00:42 by MURPHY
;NVT IMPROVEMENTS
; UPD ID= 1101, SNARK:<5.MONITOR>TTYSRV.MAC.13,   2-Oct-80 09:19:24 by MURPHY
;DITTO
; UPD ID= 1078, SNARK:<5.MONITOR>TTYSRV.MAC.12,   1-Oct-80 10:38:13 by MURPHY
;ADD APPROPRIATE ENDXX STATEMENTS FOR ACVAR, STKVAR, ETC.
; UPD ID= 1062, SNARK:<5.MONITOR>TTYSRV.MAC.11,  30-Sep-80 10:16:42 by MURPHY
;NVT bugs
;Change numeric ACs 5-7 to Q1,Q2,FX
; UPD ID= 991, SNARK:<5.MONITOR>TTYSRV.MAC.10,   5-Sep-80 15:57:46 by LYONS
;Fix detach job on a carrier off message from FE
; UPD ID= 924, SNARK:<5.MONITOR>TTYSRV.MAC.9,  20-Aug-80 10:21:02 by MURPHY
;Install NVTs and network user terminal state
; UPD ID= 691, SNARK:<5.MONITOR>TTYSRV.MAC.6,  24-Jun-80 20:49:47 by MURPHY
;CHANGE LINE TYPE VECTORING
;Dispatch using line type as index rather than using function as index.
; UPD ID= 649, SNARK:<5.MONITOR>TTYSRV.MAC.5,  16-Jun-80 12:11:48 by MURPHY
;CLEAN UP VECTOR COMMENTS
;<5.MONITOR>TTYSRV.MAC.4, 21-May-80 11:25:56, EDIT BY MURPHY
;FIX LISTING FORMAT
; UPD ID= 541, SNARK:<5.MONITOR>TTYSRV.MAC.3,  20-May-80 16:08:42 by OSMAN
;MORE 4.1.1142 - Make SIBE count RSCAN characters if terminal is caller's
;controlling terminal
;ALSO, make BKJFN back up RSCAN string if in use and we're reading from
;fork's controlling terminal
; UPD ID= 404, SNARK:<5.MONITOR>TTYSRV.MAC.2,   3-Apr-80 16:04:56 by HALL
;CHANGES TO WRITE-PROTECT THE RESIDENT MONITOR:
;	CHANGE TT1LIN TO BE A RESIDENT TABLE INSTEAD OF OFFSET IN
;		TRANSFER VECTOR
;	CHANGE ALL CODE THAT USES TT1LIN
;	MAKE TTINIT INITIALIZE TT1LIN FOR DC10 LINES
; UPD ID= 318, SNARK:<4.1.MONITOR>TTYSRV.MAC.164,  11-Mar-80 15:36:34 by MILLER
;TCO 4.1.1021 AGAIN. PRESERVE T2 IN WTALL
; UPD ID= 290, SNARK:<4.1.MONITOR>TTYSRV.MAC.163,  21-Feb-80 10:59:14 by MURPHY
;NEW FKINT DEFS
; UPD ID= 184, SNARK:<4.1.MONITOR>TTYSRV.MAC.162,   3-Jan-80 15:23:43 by SCHMITT
; more tco 4.1.1048
; UPD ID= 113, SNARK:<4.1.MONITOR>TTYSRV.MAC.161,   7-Dec-79 17:08:52 by KONEN
;TCO 4.2592 -- Make sure TTCON1 does RET to avoid ILLUUO
; UPD ID= 97, SNARK:<4.1.MONITOR>TTYSRV.MAC.160,   5-Dec-79 14:06:15 by SCHMITT
; TCO 4.1.1048 - Only simulate <LF> in buffer in <CR> input in non-binary
; UPD ID= 48, SNARK:<4.1.MONITOR>TTYSRV.MAC.159,  28-Nov-79 18:02:09 by MILLER
;CHANGE TESTS ON TOWRN TO PREVENT INFINITE LOOPS
; UPD ID= 11, SNARK:<4.1.MONITOR>TTYSRV.MAC.158,  21-Nov-79 18:20:21 by MURPHY
;<4.1.MONITOR>TTYSRV.MAC.157, 16-Nov-79 13:47:19, EDIT BY MILLER
;PREVIOUS CHANGES UNDER TCO 4.1.1021
;<4.1.MONITOR>TTYSRV.MAC.156, 16-Nov-79 13:44:30, EDIT BY MILLER
;CHANGE ASGALL WAIT TIME TO 30 SECS
;<4.1.MONITOR>TTYSRV.MAC.155, 16-Nov-79 12:53:01, EDIT BY MILLER
;<4.1.MONITOR>TTYSRV.MAC.154, 16-Nov-79 12:42:58, EDIT BY MILLER
;<4.1.MONITOR>TTYSRV.MAC.153, 16-Nov-79 11:28:50, EDIT BY MILLER
;ALLOW TTMSG TO TIME OUT
;<4.1.MONITOR>TTYSRV.MAC.152,  5-Nov-79 13:38:42, EDIT BY MURPHY
;FIX TTYQO2
;<4.MONITOR>TTYSRV.MAC.151,  2-Nov-79 16:57:05, EDIT BY MURPHY
;PTY OUTPUT START LOGIC
;<4.MONITOR>TTYSRV.MAC.149, 31-Oct-79 12:39:38, EDIT BY MILLER
;MOVE DEF OF TTFPK TO STATIC DATA
;<4.MONITOR>TTYSRV.MAC.148, 28-Oct-79 09:12:06, EDIT BY R.ACE
;FIX SPELLING OF ULKTTY IN TTSSPD ROUTINE
;<4.MONITOR>TTYSRV.MAC.147, 26-Oct-79 15:13:46, EDIT BY ZIMA
;TCO 4.2557 - Change calling sequence to TTSSPD to provide error
; return for ACJ rejection.  Now nonskip on error, skip on "success".
;<4.MONITOR>TTYSRV.MAC.146, 25-Oct-79 13:53:40, EDIT BY ENGEL
;TURN OFF ECHOING ON FULL DUPLEX LINES LINKED TO HALF-DUPLEX ONES
;<4.MONITOR>TTYSRV.MAC.145, 25-Oct-79 10:17:26, EDIT BY MURPHY
;FASTER WAKEUP ON OUTPUT EVENTS
;<4.MONITOR>TTYSRV.MAC.142, 10-Oct-79 13:47:32, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.141,  6-Oct-79 12:49:05, EDIT BY HALL
;FIX MURPHY'S '20.' TO BE '^D20'
;<4.MONITOR>TTYSRV.MAC.140,  5-Oct-79 16:57:37, EDIT BY MURPHY
;FIX XOFF/XON PROBLEMS
;<4.MONITOR>TTYSRV.MAC.139,  3-Oct-79 15:28:01, EDIT BY HALL
;TTCHI - RETURN SUCCESS IF WAKING PROCESS FOR BINARY LINE
;<4.MONITOR>TTYSRV.MAC.138,  1-Oct-79 14:25:35, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.137, 28-Sep-79 18:34:48, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.136, 28-Sep-79 18:25:10, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.135, 28-Sep-79 18:17:17, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.134, 28-Sep-79 17:34:04, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.133, 25-Sep-79 13:37:58, EDIT BY HELLIWELL
;<4.MONITOR>TTYSRV.MAC.132, 25-Sep-79 12:44:13, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.131, 25-Sep-79 11:43:26, EDIT BY HELLIWELL
;TCO #4.2486 - FIX .MOTPS FUNCTION OF MTOPR
;<4.MONITOR>TTYSRV.MAC.130, 24-Sep-79 14:10:24, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.129, 21-Sep-79 13:32:00, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.128, 20-Sep-79 16:20:51, EDIT BY MURPHY
;SUCCESS/FAILURE RETURNS FOR TTSTI
;<4.MONITOR>TTYSRV.MAC.126, 20-Sep-79 14:20:45, EDIT BY MURPHY
;CHANGE FORMAT OF DEVICE DISPATCH MACRO
;<4.MONITOR>TTYSRV.MAC.125, 19-Sep-79 14:54:32, EDIT BY MURPHY
;NEW SYMBOLS WITH MNEMONIC SIGNIFICANCE FOR LINE TYPE VECTOR OFFSETS
;<OSMAN.MON>TTYSRV.MAC.1, 10-Sep-79 16:16:34, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>TTYSRV.MAC.123, 23-Aug-79 12:42:26, Edit by LCAMPBELL
; Don't attempt sendall to inactive NVTs
;<4.MONITOR>TTYSRV.MAC.122, 16-Aug-79 14:43:33, EDIT BY TOMCZAK
;TTSET1 - TCO#4.2407 - Default to REFUSE LINKS when assigning CTY
;<4.MONITOR>TTYSRV.MAC.121, 21-May-79 12:58:35, EDIT BY HALL
;TTYDE0 - FIX INSTRUCTION REFERENCING TTFLGS
;<4.MONITOR>TTYSRV.MAC.120, 17-May-79 20:48:19, Edit by HESS
;FIX EDIT 118 (FORGOT COMMA)
;<4.MONITOR>TTYSRV.MAC.119, 15-May-79 09:39:49, Edit by MCLEAN
;REMOVE EXTRANEOUS INSTRUCTION AT TTCH10-5
;<4.MONITOR>TTYSRV.MAC.118, 12-May-79 13:49:46, EDIT BY MILLER
;FIX CODE AT TTYDE0
;<4.MONITOR>TTYSRV.MAC.117, 12-May-79 12:54:55, EDIT BY MILLER
;ADD TTGSTS FOR GETTING GDSTS BITS
;<4.MONITOR>TTYSRV.MAC.116, 11-May-79 14:34:07, EDIT BY MILLER
;<4.MONITOR>TTYSRV.MAC.115, 10-May-79 12:32:47, EDIT BY MILLER
;<4.MONITOR>TTYSRV.MAC.114, 30-Apr-79 22:51:23, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.113, 12-Apr-79 16:57:15, Edit by MCLEAN
;MORE XOFF FIXES SO WE WAKEUP BEFORE DOING XOFF
;<4.MONITOR>TTYSRV.MAC.112,  5-Apr-79 11:28:31, Edit by MCLEAN
;REMOVE 1ST ARG FROM GTOKM
;<4.MONITOR>TTYSRV.MAC.111, 11-Mar-79 13:19:49, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>TTYSRV.MAC.110,  7-Mar-79 14:06:14, Edit by MCLEAN
;FIX SALLI2 FOR BECOMMING ACTIVE AND BEING NOSKED ON RETURN
;<4.MONITOR>TTYSRV.MAC.109, 21-Feb-79 13:48:07, Edit by MCLEAN
;MAKE NON TERMINAL PSI'S DISABLEABLE BY -1 IN PSI
;<4.MONITOR>TTYSRV.MAC.108, 19-Feb-79 18:54:53, EDIT BY DBELL
;ADD MISSING INSTRUCTION AT TL22+11
;<4.MONITOR>TTYSRV.MAC.107, 15-Feb-79 13:43:54, EDIT BY DBELL
;FINISH TCO 4.2185
;<4.MONITOR>TTYSRV.MAC.106, 12-Feb-79 15:47:29, EDIT BY DBELL
;MAKE TCO 4.2185 BETTER BY SUPPRESSING LINK MESSAGE WHEN LINKING RANDOMLY
;<4.MONITOR>TTYSRV.MAC.105, 10-Feb-79 17:22:27, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.104, 10-Feb-79 17:17:33, Edit by MCLEAN
;ADD NEW XOFF CODE FOR FRONT-END
;<4.MONITOR>TTYSRV.MAC.102,  8-Feb-79 14:57:43, EDIT BY DBELL
;TCO 4.2185 - ALLOW ANY TERMINAL TO BE OBJECT FOR TLINK
;<4.MONITOR>TTYSRV.MAC.101,  2-Feb-79 23:38:41, Edit by MCLEAN
;ADD NEW VECTOR VSFEXO FOR XOFF RECOGNITION IN FRONT-END
;<4.MONITOR>TTYSRV.MAC.100, 31-Jan-79 12:23:58, Edit by MCLEAN
;REMOVE PREVIOUS EDIT
;<4.MONITOR>TTYSRV.MAC.99, 30-Jan-79 23:41:53, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.98, 21-Jan-79 20:11:10, Edit by MCLEAN
;MORE XON/XOFF ADJUSTMENTS
;<4.MONITOR>TTYSRV.MAC.97, 21-Jan-79 17:58:36, Edit by MCLEAN
;MORE XON/XOFF FIXES
;<4.MONITOR>TTYSRV.MAC.96, 19-Jan-79 18:09:05, Edit by MCLEAN
;FIX TTLNK3+1 TO SAVE T2
;<4.MONITOR>TTYSRV.MAC.95, 19-Jan-79 13:02:35, Edit by MCLEAN
;FIX TTCH12 TO HAVE STATIC NOT DYNAMIC ADDRESS
;<4.MONITOR>TTYSRV.MAC.94, 18-Jan-79 19:20:37, EDIT BY MILLER
;FIX TTXSET TO ALWAYS CLEAR XOFF NOW IN PROGRESS
;<4.MONITOR>TTYSRV.MAC.93, 18-Jan-79 18:23:06, Edit by MCLEAN
;FIX CONSO PI AT TTRLBF
;<4.MONITOR>TTYSRV.MAC.92, 17-Jan-79 11:37:06, EDIT BY HALL
;SUPPRESS SYMBOL FOR MSGLEN
;<4.MONITOR>TTYSRV.MAC.91, 14-Jan-79 15:07:15, Edit by MCLEAN
;MANY SPEEDUPS AND CLEANUPS
;<4.MONITOR>TTYSRV.MAC.89, 14-Jan-79 01:00:14, Edit by MCLEAN
;REMOVE JE TTSFG AT TTXON
;<4.MONITOR>TTYSRV.MAC.88, 11-Jan-79 19:59:17, Edit by MCLEAN
;FIX SENDXOFF ONCE MORE AT TTCHI9
;<4.MONITOR>TTYSRV.MAC.87,  9-Jan-79 18:10:55, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.86,  8-Jan-79 16:19:06, EDIT BY HALL
;AESTHETICS
;<4.MONITOR>TTYSRV.MAC.85,  7-Jan-79 19:50:31, Edit by MCLEAN
;XON/XOFF CUTOFF FIXES
;<4.MONITOR>TTYSRV.MAC.83,  5-Jan-79 09:55:46, EDIT BY ENGEL
; MAKE CHKPTY RESIDENT
;<4.MONITOR>TTYSRV.MAC.82, 28-Dec-78 22:44:26, Edit by MCLEAN
;ADD VSTPLN	;STOP LINE

;<4.MONITOR>TTYSRV.MAC.81, 28-Dec-78 16:26:53, Edit by MCLEAN
;FIX PSI FOR NON-TERMINAL INTERRUPTS
;<4.MONITOR>TTYSRV.MAC.80, 27-Dec-78 15:58:42, Edit by MCLEAN
;MAKE TTSTY 3 BITS AND GET CORRECT DEFSTR FOR TTXCN
;<4.MONITOR>TTYSRV.MAC.79, 24-Dec-78 16:28:34, EDIT BY DBELL
;MAKE ALL TTVTNN DEFINITIONS BE SUPPRESSED TO DDT
;<4.MONITOR>TTYSRV.MAC.78, 21-Dec-78 16:43:32, Edit by MCLEAN
;TEMP FIX AT TTCH22+3 TO FIX LOST INPUT EMPTY BUFFER INTERRUPTS
;<4.MONITOR>TTYSRV.MAC.77, 19-Dec-78 15:22:16, EDIT BY MURPHY
;ADD BLOCK PRIORITY ARG TO SCHED CALLS FOR TCITST, TCOTST, TTOBET
;<4.MONITOR>TTYSRV.MAC.76, 16-Dec-78 21:35:04, EDIT BY ZIMA
;TCO 4.2123 - FIX TERMINAL RAISE
;<4.MONITOR>TTYSRV.MAC.75, 11-Dec-78 23:01:42, Edit by MCLEAN
;ADD EXTRA BUFFERING FOR HIGH SPEED TERMINALS WHEN NECESSARY
;ADD NON-CONTROLLING TERMINAL PSI INTERRUPTS
;<4.MONITOR>TTYSRV.MAC.73, 13-Nov-78 21:53:47, Edit by MCLEAN
;FIX TTYDEA SO IT IS CHANNEL OFF WHILE DOING DE-ASSIGNMENTS
;<4.MONITOR>TTYSRV.MAC.72, 11-Nov-78 18:27:40, Edit by MCLEAN
;FIX TTRLB1 SO CHANNEL IS NOT TURNED ON IF CALLER HAS IT OFF
;<4.MONITOR>TTYSRV.MAC.71, 28-Oct-78 12:31:13, EDIT BY MILLER
;ADD TTYAO4
;<4.MONITOR>TTYSRV.MAC.70, 27-Oct-78 15:23:41, Edit by MCLEAN
;RANDOM SPEEDUPS
;<4.MONITOR>TTYSRV.MAC.69, 27-Oct-78 15:11:12, Edit by MCLEAN
;MAKE DYNAMIC BLOCK CORRECT SIZE FOR NEW BINARY OUTPUT BUFFER ADDRESS
;<4.MONITOR>TTYSRV.MAC.68, 25-Oct-78 23:08:00, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.67, 25-Oct-78 14:29:00, Edit by MCLEAN
;CHANGE ALL THE PARAMETERS AS TO WHEN XOFF AND XON GET DONE.
;<2MCLEAN>TTYSRV.MAC.78, 18-Oct-78 23:11:00, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.77, 18-Oct-78 22:53:09, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.76, 13-Oct-78 16:13:25, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.75, 11-Oct-78 13:34:12, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.74, 10-Oct-78 23:34:51, Edit by MCLEAN
;MOVE TLTYP TO TTSAL1 SO HRRZ CAN BE USED IN FNXXX MACROS
;IT IS MUCH FASTER THAN A LDB INSTRUCTION...
;<2MCLEAN>TTYSRV.MAC.73,  8-Oct-78 21:56:38, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.72,  8-Oct-78 21:45:07, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.71,  8-Oct-78 21:29:24, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.70,  8-Oct-78 14:32:28, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.69,  7-Oct-78 22:24:08, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.68,  6-Oct-78 16:28:51, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.67,  5-Oct-78 23:34:01, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.66,  5-Oct-78 22:59:28, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.65,  3-Oct-78 23:43:15, Edit by MCLEAN
;<2MCLEAN>TTYSRV.MAC.64,  3-Oct-78 23:31:25, Edit by MCLEAN
;SPEEDUPS FOR OUTPUT
;<4.MONITOR>TTYSRV.MAC.65, 18-Oct-78 14:28:09, EDIT BY MURPHY
;PUT FF HANDLING MOSTLY BACK LIKE IT WAS
;<4.MONITOR>TTYSRV.MAC.64,  6-Oct-78 14:05:37, EDIT BY MILLER
;TCO 4.2034. DON'T DETACH CTY ON POWER-FAIL RECOVERY
;<4.MONITOR>TTYSRV.MAC.63,  7-Sep-78 18:02:01, Edit by LCAMPBELL
; Create new flavor of TTYSRV, TTYASM (2020T)
;<4.MONITOR>TTYSRV.MAC.62,  5-Sep-78 16:56:25, EDIT BY MURPHY
;RESET TPGPS ON INDICATED ^L
;<4.MONITOR>TTYSRV.MAC.61, 29-Aug-78 12:10:35, EDIT BY MILLER
;DON'T INIT TT%PGM ON IF LINE IS A PTY
;<4.MONITOR>TTYSRV.MAC.60, 22-Aug-78 12:58:55, EDIT BY JBORCHEK
;REMOVE SEARCH OF IMPPAR NOW IN TTNTDV
;<4.MONITOR>TTYSRV.MAC.59, 22-Aug-78 08:25:59, EDIT BY MILLER
;SWAP MEANINGS OF TT%PGM AND TTNXO. FIX UP HANDLING OF LINE COUUNTER
;<4.MONITOR>TTYSRV.MAC.58, 17-Aug-78 13:39:50, EDIT BY ENGEL
;FIX TTSFW (JUMPLE NEEDED A T1,)
;<4.MONITOR>TTYSRV.MAC.57, 15-Aug-78 10:46:26, Edit by ENGEL
;MAKE TTWAKE WAKE ONLY SEE LF AND NEVER CR
;<OSMAN>TTYSRV.MAC.1, 10-Aug-78 16:13:14, EDIT BY OSMAN
;ADD TTLINE, TTLMAX, CODE FOR .MORLC, .MOSLC, .MORLM, .MOSLM
;<4.MONITOR>TTYSRV.MAC.55, 27-Jul-78 09:13:52, EDIT BY MILLER
;CHECK TTXNO AT TTXOFF
;<4.MONITOR>TTYSRV.MAC.54, 27-Jul-78 07:48:39, EDIT BY MILLER
;FIX TTIDON CODE
;<4.MONITOR>TTYSRV.MAC.53, 26-Jul-78 18:43:57, EDIT BY MILLER
;ADD TTRXOB
;<4.MONITOR>TTYSRV.MAC.52, 24-Jul-78 10:51:57, Edit by ENGEL
;FIX TYPEOS AT TTSW1-1
;<4.MONITOR>TTYSRV.MAC.51, 23-Jul-78 14:50:55, EDIT BY MILLER
;FIX SOME TYPEOS
;<4.MONITOR>TTYSRV.MAC.50, 23-Jul-78 14:38:28, EDIT BY MILLER
;TCO 1951. ADD MTOPR SUPPORT CODE. ADD TTNXO BIT.
;<4.MONITOR>TTYSRV.MAC.49, 21-Jul-78 16:13:11, Edit by ENGEL
;FIX HORIZONTAL TAB PROBLEM FOR WAKE-UP CLASSES
;<4.MONITOR>TTYSRV.MAC.48, 21-Jul-78 13:58:24, Edit by ENGEL
;FIX TT%IGN BEING RETURNED ON RFMOD
;<4.MONITOR>TTYSRV.MAC.47, 18-Jul-78 16:25:29, EDIT BY MILLER
;CHECK FOR XON AND XOFF AS WITH OR WITHOUT PARITY
;<4.MONITOR>TTYSRV.MAC.46, 16-Jul-78 23:21:56, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.45, 16-Jul-78 22:47:52, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.44, 16-Jul-78 22:47:09, Edit by MCLEAN
;ADD GETOK FOR SETTING TERMINAL SPEEDS
;<3A.MONITOR>TTYSRV.MAC.43,  7-Jul-78 12:57:23, EDIT BY MILLER
;FIX TL12 TO RESTORE 5 ON FAILURE FROM CALL TO TL1C
;<2MCLEAN>TTYSRV.MAC.42, 28-Jun-78 01:13:28, Edit by MCLEAN
;FIX XOFF SO IT WILL OCCUR IMMEDIATELY
;<4.MONITOR>TTYSRV.MAC.41, 22-Jun-78 09:07:29, EDIT BY MILLER
;TCO 1924. SET TT%PGM IN STTYP JSYS IF APPROPRIATE
;<4.MONITOR>TTYSRV.MAC.40, 19-Jun-78 16:55:00, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.39, 17-Jun-78 12:32:59, Edit by DBELL
;RANGE CHECK TERMINAL NUMBER IN TTMSG
;<3A.MONITOR>TTYSRV.MAC.42, 16-Jun-78 16:52:21, EDIT BY MILLER
;FIX BUG IN TCOU7 AFTER CALL TO ASGMSL
;<3A.MONITOR>TTYSRV.MAC.41, 15-Jun-78 11:56:21, EDIT BY MILLER
;ADD NOSKD1 AND OKSKD1 TO STRTOU
;<3A.MONITOR>TTYSRV.MAC.40, 14-Jun-78 13:53:11, EDIT BY MILLER
;PUT TTRLOB BACK AT TTYDEA. ADD CALL TO TTXON
;<4.MONITOR>TTYSRV.MAC.35,  9-Jun-78 14:16:10, EDIT BY MILLER
;PUT IN SAVELN AT TTEMES SO LINE NUMBER IS PRESERVED
;<4.MONITOR>TTYSRV.MAC.34,  9-Jun-78 11:11:09, EDIT BY MURPHY
;<3A.MONITOR>TTYSRV.MAC.37,  8-Jun-78 17:26:26, EDIT BY MURPHY
;TCO #1894 - QUEUE OF LINES TO START OUTPUT
;<4.MONITOR>TTYSRV.MAC.32,  6-Jun-78 01:33:58, Edit by JBORCHEK
;ADD SEARCH OF IMPPAR
;<3A.MONITOR>TTYSRV.MAC.36, 29-May-78 13:38:47, EDIT BY MILLER
;CALL TTCBF2 FROM TTYDEA INSTEAD OF CALL TTRLOB
;<4.MONITOR>TTYSRV.MAC.30, 18-May-78 13:40:02, EDIT BY MURPHY
;TCO #1911 - WAKEUP ALWAYS ON CR ON PTY
;<4.MONITOR>TTYSRV.MAC.29,  3-May-78 08:35:46, EDIT BY MILLER
;MORE FIX UPS TO TLINK
;<3A.MONITOR>TTYSRV.MAC.34,  3-May-78 08:33:03, EDIT BY MILLER
;FIX TLINK JSYS NEVER TO BLOCK WITH TTY LOCKED
;<4.MONITOR>TTYSRV.MAC.27,  2-May-78 14:54:32, EDIT BY MILLER
;DON'T NEED TO USE LINKF IN TTLNK3 ANYMORE
;<3A.MONITOR>TTYSRV.MAC.32, 24-Apr-78 08:36:19, EDIT BY MILLER
;MAKE SURE "LINK ECHOES" ARE GENERATED FOR HALF-DUPLEX LINES
;<4.MONITOR>TTYSRV.MAC.25, 22-Apr-78 15:52:47, Edit by BORCHEK
;SET UP TCJOB FOR NVT AT TTYAC4:
;<4.MONITOR>TTYSRV.MAC.24, 18-Apr-78 13:56:30, EDIT BY MURPHY
;<4.MONITOR>TTYSRV.MAC.23, 15-Apr-78 15:33:17, EDIT BY MILLER
;FIX HANDLING OF LINKF IN TTLNK3
;<3A.MONITOR>TTYSRV.MAC.29, 13-Apr-78 15:54:41, EDIT BY MURPHY
;TCO #1905 - FIX TTSTIH
;<4.MONITOR>TTYSRV.MAC.21,  5-Apr-78 16:11:11, EDIT BY MILLER
;REMOVE CHECK FOR TTLCK=0 IN TCI BLOCK ROUTINE
;<4.MONITOR>TTYSRV.MAC.20, 28-Mar-78 12:20:39, EDIT BY MILLER
;FIX TYPEO
;<3A.MONITOR>TTYSRV.MAC.26, 28-Mar-78 11:44:47, EDIT BY MILLER
;FIX UP CODE IN TTLNK3
;<4.MONITOR>TTYSRV.MAC.18, 27-Mar-78 18:23:24, EDIT BY MILLER
;FIX TTLNK3
;<3A.MONITOR>TTYSRV.MAC.24, 27-Mar-78 10:11:40, EDIT BY MILLER
;FIX TLINK NOT TO USE TTYDIS AND TTYAWK. REMOVE ROUTINES
;<4.MONITOR>TTYSRV.MAC.16, 26-Mar-78 14:38:41, EDIT BY MILLER
;CHECK FOR MESSAGE BLOCK AT CLENUP
;<4.MONITOR>TTYSRV.MAC.15, 26-Mar-78 14:32:57, EDIT BY MILLER
;FIX TYPEO
;<3A.MONITOR>TTYSRV.MAC.21, 26-Mar-78 13:11:43, EDIT BY MILLER
;FIX UP TTLNK3 TO UNLOCK TTY
;<3A.MONITOR>TTYSRV.MAC.20, 25-Mar-78 14:38:41, EDIT BY MILLER
;MORE FIX UPS
;<3A.MONITOR>TTYSRV.MAC.19, 25-Mar-78 13:43:00, EDIT BY MILLER
;MORE FIXES
;<3A.MONITOR>TTYSRV.MAC.18, 25-Mar-78 13:36:15, EDIT BY MILLER
;ALLOW TCOTST TO PROCEED WITHOUT TTY BEING LOCKED
;<4.MONITOR>TTYSRV.MAC.12, 23-Mar-78 07:55:38, EDIT BY MILLER
;CHECK FOR REQUEUE AT TTQAD
;<3.SM10-RELEASE-3>TTYSRV.MAC.9, 22-Mar-78 19:44:46, Edit by MCLEAN
;ADD TTXOC FOR 2020
;<3.SM10-RELEASE-3>TTYSRV.MAC.8, 22-Mar-78 19:38:24, Edit by MCLEAN
;<4.MONITOR>TTYSRV.MAC.10, 20-Mar-78 14:10:58, EDIT BY MILLER
;CHECK FOR SEND-ALL OR MESSAGE BLOCK AT TTSN10
;<4.MONITOR>TTYSRV.MAC.9,  9-Mar-78 09:34:49, Edit by ENGEL
;ADD SUPPORT FOR THE FULL WAKE 128-CHARACTER WAKE-UP MASK
;<4.MONITOR>TTYSRV.MAC.8,  2-Mar-78 17:49:26, EDIT BY MILLER
;GIVE TTDIBE A SKIP RETURN. +1 MEANS RETRY
;<3A.MONITOR>TTYSRV.MAC.11,  2-Mar-78 16:58:28, EDIT BY MILLER
;GIVE TTDOBE A SKIP RETURN. CALLERS MUST RETRY
;<3A.MONITOR>TTYSRV.MAC.9, 22-Feb-78 16:31:41, EDIT BY MILLER
;MAKE TTSTO BLOCK WITH TTY UNLOCKED. ADD SKIP RETURN FOR SUCCESS
;<4.MONITOR>TTYSRV.MAC.5, 22-Feb-78 08:19:01, EDIT BY MILLER
;FLUSH OUTPUT BUFFERS IN TSACT3 SCHEDULER TEST
;<4.MONITOR>TTYSRV.MAC.4, 21-Feb-78 08:42:38, EDIT BY MILLER
;CHANGE SETOBF TO USE FULL WORD TTBFRC DEFINITION
;<4.MONITOR>TTYSRV.MAC.3, 20-Feb-78 14:15:58, EDIT BY MILLER
;CHANGE TO STADYN IN TTSSPD TO CALL LCKTTY
;<4.MONITOR>TTYSRV.MAC.2, 20-Feb-78 10:29:50, EDIT BY MILLER
;FIX TYPEO IN SETOBF
;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.

	SEARCH PROLOG
	SALL

   IFNDEF ARPAF,<ARPAF==0>
   IFN KLFLG&<^-ARPAF>,<
	TTITLE TTYSRV
	SEARCH PROKL
>
   IFN ARPAF&KLFLG,<
	TTITLE TTYSRV,TTYSNV
	SEARCH PROKL
>
   IFN SMFLG&<^-ARPAF>,<
	TTITLE TTYSRV,TTYSSM
	SEARCH PROKS
>

   IFN ARPAF&SMFLG,<
	TTITLE TTYSRV,TTYASM
	SEARCH PROKS
>

;SET FLAGS FOR DEVICE CODE

  IFN KLFLG,<
	.FEFLG==1>		;INCLUDE FE CODE
  IFN SMFLG,<
	.DZFLG==1>		;INCLUDE DZ CODE
  IFN ARPAF,<
	.NTFLG==1>		;INCLUDE NT CODE
	.PTFLG==1		;ALWAYS INCLUDE PT CODE

ND .FEFLG,0
ND .MCFLG,1
ND .PTFLG,1
ND .DCFLG,0
ND .NTFLG,0
ND .DZFLG,0			;DEFAULT ALL

ND NVTLEN,0
ND TTMCLN,0

;TELETYPE SERVICE ROUTINES - D. MURPHY

	SUBTTL DATA DEFINITIONS

;AC DEFINITIONS USED HEREIN

DEFAC (FX,Q3)			;FORK INDEX
;This code supports a number (NLTYPS) of different types of terminals.
;The general code is in this module (TTYSRV), and there is another
;module for each terminal type which contains the device-dependent
;code for that type.  Device dependent code is called via a macro
;defined below.

;The macro accepts a list of pairs, where each pair indicates a
;line type and a routine to be called for that type.  If no
;specification is given for a line type, control passes through the
;TDCALL with no effect.

;TDCALL - Macro to do the device dependent subroutine call.
;Use:
;	TDCALL S,<list>,default
;	 or
;	TDCALL D,<list>,default
; where
;  S indicates that a static pointer is in T2,
;  D indicates that a dynamic pointer is in T2.
;  list is the list of dispatches for this function
;	where each item is a pair of the form <ty,adr>, where
;	  ty = one of the set FE, MC, PT, DC, NT, DZ indicating
;		the line type for which the adr is relevant
;	  adr = the address of a routine to CALL for this type
;  default, if present, is the instruction to assemble in the absence
;	of the line type and/or the line case

;The macros ultimately assemble something of the form:
;	LOAD CX,line-type
;	CALL [	JRST FECASE
;		JRST MCCASE
;		..
;		JRST DZCASE](CX)
;where the literal must be exactly NLTYPS long and must be in the
;proper order.  If no specification is found for a particular
;line type, a RET (or the default) is assembled in that literal location.
;There is also a varient, TDCALX, if the line type is already in an AC.

DEFINE TDCALL (DT,VECTOR,DEFLT)<
  IFIDN <DT><S>,<
	LOAD CX,TTSTY,(T2)>
  IFIDN <DT><D>,<
	LOAD CX,TLTYP,(T2)>
	CALL [
	  ..TDC1 (<VECTOR>,<FE,MC,PT,DC,NT,DZ>,<DEFLT>) ](CX)
  >

DEFINE ..TDC1 (VECTOR,TYLST,DEFLT)<
  IRP TYLST,<
   IFE .'TYLST'FLG,<
    IFNB <DEFLT>,<
	DEFLT>
    IFB <DEFLT>,<
	JRST TTBUGH>>		;;GO TO BUGCHK IF CODE DOESN'T EXIST
   IFN .'TYLST'FLG,<
	..F==0			;;FLAG TO SEE IF HAVE THIS TYPE
    IRP VECTOR,<
	..TDC2 (VECTOR,TYLST)>	;;SEE IF TYPES MATCH AND ASSEMBLE DISPATCH
    IFE ..F,<
     IFNB <DEFLT>,<
	DEFLT>
     IFB <DEFLT>,<
	RET>>>>>		;;RET IF NO SPEC FOR THIS TYPE

DEFINE ..TDC2 (VECTOR,LTY)<
	..TDC3 (VECTOR,LTY)>

DEFINE ..TDC3 (TY,ADR,LTY)<
  IFIDN <TY><LTY>,<
	..F=1			;;NOTE ASSEMBLED WORD HERE
	JRST ADR>>

;VARIENT MACRO USED IF LINE TYPE ALREADY IN AC

DEFINE TDCALX (AC,VECTOR,DEFLT)<
	CALL [
	  ..TDC1 (<VECTOR>,<FE,MC,PT,DC,NT,DZ>,<DEFLT>) ](AC)>

;TABLES INDEXED BY LINE TYPE NUMBER

RS TT1LIN,NLTYPS		;PLACE FOR FIRST LINE OF THIS TYPE
				; STORED AT INITIALIZATION

;TABLE OF INSTRUCTIONS TO SET/CLEAR PARITY BIT AS FUNCTION OF LINE TYPE

PARTBL:	TRO T1,200		;FE
	TRO T1,200		;MC
	TRO T1,200		;PT
	TRO T1,200		;DC
	TRZ T1,200		;NT
	TRO T1,200		;DZ
IFN .-PARTBL-NLTYPS,<PRINTX %PARTBL SIZE DOES NOT AGREE WITH NLTYPS>

;SIZE OF DYNAMIC DATA BASE TO BE ALLOCATED

DDLTBL:	TTDDLN			;FE
	TTMCLN			;MC
	TTDDLN			;PT
	TTDDLN			;DC
	NVTLEN			;NT
	TTDDLN			;DZ
IFN .-DDLTBL-NLTYPS,<PRINTX %DDLTBL SIZE DOES NOT AGREE WITH NLTYPS>
;SAVELN - MACRO TO SAVE AC2 UPON ENTRY TO A ROUTINE AND RESTORE
;IT UPON EXIT. USED TO SAVE INTERNAL LINE NUMBER OR ADDRESS OF DYNAMIC
;DATA BECAUSE CALLERS ASSUME IT IS PRESERVED

;NOTE THAT IF A ROUTINE HAS BOTH SAVELN AND STKVAR, THE SAVELN MUST
;COME FIRST

	DEFINE SAVELN <
	JSP CX,.SAV22>		;SAVE T2

	RESCD

;MACRO TO GET STATIC LINE NUMBER FROM DYNAMIC DATA BASE.
;ASSUMES THAT T2/ ADDRESS OF DYNAMIC DATA
;PRESERVES ALL REGISTERS EXCEPT T2

DEFINE DYNST (AREG) <
   IFB <AREG>,<LOAD T2,TINTL,(T2)> ;;SIMPLE PROCEDURE
   IFNB <AREG>,<LOAD AREG,TINTL,(T2)> ;;FOR SPECIAL CASES
   >

;VARIENTS OF LOAD AND STOR WHICH AUTOMATICALLY CONVERT FROM
;DYNAMIC TO STATIC

DEFINE STALOD (AC,STR,XR)<
	LOAD CX,TINTL,XR	;;GET LINE NUMBER
	LOAD AC,STR,(CX)>	;;THEN DO LOAD

DEFINE STASTO (AC,STR,XR)<
	LOAD CX,TINTL,XR
	STOR AC,STR,(CX)>
;STATIC STORAGE - ONE WORD PER DEFINED LINE, WHETHER ACTIVE OR NOT
;WORDS ARE ACTUALLY DEFINED IN STG

;RS TTSTAT,NLINES
TT%FEM==1B0			;LINE IS REMOTE
TT%NTS==1B1			;DON'T SEND SYSTEM MESSAGES
TT%FXO==1B2			;LINE NEEDS XON
TT%CON==1B3			;CARRIER IS ON
TT%FSP==1B4			;LINE NEEDS SPEED SET
TT%FXF==1B5			;LINE NEEDS XOF
TT%IGI==1B6			;IGNORE INPUT WHEN LINE IS INACTIVE
TT%AUT==1B7			;LINE IS AUTO-SPEED
TT%XOC==1B8			;LINE NEEDS XON/XOFF CHARACTER (2020)
TT%FPK==1B8			; WAITING FOR FE POST (KL)
TT%SHU==1B9			;LINE IS SHUT OFF
TT%WSO==1B10			;LINE WAS SHUT OFF
MSKSTR TTFEM,TTSTAT,TT%FEM
MSKSTR TTNTS,TTSTAT,TT%NTS
MSKSTR TTFXO,TTSTAT,TT%FXO
MSKSTR TTCON,TTSTAT,TT%CON
MSKSTR TTFSP,TTSTAT,TT%FSP
MSKSTR TTFXF,TTSTAT,TT%FXF
MSKSTR TTIGI,TTSTAT,TT%IGI	;IGNORE INPUT WHEN LINE IS INACTIVE
MSKSTR TTAUT,TTSTAT,TT%AUT	;LINE IS AUTO-SPEED
MSKSTR TTXOC,TTSTAT,TT%XOC	;LINE NEEDS XON/XOFF CHARACTER OUTPUT
MSKSTR TTFPK,TTSTAT,TT%FPK	; FE TO POST
MSKSTR TTSHU,TTSTAT,TT%SHU
MSKSTR TTWSO,TTSTAT,TT%WSO	;LINE WAS SHUT OFF
; 11-14 FREE
DEFSTR TTSTY,TTSTAT,17,3	;LINE TYPE
DEFSTR TSFMC,TTSTAT,27,8	;MAX COUNT FOR FRONT END BUFFER
DEFSTR TTFBB,TTSTAT,35,8	;NUMBER OF ENTRIES IN TTBBUF
;RS TTSPWD,NLINES		;(INPUT SPEED,,OUTPUT SPEED
DEFSTR TTISP,TTSPWD,17,18	;INPUT SPEED
DEFSTR TTOSP,TTSPWD,35,18	;OUTPUT SPEED
;RS TTACTL,NLINES		;ADDRESS OF DYNAMIC DATA IF ACTIVE
				; OR -1 IF BECOMING ACTIVE
				; OR 0 IF INACTIVE
TTSHBK==1B0			;SHORT BLOCK
;RS TTCSAD,NLINES		;BITS FOR FUNCTIONS NEEDED
;RS TTCSTM,NLINES		;TIME FOR SCHEDULER TO CALL ROUTINE

;OTHER MISC STORAGE, DEFINED HERE

RS SALLCK,1			;SENDALL LOCK
RS SALCNT,1			;SENDALL COUNT
RS SALBFR,1			;SENDALL BUFFER ADDRESS
;OFFSETS IN DYNAMIC DATA

TTFLG1==:0
TT%SAL==:1B0			;SENDALL BEING DONE TO THIS LINE
TT%SHT==1B1			;THIS IS A SHORT BLOCK
TT%MES==1B2			;THIS IS A SYSTEM MESSAGE BLOCK
TT%OTP==1B3			;OUTPUT IS ENROUTE TO THE LINE
TT%FWK==1B4			;FORCED WAKEUP
TT%SFG==1B5			;STOPPED ON END-OF-PAGE
TT%RFG==1B6			;REPEAT LAST CHARACTER (BKJFN)
TT%WFG==1B7			;BLOCKED ON INPUT
TT%PRM==1B8			;DON'T DEALLOCATE DYNAMIC DATA
TT%BAC==1B9			;PERMANENT AND BECOMING ACTIVE
TT%NXO==1B10			;PAUSE ON END-OF-PAGE MODE
TT%BKO==1B11			;FORK BLOCKED FOR OUTPUT EVENT ON THIS LINE
TT%NUS==1B12			;NET USER STATE
TT%DD1==1B13			;DEVICE DEPENDENT BIT
TT%NPM==1B14			;MCB NVT OLD PAGE MODE
TT%RXF==1B15			;HAVE RECEIVED XOFF ON LINE
TT%FLO==1B16			;FLUSHING OUTPUT AT TTSND
TT%HPO==1B17			;HIGH PRIORITY OUTPUT QUEUED
TT%DAL==1B18			;DEALLOCATE OF BLOCK REQUESTED
TT%LCK==77B35			;COUNT OF LOCKS ON THIS BLOCK
MSKSTR TTSAL,TTFLG1,TT%SAL
MSKSTR TTSHT,TTFLG1,TT%SHT
MSKSTR TTMES,TTFLG1,TT%MES
MSKSTR TTOTP,TTFLG1,TT%OTP
MSKSTR TTFWK,TTFLG1,TT%FWK
MSKSTR TTSFG,TTFLG1,TT%SFG
MSKSTR TTRFG,TTFLG1,TT%RFG
MSKSTR TTWFG,TTFLG1,TT%WFG
MSKSTR TTPRM,TTFLG1,TT%PRM
MSKSTR TTBAC,TTFLG1,TT%BAC
MSKSTR TTNXO,TTFLG1,TT%NXO
MSKSTR TTBKO,TTFLG1,TT%BKO
MSKSTR TTNUS,TTFLG1,TT%NUS
MSKSTR TTDD1,TTFLG1,TT%DD1	;DEVICE DEPENDENT BIT
MSKSTR TTNPM,TTFLG1,TT%NPM
MSKSTR TTRXF,TTFLG1,TT%RXF
MSKSTR TTFLO,TTFLG1,TT%FLO
MSKSTR TTHPO,TTFLG1,TT%HPO
MSKSTR TTDAL,TTFLG1,TT%DAL
MSKSTR TTLCK,TTFLG1,TT%LCK

TTDAT1==1
DEFSTR TYLMD,TTDAT1,5,2		;TERMINAL DATA MODE FOR LAST INPUT CHAR
DEFSTR TTOCN,TTDAT1,7,3		;COUNT OF EXTRA BUFFERS
DEFSTR TTOMX,TTDAT1,8,1		;EXTRA BUFFERS IN USE
DEFSTR TTTYP,TTDAT1,17,9	;TERMINAL TYPE
DEFSTR TINTL,TTDAT1,35,18	;INTERNAL LINE NUMBER (INDEX INTO STATIC DATA)

TTSAL1==2
DEFSTR TLTYP,TTSAL1,17,18	;LINE TYPE (SAME AS TTSTY)
DEFSTR TSALT,TTSAL1,23,6	;SENDALL TIMEOUT COUNT
DEFSTR TSALC,TTSAL1,35,12	;SENDALL CHARACTER COUNT

TTSAL2==3			;SENDALL BYTE POINTER

TTDEV==4
;DEVICE DEPENDET WORD SEE DEVICE MODULES FOR DEFINITIONS


TTBFRC==5
DEFSTR TOWRN,TTBFRC,7,8		;COUNT IN OUPUT BUFFER FOR WAKEUP
DEFSTR TTNIN,TTBFRC,11,4	;NO. INPUT BUFFERS
DEFSTR TTNOU,TTBFRC,15,4	;NUMBER OUTPUT BUFFERS
DEFSTR TIMAX,TTBFRC,25,10	;MAX BYTES IN INPUT BUFFER
DEFSTR TOMAX,TTBFRC,35,10	;MAX BYTES IN OUTPUT BUFFER

TTOCT==6			;NUMBER CHARACTERS IN OUTPUT BUFFER
TTOOUT==7			;POINTER FOR REMOVING CHAR FROM OUTPUT BUFFER
TTOIN==10			;POINTER FOR ENTERING CHAR INTO OUTPUT BUFFER

TTDAT2==11
DEFSTR TTUPC,TTDAT2,8,9		;UNPAUSE ON PAGE CHARACTER
DEFSTR TYLCH,TTDAT2,17,9	;LAST CHAR REMOVED FROM INPUT BUFFER
DEFSTR TPWID,TTDAT2,26,9	;PAGE WIDTH
DEFSTR TTPPC,TTDAT2,35,9	;PAUSE/UNPAUSE ON PAGE CHARACTER

TTICT==12			;NUMBER CHARACTERS IN INPUT BUFFER
TTIOUT==13			;POINTER FOR REMOVING CHAR FROM INPUT BUFFER
TTIIN==14			;POINTER FOR ENTERING CHAR INTO INPUT BUFFER

FCMOD1==15			;CONTROL CHARACTER OUTPUT CONTROL WORDS
FCMOD2==16			; (2 BITS PER CHARACTER)
;POSSIBLE VALUES FOR EACH CHARACTER
CCNONE==0			;SEND NOTHING
CCIND==1			;INDICATE VIA ^
CCSEND==2			;SEND ACTUAL CODE
CCSIM==3			;SIMULATE FORMAT ACTION

TTDPSI==17			;BIT FOR TERMINAL CODE SET IF DEFERRED INTERRUPT
TTPSI==20			;BIT FOR TERMINAL CODE SET IF INTERRUPT
TTLINK==21			;LINES LINKED TO (9 BITS PER LINE)

TTLPOS==22
DEFSTR TPGPS,TTLPOS,17,18	;CURRENT LINE POSITION WITHIN PAGE
DEFSTR TLNPS,TTLPOS,35,18	;CURRENT CHARACTER POSITION WITHIN LINE

TTFLGS==23
MSKSTR TOFLG,TTFLGS,TT%OSP	;CTRL/O WAS TYPED
DEFSTR TPLEN,TTFLGS,17,8	;PAGE LENGTH
;(BITS ARE DEFINED IN MONSYM AS JFN MODE WORD)

TTFORK==24
DEFSTR TCJOB,TTFORK,17,18	;CONTROLLING JOB NUMBER
DEFSTR TWFRK,TTFORK,35,18	;NUMBER OF FORK IN INPUT WAIT ON THIS LINE

TTFRK1==25
DEFSTR TTPFK,TTFRK1,35,18	;FORK WHICH IS TOP FORK OF A SCTTY TREE
				;-1 IF NONE
DEFSTR TTPSFK,TTFRK1,17,18	;PSI FORK FOR NON CONTROL TTY PSI'S


TTCHR1==26			;WAKE UP CHARACTER MASK (ASCII CODES 0-31.)
TTCHR2==27			;WAKE UP CHARACTER MASK (ASCII CODES 32.-63.)
TTCHR3==30			;WAKE UP CHARACTER MASK (ASCII CODES 64.-95.)
TTCHR4==31			;WAKE UP CHARACTER MASK (ASCII CODES 96.-127.)

; ** TTCHR1,TTCHR2,TTCHR3  AND TTCHR4 SHOULD REMAIN TOGETHER IN THAT ORDER

TTFWTH==32			;WAKE UP FIELD WIDTH BYTE COUNT
DEFSTR TTIPSI,TTFWTH,11,6	;INPUT PSI LEVEL
DEFSTR TTOPSI,TTFWTH,17,6	;OUPUT PSI LEVEL
DEFSTR TTFCNT,TTFWTH,35,18	;BYTE COUNT FOR WAKE-UP (0=DISABLED FOR WAKE UP)

TTLINE==33			;LINE COUNTER
TTLMAX==34			;MAXIMUM OF TTLINE
DEFSTR TTULL,TTLMAX,35,18	;NET USER LOGICAL LINK - WHEN TTLMAX NOT IN USE
DEFSTR TTUEC,TTLMAX,17,7	;NET USER ESCAPE CHAR

;LENGTHS OF DYNAMIC BLOCKS

TTDDLN==35			;DEFAULT DYNAMIC DATA SIZE
MSGLEN==11			;SIZE OF MESSAGE BLOCK
;FIELDS OF JFN MODE WORD AS DEFINED IN MONSYM

REPEAT 0,<
TT%OSP==:1B0			;OUTPUT SUPPRESS
TT%MFF==:1B1			;MECHANICAL FORMFEED PRESENT
TT%TAB==:1B2			;MECHANICAL TAB PRESENT
TT%LCA==:1B3			;LOWER CASE CAPABILITIES PRESENT
TT%LEN==:177B10			;PAGE LENGTH
TT%WID==:177B17			;PAGE WIDTH
TT%WAK==:17B23			;WAKEUP FIELD
TT%WK0==:1B18			;WAKEUP CLASS 0 (UNUSED)
TT%IGN==:1B19			;IGNORE THE TT%WAK BITS ON SFMOD
TT%WKF==:1B20			;WAKEUP ON FORMATING CONTROL CHARS
TT%WKN==:1B21			;WAKEUP ON NON-FORMATTING CONTROLS
TT%WKP==:1B22			;WAKEUP ON PUNCTUATION
TT%WKA==:1B23			;WAKEUP ON ALPHANUMERICS
TT%ECO==:1B24			;ECHOS ON
TT%ECM==:1B25			;ECHO MODE
TT%ALK==:1B26			;ALLOW LINKS
TT%AAD==:1B27			;ALLOW ADVICE (NOT IMPLEMENTED)
TT%DAM==:3B29			;DATA MODE
.TTBIN==:0			;BINARY
.TTASC==:1			;ASCII
.TTATO==:2			;ASCII AND TRANSLATE OUTPUT ONLY
.TTATE==:3			;ASCII AND TRANSLATE ECHOS ONLY
TT%UOC==:1B30			;UPPER CASE OUTPUT CONTROL
TT%LIC==:1B31			;LOWER CASE INPUT CONTROL
TT%DUM==:3B33			;DUPLEX MODE
.TTFDX==:0			;FULL DUPLEX
.TT0DX==:1			;NOT USED, RESERVED
.TTHDX==:2			;HALF DUPLEX (CHARACTER)
.TTLDX==:3			;LINE HALF DUPLEX
TT%PGM==:1B34			;PAGE MODE
TT%CAR==:1B35			;CARRIER STATE
>
;LOCAL PARAMETERS

MXFECC==50			;MAX CHARACTERS FOR A FE LINE IN -11

;FIELDS IN TTBBUF

DLSRCF==:400			;DLS RECEIVER FLAG, DATAI WORD
TTNCF==1B19			;FLAG - CHARACTER CAME FROM NETWORK
REPEAT 0,<
TTSCF==1B20			;FLAG - CHARACTER CAME FROM STI
>
TTPIRQ==1B23			;OUTPUT INTERRUPT REQUEST (SOFTWARE)
TTOIRQ==1B24			;OUTPUT INTERRUPT REQUEST (SOFTWARE)
DLSCXF==:1B25			;CARRIER XITION FLAG (SOFTWARE)
CARONB==:1B33

TTXECO==1B27			;INPUT STREAM - CHARACTER ALREADY ECHOED
MAXBBC==^D20			;MAX ENTRIES ALLOWED IN BIGBUF FOR THIS
				; LINE
MXBBC1==5			;WHEN AN X-ON IS ALLOWED AGAIN
MAXABC==TTBSIZ/2		;WHEN LINE IS SHUT OFF
XOFFC=="S"-100			;THE X-OFF CODE (TO SEND)
XONC=="Q"-100			;THE X-ON CODE (TO SEND)
MINICT==30			;WHEN TO SEND AN X-OFF
MINCT1==MINICT+10		;WHEN TO FORCE WAKEUP BEFORE XOFF
MINXON==20			;WHERE TO SEND XON

TTLIND=="'"			;UPPER CASE INDICATION CHARACTER FOR OUTPUT
TTCIND=="^"			;CONTROL INDICATION CHARACTER FOR OUTPUT
TTFILL==0			;FILLER CHARACTER
PGMONC=="Q"-100			;XON - RESTART OUTPUT IN PAGE MODE (RECEIVED)
PGMOFC=="S"-100			;XOFF - STOP OUTPUT IN PAGE MODE (RECEIVED)
PGMOC2=="A"-100			;RESTART OUTPUT FROM PAUSE ON END-OF-PAGE
FLOCHR=="O"-100			;FLUSH OUTPUT CHARACTER - CTRL-O

TTOESC==400			;FUNCTION ESCAPE IN OUTPUT STREAM
TTOPFC==420			;PAGE FULL CODE IN OUTPUT STREAM
TTOMRK==421			;OUTPUT STREAM MARKER, CLEAR OUTPUT FLUSHING

TABSIZ==:^D8			;STANDARD TAB SPACING
DFLWID==1			;OLD STYLE DEFAULT WIDTH
DFLLEN==1			;OLD STYLE DEFAULT LENGTH
LOWSPD==^D600			;HIGHEST SPEED WHERE NTTBL SUFFICES
	RESCD

;INDEX TO DEV TABLES FOR TTY0

DEVTT0:: DVXTT0


;USUAL DEVICE FLAGS AND STATUS
; 66 LINES/PAGE, 75 CHARS/LINE
; WAKEUP ON ALL, ECHO MODE 2 (DEFERRED OR IMMED)
; DATA MODE ASCII, 'RAISE' LC INPUT (ALSO CONVERTS OLD-STYLE ALT-MODES)

NORMTF::^D66B10+^D72B17+17B23+2B25+TT%ALK+1B29+1B31+TT%PGM
NORMTY:: ^D8			;NORMAL TERMINAL TYPE

TAB81::	EXP 1B0+1B8+1B16+1B24+1B32
TAB82::	EXP 1B4+1B12+1B20+1B28
TAB83:	EXP 1B0+1B8+1B16+1B24+1B32

;NORMAL CONTROL CHARACTER SETTINGS

TTICB1::BYTE (2) 0,1,1,1,1,1,1,2,1,2,3,1,1,2,1,1,1,1
TTICB2::BYTE (2) 1,1,1,1,1,1,1,1,1,3,1,1,1,1


;	DEFAULT DEFINITIONS FOR TERMINAL WAKE-UP

TTWKDF:	EXP -20			;WAKE-UP ON ALL CHARACTERS
	EXP -20
	EXP -20
	EXP -20

;POINTERS TO TERMINAL TYPE FIELDS
;ASSUME TYPE NUMBER IN 3

TTMBIT:	POINT 3,TTYPE0(3),2	;MECHANICAL BITS
TTCRPD:	POINT 4,TTYPE0(3),7	;CR PADDING FOR FULL LINE
TTLFPD:	POINT 4,TTYPE0(3),11	;LF PADDING FOR ONE LINE
TTTBPD:	POINT 4,TTYPE0(3),15	;TAB PAD FOR 4 SPACES
TTFFPD:	POINT 4,TTYPE0(3),19	;FF PAD FOR FULL PAGE
TTTWID:	POINT 8,TTYPE0(3),27	;WIDTH OF LINE
TTTLEN:	POINT 8,TTYPE0(3),35	;LENGTH OF PAGE

SCNTIM==^D1000			;CONTROLLER CHECK INTERVAL (1 SEC)

CTRLOF::0			;NEW CTRL-O HANDLING POSSIBLE
	SUBTTL ONCE-ONLY INITIALIZATION

;INITIALIZATION. CALLED FROM STG AT SYSTEM STARTUP

	RESCD			;MUST BE RESIDENT

;INITIALIZE CHAIN OF LINE BUFFERS.  LINE BUFFERS ARE OF SIZE TTSIZ.
;THIS CODE MAKES WORD 0 OF BUFFER N CONTAIN THE ADDRESS OF BUFFER N-1
;AND TTFREB CONTAIN THE ADDRESS OF THE HIGHEST-NUMBERED BUFFER

TTINIT::MOVEI T1,SCNTIM		;TIME FOR NEXT SCAN
	MOVEM T1,TTYTIM		;STASH IT
   IFN .MCFLG,<			;IF HAVE MCB CODE
   IFN CZQDBG,<			;AND IF DEBUG CODE,
	MOVEI T1,CZQBF		;INIT TRACE PTR
	MOVEM T1,CZQPTR
   >>
	MOVEI 1,TTBUFS		;COMPUTE BEGINNING OF BUFFERS
	SETOM TTQCNT		;INIT SCAN COUNT
	TRNE 1,TTSIZ-2		; TO BE N*TTSIZ+1
	ADDI 1,TTSIZ		;FIRST WORD IN BUFFER AREA
	ANDCMI 1,TTSIZ-1	;WHICH IS 0 MOD TTSIZ
	ADDI 1,1		;SUCH THAT EACH BUFFER ENDS 0 MOD ADR
	MOVEI 2,NTTBF
	MOVEM 2,TTFREC		;FREE BUFFER COUNT
	SUBI 2,1
	MOVEM 1,TTSIZ(1)	;CONSTRUCT LIST OF FREE BUFFERS
	ADDI 1,TTSIZ
	SOJG 2,.-2
	MOVEM 1,TTFREB		;FREE BUFFER LIST

;INITIALIZE THE STATIC DATA FOR ALL LINES. TTSPWD IS DONE BY DTEINI

	SETOM SALLCK		;INIT SENDALL LOCK
	MOVEI T1,NLINES		;DO ALL LINES
	SETZ T2,		;START WITH LINE 0
TTINI1:	SETZM TTSTAT(T2)	;CLEAR STATUS WORD
	MOVEI T3,MXFECC		;GET DEFAULT LINE ALLOCATION
	STOR T3,TSFMC,(T2)	; AND SAVE IT FOR THIS LINE
	SETZM TTACTL(T2)	;NO DYNAMIC DATA YET
	AOS T2			;GO TO NEXT LINE
	SOJG T1,TTINI1		; UNTIL ALL LINES ARE DONE
	;..
;THIS CODE ESTABLISHES THE TYPE OF EACH LINE. LINES OF A TYPE ARE ASSIGNED
;CONSECUTIVELY, STARTING WITH LINES THAT ARE LOCAL TO THE MACHINE.  THIS
;CODE STORES THE LINE TYPE WITH THE LINE AND SETS UP TT1LIN
;FOR EACH TYPE TO CONTAIN THE NUMBER OF THE FIRST LINE.

	;..
	MOVEI T2,0		;T2/ FIRST LINE IS LINE 0
	MOVEI T3,TT.FE		;T3/ CODE FOR FRONT-END LINES
	MOVEI T4,NTTFE		;T4/ NUMBER OF FRONT END LINES
	CALL SETTYP
	MOVEI T3,TT.DZ		;T3/ CODE FOR DZ11 LINES
	MOVEI T4,NTTDZ		;T4/ NUMBER OF DZ11 LINES
	CALL SETTYP
	MOVEI T3,TT.MCB		;T3/ CODE FOR MCB LINES
	MOVEI T4,NTTMCB		;T4/ NUMBER OF MCB LINES
	CALL SETTYP
	MOVEI T3,TT.PTY		;T3/ CODE FOR PSEUDO-TERMINALS
	MOVEI T4,NTTPTY		;T4/ NUMBER OF PTY'S
	CALL SETTYP
	MOVEI T3,TT.D10		;T3/ CODE FOR DC10 LINES
	MOVEI T4,NTTD10		;T4/ NUMBER OF DC10 LINES
	CALL SETTYP
	MOVEI T3,TT.NVT		;T3/ CODE FOR ARPANET LINES
	HRLI T4,-NTTNVT		;SET UP NVT PAR WITH -NTTNVT,,FIRST NVT
	HRR T4,T2		;GET FIRST NVT
	MOVEM T4,NVTPTR		;STORE IT AWAY
	MOVEI T4,NTTNVT		;T4/ NUMBER OF ARPANET LINES
	CALL SETTYP


;INITIALIZE POINTERS TO TTBBUF

	SETZM TTBIGO
	SETZM TTBIGC
	SETZM TTBIGI

	SETZM TTCQLN		;INITIALIZE FOR TTHNG4

	SAVEAC <Q1>
	MOVSI Q1,-NLTYPS	;FIND NUMBER OF LINE TYPES
TYINLP:	TDCALX Q1,<<DZ,DZINIT>>,<RET>
	AOBJN Q1,TYINLP		;DO ALL TYPES
	CALLRET TTSTRT
;SETTYP - SET THE TERMINAL TYPE FOR A GROUP OF LINES

;ACCEPTS:
;	T2/ CURRENT LINE NUMBER (FIRST FOR THIS TYPE)
;	T3/ LINE TYPE
;	T4/ NUMBER OF LINES OF THIS TYPE

;	CALL SETTYP

;RETURNS +1: ALWAYS
;		T2/ UPDATED LINE NUMBER (FIRST LINE OF NEXT TYPE)

SETTYP:	JUMPG T4,SETTY2		;IF NO LINES OF THIS TYPE,
	SETOM TT1LIN(T3)	;SET FIRST LINE TO -1
	RET			; AND RETURN

SETTY2:	MOVEM T2,TT1LIN(T3)	;STORE FIRST LINE FOR THIS TYPE
SETTY1:	STOR T3,TTSTY,(T2)	;SAVE LINE TYPE FOR THIS LINE
	AOS T2			;NEXT LINE NUMBER
	SOJG T4,SETTY1		;GO DO THE NEXT LINE IN THIS TYPE
	CAMN T3,CTYTYP		;IS THIS THE LINE TYPE FOR THE CTY?
	JRST [	CALL INICTY	;YES. INITIALIZE IT
		AOS T2		;POINT TO NEXT LINE
		RET]
	RET
;INICTY - INITIALIZE THE CTY

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER
;	T3/ LINE TYPE

;	CALL INICTY

;RETURNS +1: ALWAYS

;CTY IS A SPECIAL CASE. IT IS ALWAYS LINE 'CTYLNO', AND ITS DYNAMIC DATA
;IS PERMANENTLY ALLOCATED. CTYUNT AND CTYINT WILL BE FIXED BY IDCTY.

INICTY:	SAVET
	MOVEM T2,CTYLNO		;SAVE INTERNAL LINE NUMBER
	SETOM CTYINT		;INITIALIZE INTERNAL EQUIVALENT OF ACTUAL
				; CTY LINE ON .FEDLS DEVICE
	HRRZ T1,DDLTBL(T3)	; AND FULL LENGTH BLOCK
	HRLI T1,.RESP1		;INDICATE NOT SWAPPABLE
	MOVEI T2,.RESTP
	CALL ASGRES		;GET RESIDENT SPACE
	 BUG(NOCTY)
	MOVE T2,CTYLNO		;T2/ LINE NUMBER, T1/ ADDRESS OF BLOCK
	MOVE T3,CTYTYP		;INDICATE LINE TYPE
	STOR T3,TTSTY,(T2)
	CALL TTSETL		;SET INITIAL VALUES IN DYNAMIC DATA
	SETONE TTPRM,(T1)	;DON'T DEALLOCATE THIS DYNAMIC DATA
	MOVEM T1,TTACTL(T2)	;POINT TO DYNAMIC DATA
	RET
;TTSET - SET INITIAL VALUES FOR A LINE

;ACCEPTS:
;	T1/ ADDRESS OF DYNAMIC DATA
;	T2/ LINE NUMBER

;CALL TTSET

;RETURNS +1: ALWAYS
;Leaves TTACTL unchanged to protect against state changes
; * * * *
;NEEDS WORK - CAN'T INIT TOO MANY WORDS
; * * * *

TTSETL:	LOAD T4,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T4,DDLTBL(T4)	;GET LONG BLOCK LENGTH
	JRST TTSET

TTSETS:
TTSETM:	MOVEI T4,MSGLEN		;INDICATE MESSAGE BLOCK
	JRST TTSET

TTSET:	SAVEQ
	TDCALL S,<<FE,TTSETF>>
	LOAD T3,TTSTY,(T2)	;GET LINE TYPE FROM STATIC
	STOR T3,TLTYP,(T1)	; AND COPY TO DYNAMIC
	MOVE Q1,NORMTY		;GET NORMAL TERMINAL TYPE
	STOR Q1,TTTYP,(T1)	;SET IN DYNAMIC DATA
	STOR T2,TINTL,(T1)	;MAKE DYNAMIC DATA POINT TO STATIC
	MOVE T3,IBFRC		;GET DEFAULT BUFFER CONTROL
	MOVEM T3,TTBFRC(T1)	; AND STORE IN DYNAMIC DATA
	CAIN T4,MSGLEN		;IS THIS A MESSAGE-LENGTH BLOCK?
	RET			;YES. NO MORE INITIALIZATION
	CAME T2,CTYLNO		;CTY ASSIGN?
	CALL SETOBF		;NO, SET OUTPUT BUFFER COUNTS
	SETONE TTIPSI,(T1)	;SET NO PSI
	SETONE TTOPSI,(T1)	;INPUT OR OUTPUT
	SETONE TTPSFK,(T1)	;AND NO FORK
	MOVE Q1,TTICB1		;SETUP USUAL CONTROL CHARACTER MODES
	MOVEM Q1,FCMOD1(T1)
	MOVE Q1,TTICB2
	MOVEM Q1,FCMOD2(T1)
	SETOM TTLINK(T1)	;NO LINKS TO OTHER LINES
	MOVE Q1,NORMTF		;USUAL DEVICE FLAGS AND STATUS
	CAMN T2,CTYLNO		;Assigning CTY?
	TXZ Q1,TT%ALK		;Yes - disallow TALK links
	LOAD T3,TTSTY,(T2)	;GET TYPE OF LINE AGAIN
	CAIN T3,TT.PTY		;IS IT A PTY?
	TXZ Q1,TT%PGM		;YES. NO XON/XOFF THEN
	LOAD T3,TT%WID,Q1	;GET STANDARD WIDTH
	LOAD T4,TT%LEN,Q1	;GET LENGTH
	SETZRO <TT%WID,TT%LEN>,Q1 ;CLEAR OUT THESE VALUES
	DPB Q1,[POINT 35,TTFLGS(T1),35] ;STORE STANDARD VALUES IN DYNAMIC DATA
	PUSH P,T2		;SAVE
	MOVE T2,T1
	TDCALL D,<<FE,TTEXF>,<MC,MCEXF>>	;ENABLE XOFF RECOGNITION IN FE
	STOR T3,TPWID,(T2)	;SET UP STANDARD WIDTH
	STOR T4,TPLEN,(T2)	;STORE PAGE LENGTH
	MOVEI T3,PGMOC2		;SET DEFAULT PAGE UNPAUSE CHARACTER
	TDCALL D,<<MC,RSKP>>	;DECNET NVT?
	 MOVEI T3,PGMONC	;NOT NVT, USE SAME AS COMMAND UNPAUSE
	STOR T3,TTUPC,(T2)
	TDCALL D,<<MC,RSKP>>	;DECNET NVT?
	 MOVEI T3,PGMOFC	;NO, USE SAME AS COMMAND PAUSE
	STOR T3,TTPPC,(T2)
	SETONE TWFRK,(T2)	;INDICATE NO FORK WAITING
	MOVE Q1,JOBNO		;GET THIS JOB NUMBER
	STOR Q1,TCJOB,(T2)	;INDICATE THAT IT OWNS THE TERMINAL
	SETONE TTPFK,(T2)	;NO SCTTY FORK YET
	XMOVEI T1,TTWKDF	;POINT TO DEFAULT 4-WORD MASK
	CALL TTSBM		;GO SET IT
	SETZ T1,		;TURN OFF FIELD WIDTH
	CALL TTSFW
	MOVE T1,T2		;RESTORE T1
	POP P,T2		;RESTORE T2
	RET
;TTSTRT - ACTIVATE ALL LINES.  USED ON RESTART AS WELL AS START

TTSTRT:	SETZM TTHNGT
	SETZM TTHNGN
	SAVEQ			;SAVE REGISTERS
	MOVSI Q1,-NLTYPS	;GET THE COUNT OF TYPES
TYRSLP:	TDCALX Q1,<<DZ,DZRSTR>>,<RET>
	AOBJN Q1,TYRSLP		;DO ALL LINES
	RET


;TTRSET - RESUME RUNNING TTY'S AFTER POWER FAILURE

;* * * *
;DON'T DO THIS FOR FE LINES.  MAYBE REMOVE ALL OF IT
; * * * *

;THIS CODE HANDLES ALL LINES. IN FACT, NON-PHYSICAL LINES WON'T HAVE
;TTOTP SET, SO TTSND0 WILL NOT BE CALLED FOR THEM

TTRSET::MOVSI 2,-NLINES		;DO ALL LINES
TTRST1:	PUSH P,T2		;SAVE LINE NUMBER
	CALL STADY		;IS LINE ACTIVE?
	 JRST TTRST2		;NOT AT ALL
	JE TTOTP,(T2),TTRST2	;ACTIVE IN SOME WAY. WAS OUTPUT IN PROGRESS?
	SETZRO TTOTP,(T2)	;YES, CLEAR FLAG SO IT WILL GET RESTARTED
	CALL TTSND0		;RESTART IT
TTRST2:	POP P,T2		;RESTORE COUNTER AND LINE NUMBER
	AOBJN 2,TTRST1
	CALLRET TTSTRT		;ACTIVATE DATASETS, ETC.
;THE FOLLOWING ROUTINES PROVIDE THE MECHANISM FOR INSURING THAT A LINE
;REMAINS ACTIVE (AND THUS THE ADDRESS OF ITS DYNAMIC DATA REMAINS VALID)
;WHILE ITS DYNAMIC DATA IS BEING USED.  TO ADDRESS A LINE'S DYNAMIC DATA
;FROM PROCESS CONTEXT, DO THE FOLLOWING:

;1. CALL LCKTTY, WHICH WILL INCREMENT THE LOCK COUNT IN THE LINE'S DYNAMIC
;DATA AND RETURN NOINT.

;2. IF A DISMISS MUST BE DONE, CALL TTYDIS, WHICH WILL PLACE AN ENTRY ON THE
;JOB'S JSB STACK AND GO OKINT.  AT THIS POINT THE USER CAN CTRL/C, IN
;WHICH CASE THE PROCESSING OF THE JSB STACK WILL DECREMENT THE LINE'S
;LOCK COUNT.

;3. WHEN THE DISMISS COMPLETES, CALL TTYAWK, WHICH WILL REMOVE THE STACK
;ENTRY AND RETURN NOINT

;4. WHEN THE DYNAMIC DATA IS NOT LONGER NEEDED, CALL ULKTTY, WHICH WILL
;DECREMENT THE LOCK COUNT AND RETURN OKINT.

;WHEN ADDRESSING DYNAMIC DATA FROM SCHEDULER CONTEXT, CALLING LCKTTY
;AND ULKTTY IS LEGAL BUT DOES NOT INCREMENT THE COUNT.  IT IS ASSUMED
;THAT THE DYMAMIC DATA WILL NOT DISAPPEAR WHILE THE SCHEDULER IS RUNNING.
;THEREFORE, CALLING STADYN WILL HAVE THE SAME EFFECT; I.E. CONVERTING
;LINE NUMBER TO ADDRESS OF DYNAMIC DATA

;IF THE DYNAMIC DATA IS TO BE ADDRESSED OVER A VERY SHORT PERIOD, THE
;CALLER CAN GO NOSKED, CALL STADYN, ADDRESS THE DATA, AND THEN GO
;OKSKED
	SUBTTL LINE NUMBER/ADDRESS CONVERSION

;STADYN - CONVERT STATIC LINE NUMBER TO DYNAMIC ADDRESS

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL STADYN

;RETURNS +1: LINE DOES NOT HAVE FULL-SIZED DYNAMIC DATA BASE,
;		T2/ -1 IF LINE IS BECOMING ACTIVE
;			OR
;		T2/ 0 IF LINE IS TOTALLY INACTIVE
;			OR
;		T2/ ADDRESS OF DYNAMIC DATA BLOCK IF BLOCK IS NONSTANDARD
;	+2: LINE HAS FULL-SIZED DYNAMIC DATA BASE,
;		T2/ ADDRESS OF DYNAMIC DATA BLOCK

;CLOBBERS NO AC'S

;CALLER SHOULD INSURE THAT THE TERMINAL'S DATA CANNOT GO AWAY EITHER
;BY BEING NOSKED OR BY CALLING LCKTTY

STADYN::SKIPLE T2,TTACTL(T2)	;HAVE A BLOCK?
	RETSKP			;YES. FULLY ACTIVE LINE
	CAME T2,[-1]		;NO. IS IT BECOMING ACTIVE?
	TXZ T2,TTSHBK		;NO. IS MESSAGE OR SHORT. RETURN IT
	RET			;DONE

;VARIENT OF ABOVE - RETURNS +1 IF NO BLOCK PRESENT, +2 IF ANY BLOCK PRESENT

STADY::	SKIPLE T2,TTACTL(T2)	;FULL BLOCK?
	RETSKP			;YES
	CAME T2,[-1]
	TXZ T2,TTSHBK
	JUMPG T2,RSKP		;RETURN +2 IF ANY BLOCK
	RET

;DYNSTA - CONVERT ADDRESS OF STATIC DATA BASE TO INTERNAL LINE NUMBER

;ACCEPTS: T2/ ADDRESS OF STATIC DATA BASE

;	CALL DYNSTA

;RETURNS +1: ALWAYS,
;		T2/ INTERNAL LINE NUMBER

DYNSTA::LOAD T2,TINTL,(T2)	;GET FROM DYNAMIC DATA
	RET			;RETURN
;LCKTTY - GET ADDRESS OF DYNAMIC DATA AND PREVENT DEALLOCATION

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL LCKTTY

;RETURNS +1: LINE DOES NOT HAVE FULL-SIZED DYNAMIC DATA BASE,
;		T2/ -1 IF LINE IS BECOMING ACTIVE
;			OR
;		T2/ 0 IF LINE IS TOTALLY INACTIVE
;			OR
;		T2/ ADDRESS OF DYNAMIC DATA BLOCK IF BLOCK IS NONSTANDARD
;	+2: LINE HAS FULL-SIZED DYNAMIC DATA BASE,
;		T2/ ADDRESS OF DYNAMIC DATA BLOCK

;NOTE THAT THE CALLER MUST CALL ULKTTY BEFORE THE DATA BLOCK CAN BE
;DEASSIGNED. ULKTTY WILL ACCEPT ANY OUTPUT FROM LCKTTY, SO IF THE CALLER
;IS INTERESTED ONLY IN FULLY ACTIVE BLOCKS, IT SHOULD CALL ULKTTY EVEN
;IF LCKTTY TAKES A NON-SKIP RETURN

;CLOBBERS NO AC'S

LCKTTY::NOSKD1			;NO OTHER JOBS RUNNING UNTIL DATA LOCKED
	SKIPG T2,TTACTL(T2)	;ANY DATA BASE AT ALL?
	JRST [	SKIPE T2	;NOT FULLY ACTIVE. IS IT ASSIGNED?
		CAMN T2,[-1]	;OR BECOMING ACITVE?
		RETBAD (,<OKSKD1>) ;NOT A BLOCK
		TXZ T2,TTSHBK	;MESSAGE OR SHORT. MAKE IT ADDRESSABLE
		CALLRET LCKTT]	;LOCK IT
	CALL LCKTT		;LINE IS FULLY ACTIVE. DO THE LOCKING
	RETSKP			;INDICATE FULL-LENGTH BLOCK

;LCKTT - DO THE REAL LOCKING

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL LCKTT

;RETURNS +1: ALWAYS, NOINT

;PRESERVES ALL AC'S

LCKTT:	SETZRO TTDAL,(T2)	;FLUSH DEALLOCATE REQUEST IF ANY
	SKIPE INSKED		;DON'T LOCK IF IN SCHEDULER
	RET
	NOINT			;BE NOINT WHILE LINE IS LOCKED
LCKTT1:	INCR TTLCK,(T2)		;BUMP THE LOCK
	JE TTLCK,(T2),LCKTT2	;CHECK FOR BAD LOCK
	OKSKD1			;ALLOW SCHEDULING ONCE LOCKED
	RET
LCKTT2:				;HERE TO HANDLE BAD LOCK
	BUG(TTLOKB)		;KILL US
	JRST LCKTT1		;HANDLE IF WE ARE CONTINUED FROM BUGHLT
;ULKTTY - CLEAR LOCK BIT

;ACCEPTS:
;	T2/ OUTPUT FROM LCKTTY

;	CALL ULKTTY

;RETURNS +1: ALWAYS, OKINT

;CLOBBERS NO AC'S

ULKTTY::SKIPN INSKED		;DON'T DECREMENT COUNT IF IN SCHEDULER
	SKIPG T2		;NO COUNT IF INACTIVE OR BECOMING ACTIVE
	RET
	JE TTLCK,(T2),ULKTMP	;CHECK FOR OVERLY DECREMENTING
	DECR TTLCK,(T2)		;DECREMENT LINE'S LOCK COUNT
	IFQN. TTDAL,(T2)	;DID SOMEBODY TRY TO DEALLOCATE THIS?
	  CALL TTYDED		;YES, DO IT NOW
	   NOP
	ENDIF.
	OKINT			;ALLOW INTERRUPTS NOW THAT BLOCK IS UNLOCKED
	RET

ULKTMP:	SAVELN
	LOAD T2,TINTL,(T2)
	BUG(ULKBAD,<<T2,D>>)
	OKINT
	RET

;ULKTT - DECREMENT THE LOCK COUNT. CALLED ONLY FROM FREE

ULKTT::	JE TTLCK,(T2),ULKTT2	;CHECK FOR BAD UNLOCK
	DECR TTLCK,(T2)		;UNLOCK THE TTY
ULKTT1:	IFQN. TTDAL,(T2)	;DID SOMEBODY TRY TO DEALLOCATE THIS?
	  CALL TTYDED		;YES, DO IT NOW
	   NOP
	ENDIF.
	RET
ULKTT2:				;HERE ON BAD UNLOCK
	BUG(TTULKB)		;KILL US
	JRST ULKTT1		;HANDLE IF CONTINUE AFTER BUGHLT
;ROUTINES TO ADJUST LOCK STATUS BEFORE AND AFTER DISMISSING.
;THIS CODE PUTS AN ENTRY ON THE JSB STACK IN THE EVENT THE PROCESS
;IS INTERRUPTED WHILE DISMISSED.

;PUT ENTRY ON JSB STACK, AND GO OKINT
;ACCEPTS:	T2/ ADDRESS OF DYNAMIC DATA

	REPEAT 0,<		;NOT USED
TTYDIS:	JE TTLCK,(T2),R		;THIS IS A HACK TO KEEP FSIINI HAPPY.
				;SINCE THE SWAPPABLE MONITOR IS NOT
				;LOADED YET, WE CAN'T USE THE NORMAL
				;LOCKING STATEGY. THIS IS ACCEPTABLE
				;HERE SINCE NO CONFUISION CAN RESULT.
	SKIPE INSKED		;IN THE SCHEDULER?
	RET			;YES. DON'T MANIPULATE THE JSB STACK
	SAVET			;SAVE ALL REGISTERS
	LOAD T1,TINTL,(T2)	;GET INTERNAL LINE NUMBER
	MOVEI T2,STKCD3		;GET PROPER CODE
	CALL JSBSTK		;QUEUE UP THE ENTRY
	OKINT			;ALLOW INTS NOW
	RET			;AND DONE

;DISMISS WAS SATISFIED. DEQUEUE THE ENTRY AND GO NOINT

TTYAWK:	JE TTLCK,(T2),R		;THIS IS A HACK TO KEEP FSIINI HAPPY.
				;SINCE THE SWAPPABLE MONITOR IS NOT
				;LOADED YET, WE CAN'T USE THE NORMAL
				;LOCKING STATEGY. THIS IS ACCEPTABLE
				;HERE SINCE NO CONFUISION CAN RESULT.
	SKIPE INSKED		;IN THE SCHEDULER?
	RET			;YES. DON'T MANIPULATE THE JSB STACK
	SAVET			;SAVE ALL REGISTERS
	NOINT			;PREVENT INTS
	LOAD T1,TINTL,(T2)	;GET INTERNAL LINE NUMBER
	MOVEI T2,STKCD3		;GET TYPE
	CALLRET JSFRMV		;REMOVE ENTRY AND DONE
	>			;END OF REPEAT 0
	SUBTTL ALLOCATION/DEALLOCATION

;TTYASO - ASSIGN TERMINAL FOR OPENF

;ACCEPTS:
;	T2/ LINE NUMBER

;	CALL TTYASO

;RETURNS +1: FAILED,
;		T1/ 1B0 + ADDRESS OF ROUTINE IF NEED TO DISMS
;		T1/ ERROR CODE IF FAILED
;	 +2: SUCCEEDED

;PRESERVES T2

	SWAPCD
TTYASO::SAVELN
	STKVAR <TTYALN>
	MOVEM T2,TTYALN		;SAVE LINE NUMBER
	NOSKD1			;NO STATE CHANGE PLEASE
	CALL STADYN		;IS LINE FULLY ACTIVE?
	 SKIPA			;NO.
	JRST TTYAO4		;FULLY ACTIVE. HANDLE SPECIALLY
	JUMPLE T2,TTYAO1	;SEE IF SHORT OR MESSAGE BLOCK IN USE

;TTACTL>0. LINE IS TEMPORARILY ACTIVE FOR SYSTEM MESSAGE OR SENDALL
;WAIT UNTIL TTACTL<=0 OR FULL-LENGTH BLOCK HAS BEEN ASSIGNED AND TRY AGAIN.

	OKSKD1
	MOVE T1,[TSACT1]	;YES. SET UP TO WAIT
	TXO T1,1B0		;INDICATE IT'S A ROUTINE ADDRESS
	RETBAD 			;LET CALLER DO A DISMS

TTYAO1:	JUMPE T2,TTYAO2		;SEE IF LINE BECOMING ACTIVE

;TTACTL<0. LINE IS BECOMING ACTIVE (ANOTHER FORK IN THIS JOB IS
;INITIALIZING IT). WAIT UNTIL LINE IS INACTIVE OR HAS FULL-LENGTH BLOCK
;AND TRY AGAIN

	OKSKD1
	MOVE T1,[TSACT2]	;YES. SET UP TO WAIT
	TXO T1,1B0		;INDICATE IT'S A ROUTINE ADDRESS
	RETBAD 			;LET CALLER DO A DISMS

;TTACTL=0. ASSIGN A DYNAMIC BLOCK FOR THE LINE AND INITIALIZE ITS VALUES.

TTYAO2:	MOVE T2,TTYALN		;GET LINE NUMBER
	SETOM TTACTL(T2)	;INDICATE BEING INITIALIZED
	OKSKD1
	LOAD T1,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T1,DDLTBL(T1)	;GET LONG BLOCK LENGTH
	HRLI T1,.RESP3		;T1/ INDICATE PROCESS CONTEXT
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 JRST TTYAO3		;NO SPACE AVAILABLE
	MOVE T2,TTYALN		;T2/ LINE NUMBER, T1/ ADDRESS OF DYNAMIC BLOCK
	CALL TTSETL		;INITIALIZE VALUES FOR TERMINAL
	MOVEM T1,TTACTL(T2)	;MAKE STATIC DATA POINT TO DYNAMIC
	RETSKP

;FAILED TO GET RESIDENT STORAGE. LET THE OPENF FAIL

TTYAO3:	MOVE T2,TTYALN		;GET LINE NUMBER
	SETZM TTACTL(T2)	;RESTORE TTACTL TO PREVIOUS VALUE
	RETBAD

;LINE WAS ALREADY ACTIVE. IF PERMANENT, IT MAY BE BECOMING
;ACTIVE. IN THAT CASE, MAKE IT ACTIVE.

TTYAO4:	OKSKD1
	JE <TTBAC,TTPRM>,(T2),RSKP	;IF NOT BECOMING ACTIVE, OK AS IS
	MOVE T3,JOBNO		;GET THIS JOB'S NUMBER
	STOR T3,TCJOB,(T2)	;INDICATE IT OWNS THIS TERMINAL
	SETZRO TTBAC,(T2)	;INDICATE NOT BECOMING ACTIVE
	RETSKP

	ENDSV.			;END STKVAR

;TSACT1 - SCHEDULER TEST TO SEE IF LINE IS AVAILABLE

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;CAUSES WAKEUP IF LINE IS INACTIVE, BECOMING ACTIVE, OR HAS A FULL-LENGTH
;BLOCK

	RESCD
TSACT1::HRRZ T2,T1		;GET LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JUMPG T2,0(T4)		;NOT FULLY ACTIVE
	JRST 1(T4)		;FULLY ACTIVE. WAKEUP

;TSACT2 - SCHEDULER TEST TO SEE IF LINE IS AVAILABLE

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;CAUSES WAKEUP IF LINE IS INACTIVE OR FULLY ACTIVE

TSACT2:	HRRZ T2,T1		;GET LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	JUMPN T2,0(T4)		;NOT FULLY ACTIVE
	JRST 1(T4)		;FULLY ACTIVE. WAKEUP
;TTYASC - ASSIGN TERMINAL AS CONTROLLING TERMINAL FOR A JOB

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTYASC

;RETURNS +1: FAILED,
;		T1/ ERROR CODE
;	 +2: SUCCEEDED

;PRESERVES T2

	SWAPCD
TTYASC::SAVELN
	STKVAR <TTYALN>
	MOVEM T2,TTYALN		;SAVE LINE NUMBER
	NOSKD1
	CALL STADYN		;POINT TO DYNAMIC DATA
	 SKIPA			;NOT FULLY ACTIVE
	JRST TTYAC4		;FULLY ACTIVE. GO HANDLE SPECIALLY
	JUMPLE T2,TTYAC1	;SEE IF SHORT OR MESSAGE BLOCK IN USE

;TTACTL>0. LINE IS TEMPORARILY ACTIVE FOR SYSTEM MESSAGE OR SENDALL.
;FAIL ON THE ASSUMPTION THAT THE USER WILL TYPE ANOTHER CTRL/C.

	OKSKD1
	RETBAD (TTYX01)

;TTACTL<=0. LINE IS INACTIVE OR BECOMING ACTIVE.  ASSIGN STORAGE AND
;INITIALIZE VALUES

TTYAC1:	MOVE T2,TTYALN		;GET LINE NUMBER
	SETOM TTACTL(T2)	;INDICATE BEING INITIALIZED
	OKSKD1
	LOAD T1,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T1,DDLTBL(T1)	;GET LONG BLOCK LENGTH
	HRLI T1,.RESP3		;T1/ INDICATE PROCESS CONTEXT
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 JRST TTYAC3		;NO SPACE AVAILABLE
	MOVE T2,TTYALN		;T2/ LINE NUMBER, T1/ ADDRESS OF DYNAMIC BLOCK
	CALL TTSETL		;INITIALIZE VALUES FOR TERMINAL
	MOVEM T1,TTACTL(T2)	;MAKE STATIC DATA POINT TO DYNAMIC
	RETSKP

;FAILED TO GET RESIDENT STORAGE. FAIL

TTYAC3:	MOVE T2,TTYALN		;GET LINE NUMBER
	SETZM TTACTL(T2)	; INDICATE INACTIVE
	RETBAD

;LINE WAS ALREADY ACTIVE. IF PERMANENT, IT MAY BE BECOMING
;ACTIVE. IN THAT CASE, MAKE IT ACTIVE.

TTYAC4:	OKSKD1
	JE TTPRM,(T2),RSKP
	MOVE T3,JOBNO		;GET THIS JOB'S NUMBER
	STOR T3,TCJOB,(T2)	;INDICATE IT OWNS THIS TERMINAL
	SETZRO TTBAC,(T2)	;INDICATE NOT BECOMING ACTIVE
	RETSKP

	ENDSV.			;END STKVAR
;TTYDEA - DEALLOCATE A DYNAMIC BLOCK

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTYDEA

;RETURNS +1: FAILURE, (NO CASES CURRENTLY)
;	 +2: SUCCESS

	RESCD

TTYDED:	SAVELN			;ENTRY WITH T2/ DYNAMIC PTR
	STKVAR <TTYDLN,TTYDAD>
	DYNST
	JRST TTYDE4

TTYDEA::TDCALL S,<<NT,NVTDET>>
TTYDE0:	SAVELN
	STKVAR<TTYDLN,TTYDAD>
TTYDE4:	MOVEM T2,TTYDLN		;SAVE INTERNAL LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST TTYDE1		;NOT ACTIVE. SHOULDN'T HAPPEN
	JN TTPRM,(T2),TTYDE3	;HANDLE PERMANENT BLOCK SPECIALLY
	JN TTLCK,(T2),TTYDE2	;IF LOCKED, WAIT FOR COUNT TO GO TO 0
	JN TTSAL,(T2),TTYDE2	;IF DOING SENDALL, WAIT UNTIL DONE
	MOVEM T2,TTYDAD		;SAVE ADDRESS OF DYNAMIC DATA
	NOSKD1			;NO SCHEDULING WHILE CHNOFF IN FORCE
	CHNOFF DLSCHN		;TURN OFF TTY CHANNEL
	CALL TTRLOB		;RELEASE OUTPUT BUFFERS
	MOVE T2,TTYDAD		;T2/ ADDRESS OF DYNAMIC DATA
	CALL TTCIBF		;CLEAR INPUT, RELEASE BUFFERS IF NEEDED
	MOVE T2,TTYDAD		;DYNAMIC DATA ADDRESS AGAIN
	CALL TTXONA		;MAKE SURE IS NOT X-OFF'ED
	MOVE T2,TTYDAD		;GET DYN ADDRESS
	SETZRO TT%PGM,TTFLGS(T2) ;INSURE WE WILL TURN XOFF FLAGS OFF
	TDCALL D,<<FE,TTEXF>,<MC,MCEXF>> ;SET FE XOFF RECOGNITION
	MOVE T2,TTYDLN		;GET BACK LINE NUMBER
	SETZM TTACTL(T2)	;INDICATE NO DYNAMIC DATA
	CHNON DLSCHN		;TURN CHANNEL BACK ON
	OKSKD1			;OK TO SCHED NOW
	MOVE T1,TTYDAD		;T1/ ADDRESS OF BLOCK
	CALL RELRES		;RELEASE THE RESIDENT SPACE
	RETSKP			;SUCCESS

;LINE IS NOT ACTIVE. THIS SHOULD NOT HAPPEN

TTYDE1:	MOVE T2,TTYDLN		;GET LINE NUMBER
	BUG(TTNAC7,<<T2,D>>)
	RETSKP

;DYNAMIC DATA IS LOCKED OR SENDALL IN PROGRESS.  REQUEST DEALLOCATION
;WHEN FINISHED

TTYDE2:	SETONE TTDAL,(T2)	;REQUEST DEALLOCATION WHEN FINISHED
	RETSKP

;PERMANENT BLOCK. DON'T DEALLOCATE IN THE USUAL WAY

TTYDE3:	SETZM TTPSI(T2)		;CLEAR INTERRUPTS
	SETZM TTDPSI(T2)	; AND DEFERRED INTERRUPTS
	SETONE TCJOB,(T2)	;INDICATE NO OWNING JOB
	MOVE T1,TTYDLN		;T1/ LINE NUMBER
	CALL CHKPTY		;IS THIS A PTY?
	 RETSKP			;NO.
	CALL PTYFIN		;YES. INDICATE HUNGRY
	RETSKP

	ENDSV.			;END STKVAR
;ASGMSG - ASSIGN BLOCK FOR MESSAGE
;ASGMSL- ASSIGN FULL LENGTH MESSAGE BLOCK FOR SPECIAL PURPOSES

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL ASGMSG
;	CALL ASGMSL

;RETURNS +1: FAILURE,
;		T1/ ERROR CODE
;	 +2: SUCCESS,
;		T2/ LINE NUMBER

	RESCD
ASGMSG:	TDZA T4,T4		;EXTRA LENGTH
ASGMSL:	MOVEI T4,TTDDLN-MSGLEN	;"LONG MESSAGE BLOCK"
	STKVAR <ASGMLN>
	MOVEM T2,ASGMLN		;SAVE LINE NUMBER
	MOVSI T1,.RESP2		;INDICATE CAN'T TAKE PAGE FAULT
	HRRI T1,MSGLEN(T4)	;T1/ (SIZE,,PRIORITY)
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 RETBAD			;FAILED
	MOVE T2,ASGMLN		;GET LINE NUMBER
	CALL TTSETM		;INITIALIZE VALUES
	SETONE TTMES,(T1)	;INDICATE MESSAGE BLOCK
	TXO T1,TTSHBK		;SAY IS A SPECIAL BLOCK
	MOVEM T1,TTACTL(T2)	;MAKE STATIC POINT TO DYNAMIC
	AOSG TTQCNT		;FIRST SPECIAL LINE?
	MOVEM T2,TTCQLN		;YES. START SCAN HERE THEN
	TXZ T1,TTSHBK		;RETURN ADDRESSABLE BLOCK
	RETSKP			;INDICATE SUCCESS

	ENDSV.			;END STKVAR
;ASHSHT - ASSIGN A SHORT (SENDALL) BLOCK

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL ASGSHT

;RETURNS +1: FAILURE,
;		T1/ ERROR CODE
;	 +2: SUCCESS,
;		T1/BUFFER ADDRESS
;		T2/ LINE NUMBER

	SWAPCD

ASGSHT:	LOAD T1,TTSTY,(T2)	; Get line type
	CAIN T1,TT.NVT		; NVT?
	RET			; Yes, don't do this then
	STKVAR <ASGSLN>
	MOVEM T2,ASGSLN		;SAVE LINE NUMBER
	MOVSI T1,.RESP3		;INDICATE CAN TAKE PAGE FAULT
	HRRI T1,MSGLEN		;T1/ (SIZE,,PRIORITY)
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 RETBAD			;FAILED
	MOVE T2,ASGSLN		;GET LINE NUMBER
	CALL TTSETS		;INITIALIZE VALUES
	SETONE TTSHT,(T1)	;INDICATE MESSAGE BLOCK
	RETSKP			;INDICATE SUCCESS

	ENDSV.			;END STKVAR
	SUBTTL JSYS SUPPORT ROUTINES

;TTCOBF - CLEAR OUTPUT BUFFER

;TTCOB1 - ENTRY POINT FOR CALLING FROM WITHIN TTYSRV

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTCOB1

;RETURNS +1: ALWAYS

;IF LINE HAS NO OUTPUT BUFFERS, RETURNS QUIETLY. IF IT HAS A MESSAGE BLOCK,
;IGNORES LINKS.  IF FULLY ACTIVE, HANDLES LINKS

	RESCD

TTCOB1:	SAVELN			;SAVE LINE NUMBER
	CALL LCKTTY		;POINT TO DYNAMIC DATA
	 JRST [	JUMPLE T2,TTCOB3 ;IF BECOMING ACTIVE OR INACTIVE, NO BUFFERS
		JE TTMES,(T2),TTCOB3 ;IF NOT A MESSAGE BLOCK, NO BUFFERS
		CALL TTCBF9	;MESSAGE BLOCK (HAS NO LINKS). CLEAR
		CALLRET ULKTTY]	;ALLOW DEALLOCATION
	CALL TTCBF9		;DO IT

TTCOB3:	CALLRET ULKTTY		;ALLOW DEALLOCATION
;TTCOBF - ENTRY FOR OUTSIDE OF TTYSRV

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCOBF

;RETURNS +1: ALWAYS

;LINE MUST BE FULLY ACTIVE AND ITS DYNAMIC BLOCK LOCKED WHEN CALLED FROM OUTSIDE

TTCOBF::SAVELN
TTCOB2:	MOVE C,TTLINK(B)	;GET LINES THAT THIS LINE IS LINKED TO
	CAMN C,[-1]		;ANY LINKS?
	CALLRET TTCBF2		;NO. JUST CLEAR THIS LINE'S BUFFERS

;LINE IS LINKED TO ONE OR MORE LINES. LOOP THROUGH TTLINK, PICKING UP
;A LINE NUMBER AND CLEARING ITS OUTPUT BUFFERS UNTIL ALL LINKS ARE
;PROCESSED

	PUSH P,B		;SAVE ADDRESS OF DYNAMIC DATA
TTCBF3:	SETZ B,			;INITIALIZE TO GET LINE NUMBER
	LSHC B,^D9		;GET NEXT LINE LINKED TO
	CAIN B,777		;THIS FIELD BEING USED?
	JRST TTCBF4		;NO
	CALL LCKTTY		;GET ADDRESS OF DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY
		JRST TTCBF4]	;NOT ACTIVE. DON'T DO ANYTHING
	PUSH P,C		;SAVE LINK WORD
	CALL TTCBF2		;GO CLEAR BUFFER FOR LINKED LINE
	CALL ULKTTY		;ALLOW DEALLOCATION
	POP P,C			;RESTORE LINK WORD
TTCBF4:	JUMPN C,TTCBF3		;GO DO ALL OF THEM

;ALL LINKS HAVE BEEN PROCESSED. NOW PROCESS THE ORIGINAL LINE AND QUIT

	POP P,B			;RESTORE ADDRESS OF DYNAMIC DATA
	CALLRET TTCBF2		;CLEAR BUFFERS FOR THIS LINE
;TTCBF2 - CLEAR OUTPUT BUFFER FOR ONE LINE

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCBF2

;RETURNS +1: ALWAYS

;CALLER MUST HAVE CALLED LCKTTY ON THIS LINE

TTCBF2:	CALL SKCOE		;SKIP CTRL-O INTERRUPT ENABLED
	 SKIPN CTRLOF		;NEW STYLE?
	JRST TTCBF9		;NO
	CALL OWNTTY		;YES, TTY OWNED BY THIS JOB?
	JRST TTCBF9		;NO
	JE TTFLO,(T2),R		;DO NOTHING UNLESS FLUSHING OUTPUT
	NOSKD1
	CHNOFF DLSCHN
TTCBF8:	CALL GTOCHR		;GET CHAR FROM OUTBUF
	 JRST TTCBF7		;NOW EMPTY
	CAIE T1,TTOMRK		;A MARKER?
	JRST TTCBF8		;NO, KEEP FLUSHING
	SETZRO TTFLO,(T2)	;CLEAR FLUSH FLAG
	JRST TTCBF7		;DONE

TTCBF9:	NOSKD1
	CHNOFF DLSCHN		;TURN OFF CHANNEL ALSO
	CALL CFEOB		;CLEAR FE OUTBUF
TTCOB5:	SETZM TTOCT(2)		;ZERO OUTPUT COUNT
	SETZB 3,TTOOUT(2)	;CLEAR OUTPUT POINTER
	EXCH 3,TTOIN(2)		;CLEAR INPUT POINTER
	CALL TTRLBF		;RELEASE BUFFERS
TTCBF7:	CHNON DLSCHN
	CALL TTXONA		;REACTIVATE OUTPUT IF NECESSARY
	OKSKD1
	TDCALL D,<<NT,NVTCOB>>	;CLEAR NVT OUTPUT BUFFER (SEND SYNCH)
	CALL CHKBKO		;PERHAPS FORK WAITING FOR OBUF EMPTY
	RET

;OWNTTY - SKIP IF THIS TTY IS OWNED BY THIS JOB
; T2/ DYNAMIC PTR

OWNTTY:	SKIPE INSKED		;SCHED?
	RET			;YES, NOT A JOB
	LOAD T1,TCJOB,(T2)	;GET CONTROLLING JOB FOR THIS TTY
	CAME T1,JOBNO		;THIS JOB?
	RET			;NO
	RETSKP			;YES

;CLEAR OUTBUF OF FE
; T2/ DYNAMIC PTR
; RETURN +1 ALWAYS

CFEOB:	TDCALL D,<<FE,TTCOB4>,<MC,MCCOBF>>
	RET
;TTCIBF - CLEAR INPUT BUFFER

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCIBF (TTCIB0 TO CLEAR RESCAN POINTER TOO)

;RETURNS +1: ALWAYS,
;		T2 PRESERVED

TTCIB0::PUSH P,2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	CAMN 2,CTRLTT		;CONTROLLING TTY?
	SETZM RSCNPT		;YES, CLEAR RESCAN POINTER TOO
	POP P,2			;RESTORE ADDRESS OF DYNAMIC DATA

TTCIBF::SAVELN			;SAVE LINE NUMBER
	NOSKD1
	SETZRO <TTRFG>,(T2)	;CLEAR BKJFN FLAG
	SETZB T1,TTICT(T2)	;CLEAR COUNT OF INPUT CHARACTERS
	STOR T1,TYLCH,(T2)	;CLOBBER LAST CH IN CASE CR
	SETZB 3,TTIOUT(T2)	;CLEAR POINTER FOR REMOVING CHARACTERS
	EXCH 3,TTIIN(2)		; AND POINTER FOR ADDING CHARACTERS
	CALL TTRLBF		;RELEASE INPUT BUFFERS
	OKSKD1
	CALL SNDXON		;SEND XON IF NEEDED
	RET
	SWAPCD
;TTSIBE - SKIP IF INPUT BUFFER IS EMPTY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ BYTE SIZE OF OPEN OR 0 IF A JFN WAS NOT GIVEN BY CALLER

;	CALL TTSIBE

;RETURNS +1: INPUT BUFFER IS NOT EMPTY
;		T1/ COUNT OF CHARACTERS
;	 +2: INPUT BUFFER IS EMPTY
;		T1/ 0

;THIS ROUTINE COUNTS NUMBER OF CHARACTERS AVAILABLE FOR INPUT FROM LINE
;IN T2.  THE COUNT IS RETURNED IN T1.  THE QUANTITIES ACCUMULATED ARE
;THE FOLLOWING:
;
;	1)	RECIRCULATED CHARACTER, LIKE IF BKJFN WAS DONE
;	2)	RSCANED DATA(*)
;	3)	TYPEAHEAD THAT'S STILL IN THE INPUT BUFFER
;	4)	PHANTOM LINEFEED, ASSUMED IF LAST READ CHARACTER WAS CR
;
;	(*)	THERE IS A BUG HERE.  THIS ROUTINE ONLY EXAMINES THE
;		RSCAN BUFFER IF THE TERMINAL IS THE PROGRAM'S
;		CONTROLLING TERMINAL.  THE CORRECT PROCEDURE IS TO
;		EXAMINE THE RSCAN BUFFER FOR WHICHEVER TERMINAL IS
;		BEING INTERRAGATED.  THIS IS A BIT TRICKY, SINCE THE
;		RSCAN STATUS IS STORED IN SOMEON'S JSB, AND YOU FIRST
;		HAVE TO FIGURE OUT WHO, THEN CALL SETJSB, ETC...

TTSIBE::LOAD T1,TTRFG,(T2)	;0 IF NO RECIRCULATED CHARACTER, 1 IF SO
	PUSH P,T3		;SAVE THE BYTE SIZE
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	MOVE T3,FORKN		;GET JOB FORK NUMBER
	LOAD T3,FRKTTY,(T3)	;GET POSSIBLE FORK CONTROLLING TERMINAL
	CAIE T3,.TTDES(T2)	;IS SIBE BEING DONE ON FORK'S OWN TERMINAL?
	CAMN T2,CTRLTT		;NO, IS THIS THE CONTROLLING TERMINAL FOR THIS JOB?
	SKIPN T3,RSCNPT		;YES. GET RESCAN POINTER
	JRST TTSIB1		;NOT CONTROLLING OR POINTER IS 0
TTSIB2:	ILDB T4,T3		;PICK UP CHARACTER FROM RSCAN BUFFER
	JUMPE T4,TTSIB1		;LEAVE LOOP IF NO MORE.
	AOJA T1,TTSIB2		;COUNT LENGTH OF RSCAN BUFFER
TTSIB1:	POP P,T2		;RESTORE ADDRESS OF DYNAMIC DATA
	POP P,T4		;GET BACK BYTE SIZE
	ADD T1,TTICT(T2)	;ADD CHARACTERS IN REGULAR INPUT BUFFER
	LOAD T3,TT%DAM,TTFLGS(T2) ;GET CURRENT MODE
	CAIE T4,10		;BINARY MODE OPEN ON THE JFN?
	JUMPN T3,[LOAD T3,TYLCH,(T2) ;NOT BINARY, CHECK LAST CHAR
		  LOAD T4,TYLMD,(T2) ; GET DATA MODE OF LAST CHAR
		  CAIN T3,.CHCRT ;CR?
		  CAIN T4,.TTBIN ; YES, INPUT IN NON-BINARY?
		  JRST .+1	; NO TO EITHER, NO LF.
		  AOJA T1,.+1]	;YES TO BOTH, LF STILL AVAILABLE
	CAILE T1,0		;POSITIVE COUNT?
	RET			;YES, SO TAKE NON-SKIP RETURN
	RETSKP			;NO. SKIP
;TTSOBE - SKIP IF OUTPUT BUFFER IS EMPTY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSOBE

;RETURNS +1: OUTPUT BUFFER NOT EMPTY
;		T1/ COUNT
;	 +2: OUTPUT BUFFER IS EMPTY
;		T1/ 0
	RESCD

TTSOBE::CALL SKCOE		;SKIP IF CTRL-O INTERRUPT ENABLED
	 SKIPN CTRLOF		;NEW STYLE?
	IFSKP.
	  CALL OWNTTY		;JOB OWN TTY?
	  IFSKP.
	    MOVEI T1,TTOMRK	;YES, JUST PUT MARKER IN STREAM
	    CALL TCOUM
	    SETZ T1,
	    RETSKP		;SAY OUTBUF EMPTY
	  ENDIF.
	ENDIF.
	JN TTOTP,(T2),R		;RETURN NOSKIP IF OUTPUT IS STILL ACTIVE
	SKIPLE 1,TTOCT(2)	;BYTES STILL IN -10 MEMORY
	RET			;NO. NONSKIP
	TDCALL D,<<FE,TTSBEF>,<MC,MCSBEF>>
	 RETSKP			;DEVICE BUFFER (IF ANY) ALSO EMPTY
	RET			;DEVICE BUFFER NOT EMPTY

;TTSOBF - SKIP IF OUTPUT BUFFER IS FULL

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSOBF

;RETURNS +1: OUTPUT BUFFER IS NOT FULL
;		T1/ COUNT
;	 +2: OUTPUT BUFFER IS FULL
;		T1/ COUNT
	SWAPCD

TTSOBF::LOAD 3,TOMAX,(2)	;CAPACITY OF OUTPUT BUFFER
	MOVE 1,TTOCT(2)		;GET NUMBER OF CHARACTERS IN BUFFER
	CAIL 1,0(3)		;FULL?
	RETSKP			;YES. SKIP
	RET			;NO. NONSKIP
;TTDOBE - DISMISS UNTIL OUTPUT BUFFER IS EMPTY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTDOBE

;RETURNS +1: NEED TO RETRY
;	+2 DONE. BUFFER IS EMPTY

;WAITS UNTIL OUTPUT BUFFER IS EMPTY

TTDOBE::CALL SKCOE		;SKIP IF CTRL-O INTERRUPT ENABLED
	 SKIPN CTRLOF		;NEW STYLE?
	IFSKP.
	  MOVEI T1,TTOMRK	;YES, JUST PUT MARKER IN OUTPUT STREAM
	  CALL TCOUM
	  RETSKP
	ENDIF.
	CALL TSOBED		;SEE IF OUTPUT IN PIPE
	IFSKP. <RETSKP>		;NO, RETURN OK

;CHARACTERS ARE PRESENT. DISMISS UNTIL THEY ARE GONE

TTDBE1:	TDCALL D,<<PT,CHKPTA>>	;CHECK FOR INTERRUPT NEEDED
	SETONE TTBKO,(T2)	;NOTE WAITING FOR OUTPUT EVENT
	DYNST T1		;GET STATIC DATA ADDRESS
	CALL ULKTTY		;UNLOCK TTY
	HRLZS T1		;LINE # TO LH
	HRRI 1,TTOBET		;1/(LINE NUMBER,,ROUTINE TO CALL)
	MOVSI T2,FHV5		;BLOCK PRIORITY
	HDISMS
	RET			;SAY NEED TO RETRY
;TTDIBE - DISMISS UNTIL INPUT BUFFER IS EMPTY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTDIBE

;RETURNS +1: NEED TO RETRY
;	+2 DONE. BUFFER EMPTY

;WAITS UNTIL INPUT BUFFER IS EMPTY

TTDIBE::SKIPG TTICT(T2)		;BUFFER EMPTY NOW?
	RETSKP
	DYNST T1		;GET LINE NUMBER
	CALL ULKTTY		;UNLOCK TTY
	HRLZS T1		;LINE # TO LH
	HRRI 1,TTIBET		;1/(LINE NUMBER,,ROUTINE TO CALL)
	MDISMS
	RET			;NEED TO RETRY
;SCHEDULER TESTS FOR TTDOBE AND TTDIBE
	RESCD

;TTOBET - CAUSES WAKEUP IF OUTPUT BUFFER IS EMPTY (INCLUDING CHARACTERS
;EN ROUTE TO THE LINE)

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

TTOBET::PUSH P,T4		;PUT RETURN ON STACK SO RET, RETSKP WORK
	HRRZ T2,T1		;GET LINE NUMBER
	JRST TTOBE0		;DO THE WORK

;HERE FOR NORMAL CALL
; T2/ LINE NUMBER
; RETURN +1 OUT BUFFER NOT EMPTY
;	+2 OUT BUFFER EMPTY

TSOBEX:	SAVEAC <T2>
TTOBE0:	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 RETSKP			;NOT ACTIVE. THIS SHOULDN'T HAPPEN

;ENTER HERE IF DYNAMIC PTR  IN T2
; T2/ DYNAMIC PTR
; RETURN +1: NOT EMPTY
;	+2: EMPTY

TSOBED:	SKIPE TTOCT(T2)		;IS OUTPUT BUFFER EMPTY?
	RET			;NO. DON'T WAKE UP
	JN TTOTP,(T2),R		;NO IF STILL OUTPUT ACTIVE
	TDCALL D,<<FE,TTSBEF>,<MC,MCSBEF>> ;CHECK DEVICE BUFFERING IF ANY
	IFSKP. <RET>		;SKIPS IF BUFFER *NOT* EMPTY
	SETZRO TTBKO,(T2)	;NOTE WAIT COMPLETED
	RETSKP

;TTIBET - CAUSES WAKEUP IF INPUT BUFFER IS EMPTY

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

TTIBET:	HRRZ T2,T1		;GET LINE NUMBER
	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 JRST 1(T4)		;NOT ACTIVE. THIS SHOULDN'T HAPPEN
	SKIPE TTICT(T2)		;IS INPUT BUFFER EMPTY?
	JRST 0(4)		;NOT EMPTY. DON'T WAKE UP
	JRST 1(4)		;EMPTY. WAKE UP
;TAB GET/SET - PHASED OUT
	SWAPCD

TTGTBS::
TTSTBS::RET

;TTRMOD - CODE TO DO THE RFMOD JSYS

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;RETURNS +1: ALWAYS
;		T1/JFN MODE WORD

;NOTE: IF PAGE WIDTH OR LENGTH IS >177, RETURNS 1 IN THESE FIELDS.
;USER MUST THEN DO AN MTOPR TO GET THE REAL VALUE

TTRMOD::SAVELN
	MOVE 1,TTFLGS(2)	;READ MODES
	LOAD T3,TPWID,(T2)	;GET WIDTH
	LOAD T4,TPLEN,(T2)	;AND PAGE LENGTH
	CAILE T3,177		;OLD MAXIMUM VALUE
	MOVEI T3,DFLWID		;TOO BIG. GET DEFAULT WIDTH
	CAILE T4,177		;OLD MAXIMUM VALUE
	MOVEI T4,DFLLEN		;TOO BIG. GET DEFAULT LENGTH
	STOR T3,TT%WID,1	;STORE OLD STYLE WIDTH
	STOR T4,TT%LEN,1	;STORE OLD STYLE LENGTH
	CALL TTCBM		;GET A TT%WAK FROM THE BREAK MASK
	DYNST			;GET LINE NUMBER
	JE TTCON,(T2),R		;RETURN UNLESS CARRIER IS ON
	SETONE TT%CAR,T1	;INDICATE CARRIER ON
	RET
;TTSMOD - SET TERMINAL MODE

;ACCEPTS:
;	T1/ JFN MODE WORD
;	T2/ ADDRESS OF DYNAMIC DATA

;RETURNS +1: ALWAYS

;IMPLEMENTS SFMOD JSYS

TTSMOD::PUSH P,1
	TRNE 1,400000		;THIS BIT MUST BE ZERO
	ITERR(DECRSV,<CALL ULKTTY>)	;NOT ZERO - ERROR RETURN
	XOR 1,TTFLGS(2)		;FIND THE CHANGED BITS
	ANDX 1,TT%OSP+TT%WAK+TT%IGN+TT%ECO+TT%DAM ;CHANGE ONLY THESE BITS
	XORM 1,TTFLGS(2)
	SKIPE CTRLOF		;NEW STYLE AND CHANGING OUTPUT SUPPRESS?
	TXNN T1,TT%OSP
	IFSKP. <
	  CALL SKCON		;SKIP IF CTRL-O NOT ENABLED
	  IFSKP. <
	  MOVEI T1,TTOMRK	;YES, PUT MARKER IN OUTPUT STREAM
	  CALL TCOUM>>
	LOAD T1,TT%DAM,TTFLGS(T2) ;GET TERMINAL DATA MODE
	STOR 1,TYLMD,(T2)	;CHANGE IT FOR PI LEV ALSO
	POP P,T1
	TXNE T1,TT%IGN		;SHOULD WE IGNORE THE TT%WAK BITS
	RET			;YES - THEN DON'T FORCE WAKE-UP
	CALL TTCFM		;COMPUTE AND SET FULL MASK
	CALLRET TTFWAK		;FORCE WAKEUP
;TTRPOS - READ POSITIONS

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTRPOS

;RETURNS +1: ALWAYS,
;	T1/ (LINE POSITION WITHIN PAGE,,CHARACTER POSITION WITHIN LINE)

TTRPOS::MOVE 1,TTLPOS(2)	;READ POSITION
	RET

;TTSPOS - SET POSITION

;ACCEPTS:
;	T1/ (LINE POSITION WITHIN PAGE,,CHARACTER POSITION WITHIN LINE)
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSPOS

;RETURNS +1: ALWAYS

TTSPOS::MOVEM 1,TTLPOS(2)	;SET LINE CHARACTER POSITION
	RET

;TTRCOC - READ CONTROL CHARACTER OUTPUT CONTROL WORDS

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTRCOC

;RETURNS +1: ALWAYS,
;		T1/ FIRST WORD
;		T3/ SECOND WORD

TTRCOC::MOVE 1,FCMOD1(2)	;READ CONTROL CHARACTER MODES
	MOVE 3,FCMOD2(2)
	RET

;TTSCOC - SET CONTROL CHARACTER OUTPUT CONTROL WORDS

;ACCEPTS:
;	T1/ FIRST WORD
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ SECOND WORD

;	CALL TTSCOC

;RETURNS +1: ALWAYS

TTSCOC::MOVEM 1,FCMOD1(2)	;SET CONTROL CHARACTER MODES
	MOVEM 3,FCMOD2(2)
	RET
;TTBKPT - "BACKUP" INPUT POINTER - CAN ONLY BACKUP ONE

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTBKPT

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TTBKPT::MOVE C,FORKN		;GET OUR FORK NUMBER
	LOAD C,FRKTTY,(C)	;GET POSSIBLE CONTROLLING TERMINAL
	CAIE C,.TTDES(B)	;USE RSCAN BUFFER IF READING FROM CONTROLLING TERMINAL
	CAMN 2,CTRLTT		;JOB CONTROLLING TTY?
	SKIPN A,RSCNPT		;YES, USING RESCAN BUFFER?
	JRST TTBKP1		;NO, DO NORMAL THING
	MOVE C,RSCNBP		;GET POINTER TO RSCAN BUFFER
	HRLI C,(POINT 7,0,34)	;SEE IF AT START OF BUFFER
	CAMN A,C
	JRST TTBKP1		;YES, DONT BACK IT UP MORE
	CALL DBP		;BACK UP BYTE POINTER
	MOVEM A,RSCNPT		;PUT IT BACK
	RETSKP			;INDICATE SUCCESS

TTBKP1:	CALL LCKTTY		;GET DYNAMIC DATA AND LOCK DYNAMIC BLOCK
	 JRST [	CALL ULKTTY	;NOT ACTIVE. CAN'T BACKUP
		RETBAD (TTYX01)]
	TMNE TTRFG,(T2)		;HAS BACKUP ALREADY BEEN DONE?
	JRST [	CALL ULKTTY	;YES. CAN'T DO ANOTHER
		RETBAD (BKJFX1)]
	SETONE TTRFG,(T2)	;NOT SET. SET IT TO BE NOTICED AT NEXT TCI
	CALL ULKTTY		;ALLOW DEALLOCATION
	RETSKP			;SUCCESS


;GET DEVICE DEPENDENT BITS

TTGSTS::LOAD T3,TLTYP,(T2)	;GET VECTOR ADR FOR THIS TTY
	SETZ T1,
	XCT PARTBL(T3)		;SEE IF PARITY BIT WOULD GET SET
	CAIE T1,0
	MOVX T1,GD%PAR		;YES
	RET			;AND DONE
;TTSSPD - CODE TO DO A SET LINE SPEED
;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER
;	USER 3/ INPUT SPEED,,OUTPUT SPEED
;
;	CALL TTSSPD
;
;RETURNS +1:	ON ERROR (CURRENTLY ONLY FOR ACJ REJECTION)
;	 +2:	ON ALL OTHER CONDITIONS
;
;SETS SPEEDS OF FRONT END LINES ONLY. IGNORES ALL OTHERS
;IMPLEMENTS THE .MOSPD FUNCTION OF MTOPR

TTSSPD::
	STKVAR <TTSLIN>		;SAVE LINE NUMBER HERE
	CAIL B,NLINES		;VALID LINE NUMBER?
	RETSKP			;NO. JUST RETURN QUIETLY
	MOVEM B,TTSLIN		;SAVE LINE NUMBER
	UMOVE C,C		;GET SPEED
	GTOKM (.GOTBR,<B,C>,[RETBAD ()]) ;DO GETOK IF NECESSARY AND RETBAD IF ERROR
	TDCALL S,<<FE,TTSSP2>,<DZ,DZSSP2>>
	MOVE B,TTSLIN		;GET BACK LINE NUMBER
	CALL LCKTTY		;GET DYNAMIC DATA ADDRESS
	 JRST [	CALL ULKTTY	;FAILED TO LOCK, NOT INTERESTING
		RETSKP]		; UNLOCK AND RETURN QUIETLY
	MOVE T1,T2		;GET DYNAMIC DATA ADDRESS
	MOVE T2,TTSLIN		;GET LINE NUMBER AGAIN
	CALL SETOBF		;SET BUFFERING
	MOVE T2,T1		;GET DYNAMIC DATA ADDRESS
	CALL ULKTTY		;DONE, UNLOCK DATA
	RETSKP			; AND RETURN SUCCESS

	ENDSV.			;END STKVAR


;TTRSPD -READ OUT THE SPEED OF A TERMINAL

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTRSPD

;RETURNS +1: ALWAYS,
;		USER T3/ (INPUT SPEED,,OUTPUT SPEED)
;			OR
;		    -1 IF NOT PHYSICAL TERMINAL OR SPEED NOT SET

;IMPLEMENTS THE .MORSP FUNCTION OF MTOPR

TTRSPD::CAIL B,NLINES		;LEGAL LINE NUMBER?
	JRST TTRSP2		;NO. RETURN NO SPEED
	TDCALL S,<<MC,RSKP>,<PT,RSKP>,<NT,RSKP>> ;SKIP IF SPEED NOT KNOWN
	 SKIPA C,TTSPWD(B)	;GET SPEED SETTING
TTRSP2:	SETO C,			;NO. ASSUME UNKNOWN
	UMOVEM C,C		;RETURN IT TO THE CALLER
	SETZ C,			;GET AN ACCUMULATOR
	TMNE TTFEM,(B)		;REMOTE?
	TXO C,MO%RMT		;YES
	TMNE TTAUT,(B)		;AUTO?
	TXO C,MO%AUT		;YES
	XCTU [HLLM C,2]		;RETURN FLAGS
	RET			;AND DONE


;TTSSIG - ROUTINE TO SET THE "IGNORE INPUT ON INACTIVE LINE" BIT
;
;ACCEPTS IN T1/ NEW SETTING (0 OR 1)
;	    T2/ LINE NUMBER
;		CALL TTSSIG
;RETURNS: +1 ALWAYS

TTSSIG::STOR T1,TTIGI,(T2)	;STORE NEW SETTING OF IGNORE INPUT BIT
	RET			;DONE, RETURN
;ROUTINE TO INIT OUTPUT BUFFERING PARAMETERS.
;CALLED FROM TTSETL AND TTSSPD.
;ONLY CALLED FOR NON-CTY ASSIGNS
;	T1/ DYNAMIC DATA ADDRESS
;	T2/ LINE NUMBER
;RETURNS:	+1 ALWAYS
;ALL REGS PRESERVED

SETOBF:	SAVET			;SAVE ALL REGS
	MOVE T3,TTSPWD(T2)	;GET LINE SPEED
	CAMN T3,[-1]		;KNOWN SPEED?
	RET			;NO. GIVE UP THEN
	HRRZS T3		;YES. GET OUTPUT SPEED
	MOVE T4,IBFRC		;ASSUME SLOW SPEED
	CAILE T3,LOWSPD		;ACCEPTABLE?
	MOVE T4,IBFRC1		;NO. GET OTHER VALUE
	MOVEM T4,TTBFRC(T1)	;SET COUNT FIELDS
	SETZ T4,0		;NO BUFFER COUNT IF LOW SPEED
	CAILE T3,LOWSPD
	MOVEI T4,OVRBCT		;SET OVER QUOTA BUFFER COUNT
	STOR T4,TTOCN,(T1)	;SET COUNT
	SETZRO TTOMX,(T1)	;INDICATE OVERBUFFER NOT IN USE
	RET			;AND DONE
; .MOTPS - ENABLE FOR PSI INTERRUPTS ON NON-CONTROLLING TERMINAL I/O

;CALL WITH:
;B/		TERMINAL NUMBER
;USER AC3/	POINTER TO USER ARGUMENT BLOCK
;BLOCK+0/	LENGTH OF BLOCK (INCLUDING THIS WORD)
;BLOCK+1/	OUTPUT PSI,,INPUT PSI

TTYNPS::ACVAR <W1>		;GET A REGISTER
	MOVE W1,B		;SAVE LINE NUMBER
	MOVEI A,1		;OFFSET 1 IN ARG BLOCK
	CALL GETWRD		;GET IT
	 RETBAD(MTOX13)		;ERROR, NO SUCH ARG
	HLRZ A,B		;GET OUTPUT PSI CHANNEL
	CALL TTNPCK		;VALIDITY CHECK IT
	 RETBAD(MTOX14)		;ILLEGAL PSI CHANNEL
	HRRZ A,B		;GET INPUT PSI CHANNEL
	CALL TTNPCK		;VALIDITY CHECK IT
	 RETBAD(MTOX14)		;ILLEGAL PSI CHANNEL
	EXCH W1,B		;GET BACK LINE NUMBER SAVE CHANNELS
	CALL LCKTTY		;LOCK TTY DATABASE
	 RETBAD(TTYX01,<CALL ULKTTY>)
	HLRZ A,W1		;GET OUTPUT PSI
	STOR A,TTOPSI,(B)	;STORE IN TTY DATABLOCK
	STOR W1,TTIPSI,(B)	;STORE INPUT PSI
	CAMN W1,[-1]		;TURNING OFF BOTH CHANNELS?
	JRST TTYNP1
	MOVE A,FORKX		;NO, GET CALLING FORK NUMBER
	STOR A,TTPSFK,(B)	;STORE IT AS WELL
	SETONE PSUTPS		;FLAG .MOTPS DONE TO THIS FORK
	JRST TTYNP2

TTYNP1:	SETONE TTPSFK,(B)
TTYNP2:	CALL ULKTTY		;RELEASE TTY DATABASE
	RETSKP			;SUCCESS

;VALIDITY CHECK AN ASSIGNABLE PSI CHANNEL

TTNPCK:	CAIE A,-1		;-1 = DEASSIGN
	CAIG A,5		;0-5 OK
	RETSKP
	CAIL A,^D24
	CAILE A,^D35
	RET			;NOT 24-35, ILLEGAL
	RETSKP			;OK

	ENDAV.			;END ACVAR W1

;TTDTPS - REMOVE CURRENT FORK FROM TTPSFK OF ALL TERMINALS

TTDTPS::SAVET
	SETZRO PSUTPS			;CLEAR BIT THAT GOT US HERE
	MOVEI T1,NLINES-1		;GET HIGHEST LINE NUMBER
TTDTP1:	MOVE T2,T1			;GET LINE NUMBER
	CALL LCKTTY			;LOCK DATABASE
	 JRST TTDTP2			;NOT FULLY ACTIVE, SKIP
	LOAD T3,TTPSFK,(T2)		;GET FORK RECEIVING INT
	CAME T3,FORKX			;SAME AS CURRENT?
	JRST TTDTP2			;NO, SKIP IT
	SETONE TTPSFK,(T2)		;YES, CLEAR IT
TTDTP2:	CALL ULKTTY			;UNLOCK DATABASE
	SOJGE T1,TTDTP1			;LOOP THRU ALL LINES
	RET
;TTSNTS - CODE TO DO A SET/RESET NON-TERMINAL STATUS FOR TTY LINE.
; THIS IS PRIMARILY FOR SUPPRESSING UNWANTED SYS MESSAGES
;ACCEPTS:
;	2/ LINE TO SET STATUS OF
;	3/ STATUS VALUE (1 TO TURN OFF MESSAGES, 0 TO TURN ON)

;	CALL TTSNTS

;RETURNS +1: ALWAYS

;IGNORES NON-FRONT END LINES

;IMPLEMENTS .MOSNT FUNCTION OF MTOPR

TTSNTS::CAIL B,NLINES		;LEGAL LINE NUMBER?
	RET			;NO. IGNORE IT THEN
	TDCALL S,<<FE,TTSNT1>,<PT,RSKP>>
	 SKIPA
	RET			;DON'T CHANGE IT
	STOR T3,TTNTS,(T2)	;SAVE THE NEW STATUS
	RET


;TTRNTS - READ TTY NON-TERMINAL DEVICE STATUS
;ACCEPTS:
;	2/ INTERNAL LINE NUMBER

;	CALL TTRNTS

;RETURNS +1 : ALWAYS,
;		3/ STATUS (0 IF SYSTEM MESSAGES ACCEPTED, 1 IF NOT)

;IMPLEMENTS .MORNT FUNCTION OF MTOPR

TTRNTS::SETZ C,			;GET DEFAULT VALUE
	CAIL B,NLINES		;A VALID TERMINAL LINE?
	RET			;NO. ASSUME DEFAULT
	LOAD T3,TTNTS,(T2)	;GET NON-TERMINAL STATUS
	RET
;TTSTIH - TEST INPUT REQUIRED

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSTIH

;RETURNS +1: ALWAYS,
;		1/ 0 IF NOT HUNGRY
;		-1 IF HUNGRY

;HUNGRY IS DEFINED AS EITHER OF THE FOLLOWING:
;	1 - THERE IS NO CONTROLLING JOB FOR THIS LINE (IE, CTRL/C
;		WILL CAUSE JOB CREATION)
;	2 - A FORK IS IN INPUT WAIT ON THE LINE AND THERE IS CURRENTLY
;		NO REASON TO WAKE IT UP (IT WILL READ A CHARACTER THAT
;		IS SENT TO THIS LINE)

;NOT HUNGRY IS RETURNED IF ANY OF THE FOLLOWING IS TRUE:
;	1. THE CONTROLLING JOB NUMBER IS INVALID
;	2. NO FORK IS IN INPUT WAIT ON THIS LINE
;	3. FORCED WAKEUP IS SET SO THAT THE WAITING FORK WILL WAKE UP SOON
;	4. THE OUTPUT BUFFER IS ABOUT TO OVERFLOW (INPUT CHARACTERS ARE THROWN
;		AWAY WHEN NOT ECHOED)
;	5. AN INTERRUPT IS PENDING FOR THE WAITING FORK

TTSTIH::LOAD T3,TCJOB,(T2)	;GET OWNING JOB IF ANY
	CAIN T3,-1		;IS THIS TERMINAL ASSIGNED?
	JRST [	JE TTBAC,(T2),TTSTI2 ;NO, HUNGRY UNLESS BECOMING ACTIVE
		JRST TTSTI1]
	CAIL T3,NJOBS		;VALID JOB NUMBER?
	JRST TTSTI1		;NO, RETURN FALSE
	LOAD T1,TWFRK,(T2)	;GET FORK IN INPUT WAIT
	CAIN T1,-1		;IS THERE ONE?
	JRST TTSTI1		;NO. SAY NOT HUNGRY
	JN TTFWK,(T2),TTSTI1	;YES. IF ABOUT TO WAKEUP BECAUSE INPUT BUFFER
	SKIPE FKINT(T1)		;IF INTERRUPT IS PENDING, SAY NOT HUNGRY
TTSTI1:	TDZA 1,1		;RETURN NOT HUNGRY
TTSTI2:	SETO 1,			;RETURN HUNGRY
	RET
;ROUTINES TO SET/READ MODE FIELDS. CALLED FROM MTOPR FUNCTIONS
;IN FILMSC

;SET/READ TERMINAL WIDTH
;ACCEPTS:	T1/ NEW WIDTH
;		T2/ ADDRESS OF DYNAMIC DATA

TTSWID::JUMPE T1,TTSWI1		;ALLOW ZERO WIDTH
	CAIL T1,10		;MUST BE GREATER THAN 10
	CAIL T1,400		;AND LESS THAN 400
	RET			;ILLEGAL WIDTH
TTSWI1:	STOR T1,TPWID,(T2)	;GOOD VALUE. STORE IT
	RETSKP			;DONE

TTRWID::LOAD T1,TPWID,(T2)	;READ WIDTH
	RET			;DONE

;SET/READ TERMINAL LENGTH
;SAME ARGS AS ABOVE

TTSLEN::JUMPE T1,TTSLE1		;ALLOW ZERO
	CAIL T1,2		;MUST BE GREATER THAN 2
	CAIL T1,400		;AND LESS THAN 400
	RET			;INVALID LENGTH
TTSLE1:	STOR T1,TPLEN,(T2)	;GOOD VALUE. STORE IT
	RETSKP			;DONE

TTRLEN::LOAD T1,TPLEN,(T2)	;READ LENGTH
	RET			;DONE

;SET/READ LINE COUNTER

TTSLC::	MOVEM A,TTLINE(B)	;STORE NEW VALUE
	RET

TTRLC::	MOVE A,TTLINE(B)
	RET

;SET/READ MAXIMUM LINE COUNTER

TTSLM::	MOVEM A,TTLMAX(B)
	RET

TTRLM::	MOVE A,TTLMAX(B)
	RET

;SET/CLEAR XOFF/XON PROCESSING BIT
;	T3/ 0=> HONOR XON/XOFF
;	   1=> DON'T

TTXSET::SKIPE T3		;WANT TO DO OUTPUT STOP?
	MOVEI T3,1		;YES. MAKE SURE BIT IS THERE
	STOR T3,TTNXO,(T2)	;STORE NEW VALUE
	CALLRET TTXONP		;AND START OUTPUT IF NECESSARY

;READ VALUE OF XOFF BIT

TTRXOB::LOAD T1,TTNXO,(T2)	;GET THE BIT
	RET			;DONE


;SET/READ PAGE PAUSE CHARACTER
; T1/ PAUSE CHARACTER ,, UNPAUSE CHARACTER
; T2/ DYNAMIC PTR

TTPPCS::HRRZ T3,T1		;CHECK UNPAUSE CHARACTER
	CAIN T3,PGMOFC		;CTRL-S?
	ITERR TTYX02		;YES, DOESN'T WORK
	STOR T1,TTUPC,(T2)
	HLRZ T1,T1
	STOR T1,TTPPC,(T2)
	RET

TTPPCR::LOAD T1,TTUPC,(T2)
	LOAD T3,TTPPC,(T2)
	HRL T1,T3
	RET
	SUBTTL FULL WAKE-UP CLASSES SUPPORT

	RESCD

;SET/READ FUNCTIONS FOR  FIELD WIDTH AND 128-CHARACTER MASK WAKE-UPS

;TTSBM - SET BREAK MASK
;ACCEPTS:	T1/ADDRESS OF FOUR WORD MASK
;		T2/DYNAMIC  DATA ADDRESS
;RETURNS:	+1, ALWAYS
;			DESTROYS T3 & T4

TTSBM::	DMOVE T3,(T1)		;FIRST TWO WORDS OF MASK
	DMOVEM T3,TTCHR1(T2)	;SET NEW VALUES
	DMOVE T3,2(T1)		;LAST TWO WORDS OF MASK
	DMOVEM T3,TTCHR3(T2)	;SET LAST TWO WORDS
	RET

;TTRBM - READ BREAK MASK
;ACCEPTS:	T1/ADDRESS OF FOUR WORD AREA
;		T2/DYNAMIC  DATA ADDRESS
;RETURNS:	+1, ALWAYS
;			DESTROYS T3 & T4

TTRBM::	DMOVE T3,TTCHR1(T2)	;GET MASK VALUES
	DMOVEM T3,(T1)		;FIRST TWO WORDS OF MASK
	DMOVE T3,TTCHR3(T2)	;GET LAST TWO WORDS
	DMOVEM T3,2(T1)		;AND STORE
	RET
;TTSFW - SET THE FIELD WIDTH
;ACCEPTS:	T1/FIELD WIDTH
;		T2/DYNAMIC DATA ADDRESS
;RETURNS:	+1,ALWAYS

TTSFW::	SUB T1,TTICT(T2)	;SUBTRACT NUMBER ALREADY IN BUFFER
	JUMPLE T1,[	SETZRO TTFCNT,(T2)	;YES - DISABLE FIELD WIDTH
		CALLRET TTFWAK]	;GO WAKE PROCESS
	STOR T1,TTFCNT,(T2)	;SET THE FIELD WIDTH
	RET

;TTRFW - READ THE FIELD WIDTH
;ACCEPTS:;		T2/DYNAMIC DATA ADDRESS
;RETURNS:	+1,ALWAYS
;			T1/FIELD WIDTH

TTRFW::	LOAD T1,TTFCNT,(T2)	;READ THE FIELD WIDTH
	RET
	SWAPCD
;ROUTINE TO COMPUTE TT%WAK BITS FROM FULL CHARACTER BIT MASK
;ACCEPTS:	T1/ TERMINAL MODE WORD
;		T2/ DYNAMIC DATA ADDRESS
;	CALL TTCBM
; RETURN +1,	T1/ UPDATED TERMINAL MODE WORD
;		T3/ CLOBBERED
;		T4/ CLOBBERED

TTCBM:	PUSH P,Q1		;SAVE Q1
	TXZ T1,TT%WAK		;WE SET THIS FIELD
	TXZ T1,TT%IGN		;MAKE SURE THE "IGNORE" BIT IS OFF
	MOVSI Q1,-NRPTB		;SET TO SCAN WORDS OF TABLE
	XMOVEI T4,TTCHR1(T2)	;POINT TO BREAK MASK WORD 1
TTSW1:	MOVE T3,0(T4)		;GET USER MASK
	TDNE T3,RPTB(Q1)	;ANY PUNCTUATION HERE?
	TXO T1,TT%WKP		;YES, SET WAKEUP ON PUNCT
	TDNE T3,RATB(Q1)	;ANY ALPHANUMERICS HERE?
	TXO T1,TT%WKA		;YES, SET WAKEUP ON ALPHA
	AOS T4
	AOBJN Q1,TTSW1		;SCAN ALL MAK WORDS
	POP P,Q1		;RESTORE Q1
	MOVE T3,TTCHR1(T2)	;GET USERS FIRST WORD
	TXNE T3,MO%WN1-400	;ANY FORMAT CONTROLS HERE?
	TXO T1,TT%WKN		;YES, SET WAKEUP ON NON-FORMAT CTL
	TXNE T3,MO%WF1-400	;ANY FORMAT CONTROLS HERE?
	TXO T1,TT%WKF		;YES, SET WAKEUP ON FORMAT CTL
	TXNE T1,TT%WAK		;SPECIAL CASE FOR ESCAPE AND RUBOUT
	RET			;ALL SET - ESCAPE AND RUBBOUT TAKEN CARE OF
	TXNE T3,400		;IS THERE AN ESCAPE?
	TXO T1,TT%WKF		;YES - THEN SET IN TT%WAK
	MOVE T3,TTCHR4(T2)	;SEE IF RUBOUT IS ON
	TXNE T3,20
	TXO T1,TT%WKF		;YES - THEN SET IT
	RET

;PUNCTUATION MASK TABLE

RPTB:	MO%WP1			;0-37
	MO%WP2			;40-77
	MO%WP3			;100-137
	MO%WP4-20		;140-177
NRPTB==.-RPTB

;ALPHANUMERICS MASK TABLE

RATB:	MO%WA1			;0-37
	MO%WA2			;40-77
	MO%WA3			;100-137
	MO%WA4-20		;140-177
; ROUTINE TO COMPUTE AND SET FULL BREAK MASK FROM THE TT%WAK BITS
;
;ACCEPTS:	T1/ MODE WORD
;		T2/ ADDRESS OF DYNAMIC DATA
;RETURNS: +1,	WITH MASK SET
TTCFM:	STKVAR <<TTSMH1,2>,<TTSMH2,2>,<TTMS1,4>>
	DMOVEM T3,TTSMH1	;SAVE T3 & T4
	DMOVEM Q1,TTSMH2	;SAVE Q1 & Q2
	SETZB T3,T4
	SETZB Q1,Q2
	TXNN T1,TT%WAK		;ARE ANY BITS SET?
	JRST TTMSET		;NO - THEN CLEAR WAKE-UP MASK AND GO
	TXO T3,400		;SET THE ESCAPE BIT
	TXO Q2,20		;SET THE RUBOUT
	TXNE T1,TT%WKF		;WANT FORMATTING CONTROLLS
	TXO T3,MO%WF1		;YES - SET FORMATTING CONTROLS
	TXNE T1,TT%WKN		;WANT NON-FORMATTING CONTROLS?
	TXO T3,MO%WN1		;YES - SET THEM UP
	TXNE T1,TT%WKP		;WANT PUNCTUATION?
	JRST [	TXO T3,MO%WP1
		TXO T4,MO%WP2
		TXO Q1,MO%WP3
		TXO Q2,MO%WP4
		JRST .+1]
	TXNE T1,TT%WKA		;WANT ALPHANUMERICS?
	JRST [	TXO T3,MO%WA1
		TXO T4,MO%WA2
		TXO Q1,MO%WA3
		TXO Q2,MO%WA4
		JRST .+1]
TTMSET:	DMOVEM T3,TTMS1		;SAVE FIRST TWO WORDS OF MASK
	XMOVEI T3,TTMS1		;POINT TO SECOND TWO WORDS
	ADDI T3,2
	DMOVEM Q1,(T3)		; LAST TWO WORDS
	MOVE T3,T1
	XMOVEI T1,TTMS1		;POINT TO FULL MASK
	CALL TTSBM		;SET THE MASK
	MOVE T1,T3
	DMOVE T3,TTSMH1		;RESTORE T3 AND T4
	DMOVE Q1,TTSMH2		; AND Q1 AND Q2
	RET

	ENDSV.			;END STKVAR
;ROUTINE USED BY TEXTI TO COMPUTE PARITY FOR AN EDITING
;CHARACTER.
;	T2/ THE CHARACTER.
;RETURNS +1 ALWAYS. WITH EVEN PARITY IN B

TTCMPP::SKIPGE CHITAB(T2)	;NEED PARITY ON THIS CHARACTER?
	TRO T2,200		;YES. SO DO IT
	RET			;AND DONE
	SUBTTL TTMSG JSYS

;TTMSG JSYS - SENDS MESSAGES TO ALL TTYS VIA ECHO BUFFER

;ACCEPTS:
;	T1/ (0,,400000+N) WHERE N IS TERMINAL NUMBER
;		OR
;	    -1 FOR ALL LINES

;		OR

;		0=> TIME-OUT AND ARG IN C

;	T2/ POINTER TO SOURCE STRING

;	TTMSG

;RETURNS +1: ALWAYS

;CAN ITERR, BUT RETURNS SUCCESS IF LINE REFUSES SENDALL

;NOTE: THE TTNTS BIT, WHICH PREVENTS SENDALL TO A GIVEN LINE, APPLIES
;TO TTMSG WITH T1 CONTAINING -1 (FOR ALL LINES), NOT WITH T1 CONTAINING
;A SPECIFIC LINE NUMBER
;TTMSG...

.TTMSG::MCENT
	TRVAR <TTMSBY,TTMSCT,WTFLG,TTCAPF>
	SETOM TTCAPF		;ASSUME ALL PRIVILEGES UNLESS...
	CALL CKMMOD		;IS CALLER IN MONITOR MODE?
	IFNSK.
	  MOVE D,CAPENB		;NO. GET CAPS
	  TXNN D,SC%WHL!SC%OPR ;IS HE PRIVILEGED?
	  SETZM TTCAPF		;NO, NOTE
	ENDIF.
	SKIPN TTCAPF		;ENABLED?
	SKIPL CTRLTT		;NO, MUST NOT BE DETACHED
	IFSKP. <ITERR GTDIX1>
	NOINT
TTMSH1:	AOSE SALLCK		;CAN GET SENDALL RESOURCES?
	IFNSK.
	  OKINT
	  MOVEI A,^D30000	;WAIT 30 SEC MAX
	  CALL SETBKT		;SETUP TIMER TEST WORD
	  HRRI A,SALTST
	  MDISMS		;WAIT FOR LOCK FREE OR 30 SEC
	  NOINT
	  AOSE SALLCK		;HAVE LOCK NOW?
	  ITERR TTMSX1		;NO, SOMETHING PROBABLY BUSTED
	ENDIF.
	MOVEI A,1		;INIT COUNT OF ACTIVE LINES, +1 WHILE HEREIN
	MOVEM A,SALCNT
	UMOVE A,1
	SETZM WTFLG		;ASSUME NO WAIT
	JUMPE A,[AOS WTFLG	;NO WAIT
		 UMOVE A,3	;GET ARG
		 JRST .+1]	;PROCEED
	CAME A,[-1]		;ALLOW -1 AS AN ARGUMENT
	IFSKP.
	  SKIPN TTCAPF		;BUT ONLY IF CAPABILITIES PRESENT
	  ITERR GTDIX1
	ELSE.
	  CAIL A,.TTDES		;MAKE SURE TTY ARGUMENT IS NOT TOO SMALL
	  CAIL A,.TTDES+NLINES	;AND NOT TOO LARGE
	  JRST [SETOM SALLCK	;CLEAR LOCK
		ITERR GTJIX2]	;REPORT INVALID
	ENDIF.
	TLC B,-1		;CHECK SOURCE PTR
	TLCN B,-1		;HAD A -1 IN LH?
	HRLI B,(POINT 7,)	;YES. GET STANDARD BYTE POINTER
	UMOVEM B,B		;RETURN BYTE POINTER
	SKIPL P3,A		;SAVE ARG, ALL LINES?
	TXZ P3,.TTDES		;NO, GET LINE NUMBER
	BLCAL. GETSAL,<<.,SALBFR>,<.,TTMSCT>,<.,TTMSBY>,TTCAPF>
				;SETUP SENDALL BFR
	 ITERR ,<SETOM SALLCK>

;BUFFER IS SET UP WITH TEXT. IF THERE ARE NO CHARACTERS,
;WE ARE DONE.

	SKIPN TTMSCT		;AT LEAST ONE BYTE?
	JRST TTMS50		;NO. GO FINISH
	JUMPL P3,[SETZ C,	;IF DOING ALL LINES, START WITH LINE TYPE 0
		JRST TTMS26]	;ENTER LOOP
	MOVE B,P3		;SINGLE LINE, GET LINE NUMBER
	TDCALL S,<<FE,TTMSSN>,<MC,MCCKSA>,<NT,TTMSNT>,<DZ,RSKP>> ;SKIP TO SEND
	 JRST TTMS50		;SKIP THIS LINE
	CALL SALLIN		;DO THE LINE
	 JFCL			;FAILED. IGNORE IT.
	JRST TTMS50		;DONE
;GET THE FIRST LINE OF THIS LINE TYPE

TTMS26:	MOVE B,TT1LIN(C)	;GET FIRST LINE OF THIS TYPE
	JUMPL B,TTMS24		;JUMP IF NO LINES OF THIS TYPE
	JRST TTMS20		;GO DO IT

;GO TO NEXT LINE.  IF THE LINE TYPE CHANGES, DON'T PROCEED WITH THE NEW
;LINE.  INSTEAD, GO TO THE NEXT LINE TYPE AFTER THE ONE JUST PROCESSED.
;THIS CODE ASSUMES THAT ALL LINES OF A GIVEN TYPE ARE NUMBERED CONSECUTIVELY.

TTMS21:	LOAD C,TTSTY,(B)	;GET CURRENT TYPE
	ADDI B,1		;GO TO NEXT LINE
	CAIL B,NLINES		;BEYOND END OF LINES?
	JRST TTMS24		;YES. GO TO NEXT LINE TYPE
	LOAD A,TTSTY,(B)	;GET TYPE OF NEW LINE
	CAME C,A		;SAME AS PREVIOUS LINE?
	JRST TTMS24		;NO. GO TO NEXT LINE TYPE

;SAME LINE TYPE AS PREVIOUS ONE. DO ACCORDING TO DEVICE DEPENDENT CODE
;DEVICE-DEPENDENT CODE RETURNS:
;	+1: DON'T DO THIS LINE
;	+2 AND T2/-1: DON'T DO ANY LINES OF THIS TYPE
;	+2 AND T2/LINE NUMBER: DO THIS LINE

TTMS20:	MOVE A,SALBFR		;PASS BYTE PTR
	HRLI A,(POINT 8,0)
	MOVE D,C		;SAVE THE LINE TYPE FOR THE TDCALL
	MOVE C,TTMSCT		;PASS COUNT
	TDCALL S,<<FE,TTMSAL>,<MC,MCCKSA>,<PT,TTMSNO>,<NT,TTMSNT>,<DZ,DZSNDL>>
	 JRST TTMS21		;DON'T DO THIS LINE. GO ON TO NEXT LINE
	MOVE C,D		;RESTORE LINE TYPE
	JUMPL B,TTMS24		;SKIP THE ENTIRE GROUP

;HERE WHEN DEVICE DEPENDENT CODE WANTS THE SENDALL DONE FOR IT

TTMS22:	JN TTNTS,(B),TTMS21	;DON'T DO IF NON-TERMINAL
	CALL SALLIN		;DO SENDALL FOR THE LINE
	 JFCL			;FAILED. IGNORE IT.
	JRST TTMS21		;THEN GO GET NEXT LINE

;FINISHED THE CURRENT LINE TYPE OR THE LINE TYPE IS NOT TO BE PROCESSED
;GO TO THE NEXT TYPE

TTMS24:	AOS C			;GO TO NEXT LINE TYPE
	CAIL C,NLTYPS		;BEYOND END OF LEGAL TYPES?
	JRST TTMS50		;YES. DONE
	JRST TTMS26		;DO NEXT TYPE
;HERE WHEN ALL LINES HAVE BEEN PROCESSED FOR CURRENT BUFFERFUL.
;WAIT UNTIL ALL ARE SENT

TTMS50:	CALL DECSAL		;SEE IF ANY LINES GOING NOW
	OKINT
	JRST MRETN

;RETURN -1 IN B TO CAUSE ALL LINES OF THIS TYPE TO BE SKIPPED

TTMSNO:	SETO B,
	RETSKP
;SALLIN - DO SENDALL TO A SINGLE LINE

;ACCEPTS:
;	T2/ LINE NUMBER

	SWAPCD

SALLIN:	SAVELN			;SAVE LINE NUMBER
	STKVAR <SALLLN>
	MOVEM T2,SALLLN		;SAVE LINE NUMBER
	JN TTSHU,(T2),R		;IF LINE SHUT OFF, FORGET IT
	NOINT
	NOSKED
	CALL STADYN		;DOES LINE ALREADY HAVE DYNAMIC DATA?
	IFSKP.
SALLI2:	  TMNN <TTSAL,TTHPO>,(T2) ;YES, SENDALL PTR FREE?
	  JRST SALLI5		;YES, GO AHEAD
	  CALL LCKTT		;LOCK THE BLOCK WHILE WE DISMISS
	  OKSKED
	  MOVEI T1,SALWAT	;WAIT TEST FOR SENDALL PTR FREE
	  HRL T1,T2		;DYNAMIC PTR
	  MDISMS
	  NOSKED		;NOSKED AGAIN
	  CALL ULKTT		;UNLOCK THE BLOCK
	  JRST SALLI2		;TRY AGAIN
	ENDIF.
	JUMPG T2,SALLI5		;HAS A MESSAGE BLOCK. OK TO USE
	JUMPL T2,[ OKSKED	;GO OKSKED FIRST
		RET]		;LINE IS BECOMING ACTIVE. CAN'T USE IT
	MOVE T2,SALLLN		;GET LINE NUMBER
	SETOM TTACTL(T2)	;INDICATE BECOMING ACTIVE
	OKSKED
	CALL ASGSHT		;GO GET A SHORT BLOCK
	 JRST [	SETZM TTACTL(T2) ;RESET ACTIVE POINTER
		RETBAD]
	NOSKD1
	TXO T1,TTSHBK		;SAY IS A SPECAIL
	MOVEM T1,TTACTL(T2)	;SAVE DYNAMIC STORAGE ADDRESS
	AOSG TTQCNT		;FIRST SPECIAL LINE?
	MOVEM T2,TTCQLN		;YES. START SCAN HERE THEN
	TXZ T1,TTSHBK		;MAKE ADDRESSABLE BLOCK
	MOVE T2,T1
SALLI5:	AOS SALCNT		;INCREMENT COUNT OF LINES DOING SENDALL
	MOVE T1,SALBFR		;GET SENDALL BFR ADDRESS
	HRLI T1,(POINT 8,0)	;MAKE BYTE PTR
	MOVEM T1,TTSAL2(T2)	;SAVE POINTER TO SENDALL STRING
	MOVE T1,TTMSCT		;GET COUNT OF CHARACTERS
	STOR T1,TSALC,(T2)	;SAVE COUNT OF SENDALL STRING
	SETONE TTSAL,(T2)	;INDICATE LINE IS DOING A SENDALL
	SETZ T3,		;FAKE OUT STRTOU
	CALL STRTOU		;START OUTPUT IF NEEDED
	MOVE T3,TTMSCT		;GET CHAR COUNT
	IDIVI T3,^D10		;MINIMUM OUTPUT RATE, 10 CHARS/SEC
	ADDI T3,5		;PLUS A SMALL PAD
	STOR T3,TSALT,(T2)
	CALL TSENDQ		;QUEUE A CHECK OF THE LINE
	OKINT
	RETSKP

	ENDSV.			;END STKVAR
	ENDTV.			;END TRVAR
;PERIODIC ROUTINE TO UNHANG STUCK SENDALL LINES
;CALLED FROM DOLINE (TTCH7)
; T2/ LINE NUMBER

	RESCD			;RESDIENT STUFF

CKSALL:	CALL STADY		;STILL ACTIVE?
	 RET			;NO, DONE
	JE TTSAL,(T2),R		;DONE IF NO LONGER DOING SENDALL
	JN TTSHU,(T2),[CALLRET CLRSAL] ;IF LINE SHUT OFF, CLEAR IMMED.
	DECR TSALT,(T2)		;COUNTDOWN SECONDS
	JN TSALT,(T2),[CALLRET TSENDQ] ;NOT EXPIRED, QUEUE ANOTHER CHECK
	CALLRET CLRSAL		;EXPIRED, CLEAR THE LINE

;QUEUE A CHECK OF A LINE DOING A SENDALL
; T2/ DYNAMIC PTR

TSENDQ:	SAVEAC <T2>
	MOVEI T1,^D1000		;ONE SECOND
	LOAD T2,TINTL,(T2)	;NEED LINE NUMBER HERE
	MOVEI T3,CKSALL		;ROUTINE TO CALL
	CALLRET TTQAD		;QUEUE IT

;CLEAR SENDALL STATE FOR LINE
; T2/ DYNAMIC PTR

CLRSAL:	SETZRO <TSALC>,(T2)	;CLEAR SENDALL POINTER, COUNT
	SETZM TTSAL2
	SETZRO TTSAL,(T2)	;INDICATE NO LONGER DOING SENDALL
	IFQN. TTDAL,(T2)	;DID SOMEBODY TRY TO DEALLOCATE THIS?
	  CALL TTYDED		;YES, DO IT NOW
	   NOP
	ENDIF.
DECSAL:	SOSN SALCNT		;DECREMENT COUNT OF SENDALL LINES
	CALLRET RELSAL		;RELEASE SENDALL STORAGE
	RET

;RELEASE SENDALL STORAGE

RELSAL:	SAVEAC <T2>
	MOVE T1,SALBFR
	CALL RELRES
	SETOM SALLCK		;RELEASE LOCK
	RET

;WAIT FOR LINE TO FINISH USING SENDALL PTR
;CALLED AS SCHEDULER TEST
; T1/ LINE NUMBER
;	JSP T4,SALWAT
;	 +1: STILL WAITING
;	 +2: READY

SALWAT::TMNE <TTSAL,TTHPO>,(T1)	;STILL DOING IT?
	JRST 0(T4)		;YES
	JRST 1(T4)		;NO, WAKEUP

;TEST FOR SALLCK FREE OR TIME EXPIRED
; T1/ VALUE FOR TIME TEST

SALTST::SKIPGE SALLCK		;LOCK FREE?
	JRST 1(T4)		;YES, WAKEUP
	JRST BLOCKT		;NO, CHECK TIME

	SWAPCD
;GETSAL - GET SENDALL BUFFER AND STORE LINE OF TEXT IN IT

;RETURNS +1: FAILURE
;	 +2: SUCCESS,
;		@TTMSCT/ COUNT OF BYTES
;		@TTMSBY/ LAST BYTE
;		@TTMSBF/ BUFFER ADDRESS
;		TTCAPF/ -1 IF PRIVILEGED

GETSAL:	BLSUB. <TTMSBF,TTMSCT,TTMSBY,TTCAPF>
	UMOVE B,B		;GET BYTE PTR
	SETZ C,			;INIT COUNT
GETSB2:	XCTBU [ILDB A,B]	;SCAN BYTES
	 ERJMP [RETBAD ARGX10]	;CAN'T REFERENCE IT
	JUMPE A,GETSB1		;NUL IS END OF STRING
	CAIN A,.CHLFD		;LF?
	ADDI C,4		;YES, WILL INCLUDE 4 FILLS
	AOJA C,GETSB2		;COUNT CHARS

GETSB1:	MOVEM C,@TTMSCT		;SAVE COUNT
	SKIPN TTCAPF		;PRIVILEGED?
	ADDI C,^D55		;NO, ACCOUNT FOR HEADER
	ADDI C,4		;ROUND UP
	IDIVI C,4		;COMPUTE NUMBER WORDS REQUIRED
	BLCAL. ASGRSB,<C,[.RESP3],[.RESTP]> ;GET RES STG FROM TERMINAL POOL
	 RETBAD()		;FAILED - SHOULDN'T HAPPEN
	MOVEM A,@TTMSBF		;SAVE ADDRESS
	HRLI A,(POINT 8,0)	;BUILD BYTE PTR - 8-BIT, INCLUDES PARITY BIT
	SKIPE TTCAPF		;CAPABILITIES?
	IFSKP.
	  HRROI B,[ASCIZ /From /] ;No, must prefix header
	  CALL GSALCP		;BUILD STRING IN RES STG
	  HRROI B,USRNAM+1
	  CALL GSALCP		;USER NAME
	  HRROI B,[ASCIZ / on line /]
	  CALL GSALCP
	  MOVE B,CTRLTT
	  MOVEI C,^D8		;LINE NUMBER, OCTAL
	  NOUT
	   NOP
	  MOVEI B,[ASCIZ /: /]
	  CALL GSALCP
	  HRRZ B,A		;COMPUTE NUMBER BYTES IN HEADER STRING
	  SUB B,@TTMSBF		;NUMBER FULL WORDS
	  IMULI B,4		;NUMBER BYTES
	  ADDM B,@TTMSCT	;ADJUST COUNT
	  LDB B,[POINT 3,A,2]	;P FIELD, HIGH-ORDER 3 BITS
	  MOVN B,B
	  ADDI B,4		;NUMBER BYTES IN LAST (PARTIAL) WORD
	  ADDM B,@TTMSCT	;ADJUST COUNT
	ENDIF.
	MOVE C,A		;DEST BYTE PTR
	MOVE D,@TTMSCT

;LOOP THROUGH CHARACTERS IN USER'S STRING, COPYING TO INTERNAL BUFFER.
;ADD FILL AFTER LINE FEED.  STOP AT END OF LINE OR WHEN BUFFER IS FULL,
;WHICHEVER IS FIRST

GETSA1:	XCTBUU [ILDB P1,B]	;GET NEXT BYTE
	 ERJMP [MOVE A,@TTMSBF	;FAILED, RETURN STORAGE
		CALL RELRES
		RETBAD(ARGX10)]	;AND RETURN TO CALLER
	JUMPE P1,GETSA6		;STOP ON NULL
	ANDI P1,177		;USE ONLY 7-BIT ASCII
	SKIPG CHITAB(P1)	;NEED PARITY BIT?
	TRO P1,200		;YES. APPLY IT THEN
	SOJL D,GETSA6		;COUNT CHARS
	IDPB P1,C		;USE IT
	CAIE P1,.CHLFD		;A LINE FEED?
	JRST GETSA1		;NO, LOOP

;END OF LINE. INSERT 4 FILLS

	MOVEI P4,4		;FILLS TO DO
	MOVEI P2,TTFILL		;THE FILL CHARACTER
GETSA3:	SOJL D,GETSA6		;JUMP IF BUFFER FULL
	IDPB P2,C		;INSERT A FILL
	SOJG P4,GETSA3		;DO ALL FILLS
	JRST GETSA1		;LOOP

;END OF STRING OR COUNT EXHAUSTED (COUNT CAN ONLY BE WRONG IF STRING
;IN USER SPACE CHANGED SINCE WE COUNTED IT.)

GETSA6:	MOVEM P1,@TTMSBY	;SAVE LAST BYTE COPIED
	RETSKP

;LOCAL SUBROUTINE TO COPY STRING
; A/ DEST BYTE PTR
; B/ SOURCE BYTE PTR
;	CALL GSALCP
;COPY UNTIL NULL
; RETURN +1: ALWAYS, NULL FOLLOWS END OF DEST STRING

GSALCP:	HLRZ C,B		;CHECK SOURCE PTR
	CAIN C,-1		;NEEDS INIT?
	HRLI B,(POINT 7,0)	;YES
      DO.
	ILDB T3,T2		;GET BYTE
	IDPB T3,T1		;STORE IT
	JUMPN T3,TOP.		;LOOP IF NOT NULL
      OD.
	CALLRET DBP		;DECREMENT DEST PTR OVER NULL AND RETURN

	ENDBS.
;SIMULATE TTY INPUT

;ACCEPTS:
;	T1/ CHARACTER
;	T2/ INTERNAL LINE NUMBER

;CALL TTSTI

;RETURNS +1: ALWAYS

	SWAPCD

TTSTI::	ANDI 1,377		;ISOLATE CHARACTER
	NOSKED
	CAME 2,CTYINT		;CTY ALIAS?
	CALL TTCHI		;NO. PUT CHAR INTO LINE BUFFER
	 JRST [	OKSKED		;FAILED, BUFFER FULL
		RETBAD IOX33]
	OKSKED
	RETSKP

REPEAT 0,<
;OBNFT - SCHEDULER TEST FOR OUTPUT BUFFER NOT FULL

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;CAUSES WAKEUP IF OUTPUT BUFFER IS NOT FULL

	RESCD			;MUST BE RESIDENT
OBNFT:	MOVE T2,T1		;SETUP LINE
	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 JRST 1(T4)		;SHOULDN'T HAPPEN. WAKE PROCESS
	LOAD T3,TOMAX,(T2)
	CAMG T3,TTOCT(T2)	;FULL?
	JRST 0(T4)		;YES
	JRST 1(T4)		;NO
>
	SUBTTL STO JSYS

	SWAPCD			;SWAPPABLE. CALLED AS A JSYS
.STO::	MCENT
STO11:	UMOVE 1,1
	CALL CHKTTY		;CHECK GIVEN DESIGNATOR
	 ITERR()		;NOT TTY
	CALL LCKTTY		;GET ADDRESS OF DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY
		ITERR (TTYX01)]	;NOT ACTIVE. RETURN ERROR
	CALL TTSTO
	 JRST STO11		;BLOCKED. TRY AGAIN
	UMOVEM 1,2		;RETURN CHAR IN 2
	CALL ULKTTY		;ALLOW DEALLOCATION OF DYNAMIC DATA
	JRST MRETN

	RESCD			;MAKE RESIDENT FOR EFFICIENCY
;TTSTO - REMOVE CHARACTER FROM OUTPUT BUFFER

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSTO

;RETURNS +1: BLOCKED, TRY AGAIN
;	+2 SUCCESS
;		T1/ CHARACTER

TTSTO::	NOSKD1
	CHNOFF DLSCHN		;CAN'T ALLOW SCANNER PI HERE
	CALL GTOCHR		;GET CHAR FROM OUT BFR
	 JRST TTSTO1		;EMPTY, BLOCK
	TXNN A,TTOESC		;A MARKER?
	IFSKP.
	  CAIE T1,TTOMRK	;SYNCH?
	  IFSKP. <
	    SETZRO TTFLO,(T2)>	;YES, CLEAR FLUSH FLAG
	  SETZ T1,		;RETURN A NUL
	ENDIF.
	CHNON DLSCHN
	OKSKD1
	RETSKP

;WAIT UNTIL BUFFER BECOMES NONEMPTY AND LINE INACTIVE

TTSTO1:	CHNON DLSCHN
	OKSKD1
	SETONE TTBKO,(T2)	;NOTE WAITING FOR OUTPUT EVENT
	DYNST T1		;GET STATIC LINE NUMBER
	CALL ULKTTY
	HRLZS T1		;LINE NUMBER TO LH
	HRRI T1,TTOAV		;TEST FOR BUFFER NOT EMPTY AND LINE INACTIVE
	MDISMS			;WAIT UNTIL SPECIFIED TEST IS SATISFIED
	RET			;SAY WE BLOCKED. TRY AGAIN

;TTOAV -  SCHEDULER TEST FOR OUTPUT AVAILABLE ON A LINE

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;CAUSES WAKEUP IF OUTPUT BUFFER IS NOT EMPTY AND LINE IS INACTIVE

TTOAV::	HRRZ T2,T1		;GET LINE NUMBER
	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 JRST 1(T4)		;NOT ACTIVE. THIS SHOULDN'T HAPPEN
	TMNN TTOTP,(T2)		;IS LINE ACTIVE?
	SKIPN TTOCT(T2)		;NO. ARE THERE CHARACTERS?
	JRST 0(T4)		;ACTIVE OR NO CHARACTERS AVAILABLE. DON'T WAKEUP
	SETZRO TTBKO,(T2)	;NOTE WAIT COMPLETED
	JRST 1(T4)		;INACTIVE AND CHARACTERS AVAILABLE. WAKEUP
	SUBTTL STTYP/GTTYP JSYS'S

;.STTYP - SET TERMINAL TYPE

;ACCEPTS:
;	T1/ TERMINAL DESIGNATOR
;	T2/ TERMINAL TYPE NUMBER

;	STTYP

;RETURNS +1: ALWAYS

	SWAPCD
.STTYP::MCENT
	CALL CHKTTY
	 ITERR ()		;ASSUME CHKTTY SET UP ERROR REASON
	UMOVE 3,2		;GET TERMINAL TYPE SPECIFIED
	CAIL 3,0		;REASONABLE NUMBER?
	CAIL 3,NTTYPS
	ITERR (STYPX1)		;TERMINAL TYPE NOT IN RANGE
	CALL LCKTTY		;GET DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
		ITERR (TTYX01)]
	STOR 3,TTTYP,(2)	;STORE NEW TERMINAL TYPE
	LDB 1,TTMBIT		;GET MECH BITS
	DPB 1,[POINT 3,TTFLGS(2),3] ;PUT WHERE NOTICED
	LDB 1,TTTWID		;GET STANDARD WIDTH
	STOR 1,TPWID,(2)	;SET IT FOR THIS LINE
	LDB 1,TTTLEN		;STANDARD LENGTH
	STOR 1,TPLEN,(2)	;SET IF FOR THIS LINE
	HRRZ T1,TTYPE1(T3)	;GET VIDEO ATTRIBUTES TABLE
	SKIPE T1		;IS THIS A VIDEO TERMINAL?
	MOVEI T1,1		;YES.
	STOR T1,TTNXO,(T2)	;SET PAGE STOP BIT APPROPRIATELY
	CALL ULKTTY		;ALLOW DEALLOCATION
	JRST MRETN
;.GTTYP - GET TERMINAL TYPE

;ACCEPTS:
;	T1/ TERMINAL DESIGNATOR


;	GTTYP

;RETURNS +1: ALWAYS
;		T2/ TERMINAL TYPE
;		T3/ (NUMBER INPUT BUFFERS,,NUMBER OUTPUT BUFFERS)

.GTTYP::MCENT
	CALL CHKTTR
	 JRST [	XCTU [SETZM 2]	;NOT TTY, RETURN 0
		JRST MRETN]
	CALL LCKTTY		;POINT TO DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
		ITERR (TTYX01)]
	LOAD 1,TTTYP,(2)	;GET TERMINAL TYPE
	UMOVEM 1,2
	LOAD 1,TTNIN,(2)	;GET NUMBER OF INPUT BUFFERS
	LOAD 3,TTNOU,(2)	;GET NUMBER OF OUTPUT BUFFERS
	HRLI 3,0(1)		;COMBINE THEM FOR USER
	UMOVEM 3,3
	CALL ULKTTY		;ALLOW DEALLOCATION OF DYNAMIC DATA
	JRST MRETN
	SUBTTL STPAR JSYS

;.STPAR - SET TERMINAL PARAMETERS

;ACCEPTS:
;	T1/ TERMINAL DESIGNATOR
;	T2/ NEW JFN MODE WORD

;	STPAR

;RETURNS +1: ALWAYS

.STPAR::MCENT
	CALL CHKTTR		;IS THIS A TTY?
	 MRETNG			; NO, THEN THIS IS A NOOP
	CALL CHKTTY		;CAN WE GET TO IT?
	 EMRETN ()		; NO, ERROR OUT WITH REASON
	CALL LCKTTY		;POINT TO DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
		ITERR (TTYX01)]
	NOINT			;I WILL NOT DIE
	UMOVE 1,2		;GET NEW JFN MODE WORD
	TDCALL D,<<PT,STPAR5>,<NT,NVTPAR>>
	PUSH P,1
	XOR 1,TTFLGS(2)
	ANDI 1,TT%ECM+TT%UOC+TT%LIC+TT%DUM+TT%PGM ;CHANGE THESE BITS
	XORM 1,TTFLGS(2)
	TXNE T1,TT%PGM		;DID PAGE MODE CHANGE?
	IFNSK. <TDCALL D,<<FE,TTEXF>,<MC,MCEXF>>> ;YES, FIX XOFF RECOG IN FE
	PUSH P,1
	TXNE 1,TT%PGM		;CHANGING PAGE MODE?
	CALL TTXONA		;YES, BE SURE OUTPUT NOT STOPPED
	SETZ 1,
	STOR 1,TPGPS,(2)	;AND RESET PAGE POSITION
	POP P,1
	LDB 1,[POINT 7,0(P),10]
	JUMPE T1,STPAR2		;ALLOW ZERO LENGTH
	CAIL 1,2		;LEGAL PAGE SIZE?
	CAIL 1,200
	JRST STPAR0		;ILLEGAL SIZE DOES NOT CHANGE SETTING
STPAR2:	STOR T1,TPLEN,(2)
STPAR0:	LDB 1,[POINT 7,0(P),17]
	JUMPE T1,STPAR3		;ALLOW ZERO WIDTH
	CAIL 1,10		;LEGAL WIDTH
	CAIL 1,200
	JRST STPAR1		;ILLEGAL WIDTHS DON'T CHANGE THE SETTING
STPAR3:	STOR T1,TPWID,(2)
STPAR1:	LDB 1,[POINT 3,0(P),3]
	DPB 1,[POINT 3,TTFLGS(2),3] ;LH BITS
	POP P,1
	CALL ULKTTY		;ALLOW DEALLOCATION OF DYNAMIC DATA
	OKINT			;I CAN BE KILLED NOW
	JRST MRETN
	SUBTTL TLINK JSYS

;.TLINK - ESTABLISH/REMOVE LINKS BETWEEN TERMINALS

;ACCEPTS:
;	T1/ (FLAGS,,OBJECT LINE NUMBER)
;	T2/ REMOTE LINE NUMBER OR -1 FOR ALL

;	TLINK

;RETURNS +1: FAILURE
;		T1/ ERROR CODE
;	 +2: SUCCESS

;FLAGS:
;	TL%CRO - B0 - CLEAR REMOTE TO OBJECT
;	TL%COR - B1 - CLEAR OBJECT TO REMOTE
;	TL%EOR - B2 - SET OBJECT TO REMOTE
;	TL%ERO - B3 - SET REMOTE TO OBJECT
;	TL%SAB - B4 - SET OR CLEAR ACCEPT LINKS ACCORDING TO B5
;	TL%ABS - B5 - SET ACCEPT LINKS
;	TL%STA - B6 - SET OR CLEAR ACCEPT ADVICE ACCORDING TO B7
;	TL%AAD - B7 - SET ACCEPT ADVICE

;'OBJECT' IS USUALLY THE CALLER OF THE JSYS; 'REMOTE' IS THE OTHER LINE

.TLINK::MCENT
	TRVAR <OBJNO,OBJADR,REMNO,TLSAV1,LNKWRN>
	SETOM LNKWRN		;ASSUME LINK MESSAGE IS NEEDED
	MOVEI T1,-.TTDES(T1)	;TURN OBJECT DESIGNATOR INTO LINE NUMBER
	CAIN T1,-1-.TTDES	;SPECIFIED -1 FOR OWN TERMINAL?
	SKIPL T1,CTRLTT		;YES, GET IT
	CAIL T1,NLINES		;VALIDATE LINE NUMBER
	 RETERR(DESX1)		;ILLEGAL
	MOVEM T1,OBJNO		;SAVE LINE NUMBER
	ADDI T1,.TTDES		;CREATE DESIGNATOR AGAIN
	CALL CHKDEV		;SEE IF TERMINAL IS AVAILABLE TO THIS JOB
	 SKIPA T1,CAPENB	;NO, MUST CHECK WHEEL
	JRST TLKOBG		;YES, PROCEED
	TXNN T1,SC%WHL!SC%OPR	;PRIVILEGED TO LINK RANDOM TERMINALS?
	RETERR (WHELX1)		;NO, LOSE
	SETZM LNKWRN		;NO MESSAGE IS TYPED LATER
TLKOBG:	MOVE T2,OBJNO		;GET BACK LINE NUMBER
	CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY	;NOT ACTIVE.
		RETERR (TTYX01)]
	MOVEM T2,OBJADR		;SAVE ADDRESS OF DYNAMIC DATA FOR OBJECT
	UMOVE 1,1		;GET BITS AND OBJECT DESIGNATOR
	TLNN 1,(74B5)		;SECOND DESIGNATOR REQUIRED?
	JRST TL1		;NO

;USER IS SETTING OR CLEARING LINKS. GET SECOND ARGUMENT, WHICH IS A LINE
;NUMBER (OR -1 FOR ALL LINES IF CLEARING LINKS)

	XCTU [HRRZ 2,2]
	CAIN 2,-1		;'ALL' ?
	JRST TL1		;YES, LEAVE AS IS
	TRZE 2,.TTDES		;4XXXXX?
	JRST TL2		;YES
	MOVE 1,2		;ASSUME REGULAR JFN
	CALL CHKTTY
	 JRST TLINK9
TL2:	CAIL 2,NLINES		;LEGAL LINE?
	JRST TL3		;NO. TOO LARGE
	CAIL 2,0		;NEGATIVE IS ILLEGAL
	CAMN T2,CTYINT		;ALIAS FOR CTY?
TL3:	JRST [	MOVEI T1,DESX1	;INVALID LINE. FAIL
		JRST TLINK9]

;T2/ LINE NUMBER FOR REMOTE OR -1

TL1:	MOVEM T2,TLSAV1		;SAVE REMOTE LINE NUMBER IF ANY
	MOVE FX,OBJNO		;GET BACK OBJECT NUMBER
	UMOVE Q2,1		;GET FUNCTION FLAGS
	TXNE Q2,TL%CRO		;CLEAR REMOTE TO OBJECT?
	CALL TLINK0		;YES. GO DO IT
	TXNE Q2,TL%COR
	 JRST [	CALL TLINK1	;CLEAR OBJECT TO REMOTE
		 JRST TLINK9	;FAILED. GO RETURN ERROR
		JRST .+1]
	TXNE Q2,TL%EOR
	JRST [	CALL TLINK2	;SET OBJECT TO REMOTE
		 JRST TLINK9	;FAILED
		JRST .+1]
	TXNE Q2,TL%ERO
	JRST [	CALL TLINK3	;SET REMOTE TO OBJECT
		 JRST TLINK9
		JRST .+1]
	TXNE Q2,TL%SAB
	CALL TLINK4		;SET ACCEPT BIT TO C(B5)
	TXNE Q2,TL%STA		;SET ADVICE BIT?
	CALL TLINK5
	MOVE T2,OBJADR		;T2/ ADDRESS OF OBJECT'S DATA
	CALL ULKTTY		;ALLOW DEALLOCATION
	SMRETN

;AN ERROR OCCURRED. UNLOCK DATA AND RETURN FAILURE

TLINK9:	SKIPE T2,OBJADR		;T2/ ADDRESS OF OBJECT'S DATA
	CALL ULKTTY		;ALLOW DEALLOCATION
	RETERR			;RETURN ERROR CODE
;CLEAR REMOTE TO OBJECT

;ACCEPTS:
;	TLSAV1/ REMOTE LINE NUMBER OR -1
;	FX/ OBJECT LINE NUMBER

;	CALL TLINK0

;RETURNS +1: ALWAYS

;DETERMINES WHETHER USER WANTS TO CLEAR ALL OR ONE. CALLS ROUTINE
;FOR EACH REMOTE LINE NUMBER

TLINK0:	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	CAIE 2,-1		;ALL REMOTES?
	CALLRET TL0C		;NO, DO THE ONE SPECIFIED

;CLEAR LINKS FROM ALL REMOTES TO THIS OBJECT. LOOP THROUGH LINES

	MOVEI 2,0		;T2/ REMOTE LINE NUMBER
	CALL TL0C		;CLEAR LINKS FROM REMOTE TO OBJECT
	CAIGE 2,NLINES-1	;AT END OF LINES?
	AOJA 2,.-2		;NO. KEEP GOING
	RET			;YES. DONE

;TL0C - CLEAR ALL LINKS FROM SPECIFIED REMOTE TO OBJECT

;ACCEPTS:
;	T2/ REMOTE LINE NUMBER
;	FX/ OBJECT LINE NUMBER

;CALL TL0C

;RETURNS +1: ALWAYS

TL0C:	SAVELN
	CALL LCKTTY		;POINT TO DYNAMIC DATA FOR REMOTE
	 CALLRET ULKTTY		;NOT ACTIVE
TL0C1:	CALL TLTST1		;FIND LINK TO OBJECT IN REMOTE
	JUMPL 1,TL0C2		;DONE IF NO LINKS TO OBJ
	MOVEI 1,777		;FOUND ONE. CLEAR IT
	DPB 1,Q1		;CLEAR THE LINK JUST FOUND
	JRST TL0C1		;GO FIND ANOTHER

;DONE WITH THIS REMOTE LINE

TL0C2:	CALLRET ULKTTY		;ALLOW DEALLOCATION FOR REMOTE
;TLINK1 - CLEAR OBJECT TO REMOTE

;ACCEPTS:
;	FX/ OBJECT LINE NUMBER
;	TLSAV1/ REMOTE LINE NUMBER OR -1

;	CALL TLINK1

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TLINK1:	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	CAIE 2,-1		;ALL?
	CALLRET TL1C		;NO, CLEAR SPECIFIC

;CLEAR ALL LINKS FROM THIS OBJECT. LOOP THROUGH LINK WORD

	MOVE Q1,[POINT 9,TTLINK(4),-1] ;POINT TO LINK WORD
TL12:	MOVE 4,OBJADR		;GET ADDRESS OF OBJECT'S DATA
	ILDB 2,Q1		;GET A LINE NUMBER
	CAIN 2,777		;IS THIS SLOT FREE?
	JRST TL14		;YES. SKIP IT
	PUSH P,Q1		;NO. SAVE BYTE POINTER
	CALL TL1C		;GO CLEAR ALL LINKS TO THIS REMOTE
	 RETBAD (,<POP P,Q1>)	;SOME SORT OF FAILURE
	POP P,Q1		;RESTORE BYTE POINTER
TL14:	TLNE Q1,(7B2)		;AT END OF LINK WORD?
	JRST TL12		;NO. GO TO NEXT FIELD
	RETSKP			;YES. DONE
;TL1C - CLEAR ALL LINKS FROM OBJECT TO THIS REMOTE

;ACCEPTS:
;	T2/ REMOTE LINE NUMBER
;	FX/ OBJECT LINE NUMBER

;	CALL TL1C

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TL1C:	CALL TLTST2		;FIND LINK TO REMOTE
	JUMPL 1,RSKP		;NONE, DONE

;OBJECT POINTS TO REMOTE. DON'T ALLOW CLEARING IF REMOTE ALSO POINTS
;TO OBJECT

	MOVE 1,CAPENB
	TRNE 1,SC%WHL+SC%OPR	;PRIVILEGED?
	JRST TL13		;YES, SKIP CHECK
	MOVEM T2,REMNO		;SAVE REMOTE LINE NUMBER
	CALL LCKTTY		;POINT TO REMOTE DYNAMIC DATA
	 JRST [	CALL ULKTTY
		JRST TL13]
	PUSH P,Q1
	CALL TLTST1		;SEE IF REMOTE POINTS TO OBJECT
	CALL ULKTTY		;UNLOCK REMOTE'S DATA
	POP P,Q1		;RESTORE POINTER TO REMOTE LINK WORD
	JUMPGE 1,TL15		;ERROR IF REMOTE POINTS TO OBJECT
TL13:	MOVEI 1,777
	DPB 1,Q1		;CLEAR LINK JUST FOUND
	MOVE T2,REMNO		;RESTORE REMOTE LINE NUMBER
	JRST TL1C

TL15:	RETBAD (TLNKX1)
;TLINK2 - SET OBJECT TO REMOTE

;ACCEPTS:
;	FX/ OBJECT LINE NUMBER
;	TLSAV1 / REMOTE LINE NUMBER OR -1

;	CALL TLINK2

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TLINK2:	STKVAR <TLNKT>
	MOVEI T2,5		;MAX TRIES IF REMOTE IF REFUSING
	MOVEM T2,TLNKT		;SAVE IT
TLNK2:	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	CAIN 2,-1		;SPECIFIED ALL?
	RETBAD (DESX1)		;NON-SPECIFIC DESIGNATOR ILLEG HERE
	CAMN 2,FX		;LINK TO SELF?
	RETSKP			;YES, IGNORE
	CALL TLTST2		;LINK ALREADY EXISTS?
	JUMPG 1,RSKP		;IGNORE IF YES
	MOVEI T2,777		;LOOK FOR AN EMPTY SLOT
	CALL TLTST2		; THAT WE COULD ACCEPT WITH
	JUMPL T1,[RETBAD (TLNKX3)] ;ALL LINKS ARE IN USE ALREADY
	MOVE T2,TLSAV1		;GET BACK THE REMOTE LINE NUMBER

;IF REMOTE IS NOT ACCEPTING LINKS, RING THE BELL AND WAIT TO SEE IF
;USER DECIDES TO ACCEPT

	CALL LCKTTY		;POINT TO REMOTE DYNAMIC DATA
	 JRST [	CALL ULKTTY
		RETBAD (TTYX01)]

;REPEAT SEQUENCE OF CHECKING ACCEPT BIT, RINGING BELL, AND WAITING
;UNTIL EITHER REMOTE ALLOWS LINKS OR WE TIME OUT

TL21:	MOVEI 3,TT%ALK		;ACCEPT BIT
	MOVE 4,CAPENB
	TRNN 4,SC%WHL+SC%OPR	;PRIVILEGED? OR
	TDNE 3,TTFLGS(2)	;REMOTE ACCEPTING?
	JRST TL22		;YES
	SOSGE TLNKT		;TRY AGAIN?
	JRST TL24		;NO. CAN'T DO THE LINK
	CALL ULKTTY		;FREE REMOTE LOCK
	SKIPE T2,OBJADR		;GET OBJECT ADDRESS
	CALL ULKTTY		;FREE IT AS WELL
	SETZM OBJADR		;SAY NO LOCK HERE
	MOVEI 4,^D10		;A RING IS 10 BELLS

TL23:	NOSKED			;OWN MACHINE FOR A WHILE
	HRROI T1,[BYTE (7) .CHBEL] ;GET A BELL
	PUSH P,4		;SAVE COUNTER
	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	CALL TTEMES		;OUTPUT A BELL
	HRROI T1,[BYTE (7) .CHBEL] ;GET A BELL AGAIN
	MOVE T2,FX		;GET OBJECT LINE NUMBER
	CALL TTEMES		;OUTPUT A BELL HERE TOO
	POP P,4			;RESTORE COUNTER
	OKSKED			;RELEASE MACHINE NOW
	SOJG 4,TL23
	;..
;WAIT A WHILE

	;..
	MOVEI 1,^D3000		;WAIT FOR 3 SECONDS, THE BELL WILL BE
	DISMS			;RINGING FOR THE FIRST SECOND OF WAIT
	MOVE T2,FX		;GET OBJECT LINE NUMBER
	CALL LCKTTY		;LOCK IT UP
	 JRST [	CALL ULKTTY	;FREE IT
		RETBAD (TTYX01)] ;AND GIVE ERROR
	MOVEM T2,OBJADR		;SAY IT IS NOW LOCKED
	JRST TLNK2		;AND TRY AGAIN

	ENDSV.			;END STKVAR

;REMOTE IS ACCEPTING LINKS


TL22:	CALL ULKTTY
	MOVEI 2,777
	CALL TLTST2		;FIND FREE FIELD IN OBJECT
	JUMPL 1,[RETBAD (TLNKX3)] ;LINKS FULL
	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	DPB 2,Q1		;DEPOSIT REMOTE NUMBER IN FIELD
	MOVE T2,OBJADR		;GET OBJECT DYNAMIC DATA
	CALL ULKTTY		;FREE IT
	SETZM OBJADR		;NO LOCK HELD
	SKIPN LNKWRN		;LINKING FROM MY OWN JOB?
	JRST TL25		;NO, SKIP MESSAGE
	MOVE T1,OBJNO		;GET TERMINAL NUMBER
	ADDI T1,.TTDES		;TURN INTO DESIGNATOR
	HRROI 2,[ASCIZ /
LINK FROM /]
	SETZ 3,
	SOUT			;MSG ON OBJECT ALSO SEEN ON REMOTE
	 ERJMP TL25
	MOVE 2,JOBNO
	HRRZ 2,JOBDIR(2)	;USER ON THIS JOB
	HRLI 2,USRLH		;TURN IT INTO A USER NUMBER
	DIRST			;TYPE HIS NAME
	 JFCL
	HRROI 2,[ASCIZ /, TTY /]
	SOUT
	 ERJMP TL25
	MOVE 2,FX		;OBJECT LINE NUMBER
	MOVEI 3,10
	NOUT
	 ERJMP TL25
	HRROI T2,[ASCIZ /
/]
	SETZ T3,
	SOUT
	 ERJMP TL25
TL25:	MOVE T2,FX		;GET OBJECT LINE NUMBER
	CALL LCKTTY		;LOCK IT AGAIN
	 JRST [	CALL ULKTTY	;OOPS. WENT AWAY
		RETBAD (TTYX01)] ;GIVE ERROR
	MOVEM T2,OBJADR		;SAY HOLD LOCK
	RETSKP

TL24:	CALL ULKTTY
	RETBAD (TLNKX2)
;TLINK3 - SET REMOTE TO OBJECT

;ACCEPTS:
;	TLSAV1/ REMOTE LINE NUMBER OR -1
;	FX/ OBJECT LINE NUMBER

;	CALL TLINK3

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TLINK3:	MOVE T2,TLSAV1		;GET REMOTE LINE NUMBER
	CAIN 2,-1
	RETBAD (DESX1)		;MULTIPLE DESIGNATOR ILLEGAL
	CAMN 2,FX		;LINK TO SELF?
	RETSKP			;YES, IGNORE
	CALL LCKTTY
	 JRST [	CALL ULKTTY
		RETBAD (TTYX01)]
	CALL TLTST1		;SEE IF REMOTE POINTS TO OBJECT
	JUMPG 1,TL33		;IF SO, ALREADY DONE
	MOVE 1,CAPENB
	TRNE 1,SC%WHL+SC%OPR	;PRIVILEGED?
	JRST TL31		;YES, SKIP CHECK
	EXCH T2,TLSAV1		;GET REMOTE LINE NUMBER
	CALL TLTST2		;SEE IF OBJECT POINTS TO REMOTE
	JUMPL 1,[MOVEI T1,TLNKX1 ;IF NOT, ERROR
		EXCH T2,TLSAV1	;GET BACK REMOTE ADDRESS
		CALLRET ULKTTY]
	EXCH T2,TLSAV1		;GET BACK ADDRESS OF REMOTE
TL31:	PUSH P,FX
	MOVEI FX,777
	CALL TLTST1		;FIND FREE FIELD IN REMOTE
	POP P,FX
	JUMPL 1,[MOVEI T1,TLNKX3
		CALLRET ULKTTY]
	DPB FX,Q1		;DEPOSIT OBJ NUMBER IN FIELD
TL33:	CALL ULKTTY
	RETSKP
;TLINK4 - SET ACCEPT BIT

TLINK4:	MOVE T2,OBJADR
	MOVEI 1,TT%ALK		;IT IS BIT 26 IN TTFLGS
	TLNE Q2,(1B5)		;SET IT?
	IORM 1,TTFLGS(T2)	;YES
	TLNN Q2,(1B5)		;CLEAR IT?
	ANDCAM 1,TTFLGS(T2)	;YES
	RET

;SET OR CLEAR ACCEPT ADVICE

TLINK5:	MOVE T2,OBJADR
	MOVEI 1,TT%AAD		;YES, GET BIT
	TLNE Q2,(1B7)
	IORM 1,TTFLGS(T2)	;YES
	TLNN Q2,(1B7)		;CLEAR IT?
	ANDCAM 1,TTFLGS(T2)	;YES
	RET
;CHECK FOR EXISTENCE OF REMOTE TO OBJECT

;ACCEPTS:
;	T2/ ADDRESS OF REMOTE
;	FX/ OBJECT LINE NUMBER

;	CALL TLTST1

;RETURNS +1: ALWAYS,
;		T1/ NUMBER OF OBJECT
;			OR
;		   -1 IF REMOTE DOESN'T POINT TO OBJECT
;		Q1/ BYTE POINTER TO LINK WORD FOR REMOTE

;CLOBBERS NO AC'S

TLTST1:	MOVE Q1,[POINT 9,TTLINK(2),-1]
TLT1:	ILDB 1,Q1		;SCAN REMOTE
	CAMN 1,FX		;FOUND OBJECT?
	RET			;YES
	TLNE Q1,(7B2)		;NO, SCANNED ALL FIELDS?
	JRST TLT1		;NO
	SETO 1,			;YES, RETURN NEGATIVE VALUE
	RET

;TLTST2 - CHECK FOR EXISTENCE OF OBJECT TO REMOTE

;ACCEPTS:
;	T2/ REMOTE LINE NUMBER

;	CALL TLTST2

;RETURNS +1: ALWAYS,
;		T1/ NUMBER OF REMOTE
;			OR
;		    -1 IF OBJECT DOESN'T POINT TO REMOTE
;		Q1/ BYTE POINTER TO LINK WORD FOR OBJECT WHERE REMOTE WAS FOUND

;CLOBBERS NO AC'S

TLTST2:	MOVE 3,OBJADR		;GET ADDRESS OF OBJECT
	MOVE Q1,[POINT 9,TTLINK(3),-1] ;POINT TO LINK WORD IN OBJECT
TLT2:	ILDB 1,Q1		;SCAN OBJECT
	CAMN 1,2		;FOUND REMOTE?
	RET			;YES
	TLNE Q1,(7B2)		;NO, SCANNED ALL FIELDS?
	JRST TLT2		;NO
	SETO 1,			;YES, RETURN NEG VALUE
	RET

	ENDTV.			;END TRVAR
	SUBTTL MISCELLANEOUS GLOBAL ROUTINES

;NOTE: THE FOLLOWING ROUTINES WERE WRITTEN TO SOLVE A PARTICULAR PROBLEM;
;I. E., MODULES OTHER THAN TTYSRV WERE REFERENCING TELETYPE DATA. EACH
;OF THESE ROUTINES REPLACES CODE IN ONE OR MORE MODULES SO THAT THOSE
;MODULES NO LONGER REFERENCE TELETYPE DATA. ADDITIONS OF CALLS TO THESE
;ROUTINES MUST TAKE INTO ACCOUNT THE RULES ABOUT LOCKING/UNLOCKING DYNAMIC
;DATA.

;GTCJOB - GET JOB NUMBER FOR WHICH THIS IS THE CONTROLLING TERMINAL

;ACCEPTS: T2/ INTERNAL LINE NUMBER

;	CALL GTCJOB

;RETURNS +1: LINE IS NOT ACTIVE
;	 +2: LINE IS ACTIVE,
;		T3/ JOB NUMBER OF OWNING JOB

	RESCD

GTCJOB::SAVELN
	CALL STADYN		;POINT TO DYNAMIC DATA
	 RETBAD (TTYX01)	;LINE NOT FULLY ACTIVE
	LOAD T3,TCJOB,(T2)	;GET OWNING JOB
	RETSKP

;STCJOB - SET CONTROLLING JOB

;ACCEPTS:
;	T1/ JOB NUMBER
;	T2/ LINE NUMBER

;	CALL STCJOB

;RETURNS +1: ALWAYS

	SWAPCD
STCJOB::CALL LCKTTY
	CALLRET ULKTTY
	STOR T1,TCJOB,(T2)
	CALLRET ULKTTY
;GTTOPF - GET TOP FORK OF A SCTTY GROUP

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL GTTOPF

;RETURNS +1: LINE NOT ACTIVE
;	 +2: LINE IS ACTIVE,
;		T3/ FORK NUMBER OF TOP FORK (OR -1)
	RESCD

GTTOPF::SAVELN
	CALL STADYN		;POINT TO DYNAMIC DATA
	 RETBAD (TTYX01)	;LINE NOT FULLY ACTIVE
	LOAD T3,TTPFK,(T2)	;GET TOP FORK
	RETSKP

;STTOPF - SET TOP FORK OF A SCTTY GROUP

;ACCEPTS:
;	T1/ FORK NUMBER OR -1 TO STORE IN TTPFK
;	T2/ INTERNAL LINE NUMBER

;	CALL STTOPF

;RETURNS +1: ALWAYS

STTOPF::SAVELN
	CALL LCKTTY		;POINT TO DYNAMIC DATA
	 CALLRET ULKTTY		;NOT AN ACTIVE LINE
	STOR T1,TTPFK,(T2)	;STORE NEW FORK DATA
STTOPX:	CALLRET ULKTTY
	SWAPCD
;GTWFRK - GET NUMBER OF FORK IN INPUT WAIT ON THIS TERMINAL

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL GTWFRK

;RETURNS +1: ALWAYS,
;		T1/ NUMBER OF FORK OR -1 IF NONE

	RESCD

GTWFRK::SAVELN
	CALL STADYN
	 JRST GTWFR1
	LOAD T1,TWFRK,(T2)
	RET
GTWFR1:	MOVEI T1,-1
	RET

;TTCLFK - CLEAR WAITING FORK ON TERMINAL

;ACCEPTS:
;	T2/ LINE NUMBER

;	CALL TTCLFK

;RETURNS +1: ALWAYS

	SWAPCD

TTCLFK::NOSKED			;PREVENT RESCHEDULING
	CALL STADYN		;GET TTY'S DATA BASE
	 JRST TTCLF1		;NOT ACTIVE. IGNORE IT
	SETONE TWFRK,(T2)	;INDICATE NO WAITING FORK
TTCLF1:	OKSKED			;ALL DONE
	RET
;PTYTTY - CONVERT PTY NUMBER TO INTERNAL LINE NUMBER (TTY NUMBER)

;ACCEPTS:
;	T2/ PTY NUMBER

;	CALL PTYTTY

;RETURNS +1: ALWAYS
;		T2/ INTERNAL LINE NUMBER

;CLOBBERS NO ACS

	SWAPCD
PTYTTY::ADD T2,TT1LIN+TT.PTY	;ADD NUMBER OF FIRST PTY LINE TO GET LINE NO.
	RET

;TTYPTY - CONVERT INTERNAL LINE NUMBER TO PTY NUMBER

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;	CALL TTYPTY

;RETURNS +1:ALWAYS,
;		T1/ PTY NUMBER

;CLOBBERS NO ACS

	RESCD
TTYPTY::SUB T1,TT1LIN+TT.PTY		;SUBTRACT FIRST PTY LINE TO GET PTY NUMBER
	RET

;CHKPTY - SEE IF THIS LINE NUMBER IS A PTY

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;	CALL CHKPTY

;RETURNS +1: NOT A PTY
;	 +2: A PTY
;		T1/ PTY NUMBER

CHKPTY::ACVAR <W1>		;GET AN AC TO WORK WITH
	LOAD W1,TTSTY,(T1)	;GET LINE TYPE FOR THIS LINE
	CAIE W1,TT.PTY		;IS IT A PTY?
	RETBAD			;NO. FAILURE
	CALL TTYPTY		;CONVERT TO PTY NUMBER
	RETSKP			;RETURN SUCCESS
	SWAPCD

	ENDAV.			;END ACVAR
;CKPHYT - SEE IF THIS IS A PHYSICAL TERMINAL

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL CKPHYT

;RETURNS +1: A PTY
;	 +2: A PHYSICAL TERMINAL

;PRESERVES AC'S

	RESCD

CKPHYT::TDCALL S,<<PT,RSKP>>
	 RETSKP			;NOT A PTY
	RET			;A PTY

;CKPHYD - SAME AS ABOVE BUT FOR DYNAMIC PTR
; T2/ DYNAMIC PTR

CKPHYD:	TDCALL D,<<PT,RSKP>>
	 RETSKP			;NOT A PTY
	RET			;A PTY

;CLRINT - CLEAR INTERRUPT WORD FOR A GIVEN LINE

;ACCEPTS:
;	T1/ INTERRUPT BIT
;	T2/ LINE NUMBER

;	CALL CLRINT

;RETURNS +1: ALWAYS

CLRINT::CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 CALLRET ULKTTY		;NOT FULLY ACTIVE. IGNORE
	ANDCAM T1,TTPSI(T2)	;CLEAR INTERRUPT BIT
CLRIN1:	CALLRET ULKTTY		;ALLOW DEALLOCATION
;TTSINT - SET UP INTERRUPT WORD FOR TERMINAL

;ACCEPTS:
;	T1/ DESIRED CONTENTS OF TTPSI
;	T2/ INTERNAL LINE NUMBER
;	T3/ DESIRED CONTENTS OF TTDPSI

;RETURNS +1: ALWAYS
	SWAPCD

TTSINT::SAVELN
	CALL LCKTTY		;GET ADDRESS OF DYNAMIC DATA
	 CALLRET ULKTTY		;NOT FULLY ACTIVE
	MOVEM T1,TTPSI(T2)	;STORE INTERRUPT WORD
	MOVEM T3,TTDPSI(T2)	;STORE DEFERRED INTERRUPT WORD
	CALLRET ULKTTY		;ALLOW DEALLOCATION



;ROUTINE USED BY ATACH JSYS TO SEE IF AN ATTEMPTED ATACH IS LEGAL
;
;ACCEPTS:	T2/ TTY LINE NUMBER
;RETURNS:	+1  ILLEGAL ATACH
;		+2  OK TO ATACH

ATACTT::NOSKED			;INSURE INTEGRITY WHILE LOOKING AT TTY DATA
	CALL STADYN		;HAVE A FULL DATA BLOCK?
	IFNSK.			;NO
	   SKIPE T2		;BECOMING ACTIVE?
	   JRST ATACTL		;YES - LOSE
	   JRST ATACTW		;NO, SHORT BLOCK - WIN
	ENDIF.
	TMNN TTPRM,(T2)		;HAVE FULL BLOCK, IS IT PERMANENT?
	JRST ATACTL		;NO - LOSE
	TMNE TTBAC,(T2)		;YES, IS IT BECOMING ACTIVE?
	JRST ATACTL		;YES - LOSE
	LOAD T3,TCJOB,(T2)	;NO, GET ASSOCIATED JOB
	HRRES T3		;MAKE A FULL WORD
	SKIPL T3		;IS THERE CURRENTLY A JOB?
	JRST ATACTL		;YES - LOSE
ATACTW:	OKSKED			;DONE WITH DATA BASE
	RETSKP			;ATACH IS LEGAL

ATACTL:	OKSKED			;DONE WITH DATA BASE
	RET			;ATACH IS NOT LEGAL
;CKBJFN - SEE IF BKJFN HAS ALREADY BEEN DONE ON THIS LINE

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL CKBJFN

;RETURNS +1: BKJFN HAS NOT BEEN DONE
; 	 +2: BKJFN HAS ALREADY BEEN DONE

	SWAPCD
CKBJFN::SAVELN
	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 RETBAD			;NOT ACTIVE. BKJFN HAS NOT BEEN DONE
	JN TTRFG,(T2),RSKP	;IF FLAG SET, BKJFN HAS BEEN DONE
	RETBAD			;OTHERWISE, HASN'T BEEN DONE

;TTCKAD - SEE IF LINE IS ACCEPTING ADVICE

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCKAD

;RETURNS +1: NOT ACCEPTING ADVICE
;	 +2: ACCEPTING ADVICE

TTCKAD::JE TT%AAD,TTFLGS(T2),R	;IF NOT, NONSKIP
	RETSKP			;INDICATE ACCEPTING
;GTBPTY - GETAB ROUTINE TO GET PTY INFO

;RETURNS +1: ALWAYS
;	T1/ (NUMBER OF PTYS,,FIRST PTY NUMBER)

GTBPTY::HRLI T1,NTTPTY		;NUMBER OF PTYS
	HRR T1,TT1LIN+TT.PTY	;GET FIRST LINE NUMBER
	RET

;GTBTTF - GETAB ROUTINE FOR TTFORK TABLE

;ACCEPTS:
;	T2/ LINE NUMBER

;RETURNS +1: ALWAYS,
;	T1/ (CONTROLLING JOB,,WAITING FORK)
;		OR
;	    -1 IF LINE IS INACTIVE
;		OR
;	    (-2,,-1) IF JOB IS BEING CREATED ON THE LINE

GTBTTF::CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 JRST GTBTT1		;NOT ACTIVE.
	JN TTPRM,(T2),[	JE TTBAC,(T2),.+1 ;IF PERMANENT, AND BECOMING
			HRLOI T1,-2 ; ACTIVE, RETURN (-2,,-1)
			CALLRET ULKTTY] ;GO CLEAN UP

;LINE IS EITHER FULLY ACTIVE AND NOT PERMANENT, OR PERMANENT AND NOT BECOMING ACTIVE.
;GET OWNING JOB AND WAITING FORK AND RETURN THEM

	LOAD T1,TWFRK,(T2)	;GET WAITING FORK
	LOAD T3,TCJOB,(T2)	;GET OWNING JOB
	HRL T1,T3		;COMBINE THEM
	CALLRET ULKTTY

;LINE IS NOT FULLY ACTIVE.  RETURN -1 IF INACTIVE, (-2,,-1) IF
;BECOMING ACTIVE

GTBTT1:	SETOM T1		;NOT ACTIVE. INDICATE NO OWNER OR FORK
	SKIPGE T2		;IS JOB BEING CREATED ON THIS LINE?
	HRLI T1,-2		;YES. INDICATE THAT
	CALLRET ULKTTY		;ALLOW DEALLOCATION
;STPRM - SET THE PERMANENT BIT IN DYNAMIC DATA

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL STPRM

;RETURNS +1: ALWAYS

STPRM::	SETONE TTPRM,(T2)
	RET

;CLRPRM - CLEAR THE PERMANENT BIT

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL CLRPRM

;RETURNS +1: ALWAYS

CLRPRM::SETZRO TTPRM,(T2)
	RET

;CKINP - CHECK FOR INPUT BUFFER EMPTY

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL CKINP

;RETURNS +1: INPUT BUFFER IS EMPTY
;	 +2: INPUT BUFFER IS NOT EMPTY

	RESCD
CKINP::	CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 CALLRET ULKTTY		;NOT ACTIVE. INDICATE NO CHARACTERS
	SKIPE TTICT(T2)		;ACTIVE. ANY INPUT CHARACTERS?
	JRST [	CALL ULKTTY	;YES. ALLOW DEALLOCATION
		RETSKP]		;INDICATE NON-ZERO COUNT
	CALLRET ULKTTY		;ALLOW DEALLOCATION INDICATE ZERO COUNT
;TTCKSP - ROUTINE CALLED FROM SYSINE TO SEE IF THIS LINE NEEDS A SET SPEED
;DONE BEFORE JOB INITIALIZATION

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTCKSP

;RETURNS +1: ALWAYS

;THIS IS RELEVANT FOR REMOTE FRONT END LINES ONLY.  WHEN A JOB LOGS OFF OF A REMOTE
;LINE AND THE NEXT CARRIER-ON INTERRUPT COMES IN ON THIS LINE,
;BIT TTFSP IN TTFWED IS SET, INDICATING THAT THE SPEED MUST BE RESET
;TO THE DEFAULT. THIS ROUTINE LOOKS FOR THAT BIT
;THE (INPUT,,OUTPUT) SPEEDS ARE IN TTSPWD FOR THIS LINE

	SWAPCD
TTCKSP::JE <TTFEM,TTFSP>,(B),R	;IF NOT REMOTE, GO AWAY
				;OR IF DON'T NEED SPEED SETTING
	SETZRO TTFSP,(B)	;CLEAR SPEED SETTING REQUIRED
	TMNN TTAUT,(B)			;NON-AUTO LINE?
	SKIPG C,TTSPWD(B)	;HAVE A SPEED TO SET?
	RET			;NO. GIVE IT UP
	MOVEI A,.TTDES(B)	;A/ DEVICE DESIGNATOR FOR THIS LINE
	MOVEI B,.MOSPD		;B/ THE FUNCTION
	MTOPR			;GO SET THE SPEED
	RET			;AND DONE


;INIT SPEED WORDS
TTSPIN::MOVSI B,-NLINES		;ONLY DO THE REAL LINES
	SETOM TTSPWD(B)		;INITIALIZE THE LINE SPEEDS
	AOBJN B,.-1		;DO ALL LINES
	ret			;all done
;TTHNGU - HANG UP DATASET

;ACCEPTS:
;	T2/ LINE NUMBER

;	CALL TTHNGU

;RETURNS +1: ALWAYS

;CALLED BY THE LGOUT JSYS IF THE JOB ON THIS LINE WAS NOT LOGGED IN.

	SWAPCD
TTHNGU::CAMN 2,CTYLNO		;IS THIS THE CTY?
	RET			;YES. DON'T HANG IT UP
	PUSH P,T2		;SAVE LINE NUMBER
	CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 JRST TTHNG1		;NOT ACTIVE. CAN'T HAVE OUTPUT
	CALL TTDOBE		;WAIT TILL NO OUTPUT
	 JRST [	POP P,T2	;GET BACK LINE
		JRST TTHNGU]	;TRY AGAIN
TTHNG1:	CALL ULKTTY		;ALLOW DEALLOCATION
	POP P,T2		;RESTORE LINE NUMBER
	TDCALL S,<<FE,TTHU2>,<MC,MCHNGU>,<NT,NVTDTS>,<DZ,DZHU0>>
	RET
;TTABRT - ROUTINE TO ABORT JOB STARTUP

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTABRT

;RETURNS +1: ALWAYS

;THIS ROUTINE IS CALLED BY JOBSRT WHEN IT CANNOT START A JOB
;BECAUSE OF SOME FULL CONDITION.  IF THE LINE IS NOT A PERMANENT
;BLOCK, TTACTL SHOULD BE -1; THIS ROUTINE SETS IT TO 0.  IF THE LINE
;IS A PERMANENT BLOCK, TT%BAC SHOULD BE SET; THIS ROUTINE CLEARS IT
;THIS ALLOWS TTEMES TO SEND THE 'FULL' TO THE LINE

	RESCD
TTABRT::SAVELN
	SKIPG T3,TTACTL(T2)	;IS LINE ACTIVE?
	JRST [	SETZM TTACTL(T2) ;INDICATE NOT ACTIVE
		RET]
	SETZRO TTBAC,(T3)	;INDICATE NOT BECOMING ACTIVE
	RET
	SUBTTL BUFFER CONTROL

;ASSIGN AND SETUP TTY BUFFERS
; 3/ NUMBER OF BUFFERS TO GET
;  RETURNS +1 TRANSPARENT, EXCEPT
; 3/ BYTE POINTER FOR INPUT AND OUTPUT POINTER WORDS
;THIS ROUTINE ASSUMES THAT IT IS PROTECTED FROM RESCHEDULING

	RESCD

TTGTBF:	PUSH P,1		;TRANSPARENT TO ALL AC'S EXCEPT 3
	PUSH P,4
	PUSH P,3		;SAVE COUNT
	SETZ 1,
TTGTB1:	CHNOFF DLSCHN
	SOSGE TTFREC		;REDUCE FREE BUFFER COUNT
	JRST TTGTB3		;NONE LEFT
	HRRZ 3,@TTFREB		;GET BUFFER FROM LIST
	EXCH 3,TTFREB
	CHNON DLSCHN
	HRRZ 4,1
	JUMPE 1,[MOVSI 1,0(3)	;FIRST BUFFER, REMEMBER ITS ADDRESS
		JRST .+2]
	HRRZM 3,0(4)		;CONC NEW BUFFER ONTO LIST
	HRRI 1,0(3)
	SOSLE 0(P)		;GOT REQUESTED NUMBER OF BUFFERS?
	JRST TTGTB1		;NO
	HLRZ 3,1		;ADDRESS OF FIRST BUFFER IN LIST
	HRRZ 4,1		;ADDRESS OF LAST BUFFER IN LIST
	HRRZM 3,0(4)		;MAKE LAST POINT TO FIRST
	ADD 3,[XWD 441100,1]	;CONSTRUCT 9-BIT BYTE POINTER
	AOS -3(P)		;GIVE GOOD RETURN
TTGTB2:	ADJSP P,-1		;JUNK
	POP P,4
	POP P,1
	RET

TTGTB3:	BUG(TTYNTB)
	AOS TTFREC		;GIVE BACK FRUITLESS SOS
	CHNON DLSCHN		;RESTORE THE CHANNEL
	HRRZ 4,1
	JUMPE 1,TTGTB2		;RETURN IF THERE WERE NONE
	HLRZ 3,1		;COMPLETE THE ONES WE GOT
	HRRZM 3,0(4)
	ADD 3,[441100,,1]
	CALL TTRLBF		;THEN GIVE THEM BACK
	JRST TTGTB2
;RELEASE LIST OF TTY BUFFERS
; 3/ BYTE POINTER ANYWHERE IN ANY BUFFER OF LIST
;  RETURNS +1, CLOBBERS 3
;	PRESERVES 1
;ASSUMES INTERRUPT PROTECTION AS ABOVE

TTRLBF:	MOVEI 3,0(3)
	JUMPE 3,R		;IN CASE NO BUFFERS
	PUSH P,1
	TDNN 3,WRPMSK		;NOW AT END OF BUFFER?
	SUBI 3,TTSIZ		;YES
	ANDCM 3,WRPMSK		;NORMALIZE POINTER TO FIRST WD OF BFR
	ADDI 3,1		;WHICH IS 1 AFTER THE 0 MOD TTSIZ
	PUSH P,3		;SAVE ADDRESS OF FIRST BUFFER
	PUSH P,[0]		;DON'T CHNOFF IF ALREADY OFF
	CONSO PI,1B<DLSCHN+^D28>
	SETOM 0(P)		;INDICATE ALREADY OFF
TTRLB1:	MOVEI 1,0(3)
	HRRZ 3,0(3)		;NEXT BUFFER IN LIST
	SKIPN 0(P)		;LEAVE CHANNEL ALONE
	CHNOFF DLSCHN
	EXCH 1,TTFREB		;PUT BUFFER ON FREE LIST
	MOVEM 1,@TTFREB
	AOS TTFREC
	SKIPN 0(P)		;NO CHANNEL ON IF ALREADY OFF
	CHNON DLSCHN
	CAME 3,-1(P)		;CIRCLED AROUND TO FIRST BUFFER?
	JRST TTRLB1		;NO
	ADJSP P,-2		;RESTORE STACK
	POP P,1
	RET

;TTRLOB - RELEASE OUTPUT BUFFERS
;ACCEPTS:
;	T1/ ADDRESS OF DYNAMIC DATA
;  RETURNS +1: ALWAYS

;CLOBBERS 3 BUT PRESERVES 1
;LINE MAY BE FULLY ACTIVE OR ACTIVE WITH A MESSAGE BLOCK
;ASSUMES INTERRUPT PROTECTION AS ABOVE

TTRLOB:	SKIPN 3,TTOOUT(2)	;OUTPUT BUFFERS TO RELEASE?
	RET			;NO
	SETZM TTOCT(T2)		;CLEAR COUNT OF BYTES
	SETZM TTOOUT(2)		;YES. CLEAR OUTPUT POINTER
	SETZM TTOIN(2)		;CLEAR INPUT POINTER
	CALL CHKBKO		;PERHAPS FORK WAITING FOR OBUF EMPTY
	CALLRET TTRLBF		;RELEASE THEM
	SUBTTL CHARACTER INFORMATION TABLE (CHITAB)

	RESCD

;CHARACTER INFORMATION TABLE
;B0 - PARITY BIT FOR CHARACTER
;B12-17 - CHARACTER WAKEUP CLASS
;B18-35 - DISPATCH ADDRESS (CONTROL CHARACTERS ONLY)

PCLASS:	POINT Q2,CHITAB(1),17	;POINTER TO CLASS BITS

AN==1				;ALPHANUMERIC CLASS BIT
PC==2				;PUNCTUATION CLASS BIT
CT==4				;CONTROL (NON-FORMATTING) CLASS BIT
FC==10				;FORMATTING CONTROL CLASS BIT

DEFINE CH(PAR,CLS,DSP)<
   IFNB <DSP>,<<PAR>B0+<CLS>B17+DSP>
   IFB <DSP>,<<PAR>B0+<CLS>B17+TCOUT>>

CHITAB::CH(0,CT)		; 0 NULL
	CH(1,CT)		; 1 ^A
	CH(1,CT)		; 2 ^B
	CH(0,CT)		; 3 ^C
	CH(1,CT)		; 4 ^D
	CH(0,CT)		; 5 ^E
	CH(0,CT)		; 6 ^F
	CH(1,CT)		; 7 ^G

	CH(1,FC,TTSM4)		; 10 ^H BACKSPACE
	CH(0,PC,TTSM1)		; 11 ^I TAB
	CH(0,FC,TTSM12)		; 12 ^J LF
	CH(1,CT)		; 13 ^K
	CH(0,FC,TTSM3)		; 14 ^L FORMFEED
	CH(1,FC,TTSM5)		; 15 ^M CR
	CH(1,CT)		; 16 ^N
	CH(0,CT)		; 17 ^O

	CH(1,CT)		; 20 ^P
	CH(0,CT)		; 21 ^Q
	CH(0,CT)		; 22 ^R
	CH(1,CT)		; 23 ^S
	CH(0,CT)		; 24 ^T
	CH(1,CT)		; 25 ^U
	CH(1,CT)		; 26 ^V
	CH(0,CT)		; 27 ^W

	CH(0,CT)		; 30 ^X
	CH(1,CT)		; 31 ^Y
	CH(1,CT)		; 32 ^Z
	CH(0,17,TTSME)		; 33 ^[ ESC
	CH(1,CT)		; 34 ^\
	CH(0,CT)		; 35 ^]
	CH(0,CT)		; 36 ^^
	CH(1,CT)		; 37 ^_
	CH(1,PC)		; 40 SPACE
	CH(0,PC)		; 41 !
	CH(0,PC)		; 42 "
	CH(1,PC)		; 43 #
	CH(0,PC)		; 44 $
	CH(1,PC)		; 45 %
	CH(1,PC)		; 46 &
	CH(0,PC)		; 47 '

	CH(0,PC)		; 50 (
	CH(1,PC)		; 51 )
	CH(1,PC)		; 52 *
	CH(0,PC)		; 53 +
	CH(1,PC)		; 54 ,
	CH(0,PC)		; 55 -
	CH(0,PC)		; 56 .
	CH(1,PC)		; 57 /

	CH(0,AN)		; 60 0
	CH(1,AN)		; 61 1
	CH(1,AN)		; 62 2
	CH(0,AN)		; 63 3
	CH(1,AN)		; 64 4
	CH(0,AN)		; 65 5
	CH(0,AN)		; 66 6
	CH(1,AN)		; 67 7

	CH(1,AN)		; 70 8
	CH(0,AN)		; 71 9
	CH(0,PC)		; 72 :
	CH(1,PC)		; 73 ;
	CH(0,PC)		; 74 <
	CH(1,PC)		; 75 =
	CH(1,PC)		; 76 >
	CH(0,PC)		; 77 ?

	CH(1,PC)		; 100 @
	CH(0,AN)		; 101 A
	CH(0,AN)		; 102 B
	CH(1,AN)		; 103 C
	CH(0,AN)		; 104 D
	CH(1,AN)		; 105 E
	CH(1,AN)		; 106 F
	CH(0,AN)		; 107 G

	CH(0,AN)		; 110 H
	CH(1,AN)		; 111 I
	CH(1,AN)		; 112 J
	CH(0,AN)		; 113 K
	CH(1,AN)		; 114 L
	CH(0,AN)		; 115 M
	CH(0,AN)		; 116 N
	CH(1,AN)		; 117 O
	CH(0,AN)		; 120 P
	CH(1,AN)		; 121 Q
	CH(1,AN)		; 122 R
	CH(0,AN)		; 123 S
	CH(1,AN)		; 124 T
	CH(0,AN)		; 125 U
	CH(0,AN)		; 126 V
	CH(1,AN)		; 127 W

	CH(1,AN)		; 130 X
	CH(0,AN)		; 131 Y
	CH(0,AN)		; 132 Z
	CH(1,PC)		; 133 [
	CH(0,PC)		; 134 \
	CH(1,PC)		; 135 ]
	CH(1,PC)		; 136 ^
	CH(0,PC)		; 137 _

	CH(0,PC)		; 140 `
	CH(1,AN)		; 141 a
	CH(1,AN)		; 142 b
	CH(0,AN)		; 143 c
	CH(1,AN)		; 144 d
	CH(0,AN)		; 145 e
	CH(0,AN)		; 146 f
	CH(1,AN)		; 147 g

	CH(1,AN)		; 150 h
	CH(0,AN)		; 151 i
	CH(0,AN)		; 152 j
	CH(1,AN)		; 153 k
	CH(0,AN)		; 154 l
	CH(1,AN)		; 155 m
	CH(1,AN)		; 156 n
	CH(0,AN)		; 157 o

	CH(1,AN)		; 160 p
	CH(0,AN)		; 161 q
	CH(0,AN)		; 162 r
	CH(1,AN)		; 163 s
	CH(0,AN)		; 164 t
	CH(1,AN)		; 165 u
	CH(1,AN)		; 166 v
	CH(0,AN)		; 167 w

	CH(0,AN)		; 170 x
	CH(1,AN)		; 171 y
	CH(1,AN)		; 172 z
	CH(0,PC)		; 173 {
	CH(1,PC)		; 174 |
	CH(0,PC)		; 175 }
	CH(0,PC)		; 176 ~
	CH(1,17)		; 177 RUBOUT
	SUBTTL TCO (FIRST LEVEL OUTPUT)

;OUTPUT CHARACTER TO TERMINAL
; TCO - FIRST LEVEL, TRANSLATE ACCORDING TO PROGRAM DESIRES
; TOCY- SECOND LEVEL, DO LINKS AND FORMAT FOR PARTICULAR DEVICE
; TCOUT-THIRD LEVEL, DO BUFFERING ETC.

;TCO - FIRST LEVEL OUTPUT

;ACCEPTS:
;	T1/ CHARACTER (UP TO 9 BITS)
;	T2/ ADDRESS OF DYNAMIC DATA

;RETURNS +1: ALWAYS

;CALLED BY BOUT CODE FOR A SINGLE CHARACTER

TCO::	LOAD T3,TT%DAM,TTFLGS(T2) ;GET TERMINAL DATA MODE
	JUMPE T3,TCOB1		;GO DO BINARY MODE
	PUSH P,1		;NO. SAVE THE CHARACTER
	ANDI 1,177		;T1/ CHARACTER IN 7 BITS
	CAIN T3,.TTATE		;TRANSLATE ECHO ONLY?
	JRST TC1B		;YES, NO OUTPUT TRANSLATION
	JRST TCOE1		;NO. SOME OUTPUT TRANSLATION REQUIRED

;TCOE - ECHO OUTPUT

;ACCEPTS:
;	T1/ CHARACTER
;	T2/ ADDRESS OF DYNAMIC DATA

;RETURNS +1: ALWAYS

;THIS IS A SPECIAL ENTRY POINT USED BY TTCH7 (IN SCHEDULER CONTEXT)
;FOR IMMEDIATE ECHOING AND BY TCI FOR DEFERRED ECHOING.
;IF TCOUT IS UNABLE TO OUTPUT THE CHARACTER AND IS BEING CALLED
;FROM THE SCHEDULER, IT WILL SET TCOERR TO -1.
;THE SCHEDULER MUST CLEAR THIS WORD BEFORE CALLING AND CHECK IT UPON RETURN
;IF IN PROCESS CONTEXT AND UNABLE TO OUTPUT, IT WAITS UNTIL IT CAN DO
;THE OUTPUT

;NOTE: APPARENTLY THIS CODE IS NEVER CALLED IF TERMINAL DATA MODE IS BINARY

TCOE:	TMNE TTNXO,(T2)		;DOING PAGE STOP?
	JRST [	SETZRO TPGPS,(T2) ;YES. CLEAR LINE POSITION WITHIN PAGE
		JRST .+1]	; TO PREVENT XOFF
	PUSH P,1		;SAVE THE CHARACTER
	ANDI 1,177		;T1/ CHARACTER IN 7 BITS
	CAIN 1,.CHDEL		;RUBOUT?
	JRST TC1C		;YES, DON'T ECHO
	LOAD T3,TT%DAM,TTFLGS(T2) ;GET TERMINAL DATA MODE
	CAIE T3,.TTASC		;TRANSLATE OUTPUT AND ECHO?
	CAIN T3,.TTATE		;NO. TRANSLATE ECHO ONLY?
	JRST TCOE1		;YES. ECHO TRANSLATION REQUIRED
	JRST TC1B		;NO ECHO TRANSLATION

;CONTROL CHARACTER TRANSLATION IS REQUIRED (OUTPUT OR ECHOING).
;IF THIS IS A CONTROL CHARACTER, DO THE TRANSLATION. OTHERWISE,
;CALL LEVEL 2

 TCOE1:	CAIL 1,40		;CONTROL GROUP?
	JRST TC1B		;NO. GO CALL LEVEL 2 CODE
	;..
;TCO..

;TRANSLATE CONTROL CHARS ACCORDING TO CC OUTPUT CONTROL MODES IN FCMOD1/FCMOD2
; 00 - SEND NOTHING
; 01 - INDICATE, E.G. ^A
; 1X - DO FUNCTION (SECOND LEVEL HANDLES SIMULATION IF NECESSARY)
;	10 - SEND ACTUAL CODE
;	11 - SIMULATE FORMAT ACTION

	;..
	MOVE 4,FCMOD2(2)
	MOVE 3,FCMOD1(2)	;GET MODE BITS
	ROTC 3,0(1)
	ROTC 3,0(1)
	CAIN 1,.CHESC		;ESC SPECIAL CASE?
	JRST [	TLNN 3,(3B1)	;YES, FLUSH CASE?
		JRST TC1C	;YES
		TLNN 3,(1B1)
		JRST TC1B	;10 CASE, OUTPUT REAL CHAR
		TLNN 3,(1B0)
		JRST TC1D	;01 CASE, INDICATE WITH ^[
		MOVEI 1,"$"	;11 CASE, 'SIMULATE' WITH $
		JRST TC1B]

;DETERMINE ACTION ACCORDING TO CONTROL CHARACTER OUTPUT CONTROL BITS

	TLNE 3,(1B0)		;DO?
	JRST TC1B		;YES. CALL LEVEL 2 TO SEND CODE
				; OR SIMULATE FORMAT ACTION
	TLNN 3,(1B1)		;FLUSH?
	JRST TC1C		;YES. DON'T SEND ANYTHING

;INDICATE CONTROL CHARACTER BY ^

TC1D:	ADDI 1,100		;CONVERT TO PRINTING EQUIV.
	PUSH P,1
	MOVEI 1,TTCIND		;GET ^
	SKIPE IMECHF		;ECHOING?
	AOS LINKF		;YES. FORCE IT OUT
	CALL TCOY		;PRINT INDICATOR
	POP P,1			;GET BACK THE CHARACTER
	CALL TCOY		;OUTPUT THE CHARACTER
	SKIPE IMECHF		;DOING ECHO?
	SOS LINKF		;YES.
	JRST TC1C		;GO RETURN

;CALL LEVEL 2 TO OUTPUT THE CHARACTER. IF NECESSARY, IT WILL
;DO CONTROL CHARACTER SIMULATION

TC1B:	CALL TCOY		;CALL LEVEL 2
TC1C:	POP P,1			;RETURN THE CHARACTER
	RET

;TCOB - ENTRY FOR BINARY OUTPUT. NO TRANSLATION


;ACCEPTS:
;	T1/ CHARACTER (UP TO 9 BITS)
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TCOB

;RETURNS +1: ALWAYS

TCOB::
TCOB1:	ANDI T1,377		;7 BITS OF CHARACTER + PARITY
	CALLRET TCOU1		;GO OUTPUT THE CHARACTER WITHOUT ADDING PARITY
	SUBTTL TCOY (SECOND LEVEL OUTPUT)

;SECOND LEVEL - HANDLE DEVICE IDEOSYNCRACIES AND CHAR ACCOUNTING

;ACCEPTS:
;	T1/CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA

;IMECHF IS -1 IF THIS CHARACTER IS BEING OUTPUT FOR IMMEDIATE ECHOING
;WHEN TAKEN OUT OF TTBBUF BY TTCH7

;CALLED FROM TCO (FIRST LEVEL OUTPUT). BY NOW, IF THIS IS A CONTROL
;CHARACTER, THE CONTROL CHARACTER OUTPUT CONTROL SPECIFIED EITHER
;	10 - SEND ACTUAL CODE
;		OR
;	11 - SIMULATE FORMAT ACTION

;WE CAN ALSO GET HERE WHEN TT%DAM HAS .TTATO SET AND WE ARE DOING ECHO
;OR TT%DAM HAS .TTATE AND WE ARE DOING OUTPUT

TCOY:	SAVEQ
	CAIN 1,.CHDEL
	JRST [	CALL TCOUT	;RUBOUT, SEND DIRECTLY
		JRST TCOY3]
	SKIPE IMECHF		;IMMED ECHO CHAR?
	JRST [	MOVE 3,TTFLGS(2) ;YES, CHECK DUPLEX BITS
		TXNN T3,TT%ECO	;IS ECHOING OFF?
		JRST TCOY3	;YES - THEN DON'T ECHO
		SKIPN LINKF	;LINKED CHAR? OR
		TRCN 3,3B33	;FULL?
		JRST .+1	;YES
		CALL TTCOHA	;ACCOUNT SPACING FOR CHAR
		CAIGE 1,40	;IS CONTROL CHAR AND MODE 2?
		TRNN 3,3B33
		JRST [	MOVE T3,TTLINK(T2) ;NO. GET LINK WORD
			CAME T3,[-1] ;ANY LINKS?
			CALL TTLNK3 ;YES. DO THEM
			JRST TCOY3] ;AND DONE
		JRST TTCO1]	;YES, ECHO CONTROL FN

;EITHER NOT IMMEDIATE ECHOING OR IMMEDIATE ON A FULL-DUPLEX TERMINAL
;IF CONTROL CHARACTER, GO HANDLE SPECIALLY

	CAIGE 1,40
	JRST TTCO1		;CONTROL GROUP

;NOT A CONTROL CHARACTER. RAISE IF NECESSARY

	MOVE 3,TTFLGS(2)
	TXNE 3,TT%LCA		;TERMINAL HAS LOWER CASE?
	JRST TTCO6		;YES, NO TRANSLATION NEEDED
	CAIL 1,"A"		;UPPER CASE LETTER?
	CAILE 1,"Z"
	JRST [	CAIL 1,"A"+40	;NO, LOWER CASE LETTER?
		CAILE 1,"Z"+40
		JRST TTCO6	;NO
		SUBI A,40	;YES, CONVERT TO UPPER CASE
		JRST TTCO6]

;CHARACTER IS UPPER CASE. IF FLAGGING IS REQUIRED, CALL THIRD LEVEL
;ROUTINE TO PRINT A '^' BEFORE PRINTING THE CHARACTER

	TXNN 3,TT%UOC		;INDICATE?
	JRST TTCO6		;NO
	PUSH P,1		;YES, SAVE CHAR
	MOVEI 1,TTLIND		;OUTPUT INDICATOR
	CALL TCOP
	POP P,1
TTCO6:	CALL TCOP		;OUTPUT CHAR AND ACCOUNT SPACE
TCOY3:	RET
;TCOP - SECOND LEVEL SUBROUTINE - OUTPUT SINGLE SPACING CHARACTER
;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA FOR THIS LINE

;	CALL TCOP

TCOP:	AOS T3,TTLPOS(T2)	;GET CURRENT POSITION ON LINE
				;INCREMENT COUNT
	HRRZS T3
	LOAD 4,TPWID,(T2)	;GET RIGHT MARGIN
	JUMPE 4,TCOUT		;0 MEANS NEVER FOLD
	CAIL 4,0(3)		;CHECK FOR OVERFLOW
	CALLRET TCOUT		;NO OVERFLOW, OUTPUT CHAR

;REACHED END OF LINE. HANDLE WRAPAROUND AND GO BACK TO OUTPUT THE CHARACTER

	PUSH P,1		;LINE OVERFLOW, DO CR AND CONTINUATION
	MOVEI 1,15		;T1/ CARRIAGE RETURN
	CALL TTSM5		;DO CR
	MOVEI 1,12		;T1/ LINE FEED
	CALL TTSM2		;DO LF
	SETZRO TLNPS,(T2)	;RESET LINE POSITION TO 0
   REPEAT 0,<			;** FOLD INDICATION DISABLED
	MOVEI 1,2		;COUNT 2 *'S
	HRRM 1,TTLPOS(2)
	MOVEI 1,52
	CALL TCOUT
	CALL TCOUT
   >
	POP P,1
	JRST TCOP		;GO OUTPUT THE CHARACTER
;TTCOHA - ACCOUNT SPACING PERFORMED BY HALF-DUPLEX TERMINAL
;TERMINAL HAS PRINTED THE CHARACTER. THIS MERELY ACCOUNTS FOR THE
;RESULTING POSITION ON THE TERMINAL

;ACCEPTS:
;	T1/ CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA

TTCOHA:	CAIL 1,40		;SPACING CHAR?
	JRST [	INCR TLNPS,(T2)	;YES. INCREMENT POSITION ON LINE
		RET]
	CAIE T1,.CHLFD		;LF?
	CAIN 1,15		;CR?
	JRST [	SETZRO TLNPS,(T2) ;YES. RESET TO LEFT MARGIN
		RET]
	CAIN 1,.CHLFD		;LF?
	CALLRET INCLIN		;COUNT LINES
	CAIN 1,.CHFFD		;FF?
	JRST [	SETZRO TPGPS,(T2) ;YES. RESET TO TOP OF PAGE
		RET]
	CAIE 1,.CHBSP		;BACKSPACE?
	RET			;NO
	JE TLNPS,(T2),R		;YES. IF NOT AT LEFT MARGIN,
	DECR TLNPS,(T2)		; DECREMENT CHARACTER POSITION WITHIN PAGE
	RET
	SUBTTL TCOY FOR CONTROL CHARACTERS

;HERE WHEN THE CHARACTER TO BE OUTPUT IS A CONTROL CHARACTER

;ACCEPTS:
;	T1/CHARACTER IN 7 BITS
;	T2/INTERNAL LINE NUMBER

;THIS IS PART OF THE SECOND LEVEL OUTPUT AND IS CALLED BY TCOY.
;CHITAB CONTAINS THE ROUTINE THAT WILL PROCESS THE CHARACTER
;IN SOME CASES, IT CONTAINS TCOUT, THE THIRD LEVEL ROUTINE.
;IN OTHER CASES, IT CONTAINS A SPECIAL ROUTINE, WHICH DOES SOME TRANSLATION
;AND THEN CALLS TCOUT

;FOR EACH CHARACTER, ACTION IS CONTROLLED BY TWO BITS IN FCMOD1 OR FCMOD2:
; 00 => IGNORE, DO NOT SEND
; 01 => SEND PRINTING INDICATION (I.E. &C)
; 10 => SEND ACTUAL CODE AND ACCOUNT LINE AND PAGE POSITION
; 11 => SIMULATE FORMAT ACTION AND ACCOUNT
;WHEN THIS CODE IS CALLED, LEVEL 1 OUTPUT HAS ALREADY HANDLED THE
;TRANSLATION OF CONTROL CHARACTER IF MODE 0 OR 1 IS IN EFFECT

TTCO1:	MOVE 4,FCMOD2(2)	;SECOND CONTROL MODES WORD
	MOVE 3,FCMOD1(2)	;FIRST CONTROL MODES WORD
	ROTC 3,0(1)		;GET TWO BIT MODE FOR THIS CHAR
	ROTC 3,0(1)
	HRRZ 4,CHITAB(1)	;GET DISPATCH ADDRESS
	CALL 0(4)		;DISPATCH TO FORMAT ROUTINE
	JRST TCOY3
;TAB

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

;	CALL TTSM1

TTSM1:	PUSH P,3		;SAVE OUTPUT MODE
	LOAD 3,TLNPS,(2)	;OLD POSITION
	IDIVI T3,TABSIZ		;COMPUTE SPACES BEYOND CURRENT STOP
	MOVEI FX,TABSIZ
	SUB FX,T4		;COMPUTE SPACES TO NEXT STOP
	POP P,3			;MODE WORD
	MOVSI 4,(1B2)		;HAS-TAB BIT
	TLNN 3,(1B1)		;SIMULATE REQUESTED?
	TDNN 4,TTFLGS(2)	;OR NO MECH TAB ON DEVICE?
	JRST TTSM13		;YES, GO SIMULATE
	MOVEI 1,.CHTAB		;SEND REAL TAB
	CALL TCOUT
	MOVE 4,FX		;PLUS RUBOUTS TO KILL TIME
	IDIVI 4,4		;ASSUME FOUR SPACES PER RUBOUT
	LOAD 3,TTTYP,(2)	;GET TYPE OF TERMINAL
	LDB 1,TTTBPD		;GET NUMBER PADS PER FOUR SPACES
	IMULI 4,0(1)
	JUMPLE 4,TTSM14
	PUSH P,FX		;SAVE NEW POSITION
	MOVEI FX,0(4)		;ITERATION
TTSM16:	MOVEI 1,TTFILL
	CALL TCOUT
	SOJG FX,.-1
	POP P,FX		;RESTORE LINE POSTION
TTSM14:	OPSTR <ADD FX,>,TLNPS,(2) ;UPDATE POSITION
	STOR FX,TLNPS,(2)
	RET

TTSM13:	MOVEI 1,40		;SIMULATE WITH SPACES
	CALL TCOP		;SEND ONE
	SOJG FX,TTSM13		;SEND ALL OF THEM
	RET
;LINE FEED

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

;	CALL TTSM12

TTSM12:	TXNN T3,<1B1>		;CODE 2?
	JRST TTSM2		;YES, DO LF ONLY
	MOVEI T1,.CHCRT		;DO CR FIRST
	OPSTR <SKIPE T3,>,TLNPS,(T2)
	CALL TTSM5
	MOVEI T1,.CHLFD		;THEN LF
	;..

;LOCAL LINEFEED - DOES NOT INCLUDE CR

TTSM2:	CALL INCLIN		;ACCOUNT FOR LINE
	LOAD 3,TPLEN,(T2)	;GET PAGE LENGTH
	JUMPE 3,TTSM2X		;NO CHECK IF LENGTH 0
	LOAD 1,TPGPS,(2)	;GET CURRENT PAGE POSITION
	CAML 1,3		;PAGE FULL?
	JRST [	SETZRO TPGPS,(2) ;YES. RESET TO TOP OF PAGE
		CALL TTXOFF	;DO XOFF IF IN PAGE MODE
		JRST .+1]
TTSM2X:	MOVEI 1,.CHLFD		;GET LINE FEED
	CALL TCOUT		;OUTPUT LINE FEED
	LOAD 3,TTTYP,(2)	;GET TERMINAL TYPE
	LDB Q1,TTLFPD		;LF PADDING
	CALLRET TTSPAD		;DO PADDING

;ROUTINE TO KEEP LINE COUNTER AND MAX UPDATED.

INCLIN:	SAVET			;PRESERVE TEMPS
	INCR TPGPS,(T2)		;INCREMENT LINE POSITION ON PAGE
	AOS A,TTLINE(B)		;INCREMENT LINE COUNTER
	CAMLE A,TTLMAX(B)	;NEW MAXIMUM?
	MOVEM A,TTLMAX(B)	;YES, REMEMBER IT
	RET
;FORM FEED


;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

TTSM3:	LOAD 4,TPGPS,(2)	;GET PRESENT PAGE POSITION
	SETZRO TPGPS,(T2)	;RESET TO TOP OF PAGE
	PUSH P,3
	LOAD 3,TPLEN,(2)	;PAGE SIZE
	JUMPE T3,[SETZM Q1	;IF ZERO PAGE LENGTH, SAY AT THE END
		JRST TTSM34]
	IDIVI 4,0(3)
	SUBM 3,Q1		;Q1/ DIFFERENCE TO END OF PAGE
TTSM34:	POP P,3
	MOVSI 4,(1B1)
	TDNE 4,TTFLGS(2)	;DEVICE HAS MECH FF?
	TLNE 3,(1B1)		;AND SEND DIRECT REQUESTED?
	JRST TTSM32		;NO, SIMULATE FF
	CALL TCOUT		;SEND REAL CHARACTER
	LOAD 3,TTTYP,(2)	;GET TERMINAL TYPE
	LDB Q1,TTFFPD		;FF PADDING
	CALL TTSPAD		;DO PADDING
	JRST TTSM3Y


;SIMULATE FORM FEED BY OUTPUTTING AS MANY LINE FEEDS AS ARE NEEDED
;TO GET TO THE TOP OF THE NEXT PAGE

TTSM32:	PUSH P,TTLPOS(2)	;SAVE LINE AND PAGE POSITIONS
	PUSH P,Q1		;SAVE NUMBER OF LINES LEFT IN PAGE
TTSM33:	CALL TTSM2		;SIMULATE ONE FORM FEED
	SETZRO TPGPS,(T2)	;PREVENT TTSM2 FROM DOING X-OFF
	SOSLE 0(P)		;COUNT LF'S
	JRST TTSM33		;LOOP ON LF'S
	POP P,Q1		;FLUSH TEMP
	POP P,TTLPOS(2)		;RESTORE LINE AND PAGE POSITIONS
TTSM3Y:	LOAD 1,TPLEN,(2)	;CHECK PAGE LENGTH
	JUMPE T1,R		;DO XOFF UNLESS PLENGTH IS 0
	CALLRET TTXOFF		;DO XOFF
;ROUTINE TO INSERT PADDING

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1
;	Q1/ NUMBER OF FILLS TO SEND
;	CALL TTSPAD
; RETURN +1 ALWAYS

TTSPAD:	MOVEI 1,TTFILL		;FILLER
	JUMPLE Q1,R		;DONE IF COUNT EXHAUSTED
	CALL TCOUT		;SEND ONE
	SOJA Q1,TTSPAD		;COUND DOWN RUBOUTS

;BACKSPACE

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

TTSM4:	LOAD 4,TLNPS,(2)	;GET LINE POSITION
	JUMPE 4,TTSM45		;IF AT BEGINNING SKIP REST
	MOVE 4,TTFLGS(2)	;GET CURRENT LINE STATE
	TRNN 4,3B33		;IN HALF DUPLEX?
	JRST [	DECR TLNPS,(T2) ;NO. ACCOUNT FOR BACKSPACE
		JRST .+1]
TTSM45:	TLNN 3,200000		;REAL OR SIMULATED
	CALLRET TCOUT		;NO. OUTPUT DIRECTLY
	MOVEI 1,15		;SIMULATE WITH CR AND SPACES (UGH)
	CALL TCOUT
	LOAD 4,TLNPS,(2)	;GET CHARACTER POSITION WITHIN LINE
TTSM44:	MOVEI 1,40		;GET SPACE
	JUMPE 4,R		;IF AT LEFT MARGIN, QUIT
	PUSH P,4		;SAVE COUNTER
	CALL TCOUT		;OUTPUT A SPACE
	POP P,4			;RESTORE COUNTER
	SOJA 4,TTSM44		;DO ALL NECESSARY SPACES

;CARRIAGE RETURN

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

TTSM5:	MOVEI 1,.CHCRT		;T1/ CARRIAGE RETURN
	CALL TCOUT		;OUTPUT THE CARRIAGE RETURN
	LOAD 4,TLNPS,(2)	;GET CHARACTER POSITION WITHIN LINE
	SETZRO TLNPS,(2)	;RESET LINE POSITION
	LOAD 3,TTTYP,(2)	;GET TERMINAL TYPE
	LDB Q1,TTCRPD		;CR PADDING
	IMULI 4,0(Q1)		;COMPUTE POSN/72*PAD, I.E. PAD IS
	ADDI 4,^D71		;AMOUNT FOR 72 CHAR LINE, SO PRO-RATE
	IDIVI 4,^D72		;BASED ON FULLNESS OF LINE, ROUNDING
	MOVEI Q1,0(4)		;PAD COUNT UP TO NEXT INTEGER
	CALLRET TTSPAD		;DO PADDING

;ESC

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1

TTSME:	TLNN 3,(3B1)		;00?
	RET			;YES, NO SEND
	TLNE 3,(1B1)		;01 OR 11?
	JRST [	MOVEI 1,"$"	;YES, SEND $
		CALLRET TCOP]
	CALLRET TCOUT		;SEND ACTUAL CODE

;TTXOFF - STOP OUTPUT TO A TERMINAL, I.E. PAUSE ON END-OF-PAGE

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;CALLED WHEN OUTPUT TO A TERMINAL CAUSES THE PAGE TO FILL UP. IF TERMINAL
;IS IN PAGE MODE, PUTS SPECIAL CHARACTER IN OUTPUT STREAM TO CAUSE 'XOFF' ACTION
;WHEN ENCOUNTERED AT INTERRUPT LEVEL

TTXOFF:	MOVX 1,TT%PGM
	TMNE TTNXO,(T2)		;DOING PAGE STOP?
	TDNN 1,TTFLGS(2)	;IN PAGE MODE?
	RET			;NO, DO NOTHING
	MOVEI 1,"G"-100		;OUTPUT BELL TO TELL USER THAT
	CALL TCOUT		; HE MUST RESTART OUTPUT
	MOVEI 1,TTOPFC		;PUT SPECIAL FUNCTION CODE IN OUTPUT
	CALLRET TCOU3		; STREAM TO STOP OUTPUT AT THAT POINT
	SUBTTL TCOUT (THIRD LEVEL OUTPUT)

;OUTPUT ONE CHARACTER TO SPECIFIED TTY LINE

;ACCEPTS:
;	T1/ CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA

;RETURNS +1: ALWAYS

;IF IN SCHEDULER AND UNABLE TO SEND CHARACTER, SETS TCOERR TO -1

;SPECIAL ENTRY POINT WHEN ENTERING FROM TTEMES

;ACCEPTS:
;	T1/ CHARACTER
;	T2/ ADDRESS OF DYNAMIC DATA (FULL-LENGTH OR TTEMES BLOCK)

;RETURNS +1: ALWAYS

;IF UNABLE TO SEND CHARACTER AND IN SCHEDULER, SETS TCOERR TO -1

SCDTCO:	SKIPL CHITAB(T1)	;TEST PARITY BIT FOR THIS CHARACTER
	JRST TCOU6		;NO PARITY NEEDED. GO ON
	CALL SPARTY		;SET PARITY BIT
	JRST TCOU6		;GO STORE IN OUTPUT BUFFER

;PUT MARKER IN OUTPUT STREAM - IGNORE TOFLG

TCOUM:	CALL CKPHYD		;PTY?
	 RET			;YES, DO NOTHING
	JRST TCOUM1		;ENTER OUTPUT SEQUENCE

;PHYSICAL LINE. APPLY PARITY

TCOUT:	SKIPL CHITAB(1)		;TEST PARITY BIT FOR THIS CHAR
	JRST TCOU1		;NO PARITY NEEDED. GO ON
	CALL SPARTY		;SET PARITY BIT AS NEEDED

;FULLY ACTIVE LINE. PROCESS LINES LINKED TO THIS ONE

TCOU1:	MOVE C,TTLINK(B)	;ANY LINKS?
	CAME C,[-1]
	CALL TTLNK3		;YES. GO DO THEM

;SEE IF THERE IS ROOM IN THE OUTPUT BUFFER

TCOU3:	JN TOFLG,(T2),R		;LOSE CHARACTER IF CTRL/O TYPED
TCOUM1:	DYNST T3		;GET INTERNAL LINE NUMBER
	CAMN T3,CTYINT		;IS THIS AN ALIAS FOR THE CTY?
	RET			;YES. IGNORE CHARATCER
TCOU6:	LOAD 3,TOMAX,(2)	;CAPACITY OF OUTPUT BUFFERS
	SKIPE IMECHF		;IMMEDIATE ECHO CHARACTER?
	ADDI 3,2		;YES. EXTRA ROOM FOR THIS CHARACTER
	CAMLE 3,TTOCT(2)	;FULL?
	JRST TCOU5		;NO
	; ..
	; ..

;ACTION WHEN BUFFER FULL

	SKIPN INSKED		;ARE WE IN THE SCHEDULER?
	SKIPE NSKED		;NO. ARE WE NOSKED?
	JRST [	SETOM TCOERR	;YES. INDICATE FAILURE FOR SCHEDULER
		RET]		; AND RETURN
	TDCALL D,<<PT,CHKPTA>>	;CHECK FOR PTY ACTION NEEDED
	SETONE TTBKO,(T2)	;NOTE BLOCKE FOR OUTPUT EVENT
	PUSH P,1		;SAVE CHARACTER
	DYNST T1		;GET LINE NUMBER
	PUSH P,T1		;SAVE LINE #
	CALL ULKTTY		;UNLOCK THE TTY
	MOVEI 1,TCOTST		;SETUP SCHEDULER TEST WORD
	HRL 1,0(P)		; LINE NO,,TEST ROUTINE ADR
	MOVSI T2,FHV5		;WAIT PRIORITY
	HDISMS
	MOVE T2,0(P)		;GET STATIC LINE NUMBER
	CALL LCKTTY		;LOCK UP THE TTY
	 JRST    [CALL ULKTTY	;UNLOCK THE LINE I CASE IT GOT LOCKED
                  MOVE T2,0(P)  ;GET BACK LINE NUMBER
                  CALL TCOU7	;GET SPECIAL BLOCK
                  JRST .+1]
	ADJSP P,-1		;CLEAN UP STACK
	POP P,T1		;CHARACTER
	JRST TCOU3
;BUFFER IS NOT FULL.  SEE IF THERE IS A BUFFER. IF NOT, GET AS MANY
;AS ARE NEEDED

TCOU5:	TDCALL D,<<PT,CKPTOU>,<MC,CKMCOU>>,RETSKP ;SEE IF OUTPUT POSSIBLE
	 RET
	NOSKD1
	CHNOFF DLSCHN		;MUST PREVENT DEASSIGN OF BUFFERS
	SKIPE 3,TTOIN(2)	;BUFFERS EXIST?
	JRST TCOU4		;YES.

;THIS LINE HAS NO OUTPUT BUFFERS. GET SOME IF POSSIBLE. IF NONE
;AVAILABLE, WAIT FOR THEM UNLESS IN SCHEDULER. IN THAT CASE, SET
;ERROR FLAG AND RETURN

	CHNON DLSCHN		;NO. ALLOW DLS INTERRUPTS
	LOAD 3,TTNOU,(2)	;GET NUMBER TO ASSIGN
	CALL TTGTBF		;ASSIGN THEM
	 JRST [	OKSKD1		;FAILED. ALLOW SCHEDULING
		SKIPN INSKED	;ARE WE IN THE SCHEDULER?
		SKIPE NSKED	;NO. ARE WE NOSKED?
		JRST [	SETOM TCOERR ;YES. INDICATE ERROR FOR SCHEDULER
			RET]	; AND RETURN
		PUSH P,1	;SAVE CHARACTER
		LOAD 1,TTNOU,(2);NO, CAN WAIT FOR BUFFERS
		MOVSI 1,0(1)	;NUMBER NEEDED
		HRRI 1,TTBUFW
		MDISMS
		POP P,1		;RESTORE CHARACTER
		JRST TCOU5]	;BUFFERS ARE AVAILABLE. GO GET THEM
	CHNOFF DLSCHN
	MOVEM 3,TTOOUT(2)
	MOVEM 3,TTOIN(2)

;BUFFERS ARE AVAILABLE. AC 3 CONTAINS BYTE POINTER FOR ADDING NEXT
;CHARACTER. STORE THE CHARACTER.

TCOU4:	TDNN 3,WRPMSK		;END OF BUFFER?
	JRST [	HRRZ T4,T3	;GET NEXT ONE
		HRR T3,1-TTSIZ(T4)
		MOVEM T3,TTOIN(T2) ;SAVE CHARACTER POINTER
		JRST .+1]
	IDPB T1,TTOIN(T2)	;GET CHARACTER
	AOS 3,TTOCT(2)		;INCREMENT COUNT OF CHARACTERS IN BUFFER
	CHNON DLSCHN		;SAFE TO TURN CHN ON AFTER AOS
	AOS NTTYOT		;COUNT ALL OUTPUT
	CALLRET STRTOU		;START OUTPUT TO LINE IF NEEDED

;SET PARITY BIT IF REQUIRED FOR THIS LINE TYPE
; T2/ DYNAMIC DATA PTR
; T1/ CHARACTER
;RETURN +1 ALWAYS, T1 MODIFIED

SPARTY:	LOAD CX,TLTYP,(T2)	;GET LINE TYPE
	XCT PARTBL(CX)		;SET OR CLEAR BIT
	RET
;HERE WHEN DID TCOTST BLOCK AND AWOKE TO FIND LINE
;HAS BEEN DEASSIGNED

	SWAPCD			;GET HERE ONLY IN PROCESS CONTEXT
TCOU7:	STKVAR <LNNUMB>
	MOVEM T2,LNNUMB		;SAVE LINE NUMBER
TCOU75:	NOSKED			;OWN THE MACHINE
TCOU76:	MOVE T2,LNNUMB		;GET LINE #
	CALL LCKTTY		;CHECK IT NOW
	SKIPA   		;IF UNASSIGNED, GO ON
	JRST [	OKSKED		;ALLOW SCHEDULING
		RET]		;AND DONE
	CALL ULKTTY		;UNLOCK IN CASE IT GOT LOCKED
	JUMPG T2,TCOU77		;IF BLOCK IS SHORT WAIT IT TO BE DEALLOCATED
	MOVE T2,LNNUMB		;LINE # AGAIN
	CALL ASGMSL		;GET A MESSAGE BLOCK
	 JRST TCOU77		;FAILED
	CALL STADY		;SUCCESS. GET DYNAMIC DATA ADDRESS
	 JRST TCOU77		;SOMETHING VERY WRONG. TRY AGAIN
	SETOM TTLINK(T2)	;NO LINKS
	JRST TCOU76		;AND PROCEED

TCOU77:	MOVEI T1,^D1000		;WAIT 1 SEC
	CALL SETBKT		;COMPUTE WAIT
	HRRI T1,BLOCKT		;THE TEST
	RDISMS			;WAIT HERE
	JRST TCOU75		;TRY AGAIN

	ENDSV.			;END STKVAR

	RESCD			;BACK TO RESIDENT MONITOR
;TTLNK3 - SCAN LINK WORD, SENDING CHAR TO LINES SPECIFIED BY NON-777 BYTES

TTLNK3:	SKIPE IMECHF		;ECHO CHARACTER?
	JRST [	PUSH P,T2	;SAVE DYNAMIC DATA ADDRESS
		JRST TTLN33]	;AND PROCEED
	DYNST T4		;GET LINE NUMBER
	PUSH P,T4		;SAVE LINE NUMBER
	CALL ULKTTY		;UNLOCK THE TTY
TTLN33:	;AOS LINKF		;BE SURE CHARS GO OUT
TTLNK2:	SETZ 2,
	LSHC 2,^D9		;GET NEXT FIELD
	CAIN 2,777
	JRST TTLNK1		;MEANS NOT IN USE
	PUSH P,3
	PUSH P,1		;SAVE CHARACTER
	CALL LCKTTY		;LOCK UP DESTINATION TTY
	 JRST TTLNK4		;NOT ACTIVE. DON'T SEND TO IT
	TRNN 1,200		;THIS CHARACTER HAVE PARITY?
	JRST TTLK11		;NO. GO ON
	CALL SPARTY		;SET PARITY BIT
TTLK11:	CALL TCOU3		;GO SEND EXACT CHARACTER
TTLNK4:	CALL ULKTTY		;FREE UP THE TTY
	POP P,1
	POP P,3
TTLNK1:	JUMPN 3,TTLNK2		;DO MORE IF ANY
;	SOS LINKF		;NO LONGER LINKING
	SKIPE IMECHF		;DOING ECHOING?
	JRST PB2		;YES. CLEAN UP AND DONE
	PUSH P,1		;SAVE BYTE
	MOVE T2,-1(P)		;GET BACK LINE NUMBER
	CALL LCKTTY		;LOCK IT UP AGAIN
	 JUMPLE T2,[MOVE T2,-1(P) ;GET LINE # AGAIN
		CALL TCOU7	;GET A SPECIAL BLOCK
		JRST .+1]	;AND PROCEED
	POP P,T1		;GET BYTE
	ADJSP P,-1		;CLEAN UP STACK
	RET			;AND PROCEED
;TCOTST - CALLED FROM SCHEDULER TO TEST FOR RUNNABLE

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

;CAUSES WAKEUP IF OUTPUT BUFFER IS NOT TOO FULL TO ADD A CHARACTER TO IT

TCOTST::MOVEI 2,0(1)		;LINE NUMBER TO REGULAR AC
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST 1(T4)		;NOT ACTIVE. SHOULDN'T HAPPEN
	LOAD 1,TOWRN,(2)	;REGULAR WAKEUP COUNT
	SKIPE FKINT(FX)		;BUT IF INTERRUPT WAITING,
	LOAD 1,TOMAX,(2)	;WAKEUP IF BUFFER IS NOT FULL
	CAMG 1,TTOCT(2)		;AT WAKEUP LEVEL?
	JRST 0(4)		;NO
	SETZRO TTBKO,(T2)	;NOTE WAIT COMPLETED
	JRST 1(4)		;YES

;TTBUFW - CALLED FROM SCHEDULER TO WAIT FOR BUFFERS

;ACCEPTS:
;	T1/ NUMBER OF BUFFERS NEEDED

;CAUSES WAKEUP IF THE NEEDED NUMBER OF BUFFERS ARE AVAILABLE

TTBUFW:	CAMLE 1,TTFREC
	JRST 0(4)
	JRST 1(4)
	SUBTTL TCI (GET CHAR FROM INPUT BUFFER)

;ROUTINE TO GET CHARACTER FROM LINE INPUT BUFFER
;CONVERT FROM ASCII TO INTERNAL AND GENERATE ECHOS
;AS REQUESTED

;ACCEPTS IN T2/	LINE #
;	CALL TCI
;RETURNS +1:	NEEDED TO BLOCK, CALLER MUST VERIFY IF THE TTY BEING
;			INPUT FROM IS STILL THE CORRECT ONE.  IN
;			PARTICULAR, WAS THE JOB DETACHED?
;	 +2:	SUCCESSFUL, CHARACTER IN T1
;N.B. T2 MUST BE PRESERVED IN THIS ROUTINE

TCI::
TCI1:	LOAD T3,TT%DAM,TTFLGS(T2) ;GET CURRENT DATA MODE
	JUMPE T3,TCIB2		;JUMP IF BINARY
	LOAD T1,TYLCH,(T2)	;GET LAST CHARACTER TAKEN FROM INPUT BUFFER
	TMNE TTRFG,(T2)		;REPEAT LAST CHARACTER (BKJFN)?
	JRST [	SETZRO TTRFG,(T2) ;YES. CLEAR FLAG
		TXO T1,TTXECO	;INDICATE ALREADY ECHOED
		JRST TCI3]
	LOAD T3,TYLMD,(T2)	; GET MODE OF LAST CHAR INPUT
	CAIN T1,.CHCRT		;LAST CHAR WAS A CR?
	CAIN T3,.TTBIN		; YES, LAST MODE NON-BINARY?
	JRST [	CALL TCI0	; NO TO EITHER - GET NEXT CHAR FROM BUFFER
		 RETBAD		;NEEDED TO BLOCK. TELL THE CALLER.
		JRST TCI3]	; AND CONTINUE
	MOVE T1,[.CHLFD+TTXECO]	;YES, RETURN LF WITH NO ECHO

;NEXT CHARACTER IS IN RIGHT 9 BITS OF T1. IF IT HAS BEEN ECHOED,
;BIT TTXECO IS SET

TCI3:	CALL TCITTI		;TEST FOR TERMINAL INTERRUPT AND HANDLE IT
	 RETBAD			;IT WAS, RETURN FAILURE

;NOT AN INTERRUPT CHARACTER. RAISE AND/OR ECHO AS NEEDED AND RETURN
;IT TO THE CALLER IN 7 BITS.

	MOVE T4,T1		;T4/ CHARACTER AND ECHO BIT
	ANDI 1,177		;T1/ CHARACTER IN 7 BITS
	MOVE 3,TTFLGS(2)	;T3/ TTFLGS FOR THIS LINE
	CAIN T1,.CHCRT		;A CR?
	JRST [	CALL TCIECO	;YES, ECHO CR-LF
		MOVEI T1,.CHLFD
		CALL TCIECO
		MOVEI T1,.CHCRT	;RETURN CR THIS TIME
		JRST TCIR]
	CALL TTRAIS		;TRANSLATE, RAISE, ETC.
	CALL TCIECO		;ECHO CHARACTER IF NECESSARY
	JRST TCIR
;TCIB - ENTRY FOR BINARY INPUT

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TCIB

;RETURNS +1: NEEDED TO BLOCK
;	 +2: SUCCESS
;		T1/ CHARACTER

TCIB::
TCIB2:	TMNE TTRFG,(T2)		;REPEAT LAST CHARACTER?
	JRST [	SETZRO TTRFG,(T2) ;YES. CLEAR FLAG
		LOAD T1,TYLCH,(T2) ;GET LAST CHARACTER INPUT
		JRST TCIB1]
	MOVEI T3,.TTBIN		;USE BINARY TERINAL DATA MODE
	CALL TCI0		;GET A CHAR
	 RETBAD			;NEEDED TO BLOCK. RETURN TO CALLER.
	CALL TCITTI		;CHECK FOR TERMINAL INTERRUPT
	 RETBAD			;IT WAS, RETURN FAILURE
TCIB1:	ANDI T1,377		;RETURN CHARACTER + PARITY

;ALL ECHOING, ETC., HAS BEEN DONE. STORE IN DYNAMIC DATA AND
;RETURN THE CHARACTER TO THE CALLER

TCIR:	STOR T1,TYLCH,(T2)	;SAVE LAST CHAR
	LOAD T3,TT%DAM,TTFLGS(T2) ; GET CURRENT DATA MODE
	STOR T3,TYLMD,(T2)	; AND STORE AS DATA MODE FOR LAST CHAR INPUT
	RETSKP			;SKIP TO INDICATE BUFFER WASN'T EMPTY
;TCIECO -DO DEFERRED ECHO IF NECESSARY

;ACCEPTS:
;	T1/ CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ TTFLGS FOR THIS LINE
;	T4/ CHARACTER IN 9 BITS

TCIECO:	TXNE T3,TT%ECO		;ECHOS ON?
	TRNE T4,TTXECO		;AND CHARACTER NEEDS ECHO?
	RET			;NO, DO NOTHING
	PUSH P,T3		;SAVE 3 FOR CALLER
	PUSH P,T4		;SAVE 4 FOR CALLER
	CALL CLOFLG		;CLEAR CTRL-O FLAG IF NECESSARY
	CALL TCOE		;SEND IT
	POP P,T4
	POP P,T3
	RET

;TTCLPS - ROUTINE TO CLEAR PAGE COUNTER ON ENABLED INTERRUPT CHARACTER
;IF LINE IS IN PAGE MODE

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCLPS

;RETURNS +1: ALWAYS,
;	ALL AC'S PRESERVED

TTCLPS:	JE TTNXO,(T2),R		;IF NO PAGE STOP, DONE
	SETZRO TPGPS,(B)	;YES. CLEAR PAGE POSITION
	RET			;AND RETURN

;CLEAR CTRL-O FLAG
; T2/ DYNAMIC PTR

CLOFLG:	JNOR <TOFLG,TTFLO>,(T2),R ;RETURN IF NEITHER FLAG SET
	SAVEAC <T1>
	MOVEI T1,TTOMRK		;YES, PUT MARKER IN STREAM
	SKIPE CTRLOF		;BUT ONLY IF NEW MODE
	CALL SKCON		;AND INTERRUPT NOT ENABLED
	IFSKP. <
	  CALL TCOUM>
	SETZRO TOFLG,(T2)	;CLEAR MAIN LEVEL FLAG
	RET
;TCI..

;TEST FOR DEFERRED TERMINAL INTERRUPT CHARACTER.  INITIATE
;INTERRUPT IF NECESSARY.
; T1/ CHARACTER
; T2/ ADDRESS OF DYNAMIC DATA
;	CALL TCITTI
; RETURN +1: INTERRUPT CHAR, INTERRUPT INITIATED
; RETURN +2: NON-INTERRUPT CHAR, T1 PRESERVED

TCITTI:	SAVEAC <Q1>
	MOVEM T1,Q1		;SAVE CHAR
	ANDI T1,177		;EXTRACT ASCII
	CALL GPSICD		;GET PSI CODE IF ANY
	JUMPL T1,TCITT1		;JUMP IF NONE
	MOVE T3,BITS(T1)
	TDNN T3,TTPSI(T2)	;THIS CODE ENABLED?
	JRST TCITT1		;NO

;THIS IS A DEFERRED INTERRUPT CHARACTER.  INITIATE THE INTERRUPT
;AND WAIT UNTIL IT HAS TAKEN

	CALL TTCLPS		;YES. CLEAR OUT PAGE MODE STUFF
	MOVEM T2,Q1		;SAVE ADDRESS OF DYNAMIC DATA
	MOVE T3,T1		;PASS CODE IN T3 FOR TTPSRQ
	NOSKED
	CALL ULKTTY		;ALLOW DEALLOCATION
	DYNST			;T2/ INTERNA LINE NUMBER
	CALL TTPSRQ		;INITIATE INTERRUPT. RETURNS FORK ID IN 2
	OKSKED
	AOS TTINTS		;COUNT INTERRUPTS
	MOVEI T1,TCIPIT		;SETUP SCHED TEST FOR INTERRUPT PROCESSED
	HRL T1,T2		;GET FORK THAT GOT THE INTERRUPT
	SKIPE FKINT(T2)		;INTERRUPT STILL PENDING?
	MDISMS			;YES, WAIT A WHILE
	MOVE T2,Q1		;RESTORE ADDRESS OF DYNAMIC DATA
	RET			;RETURN NOSKIP TO RELOCK DATA

;NOT AN INTERRUPT CHARACTER.  GIVE SKIP RETURN

TCITT1:	MOVE T1,Q1		;RESTORE INPUT CHAR
	RETSKP			;RETURN TO CONTINUE PROCESSING CHAR

;TCIPIT - SCHEDULER TEST FOR MDISMS. CAUSES WAKEUP IF THE
;PROCESS POINTED TO BY AC 1 HAS NO PENDING INTERRUPTS

;ACCEPTS:
;	T1/ FORK HANDLE

TCIPIT:	SKIPE FKINT(T1)		;SCHED TEST FOR INTERRUPT STILL PENDING
	JRST 0(T4)		;STILL PENDING
	JRST 1(T4)		;COMPLETED
;TCI..

;TCI0 - GET ONE CHARACTER FROM LINE INPUT BUFFER

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ TERMINAL DATA MODE IN BITS 34-35

;RETURNS +1: LINE BUFFER WAS EMPTY, HAD TO WAIT
;	 +2: LINE BUFFER WAS NOT EMPTY,
;		T1/ CHARACTER IN 9 BITS

;CALLER MUST HAVE CALLED LCKTTY ON THE LINE. IF BLOCK ON INPUT
;WAIT OCCURS, THIS ROUTINE CALLS ULKTTY

TCI0:	NOSKED
	CALL GTTCI		;GET CHAR FROM INPUT BUFFER
	 JRST TCI01		;EMPTY
	OKSKED
	CALL SNDXON		;SEND XON IF NEEDED
	RETSKP			;SKIP TO INDICATE NO WAIT

;TAKE NEXT CHAR FROM TTY IN BFR
; T2/ TERMINAL DATA BLOCK
; RETURN +1: BUFFER EMPTY
;	+2: T1/ CHAR

GTTCI:	SKIPG 1,TTICT(2)	;ANY CHARS IN BUFFER?
	RET			;NO
	SKIPN 3,TTIOUT(2)	;GET POINTER
	BUG(TTICN0)
	HRRZ 4,3
	TDNN 3,WRPMSK		;AT END OF CURRENT BUFFER?
	HRR 3,1-TTSIZ(4)	;YES. GO TO NEXT IN CHAIN
	ILDB 1,3		;GET NEXT CHARACTER
	MOVEM 3,TTIOUT(2)	;SAVE UPDATED BYTE POINTER
	SOSG TTICT(2)		;REDUCE COUNT, NOW EMPTY?
	JRST [	SETZB 3,TTIOUT(2) ;YES, RELEASE BUFFERS
		EXCH 3,TTIIN(2)
		CALL TTRLBF
		JRST .+1]
	RETSKP
;ACTION IF BUFFER IS EMPTY. MAKE SURE NO OTHER FORK IS WAITING.
;THEN GO INTO INPUT WAIT

TCI01:	OKSKED
TCI11:	LOAD T1,TWFRK,(T2)	;GET FORK WAITING FOR THIS LINE
	CAIE T1,-1		;IS THERE ONE?
	JRST TCIF1		;YES. GO RESOLVE THE CONFLICT

;NO OTHER FORK IS WAITING. GO INTO INPUT WAIT ON THIS LINE
;NOTE: THE TEST ON TTLCK IS A BIG HACK TO KEEP FSIINI HAPPY.
;DON'T TRY TO MAKE USE OF IT FOR ANYTHING ELSE!!
;ALL CALLERS OF TCI SHOULD HAVE CALLED LCKTTY

TCIF2:	STOR T3,TYLMD,(T2)	;SAVE DATA MODE THIS INPUT
	PUSH P,3		;SAVE DATA MODE
	MOVE T3,FORKX		;GET INDEX OF THIS FORK
	STOR T3,TWFRK,(T2)	;RECORD THIS FORK WAITING FOR TTY
	SETZRO TTFWK,(T2)	;INDICATE NO FORCED WAKEUP
	TDCALL D,<<PT,TCIPTY>,<NT,NETCAP>>
	SETZRO TTWFG,(T2)	;CLEAR WAIT RESTARTED FLAG
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	HRL T1,T2		;SAVE LINE NUMBER
	POP P,T2		;RESTORE ADDRESS OF DYNAMIC DATA
;	TMNE TTLCK,(T2)		;DON'T UNLOCK IF IT'S NOT LOCKED
	CALL ULKTTY		;ALLOW DEALLOCATION
	HRRI 1,TCITST		;T1/(LINE NUMBER,,ROUTINE)
	PUSH P,T2
	MOVSI T2,FHV4		;WAIT PRIORITY - BETTER THAN AVERAGE
	HDISMS
	POP P,T2
	POP P,3			;RESTORE CURRENT MODE
	RET			;GIVE NON-SKIP RETURN TO SAY A BLOCK
				;  OCCURRED

;A FORK IS WAITING FOR INPUT ON THIS TERMINAL. IF IT IS THE CURRENT
;FORK, PROCEED AS USUAL. IF NOT, RESOLVE THE CONFLICT BY HALTING THE
;OTHER FORK IF IT IS INFERIOR TO THIS ONE OR WAITING FOR THE OTHER
;FORK IF IT IS SUPERIOR TO THIS ONE OR IN ANOTHER JOB

TCIF1:	ANDI A,7777
	CAMN A,FORKX		;IS IT THIS FORK?
	JRST TCIF2		;YES. GO TO IT THEN
	CALL ULKTTY		;RELEASE TTY LOCK AND GO OKINT
	CALLRET TTFRKT		;GO RESOLVE CONFLICT BY HALTING FORK
	SUBTTL MISCELLANEOUS ROUTINES

;FORCE WAKEUP OF FORK NOW WAITING FOR SPECIFIED TTY LINE
; 2/ ADDRESS OF DYNAMIC DATA

TTFWAK::PUSH P,FX
	LOAD FX,TWFRK,(2)	;GET INDEX OF FORK IN INPUT WAIT
	CAIN FX,-1		;IS A FORK WAITING?
	JRST TTFW1		;NO
	ANDI FX,7777		;YES, FLUSH FLAGS
	SETONE TWFRK,(T2)	;INDICATE NO FORK WAITING
	SETZRO TTFWK,(T2)	;DON'T FORCE WAKEUP ON THIS FORK
				; UNTIL INPUT BUFFER FULL AGAIN
	CALL TTUBLK		;UNBLOCK THE FORK
TTFW1:	POP P,FX
	RET

;UNBLOCK TTY INPUT FORK ONLY IF STILL WAITING FOR TTY INPUT
; FX/ FORK INDEX
;	CALL TTUBLK
; RETURN +1: ALWAYS, FORK UNBLOCKED IF IN TCITST

TTUBLK:	SAVELN
	MOVE 1,FX		;SETUP ARG
	CALLRET UNBLKF		;TELL SCHED TO UNBLOCK THE FORK

;SCHEDULER TEST ROUTINE FOR FORKS WAITING FOR TTY INPUT
;CALLED WITH JSP 4,
;AC 1 CONTAINS LINE NUMBER
;AC FX CONTAINS FORK NUMBER OF FORK BEING TESTED

TCITST::MOVE T2,T1		;GET LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST 1(4)		;LINE ISN'T ACTIVE. WAKE UP THE PROCESS
	LOAD T1,TWFRK,(T2)	;GET INDEX OF FORK IN INPUT WAIT
	CAIN T1,-1		;IF NONE, WAKEUP
	JRST 1(T4)
	JN <TTFWK,TTWFG>,(T2),1(T4)	;IF FORCED WAKEUP SET, WAKE THE PROCESS
				;WAKEUP IF WE'VE BEEN HERE BEFORE
	SKIPE TTICT(T2)		;WAKEUP IF BUFFER ISN'T EMPTY
TCITS1:	JRST 1(T4)		;WAKE THE PROCESS
	SETONE TTWFG,(T2)	;INDICATE WE'VE BEEN HERE WITHOUT WAKING
	JRST 0(T4)		;DON'T WAKE NOW

;SPECIAL CODE FOR TTY SIMULATORS. THIS ROUTINE PERFORMS THE PROPER
;TESTS FOR THE SPECIAL SIMULATOR. TO USE IT, PUT ITS ADDRESS
;IN THE LINE TYPE VECTOR AT TCIF2+7 AND PATCH IN THE PROPER LINE
;NUMBERS BELOW

TTCTRA:	MOVEI T1,"A"-100	;OUTPUT CHAR IS CONTROL-A
	DYNST (T3)		;GET STATIC DATA IS T3
	CAIL T3,.-.
	CAILE T3,.-.		;WITHIN RANGE?
	RET			;NO. DON'T SEND ^A THEN
	CALLRET TCOUT		;YES. SEND CHARACTER
;'RAISE' INPUT

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T3/ TTFLGS FOR THE LINE

TTRAIS:	TXNE T3,TT%LIC		;IF NOT RAISING INPUT
	CAIGE T1,"A"+40		; OR NOT IN RANGE
	RET			;RETURN UNCHANGED
	CAIG T1,"Z"+40		;IF LOWER CASE ALPHABETIC
	TRZ T1,40		; CONVERT TO UPPER CASE ALPHABETIC
	CAIE T1,.CHALT		;CONVERT OLD ASCII ALTMODE
	CAIN T1,.CHAL2		; AND ALTERNATE FORM
	MOVEI T1,.CHESC		; TO THE ESC CODE
	RET

;GPSICD - GET PSI CODE FOR CHARACTER
; 1/ CHARACTER
;	CALL GPSICD
; RETURN +1 ALWAYS, 1/ PSI CODE OR -1 IF NOT A POSSIBLE PSI CHAR

GPSICD::CAIG 1," "		;WITHIN NON-PSI CHAR RANGE?
	JRST GPSIC1		;NO
	CAIL 1,175
	JRST GPSIC3		;NO
GPSIC2:	SETO 1,			;YES, RETURN -1
	RET

GPSIC1:	CAIN 1," "		;SPACE?
	SKIPA T1,[^D29]		;YES, RETURN CODE
	CAIG 1,33		;CONTROL CHAR OR ESC?
	RET			;YES, CODE EQUAL CHARACTER
	JRST GPSIC2		;NOT A PSI CHAR

GPSIC3:	CAIN 1,177		;RUBOUT?
	SKIPA T1,[^D28]		;YES, RETURN CODE
	MOVEI 1,^D27		;NO, IS OLD ALT-MODE
	RET

;SKIP IF FLOCHR IS ENABLED AS A PSI
; T2/ DYN PTR

SKCOE:	MOVX CX,1B<FLOCHR>
	TDNN CX,TTPSI(T2)
	RET
	RETSKP

;SKIP IF FLOCHR NOT ENABLED AS A PSI
; T2/ DYN PTR

SKCON:	MOVX CX,1B<FLOCHR>
	TDNE CX,TTPSI(T2)
	RET
	RETSKP
	SUBTTL TTCH7 (EMPTY TTBBUF, PROCESS TTCS WORDS)

;TELETYPE INPUT CHANNEL 7 ROUTINE
;RUN EVERY SO OFTEN TO MOVE CHARACTERS FROM BIG BUFFER TO LINE BUFFERS,
;GENERATE ECHOS AND HANDLE CARRIER TRANSITIONS
;ENTERED BY  CALL  FROM SCHED
;CALLED IN SCHEDULER CONTEXT

TTCH7::	SKIPG TTBIGC		;BIG BUFFER EMPTY?
	JRST TTCH7X		;YES, RETURN
	AOS 3,TTBIGO		;NO. INCREMENT POINTER TO LOAD FROM
	CAIN 3,TTBSIZ		;AT END OF TTBBUF?
	SETZB 3,TTBIGO		;YES. POINT TO START OF TTBBUF
	MOVE 1,TTBBUF(3)	;GET NEXT ENTRY
	SOS TTBIGC		;DECREMENT COUNT OF ENTRIES
	HLRZ 2,1		;GET LINE NUMBER
	MOVEI Q2,0(1)		;SAVE ALL ORIGINAL FLAGS
	DECR TTFBB,(B)		;REDUCE LINE'S COUNT OF TTBBUF ENTRIES
	JN TTFXO,(B),[		;SEND XON IF NEEDED
		CALL SNDXNS	;SEND XON IF NEEDED
		JRST .+1]
	TRNE T1,TTPIRQ		;NON CONTROLLING TERMINAL PSI?
	JRST [	CALL STADYN	;CONVERT TO DYNAMIC DATA POINTER
		 JRST TTCH7	;NONE
		LOAD T1,TTOPSI,(B) ;GET PSI
		LOAD T2,TTPSFK,(T2) ;GET FORK
		CAIE T2,-1
		CALL PSIRQ	;IF FORK SETUP, REQUEST INTERRUPT
		JRST TTCH7]	;AND TRY NEXT
	TRNE 1,TTOIRQ		;OUTPUT INTERRUPT REQUEST?
	JRST [	MOVX 3,.TICTO	;YES. OUTPUT BUFFER WENT EMPTY AND PROCESS
		CALL TTPSRQ	; ENABLED FOR INTERRUPT. ISSUE IT
		JRST TTCH7]	;DONE WITH WORD
	TRNE 1,DLSCXF		;CARRIER TRANSITION?
	JRST TT7CX		;YES
	TRNN 1,DLSRCF		;RECEIVER?
	JRST TTCH7		;NO (SHOULD NOT HAPPEN) - RESUME  SCAN

;A CHARACTER WAS FOUND. SAVE IT IN 8 BITS AND GO STORE IN BUFFER.
;THEN GO GET NEXT WORD FROM TTBBUF

	ANDI 1,377		;GET 7 BITS OF CHARACTER + PARITY
	CALL TTCHI		;PUT CHAR IN LINE BFR
	 NOP			;IGNORE FAILURE
	JRST TTCH7		;DO NEXT
;SEND XON IF NECESSARY
; SNDXON
;	T2/ DYNAMIC
;SNDXNS
;	T2/ STATIC

SNDXON:	SAVEAC <T2>
	DYNST
	JE TTFXO,(T2),R		;DO NOTHING IF NOT XOFF'D
SNDXNS:	TDCALL S,<<FE,SNDXN2>,<MC,MCSXON>,<DZ,DZSXON>> ;SEND XON IF NEEDED
	RET
;TTCH7..

;TTBBUF IS EMPTY. DO DEVICE DEPENDENT FUNCTIONS IF NEEDED

TTCH7X:	CALL CKQLN		;CHECK QUEUED LINES
	CALL TTYQOC		;START OUTPUT ON QUEUED LINES
  IFN .MCFLG,<
	CALL MCSRV>		;PROCESS DATA FROM NET
	SKIPGE TTQCNT		;HAVE SOME SCANNING TO DO?
	RET			;NO. ALL DONE THEN

;BEFORE LEAVING, CHECK 8 LINES TO SEE IF THERE IS A SHORT BLOCK TO RELEASE

TTHNG4:	MOVE 2,TTCQLN		;GET NEXT LINE TO BE CHECKED
	MOVEI 4,10		;LIMIT OF 10 LINES FOR THIS PASS
TTCQ3:	SKIPGE TTQCNT		;ALL DONE?
	JRST TTCQ5		;YES, GO SAVE LINE NUMBER AND RETURN
	CALL CKSBK		;CHECK FOR SHORT BLOCK

;GO TO NEXT LINE. IF THE LINE TYPE CHANGES, DON'T PROCEED WITH THE NEW
;LINE. INSTEAD, GO TO THE NEXT LINE TYPE AFTER THE ONE JUST PROCESSED.
;THIS CODE ASSUMES THAT ALL LINES OF A GIVEN TYPE ARE NUMBERED CONSECUTIVELY.

TTCQ2:	LOAD C,TTSTY,(B)	;NO. GET CURRENT TYPE
	ADDI B,1		;GO TO NEXT LINE
	CAIL B,NLINES		;VALID LINE NUMBER?
	JRST TTCQ6		;NO. GO TO NEXT LINE TYPE
	LOAD A,TTSTY,(B)	;GET TYPE OF NEXT LINE
	CAMN C,A		;NEW TYPE?
	JRST TTCQ1		;NO. GO ON

;FINISHED THE CURRENT LINE TYPE OR THE CURRENT TYPE IS NOT TO BE PROCESSED
;GO TO THE NEXT TYPE AND SEE IF IT IS TO BE PROCESSED

TTCQ6:	AOS C			;GO TO NEXT LINE TYPE
	CAIL C,NLTYPS		;BEYOND END OF LEGAL TYPES?
	SETZ C,			;YES. GO BACK TO BEGINNING
	MOVE B,TT1LIN(C)	;GET FIRST LINE OF THIS TYPE
	JUMPL B,TTCQ6		;IF LINE GROUP IS NOT HERE, GO GET NEXT

;PROCESS THIS LINE UNLESS WE HAVE DONE ENOUGH FOR THIS PASS

TTCQ1:	SOJG 4,TTCQ3		;DONE ENOUGH FOR THIS TIME?
TTCQ5:	MOVEM 2,TTCQLN		;YES, START AT THIS LINE NEXT TIME
	RET
;TTCH7...
CKSBK:	SAVET
	CALL STADYN		;POINT TO DYNAMIC DATA
	 SKIPG T2		;NOT FULLY ACTIVE.  ANY DYNAMIC DATA?
	RET			;INACTIVE, BECOMING ACTIVE, OR FULL-LENGTH
	JN <TTLCK,TTSAL>,(T2),R ;DON'T RELEASE IF DOING SENDALL OR LOCKED
	JN TTSHT,(T2),DOLIN2	;IF SHORT AND SENDALL DONE, RELEASE BLOCK
	CALL TTSOBE		;IS OUTPUT COMPLETE?
	 RET			;NOT FINISHED WITH THE BLOCK YET

;HAVE A MESSAGE BLOCK.  RELEASE THE BLOCK AND RELEASE THE ASSOCIATED
;OUTPUT BUFFERS (IF ANY)

	SKIPE T3,TTOOUT(T2)	;RELEASE OUTPUT BUFFERS IF ANY
	CALL TTRLBF		; ARE ASSIGNED

;READY TO RELEASE THE BLOCK.  T2 HAS ITS ADDRESS

DOLIN2:	MOVE T1,T2		;T1/ ADDRESS OF BLOCK TO RELEASE
	DYNST			;GET LINE NUMBER
	SETZM TTACTL(T2)	;INDICATE NO DATA FOR THIS LINE
	CALL RELRES		;RELEASE THE BLOCK
	SOS TTQCNT		;ONE MORE DONE
	RET
;TTCH7..

;TTQAD - ADD ITEM TO CONTROL QUEUE

;ACCEPTS:
;	T1/ TIME UNTIL EVENT (ACTUAL MAY BE LONGER)
;	T2/ INTERNAL LINE NUMBER
;	T3/ ROUTINE TO BE CALLED AT GIVEN TIME
;	  N.B. - ROUTINE MUST BE IN TABLE HEREIN

;	CALL TTQAD (TTQAD1 FOR DEFAULT TIME LIMIT)

;RETURNS +1: ALWAYS

TTQAD1:	MOVEI T1,^D3000		;ITEM TO BE DONE IN 3 SEC.
TTQAD:	SAVEAC <T4>
	ADD T1,TODCLK		;COMPUTE ABSOLUTE TIME TO DO FUNCTION
	CAMLE T1,TTCSTM(T2)	;LATER THAN NOW SET?
	MOVEM T1,TTCSTM(T2)	;YES, SAVE TIME FOR DOING THE FUNCTION
	MOVSI T4,-NTQFN		;SCAN TABLE FOR SPECIFIED ROUTINE
TTQAD2:	CAMN T3,TQFNT(T4)	;THIS ONE?
	JRST TTQAD3		;YES
	AOBJN T4,TTQAD2		;NO
	BUG(TTQADX,<<T3,ADR>>)	;UNKNOWN FUNCTION
	RET

TTQAD3:	MOVE T1,BITS(T4)	;GET BIT TO REPRESENT FUNCTION
	IORM T1,TTCSAD(T2)	;SET IT
	MOVE T3,T2
	IDIVI T3,^D36		;GET LOCATION IN BIT MATRIX
	MOVE T4,BITS(T4)
	IORM T4,TQLNQ(T3)	;NOTE LINE NEEDS SERVICE
	RET
;SERVICE QUEUED LINES

CKQLN:	SAVEAC <P1,P2,P3>
	MOVSI P1,-NTSQWD	;SET TO SCAN BIT MATRIX
CKQL1:	SKIPE T1,TQLNQ(P1)	;ANY LINES HERE?
CKQL2:	JFFO T1,CKQL3		;YES, GET ONE
	AOBJN P1,CKQL1
	RET

CKQL3:	MOVE P2,BITS(T2)	;GET BIT FOR LINE
	HRRZ T3,P1
	IMULI T3,^D36		;COMPUTE LINE NUMBER
	ADD T2,T3
	MOVE T1,TODCLK
	CAMGE T1,TTCSTM(T2)	;TIME TO DO FUNCTION
	JRST CKQL4		;NO, MOVE ON TO NEXT LINE
	ANDCAM P2,TQLNQ(P1)	;REMOVE LINE FROM ATTENTION TABLE
	SKIPE T3,TTCSAD(T2)	;ANY FUNCTIONS REQUESTED?
CKQL5:	JFFO T3,CKQL6		;FIND A FUNCTION TO DO
CKQL4:	MOVN T1,P2		;LOOK AT REST OF WORD ONLY
	ANDCA T1,TQLNQ(P1)
	JRST CKQL2

CKQL6:	MOVE P3,BITS(T4)	;SAVE FUNCTION BIT
	ANDCAM P3,TTCSAD(T2)	;CLEAR FUNCTION REQUEST (MAY BE SET AGAIN BY ROUTINE)
	HRRZ T1,TQFNT(T4)	;GET ROUTINE ADDRESS
	CALL [	SAVEAC <T2>	;SAVE LINE NUMBER
		CALLRET 0(T1)]	;DO FUNCTION
	MOVE T1,TODCLK
	CAMGE T1,TTCSTM(T2)	;TIME BUMPED?
	JRST CKQL4		;YES, QUIT THIS LINE
	MOVN T3,P3		;LOOK AT REST OF BITS
	ANDCA T3,TTCSAD(T2)
	JRST CKQL5

;TABLE OF KNOWN TTQAD FUNCTIONS - MAXIMUM 36

TQFNT:	TTTOBL
	TTSN10
	TTCOF
	TTCON1
	DZHU2
	NTYCOF
	CKSALL
NTQFN==.-TQFNT
IFG NTQFN-^D36,<PRINTX TQFNT TOO LARGE>
;ROUTINE CALLED ONCE A SECOND TO DO CONTROLLER DEPENDENT FUNCTIONS

TTYCHK::PUSH P,Q1		;DO CHECKS FOR DEVICES
	PUSH P,Q2
	MOVSI Q1,-NLTYPS	;CALL FOR ALL DEVICES
	MOVEI T1,SCNTIM		;TIME FOR NEXT SCAN
	MOVEM T1,TTYTIM
TTLILP:	TDCALX Q1,<<DZ,DZCH7D>>,<RET>
	AOBJN Q1,TTLILP		;ALL DEVICES
	POP P,Q2		;RESTORE
	POP P,Q1
	RET			;AND DONE
;TTCH7..

;WORD IN TTBBUF INDICATED CARRIER TRANSITION (DLSCXF WAS SET).
;IF CARONB IS SET, CARRIER WENT ON. IF NOT, CARRIER WENT OFF

TT7CX:	TRNN A,CARONB		;DID CARRIER JUST COME ON?
	JRST TTCX1		;NO, OFF

;CARRIER WENT ON. IF THE LINE IS IN USE OR A JOB IS BEING
;CREATED ON IT, DON'T GO CREATE ANOTHER JOB ON IT

	SETONE TTCON,(B)	;SET CARRIER ON FOR THIS LINE
	TDCALL S,<<FE,RSKP>,<DZ,DZ7CX2>>
	 JRST TTCH7		;DO NOTHING
	CALL TTCON1		;CREATE JOB
	JRST TTCH7		;DONE

;TTCON1 - CREATE JOB AS RESULT OF CARRIER COMING ON

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTCON1

;RETURNS +1: ALWAYS

;CARRIER HAS COME ON FOR REAL. TREAT THIS LIKE A CTRL/C AND CREATE
;A JOB IF POSSIBLE

TTCON1:	MOVEM B,C		;SAVE LINE NUMBER
	CALL STADYN		;SEE IF THE LINE IS INACTIVE
	 SKIPE B		;YES. CREATE JOB ON IT IF ALLOWED
	RET			;ACTIVE OR BECOMING ACTIVE. IGNORE CARRIER-ON
	MOVE B,C		;RESTORE LINE NUMBER
	MOVE A,FACTSW		;SEE IF REMOTE LOGINS ALLOWED
	TXNN A,SF%RMT		;...
	JRST [	HRROI A,[ASCIZ /
?LOGGING IN ON DATASETS IS CURRENTLY DISALLOWED.
/]
		CALL TTEMSS	;NO. SAY SO
		RET]		;DONE
	SETONE TTFSP,(B)	;SAY LINE NEEDS SPEED SET
	CALL TTC7SK		;GO CREATE JOB
	 JFCL			;ALWAYS DOES RETSKP
	RET
;TTCH7...

;CARRIER WENT OFF

TTCX1:	JE TTCON,(B),TTCH7	;IF CARRIER WASN'T ALREADY ON, IGNORE IT
	SETZRO TTCON,(B)	;INDICATE CARRIER NO LONGER ON
	TDCALL S,<<FE,RSKP>,<DZ,DZCX2>>
	 JRST TTCH7		;NOTHING TO DO NOW
	CALL NTYCOF		;DO IT
	JRST TTCH7

;TTCOF - ROUTINE TO SEE IF CARRIER IS STILL OFF.  SCHEDULED (VIA TTQAD)
;TO BE CALLED FOR A LINE WHEN CARRIER GOES OFF ON THE LINE
;NOT USED FOR FRONT END LINES

;ACCEPTS:
;	T2/ LINE NUMBER

;RETURNS +1: ALWAYS
;		T2/ LINE NUMBER

TTCOF:	JN TTCON,(B),R		;IF CARRIER IS BACK ON NOW, DON'T HANGUP
	CALL NTYCOF
	CALLRET TTHU0		;DO HANGUP-REACTIVATE
;NTYCOF - HANDLE CARRIER OFF

;ACCEPTS:
;	2/INTERNAL LINE NUMBER

;	CALL NTYCOF

;RETURN +1: ALWAYS,
;		T2/ LINE NUMBER

;CALLED WHEN CARRIER GOES OFF FOR ANY PHYSICAL LINE. FLUSHES OUTPUT,
;ISSUES AN INTERRUPT IF A PROCESS HAS ENABLED FOR CARRIER-OFF INTERRUPT,
;ISSUES A MONITOR-INTERNAL INTERRUPT THAT CAUSES THE TOP FORK
;TO GO TO JOBCOF IN MEXEC

;ALSO CALLED FOR A LINE ASSOCIATED WITH A PTY WHEN THE PTY IS CLOSED.

NTYCOF::CALL TTCOB1		;FLUSH OUTPUT
	CALL CHKCTT		;SEE IF THIS IS A CONTROLLING TERMINAL
	 CALLRET TTJBDT		;NO. DON'T ISSUE INTERRUPT
	MOVE B,C		;YES. B/ADDRESS OF DYNAMIC DATA
	MOVEI C,.TICRF		;C/CODE FOR THIS CONDITION
	MOVE A,BITS(C)		;GET THE BIT
	PUSH P,B		;SAVE ADDRESS OF DYNAMIC DATA
	TDNE A,TTPSI(B)		;IS THE CODE ENABLED?
	CALL TTPSI2		;YES. GIVE THE INTERRUPT
	POP P,B			;RESTORE ADDRESS OF DYNAMIC DATA
	DYNST			;GET BACK THE LINE NUMBER
	CALLRET TTJBDT		;GO DETACH JOB

;TTJBDT - ROUTINE TO GENERATE AN INTERRUPT WHEN CARRIER GOES OFF

;ACCEPTS:
;	T2/ LINE NUMBER

;RETURNS +1: ALWAYS
;		T2/ LINE NUMBER

;ISSUES AN INTERRUPT TO THE TOP FORK IN THE JOB. CAUSES THE JOB TO
;BE DETACHED

TTJBDT:	CALL TTCOB1		;CLEAR OUTPUT BUFFERS
	CALL CHKCTT		;SEE IF THIS IS A CONTROLLING TERMINAL
	 RET			;NO
	SETONE TOFLG,(T3)	;FLUSH SUBSEQUENT OUTPUT
   REPEAT 0,<			;FOLLOWING CODE DOES NOT
				;WORK BECAUSE IT CAUSES PAGE
				;FAULTS IN SCHEDULER. NEED TO
				;MOVE THIS ELSEWHERE SOME DAY
	TMNE TTAUT,(B)			;IS THIS AN AUTO SPEED LINE?
	SETOM TTSPWD(B)		;YES. INIT SPEED
   >				;END OF REPEAT 0
	PUSH P,B		;SAVE LINE NUMBER
	HRRZ B,JOBPT(A)		;GET TOP FORK INDEX
	MOVX T1,FKPSI0+PSICO%
	IORM 1,FKINT(B)		;REQUEST CARRIER OFF ACTION
	CALL PSIR4
	POP P,B			;RESTORE LINE NUMBER
	RET
;TTCH7..

;CHKCTT - CHECK TO SEE TERMINAL IS A CONTROLLING TERMINAL FOR A JOB

;ACCEPTS:
;	T2/ LINE NUMBER

;	CALL CHKCTT

;RETURNS +1: NOT A CONTROLLING TERMINAL
;		T2/ LINE NUMBER
;	 +2: CONTROLLING TERMINAL,
;		T1/ JOB NUMBER
;		T2/ LINE NUMBER
;		T3/ ADDRESS OF DYNAMIC DATA

CHKCTT:	SASUBR <CHKCJN,CHKCSV,CHKCSD>
	SETOM CHKCJN		;SAY NO CONTROLLING JOB
	CALL STADYN		;POINT TO DYNAMIC DATA
	 RET			;NOT ACTIVE
	LOAD C,TCJOB,(B)	;GET OWNING JOB
	CAIN C,-1		;IS THERE ONE?
	RET			;NONE.
	MOVEM C,CHKCJN		;SAVE JOB NUMBER
	MOVEM B,CHKCSD		;RETURN DYNAMIC PTR
	HLRZ A,JOBPT(C)		;GET CONTROLLING TERMINAL FOR JOB
	CAMN A,CHKCSV		;IS THIS THE CONTROLLING TERMINAL?
	RETSKP			;YES, SUCCESS
CHKCT1:	RET			;FAILURE RETURN

	ENDSA.			;END SASUBR

;TTHU0 - HANGUP-REACTIVATE SEQUENCE

;ACCEPTS:
;	T2/ LINE NUMBER

;	CALL TTHU0

;RETURNS +1: ALWAYS

;SCHEDULED BY TTCOF WHEN A LINE HAS LOST CARRIER. CAUSES HANGUP OF THE
;LINE FOLLOWED BY ACTIVATE

TTHU0:	TDCALL S,<<FE,TTHU2>,<NT,NVTDTS>,<DZ,DZHU0>>
	RET
	SUBTTL TTCHI (MOVE CHAR FROM TTBBUF TO INPUT BUFFER)

;TTCHI - PROCESS CHARACTER AS INPUT

;ACCEPTS:
;	T1/ CHARACTER IN 8 BITS
;	T2/ INTERNAL LINE NUMBER

;	CALL TTCHI

;RETURNS +1: ALWAYS
;		T2/ LINE NUMBER

;CALLED BY TTCH7 WHEN A CHARACTER HAS BEEN FOUND IN TTBBUF
;INITIATES AN INTERRUPT IF NEEDED; ECHOES IF APPROPRIATE;
;WAKES UP WAITING PROCESS IF NEEDED; STORES CHARACTER IN LINE BUFFER

;CALLED FROM SCHEDULER CONTEXT AND PROCESS CONTEXT
;IF IN PROCESS CONTEXT, MUST BE NOSKED, SO THAT THE SETTING AND
;TESTING OF TCOERR IN TCOUT WILL BE CONSISTENT

;TTCHID - ALTERNATE ENTRY POINT, T2/ DYNAMIC PTR

TTCHID:	SAVEAC <T2,Q1,FX>
	DYNST			;GET LINE NUMBER
	JRST TTCHD1

TTCHI:	CAIL 2,NLINES		;REASONABLE LINE?
	RET			;NO
	SAVEAC <T2,Q1,FX>
TTCHD1:	STKVAR <TTCHSV,TTCHFL>	;MUST COME AFTER SAVELN
	MOVEM T2,TTCHSV		;SAVE LINE NUMBER
	MOVEM T1,TTCHIC		;SAVE ORIGINAL CHARACTER
	ANDI T1,377		;USE 8 BITS FOR LOCAL COMPARES
	CALL STADYN		;IS THIS A FULLY ACTIVE LINE?
	 JRST TTC7N		;NO. GO HANDLE THIS CASE SEPARATELY
	JN TTNUS,(T2),TTNU1	;JUMP IF NETWORK USER STATE
	CALL TTCHXX		;CHECK FOR XON, XOFF
	 RETSKP			;IT WAS, RETURN NOW
	JRST TTCHIF		;CONTINUE
;SEE IF CHARACTER IS XON OR XOFF AND HANDLE AS NECESSARY
; RETURN +1: WAS XOFF OR XON
; 	+2: WAS NOT XOFF OR XON

TTCHXX:	JE TT%PGM,TTFLGS(T2),RSKP ;IF IGNORING XOFF/XON, CONTINUE
	CAIE 1,PGMONC+1B28
	CAIN 1,PGMONC		;XON?
	IFNSK.
	  LOAD T3,TTUPC,(T2)	;YES, SEE IF PAGE UNPAUSE CHARACTER TOO
	  CAIE T3,PGMONC
	  CALLRET TTXONC	;NO, XON COMMAND ONLY
	  CALLRET TTXONA	;YES, BOTH
	ENDIF.
	CAIE 1,PGMOFC		;XOF?
	CAIN 1,PGMOFC+1B28
	SKIPA			;YES
	RETSKP			;NO
	JN TTRXF,(T2),R		;SEE IF ALREADY STOPPED
TTXOFC:	SETONE TTRXF,(T2)	;YES. INDICATE CTRL/S TYPED
	TMNN <TTSAL,TTHPO>,(T2)	;SPECIAL OUTPUT GOING?
	IFNSK. <
	  TDCALL D,<<FE,TTCHI3>> ;NO, STOP THE LINE
	 >,<
	  TDCALL D,<<FE,TTXON1>>> ;YES, RESTART THE LINE
	RET
;TTXON - DO 'XON' - CLEAR STOP FLAG AND RESTART OUTPUT TO TERMINAL IF NECESSARY
; TTXONA - RESTART ALL CASES
; TTXONC - RESTART FROM COMMAND STOP ONLY
; TTXONP - RESTART FROM PAGE STOP ONLY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTXONx

;RETURNS +1: ALWAYS

;CALLED IN ANY OF THE FOLLOWING CASES:
;	CLEAR OUTPUT BUFFER
;	STPAR
;	USER TYPES XON

TTXONA:	SETZRO TTSFG,(T2)	;CLEAR CTRL/S
TTXONC:	JE TTRXF,(T2),TTXON2	;JUMP IF HOST SIMULATED XOF ONLY
	TDCALL D,<<FE,TTXON1>,<MC,MCLNON>>
	SETZRO TTRXF,(T2)
TTXON2:	MOVE 3,TTOCT(2)		;GET COUNT OF CHARACTERS IN OUTPUT BUFFER
	NOSKD1			;NOSKED FOR STRTOU CALL
	CALLRET STRTOU		;RESTART OUTPUT

TTXONP:	SETZRO TTSFG,(T2)
	JRST TTXON2		;RESTART OUTPUT
;HANDLE LINE IN NET USER STATE

TTNU1:
  IFN .MCFLG,<
	CALL TTCHXX		;CHECK FOR XON, XOFF
	 JRST [	JN TTNPM,(T2),RSKP ;IT WAS, FLUSH THE CHAR IF OLD MODE
		JRST .+1]	;OTHERWISE KEEP IT
	LOAD T4,TTUEC,(T2)	;CHECK FOR ESCAPE CHAR
	XOR T4,T1
	JXN T4,177,TTMCI1	;JUMP IF NOT
	SETZRO TTNUS,(T2)	;GET OUT OF NET USER STATE
	LOAD T3,TCJOB,(T2)	;SEE IF HAVE JOB ON THIS LINE
	CAIN T3,-1
	IFSKP.
	  SETZRO TTPRM,(T2)	;YES, CLEAR PERMANENT
	  JRST TTCHIF		;KEEP CHAR IN INPUT STREAM
	ENDIF.
	CALL TNUCLS		;NO, CLOSE CONNECTION
  >				;END IFN .MCFLG
	RETSKP

;DO PAGE PAUSE ON COMMAND FROM USER
;THE HEURISTICS AREN'T NEEDED UNLESS WE ARE USING A CHARACTER THAT
;ALSO HAS SOME OTHER FUNCTION (E.G. ^U).  IN THAT CASE, WE ONLY
;WANT TO DO THE PAUSE IF THE CHARACTER IS NOT PART OF REGULAR TYPEIN

TTXOFP:	LOAD T3,TTPPC,(T2)	;GET PAUSE CHARACTER
	CAIL T3,40		;A CONTROL CHAR?
	IFSKP.
	  MOVE T3,BITS(T3)	;YES, SEE WHAT KIND
	  TDNN T3,TTXOBM	;HAS SYSTEM USE IN INPUT STREAM?
	  JRST TTXFP1		;NO, EXECUTE IT
	ENDIF.
	SKIPE TTICT(T2)		;ANY TYPEAHEAD?
	RET			;YES, DO NOTHING
	LOAD T3,TWFRK,(T2)
	CAIN T3,-1		;OR FORK WAITING?
	IFSKP.
	  MOVE T3,TTOCT(T2)	;YES, SEE HOW MUCH OUTPUT QUEUED
	  CAIG T3,^D40		;LOTS?
	  RET			;NO, DON'T PAUSE
	ENDIF.
TTXFP1:	SETONE TTSFG,(T2)	;PAUSE
	RETSKP

;MASK OF CONTROL CHARACTERS WHICH HAVE DEFINED SYSTEM USE IN
;INPUT STREAM

TTXOBM:	BYTE (1)0,0,0,0,0,0,1,0,1,1,1,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,1,0,0,0,0,0
TTCHIF:	ANDI T1,177		;USE 7 BITS FOR LOCAL COMPARES
	JE TTPRM,(T2),TTCHI2	;YES. PERMANENT BLOCK?
	LOAD T3,TCJOB,(T2)	;YES. GET CONTROLLING JOB
	CAIN T3,-1		;IS THERE ONE?
	JRST TTC7N		;NO

;SEE IF ANY PAGE PAUSE OR UNPAUSE FUNCTIONS REQUESTED

TTCHI2:	JE TT%PGM,TTFLGS(T2),TTCHI1 ;BYPASS ALL THIS IF NO PAGE MODE
	JE TTNXO,(T2),TTCHI1
	LOAD T3,TTUPC,(T2)	;GET PAGE UNPAUSE CHARACTER
	CAME T1,T3		;AND UNPAUSE ON PAGE CHARACTER?
	IFSKP.
	  TMNN TTSFG,(T2)	;ALREADY PAUSING?
	  IFSKP.
	    CALL TTXONP		;YES, RESTART OUTPUT
	    RETSKP		;RETURN NOW, LOSE CHARACTER
	  ENDIF.
	  LOAD T3,TTPPC,(T2)	;NOT PAUSING NOW,
	  CAMN T1,T3		;THIS THE PAUSE CHARACTER TOO?
	  IFSKP.
	    CAIL T1,40		;NO, SEE IF KEEP IT OR FLUSH IT
	    IFSKP.
	      MOVE T3,BITS(T3)	;A CONTROL CHAR, SEE WHAT KIND
	      TDNN T3,TTXOBM	;HAS SYSTEM USE IN INPUT STREAM?
	      RETSKP		;NO, FLUSH IT
	    ENDIF.
	   ELSE.
	    CALL TTXOFP		;YES, MAYBE PAUSE NOW
	    IFSKP. <RETSKP>	;RETURN NOW IF PAUSED
	  ENDIF.
	ENDIF.
	LOAD T3,TTPPC,(T2)	;GET PAGE PAUSE CHARACTER
	CAME T1,T3		;AND PAUSE CHARACTER?
	IFSKP.
	  CALL TTXOFP		;YES, MAYBE PAUSE NOW
	  IFSKP. <RETSKP>	;DID PAUSE, LOSE CHARACTER
	ENDIF.

;LINE IS ACTIVE. IT MAY OR MAY NOT BE A CONTROLLING TERMINAL FOR
;A JOB. HOWEVER, THE JOB CANNOT DO AN ATI EXCEPT ON ITS CONTROLLING
;TERMINAL. THEREFORE, SEE IF THE JOB HAS DONE AN ATI FOR THE CHARACTER

TTCHI1:	MOVE T3,T1		;COPY CHAR
	CALL GPSICD		;GET PSI CODE FOR CHAR
	EXCH 1,3		;1/CHARACTER; 3/CODE OR -1
	JUMPL 3,TTCHI6		;-1 MEANS NO CODE
	MOVE Q1,BITS(3)		;BIT FOR THIS CODE
	TDNE Q1,TTPSI(2)	;CODE ENABLED?
	JRST TTCH11		;YES
	SKIPE CTRLOF		;NEW CTRL-O HANDLING?
	CAIE T1,FLOCHR		;AND A CTRL-O?
	JRST TTCHI6		;NO
	; ..
;WE HAVE A ^O AND WE WANT MONITOR HANDLING OF IT.  ^O IS A TOGGLE, SO
;WE DO SOMETHING DIFFERENT DEPENDING ON ITS CURRENT STATE.

	; ..
	CALL CKPHYD		;PTY?
	 JRST TTCHI6		;YES, DO NOTHING
	CALL [	SAVEAC <T1>	;YES
		CALLRET TTXONA]	;CLEAR POSSIBLE XOFF
	TMNN TTFLO,(T2)		;ALREADY ON?
	IFSKP. <
	  CALL CLOFLG		;YES, DO MARKER
	  RETSKP>
	MOVE T1,[POINT 7,[BYTE (7)"[","^","O",".",".",".",.CHDEL]]
	MOVEM T1,TTSAL2(T2)	;SEND INDICATION (WITH FILLS ON CR AND LF)
	SETONE TTHPO,(T2)	;NOTE HP OUTPUT QUEUED
	SETONE TTFLO,(T2)	;FLUSH OUTPUT
	LOAD T3,TWFRK,(T2)	;SEE IF A FORK WAITING
	CAIE T3,-1
	CALL CLOFLG		;YES, PUT MARKER THROUGH
	RETSKP
;TERMINAL NOT IN PAGE MODE OR THIS WAS NOT XON OR XOFF
;IF TERMINAL DATA MODE IS BINARY, GO STORE CHARACTER IN LINE BUFFER
;WITHOUT TRANSLATION OR ECHOING

TTCHI6:	AOS NTTYIN		;COUNT INPUT
	LOAD 3,TYLMD,(2)	;CHECK MODE NOW IN FORCE
	CAIE 3,.TTBIN		;BINARY?
	JRST TTCHI4		;NO.
TTMCI1:	LOAD 3,TIMAX,(2)	;YES. GET CAPACITY OF INPUT BUFFER
	CAMLE 3,TTICT(2)	;ROOM FOR CHAR IN INPUT BUFFER?
	JRST TTCHI9		;YES. GO PUT IT IN
	RET			;NO. LOSE CHARACTER

;SOME TRANSLATION (OUTPUT OR ECHOING OR BOTH) IS REQUIRED BY TERMINAL
;DATA MODE. SEE IF ECHOING IS REQUIRED

TTCHI4:	JUMPE 1,RSKP		;FLUSH NULLS ASAP
	LOAD 3,TIMAX,(2)	;CAPACITY OF INPUT BUFFERS
	CAMG 3,TTICT(2)		;FULL?
	JRST TTCH12		;YES, ECHO BELL
	MOVE 3,TTFLGS(2)
	TRNE 3,TT%DUM		;REGULAR FDX LINE?
	JRST TTCHI7		;HDX - 'ECHO' IMMED
	TRNN 3,TT%ECO		;ECHOS ON?
	JRST TTCHI9		;NO
	TRNE 3,TT%ECM		;STANDARD ECHO MODE?
	JRST TTCHI7		;NO, IMMEDIATE ALWAYS
	LOAD 4,TWFRK,(2)	;GET WAITING FORK IF ANY
	CAIN 4,-1		;IS THERE A WAITING FORK?
	JRST TTCHI9		;NO. DON'T ECHO NOW
	; ..
;EITHER IMMEDIATE ECHOING IS REQUIRED OR DEFERRED IS REQUIRED AND
;A FORK IS IN INPUT WAIT ON THIS TERMINAL. ECHO THE CHARACTER NOW
;AND SET TTXECO WITH THE CHARACTER IN TTCHIC. THIS WILL BE STORED
;IN THE LINE BUFFER SO THAT TCI WILL NOT ECHO IT AGAIN

	; ..
TTCHI7:	CALL CLOFLG		;CLEAR CTRL-O FLAG IF NECESSARY
	MOVE T3,TTFLGS(T2)	;GET FLAGS FOR TTRAIS
	SETOM IMECHF		;FLAG ECHO CHARACTER FOR TCOUT
	CAIN T1,.CHCRT		;CR?
	 JRST [	SETZM TCOERR	;INIT ERROR INDICATOR
		CALL TCOE	;YES, ECHO CR-LF
		MOVEI T1,.CHLFD	;ECHO THE LINE FEED
		JRST TTCHI8]
	CALL TTRAIS		;RAISE FOR ECHO IF NECESSARY
TTCHI8:	SETZM TCOERR		;INIT ERROR INDICATOR
	SETZM TTCHFL		;INITIALIZE ECHO INDICATOR
	CALL TCOE		;ECHO VIA NORMAL OUTPUT STREAM
	SKIPE TCOERR		;DID TCOUT FAIL?
	 JRST [	SETZM IMECHF	;FAILED TO ECHO. RESET IMMEDIATE ECHO FLAG
		SETOM TTCHFL	;INDICATE CHARACTER NOT ECHOED
		JRST TTCHI9]	;GO STORE CHARACTER WITHOUT MARKING IT ECHOED
	MOVEI T4,TTXECO		;CHARACTER WAS ECHOED. INDICATE IT
	IORM T4,TTCHIC		; SO THAT TCI WON'T ECHO IT LATER
	SETZM IMECHF		;RESET IMMEDIATE ECHO INDICATOR
	; ..
;TTCHI..

;HERE IF THE CHARACTER IS NOT AN INTERRUPT CHARACTER, OR THE
;JOB HAS ENABLED ONLY FOR DEFERRED INTERRUPT ON THE CHARACTER
;IF ECHOING WAS REQUIRED, IT HAS BEEN DONE
;GET INPUT BUFFER IF NEEDED; PUT CHAR IN BUFFER

;	2/ ADDRESS OF DYNAMIC DATA

	;..
TTCHI9:	SKIPN 3,TTIIN(2)	;INPUT BUFFERS EXIST?
	JRST [	LOAD 3,TTNIN,(2);NO, GET NUMBER TO ASSIGN
		CALL TTGTBF	;ASSIGN THEM
		 JRST TTCH12	;NO BUFFERS, DING
		MOVEM 3,TTIOUT(2) ;SAVE BYTE POINTER FOR REMOVING CHARACTERS
		JRST .+1]
	HRRZ 4,3		;AT END OF BUFFER?
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(4)	;YES. POINT TO NEXT BUFFER IN CHAIN
	MOVE T4,TTCHIC		;GET INPUT CHARACTER
	IDPB T4,3		;STORE IN INPUT LINE BUFFER
	MOVEM 3,TTIIN(2)	;SAVE UPDATED POINTER FOR ADDING TO BUFFER
	AOS 3,TTICT(2)		;INCREMENT COUNT OF CHARACTERS

;IF INPUT BUFFER IS FULL, SEND XOFF TO TERMINAL

	LOAD D,TIMAX,(B)	;GET CAPACITY OF BUFFERS
	CAIL C,-MINICT(D)
	JRST [	PUSH P,B	;SAVE TTY
		DYNST
		TDCALL S,<<FE,SNDXO2>,<DZ,DZSXOF>> ;SEND XOFF
		POP P,B		;RESTORE LINE
		JRST .+1]
	TMNE TTNUS,(T2)		;NET USER?
	JRST [	CALL REQNS	;YES, QUEUE A SEND
		RETSKP]		;AND DONE

;IF THIS STORE MADE THE BUFFER GO NON-EMPTY, AND JOB HAS ENABLED FOR
;INTERRUPTS ON THAT CONDITION, ISSUE THE INTERRUPT

	CAIN 3,1		;JUST BECAME NON-0?
	CALL TTCH22
	;..
;TTCHI..

;IF A FORK IS IN INPUT WAIT ON THIS TERMINAL, WAKE IT UP IF EITHER
;	1. THE TERMINAL DATA MODE IS BINARY
;	2. THE INPUT BUFFER IS FULL
;	3. THE CHARACTER IS IN A WAKEUP CLASS SPECIFIED BY THE JOB

	;..
	LOAD 3,TWFRK,(2)	;IF NO FORK WAITING FOR THIS LINE,
	CAIN 3,-1
	JRST TTCH10		; THEN SKIP WAKEUP CHECKS
	LOAD 3,TYLMD,(2)	;GET TERMINAL DATA MODE FOR LAST CHARACTER
	CAIN 3,.TTBIN		;WAKE ALWAYS IF BINARY
	JRST [	CALL TTFWAK	;WAKE LISTENING PROCESS
		RETSKP]		;RETURN SUCCESS
	LOAD 3,TIMAX,(2)	;CAPACITY OF INPUT BUFFERING
	SUBI 3,MINCT1		;LESS AN ARBITRARY AMOUNT
	CAMG 3,TTICT(2)		;BUFFER NOW THAT FULL?
	JRST [	SETONE TTFWK,(2) ;YES. FORCE WAKEUP OF WAITING FORK
		JRST .+1]
	CAIN T1,.CHCRT		;IS THIS A CARRIAGE RETURN
	MOVEI T1,.CHLFD		;YES-FORCE IT TO BE ALINE FEED
	SKIPL TTCHFL		;DID WE FAIL TO ECHO CHARACTER?
	CALL TTWAKE		;DETERMINE IF CHARACTER IS IN WAKE-UP CLASS
	 JRST [	CALL TTFWAK	;YES, FORCE WAKEUP
		JRST TTCH1X]
TTCH10:	LOAD FX,TWFRK,(2)	;GET WAITING FORK IF ANY
	CAIN FX,-1		;IS THERE ONE?
	JRST TTCH1X		;NO, DON'T WAKE
	JE TTFWK,(2),TTCH1X	;YES. IS THE WAKEUP BIT SET?
	ANDI FX,7777		;YES, FLUSH FLAGS
	CALL TTUBLK		;MAKE THE FORK RUN TO EMPTY BUFFER
TTCH1X:	RETSKP
;TTCHI..

;HERE WHEN RECEIVED TERMINAL INTERRUPT CHARACTER.
;CHECK WHETHER DEFERRED OR IMMEDIATE, INITIATE INTERRUPT IF NECESSARY.

;	T1/ ORIGINAL CHARACTER, 7 BITS
;	T2/ADDRESS OF DYNAMIC DATA
;	T3/THE CODE
;	Q1/ BIT FOR CONTROL CODE FOR THIS CHARACTER

TTCH11:	TDNN Q1,TTDPSI(2)	;DEFERRED CHARACTER?
	JRST TCHI1		;NO
	LDB 4,TTIIN(2)		;GET LAST INPUT CHAR
	CAMN T4,TTCHIC		;LAST CHAR SAME AS THIS ONE?
	JRST TTCHI5		;YES, MAKE IMMEDIATE

;HANDLE DEFERRED INTERRUPT

	PUSH P,1
	CALL TTFWAK		;FORCE WAKEUP SO PGM CAN SEE INT
	POP P,1
	LOAD 3,TIMAX,(2)	;MUST PUT DEFERRED CHAR IN BUFFER
	ADDI 3,1		;1 RESERVED FOR INT CHAR
	CAMG 3,TTICT(2)		;IS ROOM?
	JRST [	DPB 1,TTIIN(2)	;NO, SMASH CHAR ON TOP OF LAST ONE
		JRST TCHIX]	;RETURN
	JRST TTCHI9		;YES. PUT IN BUFFER W NO ECHOS

;DEFERRED CHARACTER TWICE IN A ROW

TTCHI5:	PUSH P,3		;SAVE CODE
	CALL TTCIBF		;CLEAR INPUT BUFFER ON DOUBLE INT
	POP P,3			;RESTORE CODE
TCHI1:	CALL TTPSI2		;GO ISSUE THE INTERRUPT
TCHIX:	RETSKP

;TTPSI2 - ISSUE INTERRUPT TO PROCESS THAT HAS ENABLED FOR IT
;VIA ATI

;ACCEPTS:
;	T2/ADDRESS OF DYNAMIC DATA
;	T3/CODE

;	CALL TTPSI2

;RETURNS +1: ALWAYS

;NOTE: TTPSRQ CLOBBERS T2

TTPSI2:	CALL TTCLPS		;CLEAR PAGE COUNTER
	DYNST			;T2/ INTERNAL LINE NUMBER
	CALL TTPSRQ		;REQUEST INTERRUPT FROM PSI SYSTEM
	AOS TTINTS		;COUNT INTERRUPTS
	RET			;AND DONE
;INPUT BUFFER GETTING FULL. SEND BELL AND LOSE CHARACTER

TTCH12:	LOAD T3,TLTYP,(T2)	;CHECK LINE TYPE
	CAIN T3,TT.PTY		;PTY?
	RET			;YES
	MOVEI T1,"G"-100	;NO, ECHO BELL
	CALLRET SCDTCO

;DO INPUT INTERRUPT IF ENABLED

TTCH22:	LOAD T4,TTPSFK,(T2)	;CHECK FOR FORK
	CAIN T4,-1
	JRST TTCH23		;IGNORE IF NOT SET
	LOAD T4,TTIPSI,(T2)	;CHECK FOR NON CONTRL TERM PSI
	CAIL T4,^D36		;CHECKLEGAL
	JRST TTCH23		;NO TRY FOR CONTROL TERMINAL
	SAVET			;SAVE TEMPS
	MOVE T1,T4		;GET PSI
	LOAD T2,TTPSFK,(T2)	;GET FORK
	CALLRET PSIRQ		;DO REQUEST

TTCH23:	MOVX 4,1B<.TICTI>
	TDNN 4,TTPSI(2)		;YES, SEE IF INPUT INTERRUPT WANTED
	RET			;NO
	MOVX 3,.TICTI		;YES, REQUEST IT
	SAVET			;SAVE ACS
	DYNST			;T2/ INTERNAL LINE NUMBER
	CALLRET TTPSRQ		;REQUEST INTERRUPT

;NOTE: DOESN'T SET OR TEST TCOERR. IGNORES FAILURE TO SEND BELL
;TTCHI..

;RECEIVED CHARACTER ON LINE THAT IS NOT ASSIGNED A FULL-LENGTH
;DYNAMIC BLOCK.

;	T1/ CHARACTER
;	T2/-1 IF LINE IS BECOMING ASSIGNED
;		OR
;	0 IF NOT AT ALL ASSIGNED
;		OR
;	POSITIVE ADDRESS OF SHORT OR TTEMES BLOCK

TTC7N:	ANDI T1,177
	CAIN T1,.CHNUL		;FLUSH NULLS
	RET
	MOVE T4,TTCHSV		;GET LINE NUMBER
	JN TTIGI,(T4),R		;RETURN IF IGNORING CHARACTERS ON THIS LINE
	CAIE T1,.CHCRT		;CR OR LF?
	CAIN T1,.CHLFD
	JRST TTCH71		;YES, TRY TO CREATE JOB
	CAIN T1,.CHCNC		;CONTROL-C?
	JRST TTCH71		;YES.
	JUMPL T2,R		;IF BECOMING ACTIVE, IGNORE
	JUMPE T2,TTCH73		;IF INACTIVE, SEND BELL
	JE TTPRM,(T2),TTCH73	;IF TEMPORARILY ACTIVE AND NOT PERMANENT, SEND BELL
	JN TTBAC,(T2),R		;IF PERMANENT AND BECOMING ACTIVE, IGNORE
TTCH73:	HRROI T1,[BYTE(7) .CHBEL]  ;SEND A BELL
	MOVE T2,TTCHSV		;T2/ INTERNAL LINE NUMBER
	CALLRET TTEMES		;GO SEND A BELL AND LOSE CHARACTER

;A CONTROL/C WAS RECEIVED OR CARRIER CAME ON FOR A REMOTE LINE
;IF LINE IS TOTALLY INACTIVE, GO CREATE A JOB ON IT
;IF LINE IS BECOMING ACTIVE, IGNORE THE CHARACTER
;IF LINE HAS SHORT OR MESSAGE BLOCK, IGNORE THE CHARACTER

TTCH71:	JUMPE T2,TTCH75		;ACCEPT IF NOT AT ALL ACTIVE
	JUMPL T2,R		;IGNORE IF BECOMING ACTIVE
	JE TTPRM,(T2),R		;IF NOT PERMANENT, ASSUME BLOCK WILL GO AWAY
	JN TTBAC,(T2),R		;PERMANENT. IGNORE IF BECOMING ACTIVE

;LINE  HAS NO DYMAMIC DATA OR IT HAS A PERMANENT BLOCK AND 1) HAS NO
;CONTROLLING JOB AND 2) IS NOT BECOMING ACTIVE. CREATE A JOB ON IT IF
;LOGINS ARE ALLOWED

TTCH75:	MOVE T1,FACTSW		;SEE WHAT LOGINS ARE ALLOWED
	MOVE T2,TTCHSV		;RESTORE LINE NUMBER
TTC7SJ:	CAMN 2,CTYLNO		;CTY?
	JRST [	TXNE T1,SF%CTY	;YES, CTY LOGIN ALLOWED?
		JRST TTC7SK	;YES, GO LOGIN
		HRROI 1,[ASCIZ/
?LOGGING IN ON THE CTY IS CURRENTLY DISALLOWED.
/]
		CALLRET TTEMSS] ;NO LOGIN ALLOWED ON CTY
	TDCALL S,<<FE,RSKP>,<PT,TTC7S2>,<NT,TTC7SN>,<DZ,RSKP>>
	 JRST [	JUMPL T1,TTC7SK	;IF NEG, GO START A JOB
		RET]		;ELSE FAIL

;LINE IS ON THE FRONT END OR THE DC10. SEE IF LINE IS LOCAL OR REMOTE

TTC7S1:	JN TTFEM,(T2),TTCHS3	;IF REMOTE, GO CHECK REMOTE LOGINS
	TXNE T1,SF%LCL		;LOCAL LOGINS ALLOWED?
	JRST TTC7SK		;YES. GO CREATE JOB
	HRROI 1,[ASCIZ/
?LOGGING IN ON LOCAL TERMINALS IS CURRENTLY DISALLOWED.
/]
	CALLRET TTEMSS		;LOCAL LOGINS NOT ALLOWED. SEND MESSAGE

;LINE IS REMOTE

TTCHS3:	TXNE 1,SF%RMT		;...
	JRST TTC7SK		;YES. GO CREATE JOB
	SETONE TTFSP,(T2)
	HRROI 1,[ASCIZ/
?LOGGING IN ON DATASETS IS CURRENTLY DISALLOWED.
/]
	CALLRET TTEMSS		;REMOTE LOGINS NOT ALLOWED, SEND MESSAGE


;LOGINS ARE ALLOWED.

TTC7SK:	MOVEI 1,JOBSRT		;REQUEST SCHEDULER- START JOB
	HRLI 1,0(2)		;ON SPECIFIED TTY LINE
	SKIPLE T3,TTACTL(T2)
	JRST [	JE TTPRM,(T3),.+1
		SETONE TTBAC,(T3)
		JRST TTC7S3]
	SETOM TTACTL(T2)	;INDICATE LINE BECOMING ACTIVE
TTC7S3:	CALL SCDRQ7
	RETSKP

	ENDSV.			;END STKVAR
; TTWAKE - DETERMINE IF CHARACTER IS IN WAKE-UP CLASS

;ACCEPTS:
;	T1/ 7-BIT ASCII CHARATER
;	T2/ ADDRESS OF DYNAMIC DATA

;RETUNS:	+1, CHARACTER BELONGS TO A WAKE-UP CLASS
;		+2, CHARACTER NOT IN ANY WAKE-UP CLASS

TTWAKE:	LOAD T3,TTFCNT,(T2)	;DECREMENT FIELD WIDTH COUNT
	JUMPLE T3,TTMASK	;JUMP IF FIELD WIDTH DISABLED (=0)
	SOS T3			;ENABLED - DECREMENT THE COUNT
	STOR T3,TTFCNT,(T2)	;SAVE NEW VALUE
	SKIPN T3		;SKIP IF COUNT NOT EXHAUSTED
	RET			;COUNT EXHAUSTED - WAKE PROCESS

;HERE TO CHECK WAKE-UP MASK (FIELD WIDTH DISABLED OR NOT EXHAUSTED)

TTMASK:	MOVE T3,T1		;MOVE THE ASCII CHARACTER
	IDIVI T3,^D32		;COMPUTES WHICH WORD MASK BIT IS IN
	MOVE T4,BITS(T4)	;GET THE BIT MASK FOR TESTING
	ADD T3,T2		;BUMP INTO PROPER WORD OF MASK
	TDNE T4,TTCHR1(T3)	;SKIP IF NO WAKE-UP ON THIS CHARACTER
	RET			;PROCESS SHOULD BE AWAKENED
	CAIE T1,.CHLFD		;IS THIS A LF ON A PTY?
	RETSKP			;NO, NO WAKEUP
	LOAD T3,TLTYP,(T2)
	CAIN T3,TT.PTY		;PTY?
	RET			;YES, WAKEUP
	RETSKP			;PROCESS SHOULD NOT BE AWAKENED
	SUBTTL TTEMES

;TTEMES - SEND SHORT MESSAGE FROM SCHEDULER

;ACCEPTS:
;	T1/ BYTE POINTER TO STRING TO BE OUTPUT
;	T2/ LINE NUMBER

;	CALL TTEMES

;RETURNS +1: ALWAYS

;CALLED AT SCHEDULER LEVEL TO SEND A SHORT MESSAGE TO A LINE
;IF LINE IS ACTIVE, APPENDS CHARACTERS TO OUTPUT BUFFER. IF NOT
;ACTIVE, CREATES A MESSAGE-LENGTH DYNAMIC BLOCK FOR THE LINE

;TTEMSS - ENTRY POINT TO CLEAR OUTPUT BUFFER BEFORE OUTPUTTING

TTEMSS:	PUSH P,A		;SAVE STRING POINTER
	CALL TTCOB1		;CLEAR CURRENT GARABGE OUT
	POP P,A			;AND GO SEND THE MESSAGE

;TTEMES - NORMAL ENTRY POINT

TTEMES::SAVELN			;PRESERVE LINE NUMBER
	STKVAR <TTEMBP,TTEMAC,TTEMLN>
	MOVEM T1,TTEMBP		;SAVE BYTE POINTER TO STRING
	MOVEM T2,TTEMLN		;SAVE LINE NUMBER
	MOVEM Q1,TTEMAC		;SAVE WORK REGISTER
	CALL STADYN		;GET POINTER TO DYNAMIC DATA
	 SKIPA			;NOT FULLY ACTIVE
	JRST TTEME2		;FULLY ACTIVE. USE REGULAR BUFFERS
	JUMPL T2,TTEME3		;IF BECOMING ACTIVE, CAN'T SEND MESSAGE
	JUMPE T2,TTEME1		;IF INACTIVE, GO GET A BLOCK
	JN TTSHT,(T2),TTEME3	;IF SHORT BLOCK, CAN'T SEND MESSAGE
	JRST TTEME2		;HAS MESSAGE BLOCK. APPEND STRING
TTEME1:	MOVE T2,TTEMLN		;T2/LINE NUMBER
	CALL ASGMSG		;GET A BLOCK
	 JRST TTEME3		;COULDN'T GET ONE
	MOVE T2,T1		;GET ADDRESS OF DYNAMIC DATA

;T2/ ADDRESS OF DYNAMIC DATA FOR FULL-LENGTH OR MESSAGE BLOCK

TTEME2:
	MOVE T1,TTEMBP		;RESTORE BYTE POINTER
	TLC 1,-1
	TLCN 1,-1		;LH = 777777 ?
	HRLI 1,440700		;YES, MAKE BYTE PTR
	MOVEM T1,TTEMBP		;SAVE BYTE POINTER
TTEME4:	ILDB 1,TTEMBP		;GET CHARACTER
	JUMPE 1,TTEME3		;NULL TERMINATES.
	MOVEI Q1,0(1)		;SAVE THE BYTE
	CALL SCDTCO		;OUTPUT IT
	CAIE Q1,.CHCRT		;A CARRIAGE RETURN?
	CAIN Q1,.CHLFD		;OR A LF?
	SKIPA			;GO FILL
	JRST TTEME4		;NO. GET NEXT CHARACTER
	MOVEI Q1,3		;NUMBER OF FILLS TO DO
TTEME5:	MOVEI A,TTFILL		;THE FILL CHARACTER
	CALL SCDTCO		;OUTPUT IT
	SOJGE Q1,TTEME5		;DO ALL FILLS
	JRST TTEME4		;GO DO NEXT BYTE

TTEME3:	MOVE T1,TTEMBP		;RESTORE BYTE POINTER
	MOVE Q1,TTEMAC		;RESTORE WORK REGISTER
	CALLRET TTYQOC		;GET OUTPUT STARTED

	ENDSV.			;END STKVAR
	SUBTTL BIGSTO (STORE CHAR IN TTBBUF)

;BIGSTO - ROUTINE TO STORE DATA IN TTBBUF
;DATA CONSISTS OF STATUS BITS OR DLSRCF+CHARACTER IN 8 BITS
;CALLED AT INTERRUPT LEVEL OR WITH TELETYPE INTERRUPTS DISABLED
;SOMETIMES CALLED IN SCHEDULER CONTEXT

;ACCEPTS:
;	T1/ (INTERNAL LINE NUMBER,,DATA)
;	T2/ INTERNAL LINE NUMBER (MUST BE PHYSICAL LINE)

;RETURNS +1: ALWAYS

BIGSTO::MOVEI 3,TTBSIZ		;GET SIZE OF TTBBUF
	CAMLE 3,TTBIGC		;HAS TTBBUF OVERFLOWED?
	IFSKP.
	  BUG(TTYBBO)		;YES, LOSE CHARACTER
	  RET
	ENDIF.
	TDCALL S,<<FE,BIGST2>,<DZ,DZBST>>
	 RET			;FLUSH CHAR
	AOS 3,TTBIGI		;NO. POINT TO NEXT WORD IN TTBBUF
	CAIN 3,TTBSIZ		;AT END OF TTBBUF?
	SETZB 3,TTBIGI		;YES. WRAPAROUND
	MOVEM 1,TTBBUF(3)	;STORE CURRENT DATA
	AOS TTBIGC		;COUNT CONTENTS
	RET

;INPUT DONE AND CHARACTER PRESENT (CALLED FROM INTERRUPT ROUTINES)
; T1/ CHARACTER
; T2/ LINE NUMBER
;	CALL TTIDON
; RETURN +1 ALWAYS

TTIDON::CAIE T1,PGMOFC+1B28	;PARITY AND XOFF
	CAIN T1,PGMOFC		;CHECK FOR XOFF
	CALL TTYSTC		;YES CHECK ON WHAT TO DO
TTICNT::TRO T1,DLSRCF		;INDICATE RECEIVED CHARACTER
	HRL T1,T2		;COMBINE LINE NUMBER WITH CHAR
	CALLRET BIGSTO		;PUT IN BUG BUFFER

TTYSTC:	SAVEAC <T1,T2>
	CALL STADYN		;GET DYN ADDRESS
	 RET			;INACTIVE
	JE TT%PGM,TTFLGS(T2),R	;IF NO XOFF, GO AWAY
	CALLRET TTXOFC		;DO XOFF ON COMMAND
	SUBTTL TTSNDO (NON-INTERRUPT CHAR SEND)

;TTSND0 - SEND ROUTINE CALLABLE FROM NON-PI CONTEXT

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTSN10

;RETURNS +1: ALWAYS

;USE THIS ENTRY POINT IF ONLY LINE NUMBER IS AVAILABLE

TTSN10:	NOSKD1
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST [	JUMPG T2,.+1	;IF SEND-ALL OR MESSAGE,PROCEED
		OKSKD1		;NOT ACTIVE
		RET]
	JRST TTSN11

;TTSND0 - MAIN ENTRY POINT

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTSND0

;	RETURNS +1: ALWAYS

;STARTS OUTPUT TO THE SPECIFIED LINE

TTSND0:	NOSKD1
TTSN11:	CALLRET STRTOU		;QUEUE START - INCLUDES OKSKD1

;STRTOU - START OUTPUT TO A LINE

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC BLOCK
;	T3/ COUNT OF CHARACTERS IN OUTPUT BUFFER

;	CALL STRTOU
;	MUST BE NOSKD1!

;RETURNS +1: ALWAYS OKSKD1

STRTOU:	JN TTOTP,(T2),STRT11	;IF ACTIVE, NO NEED TO START IT
	TDCALL D,<<PT,STRTO2>,<NT,NTTCSO>>
	 SKIPA			;NORMAL START
	JRST STRT11		;NOTHING ELSE TO DO
	SAVELN
	DYNST			;GET LINE NUMBER
	IDIVI T2,^D36		;COMPUTE BIT POSITION IN QUEUE
	MOVE T3,BITS(T3)
	IORM T3,TTSOQ(T2)	;REQUEST START NEXT BIGBUF CYCLE
STRT11:	OKSKD1			;ALLOW SHCEDULING NOW
	RET
;ROUTINE TO START OUTPUT ON QUEUED LINES
;CALLED ONLY ON SCHED SHORT CYCLE AT TTCH7X

TTYQOC:	SAVEAC <Q1,Q2>
	MOVSI Q1,-NTSQWD	;SETUP NUMBER OF WORDS TO CHECK
TTYQO5:	SKIPE T1,TTSOQ(Q1)	;ANY QUEUED LINES IN THIS WORD?
TTYQO4:	JFFO T1,TTYQO2		;YES, FIND ONE
	AOBJN Q1,TTYQO5		;DO ALL WORDS
	RET

TTYQO2:	MOVE Q2,BITS(T2)	;CLEAR REQUEST THIS LINE
	ANDCAM Q2,TTSOQ(Q1)	;CLEAR REQUEST BIT
	HRRZ T3,Q1		;COMPUTE LINE NUMBER
	IMULI T3,^D36
	ADD T2,T3
	CALL STADY		;GET DATA ADDRESS
	 JRST TTYQO1		;QUIT IF NONE
	CALL STRTTO		;START PHYSICAL DEVICE
TTYQO1:	MOVN T1,Q2
	ANDCA T1,TTSOQ(Q1)	;LOOK AT REST OF WORD ONLY
	JRST TTYQO4		;CONTINUE

;START PHYSICAL TTY OUTPUT DEVICE
; T2/ DYNAMIC PTR
; RETURN +1 ALWAYS

STRTTO:	SAVEQ			;PROTECT AGAINST SOMEONE HERE TRASHING Q1
	TDCALL D,<<FE,FESTRO>,<DZ,DZSTRO>,<MC,MCSTRO>,<PT,PTYCTM>>
	 NOP
	RET

;CONSTANTS

WRPMSK:	XWD 770000,TTSIZ-1	;MASK FOR WRAPAROUND OF CHAR POINTER
	SUBTTL TTSND (SEND CHAR TO LINE)

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA
;	CALL TTSND
; RETURN +1: NO OUTPUT AVAILABLE
;	+2: T1/ CHARACTER FOR OUTPUT

;CALLED AT INTERRUPT LEVEL
;OR IN SCHEDULER CONTEXT WITH TELETYPE INTERRUPTS DISABLED
;OR IN PROCESS CONTEXT WITH TELETYPE INTERRUPTS DISABLED

;SEND CHARACTER TO TTY LINE,
;FROM OUTPUT BUFFER IF NOT EMPTY; OTHERWISE
;CLEAR OUTPUT-ACTIVE FLAG

TTSND:
TTSND6:	JN <TTSFG,TTRXF>,(T2),[
		SETZRO TTOTP,(T2) ;IF CTRL/S TYPED, CLEAR OUTPUT ACTIVE
		RET]
	TMNN TTHPO,(T2)		;HP MESSAGE QUEUED?
	IFSKP.
	  ILDB T1,TTSAL2(T2)	;YES, GET NEXT CHAR
	  CAIE T1,.CHDEL	;END OF STRING?
	  RETSKP		;NO, RETURN CHARACTER
	  SETZRO TTHPO,(T2)	;RUBOUT MARKS END OF STRING, CLEAR
	ENDIF.
	TMNN TTSAL,(T2)		;SENDALL?
	IFSKP.
	  OPSTR <SKIPG>,TSALC,(T2) ;ANY MORE CHARACTERS TO SEND?
	  IFSKP.
	    ILDB T1,TTSAL2(T2)	;GET NEXT CHARACTER
	    DECR TSALC,(T2)	;DECREMENT COUNT OF REMAINING CHARACTERS
	    TRNE 1,200		;THIS CHARACTER HAVE PARITY?
	    CALL SPARTY		;SET PARITY BIT APPROPRIATELY FOR LINE TYPE
	    RETSKP		;RETURN THE CHAR
	  ENDIF.
	  CALL CLRSAL		;CLEAR SENDALL FOR LINE
	ENDIF.
	CALL GTOCHR		;GET CHAR FROM OUTBUF
	 RET			;EMPTY
	TRNE T1,TTOESC		;A FUNCTION ESCAPE CHARACTER?
	JRST TTSND3		;HANDLE ESCAPE SPECIAL
	JN TTFLO,(T2),TTSND6	;IF FLUSHING OUTPUT, GO GET ANOTHER CHAR
	RETSKP
;GET CHARACTER FROM TTY OUT BFR
; T2/ DYNAMIC PTR
; RETURN +1: BUFFER EMPTY
;	+2: T1/ CHAR (9 BITS)

GTOCHR:	SOSGE TTOCT(2)		;ARE THERE CHARACTERS IN OUTPUT BUFFER?
	JRST [	SETZRO TTOTP,(T2) ;NO CHARACTERS. CLEAR OUTPUT-ACTIVE
		SETZM TTOCT(T2)	;ZERO COUNTER
		CALLRET CLENUP] ; AND GO RELEASE BUFFERS
	CALL CHKWRN		;SEE IF FORK WAKEUP NEEDED
	SKIPN 3,TTOOUT(2)	;GET BUFFER POINTER
	BUG(TTONOB)
	TDNE 3,WRPMSK		;AT END OF BUFFER?
	IFSKP.
	  HRRZ 4,3		;YES GO TO NEXT ONE
	  HRR 3,1-TTSIZ(4)
	  MOVEM 3,TTOOUT(2)	;SAVE POINTER
	ENDIF.
	ILDB T1,TTOOUT(2)	;GET NEXT CHARACTER
	RETSKP

;BACKUP OUTPUT PTR BY ONE (E.G. BECAUSE DTE QUEUE FULL)
; T2/ DYN PTR

BAKTTO:	MOVNI T3,1
	TMNN <TTSAL>,(T2)	;SENDALL?
	IFSKP. <INCR TSALC,(T2)> ;YES, ADJUST COUNT
	TMNN <TTHPO,TTSAL>,(T2)	;HP OR SENDALL STRING?
	IFSKP.
	  ADJBP T3,TTSAL2(T2)	;YES, BACKUP BYTE PTR
	  MOVEM T3,TTSAL2(T2)
	  RET
	ENDIF.
	ADJBP T3,TTOOUT(T2)
	MOVEM T3,TTOOUT(T2)	;RESTORE IT
	AOS TTOCT(T2)		;RESET COUNT
	RET
;FUNCTION ESCAPE CHARACTER ENCOUNTERED IN OUTPUT STREAM

TTSND3:	CAIE T1,TTOMRK		;OUTPUT MARKER?
	IFSKP.
	  JE TTFLO,(T2),TTSND6	;IGNORE IF NOT FLUSHING OUTPUT
	  MOVE T1,[POINT 7,[BYTE (7)"]",.CHCRT,.CHLFD,0,0,0,0,0,.CHDEL]]
	  MOVEM T1,TTSAL2(T2)	;SEND INDICATION (WITH FILLS ON CR AND LF)
	  SETONE TTHPO,(T2)	;NOTE HP OUTPUT QUEUED
	  SETZRO TTFLO,(T2)	;STOP FLUSHING OUTPUT
	  JRST TTSND6		;TRY FOR MORE OUTPUT
	ENDIF.
	JN TTFLO,(T2),TTSND6	;FLUSH OTHER CASES IF FLUSHING OUTPUT
	CAIE T1,TTOPFC		;PAGE FULL FUNCTION?
	IFSKP. <
	  SETONE TTSFG,(T2)	;YES. SIMULATE CTRL/S
	  JRST TTSND6>		; AND GO CLEAR OUTPUT ACTIVE
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER TO PRINT
	BUG(TTILEC,<<2,D>,<3,D>>)
	POP P,T2		;RESTORE ADDRESS OF DYNAMIC DATA
	JRST TTSND6

;CHKWRN - CHECK FOR WAKEUP NEEDED FROM OUTPUT BLOCK
;CALLED WHEN CHARACTERS TAKEN FROM OUTPUT BUFFER AND TTOCT REDUCED
; T2/ DYNAMIC DATA PTR

CHKWRN:	JN TTNUS,(T2),R		;DO NOTHING IF NET USEER
	JE TTBKO,(T2),R		;RETURN IMMED IF NO FORK WAITING ON LINE
	LOAD T3,TOWRN,(T2)	;GET WARNING LEVEL COUNT
	CAMLE T3,TTOCT(T2)	;CAN WAKE?
	CALL CHKTOT		;YES, POKE SCHED
	RET

;CHKBKO - CHECK FOR WAKEUP NEEDED ON OUTPUT EVENT
; T2/ DYNAMIC DATA PTR

CHKBKO:	JE TTBKO,(T2),R		;RETURN IMMED IF NO FORK WAITING ON LINE
	CALLRET CHKTOT		;REQUEST CHECK OF OUTPUT-BLOCKED FORKS

;CLENUP - GET RID OF OUTPUT BUFFERS

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL CLENUP

;RETURNS +1: ALWAYS

;OUTPUT BUFFERS ARE EMPTY.  RELEASE THEM. IF INTERRUPT
;ON EMPTY OUTPUT BUFFER IS REQUESTED, PUT A WORD IN TTBBUF WITH BIT
;TTOIRQ SET.  TTCH7 WILL FIND IT WHEN IT IS RUN AGAIN.

CLENUP:	CALL TTRLOB		;RELEASE OUTPUT BUFFERS, SINCE EMPTY
	MOVX 3,1B<.TICTO>
	TMNE <TTMES,TTSHT>,(T2)	;A NORMAL BLOCK?
	RET
	LOAD T1,TTPSFK,(T2)	;GET FORK #
	CAIE T1,-1		;SKIP IF NOT SET
	JRST CLENU1		;SET, NON-CONTROLLING TERMINAL PSI REQUESTED
CLENU2:	TDNN 3,TTPSI(2)		;OUTPUT INTERRUPT WANTED?
	RET			;NO. RETURN
	MOVEI T1,TTOIRQ		;YES, PUT REQUEST IN BIG BUF
	JRST CLENU3

CLENU1:	LOAD T1,TTOPSI,(T2)	;GET PSI CHANNEL NUMBER
	CAIL T1,^D36		;SETUP?
	JRST CLENU2		;NO TRY OLD WAY
	MOVEI T1,TTPIRQ		;SET UP TO DO INTERRUPT
CLENU3:	SAVELN
	DYNST			;GET LINE NUMBER
	HRL T1,T2
	CALLRET BIGSTO		;REQUEST INTERRUPT


;ROUTINES CALLED FROM INTERRUPT ROUTINES

;POST OUTPUT DONE.
; 2/ LINE NUMBER

TTODON::CALL STADY		;GET ADDRESS OF DYNAMIC DATA
	 RET			;RETURN IF BECOMING ACTIVE OR INACTIVE
	CALLRET STRTTO		;START OUTPUT AGAIN
;TTDALL - ROUTINE CALLED FROM POWER RESTART CODE TO DETACH ALL JOBS
	RESCD			;MUST BE RESIDENT

TTDALL::SETZ C,			;START WITH FIRST LINE TYPE
	JRST TTDAL5		;GO CHECK THEM


;GO TO NEXT LINE. IF THE LINE TYPE CHANGES, DON'T PROCEED WITH THE NEW
;LINE. INSTEAD, GO TO THE NEXT LINE TYPE AFTER THE ONE JUST PROCESSED.
;THIS CODE ASSUMES THAT ALL LINES OF A GIVEN TYPE ARE NUMBERED CONSECUTIVELY.

TTDAL3:	LOAD C,TTSTY,(B)	;GET CURRENT TYPE
	ADDI B,1		;GO TO NEXT LINE
	CAIL B,NLINES		;BEYOND END OF LINES?
	JRST TTDAL7		;YES. GO TO NEXT LINE TYPE
	LOAD A,TTSTY,(B)	;GET TYPE OF NEXT LINE
	CAME C,A		;NEW TYPE?
	JRST TTDAL7		;YES. GO INCREMENT THE LINE TYPE

;TRANSFER ACCORDING TO THE VECTOR IN A. CERTAIN TYPES ARE NEVER
;PROCESSED.

TTDAL8:	TDCALX C,<<FE,RSKP>,<NT,RSKP>> ;SKIP IF DETACH SHOULD BE DONE
	 JRST TTDAL7		;DON'T DO IT

;DETACH THE JOB ON THIS LINE IF THERE IS ONE

	CAME B,CTYLNO		;IS THIS THE CTY?
	CALL TTJBDT		;DETACH THE JOB
	JRST TTDAL3		;GO PROCESS NEXT LINE

;FINISHED THE CURRENT LINE TYPE OR THE CURRENT TYPE IS NOT TO BE PROCESSED
;GO TO THE NEXT TYPE AND SEE IF IT IS TO BE PROCESSED

TTDAL7:	AOS C			;GO TO NEXT LINE TYPE
	CAIL C,NLTYPS		;BEYOND END OF LEGAL TYPES?
	RET			;YES. DONE ALL LINES
TTDAL5:	MOVE B,TT1LIN(C)	;GET FIRST LINE OF THIS TYPE
	JRST TTDAL8
;ROUTINES TO ENABLE/DISABEL DATASETS.
;CLOBBERS ALL TEMP REGISTERS:

DTRMEN::TDZA D,D		;GET A ZERO TO DO ENABLE
DTRMDS::MOVEI D,1		;GET A ONE TO DISABLE
	SAVEQ
	MOVSI Q1,-NLTYPS	;DO ALL LINE TYPES
TTLIL2:	TDCALX Q1,<<FE,FEDABL>>,<RET>
	AOBJN Q1,TTLIL2
	RET

	RESCD

TTBUGH:	BUG(BADTTY)
	RET
;*** PTY SPECIFIC CODE ***

  IFN .PTFLG,<			;IF THIS CODE WANTED
	SUBTTL PTY DEVICE DEPENDENT CODE
	SWAPCD

; STPAR JSYS DEVICE DEPENDENT CODE

STPAR5:	TXZ A,TT%PGM		;YES. CAN'T SET PAGE MODE THEN
	RET

	RESCD

;DEVICE DEPENDENT CODE FOR START OUTPUT LINE
;LINE IS PTY.

STRTO2:	MOVE T3,TTOCT(T2)	;GET OUTPUT COUNT
	CAIN T3,1		;BUFFER WAS EMPTY BEFORE THIS CHAR?
	JRST [	SETONE TTDD1,(T2)	;NOTE OUTPUT EVENT
		JRST .+1]
	LDB T1,TTOIN(T2)	;CHECK CHAR BEING OUTPUT
	ANDI T1,177
	CAIN T1,.CHLFD		;END OF LINE?
	CALL CHKPT1		;MAYBE POKE CONTROLLING JOB
	RET
;PTYCTM - CALLED PERIODICALLY BY TTCH7 TO SEE IF OUTPUT START NEEDED
; T2/ DYNAMIC DATA PTR
; RETURN +2 TO PREVENT NORMAL OUTPUT START SEQUENCE

PTYCTM:	SKIPG TTOCT(T2)		;YES, ANY OUTPUT HERE?
	RETSKP			;NO
	CALL CHKPT1		;DO THE WORK
	RETSKP

CHKPT1:	CALL CHKBKO		;PERHAPS WAKEUP FORK WAITING FOR OUTPUT
	JE TTDD1,(T2),R		;RETURN IF NO OUTPUT EVENT RECENTLY
	SETZRO TTDD1,(T2)	;ONCE ONLY
	LOAD T1,TINTL,(T2)	;GET LINE NUMBER
	CALL TTYPTY		;CONVERT OT PTY NUMBER
	CALL PTYFOU		;NOTE PTY OUTPUT EVENT
	RET

;CHKPTA - CALLED WHEN FORK IS BLOCKING TO WAIT FOR SOME OUTPUT ACTIVITY
; IF LINE IS PTY, OUTPUT SHOULD BE STARTED IMMEDIATELY
; T2/ DYNAMIC DATA PTR

CHKPTA:	SAVET
	JRST CHKPT1		;YES, START IT

;CHECK PTY FOR OUTPUT POSSIBLE
;IF THE PTY HAS BEEN CLOSED, OUTPUT SHOULD NOT BE DONE BECAUSE
;NOTHING WILL EVER EMPTY THE OUTPUT BUFFER
; T2/ DYNAMIC PT
; RETURN +1: NO OUTPUT
;	+2: OUTPUT OK

CKPTOU:	SAVEAC <T2>
	DYNST		;GET LINE NUMBER
	CALL PTYSKO	;IS IT OPEN?
	 RET
	RETSKP
;LINE IS A PTY. SEE IF PTY LOGINS ARE ALLOWED

TTC7S2:	TXNE T1,SF%PTY		;SEE IF PTY LOGINS ALLOWED
	JRST RTRUE		;YES, GO LOGIN IN
	HRROI 1,[ASCIZ/
?LOGGING IN OVER PTY'S IS CURRENTLY DISALLOWED.
/]
	CALL TTEMSS
	JRST RFALSE		;FAIL

;DEVICE DEPENDENT CODE FOR TCI

TCIPTY:	CALL CHKPTA		;POKE OUTPUT FIRST
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER
	MOVE T1,T2		;T1/LINE NUMBER
	CALL TTYPTY		;CONVERT TO PTY NUMBER IN T1
	CALL PTYFIN		;NOTE PTY INPUT EVENT
	POP P,T2		;RESTORE ADDRESS OF DYNAMIC DATA
	RET

  >				;END IFN .PTFLG SEVERAL PAGES BACK