Google
 

Trailing-Edge - PDP-10 Archives - BB-4170G-SM - sources/ttysrv.mac
There are 50 other files named ttysrv.mac in the archive. Click here to see a list.
;<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
;<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
;<3A.MONITOR>TTYSRV.MAC.39,  9-Jun-78 14:15:28, EDIT BY MILLER
;PUT IN A SAVELN AT TTEMES SO T2 IS PRESERVED
;<3A.MONITOR>TTYSRV.MAC.38,  9-Jun-78 11:09:46, 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
;<3A.MONITOR>TTYSRV.MAC.36, 29-May-78 13:38:47, EDIT BY MILLER
;CALL TTCBF2 FROM TTYDEA INSTEAD OF CALL TTRLOB
;<3A.MONITOR>TTYSRV.MAC.35,  3-May-78 08:36:07, 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
;<3A.MONITOR>TTYSRV.MAC.33,  2-May-78 14:53:51, 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
;<3A.MONITOR>TTYSRV.MAC.31, 22-Apr-78 15:54:41, Edit by BORCHEK
;SETUP TCJOB FOR NVT AT TTYAC4:
;<3A.MONITOR>TTYSRV.MAC.30, 15-Apr-78 15:32:16, EDIT BY MILLER
;FIX UP HANDLING OF LINKF IN TTLNK3
;<3A.MONITOR>TTYSRV.MAC.29, 13-Apr-78 15:54:41, EDIT BY MURPHY
;TCO #1891 - FIX TTSTIH
;<3A.MONITOR>TTYSRV.MAC.28,  5-Apr-78 16:10:08, EDIT BY MILLER
;REMOVE CHECK IN TCI WHEN BLOCKING FOR ZERO LOCK COUNT
;<3A.MONITOR>TTYSRV.MAC.27, 28-Mar-78 12:18:57, EDIT BY MILLER
;FIX TYPEO
;<3A.MONITOR>TTYSRV.MAC.26, 28-Mar-78 11:44:47, EDIT BY MILLER
;FIX UP CODE IN TTLNK3
;<3A.MONITOR>TTYSRV.MAC.25, 27-Mar-78 18:23:05, 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
;<3A.MONITOR>TTYSRV.MAC.23, 26-Mar-78 14:38:00, EDIT BY MILLER
;CHECK FOR MESSAGE BLOCK IN CLENUP
;<3A.MONITOR>TTYSRV.MAC.22, 26-Mar-78 13:28:44, EDIT BY MILLER
;FXI 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
;<3A.MONITOR>TTYSRV.MAC.17, 23-Mar-78 07:54:49, EDIT BY MILLER
;CHECK FOR REQUEUING 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
;<3A.MONITOR>TTYSRV.MAC.15, 20-Mar-78 14:08:47, EDIT BY MILLER
;CHECK FOR MESASAGE OR SEND-ALL BLOCK AT TTSN10
;<3A.MONITOR>TTYSRV.MAC.14, 14-Mar-78 08:41:10, Edit by ENGEL
;GET RID OF THE ERROR RETURN IN SFMOD FOR BITS 18 AND 19 SET
;<3A.MONITOR>TTYSRV.MAC.13,  9-Mar-78 08:26:57, Edit by ENGEL
;CHANGE RETERR TO ITERR IN TTSMOD:
;<3A.MONITOR>TTYSRV.MAC.12,  2-Mar-78 17:45:32, EDIT BY BOSACK
;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.10,  2-Mar-78 16:14:08, Edit by ENGEL
;GIVE ERROR RETURN  WHEN BITS 18&19 ARE ON IN SFMOD
;<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
;<3A.MONITOR>TTYSRV.MAC.8, 22-Feb-78 08:18:06, EDIT BY MILLER
;FLUSH OUTPUT BUFFERS IN TSACT3 SCHEDULER TEST
;<3.SM10-RELEASE-3>TTYSRV.MAC.7,  6-Dec-77 01:31:38, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.550, 18-Nov-77 15:37:11, EDIT BY MILLER
;FIX CODE AT TTJBDT THAT CAUSES SCHEDULER PAGE FAILS
;<3.SM10-RELEASE-3>TTYSRV.MAC.5,  4-Nov-77 13:18:34, EDIT BY MILLER
;ADD CODE TO SM10 SOURCE AS WELL
;<3-MONITOR>TTYSRV.MAC.548,  4-Nov-77 13:15:37, EDIT BY MILLER
;RELEASE OUTPUT BUFFER IN TTSTO IF EMPTY
;<3.SM10-RELEASE-3>TTYSRV.MAC.4, 28-Oct-77 03:39:10, EDIT BY MILLER
;ADD TTCTRA ROUTINE FOR USE BY TTY SIMULATOR
;<3.SM10-RELEASE-3>TTYSRV.MAC.3, 25-Oct-77 11:27:48, EDIT BY MURPHY
;<3.SM10-RELEASE-3>TTYSRV.MAC.2, 24-Oct-77 17:56:36, EDIT BY MURPHY
;SEARCH PROKL OR PROKS AS APPROPRIATE
;<3-MONITOR>TTYSRV.MAC.546, 12-Oct-77 14:22:43, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>TTYSRV.MAC.545,  4-Oct-77 12:29:55, EDIT BY CROSSLAND
;CORRECT TEST FOR LINKS IN TTCOBF
;<3-MONITOR>TTYSRV.MAC.544, 24-Sep-77 17:32:22, EDIT BY MILLER
;MORE DYNST FIXES
;<3-MONITOR>TTYSRV.MAC.543, 24-Sep-77 17:29:39, EDIT BY MILLER
;FIX UP DYNST MACRO
;<3-MONITOR>TTYSRV.MAC.542, 24-Sep-77 17:21:38, EDIT BY MILLER
;REMOVE SEVERAL SAVELN'S AND SPEED  UP TCOU3
;<3-MONITOR>TTYSRV.MAC.541, 22-Sep-77 09:24:24, EDIT BY MILLER
;REPLACE SAVET IN SNDXON WITH A SAVEAC
;<3-MONITOR>TTYSRV.MAC.540, 21-Sep-77 12:19:39, EDIT BY MILLER
;SET 1B0 IN TTACTL IF LINE IS MESSAGE OR SHORT. MAKES STADYN AND
; LCKTTY FASTER FOR FULL LENGHT BLOCKS
;<3-MONITOR>TTYSRV.MAC.539, 19-Sep-77 14:56:54, EDIT BY MILLER
;CHECK FOR NON-EX LINE GROUP AT TTCQ6
;<3-MONITOR>TTYSRV.MAC.538, 19-Sep-77 13:53:20, EDIT BY MILLER
;MAKE TTYCHK UPDTADE TIMER BEFORE USING TTVT29 ROUTINES
;<3-MONITOR>TTYSRV.MAC.537, 19-Sep-77 13:51:31, EDIT BY MILLER
;IMPROVE TTCH7 CODE TO EXECUTE MANY FEWER INSTRUCTIONS.
;MAKE TTVT29 CHECKS OFF OF A SEPARATE TIMER (TTYTIM)
;<3-MONITOR>TTYSRV.MAC.536, 15-Sep-77 11:32:42, EDIT BY MILLER
;CHANGE TTVT12 ,MEANING SO CODE THAT USES IT IS MORE EFFICIENT
;<3-MONITOR>TTYSRV.MAC.535, 14-Sep-77 16:14:21, EDIT BY MILLER
;CHANGE "CALL DYNSTA" TO "DYNST". MAKE MACRO ASSEMBLE ONE INSTRUCTION
;<3-MONITOR>TTYSRV.MAC.534,  9-Sep-77 17:06:04, EDIT BY HURLEY
;SPEED UP LCKTTY/ULKTTY
;<3-MONITOR>TTYSRV.MAC.533, 17-Aug-77 16:50:57, EDIT BY HURLEY
;MOVED TTYPE0 AND TTYPE1 TABLES TO STG
;<3-MONITOR>TTYSRV.MAC.532, 10-Aug-77 13:36:47, Edit by MCLEAN
;CLEAN UP TTSND ON SENDALL
;<3-MONITOR>TTYSRV.MAC.531,  7-Aug-77 21:43:48, Edit by MCLEAN
;FIX SENDALL FOR SM10
;<3-MONITOR>TTYSRV.MAC.530,  6-Aug-77 02:21:55, Edit by MCLEAN
;FIX SALLIN IF ASGSHT FAILS
;<3-MONITOR>TTYSRV.MAC.529,  4-Aug-77 19:31:20, EDIT BY HURLEY
;FIX SIBE TO WORK FOR BINARY JFN'S
;<3-MONITOR>TTYSRV.MAC.528, 30-Jul-77 01:51:17, EDIT BY CROSSLAND
;REUSE TTVT11 FOR DEASIGNING DYNAMIC DATA
;<3-MONITOR>TTYSRV.MAC.527, 28-Jul-77 00:37:59, EDIT BY CLEMENTS
;<3-NSW-MONITOR>TTYSRV.MAC.2, 27-Jul-77 02:39:32, EDIT BY CLEMENTS
;<3-NSW-MONITOR>TTYSRV.MAC.2, 26-Jul-77 23:04:24, EDIT BY CLEMENTS
; ADD TTFRK1 TO DYNAMIC DATA, ADD ROUTINES TO READ AND SET IT
;<3-MONITOR>TTYSRV.MAC.526, 19-Jul-77 08:57:26, EDIT BY HALL
;MAKE TTMSG CALL CKMMOD TO CHECK FOR MONITOR MODE
;<3-MONITOR>TTYSRV.MAC.525, 15-Jul-77 10:20:18, EDIT BY MILLER
;FIX COMPUTATION OF LENGTH OF TTLINV
;<3-MONITOR>TTYSRV.MAC.524, 14-Jul-77 14:10:49, Edit by MCLEAN
;FIX .TTMSG SO IT WILL NOW CORRECTLY CHECK PRIVILEDGES
;<3-MONITOR>TTYSRV.MAC.523, 11-Jul-77 21:16:13, Edit by MCLEAN
;MORE ATTEMPTS TO FIX SENDALL IN TTSND
;<3-MONITOR>TTYSRV.MAC.522, 11-Jul-77 16:57:26, Edit by MCLEAN
;FIX SNDALL AT TTSND5+1
;<3-MONITOR>TTYSRV.MAC.521,  4-Jul-77 18:18:15, EDIT BY CROSSLAND
;MOVE CHECK FOR PERMANENT BLOCK TO BE FIRST CHECK IN TTYDEA
;<3-MONITOR>TTYSRV.MAC.520, 27-Jun-77 13:44:51, Edit by MCLEAN
;FIX TTSND FOR SHORT BLOCKS
;<3-MONITOR>TTYSRV.MAC.519, 27-Jun-77 13:31:10, EDIT BY HALL
;TCO 1740 - MAKE TTABRT RESIDENT
;<3-MONITOR>TTYSRV.MAC.518, 27-Jun-77 10:15:42, EDIT BY MILLER
;TCO 1831 AGAIN. SET SEED TO "UNKNOWN" FOR AUTO LINES ON HANGUP
;<3-MONITOR>TTYSRV.MAC.517, 25-Jun-77 10:57:27, EDIT BY HALL
;TCO 1740 - FIX DOLINE TO NOT CALL TTSOBE FOR SHORT BLOCKS
;<3-MONITOR>TTYSRV.MAC.516, 24-Jun-77 10:16:04, EDIT BY MILLER
;MORE OF TCO 1831
;<3-MONITOR>TTYSRV.MAC.515, 24-Jun-77 10:13:13, EDIT BY MILLER
;TCO 1831. ADD CODE FOR "AUTO" SPEED
;<3-MONITOR>TTYSRV.MAC.514, 22-Jun-77 13:13:55, EDIT BY HALL
;TCO 1740 - ADD TTABRT FOR JOBSRT
;<3-MONITOR>TTYSRV.MAC.513, 17-Jun-77 16:59:04, EDIT BY HALL
;TCO 1740 - IN TTYDEA, CLEAR TTACTL BEFORE RELEASING RESIDENT STORAGE
;<3-MONITOR>TTYSRV.MAC.512, 16-Jun-77 17:12:39, EDIT BY CROSSLAND
;MOVE TTLNK4 LABEL SO THAT LINKS WORK CORRECTLY
;<3-MONITOR>TTYSRV.MAC.511, 15-Jun-77 15:27:47, EDIT BY HALL
;TCO 1740 - IN TTYDEA, IF LINE IS A PTY, SEND PTY HUNGRY INTERRUPT
;<3-MONITOR>TTYSRV.MAC.510, 14-Jun-77 22:27:15, EDIT BY CROSSLAND
;REMOVE PARITY IF NECESSARY ON SENDALLS
;<3-MONITOR>TTYSRV.MAC.509, 14-Jun-77 17:05:28, Edit by MCLEAN
;FIX GTBTTF FOR PTY'S TO CHECK FOR TT%PRM AND TT%BAC
;<3-MONITOR>TTYSRV.MAC.507, 11-Jun-77 03:38:29, EDIT BY CROSSLAND
;ADD FNXCT AND ALWAYS TAKE PARITY OFF FOR NVT'S.  MORE MERGING OF ARPA
; SOURCES
;<3-MONITOR>TTYSRV.MAC.505,  7-Jun-77 18:18:26, EDIT BY MILLER
;FIX TCIF1 TO UNLOCK TTY AND REVERIFY TTY AFTER RESOLVING CONFLICT
;<3-MONITOR>TTYSRV.MAC.504,  7-Jun-77 17:17:02, EDIT BY HALL
;TCO 1740 - REMOVE CODE IN TTSTIH THAT RETURNS NOT HUNGRY IF OUTPUT
;	BUFFER IS NEARLY FULL
;IN TTCHI, IF ECHOING FAILS BECAUSE OUTPUT BUFFER IS FULL, KEEP THE
;	CHARACTER AND WAKE UP THE WAITING FORK
;IN TTCHI, IF LINE IS A PTY, FORCE WAKEUP ON FORMATTING CONTROL CHARACTERS
;<3-MONITOR>TTYSRV.MAC.503,  3-Jun-77 15:39:34, EDIT BY HALL
;TCO 1740 - IN TTYDEA, CALLED TTRLOB INSTEAD OF TTCBF2 TO PREVENT
;	TELLING FRONT END TO FLUSH OUTPUT
;<3-MONITOR>TTYSRV.MAC.502, 24-May-77 10:38:45, EDIT BY KIRSCHEN
;TCO 1802 - ADD .MOSIG FUNCTION TO SET "INGORE INPUT" BIT
;<3-MONITOR>TTYSRV.MAC.501, 23-May-77 12:15:28, EDIT BY HALL
;TCO 1740 - MADE TTYASO AND TTYASC SAVE AC 2 (REPLACES EDIT FOR VERSION 499)
;<3-MONITOR>TTYSRV.MAC.500, 23-May-77 09:08:09, EDIT BY MILLER
;FIX TYPEO IN TTYDIS
;<3-MONITOR>TTYSRV.MAC.499, 20-May-77 13:35:48, EDIT BY MILLER
;MAKE TTYASO ALWAYS RETURN STATIC LINE NUMBER ON ERROR
;<3-MONITOR>TTYSRV.MAC.498, 19-May-77 10:52:08, EDIT BY MILLER
;CHECK FOR INSKED IN TTYDIS AND TTYAWK
;<3-MONITOR>TTYSRV.MAC.497, 18-May-77 23:26:23, EDIT BY CROSSLAND
;FIX UP LISTING PAGING
;<3-MONITOR>TTYSRV.MAC.496, 16-May-77 16:25:39, EDIT BY CROSSLAND
;TCO 1742 MERGE ARPANET SOURCES
;<3-MONITOR>TTYSRV.MAC.495, 13-May-77 10:55:11, EDIT BY HALL
;TCO 1740 - BUG FIX IN TTMSG - CLEAR BIT 18 IN TTY DESIGNATOR
;<3-MONITOR>TTYSRV.MAC.494, 12-May-77 16:47:31, EDIT BY HALL
;TCO 1740 - MADE TTYDEA RELEASE OUTPUT BUFFERS WITHOUT TELLING FE TO 
;FLUSH OUTPUT.  REORGANIZED DOLINE TO SHORTEN IT.  MADE SOBE CHECK FOR
;OUTPUT IN PROGRESS (TTOTP BIT)
;<3-MONITOR>TTYSRV.MAC.493, 12-May-77 00:47:41, Edit by MCLEAN
;MORE OF SAME
;<3-MONITOR>TTYSRV.MAC.492, 12-May-77 00:32:01, Edit by MCLEAN
;SAVE LINE NUMBER IN SALLIN AND ELIMINATE NEED FOR DUMMY MODULES
;<3-MONITOR>TTYSRV.MAC.491, 11-May-77 12:46:24, EDIT BY HALL
;MOVED SNDFNC AND TTDTRM INTO TTFEDV.  REMOVED TTVT11 ENTRY SO THIS
;SLOT IS NOW AVAILABLE.
;MADE SOME CODE SWAPPABLE THAT WAS RESIDENT
;ADDED TTDMVT, THE UNIVERSAL TRANSFER VECTOR FOR DUMMY MODULES, AND
;TTBUGH, THE BUGHLT REACHED WHEN THE DUMMY MODULE IS CALLED
;<3-MONITOR>TTYSRV.MAC.490, 10-May-77 21:36:49, EDIT BY BOSACK
;<3-MONITOR>TTYSRV.MAC.489, 10-May-77 20:22:03, EDIT BY BOSACK
;<3-MONITOR>TTYSRV.MAC.488, 10-May-77 20:12:15, EDIT BY BOSACK
;MOVE STORAGE TO STG
;<3-MONITOR>TTYSRV.MAC.487, 10-May-77 19:39:36, EDIT BY BOSACK
;<3-MONITOR>TTYSRV.MAC.486, 10-May-77 15:45:26, EDIT BY HALL
;MORE FOR PREVIOUS EDIT
;<3-MONITOR>TTYSRV.MAC.485, 10-May-77 13:50:09, EDIT BY HURLEY
;ADD APRA ENTRY AND TITLE STATEMENTS
;<3-MONITOR>TTYSRV.MAC.484,  8-May-77 16:39:05, Edit by MCLEAN
;REMOVE CONO DLS,DLSCHN
;<3-MONITOR>TTYSRV.MAC.483,  8-May-77 16:23:07, Edit by MCLEAN
;MORE DC10 REMOVAL
;<3-MONITOR>TTYSRV.MAC.482,  8-May-77 16:17:47, Edit by MCLEAN
;MOVE SOME DC10 STUFF TO TTDCDV
;<3-MONITOR>TTYSRV.MAC.481,  6-May-77 16:12:49, EDIT BY HALL
;IMPROVED THE COMMENTS
;<3-MONITOR>TTYSRV.MAC.480,  6-May-77 12:29:58, EDIT BY HALL
;TCO 1740 - MAKE TTMSG WORK FOR ALL LINE TYPES; ADD LOCKING AND
;	UNLOCKING OF TERMINALS IN LINK CODE OF TCOUT
;<3-MONITOR>TTYSRV.MAC.479,  5-May-77 16:49:01, EDIT BY MILLER
;SAVE STATIC LINE NUMBER AROUND CALL TO TTCS ROUTINE
;<3-MONITOR>TTYSRV.MAC.478,  4-May-77 16:47:59, EDIT BY MILLER
;more edits to make ttspwd swappable
;<3-MONITOR>TTYSRV.MAC.477,  4-May-77 16:05:13, EDIT BY MILLER
;TCO1740. MAKE TTSPWD SWAPPABLE
;<3-MONITOR>TTYSRV.MAC.475,  4-May-77 08:50:57, EDIT BY MILLER
;FIX TLINK FOR NEW LOCK/UNLOCK CODE
;<3-MONITOR>TTYSRV.MAC.474,  4-May-77 03:09:56, EDIT BY CROSSLAND
;<3-MONITOR>TTYSRV.MAC.473,  3-May-77 22:41:09, EDIT BY CROSSLAND
;<3-MONITOR>TTYSRV.MAC.472,  3-May-77 18:50:45, EDIT BY CROSSLAND
;TCO 1742 MERGE ARPANET SOURCES
;<3-MONITOR>TTYSRV.MAC.471,  3-May-77 16:54:01, EDIT BY HALL
;TCO 1740 - FIX TEST ON TIME IN DOLINE - CAMGE SHOULD HAVE BEEN CAML
;<3-MONITOR>TTYSRV.MAC.470,  3-May-77 16:36:28, EDIT BY MILLER
;CHECK IN TTYDIS AND TTYAWK FOR FSIINI ENTRY
;<3-MONITOR>TTYSRV.MAC.469,  3-May-77 14:34:59, EDIT BY MILLER
;TCO 1740. IMPROVE LOCKING/UNLOCKING OF TTY DATA BASE
;<3-MONITOR>TTYSRV.MAC.468,  2-May-77 15:40:08, EDIT BY HALL
;TCO 1740 - FOR BINARY OUTPUT DON'T ADD PARITY
;<3-MONITOR>TTYSRV.MAC.467, 29-Apr-77 13:01:39, EDIT BY HALL
;TCO 1740 - FIXED DEFINITION OF TPLEN DEFSTR IN TTFLGS OFFSET
;<3-MONITOR>TTYSRV.MAC.466, 22-Apr-77 15:36:03, EDIT BY MILLER
;FIX TTCLFK NOT TO LOCK TTY. GO NOSKED INSTEAD
;<3-MONITOR>TTYSRV.MAC.465, 22-Apr-77 15:06:46, EDIT BY HALL
;TCO 1740 - CHANGE DOLINE TO CHECK FOR OUTPUT TO LINE BEING COMPLETE
;<3-MONITOR>TTYSRV.MAC.464, 22-Apr-77 12:53:43, EDIT BY HALL
;TCO 1740 - MADE GTBTTF RETURN (-2,,-1) IF JOB IS BEING CREATED
;<3-MONITOR>TTYSRV.MAC.463, 22-Apr-77 11:46:02, EDIT BY HALL
;TCO 1740 - CHANGED GTBTTF TO RETURN -2 IF JOB IS BEING CREATED
;<3-MONITOR>TTYSRV.MAC.462, 13-Apr-77 14:15:39, EDIT BY HALL
;TCO 1740 - MAKE TCI CHECK LOCK COUNT BEFORE CALLING ULKTTY
;<3-MONITOR>TTYSRV.MAC.461, 12-Apr-77 14:59:25, EDIT BY HALL
;TCO 1740 - MAKE TTSTIH RETURN NOT HUNGRY IF OUTPUT BUFFER IS FULL
;<3-MONITOR>TTYSRV.MAC.460,  7-Apr-77 10:31:17, EDIT BY HALL
;TCO 1740 - MADE TTYDEA AND DOLINE RELEASE LINE BUFFERS 
;<3-MONITOR>TTYSRV.MAC.459,  4-Apr-77 19:22:11, EDIT BY HALL
;TCO 1740 - BUG FIX IN TLINK - CHANGED FAILURE RETURN FROM SOUT
;<3-MONITOR>TTYSRV.MAC.458,  1-Apr-77 15:08:09, EDIT BY HALL
;TCO 1740 - CLEAR FORCED WAKEUP WHEN SETTING WAITING FORK (AT TCIF2)
;<3-MONITOR>TTYSRV.MAC.457, 31-Mar-77 01:11:49, Edit by MCLEAN
;ADD TTFXF FOR DZ11 TO BE ABLE TO SET XOFF IMMEDIATELY ON INTERRUPT
;<3-MONITOR>TTYSRV.MAC.456, 30-Mar-77 17:19:29, EDIT BY HURLEY
;FIX POWER FAIL RECOVERY
;<3-MONITOR>TTYSRV.MAC.455, 27-Mar-77 14:14:30, Edit by MCLEAN
;FIX TYPO
;<3-MONITOR>TTYSRV.MAC.454, 27-Mar-77 13:47:28, Edit by MCLEAN
;COMMENTS AND CLEANUP
;<3-MONITOR>TTYSRV.MAC.453, 23-Mar-77 21:35:26, Edit by MCLEAN
;SOME FIXUP
;<3-MONITOR>TTYSRV.MAC.452, 22-Mar-77 00:31:46, Edit by MCLEAN
;CHANGE FROM SM10 TO DZ11 IN LABELS
;<3-MONITOR>TTYSRV.MAC.451, 20-Mar-77 13:46:27, Edit by MCLEAN
;PUT TTSMVT BACK IN
;<3-MONITOR>TTYSRV.MAC.450, 20-Mar-77 02:52:57, Edit by MCLEAN
;TEMP REMOVE TTSMVT
;<3-MONITOR>TTYSRV.MAC.449, 20-Mar-77 02:47:03, Edit by MCLEAN
;REORGANIZATION INTO DEVICE AND DEVICE INDEPENDENT CODE
;<3-MONITOR>TTYSRV.MAC.447, 19-Mar-77 12:07:21, EDIT BY HALL
;TCO 1740 - CLEAR TTFWK IN TTFWAK - WAS CAUSING TOO MANY WAKEUPS
;<3-MONITOR>TTYSRV.MAC.446, 18-Mar-77 10:10:11, EDIT BY HALL
;TCO 1740 - MAKE BUGCHK'S PRINT LINE NUMBER
;<3-MONITOR>TTYSRV.MAC.445, 15-Mar-77 17:05:54, EDIT BY HALL
;TCO 1740 - MADE TTHU0 CALL FIXARG BEFORE CALLING DTEQ
;<3-MONITOR>TTYSRV.MAC.444, 14-Mar-77 18:42:42, EDIT BY HALL
;TCO 1740 - BUG FIX IN SNDFNC TO SEND CORRECT FUNCTION TO FRONT END
;<3-MONITOR>TTYSRV.MAC.443, 14-Mar-77 16:06:25, EDIT BY HALL
;TCO 1740 - BUG FIX IN TTRSRT, CHANGED GETLIN TO UNDERSTAND .FEDH1 DEVICE
;<3-MONITOR>TTYSRV.MAC.442, 13-Mar-77 00:32:45, Edit by MCLEAN
;MOVE DTRMEN AND DTRMDS TO TTYSRV IN PREPARATION FOR RE-ORGANIZATION
;<1MCLEAN>TTYSRV.MAC.456, 13-Mar-77 15:05:13, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.455, 13-Mar-77 14:27:37, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.454, 12-Mar-77 17:04:28, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.453, 12-Mar-77 17:01:21, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.452, 12-Mar-77 16:52:59, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.451, 12-Mar-77 16:45:21, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.450, 12-Mar-77 16:32:02, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.449, 12-Mar-77 16:28:45, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.448, 12-Mar-77 16:25:06, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.447, 12-Mar-77 16:20:45, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.446, 12-Mar-77 16:00:42, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.445, 12-Mar-77 15:13:04, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.444, 12-Mar-77 15:07:52, Edit by MCLEAN
;<1MCLEAN>TTYSRV.MAC.443, 12-Mar-77 14:52:39, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.441, 11-Mar-77 15:30:29, EDIT BY HALL
;TCO 1740 - BUG FIX IN TTC7N - CTRL/C ON PERMANENT BLOCK COULD CAUSE
;	JOB CREATION BECAUSE TT%BAC NOT CHECKED
;<3-MONITOR>TTYSRV.MAC.440, 11-Mar-77 01:16:36, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.439, 11-Mar-77 01:04:34, Edit by MCLEAN
;REMOVE BUG MESSAGES
;<3-MONITOR>TTYSRV.MAC.438,  3-Mar-77 10:12:59, EDIT BY HALL
;TCO 1740 - MAKE SENDALL WORK FOR FE LINES, WORK ON REMOTE LINES
;	MOVE TTCS WORDS AND TT%FSP INTO STATIC DATA, REMOVE CLEARING
;	OF DYNAMIC DATA (DONE BY ASGRES)
;<3-MONITOR>TTYSRV.MAC.437, 24-Feb-77 16:34:41, EDIT BY HALL
;TCO 1740 - BUG FIXES
;<3-MONITOR>TTYSRV.MAC.436, 23-Feb-77 21:52:38, EDIT BY HALL
;TCO 1740
;<3-MONITOR>TTYSRV.MAC.435, 23-Feb-77 20:52:37, EDIT BY HALL
;TCO 1740 - MASSIVE REORGANIZATION
;<3-MONITOR>TTYSRV.MAC.434,  2-Feb-77 10:09:24, Edit by HESS
;TCO 1728 - MAKE TAB A PUNCTUATION CHARACTER IN WAKEUP TABLE
;<3-MONITOR>TTYSRV.MAC.432, 18-Jan-77 11:24:26, EDIT BY HALL
;MASSIVE COMMENTS
;<3-MONITOR>TTYSRV.MAC.431, 13-Jan-77 14:17:59, Edit by LCAMPBELL
;TCO #1712
;<3-MONITOR>TTYSRV.MAC.430,  3-Jan-77 19:18:08, EDIT BY HELLIWELL
;CHANGE TTYPI1 AND TTYPI2 BUGCHK'S TO BUGINF'S
;<3-MONITOR>TTYSRV.MAC.429, 27-Dec-76 17:37:29, EDIT BY HURLEY
;<3-MONITOR>TTYSRV.MAC.428, 14-Dec-76 17:22:44, EDIT BY MILLER
;FIX TTMSG2
;<3-MONITOR>TTYSRV.MAC.427, 12-Dec-76 04:55:06, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.426, 11-Dec-76 20:30:57, EDIT BY HELLIWELL
;FIX TRANSLATION BUG IN FIXARG
;<3-MONITOR>TTYSRV.MAC.425, 10-Dec-76 15:21:14, EDIT BY HELLIWELL
;<2-MONITOR>TTYSRV.MAC.418, 10-Dec-76 15:03:56, EDIT BY HELLIWELL
;MOVE LINE NUMBER TRANSLATION FROM DTESRV(DTEFLO) TO TTYSRV
;<3-MONITOR>TTYSRV.MAC.423,  8-Dec-76 13:36:32, EDIT BY MILLER
;<3-MONITOR>TTYSRV.MAC.422,  8-Dec-76 12:49:44, EDIT BY MILLER
;TCO 1681. PUT IN CARRIER OFF INTERRUPT (CODE .TICRF)
;<3-MONITOR>TTYSRV.MAC.421,  1-Dec-76 21:33:14, Edit by MCLEAN
;<2-MONITOR>TTYSRV.MAC.415,  1-Dec-76 16:06:35, EDIT BY HELLIWELL
;ADD PROPER CONDITIONALS TO TTSNTS/TTRNTS
;<3-MONITOR>TTYSRV.MAC.419,  1-Dec-76 01:59:32, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.418, 28-Nov-76 22:34:01, Edit by MCLEAN
;<3-MONITOR>TTYSRV.MAC.417, 26-Nov-76 14:11:45, Edit by MCLEAN
;TCO1669 EXTENDED ADDRESSING
;<2-MONITOR>TTYSRV.MAC.414, 19-Nov-76 17:21:43, EDIT BY MURPHY
;<2-MONITOR>TTYSRV.MAC.413, 19-Nov-76 10:38:07, EDIT BY HURLEY
;<2-MONITOR>TTYSRV.MAC.412, 18-Nov-76 17:16:35, EDIT BY MURPHY
;<2-MONITOR>TTYSRV.MAC.411, 16-Nov-76 18:39:32, EDIT BY MURPHY
;TCO #1665 - SFCOC CODE 2/3 DISTINCTION FOR LF
;<2-MONITOR>TTYSRV.MAC.410, 15-Nov-76 18:15:53, EDIT BY HELLIWELL
;ADD DC10/DTE COMBINED CODE
;<2-MONITOR>TTYSRV.MAC.408,  4-Nov-76 14:54:44, EDIT BY HURLEY
;<2-MONITOR>TTYSRV.MAC.407,  4-Nov-76 14:49:32, EDIT BY HURLEY
;TCO 1604 - ADD TTY SYSTEM MESSAGE SUPPRESSION MTOPR
;<MON1065>TEST.MAC.2, 28-Oct-76 21:07:12, EDIT BY HELLIWELL
;COMBINED DC10/DTE
;<2-MONITOR>TTYSRV.MAC.405, 26-Oct-76 13:23:06, EDIT BY HURLEY
;<2-MONITOR>TTYSRV.MAC.404, 26-Oct-76 11:22:09, EDIT BY MILLER
;TCO 1627. ADD PARITY TO SEND ALL MESSAGES
;<2-MONITOR>TTYSRV.MAC.403, 25-Oct-76 13:54:07, EDIT BY HURLEY
;MAKE TTMSG FAIL IF PAGE CONTAINING THE STRING IS NON EXISTENT
;<2-MONITOR>TTYSRV.MAC.402, 23-Oct-76 17:12:49, EDIT BY MILLER
;FIX SNDXON AND SNDXOF TO USE MSTRDT
;<2-MONITOR>TTYSRV.MAC.401, 23-Oct-76 13:01:24, EDIT BY OSMAN
;TCO 1618 - BIN,RSCAN,BKJFN,BIN SHOULD READ LAST REAL CHAR
;<2-MONITOR>TTYSRV.MAC.400, 22-Oct-76 23:32:39, EDIT BY OSMAN
;TCO 1619 - MAKE BKJFN USE REAL TERMINAL IF RESCANNING, BUT
;	HAVEN'T STARTED READING RSCAN BUFFER YET
;<2-MONITOR>TTYSRV.MAC.399, 11-Oct-76 08:32:15, EDIT BY HURLEY
;TCO 1582 - MAKE .STPAR ACCEPT .NULIO AS A DESIGNATOR
;<2-MONITOR>TTYSRV.MAC.398,  8-Oct-76 08:56:57, EDIT BY MILLER
;ALLOW ZERO LENGTH AND WIDTH SETTINGS IN STPAR JSYS
;<2-MONITOR>TTYSRV.MAC.397,  7-Oct-76 10:40:46, EDIT BY MILLER
;FIX TTILIN TO SET UP WIDTH AND LENGTH CORRECTLY
;<2-MONITOR>TTYSRV.MAC.396,  7-Oct-76 10:05:13, EDIT BY MILLER
;CHECK VALUES OF LENGTH AND WIDTH SETTINGS
;<2-MONITOR>TTYSRV.MAC.395,  6-Oct-76 16:10:54, EDIT BY HURLEY
;TCO 1571 - MAKE RSCAN BUFFER BE DYNAMIC
;<2-MONITOR>TTYSRV.MAC.394,  6-Oct-76 16:06:34, EDIT BY MILLER
;ADD SET/READ FUNCTIONS FOR WIDTH AND LENGTH
;<2-MONITOR>TTYSRV.MAC.393,  6-Oct-76 15:40:59, EDIT BY MILLER
;TCO 1570. ALLOW TTY WIDTHS AND LENGTHS > 127
;<2-MONITOR>TTYSRV.MAC.392, 20-Aug-76 11:07:04, EDIT BY OSMAN
;<2-MONITOR>TTYSRV.MAC.391, 20-Aug-76 11:03:24, EDIT BY OSMAN
;TCO 1498 - MAKE SIBE RETURN CORRECT COUNT IN AC2 MORE OFTEN
;<2-MONITOR>TTYSRV.MAC.390, 17-Aug-76 13:06:58, EDIT BY HURLEY
;<2-MONITOR>TTYSRV.MAC.389, 17-Aug-76 11:36:34, EDIT BY HURLEY
;FIXED TLINK TO USE 36 BIT USER NUMBERS
;<2-MONITOR>TTYSRV.MAC.388, 29-Jun-76 20:42:47, EDIT BY MILLER
;TCO 1382 - MAKE STTYP GIVE CORRECT ERROR CODE
;<1B-MONITOR>TTYSRV.MAC.386, 15-JUN-76 17:23:23, EDIT BY HURLEY
;TCO # 1424 - FIX UP TI TERMINAL WIDTH (80) AND FILL
;<1B-MONITOR>TTYSRV.MAC.385, 11-JUN-76 17:28:14, EDIT BY OSMAN
;TCO 1404 - MAKE STTYP GIVE CORRECT ERROR RETURNS
;<1B-MONITOR>TTYSRV.MAC.384, 11-JUN-76 10:23:50, EDIT BY JMCCARTHY
;TCO 1384 - PTY'S GET DETACHED ON POWER FAIL RESTART
;<1B-MONITOR>TTYSRV.MAC.383,  7-JUN-76 18:12:14, EDIT BY HALL
;TCO # 1352 - MAKE TTFWAK GLOBAL
;<1B-MONITOR>TTYSRV.MAC.382,  7-JUN-76 15:37:12, EDIT BY MILLER
;TCO 1356. FIX DOBE FOR SECONDARY PROTOCOL.
;<1B-MONITOR>TTYSRV.MAC.381,  7-JUN-76 14:28:16, EDIT BY HURLEY
;TCO # 1352 - MAKE DETACHED FORK TO NO LONGER WAIT ON DETACHED TTY
;<1B-MONITOR>TTYSRV.MAC.380, 12-MAY-76 11:17:52, EDIT BY MILLER
;<1B-MONITOR>TTYSRV.MAC.3,  6-MAY-76 11:28:26, EDIT BY MILLER
;FIX OFF X-ON NOT RIGHT. REMOVE FOR NOW
;<1B-MONITOR>TTYSRV.MAC.2, 28-APR-76 10:16:21, EDIT BY MILLER
;TCO 1266. FIX X-OFF FRO BINARY LINES AND TO CLEAR COUNTER
;<1B-MONITOR>TTYSRV.MAC.1,  6-APR-76 17:20:31, EDIT BY MILLER
;TCO 1242. FIX AUTO DETACH
;<1A-MONITOR>TTYSRV.MAC.378,  4-APR-76 11:44:23, EDIT BY MILLER
;TCO 1237. FIX LINKING
;<1A-MONITOR>TTYSRV.MAC.377,  1-APR-76 14:00:41, EDIT BY HURLEY
;TCO # 1231 - ADD HARDWARE TABS TO VT52
;<1MONITOR>TTYSRV.MAC.376, 16-MAR-76 13:01:40, EDIT BY MILLER
;TCO 1177. DON'T SEND FLUSH ON PTY
;<1MONITOR>TTYSRV.MAC.375,  9-MAR-76 21:15:08, EDIT BY MILLER
;<1MONITOR>TTYSRV.MAC.374,  9-MAR-76 10:11:46, EDIT BY MILLER
;<1MONITOR>TTYSRV.MAC.373,  7-MAR-76 16:14:03, EDIT BY MILLER
;<1MONITOR>TTYSRV.MAC.372,  7-MAR-76 15:16:33, EDIT BY MILLER
;TCO 1153. FIX STO CODE
;<1MONITOR>TTYSRV.MAC.371,  4-MAR-76 13:12:35, EDIT BY MILLER
;TCO 1151. ONLY SEND ONE X-OFF ON BIGBUF QUOTA VIOLATION
;<1MONITOR>TTYSRV.MAC.370,  2-MAR-76 14:01:58, EDIT BY MILLER
;<1MONITOR>TTYSRV.MAC.369,  2-MAR-76 13:50:58, EDIT BY MILLER
;TCO 1145. ENABLE/DISABLE REMOTE ANSWER
;<2MONITOR>TTYSRV.MAC.368, 17-FEB-76 09:29:03, EDIT BY MILLER
;TCO 1098. DETACH ALL JOBS ON POWER RESTART
;<2MONITOR>TTYSRV.MAC.367, 16-FEB-76 10:26:22, EDIT BY MILLER
;TCO 1095. SEND X-OFF TO LINE CAUSING BIG BUFFER OVERFLOW
;<2MONITOR>TTYSRV.MAC.366, 15-FEB-76 13:10:34, EDIT BY MILLER
;TCO 1094. FIX MULTIPLE FORKS IN INPUT WAIT
;<2MONITOR>TTYSRV.MAC.365, 15-FEB-76 11:59:52, EDIT BY MILLER
;TCO 1093. ADD RELOAD ENTRY TO DTE VECTOR
;<2MONITOR>TTYSRV.MAC.364,  2-FEB-76 11:32:06, EDIT BY KIRSCHEN
;MCO 48 MAKE EMPTYING BIG BUFFER AND CONTROL QUEUE CHECKING INTERRUPTABLE
;<2MONITOR>TTYSRV.MAC.363,  2-FEB-76 10:47:47, EDIT BY KIRSCHEN
;MCO 47 CHANGE 4 CALL'S FOLLOWED BY RET'S TO CALLRET'S
;<2MONITOR>TTYSRV.MAC.362, 27-JAN-76 17:25:51, EDIT BY MILLER
;MCO 36 FIX SNDXOF TO TERMINAL
;<2MONITOR>TTYSRV.MAC.361, 27-JAN-76 13:58:17, EDIT BY MILLER
;MCO 35. FIX X-OFF FOR DEFERRED INT CHARACTERS
;<2MONITOR>TTYSRV.MAC.360, 25-JAN-76 13:32:01, EDIT BY MILLER
;mco #27. make ttdtrm swappable
;<2MONITOR>TTYSRV.MAC.359, 25-JAN-76 11:22:46, EDIT BY MILLER
;MORE EDITS FOR MCO #21
;<2MONITOR>TTYSRV.MAC.358, 23-JAN-76 13:19:05, EDIT BY MILLER
;MCO #21. ALLOW MASTER -11 TO BE ANYWHERE
;<2MONITOR>TTYSRV.MAC.357, 20-JAN-76 14:36:30, EDIT BY MURPHY
;<2MONITOR>TTYSRV.MAC.356, 20-JAN-76 13:35:55, EDIT BY MURPHY
;MCO #13 - ^C IN BINARY MODE, WAKEUP AFTER CONTINUE FROM ^C
;<2MONITOR>TTYSRV.MAC.355, 19-JAN-76 12:28:20, EDIT BY MURPHY
;<2MONITOR>TTYSRV.MAC.354, 19-JAN-76 12:21:55, EDIT BY MILLER
;MCO #10 . FIX SEND TO SINGLE LINE.
;<1MONITOR>TTYSRV.MAC.3, 12-JAN-76 12:10:55, EDIT BY MILLER
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1977 BY DIGITAL EQUIPMENT CORPORATION

	SEARCH PROLOG

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

;TELETYPE SERVICE ROUTINES - D. MURPHY

	SUBTTL DATA DEFINITIONS

;AC DEFINITIONS USED HEREIN

DEFAC (FX,Q3)			;FORK INDEX

;
; TTVTXX -- VECTOR TABLE FOR DATA AND ROUTINE OFFSETS INTO DEVICE
;SPECIFIC VECTOR
;

;TELETYPE SERVICE CONSISTS OF THIS MODULE - TTYSRV - WHICH CONTAINS ALL
;DEVICE-INDEPENDENT CODE, AND ONE MODULE FOR EACH LINE TYPE.  THE
;LATTER MODULES CONTAIN ALL THE DEVICE-DEPENDENT CODE FOR THEIR LINE TYPE.

;EACH MODULE HAS A TRANSFER VECTOR OF THE NAME TTXXVT, WHERE XX IS
;UNIQUE FOR EACH LINE TYPE; THE MODULE NAME IS TTXXDV IF LINES OF THAT
;TYPE EXIST OR TTXXDM IF LINES OF THAT TYPE DO NOT EXIST.

;THE DEFINITIONS BELOW ARE THE OFFSETS INTO THOSE TRANSFER VECTORS

DDLEN=0			;LENGTH OF DYNAMIC DATA FOR THIS TYPE
TT1LIN=1			;FIRST LINE OF THIS TYPE/-1 NO LINES
TTVT00=2			;INITIALIZE TABLES AT SYSTEM STARTUP
TTVT01=3			;ACTIVATE LINES AT STARTUP OR RESTART
TTVT02=4			;CLEAR OUTPUT BUFFER
TTVT03=5			;SET LINE SPEED
TTVT04=6			;READ LINE SPEED
TTVT05=7			;SET TERMINAL/NON-TERMINAL STATUS
TTVT06=10			;READ TERMINAL/NON-TERMINAL STATUS
TTVT07=11			;STO JSYS
TTVT08=12			;STPAR JSYS
TTVT09=13			;CKPHYT - SEE IF PHYSICAL TERMINAL
TTVT10=14			;PROCESS XON FROM TERMINAL
TTVT11=15			;DEASIGN TTY DATA BASE
TTVT12=16			;TCOUT - ADD PARITY TO CHARACTER
TTVT13=17			;START OUTPUT TO LINE
TTVT14=20			;SEND XOFF TO TERMINAL
TTVT15=21			;SEND XON TO TERMINAL
TTVT16=22			;TTCH7 - PROCESS TTCS WORDS
TTVT17=23			;HANDLE CARRIER/ON
TTVT18=24			;HANDLE CARRIER/OFF
TTVT19=25			;HANGUP, REACTIVATE REMOTE LINE
TTVT20=26			;PROCESS XOFF FROM TERMINAL
TTVT21=27			;HANDLE CTRL/C FROM INACTIVE LINE
TTVT22=30			;BIGSTO - STORE CHARACTER IN TTBBUF
TTVT23=31			;TTSND -SEND CHARACTER TO LINE
TTVT24=32			;DETACH JOB ON THIS LINE
TTVT25=33			;HANDLE OVERFLOW OF TTBBUF
TTVT26=34			;REMOVE CHARACTER FROM TTBBUF
TTVT27=35			;DO TTMSG FOR ONE LINE?
TTVT28=36			;ENABLE/DISABLE DATASETS
TTVT29=37			;TTCH7 AFTER EMPTYING TTBBUF
TTVT30=40			;CLEAR INPUT BUFFER
TTVT31=41			;DOBE
TTVT32=42			;INPUT GA
TTVT33=43			;SET INIT. VALUES FOR A LINE
TTVT34=44			;SOBE
TTVT35=45			;WAKEUP IF OUTPUT BUFFER EMPTY
TTVT36==46			;SENDALL FOR ONE LINE
TTVT37==47			;SENDALL FOR ALL LINES
TTVT38==50			;ADJUST WAKEUP CLASS
TTVTMX==51			;MAXIMUM NUMBER OF VECTOR ENTRIES

;VECTOR TABLE FOR DEVICE TYPES TO DEVICE SPECIFIC VECTORS
;INDEXED BY DEVICE TYPE

TTLINV:	IFIW!TTFEVT		;FE VECTOR TABLE
	IFIW!TTMCVT		;MCB VECTOR TABLE
	IFIW!TTPTVT		;PTY VECTOR TABLE
	IFIW!TTDCVT		;DC10 VECTOR TABLE
	IFIW!TTNTVT		;NETWORK VECTOR TABLE
	IFIW!TTDZVT		;DZ11 VECTOR TABLE
TTLINO=.-TTLINV
   IFN <TTLINO-NLTYPS>,<PRINTX %% LINE TYPE TABLES OF INCORRECT LENGTH>
;FNCALL - MACRO TO DO THE DEVICE DEPENDENT SUBROUTINE CALLS.
;FNJRST - MACRO TO DO THE DEVICE DEPENDENT JUMPS
;FNXCT - MACRO TO DO THE DEVICE DEPENDENT XCTS
;
; CALLING SEQUENCE:
;
;	LINDX - FREE INDEX REGISTER
;	STGADR - ADDRESS OF DEVICE TYPE #
;	INDX - INDEX INTO DEVICE TYPE TABLE
;	VECTOR - OFFSET INTO DEVICE DEPENDENT CODE  TABLE
;
	DEFINE FNCALL (LINDX,STGADR,INDX,VECTOR) <
	LOAD LINDX,STGADR,INDX
	MOVE LINDX,TTLINV(LINDX)
	CALL @VECTOR(LINDX)
	>
;
	DEFINE FNJRST ( LINDX,STGADR,INDX,VECTOR) <
	LOAD LINDX,STGADR,INDX
	MOVE LINDX,TTLINV(LINDX)
	JRST @VECTOR(LINDX)
	>
;
	DEFINE FNXCT ( LINDX,STGADR,INDX,VECTOR) <
	LOAD LINDX,STGADR,INDX
	MOVE LINDX,TTLINV(LINDX)
	XCT VECTOR(LINDX)
	>


;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,.SAVLN>

;.SAVLN - SUPPORT ROUTINE FOR SAVELN MACRO.  PUTS AC 2 ON THE STACK
;AND CALLS THE ROUTINE THAT EXECUTED THE MACRO.  WHEN THAT ROUTINE
;RETURNS, IT RETURNS TO THIS ROUTINE TO POP THE STACK AND RETURN TO THE
;ORIGINAL CALLER

	RESCD

.SAVLN:	PUSH P,T2		;SAVE T2
	CALL 0(CX)		;GO BACK INLINE
	SKIPA			;NON-SKIP RETURN
	AOS -1(P)		;SKIP RETURN
	POP P,T2		;RESTORE T2
	RET
;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
   >
;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)
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
DEFSTR TTSTY,TTSTAT,17,6	;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
;RS TTACTL,NLINES		;ADDRESS OF DYNAMIC DATA IF ACTIVE
				; OR -1 IF BECOMING ACTIVE
				; OR 0 IF INACTIVE
;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
;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			;CTRL/S WAS TYPED
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%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 TTLCK,TTFLG1,TT%LCK

TTDAT1==1
DEFSTR TLTYP,TTDAT1,8,6		;LINE TYPE (COPIED FROM TTSTAT)
DEFSTR TTTYP,TTDAT1,17,9	;TERMINAL TYPE
DEFSTR TINTL,TTDAT1,35,18	;INTERNAL LINE NUMBER (INDEX INTO STATIC DATA)

TTSAL1==2
DEFSTR TSALC,TTSAL1,35,36	;SENDALL CHARACTER COUNT

TTSAL2==3
DEFSTR TSALP,TTSAL2,35,36	;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,12,5	;NO. INPUT BUFFERS
DEFSTR TTNOU,TTBFRC,17,5	;NUMBER OUTPUT BUFFERS
DEFSTR TIMAX,TTBFRC,26,9	;MAX BYTES IN INPUT BUFFER
DEFSTR TOMAX,TTBFRC,35,9	;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 TYLMD,TTDAT2,8,2		;TERMINAL DATA MODE FOR LAST INPUT CHAR
DEFSTR TYLCH,TTDAT2,17,9	;LAST CHAR REMOVED FROM INPUT BUFFER
DEFSTR TPWID,TTDAT2,26,9	;PAGE WIDTH

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

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

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

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

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

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

TTFRK1==25
DEFSTR TTPFK,TTFRK1,35,18	;FORK WHICH IS TOP FORK OF A SCTTY TREE
				;-1 IF NONE
				;HALF WORD SPARE HERE

;LENGTHS OF DYNAMIC BLOCKS

TTDDLN=26			;DEFAULT DYNAMIC DATA SIZE
MSGLEN==11			;SIZE OF MESSAGE BLOCK
SHTLEN==5			;SIZE OF SHORT (SENDALL) 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==:77B23			;WAKEUP FIELD
TT%WK0==:1B18			;WAKEUP CLASS 0 (UNUSED)
TT%WK1==:1B19			;WAKEUP CLASS 1 (UNUSED)
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
>
TTOIRQ==1B24			;OUTPUT INTERRUPT REQUEST (SOFTWARE)
DLSCXF==:1B25			;CARRIER XITION FLAG (SOFTWARE)
CARONB==:1B33

TTXECO==1B27			;INPUT STREAM - CHARACTER ALREADY ECHOED
MAXBBC==TTBSIZ/4		;MAX ENTRIES ALLOWED IN BIGBUF FOR THIS
				; LINE
MXBBC1==TTBSIZ/10		;WHEN AN X-ON IS ALLOWED AGAIN
MAXABC==TTBSIZ/2		;LEVEL AT WHICH THIS LINE IS A BAD GUY
XOFFC=="S"-100			;THE X-OFF CODE (TO SEND)
XONC=="Q"-100			;THE X-ON CODE (TO SEND)
MINICT==40			;WHEN TO SEND AN X-ON

TTLIND=="'"			;UPPER CASE INDICATION CHARACTER FOR OUTPUT
TTCIND=="^"			;CONTROL INDICATION CHARACTER FOR OUTPUT
TTFILL==0			;FILLER CHARACTER
PGMONC=="Q"-100			;XON - RESTART OUTPUT IN PAGE MODE (RECEIVED)
PGMOFC=="S"-100			;XOFF - STOP OUTPUT IN PAGE MODE (RECEIVED)

TTOESC==400			;FUNCTION ESCAPE IN OUTPUT STREAM
TTOPFC==420			;PAGE FULL CODE IN OUTPUT STREAM
TABSIZ==:^D8			;STANDARD TAB SPACING
DFLWID==1			;OLD STYLE DEFAULT WIDTH
DFLLEN==1			;OLD STYLE DEFAULT LENGTH
	RESCD

;INDEX TO DEV TABLES FOR TTY0

DEVTT0:: DVXTT0


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

NORMTF::^D66B10+^D72B17+17B23+2B25+1B26+1B29+1B31
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
;POINTERS TO TERMINAL TYPE FIELDS
;ASSUME TYPE NUMBER IN 3

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

SCNTIM==^D1000			;CONTROLLER CHECK INTERVAL (1 SEC)
	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
	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

	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 IN THE
;VECTOR TO CONTAIN THE NUMBER OF THE FIRST LINE.

	;..
	MOVEI T2,0		;T2/ FIRST LINE IS LINE 0
	MOVEI T3,TT.FE		;T3/ CODE FOR FRONT-END LINES
	MOVEI T4,NTTFE		;T4/ NUMBER OF FRONT END LINES
	CALL SETTYP
	MOVEI T3,TT.DZ		;T3/ CODE FOR DZ11 LINES
	MOVEI T4,NTTDZ		;T4/ NUMBER OF DZ11 LINES
	CALL SETTYP
	MOVEI T3,TT.D10		;T3/ CODE FOR DC10 LINES
	MOVEI T4,NTTD10		;T4/ NUMBER OF DC10 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.NVT		;T3/ CODE FOR ARPANET LINES
	HRLI T4,-NTTNVT		;SET UP NVT PAR WITH -NTTNVT,,FIRST NVT
	HRR T4,T2		;GET FIRST NVT
	MOVEM T4,NVTPTR		;STORE IT AWAY
	MOVEI T4,NTTNVT		;T4/ NUMBER OF ARPANET LINES
	CALL SETTYP


;INITIALIZE POINTERS TO TTBBUF

	SETZM TTBIGO
	SETZM TTBIGC
	SETZM TTBIGI

	SETZM TTCQLN		;INITIALIZE FOR TTHNG4

	PUSH P,Q1		;SAVE A COUNTER REGISTER
	PUSH P,Q2		;SAVE ANOTHER REGISTER
	MOVEI Q1,NLTYPS		;FIND NUMBER OF LINE TYPES
TYINLP:	MOVE Q2,TTLINV-1(Q1)	;FIND VECTOR
	CALL @TTVT00(Q2)	;GO INIT L INES
	SOJG Q1,TYINLP		;DO ALL TYPES
	POP P,Q2
	POP P,Q1		;RESTORE
	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:	MOVE T1,TTLINV(T3)	;POINT TO VECTOR TABLE ENTRY
	JUMPG T4,SETTY2		;IF NO LINES OF THIS TYPE,
	SETOM TT1LIN(T1)	;SET FIRST LINE TO -1
	RET			; AND RETURN
SETTY2:	MOVEM T2,TT1LIN(T1)	;STORE FIRST LINE FOR THIS TYPE
SETTY1:	STOR T3,TTSTY,(T2)	;SAVE LINE TYPE FOR THIS LINE
	AOS T2			;NEXT LINE NUMBER
	SOJG T4,SETTY1		;GO DO THE NEXT LINE IN THIS TYPE
	CAMN T3,CTYTYP		;IS THIS THE LINE TYPE FOR THE CTY?
	JRST [	CALL INICTY	;YES. INITIALIZE IT
		AOS T2		;POINT TO NEXT LINE
		RET]
	RET
;INICTY - INITIALIZE THE CTY

;ACCEPTS:
;	T1/ ADDRESS OF LINE TYPE VECTOR TABLE
;	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
	HRR T1,DDLEN(T1)	; AND FULL LENGTH BLOCK
	HRLI T1,.RESP1		;INDICATE NOT SWAPPABLE
	MOVEI T2,.RESTP
	CALL ASGRES		;GET RESIDENT SPACE
	 BUG(HLT,NOCTY,<UNABLE TO ALLOCATE DATA FOR CTY>)
	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

; * * * *
;NEEDS WORK - CAN'T INIT TOO MANY WORDS
; * * * *

TTSETL:	LOAD T4,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T4,TTLINV(T4)	;GET ADDRESS OF VETOR TABLE
	MOVE T4,DDLEN(T4)	;GET LONG BLOCK LENGTH
	JRST TTSET
TTSETM:	MOVEI T4,MSGLEN		;INDICATE MESSAGE BLOCK
	JRST TTSET
TTSETS:	MOVEI T4,SHTLEN		;INDICATE SENDALL BLOCK
	JRST TTSET
TTSET:	SAVEQ
	FNJRST T3,TTSTY,(T2),TTVT33
TTSET1:	LOAD T3,TTSTY,(T2)	;GET LINE TYPE FROM STATIC
	STOR T3,TLTYP,(T1)	; AND COPY TO DYNAMIC
	MOVE Q1,NORMTY		;GET NORMAL TERMINAL TYPE
	STOR Q1,TTTYP,(T1)	;SET IN DYNAMIC DATA
	STOR T2,TINTL,(T1)	;MAKE DYNAMIC DATA POINT TO STATIC
	CAIN T4,SHTLEN		;IS THIS A SENDALL BLOCK?
	RET			;YES. NO MORE INITIAILIZATION
	MOVE T3,IBFRC		;GET DEFAULT BUFFER CONTROL
	MOVEM T3,TTBFRC(T1)	; AND STORE IN DYNAMIC DATA
	CAIN T4,MSGLEN		;IS THIS A MESSAGE-LENGTH BLOCK?
	RET			;YES. NO MORE INITIALIZATION
	MOVE Q1,TTICB1		;SETUP USUAL CONTROL CHARACTER MODES
	MOVEM Q1,FCMOD1(T1)
	MOVE Q1,TTICB2
	MOVEM Q1,FCMOD2(T1)
	SETOM TTLINK(T1)	;NO LINKS TO OTHER LINES
	MOVE Q1,NORMTF		;USUAL DEVICE FLAGS AND STATUS
	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
	STOR T3,TPWID,(T1)	;SET UP STANDARD WIDTH
	STOR T4,TPLEN,(T1)	;STORE PAGE LENGTH
	SETONE TWFRK,(T1)	;INDICATE NO FORK WAITING
	MOVE Q1,JOBNO		;GET THIS JOB NUMBER
	STOR Q1,TCJOB,(T1)	;INDICATE THAT IT OWNS THE TERMINAL
	SETONE TTPFK,(T1)	;NO SCTTY FORK YET
	RET
;TTSTRT - ACTIVATE ALL LINES.  USED ON RESTART AS WELL AS START

TTSTRT:	SETZM TTHNGT
	SETZM TTHNGN
	PUSH P,Q1		;SAVE A REGISTER
	PUSH P,Q2
	MOVEI Q1,NLTYPS		;GET THE COUNT OF TYPES
TYRSLP:	MOVE Q2,TTLINV-1(Q1)	;FIND VECTOR
	CALL @TTVT01(Q2)	;RESTART
	SOJG Q1,TYRSLP		;DO ALL LINES
	POP P,Q2
	POP P,Q1		;RESTORE
	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 STADYN		;IS LINE ACTIVE?
	 JUMPLE T2,TTRST2	;NOT AT ALL
	JE TTOTP,(T2),TTRST2	;ACTIVE IN SOME WAY. WAS OUTPUT IN PROGRESS?
	CALL TTSND0		;YES, RESTART IT
TTRST2:	POP P,T2		;RESTORE COUNTER AND LINE NUMBER
	AOBJN 2,TTRST1
	CALLRET TTSTRT		;ACTIVATE DATASETS, ETC.
;THE FOLLOWING ROUTINES PROVIDE THE MECHANISM FOR INSURING THAT A LINE
;REMAINS ACTIVE (AND THUS THE ADDRESS OF ITS DYNAMIC DATA REMAINS VALID)
;WHILE ITS DYNAMIC DATA IS BEING USED.  TO ADDRESS A LINE'S DYNAMIC DATA
;FROM PROCESS CONTEXT, DO THE FOLLOWING:

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

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

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

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

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

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

;STADYN - CONVERT STATIC LINE NUMBER TO DYNAMIC ADDRESS

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL STADYN

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

;CLOBBERS NO AC'S

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

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

   REPEAT 0,<			;UNUSED ROUTINE
;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
   >				;END OF REPEAT 0
;LCKTTY - GET ADDRESS OF DYNAMIC DATA AND PREVENT DEALLOCATION

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL LCKTTY

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

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

;CLOBBERS NO AC'S

LCKTTY::NOSKD1			;NO OTHER JOBS RUNNING UNTIL DATA LOCKED
	SKIPG T2,TTACTL(T2)	;ANY DATA BASE AT ALL?
	JRST [	SKIPE T2	;NOT FULLY ACTIVE. IS IT ASSIGNED?
		CAMN T2,[-1]	;OR BECOMING ACITVE?
		RETBAD (,<OKSKD1>) ;NOT A BLOCK
		TXZ T2,1B0	;MESSAGE OR SHORT. MAKE IT ADDRESSABLE
		CALL LCKTT	;LOCK IT
		RET]		;AND RETURN
	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:	SKIPE INSKED		;DON'T LOCK IF IN SCHEDULER
	RET
	NOINT			;BE NOINT WHILE LINE IS LOCKED
	INCR TTLCK,(T2)		;INCREMENT LINE'S LOCK COUNT
	OKSKD1			;ALLOW SCHEDULING ONCE LOCKED
	RET
;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
	OKINT			;ALLOW INTERRUPTS NOW THAT BLOCK IS UNLOCKED
	RET

ULKTMP:	PUSH P,T2
	LOAD T2,TINTL,(T2)
	BUG(CHK,ULKBAD,<UNLOCKING TTY WHEN COUNT IS ZERO>,T2)
	POP P,T2
	OKINT
	RET

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

ULKTT::	DECR TTLCK,(T2)
	RET
;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
	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.

	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

	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
	LOAD T1,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T1,TTLINV(T1)	;GET ADDRESS OF VETOR TABLE
	MOVE T1,DDLEN(T1)	;GET LONG BLOCK LENGTH
	HRLI T1,.RESP3		;T1/ INDICATE PROCESS CONTEXT
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 JRST TTYAO3		;NO SPACE AVAILABLE
	MOVE T2,TTYALN		;T2/ LINE NUMBER, T1/ ADDRESS OF DYNAMIC BLOCK
	CALL TTSETL		;INITIALIZE VALUES FOR TERMINAL
	MOVEM T1,TTACTL(T2)	;MAKE STATIC DATA POINT TO DYNAMIC
	RETSKP

;FAILED TO GET RESIDENT STORAGE. LET THE OPENF FAIL

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

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

TTYAO4:	JE TTPRM,(T2),RSKP
	JE TTBAC,(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

;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
	 SKIPA			;NOT FULLY ACTIVE
	JRST 1(T4)		;FULLY ACTIVE. WAKEUP
	SKIPG T2		;NOT FULLY ACTIVE. SHORT OR MESSAGE BLOCK?
	JRST 1(T4)		;NO. WAKEUP
	JRST 0(T4)		;YES. DON'T 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
	 SKIPA			;NOT FULLY ACTIVE
	JRST 1(T4)		;FULLY ACTIVE. WAKEUP
	SKIPN T2		;INACTIVE?
	JRST 1(T4)		;YES. WAKEUP
	JRST 0(T4)		;NO. DON'T 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
	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.

	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
	LOAD T1,TTSTY,(T2)	;GET THE LINE TYPE
	MOVE T1,TTLINV(T1)	;GET ADDRESS OF VETOR TABLE
	MOVE T1,DDLEN(T1)	;GET LONG BLOCK LENGTH
	HRLI T1,.RESP3		;T1/ INDICATE PROCESS CONTEXT
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 JRST TTYAC3		;NO SPACE AVAILABLE
	MOVE T2,TTYALN		;T2/ LINE NUMBER, T1/ ADDRESS OF DYNAMIC BLOCK
	CALL TTSETL		;INITIALIZE VALUES FOR TERMINAL
	MOVEM T1,TTACTL(T2)	;MAKE STATIC DATA POINT TO DYNAMIC
	RETSKP

;FAILED TO GET RESIDENT STORAGE. FAIL

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

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

TTYAC4:	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
;TTYDEA - DEALLOCATE A DYNAMIC BLOCK

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTYDEA

;RETURNS +1: FAILURE,
;		T1/ 1B0+ ADDRESSOF ROUTINE IF NEED TO DISMISS
;		T1/ ERROR CODE IF FAILED
;	 +2: SUCCESS

	SWAPCD
TTYDEA::FNJRST T1,TTSTY,(T2),TTVT11 ;GO DO DEVICE DEPENDENT STUFF
TTYDE0:	SAVELN
	STKVAR<TTYDLN,TTYDAD>
	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
	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 TTXON		;MAKE SURE IS NOT X-OFF'ED
	MOVE T2,TTYDLN		;GET BACK LINE NUMBER
	SETZM TTACTL(T2)	;INDICATE NO DYNAMIC DATA
	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(CHK,TTNAC7,<DEALLOCATING INACTIVE LINE>,T2)
	RETSKP

;DYNAMIC DATA IS LOCKED. RETURN TO CALLER TO WAIT FOR IT TO 
;BECOME UNLOCKED

TTYDE2:	MOVE T1,[TSACT3]	;POINT TO SCHEDULER TEST
	TXO T1,1B0		;INDICATE ROUTINE NAME
	RETBAD

;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?
	 SKIPA			;NO.
	CALL PTYFIN		;YES. INDICATE HUNGRY
	RETSKP
;TSACT3 - SCHEDULER TEST FOR ACTIVE LINE

;ACCEPTS:
;	T1/ LINE NUMBER

;CAUSES WAKEUP IF LOCK COUNT FOR THE DATA IS 0

	RESCD
TSACT3::HRRZ T2,T1		;T2/ LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST 1(T4)		;NOT ACTIVE. WAKE PROCESS
	JN TTSAL,(T2),TSAC31	;DON'T WAKE UP IF DOING SENDALL
	OPSTR <SKIPN>,TTLCK,(T2) ;IS LOCK COUNT DOWN TO 0 YET?
	JRST 1(T4)		;YES. WAKE UP
	PUSH P,T4		;SAVE RETURN PC
	CALL TTCBF2		;FLUSH OUTPUT BUFFERS
	POP P,T4		;RESTORE RETURN PC
TSAC31:	JRST 0(T4)		;NO. DON'T WAKE UP
;ASGMSG - ASSIGN BLOCK FOR MESSAGE
;ASGMSL- ASSIGN FULL LENGTH MESSAGE BLOCK FOR SPECIAL PURPOSES

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL ASGMSG
;	CALL ASGMSL

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

	RESCD
ASGMSG:	TDZA T4,T4		;EXTRA LENGTH
ASGMSL:	MOVEI T4,TTDDLN-MSGLEN	;"LONG MESSAGE BLOCK"
	STKVAR <ASGMLN>
	MOVEM T2,ASGMLN		;SAVE LINE NUMBER
	MOVSI T1,.RESP2		;INDICATE CAN'T TAKE PAGE FAULT
	HRRI T1,MSGLEN(T4)	;T1/ (SIZE,,PRIORITY)
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 RETBAD			;FAILED
	MOVE T2,ASGMLN		;GET LINE NUMBER
	CALL TTSETM		;INITIALIZE VALUES
	SETONE TTMES,(T1)	;INDICATE MESSAGE BLOCK
	TXO T1,1B0		;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,1B0		;RETURN ADDRESSABLE BLOCK
	RETSKP			;INDICATE SUCCESS
;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:
	STKVAR <ASGSLN>
	MOVEM T2,ASGSLN		;SAVE LINE NUMBER
	MOVSI T1,.RESP3		;INDICATE CAN TAKE PAGE FAULT
	HRRI T1,SHTLEN		;T1/ (SIZE,,PRIORITY)
	MOVEI T2,.RESTP
	CALL ASGRES		;GET SOME FREE SPACE
	 RETBAD			;FAILED
	MOVE T2,ASGSLN		;GET LINE NUMBER
	CALL TTSETS		;INITIALIZE VALUES
	SETONE TTSHT,(T1)	;INDICATE MESSAGE BLOCK
	RETSKP			;INDICATE SUCCESS
	SUBTTL JSYS SUPPORT ROUTINES

;TTCOBF - CLEAR OUTPUT BUFFER

;TTCOB1 - ENTRY POINT FOR CALLING FROM WITHIN TTYSRV

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTCOB1

;RETURNS +1: ALWAYS

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

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

TTCOB3:	CALL ULKTTY		;ALLOW DEALLOCATION
	RET
;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?
	JRST TTCBF1		;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
TTCBF1:	CALL TTCBF2		;CLEAR BUFFERS FOR THIS LINE
	RET
;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:	NOSKD1
	CHNOFF DLSCHN		;TURN OFF CHANNEL ALSO
	FNJRST C,TLTYP,(B),TTVT02

;HERE WHEN LINE IS NOT A FRONT END LINE OR WHEN FRONT END WORK HAS
;BEEN DONE

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
	CHNON DLSCHN
	CALL TTXON		;REACTIVATE OUTPUT IF NECESSARY
	OKSKD1
	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
	FNCALL T1,TLTYP,(T2),TTVT30 
	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
	DYNST			;GET BACK LINE NUMBER
	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
	CAMN T2,CTRLTT		;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
		CAIN T3,.CHCRT	;CR?
		AOJ T1,		;YES, LF STILL AVAILABLE
		JRST .+1]
	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::
	FNJRST T1,TLTYP,(T2),TTVT34
TTSBE1:	JN TTOTP,(T2),R		;NONSKIP IF OUTPUT IS STILL ACTIVE
	SKIPG 1,TTOCT(2)	;BYTES STILL IN -10 MEMORY
	RETSKP			;YES. SKIP
	RET			;NO. NONSKIP

;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::
	JN TTOTP,(T2),TTDBE1	;IF OUTPUT ACTIVE, GO DISMISS
	MOVE T1,TTOCT(2)	;ANY CHARACTERS IN BUFFER?
	JUMPG T1,TTDBE1		;YES DISMISS
	FNCALL T1,TLTYP,(T2),TTVT31 ;NO.  NOW EMPTY
	RETSKP			;SAY SO

;CHARACTERS ARE PRESENT. DISMISS UNTIL THEY ARE GONE

TTDBE1:	DYNST T1		;GET STATIC DATA ADDRESS
	CALL ULKTTY		;UNLOCK TTY
	HRLZS T1		;LINE # TO LH
	HRRI 1,TTOBET		;1/(LINE NUMBER,,ROUTINE TO CALL)
	MDISMS
	RET			;SAY NEED TO RETRY

;TTDIBE - DISMISS UNTIL INPUT BUFFER IS EMPTY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTDIBE

;RETURNS +1: BLOCKED. NEED TO TRY AGAIN
;	+2 DONE. BUFFER EMPTY

;WAITS UNTIL INPUT BUFFER IS EMPTY

TTDIBE::SKIPG TTICT(T2)		;BUFFER EMPTY NOW?
	RETSKP			;YES. DONE
	DYNST T1		;GET LINE NUMBER
	CALL ULKTTY		;UNLOCK TTY
	HRLZS T1		;LINE NUMBER TO LH
	HRRI T1,TTIBET		;SCHEDULER TEST
	MDISMS
	RET			;SAY BLOCKED
;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:
	HRRZ T2,T1		;GET LINE NUMBER
	CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 JRST 1(T4)		;NOT ACTIVE. THIS SHOULDN'T HAPPEN
	FNJRST T1,TLTYP,(T2),TTVT35
TTOBE1:	SKIPE TTOCT(T2)		;IS OUTPUT BUFFER EMPTY?
	JRST 0(4)		;NO. DON'T WAKE UP
	OPSTR <SKIPN>,TTOTP,(T2) ;OUTPUT ACTIVE?
	JRST 1(4)		;NO. WAKE UP
	JRST 0(4)		;YES. CAN'T UNLBLOCK

;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
	DYNST			;GET LINE NUMBER
	JE TTCON,(T2),R		;RETURN UNLESS CARRIER IS ON
	SETONE TT%CAR,T1	;INDICATE CARRIER ON
	RET

;TTSMOD - SET TERMINAL MODE

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

;RETURNS +1: ALWAYS

;IMPLEMENTS SFMOD JSYS

TTSMOD::PUSH P,1
;	TXNE 1,600000		;SKIP IF THESE BITS ARE ZERO
;	ITERR (DECRSV,<CALL ULKTTY>)	;BITS ON UNLOCK TTY AND RETURN ERROR
	XOR 1,TTFLGS(2)		;FIND THE CHANGED BITS
	ANDX 1,TT%OSP+TT%WAK+TT%ECO+TT%DAM ;CHANGE ONLY THESE BITS
	XORM 1,TTFLGS(2)
	LOAD T1,TT%DAM,TTFLGS(T2) ;GET TERMINAL DATA MODE
	STOR 1,TYLMD,(T2)	;CHANGE IT FOR PI LEV ALSO
	POP P,1
	CALL TTFWAK		;FORCE WAKEUP
	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 1,TTLPOS(2)	;SET LINE CHARACTER POSITION
	RET

;TTRCOC - READ CONTROL CHARACTER OUTPUT CONTROL WORDS

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTRCOC

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

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

;TTSCOC - SET CONTROL CHARACTER OUTPUT CONTROL WORDS

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

;	CALL TTSCOC

;RETURNS +1: ALWAYS

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

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTBKPT

;RETURNS +1: FAILURE
;	 +2: SUCCESS

TTBKPT::CAMN 2,CTRLTT		;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)]
	OPSTR <SKIPE>,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
;TTSSPD - CODE TO DO A SET LINE SPEED 
;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER
;	USER 3/ INPUT SPEED,,OUTPUT SPEED

;	CALL TTSSPD

;RETURNS +1: ALWAYS

;SETS SPEEDS OF FRONT END LINES ONLY. IGNORES ALL OTHERS
;IMPLEMENTS THE .MOSPD FUNCTION OF MTOPR

TTSSPD::
	CAIL B,NLINES		;VALID LINE NUMBER?
	RET			;NO. JUST RETURN QUIETLY
	FNJRST C,TTSTY,(B),TTVT03 ;YES GO SET LINE SPEED FOR THIS TYPE


;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
	FNJRST C,TTSTY,(B),TTVT04 ;YES GO TO DEV DEP CODE AND READ SPEED

;THIS IS A PHYSICAL TERMINAL. RETURN ITS SPEED

TTRSP1:	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
	OPSTR <SKIPE>,TTFEM,(B)	;REMOTE?
	TXO C,MO%RMT		;YES
	OPSTR <SKIPE>,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
;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
	FNJRST A,TTSTY,(B),TTVT05 ;YES GO SET STATUS FOR THIS LINE


TTSNT2:	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
	FNJRST A,TTSTY,(B),TTVT06 ;YES GO SET STATUS FOR THIS LINE TYPE


TTRNT1:	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
   REPEAT 0,<
	MOVEI 1,1B19
	SKIPE TTICT(2)		;ANY CHARS IN BFR?
	IORM 1,TTFORK(2)	;YES, WAKE JOB SO CHARS WILL BE TAKEN
   >
	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
				; IS FULL, RETURN NOT HUNGRY
REPEAT 0,<
	LOAD T3,TOMAX,(T2)	;IF THE OUTPUT BUFFER IS NEARLY FULL
	SUBI T3,^D10		; SUCH THAT INPUT WILL BE THROWN AWAY
	CAMLE T3,TTOCT(T2)	; RETURN NOT HUNGRY
>
	SKIPE FKINT(T1)		;IF INTERRUPT IS PENDING, SAY NOT HUNGRY
TTSTI1:	TDZA 1,1		;RETURN NOT HUNGRY
TTSTI2:	SETO 1,			;RETURN HUNGRY
	RET
;ROUTINES TO SET/READ MODE FIELDS. CALLED FROM MTOPR FUNCTIONS
;IN FILMSC

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

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

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

;SET/READ TERMINAL LENGTH
;SAME ARGS AS ABOVE

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

TTRLEN::LOAD T1,TPLEN,(T2)	;READ LENGTH
	RET			;DONE
	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

;	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::MCENT
	CALL CKMMOD		;IS CALLER IN MONITOR MODE?
	 JRST [	MOVE D,CAPENB	;NO. GET CAPS
		TXNE D,SC%WHL!SC%OPR ;IS HE PRIVILEGED?
		JRST .+1	;YES. ALLOW IT
		ITERR (GTDIX1)]	;NO. BOMB IT
	TRVAR <TTMSBY,TTMSCT>
	TLC B,-1
	TLCN B,-1		;HAD A -1 IN LH?
	HRLI B,(POINT 7,)	;YES. GET STANDARD BYTE POINTER
	UMOVEM B,B		;RETURN BYTE POINTER
	SKIPGE P3,A		;STORE LINE NUMBER IN PERMANENT AC
	JRST TTMS10		;USER WANTS ALL LINES

;USER SPECIFIED LINE NUMBER.  SEE IF DEVICE-DEPENDENT CODE WANTS TO DO
;A SENDALL

	TRZ P3,.TTDES		;NO. GET JUST LINE NUMBER
	MOVE B,P3
	FNCALL C,TTSTY,(B),TTVT27 ;WANT TO DO ONE?
	 JRST MRETN		;NO.

;EITHER ONE LINE WAS SPECIFIED AND SENDALL IS TO BE DONE, OR ALL LINES
;WERE SPECIFIED.  SET UP THE STRING IN A RESIDENT BLOCK

TTMS10:	CALL GETSAL		;SET UP SNDALL BUFFER WITH ONE LINE
	 ITERR

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

	SKIPN TTMSCT		;AT LEAST ONE BYTE?
	JRST TTMS55		;NO. GO FINISH 

;MESSAGE IS BUILT IN SNDALL BUFFER. IF SENDING TO ONE LINE, LET DEVICE CODE
;DECIDE WHETHER TO DO IT ITSELF OR RETURN HERE

	JUMPL P3,TTMS20		;SENDING TO ONE LINE?
	MOVE B,P3		;YES. GET LINE NUMBER
	FNCALL C,TTSTY,(B),TTVT36
	 JRST TTMS50		;DONE OR NOT DOING. GO GET MORE TEXT
	CALL SALLIN		;DO THE LINE
; * * * *
;WORK ON THIS
; * * * *
	 JFCL			;FAILED. IGNORE FOR NOW
	JRST TTMS50		;GO SEE IF THERE IS MORE TEXT

;HERE WHEN DOING ALL LINES

TTMS20:
	SETZ C,			;START WITH LINE TYPE 0
	JRST TTMS26		;GO GET ITS FIRST LINE

;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

	MOVE A,TTLINV(C)	;POINT TO VECTOR FOR THIS LINE
	CALL @TTVT37(A)		;LET DEVICE CODE DO WHAT IT WANTS
	 JRST TTMS21		;DON'T DO THIS LINE. GO ON TO NEXT LINE
	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
; * * * *
;WORK ON THIS
	 JFCL			;FAILED. IGNORE FOR NOW
; * * * *
	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

;GET THE FIRST LINE OF THIS LINE TYPE

TTMS26:	MOVE A,TTLINV(C)	;POINT TO VECTOR FOR THIS TYPE
	MOVE B,TT1LIN(A)	;GET FIRST LINE OF THIS TYPE
	CALL @TTVT37(A)		;SEE WHAT DEVICE WANTS TO DO
	 JRST TTMS21		;DON'T DO THIS LINE. GO ON TO NEXT LINE
	JUMPL B,TTMS24		;SKIP THE ENTIRE GROUP
	JRST TTMS22		;GO DO THIS LINE

;HERE WHEN ALL LINES HAVE BEEN PROCESSED FOR CURRENT BUFFERFUL.
;WAIT UNTIL ALL ARE SENT

TTMS50:
	SKIPN SALCNT		;HAVE ALL THE LINES FINISHED?
	JRST TTMS55		;YES. DONE WITH THIS LINE OF TEXT
	MOVEI A,TSTSAL		;A/ ROUTINE NAME
	MDISMS			;WAIT UNTIL ALL LINES HAVE FINISHED
	JRST TTMS55		;DONE

	RESCD
TSTSAL:	SKIPE SALCNT		;ANY LINES STILL DOING SENDALL?
	JRST 0(T4)		;YES. DON'T WAKE UP
	JRST 1(T4)		;NO. WAKE UP

	SWAPCD

TTMS55:	SETZM SNDALL		;RELEASE SENDALL BUFFER
	OKINT
	SKIPE TTMSBY		;DID USER HAVE MORE TEXT?
	JRST TTMS10		;YES. GO GET IT

TTMS60:	JRST MRETN
;GETSAL - GET SENDALL BUFFER AND STORE LINE OF TEXT IN IT

;RETURNS +1: FAILURE
;	 +2: SUCCESS,
;		TTMSCT/ COUNT OF BYTES
;		TTMSBY/ LAST BYTE

GETSAL:	CALL ASGALL		;GET THE BUFFER
	MOVE C,[POINT 8,SNDALL]	;POINTER TO DESTINATION
	MOVNI D,4		;NEG OF BYTES PER WORD
	IMULI D,SNDSIZ		;CALCULATE BYTES IN BUFFER
	HRLZS D			;FORM AOBJN WORD

;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 [CALL INTALL	;FAILED, GO CLEAR THE DATABASE LOCK
		OKINT		;ALLOW THE INTERRUPT
		RETBAD(ARGX10)]	;AND RETURN TO CALLER
	JUMPE P1,GETSA6		;STOP ON NULL
	ANDI P1,177		;USE ONLY 7-BIT ASCII
	SKIPL CHITAB(P1)	;NEED PARITY BIT?
	JRST GETSA2		;NO. DON'T TRY THEN
	TRO P1,200		;YES. APPLY IT THEN
GETSA2:	IDPB P1,C		;USE IT
	CAIE P1,.CHLFD		;A LINE FEED?
	JRST GETSA5		;NO. GO INCREMENT BYTE COUNT

;END OF LINE. INSERT 4 FILLS

	MOVEI P4,4		;FILLS TO DO
	MOVEI P2,TTFILL		;THE FILL CHARACTER
GETSA3:	AOBJN D,GETSA4		;MAKE SURE IS ROOM
	JRST GETSA6		;BUFFER IS FULL
GETSA4:	IDPB P2,C		;INSERT A FILL
	SOJG P4,GETSA3		;DO ALL FILLS

;FILL HAS BEEN ADDED.  GO OUTPUT THE LINE UNLESS NO TEXT PRECEDED THE
;LINE FEED.

	MOVEI P2,0(D)		;FIND OUT HOW MANY BYTES IN MESSAGE
	CAILE P2,6		;A NULL LINE?
	JRST GETSA6		;NO OUTPUT THIS LINE NOW
GETSA5:	AOBJN D,GETSA1		;INCREMENT COUNT OF MESSAGE, GO TO NEXT CHAR
GETSA6:	HRRZM D,TTMSCT		;SAVE COUNT OF CHARACTERS
	MOVEM P1,TTMSBY		;SAVE LAST BYTE COPIED
	RETSKP
	RESCD			;RESDIENT STUFF

INTALL:	SETZM SNDALL		;DONE WITH THE BUFFER
	RET			;GO BACK TO DTE SERVICE

WTALL:	MOVEI A,SEEALL		;MUST WAIT FOR BUFFER
	OKSKED			;TURN ON SCHEDULER
	MDISMS			;WAIT HERE
	RET			;GO TRY AGAIN

SEEALL:	SKIPE SNDALL		;SCHEDULER TEST FOR BUFFER AVAILABLE
	JRST 0(4)		;STILL IN USE
	JRST 1(4)		;AVAILABLE


;ROUTINE TO GET THE SNDALL BUFFER

ASGALL:	NOSKED			;MUST NOT BE INTERRUPTED
	SKIPE SNDALL		;AVAILABLE?
	JRST [	CALL WTALL	;NO. GO GET IT
		JRST ASGALL]	;GO TRY AGAIN
	SETOM SNDALL		;YES. GET IT
	NOINT
	OKSKED			;ALLOW SCHEDULING AGAIN
	RET			;AND RETURN
;SALLIN - DO SENDALL TO A NON-FE LINE

;ACCEPTS:
;	T2/ LINE NUMBER

	SWAPCD
SALLIN:
	SAVELN			;SAVE LINE NUMBER
	STKVAR <SALLLN>
	MOVEM T2,SALLLN		;SAVE LINE NUMBER
SALLI2:	NOSKED
	CALL STADYN		;DOES LINE ALREADY HAVE DYNAMIC DATA?
	 SKIPA			;NOT FULLY ACTIVE
	JRST SALLI5		;FULLY ACTIVE.
	JUMPG T2,SALLI5		;HAS A MESSAGE BLOCK. OK TO USE
	JUMPL T2,R		;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]
	NOSKED
	TXO T1,1B0		;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,1B0		;MAKE ADDRESSABLE BLOCK
	MOVE T2,T1
SALLI5:	AOS SALCNT		;INCREMENT COUNT OF LINES DOING SENDALL
	MOVE T1,[POINT 8,SNDALL]
	STOR T1,TSALP,(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
	OKSKED
	SETZ T3,		;FAKE OUT STRTOU
	CALL STRTOU		;START OUTPUT IF NEEDED
	RETSKP
;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
	OKSKED
	RET

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::
TTSTO2:	NOSKD1
	CHNOFF DLSCHN		;CAN'T ALLOW SCANNER PI HERE
	SKIPG TTOCT(B)		;ARE THERE ANY CHARACTERS?
	JRST TTSTO1		;NO. WAIT
	LOAD C,TLTYP,(B)
	FNJRST D,TLTYP,(B),TTVT07


;LINE TYPE CURRENTLY NOT SUPPORTED. RETURN A NULL TO THE CALLER

TTSTO4:	CHNON DLSCHN
	OKSKD1
	SETZ A,
	RETSKP

;PHYSICAL LINE. DON'T TAKE CHARACTER IF OUTPUT IS ENROUTE TO THE LINE

TTSTO3:	JN TTOTP,(B),TTSTO1	;WAIT IF OUTPUT IS ACTIVE

;TAKE A CHARACTER FROM THE OUTPUT BUFFER

TTSTO5:	STKVAR <TTSTSV>
	MOVEM C,TTSTSV		;SAVE LINE TYPE
	SKIPN C,TTOOUT(2)	;GET OUT POINTER
	BUG(HLT,TTOCN0,<TTSTO - NO BUFFER BUT COUNT NON-0>)
	HRRZ D,C
	TDNN C,WRPMSK		;AT END OF THIS BUFFER?
	HRR C,1-TTSIZ(4)	;YES. POINT TO NEXT BUFFER
	MOVEM C,TTOOUT(2)
	ILDB 1,TTOOUT(2)	;GET NEXT CHARACTER FROM OUTPUT BUFFER
	TXZE A,TTOESC		;AN ESCAPE CHARACTER?
	JRST [	MOVE D,TTSTSV	;GET LINE TYPE
		CAIN D,TT.PTY	;A PTY?
		JRST .+1	;YES. ALLOW IT THEN
		MOVEM C,TTOOUT(B) ;NO. RESTORE BYTE POINTER
		JRST TTSTO1]	;AND FORCE A BLOCK

;CHARACTER HAS BEEN REMOVED AND POINTER UPDATED. REDUCE COUNT OF
;CHARACTERS IN OUTPUT BUFFER AND RETURN CHARACTER TO CALLER

	SOSG TTOCT(2)		;UPDATE COUNT OF CHARACTERS
	CALL TTRLOB		;BUFFER IS EMPTY. RELEASE IT
	CHNON DLSCHN
	OKSKD1
	RETSKP

;WAIT UNTIL BUFFER BECOMES NONEMPTY AND LINE INACTIVE

TTSTO1:	CHNON DLSCHN
	OKSKD1
	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
	OPSTR <SKIPN>,TTOTP,(T2) ;IS LINE ACTIVE?
	SKIPN TTOCT(T2)		;NO. ARE THERE CHARACTERS?
	JRST 0(T4)		;ACTIVE OR NO CHARACTERS AVAILABLE. DON'T WAKEUP
	JRST 1(T4)		;INACTIVE AND CHARACTERS AVAILABLE. WAKEUP
	SUBTTL STTYP/GTTYP JSYS'S

;.STTYP - SET TERMINAL TYPE

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

;	STTYP

;RETURNS +1: ALWAYS

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

;ACCEPTS:
;	T1/ TERMINAL DESIGNATOR


;	GTTYP

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

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

;.STPAR - SET TERMINAL PARAMETERS

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

;	STPAR

;RETURNS +1: ALWAYS

.STPAR::MCENT
	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)]
	UMOVE 1,2		;GET NEW JFN MODE WORD
	FNCALL C,TLTYP,(B),TTVT08

; STPAR4 - COMMON CODE FOR STPAR JSYS (RETURN FROM FNCALL)

STPAR4:	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)
	PUSH P,1
	TXNE 1,TT%PGM		;CHANGING PAGE MODE?
	CALL TTXON		;YES, BE SURE OUTPUT NOT STOPPED
	SETZ 1,
	STOR 1,TPGPS,(2)	;AND RESET PAGE POSITION
	POP P,1
	LDB 1,[POINT 7,0(P),10]
	JUMPE T1,STPAR2		;ALLOW ZERO LENGTH
	CAIL 1,2		;LEGAL PAGE SIZE?
	CAIL 1,200
	JRST STPAR0		;ILLEGAL SIZE DOES NOT CHANGE SETTING
STPAR2:	STOR T1,TPLEN,(2)
STPAR0:	LDB 1,[POINT 7,0(P),17]
	JUMPE T1,STPAR3		;ALLOW ZERO WIDTH
	CAIL 1,10		;LEGAL WIDTH
	CAIL 1,200
	JRST STPAR1		;ILLEGAL WIDTHS DON'T CHANGE THE SETTING
STPAR3:	STOR T1,TPWID,(2)
STPAR1:	LDB 1,[POINT 3,0(P),3]
	DPB 1,[POINT 3,TTFLGS(2),3] ;LH BITS
	POP P,1
	CALL ULKTTY		;ALLOW DEALLOCATION OF DYNAMIC DATA
	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 THE CALLER OF THE JSYS; 'REMOTE' IS THE OTHER LINE

.TLINK::MCENT
	TRVAR <OBJNO,OBJADR,REMNO,TLSAV1>
	MOVEI 1,0(1)		;GET OBJECT DESIGNATOR
	CALL CHKTTM		;CHECK DESIGNATOR, GET LINE NO IN 2
	 RETERR()
	MOVEM T2,OBJNO		;SAVE TERMINAL NUMBER FOR OBJECT
	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 7,OBJNO		;GET BACK OBJECT NUMBER
	UMOVE 6,1		;GET FUNCTION FLAGS
	TXNE 6,TL%CRO		;CLEAR REMOTE TO OBJECT?
	CALL TLINK0		;YES. GO DO IT
	TXNE 6,TL%COR
	 JRST [	CALL TLINK1	;CLEAR OBJECT TO REMOTE
		 JRST TLINK9	;FAILED. GO RETURN ERROR
		JRST .+1]
	TXNE 6,TL%EOR
	JRST [	CALL TLINK2	;SET OBJECT TO REMOTE
		 JRST TLINK9	;FAILED
		JRST .+1]
	TXNE 6,TL%ERO
	JRST [	CALL TLINK3	;SET REMOTE TO OBJECT
		 JRST TLINK9
		JRST .+1]
	TXNE 6,TL%SAB
	CALL TLINK4		;SET ACCEPT BIT TO C(B5)
	TXNE 6,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
;	7/ 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?
	JRST [	CALL TL0C	;NO, DO THE ONE SPECIFIED
		RET]

;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
;	7/ OBJECT LINE NUMBER

;CALL TL0C

;RETURNS +1: ALWAYS

TL0C:	SAVELN
	CALL LCKTTY		;POINT TO DYNAMIC DATA FOR REMOTE
	 JRST [	CALL ULKTTY	;NOT ACTIVE
		RET]
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,5			;CLEAR THE LINK JUST FOUND
	JRST TL0C1		;GO FIND ANOTHER

;DONE WITH THIS REMOTE LINE

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

;ACCEPTS:
;	7/ 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?
	JRST [	CALL TL1C	;NO, CLEAR SPECIFIC
		 RETBAD
		RETSKP]

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

	MOVE 5,[POINT 9,TTLINK(4),-1] ;POINT TO LINK WORD
TL12:	MOVE 4,OBJADR		;GET ADDRESS OF OBJECT'S DATA
	ILDB 2,5		;GET A LINE NUMBER
	CAIN 2,777		;IS THIS SLOT FREE?
	JRST TL14		;YES. SKIP IT
	PUSH P,5		;NO. SAVE BYTE POINTER
	CALL TL1C		;GO CLEAR ALL LINKS TO THIS REMOTE
	 RETBAD (,<POP P,5>)	;SOME SORT OF FAILURE
	POP P,5			;RESTORE BYTE POINTER
TL14:	TLNE 5,(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
;	7/ 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,5
	CALL TLTST1		;SEE IF REMOTE POINTS TO OBJECT
	CALL ULKTTY		;UNLOCK REMOTE'S DATA
	POP P,5			;RESTORE POINTER TO REMOTE LINK WORD
	JUMPGE 1,TL15		;ERROR IF REMOTE POINTS TO OBJECT
TL13:	MOVEI 1,777
	DPB 1,5			;CLEAR LINK JUST FOUND
	MOVE T2,REMNO		;RESTORE REMOTE LINE NUMBER
	JRST TL1C

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

;ACCEPTS:
;	7/ 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,7		;LINK TO SELF?
	RETSKP			;YES, IGNORE
	CALL TLTST2		;LINK ALREADY EXISTS?
	JUMPG 1,RSKP		;IGNORE IF YES

;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,1B26		;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,7		;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,7		;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

;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,5			;DEPOSIT REMOTE NUMBER IN FIELD
	MOVE T2,OBJADR		;GET OBJECT DYNAMIC DATA
	CALL ULKTTY		;FREE IT
	SETZM OBJADR		;NO LOCK HELD
	XCTU [HRRZ 1,1]		;OBJECT DESIGNATOR
	HRROI 2,[ASCIZ /
LINK FROM /]
	SETZ 3,
	SOUT			;MSG ON OBJECT ALSO SEEN ON REMOTE
	 ERJMP TL25
	MOVE 2,JOBNO
	HRRZ 2,JOBDIR(2)	;USER ON THIS JOB
	HRLI 2,USRLH		;TURN IT INTO A USER NUMBER
	DIRST			;TYPE HIS NAME
	 JFCL
	HRROI 2,[ASCIZ /, TTY /]
	SOUT
	 ERJMP TL25
	MOVE 2,7		;OBJECT LINE NUMBER
	MOVEI 3,10
	NOUT
	 ERJMP TL25
	HRROI T2,[ASCIZ /
/]
	SETZ T3,
	SOUT
	 ERJMP TL25
TL25:	MOVE T2,7		;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
;	7/ 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,7		;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
		JRST TL32]
	EXCH T2,TLSAV1		;GET BACK ADDRESS OF REMOTE
TL31:	PUSH P,7
	MOVEI 7,777
	CALL TLTST1		;FIND FREE FIELD IN REMOTE
	POP P,7
	JUMPL 1,[MOVEI T1,TLNKX3
		JRST TL32]
	DPB 7,5			;DEPOSIT OBJ NUMBER IN FIELD
TL33:	CALL ULKTTY
	RETSKP

TL32:	CALL ULKTTY
	RETBAD
;TLINK4 - SET ACCEPT BIT

TLINK4:	MOVE T2,OBJADR
	MOVEI 1,1B26		;IT IS BIT 26 IN TTFLGS
	TLNE 6,(1B5)		;SET IT?
	IORM 1,TTFLGS(T2)	;YES
	TLNN 6,(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 6,(1B7)
	IORM 1,TTFLGS(T2)	;YES
	TLNN 6,(1B7)		;CLEAR IT?
	ANDCAM 1,TTFLGS(T2)	;YES
	RET
;CHECK FOR EXISTENCE OF REMOTE TO OBJECT

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

;	CALL TLTST1

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

;CLOBBERS NO AC'S

TLTST1:	MOVE 5,[POINT 9,TTLINK(2),-1]
TLT1:	ILDB 1,5		;SCAN REMOTE
	CAMN 1,7		;FOUND OBJECT?
	RET			;YES
	TLNE 5,(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
;		5/ BYTE POINTER TO LINK WORD FOR OBJECT WHERE REMOTE WAS FOUND

;CLOBBERS NO AC'S

TLTST2:	MOVE 3,OBJADR		;GET ADDRESS OF OBJECT
	MOVE 5,[POINT 9,TTLINK(3),-1] ;POINT TO LINK WORD IN OBJECT
TLT2:	ILDB 1,5		;SCAN OBJECT
	CAMN 1,2		;FOUND REMOTE?
	RET			;YES
	TLNE 5,(7B2)		;NO, SCANNED ALL FIELDS?
	JRST TLT2		;NO
	SETO 1,			;YES, RETURN NEG VALUE
	RET
	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
	 JRST [	CALL ULKTTY
		RET]
	STOR T1,TCJOB,(T2)
	CALL ULKTTY
	RET
;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
	 JRST STTOPX		;NOT AN ACTIVE LINE
	STOR T1,TTPFK,(T2)	;STORE NEW FORK DATA
STTOPX:	CALL ULKTTY
	RET
	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::PUSH P,T1		;SAVE TEMPORARY
	MOVE T1,TTLINV+TT.PTY	;POINT TO VECTOR TABLE
	ADD T2,TT1LIN(T1)	;ADD NUMBER OF FIRST PTY LINE TO GET LINE NO.
	POP P,T1		;RESTORE TEMPORARY
	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::ACVAR <W1>		;GET A WORK REGISTER
	MOVE W1,TTLINV+TT.PTY	;POINT TO VECTOR TABLE
	SUB T1,TT1LIN(W1)	;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

	SWAPCD
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
;CKPHYT - SEE IF THIS IS A PHYSICAL TERMINAL

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL CKPHYT

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

;PRESERVES AC'S

	RESCD
CKPHYT::ACVAR <W1>		;GET A WORK AC
	FNJRST W1,TTSTY,(T2),TTVT09

;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
	 JRST CLRIN1		;NOT FULLY ACTIVE. IGNORE
	ANDCAM T1,TTPSI(T2)	;CLEAR INTERRUPT BIT
CLRIN1:	CALL ULKTTY		;ALLOW DEALLOCATION
	RET
	
;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
	 JRST [	CALL ULKTTY	;NOT FULLY ACTIVE
		RET]
	MOVEM T1,TTPSI(T2)	;STORE INTERRUPT WORD
	MOVEM T3,TTDPSI(T2)	;STORE DEFERRED INTERRUPT WORD
	CALL ULKTTY		;ALLOW DEALLOCATION
	RET
;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
	MOVE T2,TTLINV+TT.PTY	;POINT TO VECTOR TABEL
	HRR T1,TT1LIN(T2)	;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)
			JRST GTBTT3] ;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
	JRST GTBTT3

;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

GTBTT3:	CALL ULKTTY		;ALLOW DEALLOCATION
	RET
;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
	 JRST CKINP1		;NOT ACTIVE. INDICATE NO CHARACTERS
	SKIPE TTICT(T2)		;ACTIVE. ANY INPUT CHARACTERS?
	JRST [	CALL ULKTTY	;YES. ALLOW DEALLOCATION
		RETSKP]		;INDICATE NON-ZERO COUNT
CKINP1:	CALL ULKTTY		;ALLOW DEALLOCATION
	RETBAD			;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,(B),R		;IF NOT REMOTE, GO AWAY
	JE TTFSP,(B),R		;OR IF DON'T NEED SPEED SETTING
	SETZRO TTFSP,(B)	;CLEAR SPEED SETTING REQUIRED
	OPSTR <SKIPN>,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
;ROUTINE CALLED FROM job 0 TO MOVE SPEEDS FROM RESIDENT BLOCK INTO
;PERMANENT TABLE.


TTMVSP::SKIPN B,SPDBLK		;HAVE A BLOCK?
	RET			;NO. ALL DONE THEN
	MOVE C,TTLINV+TT.FE	;GET VECTOR OF FRONT END LINES
	MOVE C,TT1LIN(C)	;GET FIRST LINE NUMBER
	ADD C,[TTSPWD]		;DESTINATION OF THE DATA
	hrli b,-nttfe		;scan entire block
ttmvs1:	skipl d,0(b)		;have a value to set?
	movem d,0(c)		;yes. set it
	aos c			;next speed entry
	aobjn b,ttmvs1		;do all lines
	move a,spdblk		;get block address
	setzm spdblk		;clear pointer
	callret relres		;release block

;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
	FNJRST A,TTSTY,(B),TTVT19 ;GO DO DEVICE DEPENDENT HANGUP
;TTABRT - ROUTINE TO ABORT JOB STARTUP

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TTABRT

;RETURNS +1: ALWAYS

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

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

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

	RESCD

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

TTGTB3:	BUG(CHK,TTYNTB,<RAN OUT OF TTY BUFFERS>)
	AOS TTFREC		;GIVE BACK FRUITLESS SOS
	CHNON DLSCHN		;RESTORE THE CHANNEL
	HRRZ 4,1
	JUMPE 1,TTGTB2		;RETURN IF THERE WERE NONE
	HLRZ 3,1		;COMPLETE THE ONES WE GOT
	HRRZM 3,0(4)
	ADD 3,[441100,,1]
	CHNOFF DLSCHN		;TURN THIS OFF
	CALL TTRLBF		;THEN GIVE THEM BACK
	CHNON DLSCHN		;RESTORE CHANNEL
	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
TTRLB1:	MOVEI 1,0(3)
	HRRZ 3,0(3)		;NEXT BUFFER IN LIST
	CHNOFF DLSCHN
	EXCH 1,TTFREB		;PUT BUFFER ON FREE LIST
	MOVEM 1,@TTFREB
	AOS TTFREC
	CHNON DLSCHN
	CAME 3,0(P)		;CIRCLED AROUND TO FIRST BUFFER?
	JRST TTRLB1		;NO
	POP P,3
	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
	CALLRET TTRLBF		;RELEASE THEM
;ROUTINE CALLED FROM DTEINI  TO SET UP TTSPWD FOR EACH
;LINE. IS A SWAPPABLE INIT ROUTINE.
	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 6,CHITAB(1),17	;POINTER TO CLASS BITS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

;TCO - FIRST LEVEL OUTPUT

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

;RETURNS +1: ALWAYS

;CALLED BY BOUT CODE FOR A SINGLE CHARACTER

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

;TCOE - ECHO OUTPUT

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

;RETURNS +1: ALWAYS

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

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

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

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

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

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

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

;DETERMINE ACTION ACCORDING TO CONTROL CHARACTER OUTPUT CONTROL BITS

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

;INDICATE CONTROL CHARACTER BY ^

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

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

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

;TCOB - ENTRY FOR BINARY OUTPUT. NO TRANSLATION


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

;	CALL TCOB

;RETURNS +1: ALWAYS

TCOB::
TCOB1:	ANDI T1,377		;7 BITS OF CHARACTER + PARITY
	CALL TCOU1		;GO OUTPUT THE CHARACTER WITHOUT ADDING PARITY
	RET			;RETURN
	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:	PUSH P,5
	PUSH P,6
	PUSH P,7
	CAIN 1,.CHDEL
	JRST [	CALL TCOUT	;RUBOUT, SEND DIRECTLY
		JRST TCOY3]
	SKIPE IMECHF		;IMMED ECHO CHAR?
	JRST [	MOVE 3,TTFLGS(2) ;YES, CHECK DUPLEX BITS
		SKIPN LINKF	;LINKED CHAR? OR
		TRCN 3,3B33	;FULL?
		JRST .+1	;YES
		CALL TTCOHA	;ACCOUNT SPACING FOR CHAR
		CAIGE 1,40	;IS CONTROL CHAR AND MODE 2?
		TRNN 3,3B33
		JRST [	MOVE T3,TTLINK(T2) ;NO. GET LINK WORD
			CAME T3,[-1] ;ANY LINKS?
			CALL TTLNK3 ;YES. DO THEM
			JRST TCOY3] ;AND DONE
		JRST TTCO1]	;YES, ECHO CONTROL FN

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

	CAIGE 1,40
	JRST TTCO1		;CONTROL GROUP

;NOT A CONTROL CHARACTER. RAISE IF NECESSARY

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

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

	TXNN 3,TT%UOC		;INDICATE?
	JRST TTCO6		;NO
	PUSH P,1		;YES, SAVE CHAR
	MOVEI 1,TTLIND		;OUTPUT INDICATOR
	CALL TCOP
	POP P,1
TTCO6:	CALL TCOP		;OUTPUT CHAR AND ACCOUNT SPACE
TCOY3:	POP P,7
	POP P,6
	POP P,5
	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:	LOAD T3,TLNPS,(T2)	;GET CURRENT POSITION ON LINE
	AOS T3			;INCREMENT COUNT
	STOR T3,TLNPS,(2)	;STORE NEW COUNT
	LOAD 4,TPWID,(T2)	;GET RIGHT MARGIN
	JUMPE 4,[CALLRET TCOUT]	;0 MEANS NEVER FOLD
	CAIL 4,0(3)		;CHECK FOR OVERFLOW
	JRST [	CALLRET TCOUT]	;NO OVERFLOW, OUTPUT CHAR

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

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

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

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

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

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

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

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

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

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

;	CALL TTSM1

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

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

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

;	CALL TTSM12

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

;LOCAL LINEFEED - DOES NOT INCLUDE CR

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


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

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


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

TTSM32:	PUSH P,TTLPOS(2)	;SAVE LINE AND PAGE POSITIONS
	PUSH P,5		;SAVE NUMBER OF LINES LEFT IN PAGE
TTSM33:	CALL TTSM2		;SIMULATE ONE FORM FEED
	SETZRO TPGPS,(T2)	;PREVENT TTSM2 FROM DOING X-OFF
	SOSLE 0(P)		;COUNT LF'S
	JRST TTSM33		;LOOP ON LF'S
	POP P,5			;FLUSH TEMP
	POP P,TTLPOS(2)		;RESTORE LINE AND PAGE POSITIONS
TTSM3Y:	LOAD 1,TPLEN,(2)	;CHECK PAGE LENGTH
	CAIE 1,0		;DO XOFF UNLESS PLENGTH IS 0
	CALL TTXOFF		;DO XOFF
	RET
; * * * 
;NOT CLEAR WHY NECESSARY TO SAVE AND RESTORE TTLPOS. ASSUMES KNOWLEDGE
;OF ITS CONTENTS
; * * * *
;ROUTINE TO INSERT PADDING

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

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

;BACKSPACE

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

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

;CARRIAGE RETURN

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

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

;ESC

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

TTSME:	TLNN 3,(3B1)		;00?
	RET			;YES, NO SEND
	TLNE 3,(1B1)		;01 OR 11?
	JRST [	MOVEI 1,"$"	;YES, SEND $
		CALLRET TCOP]
	CALLRET TCOUT		;SEND ACTUAL CODE
;TTXON - DO 'XON' - CLEAR STOP FLAG AND RESTART OUTPUT TO TERMINAL IF NECESSARY

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTXON

;RETURNS +1: ALWAYS

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

TTXON:	JE TTSFG,(2),R		;IF CTRL/S NOT IN EFFECT, NOTHING TO DO
	FNJRST T1,TLTYP,(T2),TTVT10

TTXON2:	SETZRO TTSFG,(T2)	;CLEAR CTRL/S
	MOVE 3,TTOCT(2)		;GET COUNT OF CHARACTERS IN OUTPUT BUFFER
	CALLRET STRTOU		;RESTART OUTPUT


;TTXOFF - STOP OUTPUT TO A TERMINAL

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

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

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

;OUTPUT ONE CHARACTER TO SPECIFIED TTY LINE

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

;RETURNS +1: ALWAYS

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

;SPECIAL ENTRY POINT WHEN ENTERING FROM TTEMES

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

;RETURNS +1: ALWAYS

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

SCDTCO:	SKIPL CHITAB(T1)	;TEST PARITY BIT FOR THIS CHARACTER
	JRST TCOU6		;NO PARITY NEEDED. GO ON
	FNXCT T3,TLTYP,(T2),TTVT12 ;DO PARITY LOGIC
	JRST TCOU6		;GO STORE IN OUTPUT BUFFER

;PHYSICAL LINE. APPLY PARITY

TCOUT:	SKIPL CHITAB(1)		;TEST PARITY BIT FOR THIS CHAR
	JRST TCOU1		;NO PARITY NEEDED. GO ON
	FNXCT T3,TLTYP,(T2),TTVT12 ;DO PARITY LOGIC

;FULLY ACTIVE LINE. PROCESS LINES LINKED TO THIS ONE

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

;SEE IF THERE IS ROOM IN THE OUTPUT BUFFER

TCOU3:	JN TOFLG,(T2),R		;LOSE CHARACTER IF CTRL/O TYPED
	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
	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
	MDISMS
	MOVE T2,0(P)		;GET STATIC LINE NUMBER
	CALL LCKTTY		;LOCK UP THE TTY
	 JUMPLE T2,[	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:	LOAD T3,TLTYP,(T2)	;GET LINE TYPE
	CAIN T3,TT.PTY		;PTY?
	JRST [	PUSH P,2	;YES. SAVE ADDRESS OF DYNAMIC DATA
		DYNST		;GET LINE NUMBER
		CALL PTYSKO	;IS IT OPEN?
		 JRST [	POP P,2 ;NO. LOSE OUTPUT
			RET]
		POP P,T2	;YES. RESTORE ADDRESS OF DYNAMIC DATA
		JRST .+1]
	NOSKD1
	CHNOFF DLSCHN		;MUST PREVENT DEASSIGN OF BUFFERS
	SKIPE 3,TTOIN(2)	;BUFFERS EXIST?
	JRST TCOU4		;YES.

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

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

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

TCOU4:	HRRZ 4,3
	TDNN 3,WRPMSK		;END OF BUFFER?
	HRR 3,1-TTSIZ(4)	;YES, GET ADDRESS OF NEXT BUFFER
	IDPB 1,3		;STORE CHARACTER IN OUTPUT BUFFER
	MOVEM 3,TTOIN(2)	;SAVE UPDATED BYTE POINTER
	AOS 3,TTOCT(2)		;INCREMENT COUNT OF CHARACTERS IN BUFFER
	CHNON DLSCHN		;SAFE TO TURN CHN ON AFTER AOS
	OKSKD1
	AOS NTTYOT		;COUNT ALL OUTPUT
	CALLRET STRTOU		;START OUTPUT TO LINE IF NEEDED
;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
	 SKIPLE T2		;IF UNASSIGNED, GO ON
	JRST [	OKSKED		;ALLOW SCHEDULING
		RET]		;AND DONE
	MOVE T2,LNNUMB		;LINE # AGAIN
	CALL ASGMSL		;GET A MESSAGE BLOCK
	 JRST TCOU77		;FAILED
	CALL STADYN		;SUCCESS. GET DYNAMIC DATA ADDRESS
	 JUMPLE T2,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
	RESCD			;BACK TO RESIDENT MONITOR
;TTLNK3 - SCAN LINK WORD, SENDING CHAR TO LINES SPECIFIED BY NON-777 BYTES

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

;ACCEPTS:
;	T1/ INTERNAL LINE NUMBER

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

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

;TTBUFW - CALLED FROM SCHEDULER TO WAIT FOR BUFFERS

;ACCEPTS: 
;	T1/ NUMBER OF BUFFERS NEEDED

;CAUSES WAKEUP IF THE NEEDED NUMBER OF BUFFERS ARE AVAILABLE

TTBUFW:	CAMLE 1,TTFREC
	JRST 0(4)
	JRST 1(4)
;STRTOU - START OUTPUT TO A LINE

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

;	CALL STRTOU

;RETURNS +1: ALWAYS

STRTOU:	SAVELN
	FNJRST T4,TLTYP,(T2),TTVT13

;PHYSICAL LINE. START OUTPUT AT HARDWARE LEVEL IF NEEDED

STRTO1:	NOSKD1			;MAKE SURE NO ONE ELSE DOING THIS
	JN TTOTP,(T2),STRT11	;IF ACTIVE, NO NEED TO START IT
	SAVET
	DYNST			;GET LINE NUMBER
	IDIVI T2,^D36		;COMPUTE BIT POSITION IN QUEUE
	MOVE T3,BITS(T3)
	IORM T3,TTSOQ(T2)	;REQUEST START NEXT BIGBUF CYCLE
STRT11:	OKSKD1			;ALLOW SHCEDULING NOW
	RET
	SUBTTL TCI (GET CHAR FROM INPUT BUFFER)

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

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

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

;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
	 JRST TCI2		;IT WAS, RETURN FAILURE

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

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

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL TCIB

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

TCIB::
TCIB2:	OPSTR <SKIPE>,TTRFG,(T2) ;REPEAT LAST CHARACTER?
	JRST [	SETZRO TTRFG,(T2) ;YES. CLEAR FLAG
		LOAD T1,TYLCH,(T2) ;GET LAST CHARACTER INPUT
		JRST TCIB1]
	MOVEI T3,.TTBIN		;USE BINARY TERINAL DATA MODE
	CALL TCI0		;GET A CHAR
	 JRST TCI2		;NEEDED TO BLOCK. RETURN TO CALLER.
	CALL TCITTI		;CHECK FOR TERMINAL INTERRUPT
	 JRST TCI2		;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
	RETSKP			;SKIP TO INDICATE BUFFER WASN'T EMPTY

;HAD TO BLOCK.

TCI2:	RETBAD 			;RETURN 'BLOCKED'
;TCIECO -DO DEFERRED ECHO IF NECESSARY

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

TCIECO:	TXNE T3,TT%ECO		;ECHOS ON?
	TRNE T4,TTXECO		;AND CHARACTER NEEDS ECHO?
	RET			;NO, DO NOTHING
	PUSH P,T3		;SAVE 3 FOR CALLER
	PUSH P,T4		;SAVE 4 FOR CALLER
	SETZRO TOFLG,(T2)	;INPUT REQUEST MEANS IMPLICIT CLEAR OF CTRL/O
	CALL TCOE		;SEND IT
	POP P,T4
	POP P,T3
	RET

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

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;	CALL TTCLPS

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

TTCLPS:	SAVET			;PRESERVE ALL TEMPS
	MOVX C,TT%PGM		;SEE IF NOW IN PAGE MODE
	TDNN C,TTFLGS(B)	;IS IT?
	RET			;NO. JUST RETURN
	SETZRO TPGPS,(B)	;YES. CLEAR PAGE POSITION
	RET			;AND RETURN
;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:	ACVAR <Q1>
	MOVEM T1,Q1		;SAVE CHAR
	ANDI T1,177		;EXTRACT ASCII
	CALL GPSICD		;GET PSI CODE IF ANY
	JUMPL T1,TCITT1		;JUMP IF NONE
	MOVE T3,BITS(T1)
	TDNN T3,TTPSI(T2)	;THIS CODE ENABLED?
	JRST TCITT1		;NO

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

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

;NOT AN INTERRUPT CHARACTER.  GIVE SKIP RETURN

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

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

;ACCEPTS:
;	T1/ FORK HANDLE

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

;TCI0 - GET ONE CHARACTER FROM LINE INPUT BUFFER

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

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

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

TCI0:	NOSKED
	SKIPG 1,TTICT(2)	;ANY CHARS IN BUFFER?
	JRST TCI01		;NO
	SAVELN			;SAVE ADDRESS OF DYNAMIC DATA
	SKIPN 3,TTIOUT(2)	;GET POINTER
	BUG(HLT,TTICN0,<TCI - NO BUFFER POINTER BUT COUNT NON-0>)
	HRRZ 4,3
	TDNN 3,WRPMSK		;AT END OF CURRENT BUFFER?
	HRR 3,1-TTSIZ(4)	;YES. GO TO NEXT IN CHAIN
	ILDB 1,3		;GET NEXT CHARACTER
	MOVEM 3,TTIOUT(2)	;SAVE UPDATED BYTE POINTER
	SOSG TTICT(2)		;REDUCE COUNT, NOW EMPTY?
	JRST [	SETZB 3,TTIOUT(2) ;YES, RELEASE BUFFERS
		EXCH 3,TTIIN(2)
		CALL TTRLBF
		JRST .+1]
	OKSKED
	DYNST			;GET ORIGINAL LINE NUMBER
	CALL SNDXON		;SEND XON IF NEEDED
	RETSKP			;SKIP TO INDICATE NO WAIT

;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
	;..
;TCI..

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

	;..
TCIF2:	STOR T3,TYLMD,(T2)	;SAVE DATA MODE THIS INPUT
	PUSH P,3		;SAVE DATA MODE
	MOVE T3,FORKX		;GET INDEX OF THIS FORK
	STOR T3,TWFRK,(T2)	;RECORD THIS FORK WAITING FOR TTY
	SETZRO TTFWK,(T2)	;INDICATE NO FORCED WAKEUP
	FNCALL T1,TLTYP,(T2),TTVT32 
	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
;	OPSTR <SKIPE>,TTLCK,(T2) ;DON'T UNLOCK IF IT'S NOT LOCKED
	CALL ULKTTY		;ALLOW DEALLOCATION
	HRRI 1,TCITST		;T1/(LINE NUMBER,,ROUTINE)
	MDISMS			;WAIT UNTIL A CHARACTER COMES IN
	POP P,3			;RESTORE CURRENT MODE
	RET			;GIVE NON-SKIP RETURN TO SAY A BLOCK
				;  OCCURRED

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

TCIF1:	ANDI A,7777
	CAMN A,FORKX		;IS IT THIS FORK?
	JRST TCIF2		;YES. GO TO IT THEN
	CALL ULKTTY		;RELEASE TTY LOCK AND GO OKINT
	CALL TTFRKT		;GO RESOLVE CONFLICT BY HALTING FORK
	RET			;MUST REVERIFY TTY IN CASE WE BLOCKED
	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:	PUSH P,2
	MOVE 1,FX		;SETUP ARG
	CALL UNBLKF		;TELL SCHED TO UNBLOCK THE FORK
	POP P,2
	RET

;SCHEDULER TEST ROUTINE FOR FORKS WAITING FOR TTY INPUT
;CALLED WITH JSP 4,
;AC 1 CONTAINS LINE NUMBER
;AC 7 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 TCITS1
	JN TTFWK,(T2),TCITS1	;IF FORCED WAKEUP SET, WAKE THE PROCESS
	JN TTWFG,(T2),TCITS1	;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 TTVT32 OFFSET OF THE PROPER DEVICE AND PATCH IN THE 
;PROPER LINE NUMBERS

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:	TXNN 3,TT%LIC		;RAISE INPUT?
	RET			;NO
	CAIGE 1,177
	CAIGE 1,140		;LC CHAR?
	RET			;NO
	CAIGE 1,173		;REGULAR LC CHAR?
	TRZA 1,40		;YES, MAKE UC
	MOVEI 1,33		;NO, MUST BE OLD ALT-MODE. MAKE ESC
	RET

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

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

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

GPSIC3:	CAIN 1,177		;RUBOUT?
	JRST [	MOVEI 1,^D28	;YES, RETURN CODE
		RET]
	MOVEI 1,^D27		;NO, IS OLD ALT-MODE
	RET
;ROUTINES TO X-OFF AND X-ON TERMINALS WHICH ARE OVERLOADING THE
;SYSTEM. 

;SNDXOF - SEND XOFF TO STOP INPUT

;ACCEPTS:
;	B/ LINE NUMBER

;RETURNS +1 ALWAYS WITH ALL REGISTERS PRESERVED

SNDXOF:
	SAVET
	FNJRST C,TTSTY,(B),TTVT14

;SNDXON - RESUME INPUT FROM TERMINAL

;T2/ INTERNAL LINE NUMBER

;RETURNS +1: ALWAYS

SNDXON:
	SAVEAC <A>		;SAVE VULNERABLE REGISTER
	FNJRST A,TTSTY,(B),TTVT15
	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::	SKIPE RTSKED		;SCHEDULER WANT CONTROL BACK? (RUMORED NOT TO
				; BE USED)
	RET			;YES, RETURN
	SKIPG TTBIGC		;BIG BUFFER EMPTY?
	JRST TTCH7X		;YES, RETURN
	AOS 3,TTBIGO		;NO. INCREMENT POINTER TO LOAD FROM
	CAIN 3,TTBSIZ		;AT END OF TTBBUF?
	SETZB 3,TTBIGO		;YES. POINT TO START OF TTBBUF
	MOVE 1,TTBBUF(3)	;GET NEXT ENTRY
	SOS TTBIGC		;DECREMENT COUNT OF ENTRIES
	HLRZ 2,1		;GET LINE NUMBER
	MOVEI 6,0(1)		;SAVE ALL ORIGINAL FLAGS
	FNCALL C,TTSTY,(B),TTVT26
	JRST [	DECR TTFBB,(B)	;NO. DECREMENT LINE'S COUNT OF TTBBUF ENTRIES
		CALL SNDXON	;SEND XON IF NEEDED
		JRST .+1]
	TRNE 1,TTOIRQ		;OUTPUT INTERRUPT REQUEST?
	JRST [	MOVX 3,.TICTO	;YES. OUTPUT BUFFER WENT EMPTY AND PROCESS
		CALL TTPSRQ	; ENABLED FOR INTERRUPT. ISSUE IT
		JRST TTCH7]	;DONE WITH WORD
	TRNE 1,DLSCXF		;CARRIER TRANSITION?
	JRST TT7CX		;YES
	TRNN 1,DLSRCF		;RECEIVER?
	JRST TTCH7		;NO (SHOULD NOT HAPPEN) - RESUME  SCAN

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

	ANDI 1,377		;GET 7 BITS OF CHARACTER + PARITY
	CALL TTCHI		;PUT CHAR IN LINE BFR
	JRST TTCH7		;DO NEXT
;TTCH7..

;TTBBUF IS EMPTY. DO DEVICE DEPENDENT FUNCTIONS IF NEEDED

TTCH7X:	CALL TTYQOC		;START OUTPUT ON QUEUED LINES
	SKIPGE TTQCNT		;HAVE SOME SCANNING TO DO?
	RET			;NO. ALL DONE THEN
	;..
;TTCH7..

;BEFORE LEAVING, CHECK 8 LINES TO SEE IF THEY NEED ANYTHING DONE.
;DYNAMIC DATA CONTAINS ADDRESS OF ROUTINE TO CALL AND TIME TO CALL IT
;IF SOMETHING IS TO BE DONE FOR THE LINE

	;..
TTHNG4:
	MOVE 2,TTCQLN		;GET NEXT LINE TO BE CHECKED
	MOVEI 4,10		;LIMIT OF 10 LINES FOR THIS PASS
TTCQ3:	SKIPL TTQCNT		;ALL DONE?
	SKIPE RTSKED		;SCHEDULER WANT CONTROL BACK ?
	JRST TTCQ5		;YES, GO SAVE LINE NUMBER AND RETURN
	CALL DOLINE		;GO PROCESS TTCS WORD AND/OR RELEASE BLOCK

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

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

   REPEAT 0,<			;DON'T DO THIS
;TRANSFER ACCORDING TO THE VECTOR IN A. CERTAIN TYPES ARE NEVER
;PROCESSED.

	MOVE A,TTLINV(C)	;GET VECTOR
	JRST @TTVT16(A)		;GO TO DEVICE DEPENDENT ROUTINE
   >				;END OF REPEAT 0

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

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

   REPEAT 0,<			;TTVT16 DISBALED FOR NOW
;TRANSFER ACCORDING TO THE VECTOR IN A. CERTAIN TYPES ARE NEVER
;PROCESSED.

	JRST @TTVT16(A)		;GO TO DEVICE DEPENDENT ROUTINE
   >				;END OF REPEAT 0


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

TTCQ1:	SOJG 4,TTCQ3		;DONE ENOUGH FOR THIS TIME?
TTCQ5:	MOVEM 2,TTCQLN		;YES, START AT THIS LINE NEXT TIME
	RET
;TTCH7...

;DOLINE - PROCESS TTCS WORD FOR A LINE AND RELEASE BLOCK IF NECESSARY

;ACCEPTS:
;	T2/ INTERNAL LINE NUMBER

;	CALL DOLINE

;RETURNS +1: ALWAYS

;PRESERVES ALL AC'S

DOLINE:	SAVET
	OPSTR <SKIPE A,>,TTIME,(B) ;ANYTHING TO DO FOR THIS LINE?
	CAML A,TODCLK		;YES. IS IT TIME TO DO IT?
	JRST DOLIN1		;NO. GO SEE ABOUT RELEASING BLOCK
	LOAD A,TROUT,(B)	;YES. GET ADDRESS OF FUNCTION TO DO
	SETZRO <TTIME,TROUT>,(B) ;INDICATE NOTHING TO BE DONE FOR THIS LINE
	PUSH P,T2		;SAVE STATIC LINE NUMBER
	CALL 0(1)		;DO THE FUNCTION
	POP P,T2		;RESTORE STATIC LINE NUMBER
	SOS TTQCNT		;ONE MORE DONE

;SEE IF LINE IS ACTIVE.  IF IT HAS A SHORT OR MESSAGE BLOCK,
;AND IT IS FINISHED WITH THE BLOCK, RELEASE IT

DOLIN1:	CALL STADYN		;POINT TO DYNAMIC DATA
	 SKIPG T2		;NOT FULLY ACTIVE.  ANY DYNAMIC DATA?
	JRST DOLIN3		;INACTIVE, BECOMING ACTIVE, OR FULL-LENGTH
	JN <TTLCK,TTSAL>,(T2),DOLIN3 ;DON'T RELEASE IF DOING SENDALL OR LOCKED
	JN TTSHT,(T2),DOLIN2	;IF SHORT AND SENDALL DONE, RELEASE BLOCK
	CALL TTSOBE		;IS OUTPUT COMPLETE?
	 JRST DOLIN3		;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
DOLIN3:	RET
;TTCH7..

;TTQAD - ADD ITEM TO CONTROL QUEUE

;ACCEPTS:
;	T1/ TIME UNTIL EVENT
;	T2/ INTERNAL LINE NUMBER
;	T3/ ROUTINE TO BE CALLED AT GIVEN TIME

;	CALL TTQAD (TTQAD1 FOR DEFAULT TIME LIMIT)

;RETURNS +1: ALWAYS

TTQAD1:	MOVEI T1,^D3000		;ITEM TO BE DONE IN 3 SEC.
TTQAD:	ADD T1,TODCLK		;COMPUTE ABSOLUTE TIME TO DO FUNCTION
	STOR T1,TTIME,(T2)	;SAVE TIME FOR DOING THE FUNCTION
	OPSTRM <EXCH T3,>,TROUT,(T2) ;SAVE ROUTINE TO DO IT
	JUMPN T3,R		;IF ALREADY ON THE QUEUE, RETURN
	AOSG TTQCNT		;FIRST ENTRY?
	MOVEM T2,TTCQLN		;YES. START SCAN HERE THEN
	RET

;ROUTINE CALLED ONCE A SECOND TO DO CONTROLLER DEPENDENT FUNCTIONS

TTYCHK::PUSH P,Q1		;DO CHECKS FOR DEVICES
	PUSH P,Q2
	MOVEI Q1,NLTYPS		;CALL FOR ALL DEVICES
	MOVEI T1,SCNTIM		;TIME FOR NEXT SCAN
	MOVEM T1,TTYTIM
TTLILP:	MOVE Q2,TTLINV-1(Q1)
	CALL @TTVT29(Q2)	;DO DEVICE DEPENDENT FUNCTIONS
	SOJG Q1,TTLILP		;ALL DEVICES
	POP P,Q2		;RESTORE
	POP P,Q1
	RET			;AND DONE
;TTCH7..

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

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

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

	SETONE TTCON,(B)	;SET CARRIER ON FOR THIS LINE
	FNJRST C,TTSTY,(B),TTVT17



;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
	JRST TTC7SK		;GO CREATE JOB
;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
	FNJRST A,TTSTY,(B),TTVT18



;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
	MOVE C,[TTHU0]		;QUEUE A HANGUP-REACTIVATE SEQUENCE
	SETZ A,			;TO START IMMEDIATELY
	CALL TTQAD
	CALLRET NTYCOF
;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
	 RET			;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
	CALL TTJBDT		;GO DETACH JOB
	RET			;AND DONE

;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 CHKCTT		;SEE IF THIS IS A CONTROLLING TERMINAL
	 RET			;NO. DON'T ISSUE INTERRUPT
   REPEAT 0,<			;FOLLOWING CODE DOES NOT
				;WORK BECAUSE IT CAUSES PAGE
				;FAULTS IN SCHEDULER. NEED TO
				;MOVE THIS ELSEWHERE SOME DAY
	OPSTR <SKIPE>,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
	MOVSI 1,400000+PSICOB
	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:	STKVAR <CHKCSV,CHKCJN>
	MOVEM B,CHKCSV		;SAVE LINE NUMBER
	CALL STADYN		;POINT TO DYNAMIC DATA
	 JRST CHKCT1		;LINE NOT ACTIVE. 
	LOAD C,TCJOB,(B)	;GET OWNING JOB
	CAIN C,-1		;IS THERE ONE?
	JRST CHKCT1		;NONE.
	MOVEM C,CHKCJN		;SAVE JOB NUMBER
	HLRZ A,JOBPT(C)		;GET CONTROLLING TERMINAL FOR JOB
	MOVE C,B		;C/ADDRESS OF DYNAMIC DATA
	MOVE B,CHKCSV		;B/LINE NUMBER
	CAMN A,B		;IS THIS THE CONTROLLING TERMINAL?
	JRST [	MOVE B,CHKCSV
		MOVE A,CHKCJN	;A/ JOB NUMBER
		RETSKP]		;YES. SUCCESS RETURN
CHKCT1:	MOVE B,CHKCSV		;NOT CONTROLLING TERMINAL. RESTORE LINE NUMBER
	RET			;FAILURE RETURN
;TTCH7..

;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:
	FNJRST A,TTSTY,(B),TTVT19 ;GO DO DEVICE DEPENDENT HANGUP
	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

TTCHI:	CAIL 2,NLINES		;REASONABLE LINE?
	RET			;NO
	SAVELN			;SAVE THE LINE NUMBER
	STKVAR <TTCHSV,TTCHFL>	;MUST COME AFTER SAVELN
	MOVEM T2,TTCHSV		;SAVE LINE NUMBER
	MOVEM T1,TTCHIC		;SAVE ORIGINAL CHARACTER
	ANDI T1,177		;USE 7 BITS FOR LOCAL COMPARES
	CALL STADYN		;IS THIS A FULLY ACTIVE LINE?
	 JRST TTC7N		;NO. GO HANDLE THIS CASE SEPARATELY
	JE TTPRM,(T2),TTCHI2	;YES. PERMANENT BLOCK?
	LOAD T3,TCJOB,(T2)	;YES. GET CONTROLLING JOB
	CAIN T3,-1		;IS THERE ONE?
	JRST TTC7N		;NO

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

TTCHI2:	MOVE T3,T1		;COPY CHAR
	CALL GPSICD		;GET PSI CODE FOR CHAR
	EXCH 1,3		;1/CHARACTER; 3/CODE OR -1
	JUMPL 3,TTCHI6		;-1 MEANS NO CODE
	MOVE 5,BITS(3)		;BIT FOR THIS CODE
	TDNN 5,TTPSI(2)		;CODE ENABLED?
	JRST TTCHI6		;NO. PROCESS AS PART OF INPUT STREAM
	;..
;TTCHI..

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

;	2/ADDRESS OF DYNAMIC DATA
;	3/THE CODE
;	5/ BIT FOR CONTROL CODE FOR THIS CHARACTER

	;..
	TDNN 5,TTDPSI(2)	;DEFERRED CHARACTER?
	CALLRET TTPSI2		;NO, INTERRUPT IMMED
	LDB 4,TTIIN(2)		;GET LAST INPUT CHAR
	CAMN T4,TTCHIC		;LAST CHAR SAME AS THIS ONE?
	JRST TTCHI5		;YES, MAKE IMMEDIATE

;HANDLE DEFERRED INTERRUPT

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

;DEFERRED CHARACTER TWICE IN A ROW

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

;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
;TTCHI..

;NOT AN INTERRUPT CHARACTER

;2/ ADDRESS OF DYNAMIC DATA

	;..
TTCHI6:	AOS NTTYIN		;COUNT INPUT
	MOVE 3,TTFLGS(2)
	TXNN 3,TT%PGM		;IN PAGE MODE?
	JRST TTCHI1		;NO

;TERMINAL IS IN PAGE MODE. IF CHARACTER IS XON OR XOFF, DO IT.

	CAIN 1,PGMONC		;XON?
	CALLRET TTXON		;YES, DO IT
	CAIE 1,PGMOFC		;XOF?
	JRST TTCHI1		;NO
	SETONE TTSFG,(T2)	;YES. INDICATE CTRL/S TYPED
	FNJRST T1,TLTYP,(T2),TTVT20
;TTCHI..

;TERMINAL NOT IN PAGE MODE OR THIS WAS NOT XON OR XOFF
;IF TERMINAL DATA MODE IS BINARY, GO STORE CHARACTER IN LINE BUFFER 
;WITHOUT TRANSLATION OR ECHOING

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

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

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

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

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

;	2/ ADDRESS OF DYNAMIC DATA

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

;IF INPUT BUFFER IS FULL, SEND XOFF TO TERMINAL

	LOAD D,TIMAX,(B)	;GET CAPACITY OF BUFFERS
	CAIL C,-10(D)		;IS INPUT BUFFER FULL
	JRST [	PUSH P,B	;YES. SAVE ADDRESS OF DYNAMIC DATA
		DYNST		;GET LINE NUMBER
		CALL SNDXOF	;SEND XOFF TO TERMINAL
		POP P,B		;RESTORE ADDRESS
		JRST .+1]

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

	CAIN 3,1		;JUST BECAME NON-0?
	CALL [	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
	;..
;TTCHI..

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

	;..
	LOAD 3,TWFRK,(2)	;IF NO FORK WAITING FOR THIS LINE,
	CAIN 3,-1
	JRST TTCH10		; THEN SKIP WAKEUP CHECKS
	LOAD 3,TYLMD,(2)	;GET TERMINAL DATA MODE FOR LAST CHARACTER
	CAIN 3,.TTBIN		;WAKE ALWAYS IF BINARY
	JRST TTCH11
	LOAD 3,TIMAX,(2)	;CAPACITY OF INPUT BUFFERING
	SUBI 3,40		;LESS AN ARBITRARY AMOUNT
	CAMG 3,TTICT(2)		;BUFFER NOW THAT FULL?
	JRST [	SETONE TTFWK,(2) ;YES. FORCE WAKEUP OF WAITING FORK
		JRST .+1]
	LOAD 3,TT%WAK,TTFLGS(2) ;GET WAKEUP CLASSES FOR THIS FORK
	FNXCT T4,TLTYP,(T2),TTVT38
	LDB 4,PCLASS		;GET WAKEUP CLASS FOR THIS CHAR
	SKIPL TTCHFL		;DID WE FAIL TO ECHO CHARACTER?
	TDNE 3,4		;NO. IS THIS A WAKEUP CHARACTER FOR THIS LINE?
	JRST TTCH11		;YES, FORCE WAKEUP
TTCH10:	LOAD FX,TWFRK,(2)	;GET WAITING FORK IF ANY
	CAIN FX,-1		;IS THERE ONE?
	RET			;NO. DON'T WAKE ANY
	JE TTFWK,(2),R		;YES. IS THE WAKEUP BIT SET?
	ANDI FX,7777		;YES. FLUSH FLAGS
	CALLRET TTUBLK		;UNBLOCK FORK

TTCH11:	CALLRET TTFWAK		;FORCE WAKEUP

;INPUT BUFFER GETTING FULL. SEND BELL AND LOSE CHARACTER

TTCH12:	MOVEI 1,07		;INPUT BUFFER FULL,
	CALLRET SCDTCO		;ECHO BELL

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

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

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

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

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

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

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

TTCH75:	MOVE T1,FACTSW		;SEE WHAT LOGINS ARE ALLOWED
	MOVE T2,TTCHSV		;RESTORE LINE NUMBER
TTC7SJ:	CAMN 2,CTYLNO		;CTY?
	JRST [	TXNE T1,SF%CTY	;YES, CTY LOGIN ALLOWED?
		JRST TTC7SK	;YES, GO LOGIN
		HRROI 1,[ASCIZ/
?LOGGING IN ON THE CTY IS CURRENTLY DISALLOWED.
/]
		CALLRET TTEMSS] ;NO LOGIN ALLOWED ON CTY
	FNJRST T3,TTSTY,(T2),TTVT21

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

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

;LINE IS REMOTE

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


;LOGINS ARE ALLOWED.

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

;TTEMES - SEND SHORT MESSAGE FROM SCHEDULER

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

;	CALL TTEMES

;RETURNS +1: ALWAYS

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

;TTEMSS - ENTRY POINT TO CLEAR OUTPUT BUFFER BEFORE OUTPUTTING

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

;TTEMES - NORMAL ENTRY POINT

TTEMES::SAVELN			;PRESERVE LINE NUMBER
	STKVAR <TTEMBP,TTEMAC,TTEMLN>
	MOVEM T1,TTEMBP		;SAVE BYTE POINTER TO STRING
	MOVEM T2,TTEMLN		;SAVE LINE NUMBER
	MOVEM 5,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 5,0(1)		;SAVE THE BYTE
	CALL SCDTCO		;OUTPUT IT
	CAIE 5,.CHCRT		;A CARRIAGE RETURN?
	CAIN 5,.CHLFD		;OR A LF?
	SKIPA			;GO FILL
	JRST TTEME4		;NO. GET NEXT CHARACTER
	MOVEI 5,3		;NUMBER OF FILLS TO DO
TTEME5:	MOVEI A,TTFILL		;THE FILL CHARACTER
	CALL SCDTCO		;OUTPUT IT
	SOJGE 5,TTEME5		;DO ALL FILLS
	JRST TTEME4		;GO DO NEXT BYTE

TTEME3:	MOVE T1,TTEMBP		;RESTORE BYTE POINTER
	MOVE 5,TTEMAC		;RESTORE WORK REGISTER
	CALLRET TTYQOC		;GET OUTPUT STARTED
	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::FNJRST C,TTSTY,(B),TTVT22

;LINE IS ON THE RSX20F FRONT END. LIMIT ITS STORAGE IN TTBBUF

;LINE IS ON RSX20F OR DC10. STORE THE CHARACTER IN TTBBUF

BIGST1:	MOVEI 3,TTBSIZ		;GET SIZE OF TTBBUF
	CAMG 3,TTBIGC		;HAS TTBBUF OVERFLOWED?
	JRST DLSSX1		;YES
	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

;TTBBUF HAS OVERFLOWED. THE CHARACTER WILL BE LOST.

DLSSX1:	BUG(CHK,TTYBBO,<TTYSRV-BIG BUFFER OVERFLOW>)
	FNJRST C,TTSTY,(B),TTVT25

DLSSX2:	DECR TTFBB,(B)		;ON FRONT END. ONE LESS IN BIGBUF
	JE TTFBB,(B),R		;IF NOW EMPTY, RETURN
	CALL SNDXOF		;AND SEND HIM AN X-OFF AS WELL
	RET			;LOSE CHARACTER
	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 MESSAGE OR SEND-ALL, 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:	CHNOFF DLSCHN
	CALL TTSND		;DO THE WORK
	CHNON DLSCHN
	OKSKD1
	RET

;ROUTINE TO START OUTPUT ON QUEUED LINES
;CALLED ONLY ON SCHED SHORT CYCLE AT TTCH7X

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

TTYQO2:	MOVE T1,BITS(T2)	;CLEAR REQUEST THIS LINE
	ANDCAM T1,TTSOQ(Q1)
	HRRZ T1,Q1		;COMPUTE LINE NUMBER
	IMULI T1,^D36
	ADD T2,T1
	CALL STADYN		;GET DATA ADDRESS
	 JUMPLE T2,TTYQO1	;QUIT IF NONE
	CHNOFF DLSCHN		;START OUTPUT
	CALL TTSND
	CHNON DLSCHN
	JRST TTYQO1

;CONSTANTS

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

;ACCEPTS:
;	T2/ ADDRESS OF DYNAMIC DATA

;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:
	STKVAR <OBFFR>		;WORD TO SAVE POINTERS
TTSND6:	JE TTSAL,(T2),TTSND7	;IS THIS LINE DOING A SENDALL?
	OPSTR <SKIPLE>,TSALC,(T2) ;ANY MORE CHARACTERS TO SEND?
	JRST TTSND8		;YES. GO DO ONE
	SETZRO TSALP,(T2)	;NO. CLEAR SENDALL POINTER
	SETZRO TTSAL,(T2)	;INDICATE NO LONGER DOING SENDALL
	SOS SALCNT		;DECREMENT COUNT OF SENDALL LINES
	JRST TTSND7		;SEE IF THERE ARE CHARACTERS TO SEND

;LINE IS DOING A SENDALL. GET THE NEXT CHARACTER FROM THE SENDALL BUFFER

TTSND8:	LOAD T3,TSALP,(T2)	;GET ITS BYTE POINTER
	ILDB T1,T3		;GET NEXT CHARACTER
	STOR T3,TSALP,(T2)	;SAVE UPDATED BYTE POINTER
	DECR TSALC,(T2)		;DECREMENT COUNT OF REMAINING CHARACTERS
	TRNN 1,200		;THIS CHARACTER HAVE PARITY?
	JRST TTSND5		;NO. GO ON
	FNXCT T4,TLTYP,(T2),TTVT12 ;YES. DO PARITY LOGIC THEN
TTSND5:	EXCH T1,T3		;GET CHARACTER IN T3
	JRST TTSND2		;GO SEND THE CHARACTER

;NOT A SENDALL

TTSND7:	JN <TTSFG,TTSHT>,(T2),[	SETZRO TTOTP,(T2) ;IF CTRL/S TYPED, SET OUTPUT
			RET]	; NOT ACTIVE
	SKIPN TTOCT(2)		;ARE THERE CHARACTERS IN OUTPUT BUFFER?
	JRST [	SETZRO TTOTP,(T2) ;NO CHARACTERS. CLEAR OUTPUT-ACTIVE
		CALLRET CLENUP] ; AND GO RELEASE BUFFERS

;SEND OUTPUT CHARACTER

	SKIPN 3,TTOOUT(2)	;GET BUFFER POINTER
	BUG(HLT,TTONOB,<TTY OUTPUT - NO BUFFER BUT COUNT NON-0>)
	MOVEM C,OBFFR		;SAVE ORIGINAL BUFFER POINTER
	HRRZ 4,3
	TDNN 3,WRPMSK		;AT END OF BUFFER?
	HRR 3,1-TTSIZ(4)	;YES. GO TO NEXT ONE IN CHAIN
	MOVEM 3,TTOOUT(2)	;WRAP POINTER
	ILDB 3,TTOOUT(2)	;GET NEXT CHARACTER
	SOS TTOCT(2)		;REDUCE COUNT OF CHARACTERS

;A 9-BIT FIELD FROM THE OUTPUT BUFFER IS IN T3. SEE IF DATA INDICATES PAGE FULL
;RATHER THAN A CHARACTER TO BE SENT.

TTSND9:	TRNN 3,TTOESC		;A FUNCTION ESCAPE CHARACTER?
	JRST TTSND2		;NO. GO SEND THE CHARACTER
	;..
;TTSND..

;FUNCTION ESCAPE CHARACTER ENCOUNTERED IN OUTPUT STREAM

	;..
	CAIN 3,TTOPFC		;PAGE FULL FUNCTION?
	JRST [	SETONE TTSFG,(T2) ;YES. SIMULATE CTRL/S
		JRST TTSND6]	; AND GO CLEAR OUTPUT ACTIVE
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	DYNST			;GET LINE NUMBER TO PRINT
	BUG(CHK,TTILEC,<TTSND-UNRECOGNIZED ESCAPE CODE>,<2,3>)
	POP P,T2		;RESTORE ADDRESS OF DYNAMIC DATA
	JRST TTSND6

;A REAL CHARACTER WAS FOUND. DO DEVICE-DEPENDENT THINGS TO SEND
;IT TO THE TERMINAL

TTSND2:	ANDI 3,377		;GET CHARACTER + PARITY
	FNJRST 4,TLTYP,(T2),TTVT23

;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:	SAVELN
	CALL TTRLOB		;RELEASE OUTPUT BUFFERS, SINCE EMPTY
	MOVX 3,1B<.TICTO>
	OPSTR <SKIPN>,TTMES,(T2) ;A NORMAL BLOCK?
	TDNN 3,TTPSI(2)		;OUTPUT INTERRUPT WANTED?
	RET			;NO. RETURN
	MOVEI 1,TTOIRQ		;YES, PUT REQUEST IN BIG BUF
	DYNST			;GET LINE NUMBER
	HRL 1,2
	CALLRET BIGSTO
;ROUTINES CALLED FROM SECONDARY PROTOCOL INTRRUPT ROUTINES

;POST OUTPUT DONE. 2/LINE NUMBER

TTODON::CALL STADYN		;GET ADDRESS OF DYNAMIC DATA
	 JRST [	JUMPLE T2,R	;RETURN IF BECOMING ACTIVE OR INACTIVE
		JE TTMES,(T2),R ;RETURN IF NOT A TTEMES BLOCK
		JRST .+1]	;CONTINUE IF TTEMES BLOCK
	CALLRET TTSND		;SEND ANOTHER CHARACTER IF ANY

;INPUT DONE AND CHARACTER PRESENT
; T1/ CHARACTER
; T2/ LINE NUMBER
;	CALL TTIDON
; RETURN +1 ALWAYS

TTIDON::TRO T1,DLSRCF		;INDICATE RECEIVED CHARACTER
	HRL T1,T2		;COMBINE LINE NUMBER WITH CHAR
	CALLRET BIGSTO		;PUT IN BUG BUFFER
;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.

	MOVE A,TTLINV(C)	;GET VECTOR FOR THIS TYPE
	JRST @TTVT24(A)		;GO TO DEVICE DEPENDENT CODE

;DETACH THE JOB ON THIS LINE IF THERE IS ONE

TTDAL6:	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 A,TTLINV(C)	;GET VECTOR FOR THIS TYPE
	MOVE B,TT1LIN(A)	;GET FIRST LINE OF THIS TYPE

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

	JRST @TTVT24(A)		;GO TO DEVICE DEPENDENT CODE
;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
	PUSH P,Q1		;DO ALL LINE TYPES
	PUSH P,Q2
	MOVEI Q1,NLTYPS		;DO ALL LINE TYPES
TTLIL2:	MOVE Q2,TTLINV-1(Q1)	;GET VECTOR
	CALL @TTVT28(Q2)	;GO DO DEVICE DEPENDENT ENABLE/DISABLE
	SOJG Q1,TTLIL2
	POP P,Q2
	POP P,Q1		;RESTORE
	RET
;DUMMY TRANSFER VECTOR.  USED FOR LINE TYPES FOR WHICH THE CURRENT
;MONITOR HAS NO LINES

	RESCD
TTFEVT=.
TTDZVT=.
TTDCVT=.
TTMCVT=.
TTNTVT=.
TTPTVT=.
TTDMVT:	TTDDLN			;DDLEN - LENGTH OF DYNAMIC DATA FOR THIS TYPE
	-1			;TT1LIN - (FIRST LINE,,NUMBER OF LINES)
	IFIW!R			;TTVT00 - INITIALIZE TABLES AT SYSTEM STARTUP
	IFIW!R			;TTVT01 - ACTIVATE LINES AT STARTUP OR RESTART
	IFIW!TTBUGH		;TTVT02 - CLEAR OUTPUT BUFFER
	IFIW!TTBUGH		;TTVT03 - SET LINE SPEED
	IFIW!TTBUGH		;TTVT04 - READ LINE SPEED
	IFIW!TTBUGH		;TTVT05 - SET TERMINAL/NON-TERMINAL STATUS
	IFIW!TTBUGH		;TTVT06 - READ TERMINAL/NON-TERMINAL STATUS
	IFIW!TTBUGH		;TTVT07 - STO JSYS
	IFIW!TTBUGH		;TTVT08 - STPAR JSYS
	IFIW!TTBUGH		;TTVT09 - CKPHYT - SEE IF PHYSICAL TERMINAL
	IFIW!TTBUGH		;TTVT10 - RESUME OUTPUT TO TERMIAL
	IFIW!TTBUGH		;TTVT11 - NOT USED
	JRST TTBUGH		;TTVT12 - TCOUT - ADD PARITY TO CHARACTER
	IFIW!TTBUGH		;TTVT13 - START OUTPUT TO LINE
	IFIW!TTBUGH		;TTVT14 - SEND XOFF TO TERMINAL
	IFIW!TTBUGH		;TTVT15 - SEND XON TO TERMINAL
	IFIW!TTCQ6		;TTVT16 - TTCH7 - PROCESS TTCS WORDS
	IFIW!TTBUGH		;TTVT17 - HANDLE CARRIER/ON
	IFIW!TTBUGH		;TTVT18 - HANDLE CARRIER OFF
	IFIW!TTBUGH		;TTVT19 - HANGUP,REACTIVATE REMOTE LINE
	IFIW!TTBUGH		;TTVT20 - PROCESS XOFF FROM TERMINAL
	IFIW!TTBUGH		;TTVT21 - HANDLE CTRL/C FROM INACTIVE LINE
	IFIW!TTBUGH		;TTVT22 - BIGSTO - STORE CHARACTER IN TTBBUF
	IFIW!TTBUGH		;TTVT23 - TTSND - SEND CHARACTER TO LINE
	IFIW!TTDAL7		;TTVT24 - DETACH JOB ON THIS LINE
	IFIW!TTBUGH		;TTVT25 - HANDLE OVERFLOW OF TTBBUF
	IFIW!TTBUGH		;TTVT26 - REMOVE CHARACTER FROM TTBBUF
	IFIW!TTBUGH		;TTVT27 - DO TTMSG FOR ONE LINE?
	IFIW!R			;TTVT28 - ENABLE/DISABLE DATASETS
	IFIW!R			;TTVT29 - TTCH7 AFTER EMPTYING TTBBUF
	IFIW!TTBUGH		;TTVT30 - CLEAR INPUT BUFFER
	IFIW!TTBUGH		;TTVT31 - DOBE
	IFIW!TTBUGH		;TTVT32 - INPUT GA
	IFIW!TTBUGH		;TTVT33 - SET INITIAL VALUES FOR A LINE
	IFIW!TTBUGH		;TTVT34 - SOBE
	IFIW!TTBUGH		;TTVT35 - WAKEUP IF OUTPUT BUFFER EMPTY
	IFIW!TTBUGH		;TTVT36 - SENDAL FOR ONE LINE
	IFIW!TTMSDM		;TTVT37 - SENDALL FOR ALL LINES
	JRST TTBUGH		;TTVT38 - ADJUST WAKEUP CLASSES

;TTVT37 - INDICATE THERE ARE NO LINES OF THIS TYPE FOR TTMSG

TTMSDM:	SETOM B			;INDICATE SKIP ENTIRE LINE GROUP
	RETSKP

TTBUGH:	BUG(HLT,BADTTY,<TRANSFER TO NONEXISTENT TTY CODE>)