Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - mit/monitor/ttysrv.mac
There are 50 other files named ttysrv.mac in the archive. Click here to see a list.
;[MIT-XX]SSY:<MONITOR.NEW>TTYSRV.MAC.5,  5-Nov-83 17:29:04, Edit by BERLIN
;[MIT-XX]SSY:<XX.MONITOR>TTYSRV.MAC.26, 23-Jun-83 08:25:25, Edit by BERLIN
;3056 Remove assumption of cursor knowledge in .VTMOV vtsop
;[MIT-XX]SSY:<XX.MONITOR>TTYSRV.MAC.25, 21-May-83 18:22:25, Edit by BERLIN
;3053 Always print CR 'cuz we don't KNOW a LF will follow (ted, eg)
;[MIT-XX]SSY:<XX.MONITOR>TTYSRV.MAC.23, 11-May-83 14:08:30, Edit by ROBERT
;3051 Fix from CLYNN and MRC to fix "slow tvt problem"
;3100 Try again.
;<5.MONITOR>TTYSRV.MAC.46, 18-Feb-83 19:33:42, Edit by JTW
;3022 TM%RSU reverses delete and nderscore chars on input
;[MIT-XX]PS:<BERLIN.M5>TTYSRV.MAC.22,  1-Mar-83 10:32:30, Edit by BERLIN
;3032 Search tcppar, mntpar, inpar
;[MIT-XX]SSY:<BERLIN.M5>TTYSRV.MAC.21, 24-Jan-83 12:56:57, Edit by ROBERT
;3030 Make ttlokb a bugchk instead of a bughlt
;[MIT-XX]SSY:<BERLIN.M5>TTYSRV.MAC.20,  7-Jan-83 13:03:38, Edit by ROBERT
;3022 Don't flush sendall or FE buffers on CFOBF
;3010 Temporary SUPDUP fix till parity is done right
;<BERLIN.M5>TTYSRV.MAC.16,  7-Oct-82 18:18:53, Edit by BERLIN
;3005 HSTTY routine
;3005 Also changed many jrst [] to IFSKP. macros
;<5.MITMON>TTYSRV.MAC.28,  6-Oct-82 02:21:21, Edit by JTW
;3004 Flag linked chars on per-tty basis - fix occasional no-eop-mode bug
;<5.MITMON>TTYSRV.MAC.27,  2-Oct-82 16:47:55, Edit by JTW
;3002 Finish up ITS-style page handling
;<BERLIN.M5>TTYSRV.MAC.13, 20-Sep-82 13:15:37, Edit by BERLIN
;1027 Fix for send all to CVT's (KDO)
;1026 Eliminate OKSKBG bughlt due to bad lock handling
;1010 Several fixes for TVT's
;1005 Fix typo causing TTY's to sometimes hang
;<5.MITMON>TTYSRV.MAC.22,  5-Aug-82 22:07:39, Edit by JTW
; Add MIT changes:
; Chaos, TCP, and MultiNet line types.
; ITP and full character (12 bit) input.
; VTS - Cleaned up and reworked some from Rel-4, but still the same logical
;	implementation - needs a little rethinking. (Translate at TTSND
;	level)
;	Changed definition of ^P codes to match ITS.
; Screw around with links so that output to linked terminals goes through
;	VTS translation and so that job won't hang if a linked terminal 
;	hits an	end-of-page.	
; Rewrote much of TTCHI to:
;	Check interrupt chars before doing anything else, so ^S/^Q
;	and the page pause/unpause characters can be used as interrupts.
;	Implement verbose end-of-page indication.
;	Implement ITS style more processing as an option.
;171 Add TTIDLE
;23 Fixed link header for not logged in terminals
;17 Added static terminal types and moved links
;2  Made NORMTF reasonable for MIT
; 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 TTVT40 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 TTVT39
;<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 TLNCT 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
;FXI 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
;FXI 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

   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
>

	SEARCH TCPPAR,INPAR,MNTPAR

;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

  IFNDEF DCN,<DCN==0>
  IFN DCN,<
	.MCFLG==1>

  IFNDEF CHAOS,<CHAOS==0>
  IFN CHAOS,<
	.NTFLG==1
	.CHFLG==1>

  IFNDEF TCPN,<TCPN==0>
  IFN TCPN,<
	.TVFLG==1>

  IFNDEF MNET,<MNET==0>
  IFN MNET,<
	.MLFLG==1>

.MLFLG==0			;+++ Set this to 0 for MIT

ND .TTYLG,0			;3032 No logging code
ND .FEFLG,0
ND .MCFLG,0
ND .PTFLG,1
ND .DCFLG,0
ND .NTFLG,0
ND .DZFLG,0
ND .MLFLG,0
ND .CHFLG,0
ND .TVFLG,0

ND NVTLEN,0
ND TTMCLN,0
ND MLCLEN,0
ND CVTLEN,0
ND TVTLEN,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, ML, CH, TV 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,ML,CH,TV>,<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>>

;VARIANT MACRO USED IF LINE TYPE ALREADY IN AC

DEFINE TDCALX (AC,VECTOR,DEFLT)<
	CALL [
	  ..TDC1 (<VECTOR>,<FE,MC,PT,DC,NT,DZ,ML,CH,TV>,<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
	JFCL			;ML
	TRZ T1,200		;CH
	TRZ T1,200		;TV

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
	MLCLEN			;ML
	CVTLEN			;CH (CHAOS)
	TVTLEN			;TV (TCP)
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			;1010 Make that 11-13
;---DEFSTR TTXCN MISSING, WON'T FIT
DEFSTR TTSTY,TTSTAT,17,4	;1010 Need 4 bits here! 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		;ADDRESS OF ROUTINE FOR SCHEDULER TO CALL
DEFSTR TTIME,TTCSTM,35,36
;RS TTCSTM,NLINES		;TIME FOR SCHEDULER TO CALL ROUTINE
DEFSTR TROUT,TTCSAD,35,36

;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%VTF==1B19			;NEXT CHAR IS VTS FUNCTION CODE
TT%VTA==1B20			;NEXT CHAR IS VTS ARGUMENT
TT%CRS==1B21			;CARRIAGE RETURN SEEN AT TCOY LEVEL
TT%CFU==1B22			;LOST TRACK OF CURSOR
TT%NAB==1B23			;DOING CURSOR RECOVERY, NO ABSOLUTE MOTION
TT%LNC==1B24			;3004 OUTPUTTING LINKED CHARACTER
TT%OVF==1B29			;3030 OVERFLOW BIT FOR COUNT OF LOCKS
;25-28 FREE
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 TTVTF,TTFLG1,TT%VTF
MSKSTR TTVTA,TTFLG1,TT%VTA
MSKSTR TTCRS,TTFLG1,TT%CRS
MSKSTR TTCFU,TTFLG1,TT%CFU
MSKSTR TTNAB,TTFLG1,TT%NAB
MSKSTR TTLNC,TTFLG1,TT%LNC	;3004
MSKSTR TTOVF,TTFLG1,TT%OVF 	;3030
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
TSALCM==^D581			;MAX 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 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 TLVPS,TTLPOS,17,18	;CURRENT LINE POSITION WITHIN PAGE
DEFSTR TLHPS,TTLPOS,35,18	;CURRENT CHARACTER POSITION WITHIN LINE

TTFLGS==23
MSKSTR TOFLG,TTFLGS,TT%OSP	;CTRL/O WAS TYPED
;(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 STORAGE
DEFSTR TLNCT,TTLINE,35,18	;NUMBER OF LINES SINCE LAST PAGE STOP

TTLMAX==34			;NET USER WORD
DEFSTR TTLMX,TTLMAX,35,18	;MAX NUMBER OF LINES
DEFSTR TTULL,TTLMAX,35,18	;NET USER LOGICAL LINK - TTLMAX NOT USED
DEFSTR TTUEC,TTLMAX,17,7	;NET USER ESCAPE CHAR

TTIDLE==35			;171 TODCLK OF LAST TYPIN

TTINPP==36			; INPUT PROCESSING
DEFSTR TIRUT,TTINPP,35,18	; ROUTINE TO CALL TO PROCESS INPUT

TTINPW==37			; WORD AVAILABLE TO INPUT PROCESSING ROUTINES
; DEFINITIONS USED BY ITP
DEFSTR TISLH,TTINPW,0,1		; ^\ SEEN, WAITING FOR COMMAND CHAR
DEFSTR TICCH,TTINPW,1,1		; COMMAND CHAR SEEN, WAITING FOR ARG
DEFSTR TIALP,TTINPW,2,1		; ALLOCATION IN EFFECT
DEFSTR TIHCP,TTINPW,3,1		; A PREFIX CHAR WAS SEEN AT TCI LEVEL
DEFSTR TICHR,TTINPW,11,8	; CHAR AFTER ^\
DEFSTR TILAC,TTINPW,19,8	; LAST ASCII CHARACTER SEEN AT TTCHI LEVEL
DEFSTR TIFCH,TTINPW,35,12	; FULL INPUT CHARACTER
DEFSTR TIHCH,TTINPW,28,5	; HIGH (BUCKY) BITS OF CHARACTER
DEFSTR TILCH,TTINPW,35,7	; LOW BITS OF CHARACTER
; LH available

TTSIZE==40			;SCREEN SIZE PARAMETERS
DEFSTR TPWID,TTSIZE,35,18	;PAGE WIDTH
DEFSTR TPLEN,TTSIZE,17,18	;PAGE LENGTH

TTTMOD==41			; DISPLAY MODE WORD
  REPEAT 0,<			; FLAGS DEFINED IN MONSYM
TM%DPY==1B0			; PROCESS ^P CODES 
TM%SCR==1B1			; SCROLL MODE / WRAP MODE
TM%MOR==1B2			; MORE PROCESSING ENABLED
TM%MVR==1B3			; VERBOSE SORT OF MORE
TM%MSM==1B4			; SMART ABOUT MORE
TM%VBL==1B5			; USE VISIBLE BELL FOR ^G
TM%GRF==1B6			; PROCESS GRAPHICS FUNCTIONS

TM%ITP==1B17			; INTELLIGENT TERMINAL PROTOCOL IN USE
   >
MSKSTR TMDPY,TTTMOD,TM%DPY
MSKSTR TMSCR,TTTMOD,TM%SCR
MSKSTR TMMOR,TTTMOD,TM%MOR
MSKSTR TMMVR,TTTMOD,TM%MVR
MSKSTR TMMSM,TTTMOD,TM%MSM
MSKSTR TMVBL,TTTMOD,TM%VBL
MSKSTR TMRSU,TTTMOD,TM%RSU
MSKSTR TMGRF,TTTMOD,TM%GRF

TTCHAR==42			;TERMINAL CHARACTERISTICS WORD
  REPEAT 0,<			;FLAGS DEFINED IN MONSYM
TC%MOV==1B0			; ABSOLUTE OR RELATIVE CURSOR MOTION
TC%BS== 1B1			; CURSOR BACK AT LEAST (BACKSPACE)
TC%HOM==1B2			; HOME TO TOP LEFT HAND CORNER
TC%CLR==1B3			; CLEAR ENTIRE SCREEN AT LEAST
TC%SCL==1B4			; CLEAR SELECTIVE PORTIONS OF SCREEN
TC%LID==1B5			; LINE INSERT/DELETE
TC%CID==1B6			; CHARACTER INSERT/DELETE
TC%VBL==1B7			; VISIBLE BELL
TC%MET==1B8			; HAS META (8-BIT) KEY
TC%SCR==1B9			; SCROLLS ON DOWN FROM BOTTOM LINE
TC%RSC==1B10			; REVERSE-SCROLLS ON UP FROM TOP-LINE
TC%OVR==1B11			; OVERWRITES
TC%FCI==1B12			; HAS FULL 12-BIT INPUT CAPABILITY

TC%PRT==1B17			; PRINTING TERMINAL
   >

TTSCPS==43			;SAVED CURSPR POSITION 

TTPPOS==44			;PHYSICAL CURSOR POSITION
DEFSTR TPVPS,TTPPOS,17,18	;PHYSICAL VERTICAL POSITION
DEFSTR TPHPS,TTPPOS,35,18	;PHYSICAL HORIZONTAL POSITION

TTVTSF==45			; RANDOM VTS-RELATED FIELDS AND BITS
DEFSTR TTLCH,TTVTSF,22,8	; CHAR IN LAST LINE POSITION
DEFSTR TSVPS,TTVTSF,29,7	; VERTICAL POS AT TTSND LEVEL
DEFSTR TTCVT,TTVTSF,35,6	; VTS FUNCTION CODE WHICH IS WAITING FOR ARG

TTPADW==46			; PADDING INFORMATION
DEFSTR TPDCH,TTPADW,35,18	; CHAR TO PAD WITH

TTTGV==47			; DISPLAY GRAPHICS CHARACTERISTICS
  REPEAT 0,<			; FIELDS ARE IN MONSYM
TQ%GRF==:1B17			;TERMINAL UNDERSTANDS GRAPHICS PROTOCOL
TQ%SET==:1B16			;TERMINAL SUPPORTS MULTIPLE SETS
TQ%REC==:1B15			;TERMINAL IMPLEMENTS RECTANGLE COMMANDS
TQ%XOR==:1B14			;TERMINAL IMPLEMENTS XOR'ING
TQ%BNK==:1B13			;TERMINAL IMPLEMENTS A STAND-OUT MODE
TQ%VIR==:1B12			;TERMINAL IMPLEMENTS VIRTUAL COORDS
TQ%WID==:17B11			;CHARACTER WIDTH IN GRAPHIC UNITS
TQ%HGT==:76B7			;CHARACTER HEIGHT IN GRAPHIC UNITS
			; THESE NEXT TWO ARE LIKELY TO GET MOVED TO THE
			; LEFT HALFWORD SOME DAY
TR%GIN==:1B18			;TERMINAL HAS A GRAPHICS INPUT DEVICE
TR%GHC==:1B19			;TERMINAL HAS A HARDCOPY OUTPUT DEVICE
   >

TTGPOS==50			;SPACE TO KEEP THE GRAPHICS CURSOR POSITION
				; AND OTHER GOODIES LIKE WHETHER THE TERMINAL
				; IS CURRENTLY DOING GRAPHICS. THERE IS ALSO
				; A FREE LEFT HALFWORD UP ABOVE THAT IS LIKELY
				; TO GET USED FOR INFORMATION OF THAT TYPE.
				; ...NOT USED FOR ANYTHING YET

;LENGTHS OF DYNAMIC BLOCKS

TTDDLN==51			;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
MINXON==20			;WHERE TO SEND XON
MINCT1==MINICT+10		;WHEN TO FORCE WAKEUP BEFORE XOFF
MINCT2==MINCT1/4+2		;LOWSPEED
MINXOS==40			;WHERE TO RESTART LOW SPEED LINES
MINXOF==4			;WHERE TO RESTART HIGH SPEED LINES

TTLIND=="'"			;UPPER CASE INDICATION CHARACTER FOR OUTPUT
TTCIND=="^"			;CONTROL INDICATION CHARACTER FOR OUTPUT
WRPCHR=="!"			;LINE WRAP INDICATOR
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
VTCESC=="P"-100			;VTS FUNCTION ESCAPE CHARACTER
MORSAF==5			;+++ # LINES TO SUPPRESS EOP STOP 

TTOESC==400			;FUNCTION ESCAPE IN OUTPUT STREAM
.TTPFC==401			;PAGE FULL CODE IN OUTPUT STREAM
.TTMRK==402			;OUTPUT STREAM MARKER, CLEAR OUTPUT FLUSHING
.TTBRK==403			;+++ MAY MARK SAFE PLACE FOR CFOBF

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

SALTMO==^D<30*1000>		;145 SENDALL TIMEOUT (MSEC)
	RESCD

;INDEX TO DEV TABLES FOR TTY0

DEVTT0:: DVXTT0


;USUAL DEVICE FLAGS AND STATUS
; 66 LINES/PAGE, 80 CHARS/LINE
; WAKEUP ON ALL, ECHO ON, ECHO DEFERRED
; ACCEPT LINKS, REFUSE ADVICE
; DATA MODE ASCII, NO RAISE, FULL DUPLEX

NORMTF::^D66B10+^D80B17+17B23+1B24+1B26+1B29	;2 CHANGED FOR MIT
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


;OKSKD1 and NOSDK1, but callable at PI level (whence we do nothing)

NSKD1:	CONSZ PI,177B27		;PI IN PROGRESS?
	 RET			;YES, DON'T DO ANYTHING
	NOSKD1			;ELSE, GO NOSKED
	RET

OSKD1:	CONSZ PI,177B27		;PI IN PROGRESS?
	 RET			;YES, NOTHING TO DO
	OKSKD1
	RET

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

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

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

CTRLOF::0			;NEW CTRL-O HANDLING POSSIBLE
	SUBTTL DEFINITIONS FOR TTYPE2 TABLE (PER TERMINAL DISPLAY INFORMATION)

;INDEXED BY TERMINAL TYPE
DEFSTR	DPTB,TTYPE2,35,18	; Address of display control table
	DPTBB==1B0		; if set, then bits 1-35 are 7 bit bytes, else
	DPTBS==1B1		; If set, then RH is address of string, else
	DPTBR==1B2		; If set, then RH is address of routine and
	DPTBP==1B3		; If set, repeat count is "parameterized"
DEFSTR  DPCNT,,17,6		; Estimated length of string or routine
DEFSTR	DPBSZ,,11,4		; Byte size for strings
; Table defining ^P codes in terms of .VT codes, and whether they take
; arguments.

; Note: NARGS can only be 0 or 1 at present

DEFINE	VT(TCOA,NARGS<0>)
   <	NARGS,,TCOA
   >

VTPTAB:	VT(VTOADV)		;ADVANCE LINE		CODE 01 "A"
	VT(VTOBCK)		;CURSOR BACK		CODE 02 "B"
	VT(VTOCLR)		;CLEAR WINDOW		CODE 03 "C"
	VT(VTODWN)		;CURSOR DOWN		CODE 04 "D"
	VT(VTOCEW)		;CLEAR TO END OF WINDOW	CODE 05 "E"
	VT(VTOFWD)		;CURSOR FORWARD		CODE 06 "F"
	VT(VTOVBL)		;VISIBLE BELL		CODE 07 "G"
	VT(VTOHRZ,1)		;HORIZONTAL POSITION	CODE 10 "H"
	VT(VTOINC)		;INSERT CHARACTER	CODE 11 "I"
	VT(VTODLC)		;DELETE CHARACTER	CODE 12 "J"
	VT(VTOERA)		;ERASE CHARACTER	CODE 13 "K"
	VT(VTOCEL)		;CLEAR TO END OF LINE	CODE 14 "L"
	VT(0)			;UNDEFINED		CODE 13 "M"
	VT(0)			;UNDEFINED		CODE 16 "N"
	VT(0)			;UNDEFINED		CODE 17 "O"
	VT(VTOSEC)		;SEND A ^P		CODE 20 "P"
	VT(VTOHMD)		;HOME DOWN		CODE 21 "Q"
	VT(VTORES)		;RESTORE CURSOR POS	CODE 22 "R"
	VT(VTOSAV)		;SAVE CURSOR POS	CODE 23 "S"
	VT(VTOHOM)		;HOME UP		CODE 24 "T"
	VT(VTOUP)		;CURSOR UP		CODE 25 "U"
	VT(VTOVRT,1)		;VERTICAL POSITION	CODE 26 "V"
	VT(0)			;UNDEFINED		CODE 27 "W"
	VT(VTOBEC)		;BACKSPACE AND ERASE CH	CODE 30 "X"
	VT(0)			;UNDEFINED		CODE 31 "Y"
	VT(VTOHMD)		;HOME DOWN		CODE 32 "Z"
	VT(VTOINL)		;INSERT LINE		CODE 33 "["
	VT(VTODLL)		;DELETE LINE		CODE 34 "\"
	VT(0)			;OBSOLETE		CODE 35 "]"
	VT(VTOINC)		;INSERT CHARACTER	CODE 36 "^"
	VT(VTODLC)		;DELETE CHARACTER	CODE 37 "_"
VTPMAX==.-VTPTAB

; Table of VTS function handling routines.

DEFINE TC (RTN)
   <	RTN
   >

VTSTAB:	TC(VTONOP)		; .VTNOP - NOP (force update)
	TC(VTOFWD)		; .VTFWD - Cursor forward
	TC(VTOBCK)		; .VTBCK - Cursor back
	TC(VTOUP)		; .VTUP - Cursor up
	TC(VTODWN)		; .VTDWN - Cursor down
	TC(VTOHRZ)		; .VTHRZ - Set horizontal pos
	TC(VTOVRT)		; .VTVRT - Set vertical pos
	TC(VTOMOV)		; .VTMOV - Move cursor (x and y)
	TC(VTOHOM)		; .VTHOM - Home up
	TC(VTOHMD)		; .VTHMD - Home down
	TC(VTOADV)		; .VTADV - Advance to next line
	TC(VTOSAV)		; .VTSAV - Save pos
	TC(VTORES)		; .VTRES - Restore pos
	TC(VTOCLR)		; .VTCLR - Clear window
	TC(VTOCEW)		; .VTCEW - Clear to end-of-window
	TC(VTOCEL)		; .VTCEL - Clear to end-of-line
	TC(VTOERA)		; .VTERA - Erase character ???
	TC(VTOBEC)		; .VTBEC - Backspace and erase
	TC(VTOLID)		; .VTLID - Line insert/delete
	TC(VTOCID)		; .VTCID - CHaracter insert/delete
	TC(VTOSEC)		; .VTESC - Output VTS escape
	TC(VTOVBL)		; .VTVBL - Visible bell
VTSMAX==VTSTAB-.
	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
	SETZM SNDALL		;FREE SEND ALL BUFFER ---
	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.
;MLC LINES SHOULD BE SECOND,TNT LINES SHOULD BE THIRD
;FOR STATIC STORAGE TO BE ALLOCATED PROPERLY
;ASSEMBLING THIS WAY ALLOWS FOR EFFICIENT STATIC STORAGE
;FOR THESE TYPES, (DEC DIDN'T ALLOW FOR THAT VIA DYNAMIC ALLOCATION)

	;..
	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
	HRLI T4,-NTTMLC		;# MLC TYPE LINES
	HRR T4,T2		;1ST ONE
	MOVEM T4,MLCXWD		;FILL OUT USEFUL AOBJN PTR
	MOVEI T3,TT.MLC		;MLC TYPE
	MOVEI T4,NTTMLC		;HOW MANY
	CALL SETTYP
	HRLI T4,-NTTTVT		; NEG. NUMBER OF TCP VIRTUAL LINES
	HRR T4,T2		; FIRST ONE
	MOVEM T4,TVTPTR		; SET AOBJN PTR OVER TVTS
	MOVEI T3,TT.TVT		; CODE FOR TVTS
	MOVEI T4,NTTTVT		; HOW MANY OF THEM
	CALL SETTYP		; SET THEM UP
	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
	MOVEI T3,TT.CVT		;T3/ CODE FOR CHAOS LINES
	HRLI T4,-NTTCVT		;SET UP NVT PAR WITH -NTTCVT,,FIRST CVT
	HRR T4,T2		;GET FIRST CVT
	MOVEM T4,CVTPTR		;STORE IT AWAY
	MOVEI T4,NTTCVT		;T4/ NUMBER OF CHAOS 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>,<ML,MLCINI>,<CH,CHTINI>>,<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
	CAME T3,CTYTYP		;IS THIS THE LINE TYPE FOR THE CTY?
	 IFSKP.
	  CALL INICTY		;YES. INITIALIZE IT
	  AOS T2		;POINT TO NEXT LINE
	 ENDIF.
	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>>
TTSET1:	LOAD T3,TTSTY,(T2)	;GET LINE TYPE FROM STATIC
	STOR T3,TLTYP,(T1)	; AND COPY TO DYNAMIC
;17 	MOVE Q1,NORMTY		;GET NORMAL TERMINAL TYPE
	CALL GTYPP0		;17 GET TERMINAL TYPE FROM PERMANENT AREA
	STOR T3,TTTYP,(T1)	;17 SET IN DYNAMIC DATA
	STOR T2,TINTL,(T1)	;STORE LINE NUMBER IN DYNAMIC DATA
	MOVE Q1,IBFRC		;GET DEFAULT BUFFER CONTROL
	MOVEM Q1,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
	SETZM TTLPOS(T1)	;CLEAR LOGICAL CURSOR POSITION
	SETZM TTPPOS(T1)	;CLEAR PHYSICAL CURSOR POSITION
	SETZM TTSCPS(T1)	;CLEAR SAVED CURSOR POSITION
	SETZM TTVTSF(T1)	;CLEAR VTS FLAGS
	MOVX Q1,TM%SCR		;DEFAULT TO SCROLL MODE
	MOVEM Q1,TTTMOD(T1)

;17 BEGIN DELETION
REPEAT 0,<
	MOVE Q1,NORMTF		;USUAL DEVICE FLAGS AND STATUS
	CAMN T2,CTYLNO		;ASSIGNING CTY?
	TXZ Q1,TT%ALK		;YES - DISALLOW TALK LINKS
	LOAD T3,TLTYP,(T1)	;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
>;17 END DELETION

;17 BEGIN ADDITION - T3/ TERMINAL TYPE FOR TTTxxx BYTEPTRS
	LDB Q1,TTTWID		;GET STANDARD WIDTH
	STOR Q1,TPWID,(T1)	;SET IT FOR THIS LINE
	LDB Q1,TTTLEN		;GET STANDARD LENGTH
	STOR Q1,TPLEN,(T1)	;SET IT FOR THIS LINE
	HRRZ Q1,NORMTF		;USUAL DEVICE FLAGS AND STATUS
	CAMN T2,CTYLNO		;ASSIGNING CTY?
	TXZ Q1,TT%ALK		;YES - DISALLOW TALK LINKS
	LDB T4,TTMBIT		;GET MECH BITS FOR THIS TERM TYPE
	DPB T4,[POINT 3,Q1,3]	;PUT WHERE NOTICED
	LOAD T3,TLTYP,(T1)	;GET TYPE OF LINE AGAIN
	CAIN T3,TT.PTY		;IS IT A PTY?
	TXZ Q1,TT%PGM		;YES. NO XON/XOFF THEN
	MOVEM Q1,TTFLGS(T1)	;SAVE FLAGS
	PUSH P,T2		;SET THINGS UP STANDARDLY (T2/ DYN DATA PTR)
	MOVE T2,T1
	TDCALL D,<<FE,TTEXF>,<MC,MCEXF>>	;ENABLE XOFF RECOGNITION IN FE
;17 END ADDITION
	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)
	CALL TTNTYP		;SET TYPE DEPENDANT DATA
	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,TODCLK		;171 LAST TYPEIN IS NOW
	MOVEM T1,TTIDLE(T2)	;171 
	MOVE T1,T2		;RESTORE T1
	POP P,T2		;RESTORE T2
	RET
;TTNTYP - CALLED WHEN TTTYP IS CHANGED
; T2/ ADDRESS OF DYNAMIC DATA

TTNTYP::LOAD T1,TTTYP,(T2)
	LOAD T1,DPTB,(T1)	; GET PTR TO DISPLAY TABLE
	MOVE T3,DPYCAP(T1)	; GET TERMINAL CHARACTERISTICS
	MOVEM T3,TTCHAR(T2)	; STORE IN DYNAMIC DATA
	MOVE T4,DPYSIZ(T1)	; GET SCREEN SIZE
	TXNE T3,TC%WRP!TC%PRT	; IF A LUSING TERMINAL
	 SOJ T4,		; SUBTRACT ONE COL FOR WRAPCHAR
	MOVEM T4,TTSIZE(T2)	; AND KEEP IN DYNAMIC DATA
	CALL SETEOP		; SET MAX LINE INDICATOR
	MOVE T4,DPYPAD(T1)	; CHAR TO USE FOR PADDING
	STOR T4,TPDCH,(T2)
	SETZM TTTGV(T2)		; FOR NOW, JUST ZERO GRAPHICS VARIABLE
	RET

;SET MAX LINE VALUE DEPENDING ON TYPE OF EOP PROCESSING
;	T2/ PTR TO DYNAMIC DATA
;
SETEOP:	LOAD T3,TPLEN,(T2)	;GET PAGE LENGTH
	TMNN TMMVR,(T2)		;VERBOSE END OF PAGE?
	IFSKP.			;ADJUST MAX LINE COUNTER CORRECTLY
	  SUBI T3,2
	ELSE.
	  SUBI T3,1
	ENDIF.
	STOR T3,TTLMX,(T2)	;AND SET IT UP
	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::HRRZS T2		;BE SURE THAT
	 CAILE T2,NLINES	;LINE NUMBER IS IN ALLOWED RANGE
	  RET			;NO, RETURN UNSUCCESFULLY
	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
	SKIPLE T2,TTACTL(T2)	;ANY DATA BASE AT ALL?
	 IFSKP.
		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
	 ENDIF.
	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 ;3030 REPORT THAT WE HAVE 100 LOCKS
	SETZRO TTOVF,(T2)	;3030 SET US BACK TO ZERO LOCKS
	INCR TTLCK,(T2)		;3030 GIVE US ANOTHER LOCK, AND CONTINUE
	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(MONX05)		;NO FREE SPACE AVAILABLE

;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 (MONX05)		; NO FREE SPACE AVAILABLE

;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>,<ML,MLTDAS>,<CH,CVTDET>,<TV,TVTDET>>
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 (MONX05)	;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
	CAIE T1,TT.CVT		; CHAOS...
	CAIN T1,TT.NVT		; OR ARPA NVT?
	JRST R			; YES, DON'T DO THIS THEN
	CAIN T1,TT.TVT		;1010 How about TVT?
	 JRST R			;1010 Don't do it!
	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	(MONX05)	;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
	 IFNSK.
		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
	 ENDIF.
	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,.TTMRK		;A MARKER?
	JRST TTCBF8		;NO, KEEP FLUSHING
	SETZRO TTFLO,(T2)	;CLEAR FLUSH FLAG
	JRST TTCBF7		;DONE

TTCBF9:	NOSKD1
	CHNOFF DLSCHN		;TURN OFF CHANNEL ALSO
;3022	JN TTSAL,(T2),TTCBFX	; CHECK FOR SENDALL IN PROGRESS
;3022	CALL CLRSAL		; CLEAR IT
;3022 TTCBFX:	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>,<ML,MLCCOB>,<CH,NVTCOB>,<TV,TVTCOB>>
				;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
	TDCALL D,<<ML,MLCCIB>>
	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,.TTMRK	;YES, JUST PUT MARKER IN STREAM
	    CALL TCOUM
	    SETZ T1,
	    RETSKP		;SAY OUTBUF EMPTY
	  ENDIF.
	ENDIF.
	LOAD T1,TSALC,(T2)	;1027 Get number of bytes from TTMSG
	JN <TTSAL,TTOTP>,(T2),R	;1027 Not empty if TTMSG in progress
;1027	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,.TTMRK	;YES, JUST PUT MARKER IN OUTPUT STREAM
	  CALL TCOUM
	  RETSKP
	ENDIF.
	TDCALL D,<<NT,NVTDOB>,<ML,MLCDOB>,<CH,NVTDOB>,<TV,TVTDOB>>
	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:	TDCALL D,<<ML,MLTOBE>>	; Device dependent
	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,T1
;;;	TRNE T1,400000		;THIS BIT MUST BE ZERO
;;;	ITERR(DECRSV,<CALL ULKTTY>)	;NOT ZERO - ERROR RETURN
	XOR T1,TTFLGS(T2)	;FIND THE CHANGED BITS
	ANDX T1,TT%OSP+TT%WAK+TT%IGN+TT%ECO+TT%DAM ;CHANGE ONLY THESE BITS
	XORM T1,TTFLGS(T2)
	SKIPE CTRLOF		;NEW STYLE AND CHANGING OUTPUT SUPPRESS?
	TXNN T1,TT%OSP
	IFSKP. <
	  CALL SKCON		;SKIP IF CTRL-O NOT ENABLED
	  IFSKP. <
	  MOVEI T1,.TTMRK	;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

;TTRTMW - READ THE TERMINAL MODE WORD FOR THE RTMOD JSYS
;ACCEPTS IN:	T2/	ADDRESS OF DYNAMIC DATA (LOCKED)
;RETURNS:	+1:	ALWAYS,
;			T1/ DISPLAY MODE WORD

TTRTMW::MOVE T1,TTTMOD(T2)
	RET

;TTSTMW - SET THE DISPLAY MODE WORD FOR THE STMOD JSYS
;ACCEPTS IN:	T1/	DISPLAY MODE WORD
;		T2/	ADDRESS OF DYNAMIC AREA (LOCKED)
;RETURNS:	+1:	ALWAYS

TTSTMW::MOVEM T1,TTTMOD(T2)	;SET NEW MODE WORD
	TXNN T1,TM%ITP		;SEE IF ITP WANTED
	IFSKP.
	  MOVEI T1,TTIITP	;YES. GET INPUT PROCESSING ROUTINE
	  STOR T1,TIRUT,(T2)	;SAVE ADDRESS (WATCH IT, ONLY 18 BITS)
	ELSE.
	  SETZRO TIRUT,(T2)	;NO, FLUSH INPUT PROCESSING ROUTINE
	ENDIF.
	CALL SETEOP		;SET SCREEN SIZE FOR EOP PROCESSING
	RET

;TTRTCW - READ DISPLAY CAPABILITY WORD FOR THE RTCHR JSYS
;ACCEPTS IN:	T2/	ADDRESS OF DYNAMIC DATA (LOCKED)
;RETURNS:	+1:	ALWAYS,
;			T1/ DISPLAY CAPABILITY WORD

TTRTCW::MOVE T1,TTCHAR(T2)
	RET

;TTSTCW - SET DISPLAY CAPABILTY WORD FOR STCHR JSYS
;ACCEPTS IN:	T1/	NEW DISPLAY CAPABILITY WORD
;		T2/	ADDRESS OF DYNAMIC DATA (LOCKED)
;RETURNS:	+1	ALWAYS

TTSTCW::MOVEM T1,TTCHAR(T2)
	RET

; RTGRV - RETURN GRAPHICS VARIABLE
;
;ACCEPTS IN:	T1/	TERMINAL DESIGNATOR
;
;RETURNS:	+1	ALWAYS, GRAPHICS VARIABLE IN T2,
;				OR 0 IF NOT A TERMINAL
;
;RTGRV ERRORS:		TTYX01: Line is not active

.RTGRV::MCENT
	CALL CHKTTR
	 JRST [	XCTU [SETZM 2]
		JRST MRETN]
	CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 ITERR (TTYX01,<CALL ULKTTY>) ;NOT ACTIVE. FAILED
	CALL TTRTGV		;GET THE GOODS
	CALL ULKTTY		;ALLOW DEALLOCATION
	UMOVEM 1,2
	JRST MRETN

; STGRV - SET TERMINAL GRAPHICS VARIABLE
;
;ACCEPTS IN:	T1/	TERMINAL DESIGNATOR
;		T2/	NEW GRAPHICS VARIABLE
;
;RETURNS:	+1	ALWAYS
;
;STGRV ERRORS:		TTYX01: Line is not active
;			TTYX1:	Device is not a terminal

.STGRV::MCENT
	CALL CHKTTR
	 ITERR(TTYX1)
	CALL LCKTTY		;POINT TO DYNAMIC DATA, PREVENT DEALLOCATION
	 ITERR (TTYX01,<CALL ULKTTY>) ;NOT ACTIVE. FAILED
	UMOVE 1,2		;GET THE DESIRED ARG
	CALL TTSTGV		;SET IT
	CALL ULKTTY		;ALLOW DEALLOCATION
	JRST MRETN


;TTSTGV - SET DISPLAY GRAPHICS VARIABLE FOR STGRV JSYS
;ACCEPTS IN:	T1/	NEW GRAPHICS VARIABLE
;		T2/	ADDRESS OF LOCKED DYNAMIC DATA
;RETURNS:	+1	ALWAYS

TTSTGV::MOVEM	T1,TTTGV(T2)
	RET

;TTRTGV - GET DISPLAY GRAPHICS VARIABLE FOR RTGRV JSYS
;ACCEPTS IN:	T2/	ADDRESS OF DYNAMIC DATA (LOCKED)
;RETURNS:	+1:	ALWAYS,
;			T1/ DISPLAY GRAPHICS VARIABLE

TTRTGV::MOVE T1,TTTGV(T2)
	RET
;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 T1,TTLPOS(T2)	;SET LINE CHARACTER POSITION
	MOVEM T1,TTPPOS(T2)	;PHYSICAL POSITION ALSO
	SETZRO TTCFU,(T2)	;KNOW CURSOR 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,TTSVT1>	;SAVE LINE NUMBER HERE, TEMP LOCATION
	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
	MOVEM T1,TTSVT1		;SAVE REG
	MOVE T1,TTSLIN		;GET LINE INDEX
	CAIGE T1,NTTFE		;SKIP CHECK IF NOT FE LINE
	 JRST [	MOVE T1,TTTYPS(T1)	;FE LINE. SEE IF LOCKED
		TXNN T1,SY%NSS
		JRST .+1	;NOT LOCKED. RETURN FROM LITERAL
		MOVE T1,CAPENB	;LOCKED. GET CAPS
		TXNE T1,SC%WHL!SC%OPR!SC%MNT!SC%CNF	;SEVERAL WILL WORK
		JRST .+1	;OK, GO DO IT
		RETSKP ]	;NO GOOD, DIE QUIETLY
	MOVE T1,TTSVT1		;GET REG BACK
	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>,<ML,RSKP>,<CH,RSKP>,<TV,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
	SETONE TTIPSI,(T1)	;SET NO PSI ---
	SETONE TTOPSI,(T1)	;INPUT OR OUTPUT ---
	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
	CALL SETEOP		;FIX UP END-OP-PAGE
	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
	TXNN T1,TT%WKP		;WANT PUNCTUATION?
	 IFSKP.
		TXO T3,MO%WP1
		TXO T4,MO%WP2
		TXO Q1,MO%WP3
		TXO Q2,MO%WP4
	 ENDIF.
	TXNN T1,TT%WKA		;WANT ALPHANUMERICS?
	 IFSKP.
		TXO T3,MO%WA1
		TXO T4,MO%WA2
		TXO Q1,MO%WA3
		TXO Q2,MO%WA4
	 ENDIF.
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
	  MOVE D,CTRLTT		;--- MAYBE LOGGED INTO CTY?
	  CAMN D,CTYLNO		;---
	  SETOM TTCAPF		;--- YEP, TURN CAPS BACK ON
	  JFCL			;--- DON'T BREAK THE WEIRD MACRO...
	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>,<ML,TTMSML>,<CH,TTMSCH>,<TV,TVMSNT>> 
				;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>,<ML,TTMSML>,<CH,TTMSCH>,<TV,TVMSNT>>
	 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
;1026	  OKSKED
	  OKINT			;1026 This oughta work better
	  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:	SAVEAC <T1>
	MOVE T1,T2		; Save line number
	CALL STADY		;STILL ACTIVE?
	 RET			;NO, DONE
	JE TTSAL,(T2),R		;DONE IF NO LONGER DOING SENDALL
	JN TTSHU,(T1),[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:	CONI PI,CX		; Get current PI state
	PUSH	P,CX		; save
	PIOFF			; turn them off
	SETZRO <TSALC>,(T2)	;CLEAR SENDALL POINTER, COUNT
	SETZM TTSAL2(T2)
	SETZRO TTSAL,(T2)	;INDICATE NO LONGER DOING SENDALL
	POP P,CX		; Get old pi state
	ANDI CX,200		; Mask off right bit
	CONO PI,(CX)		; and restore
	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 <T1,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
	CAIL C,TSALCM		;less than max allowed?
	 RETBAD ENQX19		;no, don't allow it
	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,.TTMRK	;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
	MOVEI Q1,(T2)		;17 SAVE INTERNAL LINE NUMBER
	UMOVE T3,T2		;GET TERMINAL TYPE SPECIFIED
	TLZ T3,-1		;17 CLEAR OUT FLAGS FOR CHECK
	CAIL T3,0		;REASONABLE NUMBER?
	CAIL T3,NTTYPS
	ITERR (STYPX1)		;TERMINAL TYPE NOT IN RANGE
	CAIL Q1,NTTFE		;17 IF THIS ISN'T AN FE LINE,
	 JRST STTYP0		;17  SKIP THIS CHECK
	MOVE T1,TTTYPS(Q1)	;17 IT IS, PICK UP STATIC TYPE AND FLAGS
	TXNE T1,SY%NTS		;17 TYPE SETTING ALLOWED FOR THIS LINE?
	 JRST [	MOVE T1,CAPENB	;17 ONLY IF SOME CAPS ENABLED
		TXNN T1,SC%WHL!SC%OPR!SC%CNF!SC%MNT
		JRST .+1	;17 HAS SOME, GO ON
		JRST MRETN ]	;17 NOPE, BAIL OUT
STTYP0:	CALL LCKTTY		;GET DYNAMIC DATA AND PREVENT DEALLOCATION
;17	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
;17		ITERR (TTYX01)]
	 JRST STTYP2		;17 NOT ACTIVE, ONLY SET PERMANENT DATA
	STOR T3,TTTYP,(T2)	;STORE NEW TERMINAL TYPE
	CALL TTNTYP		;SET TYPE DEPENDANT PARAMETERS IN DYN DATA
	LOAD T3,TTTYP,(T2)	;GET TYPE BACK
	LDB T1,TTMBIT		;GET MECH BITS
	DPB T1,[POINT 3,TTFLGS(T2),3] ;PUT WHERE NOTICED
;17 BEGIN ADDITION
STTYP2:	UMOVE T1,T2		;PICK UP FLAGS,,TYPE
	TXNN T1,SY%PRM		;TRYING TO SET THE STATIC TYPE?
	 JRST STTYP3		;NO, GO ON
	MOVE T1,CAPENB		;YES, MAKE SURE CAN DO IT
	TXNN T1,SC%WHL!SC%OPR!SC%CNF!SC%MNT
	JRST [	CALL ULKTTY
		ITERR(CAPX1) ]	;NOPE.
	CAIL Q1,NTTFE		;IF NOT A FE LINE,
	 JRST STTYP3		; DON'T DO ANYTHING TO THE STATIC TABLE
	LOAD T1,TTSTY,(Q1)	;GET LINE TYPE FOR THIS ONE
	CAIE T1,TT.PTY		;PTY?
	 CAIN T1,TT.NVT		;OR NVT?
	 JRST STTYP3		;YES, NOTHING MORE TO DO THEN
	CAIE T1,TT.TVT		;1010 TVT?
	CAIN T1,TT.CVT		;158 OR IF CVT
	 JRST STTYP3		;158 DO NOTHING
	HRRM T3,TTTYPS(Q1)	;SET TYPE NOW
	UMOVE T1,T2		;GET BACK FLAGS
	ANDX T1,<SY%NTS!SY%NSS> ;CLEAR OUT ALL BUT WHAT WE KNOW AND LOVE
	IORM T1,TTTYPS(Q1)	; AND SET THEM IN ALSO
STTYP3:
;17 END ADDITION
	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 T2]	;NOT TTY, RETURN 0
		JRST MRETN]
	MOVEI Q1,(T2)		;17 SAVE INTERNAL LINE NUMER
	CALL LCKTTY		;POINT TO DYNAMIC DATA AND PREVENT DEALLOCATION
;17	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
;17		ITERR (TTYX01)]
	 JRST GTTYP3		;17 NOT ACTIVE, GET DEFAULT FOR ITS LINE TYPE
	LOAD T1,TTTYP,(T2)	;GET TERMINAL TYPE
	UMOVEM T1,T2
	LOAD T1,TTNIN,(T2)	;GET NUMBER OF INPUT BUFFERS
	LOAD T3,TTNOU,(T2)	;GET NUMBER OF OUTPUT BUFFERS
	HRLI T3,0(T1)		;COMBINE THEM FOR USER
	UMOVEM T3,T3
GTTYP2:	CALL ULKTTY		;17 ALLOW DEALLOCATION OF DYNAMIC DATA
	JRST MRETN

;17 BEGIN ADDITION

GTTYP3:	EXCH T2,Q1		;SWAP INT LINE NO WITH VALUE OF LCKTTY
	CALL GTYPPE		;GET TYPE FROM PERMANENT MATRIX
	UMOVEM T3,T2		;RETURN IT TO USER
	MOVEI T2,(Q1)		;RESTORE VALUE OF LCKTTY
	JRST GTTYP2		;GO ALLOW DEALLOCATION AND RETURN

	RESCD

;GET TERMINAL TYPE FROM PERMANENT DATA
; T2/ LINE NUMBER
; T3/ LINE TYPE (FOR GTYPP0)

GTYPPE:	LOAD T3,TTSTY,(T2)	;GET LINE TYPE FROM STATIC AREA
GTYPP0:	CAIN T3,TT.PTY		;A PTY?
	 JRST GTYPP1		;YES, RETURN SYSTEM DEFAULT
	CAIE T3,TT.CVT		;158 AN NVT?
	CAIN T3,TT.NVT		;...
	 JRST GTYPP2		;YES, RETURN NVT TERMINAL TYPE
	CAIN T3,TT.TVT		;1010 TVTT?
	 JRST GTYPP2		;1010 A kind of NVT
	LOAD T3,TTFEM,(T2)	;SEE IF LINE IS REMOTE
	JUMPN T3,GTYPP1		;IF SO, USE SYSTEM DEFAULT
	CAIL T2,NTTFE		;ELSE, IF OUT OF RANGE FOR FE LINES,
	 JRST GTYPP1		; USE SYSTEM DEFAULT
	HRRZ T3,TTTYPS(T2)	;PICK UP STATIC TABLE
	JUMPN T3,R		;RETURN IT IF IT IS THERE
GTYPP1:	SKIPA T3,NORMTY		;USE SYSTEM DEFAULT
GTYPP2:	 MOVEI T3,.TTNVT	;USE NVT TYPE FOR NETWORK TERMINALS
	RET

	SWAPCD
	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>,<CH,NVTPAR>,<TV,TVTPAR>>
	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
	SETZRO TLNCT,(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)
	CALL SETEOP		;FIX UP END-OF-PAGE SIZE
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
	 IFNSK.	 <
		CALL TLINK1	;CLEAR OBJECT TO REMOTE
		 JRST TLINK9	;FAILED. GO RETURN ERROR
	 >
	TXNE Q2,TL%EOR
	 IFNSK.  <
		CALL TLINK2	;SET OBJECT TO REMOTE
		 JRST TLINK9	;FAILED
	 >
	TXNE Q2,TL%ERO
	 IFNSK.  <
		CALL TLINK3	;SET REMOTE TO OBJECT
		 JRST TLINK9
	 >
	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 /]			;23
	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
	 SKIPA 2,[POINT 7,[ASCIZ /TTY/]]	;23 
	HRROI 2,[ASCIZ /, TTY/]	;23 
	XCTU [HRRZ 1,1]		;23 RESTORE OBJECT DESIGNATOR
	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>,<ML,MLCDE1>,<CH,NVTDTS>,<TV,TVTDTS>>
	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,T1		;TRANSPARENT TO ALL AC'S EXCEPT 3
	PUSH P,T4
	PUSH P,T3		;SAVE COUNT
	SETZ T1,
TTGTB1:	CHNOFF DLSCHN
	SOSGE TTFREC		;REDUCE FREE BUFFER COUNT
	JRST TTGTB3		;NONE LEFT
	HRRZ T3,@TTFREB		;GET BUFFER FROM LIST
	EXCH T3,TTFREB
	CHNON DLSCHN
	HRRZ T4,T1
	JUMPE T1,[MOVSI T1,0(T3) ;FIRST BUFFER, REMEMBER ITS ADDRESS
		JRST .+2]
	HRRZM T3,0(T4)		;CONC NEW BUFFER ONTO LIST
	HRRI T1,0(T3)
	SOSLE 0(P)		;GOT REQUESTED NUMBER OF BUFFERS?
	JRST TTGTB1		;NO
	HLRZ T3,T1		;ADDRESS OF FIRST BUFFER IN LIST
	HRRZ T4,T1		;ADDRESS OF LAST BUFFER IN LIST
	HRRZM T3,0(T4)		;MAKE LAST POINT TO FIRST
	ADD T3,[XWD 441100,1]	;CONSTRUCT 9-BIT BYTE POINTER
	AOS -3(P)		;GIVE GOOD RETURN
TTGTB2:	ADJSP P,-1		;JUNK
	POP P,T4
	POP P,T1
	RET

TTGTB3:	BUG(TTYNTB)
	AOS TTFREC		;GIVE BACK FRUITLESS SOS
	CHNON DLSCHN		;RESTORE THE CHANNEL
	HRRZ T4,T1
	JUMPE T1,TTGTB2		;RETURN IF THERE WERE NONE
	HLRZ T3,T1		;COMPLETE THE ONES WE GOT
	HRRZM T3,0(T4)
	ADD T3,[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,VTOBEL)		; 7 ^G

	CH(1,FC,VTOBSP)		; 10 ^H BACKSPACE
	CH(0,PC,VTOTAB)		; 11 ^I TAB
	CH(0,FC,VTOLFD)		; 12 ^J LF
	CH(1,CT)		; 13 ^K
	CH(0,FC,VTOFFD)		; 14 ^L FORMFEED
;3053	CH(1,FC,VTOCRT)		; 15 ^M CR	
	CH(1,FC,VTOCR1)		;3053 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,CT,VTOESC)		; 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 VTSOP JSYS

; Do display dependent operation
; Call:  1/ terminal designator	
;	 2/ Flags,,.VT code
; 	 3/ Optional argument (function dependent)
;	 4/ Optional argument (function dependent)
;	VTSOP
; Returns
;	+1	always
; Errors
;	VTSX01	Invaild function code
;	VTSX02	Terminal cannot perform function
;	VTSX03	Required argument not supplied
;	TTYX01	Line is not active
; 	and some other errors (see SOUT, ie)

.VTSOP::MCENT
	CAIN 1,.NULIO		;NUL DESIGNATOR?
	JRST MRETN		;YES, ALLOW IT
	CALL CHKTTY
	 EMRETN ()		;NOT A TTY, GIVE ERROR RETURN
	CALL LCKTTY		;POINT TO DYNAMIC DATA AND PREVENT DEALLOCATION
	 JRST [	CALL ULKTTY	;NOT ACTIVE. ALLOW DEALLOCATION
		ITERR (TTYX01)]
	MOVE T3,TTLINK(T2)	; PROCESS LINKS, IF ANY
	CAME T3,[-1]
	 CALL VTSOP1		; DO LINKS
	CALL VTSOP5		; DO ORIGINAL LINE
	CALL ULKTTY
	JRST MRETN

VTSOP1:	PUSH P,T2		; SAVE ORIGINAL LINE
;;;	SETOM LINKF		;3004
VTSOP0:	SETZ T2,		; GET NEXT FIELD OF LINK WORD
	LSHC T2,^D9
	CAIN T2,777		; ANYTHING?
	 JRST VTSOP4		; NO
	CALL LCKTTY		; YES, GO DO IT
	 JRST [	CALL ULKTTY
		JRST VTSOP4 ]
	PUSH P,T3
	SETONE TTLNC,(T2)	;3004 DOING LINKED OPERATION
	CALL VTSOP5		; DO THE LINE
	SETZRO TTLNC,(T2)	;3004 FINISHED LINKED OPERATION
	CALL ULKTTY
	POP P,T3
VTSOP4:	JUMPN T3,VTSOP0
	POP P,T2		; RESTORE ORIGINAL LINE
;;;	SETZM LINKF		;3004
	RET

VTSOP5:	JE TTCRS,(T2),VTSOP6	; PENDING CR ON LINE?
	SETZRO TTCRS,(T2)	; YES, CLEAR IT
	CALL VTOCR1		; AND DO IT
VTSOP6:	UMOVE T1,T2		; GET FLAGS AND FUNCTION CODE
	HRRZ CX,T1		; GET FUNCTION CODE
	CAILE CX,VTSMAX
	 ITERR (VTSX01,<CALL ULKTTY>) ; CODE OUT OF RANGE
	TXNN T1,DP%AG1		; FIRST ARG SPECIFIED?
	 SKIPA T3,[1]		; NO, SET TO 1 FOR CONVENIENCE
	 UMOVE T3,T3		; GET ARGS
	UMOVE T4,T4
	CALLRET @VTSTAB(CX)	; DISPATCH TO HANDLER
	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,TCOB		;GO DO BINARY MODE
	ANDI T1,177		;T1/ CHARACTER IN 7 BITS
	MOVE T4,TTFLG1(T2)	;GET TERMINAL MODE FLAGS
	TXNN T4,TT%CFU!TT%VTA!TT%VTF	;ANYTHING SPECIAL?
	 JRST TCO1		;NO, HANDLE NORMALLY
	TXNE T4,TT%CFU		;CONFUSED?
	 CALL UNCONF		;FIX IT
	TXNE T4,TT%VTA		;ARGUMENT TO VTS FUNCTION
	 JRST TCOARG		;GO GET IT
	TXNE T4,TT%VTF		;VTS FUNCTION CODE?
	 JRST TCOVTA		;YES, DISPATCH TO FUNCTION

; HERE IF NOT IN THE MIDDLE OF ^P CODE SEQUENCE
TCO1:	CAIE T1,VTCESC		;VTS ESCAPE CHARACTER
	 JRST TCO2		;NO, SKIP THIS
	MOVE T4,TTTMOD(T2)	;ARE WE PROCESSING ^P CODES?
	TXNN T4,TM%DPY
	JRST TCO2		;NOPE, TREAT NORMALLY
	CALL TTLNK3		;YES, SEND IT ON TO LINKED TERMINALS
	JE TTCRS,(T2),TCO11	;PENDING CR ON LINE?
	SETZRO TTCRS,(T2)	;YES, CLEAR IT
	CALL VTOCR1		;AND DO IT
TCO11:	SETONE TTVTF,(T2)	;FLAG NEXT CHAR AS VTS FUNCTION CODE
	RET			;POP OFF VTS ESCAPE AND EXIT

;HERE TO HANDLE NORMAL CHARACTERS
TCO2:	CAIN T3,.TTATE		;TRANSLATE ECHO ONLY?
	JRST TC1A		;YES, NO OUTPUT TRANSLATION
	JRST TC1AT		;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:	TMNN TTNXO,(T2)		;DOING PAGE STOP?
	 IFSKP. <SETZRO TLNCT,(T2)> ;YES. CLEAR LINE POSITION WITHIN PAGE
	ANDI T1,177		;T1/ CHARACTER IN 7 BITS
	CAIN T1,.CHDEL		;RUBOUT?
	JRST TC1C		;YES, DON'T ECHO
	MOVE T3,TTFLGS(T2)	;CHECK WHETHER WE SHOULD ECHO
	TXNE T3,TT%ECO		;ECHOING OFF...
	TXNE T3,TT%DUM		; OR NOT FULL DUPLEX?
	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 TC1AT		;YES. ECHO TRANSLATION REQUIRED
;TCO...
; ASCII OUTPUT MODE, BUT NO CONTROL CHAR TRANSLATION DESIRED

; NOW HERE'S A CUTE LITTLE CROCK...
; THIS MODE IS USED BY PA1050. THINGS GOING THROUGH HERE 
; WON'T GET CHANGED TO VTS OUTPUT SEQUENCES. BUT IF THEY
; WERE CONVERTED, ONE COULDN'T SEND RANDOM ^CHARS FROM -10
; PROGRAMS, WHICH BREAKS EVERYBODY'S (?) FORTRAN PLOTTER DRIVERS
; AND APL TEXT FORMATTERS.  SO... GUESS. IF THE TERMINAL IS USING 
; ITP, ASSUME IT MUST HAVE OUTPUT TRANSLATION TO WORK RIGHT, AND
; DO VTS OUTPUT TRANSLATION. IF NOT, DON'T. IF YOU HAVE A BETTER 
; IDEA, SPEAK UP...)

TC1A:	CALL TTLNK3		;DO LINKS
	MOVE T4,TTTMOD(T2)	;GET TERMINAL MODE WORD
	TXNE T4,TM%ITP		;RUNNING ITP
	JRST TC1B		;YES, CALL LEVEL 2 FOR VTS ACTION
	CALL TTCOHA		;NO, TRY TO ACCOUNT FOR CHAR'S FORMAT ACTION
	CALLRET TCOUT		;GO DO CHAR WITH PARITY

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

TC1AT:	CALL TTLNK3		;SEND THE CHARACTER TO LINKED LINES
	CAIL T1,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 T4,FCMOD2(T2)
	MOVE T3,FCMOD1(T2)	;GET MODE BITS
	ROTC T3,0(T1)
	ROTC T3,0(T1)

;DETERMINE ACTION ACCORDING TO CONTROL CHARACTER OUTPUT CONTROL BITS

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

;INDICATE CONTROL CHARACTER BY ^

TC1D:	ADDI T1,100		;CONVERT TO PRINTING EQUIV.
	PUSH P,T1
	MOVEI T1,TTCIND		;GET ^
	CALL TCOY		;PRINT INDICATOR
	POP P,T1		;GET BACK THE CHARACTER
	CALL TCOY		;OUTPUT THE CHARACTER
	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:	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::	SETONE TTCFU,(T2)	;LOSE CURSOR
	CALL TTLNK3		;17 HANDLE LINKS
	ANDI T1,377		;7 BITS OF CHARACTER + PARITY
	CALLRET TCOU1		;GO OUTPUT THE CHARACTER WITHOUT ADDING PARITY
; HANDLER FOR VTS FUNCTION CODE BYTE FROM TCO LEVEL AFTER VTCESC SEEN
;	JRST TCOVTA FROM ASCII TCO LEVEL WITH:
;		T1/ FUNCTION CODE BYTE
;		T2/ ADDRESS OF DYNAMIC DATA
;
; CODES WHICH ARE OUT OF RANGE CAUSE AN ILLEGAL FUNCTION I/O INTERRUPT

TCOVTA:	SETZRO TTVTF,(T2)	; NO LONGER EXPECTING FUNCTION CODE BYTE
	TRZ T1,40		; UPPERCASE BYTE
	CAIL T1,"A"		; CHECK RANGE
	 CAILE T1,"Z"
	  JRST TCOVTX		; OUT OF RANGE
	TRZ T1,100		; IN RANGE, ZERO BIAS IT
	CALL TTLNK3		; SEND VTS CODE TO LINKED TERMINALS
	CAIL T1,1		; RANGE-CHECK THIS FOR SAFETY'S SAKE
	 CAILE T1,"Z"-"A"+1	; IF OUT OF RANGE
	 JRST [	BUG(TTCVOR,<<T1,FUNC>>)	; COMPLAIN
		RET ]		;  AND SKIP IT
	SKIPN T4,VTPTAB-1(T1)	; GET TABLE ENTRY
	 JRST TCOVTX		; IF NOT DEFINED THEN ERROR
	TLNE T4,-1		; TAKES ARGS?
	 JRST TCOVTG		; YES
	SETZ T1,		; NO ARGS
	MOVEI T3,1		; DEFAULT COUNT
	CALLRET @T4		; DISPATCH TO ROUTINE

TCOVTX:	ITERR(VTSX01,<CALL ULKTTY>) ;VTS INVALID FUNCTION PSI

;GET ARGUMENT TO ^P CODE
;EXPECTS:	T1/ VTS FUNCTION BYTE
;		T2/ ADDRESS OF DYNAMIC AREA

TCOVTG:	STOR T1,TTCVT,(T2)	;SAVE CONTEXT FOR TCOARG
	SETONE TTVTA,(T2)	;FLAG WAITING FOR VTS ARGUMENT
	RET			;AND EXIT OUT OF TCO

;^P CODE ARG RECEIVED, DISPATCH TO CORRECT HANDLER
; EXPECTS:	T1/ DATA BYTE
;		T2/ ADDRESS OF DYNAMIC AREA

TCOARG:	SETZRO TTVTA,(T2)	; NO LONGER EXPECTING ARGUMENT
	CALL TTLNK3		; SEND ARGUMENT TO LINKED TERMINALS
	MOVEI T3,-10(T1)	; GET ARGUMENT IN THE RIGHT AC
	LOAD T1,TTCVT,(T2)	; GET BACK FUNCTION CODE CONTEXT
	TXO T1,DP%AG1		; SAY FUNCTION HAS ONE ARGUMENT
	HRR T1,VTPTAB-1(T1)
	CALLRET (T1)		; DISPATCH
	SUBTTL VTS FUNCTION HANDLERS

;EXECUTE FUNCTION REQUESTED BY VTSOP CALL OR ^P CODE
; IF THE TERMINAL CANNOT DO THE FUNCTION REQUESTED, 
;   CAUSE AN VTSX02 ERROR PSI
; REGISTERS FOR FOLLOWING ROUTINES:
;	T1/ FLAGS IN LH
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ ARGUMENT FOR FUNCTION (WILL CONTAIN 1 EVEN IF NO ARGS SET UP)
;	T4/ ARGUMENT FOR FUNCTION


;ADVANCE TO A NEW LINE IF NOT ALREADY ON ONE (ADV)
VTOADV:	PUSH P,P1		; GET A REGISTER
	MOVEI P1,-1(T3)		; SAVE ARG IN IT
	LOAD T1,TLHPS,(T2)	; GET HORIZONTAL POSITION
	JUMPE T1,VTOAD2		; IF ZERO START AT CURRENT LINE
VTOAD1:	CALL VTONL		; DO A NEWLINE
VTOAD2:	SOJGE P1,VTOAD1		; LOOP
	POP P,P1
	RET

;CURSOR FORWARD (FWD)
VTOFWD:	MOVE T4,TTCHAR(T2)	; SEE IF CAN DO CURSOR MOTION
	TXNN T4,TC%MOV
	 JRST VTOX14		; NOPE, DATA ERROR THEN.
	CALLRET VTOHWW		; DO MOVEMENT WITH WRAPPING

;CURSOR BACK (BCK)
VTOBCK:	MOVE T1,TTCHAR(T2)	; SEE IF CAN DO BACKSPACING
	TXNN T1,TC%BS!TC%MOV
	 JRST VTOX14		; NO, NOT MUCH WE CAN DO THEN
	MOVNS T3		; SET UP ARGUMENT
	CALLRET VTOHWW		; AND DO MOVEMENT WITH WRAPPING

;CURSOR UP (UP)
VTOUP:	MOVE T1,TTCHAR(T2)	; CHECK IF TERMINAL CAN DO CURSOR MOTION
	TXNN T1,TC%MOV
	 JRST VTOX14		; NO, DATA ERROR PSI THEN
	MOVNS T3		; SET UP ARGUMENT
	CALLRET VTOVWW		; AND DO MOVEMENT WITH WRAPPING

;CURSOR DOWN (DWN)
VTODWN:	CALLRET	VTOVWW		; DO MOVEMENT WITH WRAPPING

;HOME UP (HOM) - IGNORES ARGUMENT IN T3
VTOHOM: MOVE T1,TTCHAR(T2)	; CHECK IF CAN HOME
	TXNN T1,TC%HOM!TC%MOV
	 JRST VTOX14		; NOPE
	SETZM TTLPOS(T2)	; CLEAR HORIZONTAL AND VERTICAL POSITIONS
	SETZRO TLNCT,(T2)	; ZERO LINE COUNTER
	SETZRO <TTCFU,TTNAB>,(T2) ; NO LONGER CONFUSED (WON'T ALWAYS WORK)
	CALLRET VTUPD

;HOME DOWN (HMD) - IGNORES ARGUMENTS
VTOHMD: MOVE T1,TTCHAR(T2)	; POSSIBLE?
	TXNN T1,TC%MOV
	 JRST VTOX14		; NOPE
	LOAD T3,TPLEN,(T2)	; GET PAGE LENGTH
	SOJ T3,			; FIRST LINE IS 0
	HRLZM T3,TTLPOS(T2)	; GO TO START OF LAST LINE
	SETZRO <TTCFU,TTNAB>,(T2) ; NO LONGER CONFUSED (WON'T ALWAYS WORK)
	CALLRET VTUPD		; MOVE CURSOR
;CLEAR SCREEN (CLR) - IGNORES ARGUMENT IN T3
VTOCLR:	MOVE T1,TTCHAR(T2)	; SEE IF TERMINAL CAN CLEAR THE SCREEN
	TXNN T1,TC%CLR!TC%SCL
	 JRST VTOX14		; NOPE
	SETZM TTLPOS(T2)	; CLEAR HPOS AND VPOS
	SETZM TTPPOS(T2)
	SETZRO TLNCT,(T2)	; ZERO LINE COUNTER
	SETZRO <TTCFU,TTNAB>,(T2) ; NO LONGER CONFUSED
	MOVEI T1,DPYCLS		; DO TTY-DEPENDANT STUFF
	CALLRET VTOFUN

;CLEAR TO END OF WINDOW (CEW) - IGNORES ARGUMENT IN T3
VTOCEW:	MOVEI T1,DPYCES		; DPY CODE
	JRST VTOCL0		; TEST TCW AND DO TRANSLATION

;CLEAR TO END OF LINE (CEL) - IGNORES ARGUMENT IN T3
VTOCEL:	MOVEI T1,DPYCEL		; DPY CODE
VTOCL0:	MOVE T4,TTCHAR(T2)	; CAN WE DO THIS?
	TXNN T4,TC%SCL
	 JRST VTOX14		; NO
	CALLRET VTOFUN		; DO TRANSLATION

;ERASE (NEXT) CHARACTER (ERA) - IGNORES ARGUMENT IN T3
; +++ will lose in last column
VTOERA:	MOVE T1,TTCHAR(T2)	; MUST BE ABLE TO DO BS AT LEAST
	TXNN T1,TC%PRT		; PRINTER?
	TXNN T1,TC%MOV!TC%BS	; OR CAN'T BACK UP?
	  JRST VTOX14		; YES, CAN'T DO IT
VTOER2:	TXNE T1,TC%OVR		; OVERWRITER?
	 JRST VTOER1		; YES
	AOS TTPPOS(T2)		; PHYSICAL POSITION ADVANCED
	MOVEI T1," "		; SPACE
	CALL TCOUT		; OUTPUT IT
	CALLRET VTUPD		; PUT THE CURSOR BACK WHERE IT WAS

; HERE FOR OVERWRITING TERMINALS, MUST USE TTY-DEPENDANT CODES
VTOER1:	MOVEI T1,DPYERC		;ERASE CHAR FUNCTION
	CALLRET VTOFUN		;GO DO IT

;+++ rewrite this
;BACKSPACE AND ERASE CHARACTER (BEC)
VTOBEC:	MOVE T1,TTCHAR(T2)	; MUST BE ABLE TO DO BS AT LEAST
	TXNN T1,TC%MOV!TC%BS
	 JRST VTOX14
	TXNN T1,TC%SCL		; IF CAN'T CLEAR SELECTIVLY
	 JRST VTOBE1		; THEN DO IT SLOW WAY
;+++ RANGE CHECK HERE...WE WILL LOSE IF WRAP HAPPENS
	CALL VTOBCK		; MOVE BACK THE REQUISITE AMOUNT
	MOVEI T1,DPYCEL		; SEND OFF A CLEOL
	CALLRET VTOFUN

; HERE IF CAN'T USE CLEOL
VTOBE1:	PUSH P,P1		; GET A REGISTER
VTOBE2:	MOVEI T3,1
	CALL VTOBCK		; MOVE BACK
	CALL VTOERA		; ERASE THE CHARACTER WITHOUT MOVING CURSOR
	SOJG P1,VTOBE2		; LOOP
	POP P,P1
    	RET
; THESE ENTRIES ARE FROM ^P CODES ONLY

; INSERT LINE
VTOINL:	JRST VTOLID		; JOIN FUNCTION

; DELETE LINE
VTODLL:	SETO T3,
	TXO T1,DP%AG1		; THERE IS AN ARG
	JRST VTOLID		; JOIN FUNCTION

; INSERT CHAR
VTOINC:	JRST VTOCID		; JOIN FUNCTION

;DELETE CHAR
VTODLC:	SETO T3,		; MOVE LEFT ONE CHAR
	TXO T1,DP%AG1
	JRST VTOCID		; JOIN FUNCTION

;LINE INSERT/DELETE
VTOLID:	TXNN T1,DP%AG1		; ARG PRESENT?
	 MOVEI T3,1		; NO, USE DEFAULT OF ONE LINE
	PUSH P,T1		; GRAB A TEMP
	LOAD T1,TPLEN,(T2)	; LENGTH OF SCREEN
	JUMPL T3,[ MOVN T1,T1	; DELETE CASE, RANGE CHECKING
		   CAMGE T3,T1	; WITHIN SCREEN SIZE?
		    MOVE T3,T1	; NO, SET TO LIMIT
		   JRST VTOLIA]	; DONE		   
	CAMLE T3,T1		; DON'T SCROLL MORE LINES THAN SCREEN HAS
	 MOVE T3,T1		; USE LIMITING VALUE
VTOLIA:	POP P,T1		; RESTORE TEMP
	TXNE T1,DP%AG2
	 JRST VTOLI0
	LOAD T4,TPLEN,(T2)	; DEFAULT:
	SOJ T4,			; CURRENT YPOS,,SCRLEN-1
	LOAD T1,TLVPS,(T2)
	HRLI T4,(T1)
VTOLI0:	MOVE T1,TTCHAR(T2)	; HAVE TO HAVE PROPER CAPABILITY
	TXNN T1,TC%LID
	 JRST VTOX14
	LOAD T1,TTTYP,(T2)	; GET TERMINAL TABLE
	LOAD T1,DPTB,(T1)
	SKIPE DPYMVL(T1)	; DOES IT ACTUALLY HAVE SCROLL REGION?
	 JRST VTOLI1		; YES, USE THAT
	SAVEP
	MOVE P5,T1
	DMOVE P3,T3		; PUT ARGS IN SAFE PLACE
	MOVE P2,TTLPOS(T2)	; SAVE CURSOR POSITION FOR LATER RESTORE
	SKIPG P3		; IS COUNT NEGATIVE?
	 MOVSS P4		; YES, SWAP ARGS
	HRRZI T1,(P4)		; DO THE DELETE 
	LOAD T3,TPLEN,(T2)	; IF AT BOTTOM, WE CAN SKIP IT
	SUBI T3,(T1)	
	CAIN T3,1
	 JRST VTOLI2
	SKIPL P3		; GET THE CURSOR RIGHT
	 SUBI T1,-1(P3)
	HRLZM T1,TTLPOS(T2)
	CALL VTUPD
	MOVE T1,DPYDLL(P5)
	MOVM T3,P3
	CALL VTSOUR
VTOLI2:	HLRZ T1,P4		; NOW DO THE INSERT
	LOAD T3,TPLEN,(T2)	; IF AT BOTTOM, WE CAN SKIP IT
	SUBI T3,(T1)	
	CAIN T3,1
	 JRST VTOLI3
	SKIPG P3
	 ADDI T1,1(P3)		; GET THE CURSOR RIGHT
	HRLZM T1,TTLPOS(T2)
	CALL VTUPD
	MOVE T1,DPYINL(P5)
	MOVM T3,P3
	CALL VTSOUR
VTOLI3:	MOVEM P2,TTLPOS(T2)	; RESTORE OLD CURSOR POSITION
	CALLRET VTUPD		; GO DO ALL THIS STUFF

; DO A REAL REGION SCROLL
VTOLI1:	MOVE T1,DPYMVL(T1)
	CALL VTSOUT
	CALLRET VTUPD

;CHARACTER INSERT/DELETE
VTOCID:	TXNN T1,DP%AG1		; ARG PRESENT?
	 MOVEI T3,1		; NO, DEFAULT TO 1 CHAR
	TXNE T1,DP%AG2		; SECOND ARG PRESENT,
	 JRST VTOCI0
	LOAD T4,TPWID,(T2)	; CURRENT YPOS,,SCRLEN-1
	SOJ T4,
	LOAD T1,TLHPS,(T2)
	HRLI T4,(T1)
VTOCI0:	MOVE T1,TTCHAR(T2)	; HAVE TO HAVE PROPER CAPABILITY
	TXNN T1,TC%CID
	 JRST VTOX14
	LOAD T1,TTTYP,(T2)	; GET TERMINAL TABLE
	LOAD T1,DPTB,(T1)
	SAVEP
	MOVE P5,T1
	DMOVE P3,T3		; PUT ARGS IN SAFE PLACE
	MOVE P2,TTLPOS(T2)	; SAVE CURSOR POSITION FOR LATER RESTORE
	SKIPG P3		; IS COUNT NEGATIVE?
	 MOVSS P4		; YES, SWAP ARGS
	HRRZI T1,(P4)		; DO THE DELETE 
	LOAD T3,TPWID,(T2)	; IF AT END, WE CAN SKIP IT
	SUBI T3,(T1)	
	CAIN T3,1
	 JRST VTOCI2
	HRRM T1,TTLPOS(T2)	; GET THE CURSOR RIGHT
	CALL VTUPD
	MOVE T1,DPYDLC(P5)
	MOVM T3,P3
	CALL VTSOUR
VTOCI2:	HLRZ T1,P4		; NOW DO THE INSERT
	LOAD T3,TPWID,(T2)	; IF AT END, WE CAN SKIP IT
	SUBI T3,(T1)	
	CAIN T3,1
	 JRST VTOCI3
	HRRM T1,TTLPOS(T2)	; GET THE CURSOR RIGHT
	CALL VTUPD
	MOVE T1,DPYINC(P5)
	MOVM T3,P3
	CALL VTSOUR
	MOVEM P2,TTLPOS(T2)	; RESTORE OLD CURSOR POSITION
VTOCI3:	CALLRET VTUPD

;FORCE UPDATE
VTONOP:	CALLRET VTUPD

; VISIBLE BELL (VBL) - IGNORES ARG
VTOVBL:	MOVE T1,TTCHAR(T2)	; CAN DO IT?
	TXNN T1,TC%VBL
	 JRST VTOX14
VTOVB0:	CALL VTUPD		; MAY AS WELL HAVE CURSOR IN RIGHT PLACE
	MOVEI T1,DPYVBL
	CALLRET VTOFUN
;HORIZONTAL POSITION (HRZ)
VTOHRZ:	TXNN T1,DP%AG1		; ARGUMENT PRESENT?
	 ITERR(VTSX03,<CALL ULKTTY>) ; NO, LOSE
	MOVE T1,TTCHAR(T2)	; MAKE SURE WE CAN DO IT
	TXNN T1,TC%MOV
	 JRST VTOX14
; TAB JOINS HERE
VTOHR0:	LOAD T1,TPWID,(T2)	; MAX HPOS
	JUMPE T1,VTOHR1		; ZERO WIDTH-DON'T CHECK
	CAIG T1,(T3)
	 SOS T3,T1		; TRUNCATE
VTOHR1:	STOR T3,TLHPS,(T2)	; STORE NEW POSITION
	CALLRET VTUPD
	
;VERTICAL POSITION (VRT)
VTOVRT:	TXNN T1,DP%AG1		; ARGUMENT PRESENT?
	 ITERR(VTSX03,<CALL ULKTTY>) ; NO
	MOVE T1,TTCHAR(T2)	; MAKE SURE WE CAN DO IT
	TXNN T1,TC%MOV
	 JRST VTOX14
	LOAD T1,TPLEN,(T2)	; MAX VPOS
	JUMPE T1,VTOVR1
	CAIG T1,(T3)
	 SOS T3,T1		; TRUNCATE
VTOVR1:	STOR T3,TLVPS,(T2)	; STORE NEW VALUE
	CALLRET VTUPD

;ABSOLUTE CURSOR POSITION (MOV)
VTOMOV:	TXNN T1,DP%AG1		; ARGUMENT PRESENT?
	 ITERR(VTSX03,<CALL ULKTTY>) ; NO
	MOVE T1,TTCHAR(T2)	;SEE IF CAN DO CURSOR MOTION
	TXNN T1,TC%MOV
	 JRST VTOX14		;NO, NOT MUCH WE CAN DO THEN
	HRRZI T4,(T3)		; HPOS IN T4
	HLRZS T3		; VPOS IN T3
	LOAD T1,TPLEN,(T2)	; DO RANGE CHECKING AND TRUNCATE IF NECESSARY
	JUMPE T1,VTOMV1		; 0 WIDTH INHIBITS CHECKING
	CAIG T1,(T3)
	 SOS T3,T1		; TRUNCATE
VTOMV1:	LOAD T1,TPWID,(T2)
	JUMPE T1,VTOMV0		; SAME FOR LENGTH
	CAIG T1,(T4)
	 SOS T4,T1
VTOMV0:	HRLI T4,(T3)		; ASSEMBLE POSITION
	MOVEM T4,TTLPOS(T2)	;SAVE NEW CURSOR POSITION
	MOVEM T4,TTPPOS(T2)	;3056 WE ARE SETTING PHYS POSITION , TOO
	SETZRO <TTCFU,TTNAB>,(T2) ; NO LONGER CONFUSED (WON'T ALWAYS WORK)
;3056	CALLRET VTUPD		;
	MOVE T3,T4		;3056 ARG TO T3
	LOAD T4,TTTYP,(T2)	;3056 GET TTY TYPE
	LOAD T4,DPTB,(T4)	;3056 POINTER TO DISPLAY TABLE
	MOVE T1,DPYABS(T4)	;3056 ABSOLUTE CURSOR POSITIONER
	CALLRET VTSOUT		;3056 AND GO. (VTSOUT CHECKS FOR VALID ENTRY)
; CURSOR HORIZONTAL WITH WRAP
; EXPECTS:	T3/ + OR - COLUMNS TO CHANGE
; CLOBBERS T1,T3,T4
VTOHWW:	JUMPE T3,R		; HANDLE TRIVIAL CASE
	JUMPG T3,VTOHW0
VTOHW0:	LOAD T4,TLHPS,(T2)	; GET CURRENT HPOS
	ADDI T3,(T4)
	LOAD T4,TPWID,(T2)	; GET MAX HPOS
	JUMPE T4,VTOHW2		; WIDTH OF ZERO MEANS DON'T WRAP
	MOVEI T1,(T4)		; KEEP IT SAFE
	IDIVI T3,(T1)		; DIVIDE NEW HPOS BY IT
	JUMPGE T4,VTOHW1	; IF NEGATIVE REMAINDER
	SOJ T3,			; ADJUST VERTICAL CHANGE
	ADDI T4,(T1)		; AND MAKE HPOS POSITIVE
VTOHW1:	PUSH P,T4		
	CALL VTOVWW		; DO VERTICAL ADJUSTMENT
	POP P,T3
VTOHW2:	STOR T3,TLHPS,(T2)	; STORE NEW HPOS
	CALLRET VTUPD

; MOVE VERTICALLY WITH WRAP (NO MORE PROCESSING DONE)
; EXPECTS:	T3/ + OR - LINES TO CHANGE
; CLOBBERS:	T1,T3,T4
VTOVWW:	JUMPE T3,R		; HANDLE TRIVIAL CASE
	LOAD T4,TLNCT,(T2)	; ADJUST LINE COUNTER
	ADD T4,T3
	SKIPL T4		; DON'T STORE NEGATIVE LINE COUNTER
	 STOR T4,TLNCT,(T2)
	LOAD T4,TLVPS,(T2)	; GET CURRENT VPOS
	ADD T3,T4		; MAKE NEW ONE
	LOAD T4,TPLEN,(T2)	; GET MAX VPOS+1
	JUMPE T4,VTOVW1		; 0 MEANS NO WRAP
	MOVEI T1,(T4)		; KEEP IT SAFE
	IDIVI T3,(T1)		; GET REMAINDER
	SKIPGE T4		; MAKE IT POSITIVE
	 ADDI T4,(T1)
	MOVEI T3,(T4)
VTOVW1:	STOR T3,TLVPS,(T2)	; STORE NEW VERTICAL POSITION
	CALLRET VTUPD

;SEND THE ESCAPE CHARACTER (ESC)
VTOSEC:	PUSH P,P1		;SAVE A SAFE REGISTER
	MOVEI P1,(T3)		;ITERATION COUNT
VTOSE1:	MOVEI T1,VTCESC		;GET THE ESCAPE CHARACTER
	CALL TCOUT		;AND OUTPUT IT
	SOJG P1,VTOSE1		;ITERATE DESIRED NUMBER OF TIMES
	POP P,P1		;RESTORE SAVED REGISTER
	RET			;EXIT BACK TO VTO

;RESTORE CURSOR POSITION (RES) - IGNORES ARGUMENT IN T3
VTORES:	MOVX T1,DP%AG1		;FLAG SAYING ARGUMENT PRESENT
	MOVE T3,TTSCPS(T2)	;GET SAVED CURSOR POSITION
	CALLRET VTOMOV		;AND GO TO SAVED CURSOR POSITION

;SAVE CURSOR POSITION (SAV) - IGNORES ARGUMENT IN T3
VTOSAV:	MOVE T1,TTLPOS(T2)	;CURRENT CURSOR POSITION
	MOVEM T1,TTSCPS(T2)	;SAVE IT
	RET

; NOT CAPABLE OF OPERATION, LOSE
VTOX14:	SKIPN INSKED		; IN SCHEDULER?
;;;;	SKIPE LINKF		;3004 
	TMNE TTLNC,(T2)		;3004 OR LINKED TO SOME OTHER TURKEY?
	 RET			; YES, JUST FORGET IT
	ITERR(VTSX02,<CALL ULKTTY>) ; NO, GIVE A PSI

; SKIP IF RANDOM CURSOR MOTION POSSIBLE
CANMOV:	MOVE T3,TTCHAR(T2)
	TXNE T3,TC%MOV
	AOS 0(P)
	RET
	SUBTTL VTS TABLE TRANSLATION ROUTINES

;EXECUTE TTY-DEPENDANT DISPLAY FUNCTION
;  CALL WITH:	T1/ DESIRED DPY CODE
;		T2/ DYNAMIC DATA PTR
;
VTOFUN:	LOAD T3,TTTYP,(T2)	; GET TERMINAL TYPE
	LOAD T3,DPTB,(T3)	; GET TABLE
	ADDI T1,(T3)
	MOVE T1,(T1)		; GET ENTRY
	CALLRET VTSOUT

; OUTPUT PER-TERMINAL CODES WITH A REPEAT COUNT.
; EXPECTS:	T1/ DPY TABLE ENTRY
;		T2/ POINTER TO DYNAMIC DATA
;		T3/ COUNT
;		T4/ OPTIONAL ADDITIONAL ARGS
; PRESERVES:	T4
VTSOUR:	JUMPE T3,R		; HANDLE TRIVIAL CASE RIGHT AWAY
	SAVEQ
	TXNN T1,DPTBB		; IF A ROUTINE
	 TXNN T1,DPTBP		; IS IT PARAMETERIZED?
	 CAIA
	 JRST VTSOU1		; YES
	PUSH P,P1		; NO, LOOP ON IT.  BUM COUNT REGISTER
	PUSH P,T1		; SAVE CODE
	SKIPA P1,T3
VTSOUL:	 MOVE T1,(P)
	CALL VTSOU0
	SOJG P1,VTSOUL
	POP P,T1
	POP P,P1
	RET

; OUTPUT THE PER TERMINAL DISPLAY CODES FOR THE SPECIFIED FUNCTION
; EXPECTS:	T1/ DPY TABLE ENTRY
;		T2/ DYNAMIC DATA AREA
;		T3,T4/ ARGS
VTSOUT:	SAVEQ
VTSOU0:	TXNE T1,DPTBB		; IMMEDIATE STRING?
	 JRST VTSOUB		; YES
	TXNE T1,DPTBS		; PTR TO STRING?
	 JRST VTSOUS		; YES
	TXNN T1,DPTBR		; ROUTINE?
	 JRST [	BUG(VTSOUX,<<T1,D>>) ; NO, INVALID ENTRY
		RET ]		; EXIT GIVING ERROR
VTSOU1:	HRRZS T1
	DMOVE Q1,T3		; PUT ARGS IN QREGS
	CALLRET (T1)

; HERE FOR IMMEDIATE STRING
VTSOUB:	MOVE Q1,[POINT 7,Q2,0]
	MOVE Q2,T1		; COUNTER
VTSOB1:	ILDB T1,Q1
	JUMPE T1,VTSOB2		; ZERO TERMINATES
	CALL TCOUT
	HRRZI T3,Q1		; CHECK FOR END
	CAIE T3,Q2+1		
	 JRST VTSOB1
VTSOB2:	RET	

; HERE FOR LONGER STRING
VTSOUS:	MOVE Q1,T1		; MAKE BYTE PTR
	TLZ Q1,770077
	TLO Q1,440000
VTSOS1:	ILDB T1,Q1
	JUMPE T1,R		; ZERO TERMINATES
	CALL TCOU1		; MAY BE 8-BIT STRING
	JRST VTSOS1

; STRING POINTED TO BY T3
VTSSTR::TLC T3,-1		; FIX UP -1 POINTER
	TLCN T3,-1
	 HRLI T3,440700
	PUSH P,T3
VTSST1:	ILDB T1,(P)
	JUMPE T1,[ADJSP P,-1
		  RET]
	CALL TCOUT
	JRST VTSST1
	SUBTTL UTILITY ROUTINES FOR TERMINAL-DEPENDANT CODE

; SEND CHARACTER IN T3.

VTSCHR::MOVE T1,T3
	CALLRET	TCOU1		;3006

; SEND OFF CHARACTER IN T3 PREFACED BY ESCAPE
VTSESC::MOVEI T1,.CHESC
	PUSH P,T3
	CALL TCOUT
	POP P,T1
	CALLRET TCOUT

; SEND T3 AS DECIMAL NUMBER (0-99)
VTSDEC::IDIVI T3,^D10
	JUMPE T3,VTSDE1
	PUSH P,T4
	ADDI T3,"0"
	MOVEI T1,(T3)
	CALL TCOUT
	POP P,T4
VTSDE1:	ADDI T4,"0"
	MOVEI T1,(T4)
	CALLRET TCOUT

; INFORM OF NEW PHYSICAL CURSOR POSITION (IN T3)
VTSPOS::MOVEM T3,TTPPOS(T2)
	RET

; PAD (T3) MSEC
VTSPAD::TRZE T3,777400		; EIGHT BITS?
	 BUG(VTSTMP,<<T3,D>>)	; GACK, BIGGER THAN .25 SECONDS!
	CALL TNCPAD		; CONVERT TO CHARS
	PUSH P,P1		; GET A REGISTER
	MOVEI P1,(T3)
VTSPA1:	LOAD T1,TPDCH,(T2)	; GET PAD CHAR FOR THIS TTY
	CALL TCOUT
	SOJG P1,VTSPA1
	POP P,P1
	RET

; CONVERT TIME IN MSEC IN T3 TO CHARS
TNCPAD:	LOAD T1,TINTL,(T2)	; GET OUTPUT SPEED
	HRRZ T1,TTSPWD(T1)
	CAIN T1,-1		; IF UNKNOWN
	 MOVEI T1,^D9600	; ASSUME 9600
	IMULI T3,(T1)		; COMPUTE BYTES NEEDED
	ADDI T3,^D9999		; ROUND UP ALWAYS
	IDIVI T3,^D10000
	RET
	SUBTTL CURSOR UPDATING ROUTINE
;UPDATE TTY CURSOR TO MATCH CURRENT LOGICAL POSITION
;
; CALL:		VTUPD	IF NOT SURE IF CURSOR NEEDS UPDATING
;		VTUP0	IF SURE
; EXPECTS:	T2/ DYNAMIC DATA ADDRESS
;
; METHOD CODES
CU.REL==0			;USE RELATIVE POSITIONING
CU.ABS==1			;USE ABSOLUTE POSITIONING
;
; FLAGS USED IN F
CU%ABS==1B0			; ABSOLUTE POS POSSIBLE (NCHARS IN Q2)
 CU%HOM==1B1			; USE HOME
CU%REL==1B2			; RELATIVE POSITIONING POSSIBLE
 CU%CR==1B3			; USE CR
 CU%TAB==1B4			; USE TAB(S)
 CU%UP==1B5			; USE UP
 CU%DWN==1B6			; USE DOWN
 CU%FWD==1B7			; USE FORWARD
 CU%BCK==1B8			; USE BACK
 CU%HOR==CU%BCK!CU%FWD!CU%CR!CU%TAB ; ALL RELATIVE HORIZONTAL MODES
 CU%VRT==CU%UP!CU%DWN		; ALL RELATIVE VERTICAL MODES

VTUPD:	MOVE T1,TTPPOS(T2)	; GET PHYSICAL CURSOR POSITION
	CAME T1,TTLPOS(T2)	; SAME AS VIRTUAL POSITION?
	JRST VTUP0		; NOPE, GO UPDATE
	RET

VTUP0:	
	TRVAR <SAVP1,PHPOS,PVPOS,LHPOS,LVPOS,<OMETH,2>>
	MOVEM P1,SAVP1
	LOAD P1,TTTYP,(T2)	; GET TERMINAL TYPE
	LOAD P1,DPTB,(P1)	; GET POINTER TO DPY TABLE
	SETZB F,Q2		; CLEAR FLAGS
	LOAD T3,TPWID,(T2)
	MOVE T1,TTLPOS(T2)
	JUMPE T3,VTUP1		; JUMP IF NO WRAPAROUND
	CAIN T3,(T1)		; ADJUST FOR GHOST COLUMN
	SOJ T1,

; INITIALIZE LOCAL VARIABLES
VTUP1:	HRRZM T1,LHPOS		;LOGICAL HORIZ POSITION
	HLRZM T1,LVPOS		;LOGICAL PHYSICAL POSITION
	MOVE T1,TTPPOS(T2)	;GET PHYSICAL POSITIONS
	HRRZM T1,PHPOS		;PHYSICAL HORIZ POSITION
	HLRZM T1,PVPOS		;PHYSICAL VERTICAL POSITION
	SETZM CU.ABS+OMETH	;CLEAR CHAR COUNT FOR ABS POSITIONING
	SETZM CU.REL+OMETH	;CLEAR REL POS COUNT

; CHECK WHETHER THIS IS A REAL DISPLAY TERMINAL
; IF PRINTING OR GLASS TTY, GO HANDLE DIFFERENTLY

	MOVE T1,TTCHAR(T2)	; GET TERMINAL CHARACTERISITICS
	TXNN T1,TC%MOV		; CAN MOVE CURSOR?
	JRST VTUNMV		; NO, LOSER--GO HANDLE ELSEWHERE

; HERE IF TERMINAL IS A REAL DISPLAY
; EVALUATE RELATIVE CURSOR MOTION.  

	MOVE T3,LHPOS		; NEED HORIZONTAL MOTION
	CAMN T3,PHPOS		; YES
	JRST VTUERV		; NO, GO CHECK VERTICAL MOTION
	JUMPE T3,[SKIPN DPYCRT(P1) ;IF MOTION TO LEFT EDGE, TRY A <CR>
		  JRST .+1	; DON'T HAVE IT, CAN'T DO THIS
		  TXO F,CU%CR	; HAVE IT, CAN USE <CR>
		  MOVEI T3,1	; ONE CHAR
		  MOVEM T3,CU.REL+OMETH	;SAVE CHARACTER COUNT
		  JRST VTUERV]
	SUB T3,PHPOS		; NEW POSITION FORWARD OR BACK?
	JUMPG T3,VTUERF		; FORWARD
	SKIPN T1,DPYBCK(P1)	; BACK, CAN WE DO IT?
	JRST VTUABS		; NO, CAN'T DO RELATIVE CURSOR MOTION
	TXO F,CU%BCK		; YES, FLAG POSSIBLE
	MOVNS T3		; CONVERT TO POSITIVE REPEAT COUNT
	CALL VTUCNT		; COUNT THE NUMBER OF CHARACTERS 
	MOVEM T3,CU.REL+OMETH	; AND STORE 
	JRST VTUERV		; GO CHECK VERTICAL MOTION

; HERE TO EVALUATE RELATIVE FORWARD MOTION. (T3) IS COUNT 

VTUERF:	SKIPN T1,DPYFWD(P1)	; HAVE FORWARD MOTION?
	JRST VTUETB		; NO, MAYBE USE TABS?
	TXO F,CU%FWD		; YES, MARK AS POSSIBLE
	CALL VTUCNT		; COUNT THE NUMBER OF CHARACTERS 
	MOVEM T3,CU.REL+OMETH	; AND STORE

; HERE TO SEE IF TABS CAN BE USED

VTUETB:	CALL VTUTAB		; EVALUATE TABS
	JRST VTUNTB		; CAN'T USE THEM
	CAML T3,CU.REL+OMETH	; WINNING OVER JUST FORWARDS?
	JRST VTUERV		; NO, USE REGULAR FORWARD MOTION
	TXO F,CU%TAB		; YES, MARK SUCH
	MOVEM T3,CU.REL+OMETH	; SAVE CHARACTER COUNT FOR TABS
	JRST VTUERV		; GO CHECK VERTICAL MOTION

; TABS WON'T WORK	
VTUNTB:	SKIPN CU.REL+OMETH	; SEE IF REGULAR FORWARD WON
	JRST VTUABS		; NOPE, CAN'T USE RELATIVE MOTION
				; YEP, FALL THROUGH

; EVALUATE VERTICAL MOTION

VTUERV:	MOVE T3,LVPOS		; VERTICAL POSITION CHANGED?
	CAMN T3,PVPOS
	JRST VTUEV2		; NO VERTICAL MOVEMENT NEEDED
	SUB T3,PVPOS		; GET DIFFERENCE
	JUMPG T3,VTUERD		; DOWN
	SETZRO TTNAB,(T2)	; TIME TO NOT BE CONFUSED
	SKIPN T1,DPYUP(P1)	; UP
	JRST VTUABS		; CAN'T DO CURSOR UP, TRY ABSOLUTE CURPOS
	TXO F,CU%UP		; MARK POSSIBILITY
	MOVNS T3		; MAKE REPEAT COUNT
	JRST VTUEV1

; CURSOR DOWN (T3 HAS REPEAT COUNT)

VTUERD: SKIPN T1,DPYDWN(P1)	; HAVE CURSOR DOWN FUNCTION
	JRST VTUABS		; NO, TRY ABSOLUTE CURPOS
	TXO F,CU%DWN		; YES, MARK POSSIBLE
VTUEV1:	CALL VTUCNT		; COUNT THE NUMBER OF CHARACTERS IN P1 PER ITER
	ADDM T3,CU.REL+OMETH	; ADD TO TOTAL
VTUEV2:	TXO F,CU%REL		; SAY RELATIVE POSITIONING POSSIBLE
	MOVE T1,CU.REL+OMETH	; IF RELATIVE MOTION WILL TAKE 
	CAIG T1,3		;   3 OR LESS CHARS,
	JRST VTUDR		;   DO IT WITHOUT EVALUATING ABS

; HERE TO EVALUATE ABSOLUTE CURSOR POSITIONING

VTUABS:	JN TTNAB,(T2),VTUPCK	; DON'T USE ABSOLUTE IF NOT SURE OF CURSOR
	SKIPE TTLPOS(T2)	; HOME POSSIBLE?
	JRST VTUAB1		; NO
	SKIPN T1,DPYHOM(P1)	; HOME EXIST?
	JRST VTUAB1		; NO
	TXO F,CU%HOM		; YES, MARK IT
	JRST VTUAB2		; AND COMPUTE LENGTH

; NO HOME, USE ABSOLUTE POSITIONING

VTUAB1:	SKIPN T1,DPYABS(P1)	; HAVE ABS POS SEQUENCE?
	JRST VTUPCK		; NO ABSOLUTE POSITIONING
VTUAB2:	MOVEI T3,1		; ONLY ONCE, HOPEFULLY!
	CALL VTUCNT
	MOVEM T3,CU.ABS+OMETH	; NUMBER OF CHARS NEEDED FOR ABSOLUTE
	TXO F,CU%ABS		; MARK ABSOLUTE POSITIONING POSSIBLE

; DECIDE BETWEEN ABSOLUTE AND RELATIVE POSITIONING

VTUPCK:	TXNN F,CU%ABS		; ABSOLUTE POSSIBLE?
	JRST VTUPC1		; NO
	MOVE T1,CU.ABS+OMETH	; GET COUNT FOR ABS
	TXNE F,CU%REL		; RELATIVE POSSIBLE?
	CAMGE T1,CU.REL+OMETH	; YES, DOES IT DO LESS OUTPUT
	JRST VTUDAB		; NO OR NO, GO DO ABSOLUTE
	JRST VTUDR		; REL WINS, GO DO IT THAT WAY
	
; NO ABSOLUTE POSITIONING, VERIFY RELATIVE

VTUPC1:	TXNN F,CU%REL		; RELATIVE POSITIONING POSSIBLE?
	JRST VTUERR		; NO, WE'RE IN TROUBLE
				; YES, FALL THROUGH TO REL CODE

; HERE TO DO RELATIVE CURSOR POSITIONING

VTUDR:	TXNN F,CU%HOR		; ANY HORIZONTAL REQUIRED?
	JRST VTUDRV		; NOPE
	TXNN F,CU%CR		; YES--CR POSSIBLE?
	 IFSKP.
		MOVE T1,DPYCRT(P1) ; YES, SEND ONE
		CALL VTSOUT
		SETZM PHPOS
		SKIPE LHPOS	; THAT ALL?
		JRST VTUDRF	; NO, MOVE FORWARDS
		JRST VTUDRV 	; YES, CONTINUE TO VERTICAL
	 ENDIF.
	TXNN F,CU%BCK		; BACK?
	JRST VTUDRF		; NO, DO FORWARD
	MOVE T3,PHPOS		; YES, COMPUTE REPEAT COUNT
	SUB T3,LHPOS
	SKIPN T1,DPYBCK(P1)	; GET BACKWARD TABLE ENTRY
	JRST VTUERR		;  NOT THERE
	CALL VTSOUR		; MOVE BACKWARDS
	JRST VTUDRV		; GO CHECK VERTICAL

; DO FORWARD RELATIVE
VTUDRF:	TXNN F,CU%TAB		; TAB PICKED?
	JRST VTUDF1		; NO, DO STANDARD
	MOVE T3,LHPOS		; YES, COMPUTE HOW MANY
	MOVE T4,PHPOS
	LSHC T3,-3		; BUM!
	SUBI T3,(T4)
	MOVE T1,DPYTAB(P1)
	CALL VTSOUR
	MOVE T3,LHPOS		; GET POSITION BACK
	ANDI T3,7		; NUMBER OF FORWARD SPACES TO FINISH MOTION
	JRST VTUDF2		; AND GO DO REST OF MOTION

VTUDF1:	MOVE T3,LHPOS		; FIND NUMBER OF FORWARD SPACES TO DO
	SUB T3,PHPOS
VTUDF2:	SKIPN T1,DPYFWD(P1)	; GET FORWARD FUNCTION
	JRST VTUERR		; OOPS - NOT THERE
	CALL VTSOUR		; GO DO IT

; VERTICAL
VTUDRV:	TXNN F,CU%VRT		; ANY VERTICAL REQUIRED?
	JRST VTUDON		; NOPE
	TXNE F,CU%UP		; UP?
	 IFSKP.
		MOVE T3,LVPOS	; NO, DOWN THEN
		SUB T3,PVPOS	; GET COUNT
		SKIPN T1,DPYDWN(P1)	; GET FUNCTION
		JRST VTUERR	; FUNCTION NOT THERE
		JRST VTUDV1 	; GO DO IT
	 ENDIF.
	MOVE T3,PVPOS		; GOING UP, COMPUTE COUNT
	SUB T3,LVPOS
	SKIPN T1,DPYUP(P1)	; TABLE ENTRY
	JRST VTUERR		;  NOT PRESENT
VTUDV1:	CALL VTSOUR		; EXECUTE VERTICAL MOTION
	JRST VTUDON		; AND EXIT

; DO ABSOLUTE

VTUDAB: MOVE T3,TTLPOS(T2)	; SET UP ARG
	TXNE F,CU%HOM		; HOME POSSIBLE?
	SKIPA T1,DPYHOM(P1)	; YES, GET HOME FUNCTION
	MOVE T1,DPYABS(P1)	; NO, GET MOVE FUNCTION
	CALL VTSOUT
	JRST VTUDON

; HERE TO DO PROCESSING FOR NON-DISPLAY TERMINALS
; ORDER MUST BE CR, VERTICAL, HORIZONTAL TO LOOK RIGHT

VTUNMV:	SKIPN T3,LHPOS		; GET DESIRED HORIZONTAL POSITION
	JRST VTUNCR		; IF TO LEFT MARGIN USE CR
	CAML T3,PHPOS		; COMPARE WITH CURRENT H POS
	JRST VTUNVR		; FORWARDS, DO LATER

; HERE TO MOVE BACKWARD - COMPUTE BEST WAY

	SKIPN DPYBCK(P1)	; HAVE BACKSPACE?
	JRST VTUNCR		; NO, HAVE TO DO CR AND SPACES
	MOVE T1,TTCHAR(T2)	; IS THIS A PRINTER?
	TXNN T1,TC%PRT
	JRST VTUNVR		; NO, SO HAVE TO USE BACKSPACES

	MOVE T1,PHPOS		; COST BY BSP IS PHPOS-LHPOS
	SUBI T1,(T3)		; COST BY CR-SPACES IS LHPOS+1
	AOJ T3,
	CAILE T3,(T1)
	JRST VTUNVR		; NO CR NOW, DO VERTICAL

; DO A CR

VTUNCR:	SKIPN PHPOS		; GET CURRENT POSITION
	JRST VTUNVR		; ALREADY AT LEFT MARGIN, DON'T DO THIS
	SKIPN T1,DPYCRT(P1)	; GET <CR> ENTRY IF PRESENT 
	JRST VTUERR		; OOPS - NO FUNCTION
	CALL VTSOUT		; MOVE TO LEFT MARGIN
	SETZM PHPOS		; REMEMBER THAT WE'VE GONE BACK

; VERTICAL MOTION ON STUPID TERMINALS

VTUNVR:	MOVE T3,LVPOS		; GET DESIRED VERTICAL
	SUB T3,PVPOS		; CALCULATE DIFFERENCE
	SKIPGE T3		; BETTER BE DOWN - MAKE SURE
	SETZ T3,		; IF NOT, JUST IGNORE
	SKIPN T1,DPYDWN(P1)	; GET NEEDED SEQUENCE
	JRST VTUERR		; NO SEQUENCE, LOSE
	CALL VTSOUR		; MOVE CURSOR

; HORIZONTAL MOTION OTHER THAN CR

	MOVE T3,LHPOS		; SEE WHICH DIRECTION
	CAMGE T3,PHPOS
	JRST VTUNBB		; BACKWARDS
	CALL VTUTAB		; FORWARDS, EVALUATE TABS
	JRST VTUNDF		; NO TABS
	MOVE T1,LHPOS		; COMPUTE COST OF FORWARDS
	SUB T1,PHPOS
	EXCH T1,T3
	CAILE T1,(T3)		; WHICH IS BETTER?
	JRST VTUND1		; FORWARDS
	MOVE T3,LHPOS		; TABS, COMPUTE HOW MANY
	MOVE T4,PHPOS
	LSHC T3,-3		; BUM!
	SUBI T3,(T4)
	MOVE T1,DPYTAB(P1)	; DO SOME TABS
	CALL VTSOUR
	LSHC T3,3		; BRING LOW-ORDER BITS OF LHPOS BACK
	TRZ T3,7
	JRST VTUND1		; AND DO REST OF MOTION

; HERE TO MOVE FORWARD

VTUNDF:	MOVE T3,LHPOS		; CALCULATE DISTANCE TO MOVE
	SUB T3,PHPOS
VTUND1: SKIPN T1,DPYFWD(P1)	; TRY TO DO CURSOR FORWARD
	MOVE T1,DPYSPC		; IF NO FWDS, USE A SPACE
	CALL VTSOUR		; DO IT
	JRST VTUDON		; FINISHED, CLEAN UP

; GO BACKWARDS WITH BACKSPACES (A CLEVER IDEA...)

VTUNBB:	MOVE T3,PHPOS		; GET CURRENT POS
	SUB T3,LHPOS		; GET NUMBER OF SPACES TO DO
	SKIPN T1,DPYBCK(P1)	; ROUTINE TO DO IT
	JRST VTUERR		; OOPS, NOT THERE
	CALL VTSOUR		; DO IT

; HERE WHEN IT'S ALL DONE

VTUDON:	MOVE T3,TTLPOS(T2)	; UPDATE STORED PHYSICAL POSITION
	MOVEM T3,TTPPOS(T2)
VTUDO1:	MOVE P1,SAVP1		; RESTORE KLUDGE
	RET

; HERE WHEN WE COULDN'T UPDATE THE CURSOR CORRECTLY
; REALLY THIS OUGHTN'T EVER HAPPEN...

VTUERR: BUG(VTSUPF)		; OOPS. (HOW TO SAY WHY THIS LOST?)
	MOVE T3,TTPPOS(T2)	; GET CURRENT PHYSICAL CURSOR POSITION
	MOVEM T3,TTLPOS(T2)	; SAY THATS WHERE IT IS (YECCH)
	JRST VTUDON1		; EXIT
; SUBROUTINE TO EVALUATE TABS
; CALLED ONLY FROM VTUPD - EXPECTS A LOT OF THINGS TO BE SET UP
;
; RETURNS:	+1 CAN'T USE THEM
;		+2 COUNT IN T3

VTUTAB:	SKIPN T1,DPYTAB(P1)	; GOT TABS?
	RET			; NO
	MOVE T3,LHPOS		; YES--SEE IF THEY'LL WIN
	TRZ T3,7		; LAST TABPOS BEFORE WHERE WE WANT TO BE
	MOVNI T4,(T3)		; KEEP COPY
	SUB T3,PHPOS		; IS IT AFTER WHERE WE ARE NOW?
	JUMPL T3,R		; NO
	TRZE T3,7		; YES, SEE HOW MANY WE NEED
	ADDI T3,10
	LSH T3,-3		; THIS IS NOW # OF TABS
	CALL VTUCNT
	EXCH T3,T4		; COUNT # OF FWDS NEEDED TO GET THERE
	ADD T3,LHPOS		; THIS IS IT
	JUMPE T3,VTUTB1		; IF ZERO, NO TRUBBLE
	SKIPN T1,DPYFWD(P1)
	RET			; AFTER ALL THAT...
	CALL VTUCNT
VTUTB1:	ADDI T3,(T4)		; GET TOTAL COUNT
	RETSKP			; RETURN GOODNESS
; WE LOST TRACK OF CURSOR.  ATTEMPT A RECOVERY
; PRESERVES T1
UNCONF:	PUSH P,T1
	SETZRO TTCFU,(T2)	; NO LONGER QUITE AS CONFUSED
	MOVE CX,TTCHAR(T2)	; CAN TERMINAL SCROLL?
	TXNN CX,TC%SCR
	 JRST UNCON1
	SETZRO TLVPS,(T2)	; SHOW ME THE WAY TO GO HOME...
	SETZRO TPVPS,(T2)
	SETZRO TLNCT,(T2)	; LINE COUNTER ZERO
	MOVE T1,TTCHAR(T2)	; EXCPET ON PRINTERS
	TXNE T1,TC%PRT
	 JRST UNCON9
	SETONE TTNAB,(T2)	; AVOID ABSOLUTE CURSOR MOTION
UNCON9:	POP P,T1
	RET

; HERE IF TERMINAL CAN'T SCROLL
UNCON1:	TXNN CX,TC%MOV		; CAN WE AT LEAST MOVE?
	 JRST UNCON9		; NO, NOTHING MUCH WE CAN DO THEN
	CALL VTOHMD		; YES, HOME DOWN
	CALL VTUPD
	JRST UNCON9
REPEAT 0,<
; HANDLE ANY DEFERRED CLEOLS
TTUCEL:	JE TTCLP,(T2),R		; IF NOTHING PENDING, RETURN
	MOVEI T1,DPYCEL		; OTHERWISE DO IT
	CALL VTUOUF
	SETZRO TTCLP,(T2)	; AND CLEAR FLAG
	RET
>

;CALCULATE THE CHARACTER COUNT
;EXPECTS:	T1/ DISPLAY TABLE ENTRY
;		T3/ NUMBER OF ITERATIONS
;RETURNS:	+1  T3/ COUNT OF CHARACTERS IN ENTRY
; PRESERVES:	T4
;THIS IS OBSCURE TO SAVE TIME.
VTUCNT:	PUSH P,T4
	MOVE T4,T3
	TXNN T1,DPTBB		; IMMEDIATE BYTES?
	 JRST VTUCN0		; NO
	TXNE T1,177B<3*7>	; YES.  AT LEAST 3 BYTES?
	 IFNSK.
		MOVEI T3,3	; YES
		TXNN T1,177B<4*7> ; AT LEAST 4?
		 JRST VTUCN1	; NO.  IT'S 3
		MOVEI T3,4	; ASSUME 4 (MIGHT BE 5 BUT...)
		JRST VTUCN1
	 ENDIF.
	MOVEI T3,2		; LESS THAN 3.
	TXNN T1,177B<2*7>	; HOW ABOUT 2?
	  MOVEI T3,1		; IT'S 1
	JRST VTUCN1
VTUCN0:	LOAD T3,DPCNT,T1	; NOT IMMEDIATE.  GET SIZE.
	TXNN T1,DPTBP		; IS IT PARAMETERIZED?
VTUCN1:	 IMULI T3,(T4)		; NO, MULTIPLY
	POP P,T4
	RET
	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]
	SKIPN IMECHF		;IMMED ECHO CHAR?
	 IFSKP.
		MOVE T3,TTFLGS(T2) ;YES, CHECK DUPLEX BITS
		TXNN T3,TT%ECO	;IS ECHOING OFF?
		JRST TCOY3	;YES - THEN DON'T ECHO
;;;;		SKIPN LINKF	;LINKED CHAR? OR
		TMNN TTLNC,(T2)	;3004 LINKED CHARACTER
		TRCN T3,3B33	;FULL?
		 JRST TCOY.1
		CALL TTCOHA	;ACCOUNT SPACING FOR CHAR
		CAIGE T1,40	;IS CONTROL CHAR AND MODE 2?
		TRNN T3,3B33
REPEAT 0,<	JRST [	MOVE T3,TTLINK(T2) ;17 NO. GET LINK WORD
			CAME T3,[-1] ;ANY LINKS?
			CALL TTLNK3 ;YES. DO THEM
			...]
>				;17
		 JRST TCOY3	;17 AND DONE
		JRST TTCO1	;YES, ECHO CONTROL FN
	 ENDIF.
TCOY.1:

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

	CAIGE T1,40
	JRST TTCO1		;CONTROL GROUP

;NOT A CONTROL CHARACTER. RAISE IF NECESSARY

	JE TTCRS,(T2),TCOY1	;SAW A CR LAST TIME
	SETZRO TTCRS,(T2)	;YEP, HAVE TO REALLY DO IT
	CALL VTOCR1
TCOY1:	MOVE T3,TTFLGS(2)
	TXNE T3,TT%LCA		;TERMINAL HAS LOWER CASE?
	JRST TTCO6		;YES, NO TRANSLATION NEEDED
	CAIL T1,"A"		;UPPER CASE LETTER?
	CAILE T1,"Z"
	 IFNSK.
		CAIL T1,"A"+40	;NO, LOWER CASE LETTER?
		CAILE T1,"Z"+40
		JRST TTCO6	;NO
		SUBI T1,40	;YES, CONVERT TO UPPER CASE
		JRST TTCO6
	 ENDIF.

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

	TXNN T3,TT%UOC		;INDICATE?
	JRST TTCO6		;NO
	PUSH P,T1		;YES, SAVE CHAR
	MOVEI T1,TTLIND		;OUTPUT INDICATOR
	CALL TCOP
	POP P,T1
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:	HRRZ T3,TTLPOS(T2)	;GET CURRENT CHAR POSITION ON LINE
	LOAD T4,TPWID,(T2)	;GET RIGHT MARGIN
	JUMPE T4,TCOP0		;0 MEANS NEVER WRAP
	SUBI T4,1		;CORRECT FOR 0 ORIGIN
	CAIG T4,0(T3)		;CHECK FOR OVERFLOW
	 JRST TCOPWR		;YES, GO HANDLE LINE WRAPPING

; HERE IF NO WRAP OCCURS
TCOP0:	AOS TTLPOS(T2)		;UPDATE POSITIONS
	AOS TTPPOS(T2)
	JRST TCOUT		;AND CALL 3RD LEVEL TO PRINT CHAR

;HERE TO DO WRAPPING AT EOL
TCOPWR:	SUBI T4,(T3)		; REMEMBER POSITION
	MOVE T3,TTCHAR(T2)	; GET TERMINAL CHARACTERISTICS
	TXNE T3,TC%PRT!TC%WRP	; IF PRINTER OR AUTOWRAP
	 JRST TCOPWE		; HANDLE DIFFERENTLY
	JUMPN T4,TCOPW2		; WINNING DISPLAY, WRAP ON N+1TH CHAR
	STOR T1,TTLCH,(T2)	; SAVE THIS CHAR FOR POSSIBLE RETYPING
	AOS TTLPOS(T2)		; INCREMENT LOGICAL POSITION 
	JRST TCOUT

; OVERFLOW CHAR ON WINNING DISPLAY
TCOPW2:	PUSH P,T1
	MOVEI T1,WRPCHR		; OVERPRINT WRAPCHAR IN LAST COL
	CALL TCOUT
	CALL VTONL		; DOWN A LINE
	LOAD T1,TTLCH,(T2)	; GET BACK CHAR THAT WAS OVERSTRUCK
	CALL TCOUT
	MOVE T1,TTLPOS(T2)	; FIX CURSOR POSITION
	ADDI T1,2		; LAST CHAR FROM PREVIOUS LINE + THIS ONE
	MOVEM T1,TTLPOS(T2)
	MOVEM T1,TTPPOS(T2)
	POP P,T1		; ORIGINAL CHAR, REMEMBER ME?
	CALLRET TCOUT

; PRINTER/AUTOWRAP
TCOPWE:	PUSH P,T1
	MOVEI T1,WRPCHR
	CALL TCOUT
	CALL VTONL
	AOS TTLPOS(T2)
	AOS TTPPOS(T2)
	POP P,T1
	CALLRET TCOUT
;TTCOHA - ACCOUNT FOR SPACING DUE TO INPUT ON HALF-DUPLEX TERMINALS
;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:	CAIGE T1,40		;SPACING CHAR?
	IFSKP. <
		INCR TLHPS,(T2)	;YES. INCREMENT POSITION ON LINE
		INCR TPHPS,(T2)
		RET>
	CAIE T1,.CHCRT		;CR?
	IFSKP. <
		SETZRO TLHPS,(T2) ;YES. RESET TO LEFT MARGIN
		SETZRO TPHPS,(T2)
		RET>
	CAIE T1,.CHLFD		;LF?
	IFSKP. < 
		INCR TLNCT,(T2)	;LINE COUNTER
		CALLRET INCLIN>	;FIX CURSOR POSITION
	CAIE T1,.CHFFD		;FF?
	IFSKP. <
		SETZRO TLNCT,(T2) ;YES. RESET TO TOP OF PAGE
		RET>
	CAIE T1,.CHBSP		;BACKSPACE?
	RET			;NO
	JE TLHPS,(T2),R		;YES. IF NOT AT LEFT MARGIN,
	DECR TLHPS,(T2)		; DECREMENT CHARACTER POSITION WITHIN PAGE
	DECR TPHPS,(T2)
	RET

; INCREMENT CURSOR VERTICAL POSITION IF NOT AT BOTTOM OF SCREEN
INCLIN:	LOAD T3,TLVPS,(T2)
	LOAD T4,TPLEN,(T2)
	JUMPE T4,INCLI1		;0 MEANS INFINITE LENGTH (OVERFLOW?)
	SUBI T4,1		;ADJUST FOR 0 ORIGIN OF LVPS
	CAIL T3,(T4)		;ON LAST LINE OF SCREEN?
	RET			;YES
INCLI1:	INCR TLVPS,(T2)		;LOGICAL POSITION
	INCR TPVPS,(T2)		;AND PHYSICAL POSITION
	RET
	SUBTTL TCOY FOR CONTROL CHARACTERS

;HERE WHEN THE CHARACTER TO BE OUTPUT IS A CONTROL CHARACTER
; AND CHARACTER TRANSLATION IS ENABLED
;
;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:	CAIN T1,.CHLFD		;LINEFEED?
	JRST TTCO11		;YEP, FINE
	JE TTCRS,(T2),TTCO11	;NO, SEE IF HAVE SEEN A CR
	SETZRO TTCRS,(T2)	;YES, TURN OFF FLAG
	CALL VTOCR1		;AND REALLY DO IT

TTCO11:	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
	SUBTTL CONTROL CHARACTER OUTPUT ROUTINES

;ROUTINES CALLED FROM 2ND LEVEL (TCOY) FOR SOME CONTROL CHARACTERS
; ALL THESE HAVE TO BE ABLE TO WIN ON ALL SUPPORTED TERMINALS.

;LINE FEED
; ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1
;
; IF CCOC SEZ SIMULATE, DO CRLF.
; IF CCOC SEZ SEND, JUST DO LF
;
VTOLFD:	MOVE T4,TTFLG1(T2)	;GET STATUS FLAGS
	TXNN T4,TT%CRS		;LAST CHAR WAS CR...
	TXNE T3,<1B1>		;  NO, MAYBE WE'RE SIMULATING
	IFNSK. <
	   SETZRO TTCRS,(T2)
	   CALLRET VTONL	;YES OR YES, TREAT AS NEWLINE
	>
; HERE TO MOVE STRAIGHT DOWN
VTOLFA:	MOVE T1,TTTMOD(T2)	; GET MODE WORD
	MOVE T3,TTCHAR(T2)	;  AND CHARACTERISTICS
	TXNE T3,TC%SCR		; CAPABLE OF SCROLLING?
	 TXNN T1,TM%SCR		; IN SCROLL MODE?
	 JRST VTOLF4		; NO OR NO, WRAP
	LOAD T3,TPLEN,(T2)	; GET PAGE LENGTH
	JUMPE T3,VTOLF1		; NO CHECK IF LENGTH 0
	LOAD T3,TTLMX,(T2)	; GET EOP POSITION
	LOAD T1,TLNCT,(T2)	; GET LINE COUNTER
	CAIG T1,(T3)		; PAGE FULL?
	 JRST VTOLF1		; NO, SKIP THIS
	SETZRO TLNCT,(T2)	; YES, RESET COUNTER
	CALL TTXOFF		; AND STOP
VTOLF1: INCR TLNCT,(T2)		; COUNT THE NEW LINE
	LOAD T3,TTTYP,(T2)	; GET TERMINAL TYPE
	LOAD T3,DPTB,(T3)	; GET TABLE
	SKIPN T1,DPYDWN(T3)	; HAVE A DOWN FUNCTION?
	JRST VTOLF2		; NO, TRY ANOTHER WAY
	CALLRET VTSOUT		; YES, DO IT

VTOLF2:	LOAD T3,TPLEN,(T2)	; GET PAGE LENGTH
	LOAD T4,TLVPS,(T2)	; VERTICAL POSITION
	SUBI T3,1		; ADJUST LENGTH FOR 0 ORIGIN
	CAIL T4,(T3)		; ON LAST LINE?
	JRST VTOLF3		; YES, NEED TO BE TRICKY
	MOVEI T3,1		; NO, MOVE DOWN ONE LINE
	CALLRET VTOVWW		; BY USING VERTICAL WITH WRAP

; AT END OF PAGE, MUST FORCE SCROLL
VTOLF3: LOAD T3,TTTYP,(T2)	; GET TERMINAL TYPE
	LOAD T3,DPTB,(T3)	; GET TABLE
	MOVE T1,DPYNL(T3)	; DO A NEWLINE
	CALL VTSOUT		; YES, DO IT
	SETZRO TPHPS,(T2)	; REAL HORIZ POS IS 0, VPOS DOESN'T CHANGE
	CALLRET VTUPD		; PUT HORIZONTAL CURSOR BACK WHERE IT WAS

; WRAP MODE
VTOLF4:
	LOAD T1,TLVPS,(T2)	; GET CURRENT VERTICAL POSITION,
	LOAD T3,TTLMX,(T2)	;  ADJUSTED PAGE LENGTH,
	LOAD T4,TLNCT,(T2)	;   AND LINE COUNTER
	CAIGE T1,(T3)		; COMPARE V POS WITH LENGTH
	JRST VTOLF5		; NOT END OF SCREEN, JUMP
	CAILE T4,MORSAF		; END OF SCREEN. IS LINE COUNTER SMALL?
	CALL TTXOFF		; NO, STOP OUTPUT IF PAGE MODE
	MOVEI T3,1		; MOVE DOWN ONE LINE
	CALL VTOVWW		; VERTICAL WITH WRAP
	SETZRO TLNCT,(T2)	; I GUESS
	JRST VTOLF7		; GO CLEAR LINE AND EXIT

;WRAP MODE, NOT AT END OF SCREEN
VTOLF5:	CAIG T4,(T3)		; LINE COUNTER EXCEEDED?
	JRST VTOLF6		; NO, DON'T WORRY
	CALL TTXOFF		; YES, DO A MIDSCREEN STOP -YECCH
	MOVEI T1,MORSAF+1	; AND RIG LINE COUNTER TO DO IT AGAIN
	STOR T1,TLNCT,(T2)	; AT SCREEN BOTTOM
VTOLF6:	INCR TLNCT,(T2)		; INCREMENT LINE COUNTER
	MOVEI T3,1		; MOVE DOWN ONE LINE
	CALL VTOVWW		; VERTICAL WITH WRAP

;DONE WRAPPING, CLEAR NEW LINE IF POSSIBLE
VTOLF7:	MOVE T1,TTCHAR(T2)
	TXNN T1,TC%SCL
	 RET
	MOVEI T1,DPYCEL		; CLEAR OUT NEW LINE
	CALLRET VTOFUN
;DO A NEWLINE
;	T2/ ADDRESS OF DYNAMIC DATA
;	T4/ STATUS FLAG WORD - TTFLG1(T2)
;
;	TRASHES ALL BUT T2

VTONL:	MOVE T1,TTTMOD(T2)	;GET TERMINAL MODES
	MOVE T3,TTCHAR(T2)	;AND CHARACTERISTICS
	TXNE T3,TC%SCR		;CAN SCROLL...
	TXNN T1,TM%SCR		;AND WANTS TO?
	JRST VTONL2		;NO OR NO, WRAP
	LOAD T3,TPLEN,(T2)	;GET PAGE LENGTH
	JUMPE T3,VTONL1		;NO CHECK IF LENGTH 0
	LOAD T3,TTLMX,(T2)	;GET EOP POSITION
	LOAD T1,TLNCT,(T2)	;GET LINE COUNTER
	CAIG T1,(T3)		;PAGE FULL?
	JRST VTONL1		;NO
	SETZRO TLNCT,(T2)	;YES. RESET COUNTER
	CALL TTXOFF		;STOP IF IN PAGE MODE
VTONL1:	INCR TLNCT,(T2)		;COUNT THE NEWLINE
	CALLRET VTONLD		;GO DO NL

; WRAP MODE
VTONL2:	LOAD T1,TLVPS,(T2)	;GET VERTICAL POSITION,
	LOAD T3,TTLMX,(T2)	; ADJUSTED SCREEN LENGTH,
	LOAD T4,TLNCT,(T2)	; LINE COUNTER
	CAIGE T1,(T3)		;END OF SCREEN?
	JRST VTONL3		;NO
	CAIG T4,MORSAF		;HERE ON EOS. IS LINE COUNTER SMALL?
	IFSKP.
	  SETZRO TLNCT,(T2)	;NO, RESET COUNTER
	  CALL TTXOFF		;AND STOP
	ENDIF.	  
	SETZM TTLPOS(T2)	;CLEAR HORIZONTAL AND VERTICAL POSITIONS
	INCR TLNCT,(T2)		;COUNT LINE
	SETZRO <TTCFU,TTNAB>,(T2) ;NO LONGER CONFUSED (WON'T ALWAYS WORK)
	CALL VTUPD		;HOME CURSOR
	JRST VTONL5		;CLEAR LINE AND DONE

;WRAP MODE, NOT END OF SCREEN
VTONL3:	CAIG T4,(T3)		;TOO MANY LINES SINCE LAST STOP
	JRST VTONL4		;NO, DON'T WORRY
	CALL TTXOFF		;YES, DO A MIDSCREEN STOP (YEECH)
	MOVEI T1,MORSAF+1	;AND RIG LINE COUNTER TO DO IT AGAIN
	STOR T1,TLNCT,(T2)	;AT BOTTOM OF SCREEN
VTONL4:	INCR TLNCT,(T2)		;COUNT LINE
	CALL VTONLD		;MOVE CURSOR

;HERE TO CLEAR NEW LINE IF POSSIBLE, THEN EXIT
VTONL5: MOVE T1,TTCHAR(T2)
	TXNN T1,TC%SCL		;CAN WE DO IT
	RET			;NOPE
	MOVEI T1,DPYCEL		;CLEAR EOL FUNCTION
	CALLRET VTOFUN		;DO IT AND LEAVE

VTONLD:	LOAD T3,TTTYP,(T2)	;GET TERM TYPE
	LOAD T3,DPTB,(T3)	;GET DISPLAY TABLE
	SKIPN T1,DPYNL(T3)	;GET NEWLINE FUNCTION
	BUG(VTSMNL,<<T3,TYPE>>)	;MISSING???
	CALL VTSOUT		;DO IT
	SETZRO TLHPS,(T2)	;ZERO HORIZONTAL CURSOR POSITIONS
	SETZRO TPHPS,(T2)
	CALLRET INCLIN		;MAYBE INCREMENT CURSOR POS
	
;CARRIAGE RETURN

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

VTOCRT:	SETONE TTCRS,(T2)	;JUST REMEMBER WE SAW IT
	RET

; HERE IF WE EVER HAVE TO REALLY DO ONE
VTOCR1:	SAVEAC <T1,T2,T3,T4>
	SETZRO TLHPS,(T2)	; BACK TO LEFT MARGIN
	CALLRET VTUPD		; SO CR WILL ALWAYS BE DONE

;TAB

;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1
;
VTOTAB:	LOAD T3,TLHPS,(T2)
	TRZ T3,7		; ROUND UP TO NEXT MULTIPLE OF 8.
	ADDI T3,10
	CALLRET	VTOHR0		; AND HANDLE AS HORIZONTAL MOVE
 
; SPACE
VTOSPC:	MOVEI T1," "
	CALLRET TCOUT		;SEND A SPACE


;FORM FEED
; ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1
;
VTOFFD:	MOVEI T3,TTCHAR(T2) 
	TXNN T3,TC%CLR!TC%SCL	; CAN WE CLEAR SCREEN?
	 JRST VTOFF1		; NO, PROBABLY A PRINTING TERMINAL
	CALLRET	VTOCLR		; YES, CALL IT A FORMFEED

VTOFF1:	LOAD T4,TLNCT,(T2)	;GET PRESENT PAGE POSITION ---
	SETZRO TLNCT,(T2)	;RESET TO TOP OF PAGE
	PUSH P,T3		;SAVE CCOC BITS
	LOAD T3,TPLEN,(T2)	;PAGE SIZE
	JUMPE T3,[ SETZM Q1	;IF ZERO PAGE LENGTH, SAY AT THE END
		JRST VTOFF2]
	IDIVI T4,0(3)
	SUBM T3,Q1		;Q1/ DIFFERENCE TO END OF PAGE
VTOFF2:	POP P,T3
	MOVSI T4,(1B1)
	TDNE T4,TTFLGS(2)	;DEVICE HAS MECH FF?
	TLNE T3,(1B1)		;AND SEND DIRECT REQUESTED?
	JRST VTOFF3		;NO, SIMULATE FF
	CALL TCOUT		;SEND REAL CHARACTER
	JRST VTOFF5		; !!!NEED PADDING!!!

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

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

;ESC

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

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

;BACKSPACE
; DON'T WRAP BACK IF AT BEGINNING OF LINE
;ACCEPTS:
;	T1/ THE CHARACTER IN 7 BITS
;	T2/ ADDRESS OF DYNAMIC DATA
;	T3/ CONTROL CHARACTER OUTPUT CONTROL BITS IN BITS 0-1
;
VTOBSP:	MOVEI T3,1
	LOAD T1,TLHPS,(T2)	; IF AT BEGINNING OF LINE
	SKIPE T1		;  DON'T WRAP
	SOJ T1,
	STOR T1,TLHPS,(T2)
	CALLRET VTUPD		; BUT ALWAYS UPDATE CURSOR

; BELL
VTOBEL:	MOVE T1,TTTMOD(T2)	; MAYBE HE WANTS VISIBLE BELL
	TXNN T1,TM%VBL
	JRST VTOBL1		; GUESS NOT
	MOVE T1,TTCHAR(T2)	; HE DOES, IS IT POSSIBLE
	TXNN T1,TC%VBL
	JRST VTOBL1		; NO, GO BEEP
	MOVEI T1,DPYVBL		; YES, DO IT
	CALLRET VTOFUN
VTOBL1:	MOVEI T1,"G"-100	; SEND A NORMAL BEEP.
	CALLRET TCOUT
;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 T1,TT%PGM		;DISPLAY PROCESSING
	TMNE TTNXO,(T2)		;  AND DOING PAGE STOP?
	TDNN T1,TTFLGS(T2)	;IN PAGE MODE?
	RET			;NO, DO NOTHING
;;;	SKIPE LINKF		;OUTPUTTING TO LINKED TERMINAL?
	TMNE TTLNC,(T2)		;3004 OUTPUTTING TO LINKED TERMINAL
	RET			;YES, DON'T STOP
	TMNN TMMVR,(T2)		;GOING TO STOP. BE VERBOSE?
	IFSKP.
	  CALL TTXVMR		;YES, PRINT [More]
	ELSE.
	  CALL VTOBEL		;NO, OUTPUT BELL TO TELL USER
	ENDIF.
	MOVEI T1,.TTPFC		;PUT SPECIAL FUNCTION CODE IN OUTPUT
	CALLRET TCOUF		; STREAM TO STOP OUTPUT AT THAT POINT

; SEND A VERBOSE [MORE] INDICATION
;	T2/ DYNAMIC DATA
;
TTXVMR: CALL VTONLD		;YES. DO A NEWLINE
	MOVX T4,1B<.TICMR>	;3002 BIT FOR INTERRUPT ON PAGE-FLUSH
	TMNE TMMSM,(T2)		;3002 SKIP IF SMART MORE NOT REQUESTED
	TDNN T4,TTPSI(T2)	;3002 SKIP IF MORE INTERRUPT NOT ENABLED
	SKIPA T3,[POINT 7,[ASCIZ /  --Pause--/]] ;3002 IF NO FLUSHING
	MOVE T3,[POINT 7,[ASCIZ /  --More?--/]] ;3002 IF FLUSHING
TTXVM0:	ILDB T1,T3		;GET CHAR
	JUMPE T1,TTXVM1		;DONE
	PUSH P,T3		;SAVE BYTE PTR
	CALL TCOUT		;SEND THE CHAR
	POP P,T3		;GET PTR BACK
	JRST TTXVM0
TTXVM1:	RET
	SUBTTL TCOUT (THIRD LEVEL OUTPUT)

;OUTPUT ONE CHARACTER TO SPECIFIED TTY LINE
; SEVERAL ENTRY POINTS:
;	SCDTCO - PANIC INFO - SEND EVEN IF FLUSHING OUTPUT, ETC.
;	TCOUM - PUT "TURN OUTPUT ON" FUNCTION CODE IN OUTPUT STREAM - 
;			NOT TO PTY'S - IGNORE ^O ACTION - BINARY
;	TCOUF - PUT FUNCTION ESCAPE CODE IN OUTPUT STREAM -
;			NOT TO PTY'S - BINARY
;	TCOUT - REGULAR CHARACTER - ADD PARITY
;	TCOU1 - REGULAR CHARACTER - DON'T ADD PARITY
;
;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

;PUT FUNCTION ESCAPE CODE IN OUTPUT STREAM

TCOUF:	CALL CKPHYD		;PTY
	 RET			;YES, DO NOTHING
	JRST TCOU3		;GO DO IT

;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:
REPEAT 0,<			;17 BEGIN DELETION
	MOVE C,TTLINK(B)	;ANY LINKS?
	CAME C,[-1]
	CALL TTLNK3		;YES. GO DO THEM
>				;17 END DELETION
;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
	CALL NSKD1		;+++ 
	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
	 IFNSK.
		CALL OSKD1	;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
	 ENDIF.
	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?
	 IFNSK. <
		HRRZ T4,T3	;GET NEXT ONE
		HRR T3,1-TTSIZ(T4)
		MOVEM T3,TTOIN(T2) ;SAVE CHARACTER POINTER
	 >
	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
; CALLS THE ROUTINE THAT CALLED IT TO SEND CHAR TO LINKED TERMINALS
;
; CALL WITH	T1/ CHAR
;		T2/ DYN DATA OF OBJECT TTY
;
; RETURNS 	+1

TTLNK3:	MOVE T3,TTLINK(T2)	;17 GET LINK WORD FROM DYNAMIC AREA
	CAMN T3,[-1]		;17 ANY LINKS?
	 RET			;17 NO, NOTHING TO DO THEN
	SKIPN IMECHF		;17 ECHO CHARACTER?
	 IFSKP. <
		PUSH P,T2	;SAVE DYNAMIC DATA ADDRESS
		JRST TTLN33	; AND DON'T UNLOCK OBJECT TTY
	 >
	DYNST T4		;GET LINE NUMBER
	PUSH P,T4		;SAVE LINE NUMBER
	CALL ULKTTY		;UNLOCK OBJECT TTY FOR A WHILE
TTLN33:	;;;AOS LINKF		;3004 BE SURE CHARS GO OUT
TTLNK2:	SETZ T2,
	LSHC T2,^D9		;GET NEXT FIELD FROM T3
	CAIN 2,777
	JRST TTLNK1		;MEANS NOT IN USE
	PUSH P,T3		;SAVE LINK WORD
	PUSH P,T1		;SAVE CHARACTER
	CALL LCKTTY		;LOCK UP DESTINATION TTY - /T2 DYN DATA
	 JRST TTLNK4		;NOT ACTIVE. DON'T SEND TO IT
;;	TRNN T1,200		;THIS CHARACTER HAVE PARITY?
;;	JRST TTLK11		;NO. GO ON
;;	CALL SPARTY		;SET PARITY BIT
	SETONE TTLNC,(T2)	;3004 DOING LINKED CHARACTER
TTLK11:	CALL @-3(P)		;CALL WHOEVER CALLED US TO SEND CHAR
	SETZRO TTLNC,(T2)	;3004 NOT ANY MORE
TTLNK4:	CALL ULKTTY		;FREE UP THE TTY
	POP P,T1		;RETRIEVE CHAR
	POP P,T3		;RETRIEVE LINK WORD
TTLNK1:	JUMPN T3,TTLNK2		;DO MORE IF ANY
;;;	SOS LINKF		;3004 NO LONGER LINKING
	SKIPN IMECHF		;DOING ECHOING?
	 IFSKP. <
		POP P,T2	;YES. GET OBJ TTY DYN DATA BACK
		RET		;AND EXIT
	 >
	PUSH P,T1		;SAVE CHAR
	MOVE T2,-1(P)		;GET BACK LINE NUMBER
	CALL LCKTTY		;LOCK OBJECT TTY AGAIN
	 JUMPLE T2,[MOVE T2,-1(P) ;SOMEBODY PUNTED IT, GET LINE NUMBER AGAIN
		CALL TCOU7	;GET A SPECIAL BLOCK
		JRST .+1]	;AND PROCEED
	POP P,T1		;GET CHAR
	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
	CAMLE 1,TTOCT(2)	;AT OR BELOW WAKEUP LEVEL?
	JRST	[SETZRO TTBKO,(T2)	;NOTE WAIT COMPLETED
		JRST 1(4)		;YES
		]
  IFE .MLFLG,<
	JRST 0(4)
  >
  IFN .MLFLG,<
	CALL MLCCKT		;DYNAMIC IS IT MLC TYPE?
	 JRST 0(4)		;NO - STILL BLOCKED
	CALL MLCCKD		;YES- DYNAMIC IS IT MLC OPENED?
	 CAIA			;NO-BETTER LOSEN IT UP
	JRST 0(4)		;YES-NORMAL BLOCKING
	MOVE 1,TTOIN(2)		;MAKE IN AND OUT PTRS SAME
	MOVEM 1,TTOOUT(2)	;AS THOUGH DID OUTPUT
	SETZM TTOCT(2)		;HO,HO  NO MORE CHARS!
	JRST 1(4)		;MLC MAGIC WAKEUP
  >
;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
	TRNN T3,1		;TRANSLATING INPUT?
	JRST TCIB		;JUMP IF NOT
	LOAD T1,TYLCH,(T2)	;GET LAST CHARACTER TAKEN FROM INPUT BUFFER
	TMNN TTRFG,(T2)		;REPEAT LAST CHARACTER (BKJFN)?
	 IFSKP.
		SETZRO TTRFG,(T2) ;YES. CLEAR FLAG
		TXO T1,TTXECO	;INDICATE ALREADY ECHOED
		JRST TCI3
	 ENDIF.
	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 T1,177		;T1/ CHARACTER IN 7 BITS
	MOVE T3,TTFLGS(T2)	;T3/ TTFLGS FOR THIS LINE
	CAIE T1,.CHCRT		;A CR?
	 IFSKP.
		CALL TCIECO	;YES, ECHO CR-LF
		MOVEI T1,.CHLFD
		CALL TCIECO
		MOVEI T1,.CHCRT	;RETURN CR THIS TIME
		JRST TCIR
	 ENDIF.
	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::	TMNN TTRFG,(T2)		;REPEAT LAST CHARACTER?
	 IFSKP.
		SETZRO TTRFG,(T2) ;YES. CLEAR FLAG
		LOAD T1,TYLCH,(T2) ;GET LAST CHARACTER INPUT
		JRST TCIB1
	 ENDIF.
	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,T1		;+++ SAVE 1 FOR CALLER
	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
	POP P,T1		;+++
	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 TLNCT,(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,.TTMRK		;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/ INTERNAL 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/ ASCII CHARACTER + ECHO FLAG IN 9 BITS
; 		TIFCH(T2) SET TO FULL CHAR INPUT IF ITP IN USE
;
;CALLER MUST HAVE CALLED LCKTTY ON THE LINE. IF BLOCK ON INPUT
;WAIT OCCURS, THIS ROUTINE CALLS ULKTTY

TCI0:	MOVE T1,TTTMOD(T2)	; IS ITP IN USE
	TXNN T1,TM%ITP		;
	 JRST TCI00		; NO, HANDLE NORMALLY

; HERE TO GET ITP CHARACTER FROM LINE BUFFER. BUFFER CONTAINS
; CHARACTER IN 7 BITS, + 200 BIT SET IF CHAR IS A PREFIX

TCIIT0:	CALL TCI00		; GET A CHAR
	RETBAD			; NEED TO BLOCK
	JN TIHCP,(T2),TCIIT1	; PREVIOUS CHAR WAS PREFIX, ACT DIFFERENTLY
	TRZN T1,200		; IS THIS A PREFIX CHARACTER?
	JRST [	STOR T1,TIFCH,(T2) ;NO, JUST STORE CHAR
		RETSKP]
	SETONE TIHCP,(T2)	; YES, FLAG IN PREFIX MODE
	STOR T1,TIHCH,(T2)	; SAVE PREFIX CHAR FOR LATER USE
				; => NOTE THAT TIHCH IS THE TOP HALF OF TIFCH
	JRST TCIIT0		; AND TRY FOR SECOND CHARACTER

;HERE IF PREVIOUS CHAR WAS A PREFIX, CONVERT CURRENT CHAR TO 12 BIT ASCII

TCIIT1:	SETZRO TIHCP,(T2)	; CLEAR PREFIX FLAG
	STOR T1,TILCH,(T2)	; SAVE LOW BITS OF FULL CHARACTER 
				; => TILCH IS PART OF TIFCH
	LOAD T3,TIHCH,(T2)	; GET PREFIX BITS
	PUSH P,T1		; SAVE CHAR FOR FLAGS
	ANDI T1,177
	CALL ITPASC		; CONVERT TO 7 BIT ASCII
	POP P,T3		; GET CHAR BACK
	TRNE T3,TTXECO		; 
	IORI T1,TTXECO		; MARK WHETHER CHAR WAS ECHOED
	RETSKP			; HAVE CHAR, GOOD RETURN
; HERE TO GET A NORMAL CHAR FROM BUFFER

TCI00:	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 INPUT BUFFER
; T2/ TERMINAL DATA BLOCK
; RETURN +1: BUFFER EMPTY
;	+2: T1/ CHAR

GTTCI:	
;3051	SKIPG T1,TTICT(T2)	;ANY CHARS IN BUFFER?
;3051	RET			;NO
	SKIPLE 1,TTICT(2)	;3051 ANY CHARS IN BUFFER?
	IFSKP.			;3051 NO, MAYBE NEED TO REFILL FROM PACKET BUF.
	  TDCALL D,<<TV,TVRFIL>>;3051 DO TVT-DEPENDENT REFILL SIGNAL
	  RET			;3051 RETURN EMPTY
	ENDIF.			;3051
	SKIPN T3,TTIOUT(T2)	;GET POINTER
	BUG(TTICN0)
	HRRZ T4,T3
	TDNN T3,WRPMSK		;AT END OF CURRENT BUFFER?
	HRR T3,1-TTSIZ(T4)	;YES. GO TO NEXT IN CHAIN
	ILDB T1,T3		;GET NEXT CHARACTER
	MOVEM T3,TTIOUT(T2)	;SAVE UPDATED BYTE POINTER
	SOSLE TTICT(T2)		;REDUCE COUNT, NOW EMPTY?
	 IFSKP.
		SETZB T3,TTIOUT(T2) ;YES, RELEASE BUFFERS
		EXCH T3,TTIIN(T2)
		CALL TTRLBF
	 ENDIF.
	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,T3		;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>,<CH,CVTCAP>,<TV,TVTIGA>>
	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,T3		;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
; T1/ CHARACTER
;	CALL GPSICD
; RETURN +1 ALWAYS, 
;	T1/ PSI CODE OR -1 IF NOT A POSSIBLE PSI CHAR

GPSICD::CAIL T1,200		;DON'T EVER THINK ABOUT SPECIAL CHARACTERS
	JRST GPSIC2
	CAIG T1," "		;WITHIN NON-PSI CHAR RANGE?
	JRST GPSIC1		;NO
	CAIL T1,175
	JRST GPSIC3		;NO
GPSIC2:	SETO T1,		;YES, RETURN -1
	RET

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

GPSIC3:	CAIN T1,177		;RUBOUT?
	SKIPA T1,[^D28]		;YES, RETURN CODE
	MOVEI T1,^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
;FULL (12 BIT) CHARACTER INPUT 
; CALLED FROM MTOPR
;
TTIFCI::CALL TCIB		; READ A CHARACTER AND PROCESS AS IF BINARY
	RETBAD			; NEED TO BLOCK
	MOVE T3,TTTMOD(T2)	; IS INTELLIGENT TERMINAL PROTOCOL IN USE?
	TXNN T3,TM%ITP
	JRST TTFCI1		; ASCII TERMINAL, MAY HAVE META KEY
	LOAD T1,TIFCH,(T2)	; GET FULL 12-BIT CHARACTER
	RETSKP			; AND RETURN THAT

TTFCI1:	TRZE T1,200		; META BIT SET?
	TRO T1,400		; YES, SET 12-BIT FORM OF IT
	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 T3,TTBIGO		;NO. INCREMENT POINTER TO LOAD FROM
	CAIN T3,TTBSIZ		;AT END OF TTBBUF?
	SETZB T3,TTBIGO		;YES. POINT TO START OF TTBBUF
	MOVE T1,TTBBUF(T3)	;GET NEXT ENTRY
	SOS TTBIGC		;DECREMENT COUNT OF ENTRIES
	HLRZ T2,T1		;GET LINE NUMBER
	MOVEI Q2,0(T1)		;SAVE ALL ORIGINAL FLAGS
	DECR TTFBB,(T2)		;REDUCE LINE'S COUNT OF TTBBUF ENTRIES
	JN TTFXO,(T2),[		;SEND XON IF NEEDED
		CALL SNDXNS	;SEND XON IF NEEDED
		JRST .+1]
	TRNE T1,TTPIRQ		;NON CONTROLLING TERMINAL PSI?
	 IFNSK.
		CALL STADYN	;CONVERT TO DYNAMIC DATA POINTER
		 JRST TTCH7	;NONE
		LOAD T1,TTOPSI,(T2) ;GET PSI
		LOAD T2,TTPSFK,(T2) ;GET FORK
		CAIE T2,-1
		CALL PSIRQ	;IF FORK SETUP, REQUEST INTERRUPT
		JRST TTCH7	;AND TRY NEXT
	 ENDIF.
	TRNE T1,TTOIRQ		;OUTPUT INTERRUPT REQUEST?
	JRST [	MOVX T3,.TICTO	;YES. OUTPUT BUFFER WENT EMPTY AND PROCESS
		CALL TTPSRQ	; ENABLED FOR INTERRUPT. ISSUE IT
		JRST TTCH7]	;DONE WITH WORD
	TRNE T1,DLSCXF		;CARRIER TRANSITION?
	 IFNSK. <JN TTFEM,(T2),TT7CX > ;+++ YES, HANDLE IF REMOTE
	TRNN T1,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 T1,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 T2,TTCQLN		;GET NEXT LINE TO BE CHECKED
	MOVEI T4,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 T3,TTSTY,(T2)	;NO. GET CURRENT TYPE
	ADDI T2,1		;GO TO NEXT LINE ;1005 GET THE RIGHT ACC!
	CAIL T2,NLINES		;VALID LINE NUMBER?
	JRST TTCQ6		;NO. GO TO NEXT LINE TYPE
	LOAD T1,TTSTY,(T2)	;GET TYPE OF NEXT LINE
	CAMN T3,T1		;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 T3			;GO TO NEXT LINE TYPE
	CAIL T3,NLTYPS		;BEYOND END OF LEGAL TYPES?
	SETZ T3,		;YES. GO BACK TO BEGINNING
	MOVE T2,TT1LIN(T3)	;GET FIRST LINE OF THIS TYPE
	JUMPL T2,TTCQ6		;IF LINE GROUP IS NOT HERE, GO GET NEXT

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

TTCQ1:	SOJG T4,TTCQ3		;DONE ENOUGH FOR THIS TIME?
TTCQ5:	MOVEM T2,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 T1,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,(T2)	;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>,<ML,RSKP>,<TV,RSKP>,<CH,RSKP>,<NT,RSKP>>
	 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

;
; REMTCJ -- Flush terminal controlling job
; used to clear controlling job value without otherwise
; disturbing the dynamic data (currently only from .ATACH)
; called
;	T2/	Dynamic data
;
REMTCJ::
	SETONE TCJOB,(T2)		; Clear it
	RET				; and return
;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>,<ML,MLCDE1>,<CH,NVTDTS>,<TV,TVTDTS>>
	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
	JE TMRSU,(T2),TTCHD2	;3022 WANT TO INTERCHANGE <DEL> AND _ ?
	MOVE T3,TTCHAR(T2)	;3022 SEE IF 8TH BIT MATTERS
	TXNE T3,TC%MET		;3022 META BIT PRESENT?
	SKIPA T4,[377]		;3022 YES, INCLUDE IT IN CHECK
	MOVEI T4,177		;3022 NO, IGNORE ANY PARITY BITS
	AND T1,T4		;3022 MASK CHARACTER
	CAIE T1,.CHDEL		;3022 <DEL>
	IFSKP.
	  MOVEI T1,"_"		;3022 YES, SUBSTITUTE A UNDERSCORE
	  JRST TTCHD2		;3022 AND DONE
	ENDIF.
	CAIN T1,"_"		;3022 AN UNDERSCORE?
	MOVEI T1,.CHDEL		;3022 YEP, SUBSTITUTE A RUBOUT
TTCHD2:	MOVE T3,TTTMOD(T2)	;CHECK WHETHER ITP PROCESSING IS DESIRED
	TXNN T3,TM%ITP
	 IFNSK.
		MOVEM T1,TTCHIC ; NO, SAVE INPUT CHAR
		ANDX T1,177	; USE 7 BITS FOR LOCAL COMPARES
		JRST TTCHI0	; GO DO PROCESSING
	 ENDIF.
	CALL TTIITP		;EXECUTE INPUT PROCESSING ROUTINE
	RET			; +1 RETURN - NO CHARACTER, RETURN ERROR
	MOVEM T3,TTCHIC		; +2 RETURN
				;	CHAR FOR LINE BUFFER IN T3
				;	CHAR FOR TESTS IN T1 - ASSUMED 7 BITS
				;	CHAR WITH 200 BIT SET WILL NEVER
				;	 TRIGGER INTERRUPT OR PAGE PROCESSING
; TTCHI...
;CHECK FOR SPECIAL FUNCTION CHARACTERS
;
; FROM HERE ON IN, T1 IS THE CHAR IN 7 BITS. THE 200 BIT WILL BE
; SET IF THE CHAR SHOULD BE IGNORED BY THE FOLLOWING TESTS

TTCHI0:	MOVE T3,TODCLK		;171 GET TIME
	MOVEM T3,TTIDLE(T2)	;171 REMEMBER IT
	JE TTPRM,(T2),TTCHI2	;PERMANENT DATA?
	LOAD T3,TCJOB,(T2)	;YES. GET CONTROLLING JOB
	CAIN T3,-1		;IS THERE ONE?
	JRST TTC7N		;NO, MAYBE START ONE

; CHECK FOR TERMINAL INTERRUPT CHARACTER
TTCHI2:	CALL TTCHIT		;INTERRUPT CHAR?
	JRST TTCH11		;YES, GO PROCESS
				;NO, FALL THROUGH

; SEE IF ANY PAUSE OR UNPAUSE FUNCTIONS REQUIRED
	JE TT%PGM,TTFLGS(T2),TTCHI1	; BYPASS IF NOT IN DISPLAY MODE
	CALL TTCHPF		; HANDLE PAUSE/UNPAUSE CHARACTERS
	JRST [	CALL TTITPK	; USED CHAR, CLEAN OUT LINE BUFFER
		RETSKP]		; AND RETURN

; SEE IF ^O ACTION NEEDED	
TTCHI1:	CALL TTCHOA		; CHECK FOR ^O AND DO PROPER ACTION
	JRST [	CALL TTITPK	; YES, MAYBE CLEAN OUT LINE BUFFER
		RETSKP]		; EAT CHAR AND RETURN
	JRST TTCHI6		; REAL CHARACTER, GO PROCESS IT
;TTCHI...

; CHECK FOR INTERRUPT CHAR
;	T1/ CHAR IN 7 BITS
;	T2/ DYN DATA
;	T1 PRESERVED
; RETURN +1/ CHAR IS INTERRUPT CHAR, +2/ NOT

TTCHIT:	MOVE T3,T1		;COPY CHAR
	CALL GPSICD		;GET PSI CODE FOR CHAR
	EXCH T1,T3		;T1/CHARACTER, T3/CODE OR -1
	JUMPL T3,TCHIC1		;-1 MEANS NO CODE
	MOVE Q1,BITS(T3)	;BIT FOR THIS CODE
	TDNN Q1,TTPSI(T2)	;CODE ENABLED?
TCHIC1:	AOS (P)			;NO, SKIP RETURN
	RET			;YES, +1 RETURN

;CHECK FOR ^O AND ACT IF FOUND
;	T1/ CHAR
;	T2/ DYN DATA
;	T1 PRESERVED
; RETURN +1, ^O FOUND, +2 NOT

TTCHOA:	SKIPE CTRLOF		;NEW CTRL-O HANDLING?
	CAIE T1,FLOCHR		;AND A CTRL-O?
	RETSKP			;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?
	 RETSKP			;YES, DO NOTHING
	CALL [	SAVEAC <T1>	;YES
		CALLRET TTXONA]	;CLEAR POSSIBLE XOFF
	TMNN TTFLO,(T2)		;ALREADY FLUSHING OUTPUT?
	IFSKP. <
	  CALL CLOFLG		;YES, DO MARKER
	  RET>
	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
	RET
;TTCHI...
;CHECK FOR PAUSE OR UNPAUSE FUNCTIONS
;	T1/ CHAR 
;	T2/ DYN DATA
;	T1 PRESERVED
;RETURNS +1, CHAR WAS FUNCTION, FUNCTION PERFORMED
;	 +2, CHAR WASN'T A PAUSE/UNPAUSE FUNCTION

TTCHPF:	
; CHECK FOR XOFF/XON AND HANDLE QUICKLY
	CAIN T1,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 T1,PGMOFC		;MAYBE XOFF
	JRST TTCHP1		;NO, GO CHECK PAGE CHARACTERS
	JN TTRXF,(T2),R		;YES, SEE IF ALREADY STOPPED
	SETONE TTRXF,(T2)	;YES. INDICATE FRONT-END XOFF
	TMNN <TTSAL,TTHPO>,(T2)	;SPECIAL OUTPUT GOING?
	IFNSK. <
	  TDCALL D,<<FE,TTCHI3>,<MC,MCLNOF>> ;NO, STOP THE LINE
	 >,<
	  TDCALL D,<<FE,TTXON1>,<MC,MCLNON>>> ;YES, RESTART THE LINE
	RET

;CHECK PAGE PAUSE/UNPAUSE CHARACTERS
TTCHP1:	JE TTNXO,(T2),RSKP	;BYPASS IF NOT IN PAUSE EOP MODE
	JN TMMOR,(T2),TTCHP2	;JUMP IF ITS PAGING MODE
	LOAD T3,TTUPC,(T2)	;GET PAGE UNPAUSE CHARACTER
	CAME T1,T3		;IS THIS AN UNPAUSE ON PAGE CHARACTER?
	IFSKP.
	  TMNN TTSFG,(T2)	;ALREADY PAUSING?
	  IFSKP.
	    CALL TTXONP		;YES, RESTART OUTPUT
	    RET			;RETURN NOW, LOSE CHARACTER
	  ENDIF.
	  LOAD T3,TTPPC,(T2)	;NOT PAUSING NOW,
	  CAME T1,T3		;THIS THE PAUSE CHARACTER TOO?
	  IFSKP.
	    CALL TTXOFP		;YES, MAYBE PAUSE NOW
	    IFSKP. <RET>	;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. <RET>		;DID PAUSE, LOSE CHARACTER
	ENDIF.
	RETSKP			;DIDN'T DO ANYTHING WITH CHAR
;DO ITS-STYLE PAGING		;3002 FLUSH OUTPUT INTERRUPTS INSTALLED
TTCHP2:	JE TTSFG,(T2),TTCHP4	;3002 NOT STOPPED, RETURN CHAR
	PUSH P,T1		;3002 SAVE CHARACTER
	CALL TTXONA		;3002 RESTART OUTPUT
	POP P,T1		;3002 GET CHAR BACK
	CAIN T1," "		;3002 SPACE CHAR?
	JRST TTCHP3		;3002 YES, JUST FLUSH IT
	MOVX T4,1B<.TICMR>	;3002 BIT FOR INTERRUPT ON PAGE-FLUSH
	TMNE TMMSM,(T2)		;3002 SMART MORE PROCESSING ENABLED?
	TDNN T4,TTPSI(T2)	;3002 INTERRUPT ENABLED?
	JRST TTCHP4		;3002 NO OR NO, START OUTPUT AND KEEP CHAR
	MOVX T3,.TICMR		;3002 YES, REQUEST INTERRUPT
	PUSH P,T1		;3002 SAVE CHAR
	PUSH P,T2		;3002 AND TTY DATA PTR
	DYNST			;3002 T2/ INTERNAL LINE NUMBER
	CALL TTPSRQ		;3002 REQUEST INTERRUPT, EAT CHARACTER
	POP P,T2		;3002 RESTORE STUFF
	POP P,T1
	CAIE T1,.CHDEL		;3002 CHAR WAS RUBOUT
TTCHP4:	AOS 0(P)		;3002 NO, SKIP RETURN KEEPS CHAR
TTCHP3:	RET			;3002 YES, FLUSH IT
;TTCHI...
;HERE TO HANDLE NORMAL CHARACTER

TTCHI6:	AOS NTTYIN		;COUNT INPUT
	TRNE T1,200		;221 UNLESS A PREFIX CHAR
	JRST TCHI6A		;221
	SETONE TILAC,(T2)	;221 NO DEFERRED INTERRUPT 

TCHI6A:	LOAD T3,TYLMD,(T2)	;CHECK MODE NOW IN FORCE
	CAIE T3,.TTBIN		;BINARY?
	JRST TTCHI4		;NO.
TTMCI1:	LOAD T3,TIMAX,(T2)	;YES. GET CAPACITY OF INPUT BUFFER
	CAMLE T3,TTICT(T2)	;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 T1,RSKP		;FLUSH NULLS ASAP
	LOAD T3,TIMAX,(T2)	;CAPACITY OF INPUT BUFFERS
	CAMG T3,TTICT(T2)	;FULL?
	JRST TTCH12		;YES, ECHO BELL
	MOVE T3,TTFLGS(T2)
	TRNE T3,TT%DUM		;REGULAR FDX LINE?
	JRST TTCHI7		;HDX - 'ECHO' IMMED
	TRNN T3,TT%ECO		;ECHOS ON?
	JRST TTCHI9		;NO
	TRNE T3,TT%ECM		;STANDARD ECHO MODE?
	JRST TTCHI7		;NO, IMMEDIATE ALWAYS
	LOAD T4,TWFRK,(T2)	;GET WAITING FORK IF ANY
	CAIN T4,-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
	CAIE T1,.CHCRT		;CR?
	 IFSKP.
	 	SETZM TCOERR	;INIT ERROR INDICATOR
		CALL TCOE	;YES, ECHO CR-LF
		MOVEI T1,.CHLFD	;ECHO THE LINE FEED
		JRST TTCHI8
	 ENDIF.
	CALL TTRAIS		;RAISE FOR ECHO IF NECESSARY
TTCHI8:	SETZM TCOERR		;INIT ERROR INDICATOR
	SETZM TTCHFL		;INITIALIZE ECHO INDICATOR
	PUSH P,T1		;SAVE CHAR
	TXNN T1,200		;DON'T ECHO SPECIAL CHARACTER
	CALL TCOE		; ELSE ECHO VIA NORMAL OUTPUT STREAM
	POP P,T1		;GET CHAR BACK
	SKIPN TCOERR		;DID TCOUT FAIL?
	 IFSKP.
		SETZM IMECHF	;FAILED TO ECHO. RESET IMMEDIATE ECHO FLAG
		SETOM TTCHFL	;INDICATE CHARACTER NOT ECHOED
		JRST TTCHI9	;GO STORE CHARACTER WITHOUT MARKING IT ECHOED
	 ENDIF.
	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

;	T2/ ADDRESS OF DYNAMIC DATA

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

;IF INPUT BUFFER IS FULL, SEND XOFF TO TERMINAL

	LOAD T4,TIMAX,(T2)	;GET CAPACITY OF BUFFERS
	CAIGE T3,-MINICT(T4)
	 IFSKP.
		PUSH P,T2	;SAVE TTY
		DYNST
		TDCALL S,<<FE,SNDXO2>,<DZ,DZSXOF>> ;SEND XOFF
		POP P,T2	;RESTORE LINE
	 ENDIF.
	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 T3,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 T3,TWFRK,(T2)	;IF NO FORK WAITING FOR THIS LINE,
	CAIN T3,-1
	JRST TTCH10		; THEN SKIP WAKEUP CHECKS
	LOAD T3,TYLMD,(T2)	;GET TERMINAL DATA MODE FOR LAST CHARACTER
	CAIN T3,.TTBIN		;WAKE ALWAYS IF BINARY
	JRST [	CALL TTFWAK	;WAKE LISTENING PROCESS
		RETSKP]		;RETURN SUCCESS
	LOAD T3,TIMAX,(T2)	;CAPACITY OF INPUT BUFFERING
	SUBI T3,MINCT1		;LESS AN ARBITRARY AMOUNT
	CAMG T3,TTICT(T2)	;BUFFER NOW THAT FULL?
	JRST [	SETONE TTFWK,(T2) ;YES. FORCE WAKEUP OF WAITING FORK
		JRST .+1]
	CAIN T1,.CHCRT		;IS THIS A CARRIAGE RETURN
	MOVEI T1,.CHLFD		;YES-FORCE IT TO BE A LINE 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,(T2)	;GET WAITING FORK IF ANY
	CAIN FX,-1		;IS THERE ONE?
	JRST TTCH1X		;NO, DON'T WAKE
	JE TTFWK,(T2),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


;221 REARRANGED

TTCH11:	LOAD T4,TILAC,(T2)	;GET LAST DEFERRED INTERRUPT CHAR
	SETONE TILAC,(T2)	;THERE ISN'T ONE NOW
	TDNN Q1,TTDPSI(T2)	;DEFERRED CHARACTER?
	JRST TCHI1		;NO, INTERRUPT IMMEDIATELY
	CAMN T4,T1		;LAST CHAR SAME AS THIS ONE?
	JRST TTCHI5		;YES, MAKE IMMEDIATE

;HANDLE DEFERRED INTERRUPT CHARACTER

	STOR T1,TILAC,(T2)	;SAVE THIS DEFERRED INT CHAR ONE
	PUSH P,T1		;SAVE CHAR
	CALL TTFWAK		;FORCE WAKEUP SO PGM CAN SEE INT
	POP P,T1		;GET CHAR BACK
	LOAD T3,TIMAX,(T2)	;MUST PUT DEFERRED CHAR IN BUFFER
	ADDI T3,1		;1 RESERVED FOR INT CHAR
	CAMG T3,TTICT(T2)	;IS ROOM?
	JRST [	DPB T1,TTIIN(T2);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,T3		;SAVE CODE
	CALL TTCIBF		;CLEAR INPUT BUFFER ON DOUBLE INT
	POP P,T3		;RESTORE CODE
TCHI1:	CALL TTITPK		;221 MAYBE FLUSH SPECIAL CHAR
	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
;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 T1,PGMONC+1B28
	CAIN T1,PGMONC		;XON?
	IFNSK.
	  CALL TTITPK		;+++ MAYBE FLUSH PREFIX CHAR FROM LINE BUFFER
	  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 T1,PGMOFC		;XOF?
	CAIN T1,PGMOFC+1B28
	SKIPA			;YES
	CAIN T1,PGMOFC
	RETSKP			;NO, EXIT
	JN TTRXF,(T2),R		;SEE IF ALREADY STOPPED
	CALL TTITPK		;+++ MAYBE FLUSH PREFIX CHAR FROM LINE BUFFER
TTXOFC:	SETONE TTRXF,(T2)	;YES. INDICATE FRONT-END XOFF
	TMNN <TTSAL,TTHPO>,(T2)	;SPECIAL OUTPUT GOING?
	IFNSK. <
	  TDCALL D,<<FE,TTCHI3>,<MC,MCLNOF>> ;NO, STOP THE LINE
	 >,<
	  TDCALL D,<<FE,TTXON1>,<MC,MCLNON>>> ;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, MUST BE PAUSE. 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:	CALL TTITPK		;MAYBE FLUSH PREFIX CHAR FROM LINE BUFFER
	SETONE TTSFG,(T2)	;PAUSE
	RETSKP			;AND EAT CHARACTER

;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
;IF LAST CHAR IN LINE INPUT BUFFER WAS A SPECIAL CHAR, FLUSH IT

TTITPK:	MOVE T4,TTTMOD(T2)	;CHECK IF ITP TERMINAL
	TXNN T4,TM%ITP
	RET			;NO, NOTHING TO DO
	LDB T4,TTIIN(T2)	;GET LAST CHAR
	TXNN T4,200		;WAS PREFIX?
	RET			;NO, NOTHING TO DO
	SOSLE TTICT(T2)		;YES, DECR COUNT OF CHARS
	 IFSKP.
		PUSH P,T3	;EMPTY, FLUSH BUFFERS
		SETZB T3,TTIOUT(T2)
		EXCH T3,TTIIN(T2)
		CALL TTRLBF
		POP P,T3
		RET
	 ENDIF.
	SETO T4,
	ADJBP T4,TTIIN(T2)	;MOVE POINTER BACK ONE
	MOVEM T4,TTIIN(T2)
	RET
	
;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:	CAIN T1,.CHBEL		;+++ IF ^G, DON'T ECHO IT
	 RET			;+++ SO LOOPBACK CAN BE SAFELY DONE
	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:	CAME 2,CTYLNO		;CTY?
	 IFSKP.
		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
	 ENDIF.
	TDCALL S,<<FE,RSKP>,<PT,TTC7S2>,<NT,TTC7SN>,<DZ,RSKP>,<ML,TTC7SN>,<CH,TTC7SN>,<TV,TTC7SN>>
	 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
	SKIPG T3,TTACTL(T2)
	 IFSKP.
		JE TTPRM,(T3),.+1
		SETONE TTBAC,(T3)
		JRST TTC7S3
	 ENDIF.
	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
;+++ BEGIN ADDITION

	SUBTTL INPUT PROCESSING ROUTINES

; THESE ROUTINES ARE POINTED TO BY TTRUT IN DYNAMIC DATA.
; ACCEPT	
;	T1/ CHAR
;	T2/ DYNAMIC DATA
; RETURN
;	+1 FOR NO CHAR INPUT, 
;	+2 WITH CHAR TO INPUT IN T3,
;	   CHAR TO USE FOR XON/XOFF AND INTERRUPT TESTS IN T1
;	    NORMAL CHAR EXPECTED TO BE IN 7 BITS, 
;	    200 BIT SET INDICATES SPECIAL OR PREFIX CHAR TO 
;	    BE IGNORED BY TESTS

; INPUT ROUTINES FOR INTELLIGENT TERMINAL PROTOCOL
TTIITP:	JE <TISLH,TICCH>,(T2),TTIIT1 ;NOT IN ESC SEQUENCE,CHECK FOR /034
	SETZRO TISLH,(T2)	; TURN OFF ESC SEEN FLAG
	LOAD T3,TICHR,(T2)	; GET POSSIBLE PREFIX CHAR
	SKIPN T3		; ALREADY EXISTS, USE IT FOR DISPATCH
	MOVEI T3,(T1)		; ELSE THIS IS A PREFIX CHAR...
	CAIL T3,"@"		; POSSIBLE META BITS?
	 CAILE T3,"_"
	 CAIA			; NO, TREAT AS COMMAND
	 JRST ITPESC		; YES, GO BUILD A FULL CHARACTER
	MOVEI T4,ITPTBL		; SEARCH THROUGH TABLE FOR DISPATCH CHAR
TTITP0:	HLRZ CX,(T4)		; GET CHAR FROM TABLE
	JUMPE CX,RSKP		; END OF TABLE, NOT FOUND
	CAIN CX,(T3)		; MATCHING ENTRY?
	 JRST [	HRRZ CX,(T4)	; YES, GO RUN ROUTINE
		JRST (CX) ]
	AOJA T4,TTITP0		; TRY NEXT ENTRY

TTIIT1:	CAIN T1,""		; ITP ESCAPE CHAR?
	 JRST [ SETONE TISLH,(T2)	; YES, FLAG IT
		RET]		; AND NO REAL CHAR INPUT
	MOVE T3,T1		; REGULAR CHARACTER, RETURN AS INPUT
	RETSKP

; DISPATCH TABLE FOR ITP COMMANDS
ITPTBL:	"P"-100,,ITPSCP		; ^\ ^P # # SET CURSOR POSITION
	"Q"-100,,ITPSCQ		; FAKE FOR ^P
	"\"-100,,ITPSLH		; ^\ ^\ INPUT A ^\
	"C"-100,,ITPMNG		; ^\ ^C SCREEN HAS BEEN MUSSED
	"A"-100,,ITPALC		; ^\ ^A INCREMENT ALLOCATION
	"Z"-100,,ITPZAL		; ^\ ^Z ZERO ALLOCATION
	"I"-100,,ITPIAL		; ^\ ^I SET ALLOCATION TO INFINITY
	"S"-100,,ITPSTP		; ^\ ^S STOP OUTPUT
	"R"-100,,ITPRES		; ^\ ^R RESUME OUTPUT
	0			; MARK END OF THE TABLE

; ESCAPED TV CODE
ITPESC:	JN TICCH,(T2),ITPES1	; FIRST TIME THROUGH?
	STOR T1,TICHR,(T2)	; YES, SAVE META BITS
	SETONE TICCH,(T2)	; REMEMBER WE SAW THEM
	ANDI T1,37		; GET 5 META BITS
	TRO T1,200		; FLAG THAT THIS WAS A PREFIX
	MOVE T3,T1		; BOTH LINE BUFFER AND TEST CHAR
	RETSKP			; RETURN CHAR

; ESCAPED CODE LAST TIME, RETURN IT AND COMPOSITE ASCII
ITPES1:	ANDI T1,177		; MASK TO SEVEN BITS
	PUSH P,T1		; SAVE CHARACTER
	CALL ITPASC		; CONVERT TO 7-BIT ASCII IN T1
	POP P,T3		; RESTORE REAL VERSION TO T3
	SETZRO <TICHR,TICCH>,(T2)	;CLEAR FLAGS
	RETSKP
; CONVERT CHARACTER IN T1 TO ASCII USING META PREFIX IN T3
; CALLED TWICE ON PREFIX CHARACTERS, ONCE TO INTERRUPT CHECKING
; AT TTCHI LEVEL AND ONCE FOR TCI0 TO RETURN TO USER.
; ACCEPTS
;		T1/ LOW ORDER BITS OF 12 BIT CHAR
;		T3/ HIGH ORDER BITS OF 12 BIT CHAR
;
; RETURNS
;	+1, ALWAYS
;		T1/ 7-BIT ASCII CHAR

ITPASC:	TRNN T3,1		; %TXCTL ON?
	 JRST ITPAS2		; NO
	CAIL T1,"a"		; YES, IS IT A LOWERCASE LETTER?
	 CAILE T1,"z"
	 CAIA			; NO
	 TRZ T1,40		; YES, UPPERCASIFY IT
	CAIL T1,77		; BETWEEN 077 AND 137?
	 CAILE T1,137
	 CAIA			; NO
	 TRC T1,100		; YES
	CAIN T1,40		; MAKE ^<SPACE> BE NULL
	 SETZ T1,
ITPAS2:	TRNE T3,2		; %TXMTA ON?
	 TRO T1,200		; YES, SET PSEUDO-META
	RET

; SET POSITION (IN RESPONSE TO %TDORS)

ITPSCP:	JN TICCH,(T2),ITPSC1	; FIRST TIME THROUGH?
	STOR T3,TICHR,(T2)	; YES, SAVE STATE
	SETONE TICCH,(T2)
	RET

ITPSC1:	STOR T1,TPVPS,(T2)	; SECOND TIME -- VERTICAL POSITION
	STOR T1,TLVPS,(T2)
	MOVEI T3,"Q"-100	; FAKE COMMAND
	STOR T3,TICHR,(T2)
	RET

ITPSCQ:	STOR T1,TPHPS,(T2)	; HORIZONTAL POS
	STOR T1,TLHPS,(T2)
	SETZRO <TTCFU,TTNAB>,(T2) ; NOT CONFUSED
	SETZRO <TICHR,TICCH>,(T2) ; DONE WITH COMMAND
	RET

; SCREEN HAS BEEN MUNGED

ITPMNG:	RET			; DON'T HANDLE THIS YET

; START/STOP OUTPUT

ITPSTP:	SETONE TTSFG,(T2)	; SHUT OFF OUTPUT (MAYBE SHOULD STOP FE?)
	RET

ITPRES:	CALLRET TTXONP		; ^S FLAG OFF, START LINE
	
; INCREMENT ALLOCATION

ITPALC:	JN TICCH,(T2),ITPAL1	; FIRST TIME THROUGH?
	MOVEI T3,"A"-100	; YES, JUST REMEMBER STATE
	STOR T3,TICHR,(T2)
	SETONE TICCH,(T2)
	RET

ITPAL1:	SETZRO <TICCH,TICHR>,(T2) ; SECOND TIME THROUGH
REPEAT 0,<
	LOAD T3,TIALC,(T2)	; INCREMENT ALLOCATION
	ADDI T3,(T1)
	STOR T3,TIALC,(T2)
>
	RET

; ZERO ALLOCATION
ITPZAL:	
;	SETZRO TIALC,(T2)
	SETONE TIALP,(T2)	; TURN ON ALLOCATION
	RET

; SET ALLOCATION TO INFINITY (TURN IT OFF)
ITPIAL:	SETZRO TIALP,(T2)
	RET

; SEND A REAL ^\
ITPSLH:	MOVE T3,T1		;CHAR TO LINE BUFFER, TOO
	RETSKP
	SUBTTL 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 BIG 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>,<ML,MLCTCO>,<CH,CHTCSO>,<TV,TVTCSO>>
	 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:	CALL OSKD1		;ALLOW SCHEDULING 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
	TRZE 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:	SOSL TTOCT(T2)		;ARE THERE CHARACTERS IN OUTPUT BUFFER?
	 IFSKP.
		SETZRO TTOTP,(T2) ;NO CHARACTERS. CLEAR OUTPUT-ACTIVE
		SETZM TTOCT(T2)	;ZERO COUNTER
		CALLRET CLENUP  ; AND GO RELEASE BUFFERS
	 ENDIF.
	CALL CHKWRN		;SEE IF FORK WAKEUP NEEDED
	SKIPN T3,TTOOUT(T2)	;GET BUFFER POINTER
	BUG(TTONOB)
	TDNE T3,WRPMSK		;AT END OF BUFFER?
	IFSKP.
	  HRRZ T4,T3		;YES GO TO NEXT ONE
	  HRR T3,1-TTSIZ(T4)
	  MOVEM T3,TTOOUT(T2)	;SAVE POINTER
	ENDIF.
	ILDB T1,TTOOUT(T2)	;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
;  CURRENT POSSIBILITIES ARE:
;
;	.TTPFC - TERMINAL PAGE FILL, DO XOFF
;	.TTMRK - STOP FLUSHING OUTPUT
;	.TTBRK - MARK SAFE PLACE FOR CFOBF

TTSND3:	CAILE T1,NTTSCD		;RANGE CHECK, 400 BIT ZEROED IN TEST ABOVE
	JRST TTSILE		;NO GOOD
	XCT TTSCOD(T1)		;DO SOMETHING
	JRST TTSND6		;AND GO GET ANOTHER CHAR

TTSCOD:	JRST TTSILE		;ILLEGAL
	CALL TTSPFC		;.TTPFC - PAGE FULL
	CALL TTSMRK		;.TTMRK - STOP FLUSHING OUTPUT
	JFCL			;.TTBRK - SAFE PLACE FOR CFOBF
NTTSCD=.-TTSCOD

;HANDLERS FOR FUNCTION ESCAPE CODES
; ALL (EXCEPT TTSMRK) MUST IGNORE CODE IF FLUSHING OUTPUT

TTSMRK:	JE TTFLO,(T2),R		;IGNORE IF NOT FLUSHING OUTPUT
	LOAD T1,TTTYP,(T2)	;GET TERMINAL TYPE
	CAIN T1,.TTSUP		;TRY TO DO THE RIGHT THING (YECCH)
	SKIPA T1,[POINT 8,[BYTE (8)"]",%TDCRL,.CHDEL]]
	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 TTCFU,(T2)	;LOSE CURSOR, I GUESS
	SETONE TTHPO,(T2)	;NOTE HP OUTPUT QUEUED
	SETZRO TTFLO,(T2)	;STOP FLUSHING OUTPUT
	RET

TTSPFC:	JN TTFLO,(T2),R		;IGNORE IF FLUSHING OUTPUT
	SETONE TTSFG,(T2)	;YES. SIMULATE CTRL/S
	RET

;HERE FOR ILLEGAL ESCAPE CHAR
TTSILE:	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER TO PRINT
	TRO T1,400		;PUT ESC BIT BACK FOR BUG OUTPUT
	BUG(TTILEC,<<1,CHAR>,<2,LINE>>)
	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>,<ML,RSKP>,<CH,RSKP>,<TV,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

;3005 Begin addition
	SWAPCD
;Call here to get current TTY # (or host if net tty) into T2

HSTTY::	MOVE T2,CTRLTT		;
	TDCALL S,<<NT,NTHST>>	;
	RET			;Value returned in T2

;3005 End addition

	RESCD

TTBUGH:	BUG(BADTTY)
	RET

;3005 Begin addition (1 line)
IF2,<	PURGE TDCALL, ..TDC1, ..TDC2, ..TDC3, TDCALX
>