;<134-TENEX>TTYSRV.MAC;217     2-DEC-75 10:23:56    EDIT BY TOMLINSON
; ADDED COUNTER FOR SPECIAL MARKS IN INPUT BUFFERS (TTMCT)
;<134-TENEX>TTYSRV.MAC;215    26-OCT-75 11:46:40    EDIT BY TOMLINSON
;<134-TENEX>TTYSRV.MAC;213    22-OCT-75 14:52:40    EDIT BY TOMLINSON
;<134-TENEX>TTYSRV.MAC;212    21-OCT-75 13:19:12    EDIT BY TOMLINSON
; CHANGED TTYGPI TO RETURN COC FORMAT WORDS
;<134-TENEX>TTYSRV.MAC;210    17-SEP-75 13:11:13    EDIT BY TOMLINSON
; RCTE BUG FIXES
;<TOMLINSON>TTYSRV.MAC;1    10-SEP-75 07:40:44    EDIT BY TOMLINSON
; RCTE: MAKE IT WORK IN MORE CASES.
;<134-TENEX>TTYSRV.MAC;202    24-JUL-75 15:37:25    EDIT BY PLUMMER
; ADD OMRON TERMINAL TYPE
;<134-TENEX>TTYSRV.MAC;201    11-JUL-75 16:32:57    EDIT BY ALLEN
; TCOTST IGNORES WAKEUP THRESHOLD FOR NVTS
;<134-TENEX>TTYSRV.MAC;200    23-JUN-75 16:41:23    EDIT BY CLEMENTS
; REARRANGE TTHANG. IT WAS HANGING UP NVT'S IN USE.
;<134-TENEX>TTYSRV.MAC;199     4-JUN-75 12:09:40    EDIT BY PLUMMER
; HOLD OFF JOBS UNTIL OPERATOR HAS A CHANCE TO SET THE TIME
;<134-TENEX>TTYSRV.MAC;196    15-MAY-75 08:06:45    EDIT BY TOMLINSON
;<134-TENEX>TTYSRV.MAC;195    15-MAY-75 08:03:49    EDIT BY TOMLINSON
; CHECK NVTHI IN ALL CASES BEFORE DOING ARPANET SPECIFIC FUNCTIONS
;<134-TENEX>TTYSRV.MAC;194    12-MAY-75 10:36:28    EDIT BY TOMLINSON
; FIX BUG IN TTSTO CHECK FOR ECHO BUFFER EMPTY
;<TOMLINSON>TTYSRV.MAC;3     6-MAY-75 13:06:47    EDIT BY TOMLINSON
;<TOMLINSON>TTYSRV.MAC;2     5-MAY-75 21:56:55    EDIT BY TOMLINSON
;<TOMLINSON>TTYSRV.MAC;1     5-MAY-75 21:34:46    EDIT BY TOMLINSON
; ADDED TELENET CODE
;<134-TENEX>TTYSRV.MAC;193    27-FEB-75 15:56:50    EDIT BY CLEMENTS
; ALLOCATE MORE OUTPUT BUFFERS FOR TERM TYPES 12 AND 13
;<134-TENEX>TTYSRV.MAC;192    21-JAN-75 14:21:29    EDIT BY CLEMENTS
; MOVE MISPLACED CLOSE ANGLE BRACKET IN TTHNGU, WHICH SOMEHOW WORKED.
;<133-TENEX>TTYSRV.MAC;191     1-JAN-75 10:43:57    EDIT BY TOMLINSON
; SUPPLY TTHNG2 IF EITHER NDLS OR IMPCHN DEFINIED

	SEARCH	PROLOG
	TITLE	TTYSRV

;TELETYPE SERVICE ROUTINES - D. MURPHY
; LINKAGE TO PISRV

EXTERN	MENTR,UJSYS,MRETN,SKMRTN,MRETNE,ITRAP,ITRAP1
EXTERN	BUGCHK,BUGHLT,BUGNTE

; LINKAGE TO SCHEDULER

EXTERN	INSKED,ISKED,FKINT,BLOCK1

; LINKAGE TO IMPDV

IFDEF IMPCHN,<
EXTERN	NVTDOB,NVTXCR,NVTCHO,NTTCSO,NETCAP,NVTCOB
EXTERN	NVTDET,NVTPAR,NVTMOD,NVTRCC>

; MISCELLANEOUS EXTERNS

EXTERN AUTONX
EXTERN FACTSW
EXTERN	R,RSKP,CAPMSK,CAPENB,JOBDIR,NTTYOT,NTTYIN,TTFRKT

INTERN	TTCHI,PSICHU,PSICHL,PSICHO,TTIMAX,TTOMAX,TTRLOB,TTYLMD,WRPMSK,NVTCOF
	INTERN NLINES,NTTYS,CTYLIN,OTYLIN,TCI,TCO,TTHNGU,TTEMES
	INTERN .TLINK,.ADVIZ,NORMTF,TAB81,TAB82,TCOB,TCIB
IFDEF IMPCHN,<INTERN TCOBQ>
	INTERN BUGTYO,BUGMSG
	INTERN .TTMSG,.STTYP,.GTTYP,.STPAR
	INTERN TTINIT,TTRSET
	INTERN TTCOBF,TTCOBI,TTCIBF,TTILIN
	INTERN TTSIBE,TTSOBE,TTSOBF,TTDOBE,TTGTBS,TTSTBS,TTSPOS
	INTERN TTRMOD,TTSMOD,TTRPOS,TTRCOC,TTSCOC,TTSTI,TTBKPT
	INTERN TTDIBE
	INTERN PSICH
	INTERN CH6TAB,BHC
	INTERN BITS
	INTERN TTICB1,TTICB2
	INTERN TCITST,TCOTST
	INTERN TTCH7,DLSCHK
	INTERN DLSSV

; linkage to Telenet Code

EXTERN	TNTINI,TNTRST,TNTCOB,TNTSBE,TNTSBF,TNTDOB,TNTDET,TNTSTI
EXTERN	TNTCHO,TNTCHE,TNTAVS,TNTCIB,TNTGA

;NLINES PARAMETER IN PROLOG

NCHBF==<TTSIZ-1>*4		;NUMBER OF CHARS IN 1 BUFFER
TTBSIZ==200		;BIG BUFFER SIZE
NTABBF==^D20		;NUMBER OF TABS BUFFERS
NDLSPD==10		;SIZE OF DLS PI-LEVEL STACK
OTYLIN:	OTYLNE		;OTY FOR FIXING DISK
TTLCBT==1B3		;LOWER CASE FLAG BIT
DLSRCF==400		;DLS RECEIVER FLAG, DATAI WORD
DLSXMF==1000		;DLS XMITTER FLAG, DATAI WORD
DLSCXF==1B25		;CARRIER XITION FLAG
DLSACT==1B26		;ACTIVATE LEVEL IN DATAO
DLSDLB==1B29		;DIRECTED LINE BIT, LH OF DATAO
TTSCF==1B20		;FLAG - CHARACTER CAME FROM STI
IFDEF BBNDLS,<CARONB==1B24>	;CARRIER ON BIT IN BBN SCANNER
IFDEF DECDLS,<CARONB==1B33>	;CARRIER ON BIT IN DEC SCANNER

TTLIND=="%"		;LOWER CASE INDICATION CHARACTER
TTCIND=="^"		;CONTROL INDICATION CHARACTER

	EXTERN JOBPT,FKJOB,FORKX,EDISMS,TODCLK,CHKTTM,ENTFLG
	EXTERN SCDRQ7,JOBSRT,RSKP,SYSIFG,TTINTS
	EXTERN TTPSRQ,DLSTIM

IFN NDLS,<
;RANGE OF LINES TO ACCEPT FROM SCANNER

HILIN:	NTTYS-1
LOLIN:	0
>

IFN NDLS,<

;DC10E CORRESPONDENCE TABLES
;CORRESPONDENCE IS GIVEN BY PARAMETERS OF THE FORM DC10GX=Y
;WHICH MEANS THAT LINE GROUP X IS CONTROLLED BY DC10E GROUP Y

IFDEF DECDLS,<

;THIS TABLE GIVES THE DC10E GROUP IF ANY WHEN INDEXED BY A LINE GROUP

DCTAB:
DEFINE TTEST(G)<
IFDEF D10G'G,<D10G'G*10>
IFNDEF D10G'G,<1B0> >

	TTEST(0)
	TTEST(1)
	TTEST(2)
	TTEST(3)
	TTEST(4)
	TTEST(5)
	TTEST(6)
	TTEST(7)

;INVERSE OF ABOVE - GIVES TTY GROUP FOR DC10E GROUP. IT IS
;SET UP AT INIT TIME

DCTAB1:	REPEAT 10,<1B18>

DCTABI:	SETZ 1,
	MOVSI 3,-10
DCTABJ:	LDB 2,[POINT 3,DCTAB(3),32]	;GET "GROUP" FIELD
	SKIPL DCTAB(3)		;IN USE?
	HRRZM 1,DCTAB1(2)	;YES. SET INVERSE POINTER
	ADDI 1,10
	AOBJN 3,DCTABJ
	RET
>
>; END CONDITIONAL ON NDLS

	SWAPCD

;STORAGE

LS TTOIN,TNTLO		;OUTPUT BUFFER POINTERS (IN)
LS TTOOUT,TNTLO		;	(OUT)
LS TTOCT,TNTLO		;	(COUNT)

LS TTEIN,TNTLO		;ECHO OUTPUT BUFFER POINTERS (IN)
LS TTEOUT,TNTLO		;	(OUT)
LS TTECT,TNTLO		;	(COUNT)

LS TTIIN,NLINES		;INPUT BUFFER POINTERS (IN)
LS TTIOUT,NLINES	;	(OUT)
LS TTICT,NLINES		;	(COUNT)
LS TTMCT,NLINES		; COUNT OF MARKS IN INPUT BUFFER

;TTY BUFFERS--INPUT, OUTPUT, AND ECHO
;BUFFERS ARE OF SIZE TTSIZ, AND START AT LOCATIONS N*TTSIZ+1

IFNDEF TTBUFF,<		;IF DEFINED, MEANS TTBUFS ALREADY DEFINED
LS TTBUFS,NTTBF*TTSIZ+TTSIZ >
LS TTFREC,1		;COUNT OF FREE BUFFERS
LS TTFREB,1		;LIST OF FREE BUFFERS

LS TTFLGS,NLINES	;FLAGS
LS TTLINK,NLINES	;OUTPUT-LINKED LINES (9-BIT BYTES)
LS TTADVS,NLINES	;ADVISE LINKS. -1 MEANS NONE, 0,,N MEANS
			; ADVISING LINE N, B0+N MEANS WILL ACCEPT
			; AN ADVIZ FROM LINE N
			; -1,,N MEANS AM RECEIVING ADVICE FROM N


LS FCMOD1,NLINES
LS FCMOD2,NLINES	;CONTROL CHARACTER MODES

LS TTLPOS,NLINES	;PAGE,,LINE POSITION
LS TTPSI,NLINES		;PSEUDO-INTERRUPT MASK
GS TTDPSI,NLINES	;DEFERRED INT CODES
GS TTFORK,NLINES	;OWNERSHIP STATUS,,INPUT WAIT STATUS
GS TTCS,NLINES		;CONTROL STATE
GS TTBFRC,NLINES	;BUFFER CONTROL FIELDS
GS TTMOD1,NLINES	;LAST CHAR INPUT, LAST MODE, TAB TABLE ADR
GS TTYPE,NLINES		;TYPE OF TERMINAL ON THIS LINE
GS TTFRK1,NLINES-<NLINES/2>	;HALFWORD/LINE: TOP FORK IN PSI GROUP
			;-1=NO FORK,-2=FORK BEING ASSIGNED
			;N=SYS FORK INDEX OF FORK TO PSI

LS TABLST,1		;LIST OF FREE TAB BUFFERS
LS TABBFR,NTABBF*3	;TAB BUFFERS

;BIG BUFFER

LS TTBIGI,1		;INPUT INDEX
LS TTBIGO,1		;OUTPUT INDEX
LS TTBIGC,1		;COUNT
LS TTBBUF,TTBSIZ	;BUFFER

;MISC TTY STORAGE

LS TTNIT1,1		;ISB COMMUNICATION REG
LS XDLSSV,1		;PI RETURN
LS TTCQLN,1		;CONTROL OP CURRENT LINE NUMBER
IFN NDLS,<
LS DLSLPI,1		;DLS LOST PI ASMT COUNT
LS TTHNGL,1		;LINE BEING EXAMINED FOR HUNG
LS TTHNGT,1		;TIME AT WHICH LINE WILL BE DEFINED AS HUNG
LS TTHNGN,1		;LAST HUNG LINE ,, NUMBER UNHANGS DONE
IFDEF BBNDLS,<
LS TTHNL2,1		; LINE NUMBER BEING CHECKED FOR DATASET 113
LS TTHNT2,1		;  HANGUP CONDITION. TIME FOR IT.
>
>; END TEST ON NDLS
LS LINKF,1		;LINKED OUTPUT CHAR IN NOT 0
LS IMECHF,1		; SET IF IMMEDIATE ECHO BEING OUTPUT

LS DLSVAP,1		;PI-LEVEL STORAGE
LS DLSPDL,NDLSPD	;PI-LEVEL PDL

	RESCD

TTYLCH:	POINT 9,TTMOD1(2),8
TTYLMD:	POINT 2,TTMOD1(2),10	;TERM DATA MODE FOR LAST TCI
NSMODM==1B11			;NON-STANDARD MODEM HANDLING BIT IN TTMOD1
TTYFFC:: POINT 2,TTMOD1(2),13	;SFCOC BITS FOR ^L LAST DONE IN TOP FK
;RH OF TTMOD1 IS THE POINTER TO TAB STOPS TABLE

;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+1B29+1B31

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,2,1,2,2,1,1,1,1
TTICB2:	BYTE (2) 1,1,1,1,1,1,1,1,1,3,1,1,1,2

;POINTERS TO FIELDS IN TTBFRC WORD

TTOMAX:	POINT 9,TTBFRC(2),35	;MAX BYTES IN OUTPUT BUFFER(S)
TTIMAX:	POINT 9,TTBFRC(2),26	; " INPUT BUFFER(S)
TTNOU:	POINT 5,TTBFRC(2),17	;NUMBER OF OUTPUT BUFFERS TO ASSIGN
TTNIN:	POINT 5,TTBFRC(2),12	;NUMBER OF INPUT BUFFERS TO ASSIGN
TTOWRN:	POINT 8,TTBFRC(2),7	;OUTPUT WAKEUP LEVEL

;TERMINAL TYPE TABLES
; B0, B1, B2, B3       , B4-7, B8-11, B12-15, B16-19, B20
; FF,TAB, LC, SPEC CRPD, CRPD, LFPAD, TABPAD, FF PAD, PAGEPAUSE
;SPECIAL CRPAD: PAD WITH RUBOUTS, NOT CR'S, NOT PROPORTIONAL.

;NORMAL MODE IS LOWERCASE BIT ON, MOST DEVICES WILL PRINT LC CHAR
;AS UC.  FF AND TAB PADDING IS SPECIFIED FOR TTYS IN CASE
;FF OR TAB BIT TURNED ON MANUALLY

TTYPE0:	1B2+1B15+12B19		;(0) MOD 33
	1B0+1B1+1B2+1B15+12B19	;(1) MOD 35 (FF+TAB)
	1B2+1B15+12B19		;(2) MOD 37 (LC)
	1B2+10B7		;(3) TI (LC+CRPAD)
	0			;(4) RESERVED FOR SRI-ARC
	0			;(5)   "  "  "
	0			;(6)   "  "  "
	1B0+1B1+1B2		;(7) NVT (TAB+LC+FF, NO PAD)
	1B2!6B7!6B11		;(10) LA30, GE TERMINET-300
	1B2!1B3!6B7		;(11) TI 733, STRANGE CR'S.
	1B2+1B20		;(12) SCOPES
	1B2!1B3!17B7!17B11	;(13) ARC LINEPROCESSOR
	1B0+1B2+10B7+16B11+1B20	;(14) OMRON
	0			;(15) AVAIL
	0
NTTYPS==.-TTYPE0

;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

;NON PI ROUTINES

BUGTYO:	0
	CONSZ TTY,1B31
	JRST .-1
	DATAO TTY,1
	CONSZ TTY,1B31
	JRST .-1
	JRST @BUGTYO

BUGMSG:	0
	MOVE 7,1
	HRLI 7,440600
BUGM2:	ILDB 1,7
	ADDI 1,40
	CAIN 1,"/"
	JRST @BUGMSG
	CAIN 1,"$"
	JRST BUGM1
BUGM3:	JSR BUGTYO
	JRST BUGM2

BUGM1:	MOVEI 1,15
	JSR BUGTYO
	MOVEI 1,12
	JRST BUGM3

	SWAPCD

;SENDS MESSAGES TO ALL TTYS VIA ECHO BUFFER

.TTMSG:	JSYS MENTR
	MOVE 7,0(P)
	TLNE 7,UMODF		;FROM MONITOR?
	JRST [			;NO, CHECK CAPABILITIES
		MOVE 7,CAPENB	;  AND ALLOW FOR WHEELS AND OPER.
		TRNN 7,WHEEL+OPER
		JRST UJSYS
		JRST .+1 ]
	TLNE 2,007000
	HRLI 2,440700		;MAKE BYTE POINTER
	PUSH P,2
	JUMPGE 1,TPA5		;NOT ALL TTYS
	MOVSI 16,-NLINES
TPA6:	MOVE 14,0(P)		;BYTE POINTER
	MOVEI 2,0(16)		;LINE NUMBER
TPA3:	XCTBU [ILDB 1,14]
	JUMPE 1,TPA1		;TERMINATE ON NULL
	CALL TCEO2
	JRST TPA3

TPA1:	AOBJN 16,TPA6
	POP P,2
	JRST MRETN

TPA5:	HRROI 16,0(1)		;DO ONE LINE OF GIVEN NUMBER
	JRST TPA6

;SEND SYSTEM CRASH MESSAGE TO ALL TTYS

	RESCD

LS CRSMSG,2			;CALLED BY JSR CRSMSG

CRSMS0:	MOVEM 17,CRSAC+17	;SAVE AC'S
	MOVEI 17,CRSAC
	BLT 17,CRSAC+16
	MOVE P,[IOWD NCRSPD,CRSPDL]
	MOVSI 16,-NLINES	;DO ALL EXISTING LINES
CRSM3:	MOVEI 14,[ASCIZ /
**TENEX IS DOWN**
/]
	HRLI 14,440700
	MOVEI 2,0(16)		;LINE NUMBER
CRSM2:	ILDB 1,14		;CHARACTER
	JUMPE 1,CRSM1		;NULL MARKS END
	CALL TCEO2		;OUTPUT VIA ECHO BUFFER
	JRST CRSM2

CRSM1:	AOBJN 16,CRSM3
	MOVSI 17,CRSAC		;RESTORE ACS
	BLT 17,17
	JRST @CRSMSG

LS CRSAC,20
NCRSPD==10
LS CRSPDL,NCRSPD

;INITIALIZATION

TTINIT:	MOVEI 1,TTBUFS		;COMPUTE BEGINNING OF BUFFERS
	TRNE 1,TTSIZ-2		; TO BE N*TTSIZ+1
	ADDI 1,TTSIZ		;FIRST WORD IN BUFFER AREA
	ANDCMI 1,TTSIZ-1	;WHICH IS 0 MOD TTSIZ
	ADDI 1,1		;SUCH THAT EACH BUFFER ENDS 0 MOD ADR
	MOVEI 2,NTTBF
	MOVEM 2,TTFREC		;FREE BUFFER COUNT
	SUBI 2,1
	MOVEM 1,TTSIZ(1)	;CONSTRUCT LIST OF FREE BUFFERS
	ADDI 1,TTSIZ
	SOJG 2,.-2
	MOVEM 1,TTFREB		;FREE BUFFER LIST
	ADD 1,[XWD 441100,1]	; +1 AND MAKE INTO BYTE POINTER
	MOVSI 7,-NLINES
TTIB1:	MOVEI 2,0(7)
	CAIL 2,TNTLO
	 JRST TTIB2
	SETZM TTOIN(7)
	SETZM TTOOUT(7)
	SETZM TTOCT(7)		;INITIALIZE OUTPUT BUFFER WORDS
	SETZM TTEIN(7)
	SETZM TTEOUT(7)
	SETZM TTECT(7)		; ... ECHO BUFFER WORDS
TTIB2:	SETZM TTIIN(7)
	SETZM TTIOUT(7)
	SETZM TTICT(7)		; ... INPUT BUFFER WORDS
	SETZM TTMCT(7)		; ... MARKS
	SETOM TTFORK(7)
	SETZM TTFLGS(7)
	SETZM TTYPE(7)
	SETOM TTLINK(7)
	SETOM TTADVS(7)		;NO LINKS OR ADVICE IN PROGRESS
	MOVE 1,[<^D20>B7+2B12+2B17+<2*NCHBF-1>B26+<2*NCHBF-2>B35]
	MOVEM 1,TTBFRC(7)	;NORMAL IS 2 BUFFERS FOR IN AND OUT
	AOBJN 7,TTIB1
	SETOM TTFRK1		; ... TOP FORKS FOR TERM PSI'S
	MOVE 2,[XWD TTFRK1,TTFRK1+1]
	BLT 2,TTFRK1+NLINES-<NLINES/2>-1
	MOVSI 2,-NLINES
	CALL TTILIN
	AOBJN 2,.-1
IFDEF DIALLN,<
	MOVSI 1,(NSMODM)	;NON-STANDARD MODEM HANDLING
	IORM 1,TTMOD1+DIALLN>	;ON THE DIALLER LINE
	MOVEI 2,NTABBF-1	;INIT FREE LIST OF TAB BUFFERS
	MOVEI 1,TABBFR
	MOVEM 1,3(1)
	ADDI 1,3
	SOJG 2,.-2
	MOVEM 1,TABLST
IFDEF DECDLS,<
	CALL DCTABI>		;INITIALIZE FOR DC10E CONTROL
	SETZM TTBIGI
	SETZM TTBIGO
	SETZM TTBIGC
	CONO TTY,DLSCHN
IFN NDLS,<
	CONO DLS,DLSCHN>
TTACTL:	MOVE 1,[JRST CRSMS0]	;SETUP JSR DISPATCH
	MOVEM 1,CRSMSG+1
IFN NDLS,<
	SETZM TTHNGT
	SETZM TTHNGN
	MOVSI 2,-NTTYS+1	;ACTIVATE DLS LINES (BUT NOT CTY)
TTACT2:
IFDEF BBNDLS,<
	MOVE 1,[XWD DLSDLB,DLSACT+1B27]	;DIRECTED LINE, ACTIVATE, NO XMIT
	DPB 2,[POINT 6,1,17]	;PUT LINE NUMBER IN DATAO WORD
	MOVSI 3,(NSMODM)	;NONSTANDARD MODEM?
	TDNE 3,TTMOD1(2)	; ..
	HRRI 1,1B27		;YES. DEACTIVATE THIS ONE
	DATAO DLS,1
>
IFDEF DECDLS,<
	CALL TTECNV		;GET CORRESPONDING DC10E LINE
	HRRI 3,1B29		;ACTIVATE (DATA TERM RDY)
	JUMPL 3,.+2		;UNLESS NONE THERE
	DATAO DLS,3>
	AOBJN 2,TTACT2
>; END COND ON NDLS
	CALL TNTINI
	RET

;CALLED ONLY FROM TTINIT

TTILIN:	CALL TTCIBF		;INITIALIZE TTY LINE
	MOVE 1,NORMTF		;USUAL DEVICE FLAGS AND STATUS
	DPB 1,[POINT 35,TTFLGS(2),35]
	SETZM TTPSI(2)
	SETZM TTLPOS(2)
	MOVE 1,TTICB1		;SETUP USUAL CONTROL CHARACTER MODES
	MOVEM 1,FCMOD1(2)
	MOVE 1,TTICB2
	MOVEM 1,FCMOD2(2)
	MOVEI 1,TAB81		;NORMAL TABS
	MOVEM 1,TTMOD1(2)
	RET

;RESUME RUNNING TTY'S AFTER RESTART

TTRSET:	CALL TNTRST
	MOVSI 2,-NLINES
	CONO TTY,DLSCHN
IFN NDLS,<
	CONO DLS,DLSCHN>	;ASSUMES I-O RESET WAS DONE
TTRST1:	SKIPL TTFLGS(2)		;WAS XMITTER IN OPERATION
	JRST .+3		;NO
	HRRZM 2,TTNIT1		;YES, SIMULATE INT TO RESUME ACTION
	ISB DLSCHN
	AOBJN 2,TTRST1
	JRST TTACTL

;TTY BUFFER CONTROL ROUTINES

;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

TTGTBF:	PUSH P,1		;TRANSPARENT TO ALL AC'S EXCEPT 3
	PUSH P,3		;SAVE COUNT
	SETZ 1,
TTGTB1:	CHNOFF DLSCHN
	SOSGE TTFREC		;REDUCE FREE BUFFER COUNT
	JRST TTGTB3
	HRRZ 3,@TTFREB		;GET BUFFER FROM LIST
	EXCH 3,TTFREB
	CHNON DLSCHN
	JUMPE 1,[MOVSI 1,0(3)	;FIRST BUFFER, REMEMBER ITS ADDRESS
		JRST .+2]
	HRRZM 3,0(1)		;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
	HRRZM 3,0(1)		;COMPLETE CIRCULAR LIST
	ADD 3,[XWD 441100,1]	;CONSTRUCT 9-BIT BYTE POINTER
	AOS -2(P)		; SKIP RETURN
TTGTB2:	POP P,1			;JUNK
	POP P,1
	RET

TTGTB3:	AOS TTFREC	; CORRECT COUNT, NOT REALLY TAKING ONE HERE.
	CHNON DLSCHN
	BUG(NTE,<RAN OUT OF TTY BUFFERS>)
	JUMPE 1,TTGTB2	; NONE ASSIGNED, RETURN
	HLRZ 3,1	; COMPLETE WHAT WE HAVE
	MOVEM 3,0(1)
	ADD 3,[XWD 441100,1]
	CALL TTRLBF	; RELEASE THEM
	JRST TTGTB2

;RELEASE LIST OF TTY BUFFERS
; 3/ BYTE POINTER ANYWHERE IN ANY BUFFER OF LIST
;  RETURNS +1, CLOBBERS 3
;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

;RELEASE OUTPUT BUFFERS
; 2/ LINE NUMBER
;  RETURNS +1, CLOBBERS 3
;ASSUMES INTERRUPT PROTECTION AS ABOVE

TTRLOB:	SKIPN 3,TTEOUT(2)	;ECHO BUFFER TO RELEASE?
	JRST .+4		;NO
	SETZM TTEOUT(2)
	SETZM TTEIN(2)
	CALL TTRLBF		;RELEASE IT
	SKIPN 3,TTOOUT(2)	;OUTPUT BUFFERS TO RELEASE?
	JRST .+4		;NO
	SETZM TTOOUT(2)
	SETZM TTOIN(2)
	CALL TTRLBF		;RELEASE THEM
	HRRZ 3,TTYPE(2)		;SEE WHAT KIND OF LINE IT IS
	CAIE 3,12
	CAIN 3,13		;SCOPE OR LINEPROCESSOR?
	JRST TTROB1		;YES
	MOVEI 3,2		;NO, ORDINARY. SET BUFFERS FOR OUTPUT
	DPB 3,TTNOU		;TO STANDARD VALUE
	MOVEI 3,<2*NCHBF>-2	;AND MAX OUTPUT
	DPB 3,TTOMAX		; ..
	RET
TTROB1:	MOVEI 3,6		;EXTRA OUTPUT BUFFERS FOR FAST TERMINALS
	DPB 3,TTNOU		; ..
	MOVEI 3,<6*NCHBF>-2
	DPB 3,TTOMAX
	RET

;TTY CONTROL ROUTINES

TTCOBF:	CALL TNTCOB		; CLEAR TELENET OUTPUT BFR IF TNET LINE
	 RET			; DONE IF IT WAS A TELENET LINE

IFDEF IMPCHN,<
	CAIL 2,NVTLO		; NVT?
	CAILE 2,NVTHI
	SKIPA
	 JRST NVTCOB>		;YES, DO PROTOCOL FOR CLEARING OUTPUT
TTCOBI:	NOSKD1
	SETZM TTOCT(2)		;ZERO OUTPUT COUNT
	SETZB 3,TTOOUT(2)
	EXCH 3,TTOIN(2)
	CALL TTRLBF		;RELEASE BUFFERS
	SETZM TTECT(2)		;CLEAR ECHO BUFFER TOO
	SETZB 3,TTEOUT(2)
	EXCH 3,TTEIN(2)
	CALL TTRLBF
	OKSKD1
	RET

TTCIBF:	CALL TNTCIB		; PERFORM ANY TELENET ACTIONS
	 JFCL
	CALL NVTCIB##		; AND ANY NVT ACTIONS
	NOSKD1
	MOVEI 1,1B34
	ANDCAM 1,TTFLGS(2)	;CLEAR BKJFN FLAG
	SETZM TTICT(2)
	SETZM TTMCT(2)		; NO MARKS EITHER
	SETZB 3,TTIOUT(2)
	EXCH 3,TTIIN(2)
	CALL TTRLBF		;RELEASE BUFFERS
	OKSKD1
	RET

TTOBET:	SKIPE TTOCT(1)		;SCHEDULER TEST - NOW EMPTY?
	JRST 0(4)
	JRST 1(4)		;YES, RESCHED

TTOBNT:	SKIPN TTOCT(1)		;SCHEDULER TEST - NON-EMPTY?
	JRST 0(4)		;NO, EMPTY.
	JRST 1(4)		;NOT EMPTY. CAN READ CHARACTER(S).

TTIBET:	SKIPE TTICT(1)		;SCHEDULER TEST FOR INPUT BUF EMPTY
	JRST 0(4)		;NOT EMPTY
	JRST 1(4)		;EMPTY

	SWAPCD

;MORE CONTROL ROUTINES
;ALL TAKE LINE NUMBER IN AC2, ARG/VALUE IN 1, 2ND ARG/VALUE IN 3, ...

TTSIBE:	MOVEI 3,1B34		;BACKUP BIT
	MOVE 1,TTICT(2)		;SOMETHING IN BUFFER?
	SUB 1,TTMCT(2)		; DON'T COUNT MARKS
	SKIPG 1
	TDNE 3,TTFLGS(2)	;OR CAN RE-READ PREVIOUS CHAR?
	RET			;YES, BUFFER NOT EMPTY
	JRST RSKP

TTSOBE:	CALL TNTSBE		; CHECK IF TNET AND OUTPUT EMPTY
	 RET
	 JRST RSKP
	SKIPG 1,TTOCT(2)	;SKIP IF OUTPUT BUFFER EMPTY
	AOS 0(P)
	RET

TTSOBF:	CALL TNTSBF		; CHECK IF TELENET LINE AND BFR FULL
	 RET			; NOT FULL
	 JRST RSKP		; FULL
	LDB 3,TTOMAX		;CAPACITY OF OUTPUT BUFFER
	MOVE 1,TTOCT(2)		;SKIP IF OUTPUT BUFFER FULL
	CAIL 1,0(3)
	AOS 0(P)
	RET

TTDOBE:	CALL TNTDOB		; CHECK FOR TELENET
	 RET			; IT WAS AND THE BUFFER IS NOW EMPTY
	SKIPG 1,TTOCT(2)	;DISMISS UNTIL OUTPUT BUFFER EMPTY
IFNDEF IMPCHN,<	RET>		;NOW EMPTY
IFDEF IMPCHN,< JRST [CAIL 2,NVTLO
		CAILE 2,NVTHI
		 RET		; NOT NVT, DONE
		JRST NVTDOB]>	; NVT WAIT FOR ALL NET BUFFERS TO CLEAR
	MOVEI 1,TTOBET
	HRLI 1,0(2)		;LINE NUMBER
	JSYS EDISMS
	JRST TTDOBE

TTDIBE:	SKIPN TTICT(2)
	RET
	MOVEI 1,TTIBET		;INPUT BUFFER EMPTY TEST
	HRLI 1,0(2)
	JSYS EDISMS
	JRST TTDIBE

;TAB GET/SET

TTGTBS:	HRRZ 1,TTMOD1(2)	;TAB TABLE ADR
	MOVE 3,1(1)
	MOVE 4,2(1)
	MOVE 1,0(1)
	RET

TTSTBS:	PUSH P,1
	NOSKED			;TABLST AND TTMOD1 MUST BE CONSISTENT
	HRRZ 1,TTMOD1(2)	;ADDRESS OF CURRENT TABS
	CAIN 1,TAB81		;STANDARD?
	JRST TTSTB1		;YES, NOTHING TO RELEASE
	EXCH 1,TABLST		;PUT BUFFER ON FREE LIST
	MOVEM 1,@TABLST
	MOVEI 1,TAB81		;PUT STANDARD IN LINE WORD SO
	HRRM 1,TTMOD1		; NON-STD CAN'T BE FREED AGAIN
				; BY ANOTHER FORK IN THIS CODE
TTSTB1:	OKSKED
	POP P,1
	CAME 1,TAB81		;SEE IF REQUEST TABS ARE STANDARD
	JRST TTSTB2		;NO
	CAMN 3,TAB82
	CAME 4,TAB83
	JRST TTSTB2		;NO, NO
TTSTB4:	MOVEI 1,TAB81		;ADDRESS OF STANDARD TABS
TTSTB3:	HRRM 1,TTMOD1(2)
	RET

TTSTB2:	PUSH P,1
	NOSKED
	SKIPN TABLST		;FREE TAB BUFFERS?
	JRST [	OKSKED		;NO
		POP P,1
		JRST TTSTB4]	;USE STANDARD
	MOVE 1,@TABLST		;GET BUFFER
	EXCH 1,TABLST
	OKSKED
	MOVEM 4,2(1)		;STORE BIT WORDS IN BUFFER
	MOVEM 3,1(1)
	POP P,0(1)
	JRST TTSTB3

TTRMOD:	MOVE 1,TTFLGS(2)	;READ MODES
	RET

TTSMOD:	IFDEF IMPCHN,<CALL NVTMOD>
	PUSH P,1
	XOR 1,TTFLGS(2)		;SET RH BITS
	ANDI 1,776300		;CHANGE ONLY THESE BITS
	XORM 1,TTFLGS(2)
	LDB 1,[POINT 2,TTFLGS(2),29]; GET POSSIBLE NEW MODE
	DPB 1,TTYLMD		; MAKE IT BE CURRENT MODE
	POP P,1
	HLLOS TTFORK(2)		;RESET LINE TO NO-WAIT STATE
	RET

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

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

TTSCOC:	MOVEM 1,FCMOD1(2)	;SET CONTROL CHARACTER MODES
	MOVEM 3,FCMOD2(2)
	RET

;HANG UP DATASET
;STORAGE FOR HANGER-UPPER
LS TTHUR,<^D<<NLINES+35>/36>>	;FIRST REQUEST BITS
LS TTHUS,<^D<<NLINES+35>/36>>	;DELAYED REQUEST BITS
LS TTHTIM,1			;AND TODCLK FOR STEPPING THIS ROUTINE.

;CALL FROM LOGOUT JSYS TO TTHNGI OR TTHNGU, REQUESTING THE
; HANGUP. IF SLOW, JOB 0 DOES IT LATER.
TTHNGI::TDZA 1,1		;HANG UP IMMEDIATELY
TTHNGU:	SETO 1,0		;HANG UP AFTER POLITE DELAY
	CAIN 2,CTYLIN		;CAN'T HANGUP CTY
	RET
	PUSH P,1		;SAVE FAST/SLOW HANGUP FLAG
	CALL TTDOBE		;WAIT TILL NO OUTPUT
	POP P,1			;GET FAST/SLOW FLAG
	JUMPN 1,TTHNG2		;JUMP IF SLOW
	CALL TNTDET		; DETACH TELENET LINE
	 RET			; IT WAS AND IS NOW DETACHED
IFDEF IMPCHN,<
	CAIL 2,NVTLO		;IS IT AN NVT?
	CAILE 2,NVTHI		; ..
	SKIPA			;NO
	JRST NVTDET		;YES.
>
	MOVEI 1,TTHU0		;HANGUP FIRST STATE ROUTINE
	CALL TTQAD		;ADD TO QUEUE
	RET

..Q..==NDLS		; COMPUTE OR OF NDLS AND IFDEF IMPCHN
IFDEF IMPCHN,<..Q..==1>
IFN ..Q..,<
TTHNG2:	PUSH P,2		;SAVE LINE NUMBER
	MOVE 1,2		;COMPUTE A BIT FOR THE LINE NUMBER
	IDIVI 1,^D36		; ..
	MOVE 2,BITS(2)		; ..
	IORM 2,TTHUR(1)		;SET A BIT FOR REQUEST
	POP P,2			;RESTORE LINE NUMBER
	RET
>
;JOB ZERO ROUTINE TO ACTUALLY DO THE HANGUP ON LINES WHICH
;LOGGED OUT AND WHICH HAVE NOT HAD A ^C TYPED ON THEM.

TTHCK::	MOVE 1,TODCLK		;IS IT TIME TO DO THIS YET?
	CAMGE 1,TTHTIM		; ..
	RET			; NO. RETURN
	ADDI 1,^D60000		;YES. UPDATE FOR NEXT CHECK
	MOVEM 1,TTHTIM		; ..
	MOVSI 10,-^D<<NLINES+35>/36>
TTHCK2:	MOVEI 11,0		;CLEAR REQUEST WORD
	EXCH 11,TTHUR(10)	;PICK UP REQUESTS SINCE LAST CALL
	EXCH 11,TTHUS(10)	;MOVE THEM TO SECOND BIT PER LINE.
TTHCK0:	JFFO 11,TTHCK1		;SEE IF ANY OVER A MINUTE OLD.
	AOBJN 10,TTHCK2		;THEN GO ON TO NEXT WORD
	RET			;AND QUIT WHEN WHOLE TABLE SEARCHED

;HERE WHEN FOUND A LINE TO HANG UP
TTHCK1:	TDZ 11,BITS(12)		;CLEAR THE BIT WHICH WAS FOUND
	MOVEI 2,(10)		;COMPUTE THE LINE NUMBER IN 2
	IMULI 2,^D36		; ..
	ADDI 2,(12)		; ..
	PUSH P,11		;SAVE CURRENT WORD
	PUSH P,12		;AND INDEX
	CALL TTHANG		;INITIATE THE HANGUP SEQUENCE IN HWARE
	POP P,12
	POP P,11		;RESTORE BITS
	JRST TTHCK0		;BACK TO SEE IF MORE IN THIS WORD

;PLACE REQUEST IN QUEUE IFF LINE IS STILL IDLE

TTHANG:	SKIPGE 1,TTFORK(2)	;LINE UNASSIGNED?
	TLNN 1,1		;AND NOT IN STARTUP STATE?
	  RET			;BUSY. DON'T HANG UP.
	CALL TNTDET		; CHECK IF TELENET
	 RET			; IT WAS AND IS NOW DETACHED
IFDEF IMPCHN,<
	CAIL 2,NVTLO		;IS IT AN NVT?
	CAILE 2,NVTHI		; ..
	SKIPA			;NO
	JRST NVTDET		;YES.
>
	CAIN 2,CTYLIN		;IS IT THE CTY?
	RET			;YES. DON'T TRY TO HANG IT UP
	MOVEI 1,TTHU0		;FREE. HANG IT UP.
	CALL TTQAD		; ..
	RET

;"BACKUP" INPUT POINTER - CAN ONLY BACKUP ONE

TTBKPT:	MOVEI 3,1B34
	TDNE 3,TTFLGS(2)	;ALREADY BACKUPED?
	RET			;YES
	IORM 3,TTFLGS(2)	;SET FLAG TO BE NOTICED AT NEXT TCI
	JRST RSKP

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

	RESCD

TTSTI:	PUSH P,1
	CALL TNTSTI		; CHECK IF TELENET
	 JRST TTSTI0		; BYPASS WAITS
	CALL TTSOBF		; ROOM FOR DEFERRED ECHOS?
	 JRST TTSTI0		; YES, GO AHEAD
	MOVEI 1,TCOTST		; NO, WAIT
	HRL 1,2
	JSYS EDISMS
TTSTI0:	POP P,1
	ANDI 1,377		;ISOLATE CHARACTER
	MOVEI 6,TTSCF		; FLAG CH FROM STI
	NOSKED
	CALL TTCHI		; STUFF IT INTO TTY BUFFER
	OKSKED
	RET

.STO::	JSYS MENTR
	UMOVE 1,1		;DESIRED INPUT TTY DESIGNATOR
	CALL CHKTTM		;THIS GUY ALLOWED TO USE IT?
	CALL TTSTO		;YES. GET A CHARACTER
	UMOVEM 1,2		; RETURN TO USER IN AC 2
	JRST MRETN

TTSTO:
TTSTO2:	NOSKD1
	CHNOFF DLSCHN		;PROTECT BUFFER ROUTINES
	SKIPN TTECT(2)		;ECHO BUFFER HAVE ANYTHING?
	JRST TTSTO0		;NO, TRY MAIN OUTPUT BUFFER
	SKIPN 1,TTEOUT(2)	;YES. GET POINTER
	JRST STOBUG		;FAILURE.
	TDNN 1,WRPMSK		;DO POINTER WRAPAROUND
	HRR 1,1-TTSIZ(1)
	MOVEM 1,TTEOUT(2)
	ILDB 1,TTEOUT(2)	;GET A CHARACTER
	SOS TTECT(2)		;COUNT IT
	JRST TTSTO4		;FINISH UP
TTSTO0:	SKIPN TTOCT(2)		;ANY CHARS TO READ?
	JRST TTSTO1		;NO
	SKIPN 1,TTOOUT(2)	;YES. GET BUFFER PTR
STOBUG:	BUG(HLT,<TTSTO - NO OUTPUT BFR BUT COUNT NON-0>)
	TDNN 1,WRPMSK
	HRR 1,1-TTSIZ(1)	;FOLLOW LINK
	MOVEM 1,TTOOUT(2)
	ILDB 1,TTOOUT(2)
	SOS TTOCT(2)
TTSTO4:	CHNON DLSCHN
	OKSKD1
	ANDI 1,377
	RET

TTSTO1:	CHNON DLSCHN
	OKSKD1
	MOVSI 1,0(2)
	HRRI 1,TTOBNT
	JSYS EDISMS
	JRST TTSTO2
	SWAPCD

;SET/GET TERMINAL TYPE

.STTYP:	JSYS MENTR
	CALL CHKTTM
	UMOVE 3,2
	CAIL 3,0		;REASONABLE NUMBER?
	CAIL 3,NTTYPS
	ITERR			;NO
	HRRM 3,TTYPE(2)
	LDB 1,TTMBIT		;GET MECH BITS
	DPB 1,[POINT 3,TTFLGS(2),3] ;PUT WHERE NOTICED
	JRST MRETN

.GTTYP:	JSYS MENTR
	CALL CHKTTM
	HRRZ 1,TTYPE(2)
	UMOVEM 1,2
	LDB 1,TTNIN		;RETURN BUFFER ALLOC ALSO
	LDB 3,TTNOU
	HRLI 3,0(1)
	UMOVEM 3,3
	JRST MRETN

;SET TERMINAL PARAMETERS

.STPAR:	JSYS MENTR
	CALL CHKTTM
	UMOVE 1,2
	IFDEF IMPCHN,<
	CALL NVTPAR>		; GO PERFORM ANY NVT NEGOTIATIONS NEEDED
	PUSH P,1
	XOR 1,TTFLGS(2)
	ANDI 1,74		;CHANGE THESE BITS
	XORM 1,TTFLGS(2)
	LDB 1,[POINT 7,0(P),10]
	CAIL 1,10		;LEGAL PAGE SIZE?
	CAIL 1,200
	MOVEI 1,^D66		;USE DEFAULT
	DPB 1,[POINT 7,TTFLGS(2),10]
	LDB 1,[POINT 7,0(P),17]
	CAIL 1,10		;LEGAL WIDTH
	CAIL 1,200
	SETZ 1,			;DEFAULT IS NO FOLDING
	DPB 1,[POINT 7,TTFLGS(2),17]
	LDB 1,[POINT 3,0(P),3]
	DPB 1,[POINT 3,TTFLGS(2),3]	;LH BITS
	POP P,1
	JRST MRETN

;CODE TO DRIVE NON-STANDARD AUTOMATIC DIALLER AT BBN
;
;JSYS IS TDIAL: CALLING SEQUENCE IS
;
;	MOVE 1,DESIGNATOR OF DIALLER TTY
;	MOVEI 2,CODE FOR WHAT TO DO
;	TDIAL
;	  LOSE RETURN
;	WIN RETURN
;
;CODES DEFINED SO FAR:
;
;	CODE 0: DIAL THE NUMBER IN AC'S 3 AND 4. THE NUMBER
;IS SUPPLIED IN 4-BIT BYTES, WITH A 17 BYTE TERMINATING THE NUMBERN
;THUS 17 DIGITS AND A TERMINATOR IS THE LONGET NUMBER POSSIBLE.
;FIRST DIGIT IS BITS 0-3 OF AC3, ETC...
;
;	CODE 1: DISCONNECT. HANG UP THE PHONE.
;
;	CODE 2: SELECT DIALLER ON WATS LINE
;	CODE 3: SELECT DIALLER ON LOCAL LINE
;	CODE 4: TEST NCC EXCLUSION KEY. 1 GETS 0 IF BUSY, -1 IF FREE
;
IFDEF DIALLN,<

.TDIAL::JSYS MENTR		;SLOW JSYS
	PUSHJ P,CHKTTM##	;MAKE SURE A TTY. GET LINE IN 2
	MOVSI 1,(NSMODM)	;IS THAT A GOOD UNIT?
	TDNN 1,TTMOD1(2)	; ..
	RETERR
	UMOVE 1,2		;OK, GET THE ARGUMENT
	CAIL 1,0
	CAIL 1,NDIALC		;RANGE CHECK IT
	RETERR
	JRST @DIALTB(1)		;OK. DISPATCH
DIALTB:	EXP DIALPC,DIALHU,DIALSW,DIALCW,DIALTW
NDIALC==.-DIALTB

DIALHU:	PUSHJ P,TTHU2
	MOVEI 1,^D2000		; WAIT 2 SECONDS
	DISMS
	JRST SKMRTN		;HANG UP THE PHONE, WAIT, RETURN GOOD

DIALSW:	SKIPA 3,BITS+^D16	;SET DIALER TO WATS LINE
DIALCW:	MOVSI 3,(1B17)		;CLEAR WATS, SET LOCAL LINE
	DATAO PTR,3		;SEND TO KLUDGE BIT IN CPU
	JRST SKMRTN		;SUCCESS RETURN

DIALTW:	CONI PTR,1		;TEST WATS LINE AVAILABILITY
	TLNN 1,(1B17)		;KLUDGE INPUT BIT FROM NCC EXCL KEY
	TDZA 1,1		;LINE IS AVAILABLE
	SETO 1,0		;LINE IS IN USE AT NCC
	UMOVEM 1,1		;RETURN THE ANSWER
	JRST SKMRTN		;AND SUCCESS RETURN

DIALPC:	MOVE A,TTFLGS(B)	;SEE IF PHONE IN USE
	TRNE A,1		;CARRIER ON?
	RETERR			;YES. FAIL.
	UMOVE A,3		;OK. GET THE NUMBER.
	MOVEM A,DILNM1		; SAVE FIRST HALF OF NUMBER
	UMOVE A,4
	TRO A,17		;MAKE SURE IT TERMINATES
	MOVEM A,DILNM2		;SAVE SECOND HALF OF NUMBER
	SETOM DILOOF		;WAIT FOR CARRIER ON FIRST TIME.
	NOINT
	CALL TTHU2		;MAKE SURE LINE IS FREE
	MOVEI A,^D100
	DISMS
	CALL TTHU1		;GET DIAL TONE
	MOVEI A,^D30000		;WAIT HALF A MINUTE FOR DIAL TONE
	ADD A,TODCLK
	MOVEM A,DILTIM		; ..
	MOVE A,[440400,,DILNM1]	; POINTER TO THE NUMBER
	MOVEM A,DILNMP
	MOVE A,[DILNMP,,DISET##]; WAIT FOR CLK ROUTINE TO CLEAR IT
	JSYS EDISMS		; ..
	MOVE A,DILDNF		; SEE WHAT THE RESULT WAS.
	JUMPGE A,DILPCF		; IF POSITIVE, FAILED.
	OKINT
	JRST SKMRTN		;GOOD RETURN
DILPCF:	CALL TTHU2		;HANG UP PHONE
	MOVEI 1,^D5000		;WAIT FOR IT
	DISMS
	OKINT
	RETERR

RESCD

INTERN DILCHK
DILCHK:	SKIPN DILNMP		;CALL HERE FROM CLK2 CHECK ROUTINE
	RET			; NOTHING TO DO
	MOVE A,TTFLGS+DIALLN	;GET THE FLAG WORD OF DIALLER LINE
	XOR A,DILOOF		;WHICH WAY DO WE WANT IT?
	TRNN A,1		;IS IT THERE YET?
	JRST DLCHK1		;YES.
	MOVE A,DILTIM		;NO. TIME TO GIVE UP?
	CAML A,TODCLK
	RET			;NO. WAIT.
	MOVEI A,1		;YES. FAIL CODE IS +N. SHOULD BE REAL
	MOVEM A,DILDNF		;  ERROR CODE.
	SETZM DILNMP		;CLEAR POINTER AS FLAG TO RUN PROCESS
	RET

DLCHK1:	SKIPN DILOOF		;CARRIER FLAG NOW ON OR OFF?
	JRST DLCHK2		;OFF.
	ILDB A,DILNMP		;ON. GET ANOTHER DIGIT
	CAIL A,14		;NORMALIZE EON CODES
	MOVEI A,14
	TRO A,60		;ASCII DIGIT TO BE READABLE
	MOVEI B,DIALLN		;LINE WITH DIALLER
	CALL TCEOUT		;TYPE THE DIGIT
	SETZM DILOOF		;NOW HAVE TO WAIT FOR CARRIER FLG OFF
DLCHK3:	MOVEI A,^D30000		;ANOTHER HALF-MINUTE TIMEOUT
	ADD A,TODCLK		; ..
	MOVEM A,DILTIM		; ..
	RET

DLCHK2:	LDB A,DILNMP		;CARRIER OFF. WAS LAST DIGIT EON?
	CAIL A,14		; ..
	JRST DLCHKW		;YES. THIS JSYS HAS WON.
	SETOM DILOOF		;NO, MUST WAIT FOR OFF, ON AND SEND MORE
	JRST DLCHK3		; ..

DLCHKW:	SETOM DILDNF		;FLAG WE HAVE WON
	SETZM DILNMP		;WAKE UP THE PROCESS
	RET

LS DILNMP,1			;POINTER TO NUMBER BEING DIALLED
LS DILNM1,1			;STORAGE FOR THE NUMBER
LS DILNM2,1			; ..
LS DILDNF,1			;COMMUNICATION CELL FOR ANSWER
LS DILOOF,1			;DIALLER ON/OFF FLAG. FOR CARRIER WAITS.
LS DILTIM,1			;TIMEOUT IN CASE HARDWARE FAILS

SWAPCD

>;END OF CONDITIONAL ON DIALLER EXISTANCE

;TLINK JSYS

.TLINK:	JSYS MENTR
	MOVEI 1,0(1)
	CALL CHKTTM		;CHECK DESIGNATOR, GET LINE NO IN 2
	PUSH P,2		;SAVE OBJECT LINE NUMBER
	UMOVE 1,1
	TLNN 1,(74B5)		;SECOND DESIGNATOR REQUIRED?
	JRST TL1		;NO
	XCTUU [HRRZ 2,2]
	CAIN 2,-1		;'ALL' ?
	JRST TL1		;YES, LEAVE AS IS
	TRZE 2,1B18		;4XXXXX?
	JRST TL2		;YES
	MOVE 1,2		;ASSUME REGULAR JFN
	CALL CHKTTM
TL2:	CAIGE 2,NLINES		;LEGAL LINE?
	CAIGE 2,0
	RETERR DESX1		;NO
TL1:	POP P,7			;OBJECT DESIGNATOR
	UMOVE 6,1		;GET FUNCTION FLAGS
	TLNE 6,(1B0)
	CALL TLINK0		;CLEAR REMOTE TO OBJECT
	TLNE 6,(1B1)
	CALL TLINK1		;CLEAR OBJECT TO REMOTE
	TLNE 6,(1B2)
	CALL TLINK2		;SET OBJECT TO REMOTE
	TLNE 6,(1B3)
	CALL TLINK3		;SET REMOTE TO OBJECT
	TLNE 6,(1B4)
	CALL TLINK4		;SET ACCEPT BIT TO C(B5)
MRSKP:	AOS 0(P)
	JRST MRETN

;CLEAR REMOTE TO OBJECT

TLINK0:	CAIE 2,-1		;ALL REMOTES?
	JRST [	CALL TL0C	;NO, DO THE ONE SPECIFIED
		RET]
	PUSH P,2
	MOVEI 2,0		;SCAN ALL LINES
	CALL TL0C		;CLEARING ANY LINKS TO OBJECT
	CAIGE 2,NLINES-1
	AOJA 2,.-2
	POP P,2
	RET

TL0C:	CALL TLTST1		;LOOK AT REMOTE LINE
	JUMPL 1,R		;DONE IF NO LINKS TO OBJ
	MOVEI 1,777
	DPB 1,5			;CLEAR THE LINK JUST FOUND
	JRST TL0C

;CLEAR OBJECT TO REMOTE

TLINK1:	CAIE 2,-1		;ALL?
	JRST [	CALL TL1C	;NO, CLEAR SPECIFIC
		RET]
	MOVE 5,[POINT 9,TTLINK(7),-1]
	PUSH P,2
TL12:	ILDB 2,5		;SCAN ALL FIELDS OF OBJECT LINE
	CAIN 2,777
	JRST .+4
	PUSH P,5
	CALL TL1C
	POP P,5
	TLNE 5,(7B2)
	JRST TL12
	POP P,2
	RET

TL1C:	CALL TLTST2		;FIND LINK TO REMOTE
	JUMPL 1,R		;NONE, DONE
	MOVE 1,CAPMSK
	TRNE 1,WHEEL+OPER	;PRIVILEGED?
	JRST TL13		;YES, SKIP CHECK
	PUSH P,5
	CALL TLTST1		;EXISTS REMOTE TO OBJECT?
	POP P,5
	JUMPG 1,TLNKE1		;ERROR IF YES
TL13:	MOVEI 1,777
	DPB 1,5			;CLEAR LINK JUST FOUND
	JRST TL1C

TLNKE1:	ITERR TLNKX1		;ILLEG REM TO OBJ

;SET OBJECT TO REMOTE

TLINK2:	CAIN 2,-1
	RETERR DESX1		;NON-SPECIFIC DESIGNATOR ILLEG HERE
	CAMN 2,7		;LINK TO SELF?
	RET			;YES, IGNORE
	CALL TLTST2		;LINK ALREADY EXISTS?
	JUMPG 1,R		;IGNORE IF YES
	MOVEI 5,5		;DO 5 RINGS
TL21:	MOVEI 3,1B26		;ACCEPT BIT
	MOVE 4,CAPENB
	TRNN 4,WHEEL+OPER	;PRIVILEGED? OR
	TDNE 3,TTFLGS(2)	;REMOTE ACCEPTING?
	JRST TL22		;YES
	JUMPL 5,[		;NO, GIVEE ERROR AFTER FIVE RINGS
		RETERR(TLNKX2)]
	MOVEI 4,^D10		;A RING IS 10 BELLS
	MOVEI 1,"G"-100		;BELL
TL23:	CALL TCEO2		;RING REMOTE
	EXCH 2,7
	CALL TCEO2		;RING LOCAL
	EXCH 2,7
	SOJG 4,TL23
	MOVEI 1,^D3000		;WAIT FOR 3 SECONDS, THE BELL WILL BE
	DISMS			;RINGING FOR THE FIRST SECOND OF WAIT
	SOJA 5,TL21		;GO SEE IF REMOTE NOW ACCEPTING

TL22:	PUSH P,2
	MOVEI 2,777
	CALL TLTST2		;FIND FREE FIELD IN OBJECT
	POP P,2
	JUMPL 1,[		;GIVE LINKS FULL ERROR
		RETERR(TLNKX3)]
	DPB 2,5			;DEPOSIT REMOTE NUMBER IN FIELD
	HLRZ 1,TTFORK(2)	;1=OWNING JOB OF REMOTE
	TLNN 6,(1B17)		;SUPPRESS MSG REQUESTED?
	JRST TL22B		;NO, GO GIVE IT.
	CAMN 1,JOBNO		;YES, USER HAVE REMOTE ASSIGNED?
	RET			;YES, FINISHED
	MOVE 1,CAPENB		;NO. SEE IF ENABLED WHOPR
	TRNE 1,WHEEL+OPER	; ..
	RET			; YES. SUPPRESS MSG
TL22B:	PUSH P,2		;OUTPUT MESSAGE TO SOURCE, THUS
				; GETTING TO DEST TOO.
	XCTUU [HRRZ 1,1]	;OBJECT DESIGNATOR
	HRROI 2,[ASCIZ /
LINK FROM /]
TL22AD:	SETZ 3,
	SOUT			;MSG ON OBJECT ALSO SEEN ON REMOTE
	MOVE 2,JOBNO
	HRRZ 2,JOBDIR(2)	;USER ON THIS JOB
	DIRST			;TYPE HIS NAME
	JFCL
	HRROI 2,[ASCIZ /, JOB /]
	SOUT
	MOVE 2,JOBNO
	MOVEI 3,12
	NOUT
	  JFCL
	MOVEI 3,0
	HRROI 2,[ASCIZ /, TTY /]
	SOUT
	MOVE 2,7		;OBJECT LINE NUMBER
	MOVEI 3,10
	NOUT
	JFCL
	MOVEI 2,37
	BOUT
	POP P,2
	RET

;SET REMOTE TO OBJECT

TLINK3:	CAIN 2,-1
	RETERR DESX1		;MULTIPLE DESIGNATOR ILLEGAL
	CAMN 2,7		;LINK TO SELF?
	RET			;YES, IGNORE
	CALL TLTST1		;LINK ALREADY EXISTS?
	JUMPG 1,R		;RETURN IF SO
	MOVE 1,CAPENB
	TRNE 1,WHEEL+OPER	;PRIVILEGED?
	JRST TL31		;YES, SKIP SHECK
	CALL TLTST2		;CHECK OBJ TO REMOTE
	JUMPL 1,TLNKE1		;ERROR, OBJ TO REMOTE NOT DONE FIRST
TL31:	PUSH P,7
	MOVEI 7,777
	CALL TLTST1		;FIND FREE FIELD IN REMOTE
	POP P,7
	JUMPL 1,MRETN		;LINK WORD FULL
	DPB 7,5			;DEPOSIT OBJ NUMBER IN FIELD
	RET

;SET ACCEPT BIT

TLINK4:	MOVEI 1,1B26		;IT IS BIT 26 IN TTFLGS
	TLNE 6,(1B5)		;SET IT?
	IORM 1,TTFLGS(7)	;YES
	TLNN 6,(1B5)		;CLEAR IT?
	ANDCAM 1,TTFLGS(7)	;YES
	RET

;CHECK FOR EXISTENCE OF REMOTE TO OBJECT
; VALUE .GE. 0 MEANS YES

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

;CHECK FOR EXISTENCE OF OBJECT TO REMOTE
; VALUE .GE. 0 MEANS YES

TLTST2:	MOVE 5,[POINT 9,TTLINK(7),-1]
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

COMMENT \

;ADVIZ JSYS -- ADVISE ANOTHER TERMINAL
	ACCEPTS IN 1: CONTROL WORD AS FOLLOWS:
	B0=1 BREAK ANY ADVISE LINK TO/FROM ME
	B1=1 ESTABLISH ADVISE LINK FROM ME TO LINE IN 18-35
	B2=1 SET UP TO RECEIVE ADVICE FROM LINE IN 18-35

	RETURNS +1:	UNSUCCESSFUL, ERROR CODE IN 1
		+2:	SUCCESSFUL, ADVISE LINK ESTABLISHED
NOTE THAT THE CHARACTERS ^Y AND ^C HAVE SPECIAL MEANING FROM AN
ADVISOR: ^Y IS TRANSLATED TO ^C AND SENT AS ADVICE. ^C BREAKS
THE ADVISE LINK, BUT NOT THE OUTPUT LINK

TTADVS(LINE) HAS -1 IF NOT ADVISING OR BEING ADVISED,  0,,N  IF
	ADVISING LINE N,  OR  -1,,M  IF RECEIVING ADVISE FROM
	LINE M, OR  400000,,P IF WILLING TO RECEIVE ADVISE
	FROM LINE P
\

.ADVIZ:	JSYS MENTR		;ENTER MONITOR ENVIRONMENT
	MOVE 6,1		;SAVE CALLING ARGUMENT IN 6
	TLNE 1,(1B1)		;MAKE SURE NOT REQUESTING BOTH
	TLNN 1,(1B2)		;DIRECTIONS AT ONCE
	CAIA			;OK
	  RETERR ADVX3		;NO GOOD
	TLNN 1,(1B1!1B2)	;BOTH OFF?
	JRST ADVIZ0		;YES. BREAK THE LINKS, IF ANY.
	HRRZ 2,6		;GET TTY NUMBER INVOLVED
	TRZE 2,400000		;DESIGNATOR BIT ON?
	JRST ADVIZ1		;YES
	MOVE 1,2		;NO. MAY BE A TTY JFN
	CALL CHKTTM		;GO SEE, ERROR IF NOT.
ADVIZ1:	CAIGE 2,NLINES		;LEGAL LINE?
	CAIGE 2,0		; ..
	RETERR DESX1		;NO.
	MOVE 10,2		;OK. SAVE THE LINE NUMBER IN 10
ADVIZ0:	TLNE 6,(1B0)		;REQUEST TO BREAK LINK?
	CALL TADVS0		;YES
	TLNE 6,(1B1)		;REQUEST TO ADVISE SOMEONE?
	CALL TADVS1		;YES
	TLNE 6,(1B2)		;REQUEST TO RECEIVE ADVICE?
	CALL TADVS2		;YES
	JRST SKMRTN		;GIVE SKIP RETURN
RESCD
;RESIDENT BECAUSE DONE BY ^C
;BREAK ADVISE LINK.
TADVS0:	HRRZ 2,CTRLTT		;GET MY LINE NUMBER
	CAIN 2,-1
	RETERR DESX1		;BUT I AM DETACHED!
TADV00:	PUSH P,1		;CALLED HERE BY ^C
	SETO 1,
	EXCH 1,TTADVS(2)	;BREAK THE LINK. WHAT WAS IT?
	HRRZS 1			;LINE NUMBER
	CAIGE 1,NLINES		;IF STILL THERE.
	SETOM TTADVS(1)		;BREAK HIS SIDE OF IT TOO.
	POP P,1			;RESTORE AC 1
	RET			;POPJ
SWAPCD

;SET ME UP TO ADVISE SOMEONE ELSE (LINE IN 10)

TADVS1:	HRRZ 7,CTRLTT		;GET THE CONTROLLING TTY NUMBER
	CAIE 7,-1		;DETACHED?
	CAIN 7,0(10)		;OR TRYING TO ADVISE SELF?
	RET			;JUST RETURN.
	CAMN 10,TTADVS(7)	;ALREADY SET UP?
	RET			;YES. IGNORE.
	NOSKED
	MOVE 2,TTADVS(7)	;SEE IF ALREADY ANOTHER ONE
	AOJN 2,CADVX4		;JUMP IF WASN'T -1
TADV11:	MOVE 4,CAPENB		;SEE IF A WHEEL/OPER
	TRNE 4,WHEEL+OPER
	JRST TADV12		;YES. DONT NEED PERMISSION
	HRRZ 4,TTADVS(10)	;NO, SEE IF ACCEPT HAS BEEN DONE
	HLRZ 3,TTADVS(10)
	CAIN 3,(1B0)		;B0 ON?
	CAME 4,7		;AND THIS LINE NUMBER = SELF?
	CAIA			;NO. NOT ACCEPTED
	JRST TADV12		;OK
	OKSKED			;ALLOW SCHEDULING AGAIN
	RETERR(ADVX1)		;NOT ACCEPTED

;HERE TO ACTUALLY SET THE ADVISE LINK

TADV12:	NOINT			;STABILIZE TABLES
	OKSKED			;ALLOW OTHER JOBS TO RUN
	HRRZ 2,10		;GET ADVISEE LINE
	CALL TLTST2		;ADVISOR ALREADY LINKED TO ADVISEE?
	JUMPGE 1,TADV13		;YES
	MOVEI 2,777
	CALL TLTST2		;LOOK FOR FREE LINK
	JUMPL 1,TADV19		;NONE, GIVE ERROR
	DPB 10,5		;SET LINK
TADV13:	HRRZ 2,10		;ADVISEE LINE
	CALL TLTST1		;ADVISEE ALREADY LINKED TO ADVISOR?
	JUMPGE 1,TADV14		;YES
	PUSH P,7
	MOVEI 7,777
	CALL TLTST1		;LOOK FOR FREE ENTRY
	POP P,7
	DPB 7,5			;SET THE LINK
	JUMPL 1,TADV19		;NONE, GIVE ERROR

TADV14:	HRRZM 10,TTADVS(7)	;SET UP ADVISEE TO BE RECEIVING
	HRROM 7,TTADVS(10)	;AND ADVISOR TO BE SENDING
	OKINT
	PUSH P,2		;NEEDED TO MATCH LEVEL IN LINK
	MOVEI 1,400000(7)	;SEND MSG TO THIS LINE
	HRROI 2,[ASCIZ /
ADVICE FROM /]
	JRST TL22AD		;JOIN CODE FOR LINK MESSAGE


TADV19:	SETOM TTADVS(10)	;FLUSH ADVISE LINK (MAKE IDLE)
	MOVEI 1,TLNKX3
	OKINT
	JRST MRETNE		;RETURN ERROR CODE

;HERE FROM ADVIZ JSYS TO ACCEPT ADVICE.

TADVS2:	HRRZ 7,CTRLTT		;MY LINE NUMBER
	CAIL 7,-1		;DETACHED?
	RETERR DESX1
	NOSKED
	MOVE 3,TTADVS(7)	;GET MY CURRENT ADVISE STATE
	AOJE 3,TADV20		;JUMP IF WAS IDLE
CADVX4:	OKSKED
	RETERR ADVX4		;ERROR. ANOTHER ADVISE IN PROGRESS.

TADV20:	MOVSI 3,(1B0)		;SET RECEIVING FROM LINE N
	HRR 3,10		;HERE'S N
	MOVEM 3,TTADVS(7)	;SET TO ACCEPT ADVISE
	OKSKED
	RET

;CODE TO ACTUALLY DO THE ADVISE
;
; 1)	CHAR TYPED BY ADVISOR
; 2)	LINE NUMBER OF ADVISOR
; 3)	LINE NUMBER OF ADVISEE

RESCD

TTAVS:	CALL TNTAVS		; DO ANY TELENET SPECIFIC THINGS
	 JFCL
	MOVEI 4,0(1)		;GET JUST 7 BITS
	ANDI 4,177		; ..
	CAIN 4,"C"&37		;CONTROL C?
	JRST [	CALL TADV00	;YES. BREAK LINK.
		RET]		;AND RETURN
	MOVE 2,3		;SWITCH LINE NUMBERS
	CAIN 4,"Y"&37		;CONTROL Y?
	MOVEI A,"C"&37		;YES, MAKE IT A CONTROL C
	RET

;PSEUDO-INTERRUPT CHARACTER TABLE
	RADIX 10
NU==36		;NOT USED VALUE

PSICH:	0	;CONTROL GROUP - @ (BREAK)
	1	;A
	2	;B
	3	;C
	4	;D
	5	;E
	6	;F
	7	;G

	8	;H
	9	;I
	10	;J
	11	;K
	12	;L
	13	;M (CR)
	14	;N
	15	;O

	16	;P
	17	;Q
	18	;R
	19	;S
	20	;T
	21	;U
	22	;V
	23	;W

	24	;X
	25	;Y
	26	;Z
	27	;ALTMODE
	NU	;34
	NU	;35
	NU	;36
	NU	;37

	29	;SPACE
PSICHH:	NU	;173
	NU	;174
	27	;175 (OLD ALTMODE)
	27	;176 (OLD ALTMODE)
	28	;177 (RUBOUT)
	RADIX 8

PSICHU==173		;FIRST CHARACTER OF UPPER GROUP
PSICHL==PSICHH-PSICH	;SIZE OF LOWER GROUP
PSICHO==PSICH+PSICHU-PSICHH	;UPPER GROUP OFFSET

;CHARACTER CLASS TABLE (FOR WAKEUP CONTROL)

FC==10		;FORMAT CONTROL
CC==4		;CONTROL, NON-FORMAT
PC==2		;PUNCTUATION
ANC==1		;ALPHANUMERIC

DEFINE	%BYTE(AA)<
	BYTE (6)AA
	IRP AA,<
	IFE CHB&377,<
	IFN AA&FC,<FCM==FCM!CHB>
	IFN AA&CC,<CCM==CCM!CHB>
>
CHB==CHB_-1>
>

CHB==400000000000
FCM==0
CCM==1B28	; START WITH RUBOUT
PCM==1B29		; ONLY SPACE IS INTERRUPT

TTWKTB:	%BYTE<CC,CC,CC,CC,CC,CC>		;NULL - E(C)
	%BYTE<CC,CC,FC,FC,FC,FC>		;F(C) - K(C)
	%BYTE<FC,FC,CC,CC,CC,CC>		;L(C) - Q(C)
	%BYTE<CC,CC,CC,CC,CC,CC>		;R(C) - W(C)
	%BYTE<CC,CC,CC,CC,CC,CC>		;X(C) - Z(C), ESC - 035
	BYTE (6) CC,FC,PC,PC,PC,PC		;036, EOL, SPACE - #
	REPEAT 2,<BYTE (6) PC,PC,PC,PC,PC,PC>
						;$ - /
	BYTE (6) ANC,ANC,ANC,ANC,ANC,ANC	;0 - 5
	BYTE (6) ANC,ANC,ANC,ANC,PC,PC		;6 - 9, COLON, SEMI
	BYTE (6) PC,PC,PC,PC,PC,ANC		;LEFT ANG BK - AT, A
	REPEAT 4,<BYTE (6) ANC,ANC,ANC,ANC,ANC,ANC>
						;B - Y
	BYTE (6) ANC,PC,PC,PC,PC,PC		;Z, LEFT BK - LARR
	BYTE (6) PC,ANC,ANC,ANC,ANC,ANC		;140, A(LC) - E
	REPEAT 3,<BYTE (6) ANC,ANC,ANC,ANC,ANC,ANC>
						;;F(LC) - W(LC)
	BYTE (6) ANC,ANC,ANC,PC,PC,PC		;X - Z(LC), 173 - 175
	BYTE (6) PC,CC			;176, RUBOUT

;6-BIT POINTER TABLE

	POINT 6,0,-1
CH6TAB:	POINT 6,0,5
	POINT 6,0,11
	POINT 6,0,17
	POINT 6,0,23
	POINT 6,0,29
	POINT 6,0,35

BHC:	XLIST	;REPEAT 20,<	XWD .-BHC,.-BHC>
	REPEAT 20,<	XWD .-BHC,.-BHC>
	LIST

BITS:	XLIST
	REPEAT ^D36,<	EXP 1B<.-BITS>>
	LIST

;DEFINE SOME HANDY CONSTANTS AS GLOBALS TO REDUCE DUPLICATED LITERALS
ZERO=:BHC		;FIRST WORD OF BHC CONTAIS 0,,0 , I.E., 0
ONE=:BITS+43		;BIT 35 ON IS A CONSTANT ONE
TWO=:BITS+42		;BIT 34 ON IS A CONSTANT TWO
MINUS1:: EXP -1		;AND A CONSTANT MINUS ONE IS COMMONLY USED.

;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:	MOVE 3,TTFLGS(2)
	TRCN 3,3B29		;BINARY?
	JRST TCOUTX		;YES, DIRECT OUTPUT, NO TRANSLATION
	PUSH P,6
	SETZ 6,			; COMMUNICATE TO LOW LEVEL "NOT ECHO"
	PUSH P,1
	ANDI 1,177
	TRCN 3,3B29		;MODE 3? (BOTH 1'S)
	JRST TC1B		;YES, NO OUTPUT TRANSLATION
TCOE1:	CAIGE 1,40		;CONTROL GROUP?
	JRST TC1A		;YES
TC1B:	CALL TCOY
TC1C:	POP P,1
	POP P,6
	RET

;ECHO OUTPUT

TCOE:	PUSH P,6
	SETO 6,			; COMMUNICATE TO LOW LEVEL "ECHO"
	PUSH P,1
	ANDI 1,177
	CAIN 1,177		;RUBOUT?
	JRST TC1C		;DON'T ECHO (FIXES NVT LINK PROBLEM)
	MOVE 3,TTFLGS(2)
	TRNE 3,1B29		;MODE 1 OR 3?
	JRST TCOE1		;YES, TRANSLATE INPUT
	JRST TC1B

;TRANSLATE CONTROL CHARS ACCORDING TO CC MODES
; 00 - SEND NOTHING
; 01 - INDICATE, E.G. ^A
; 1X - DO FUNCTION (SECOND LEVEL HANDLES SIMULATION IF NECESSARY)

TC1A:	MOVE 4,FCMOD2(2)
	MOVE 3,FCMOD1(2)	;GET MODE BITS
	ROTC 3,0(1)
	ROTC 3,0(1)
	CAIN 1,33		;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]
	TLNE 3,(1B0)		;DO?
	JRST TC1B		;YES
	TLNN 3,(1B1)		;FLUSH?
	JRST TC1C		;YES
TC1D:	ADDI 1,100		;CONVERT TO PRINTING EQUIV.
	PUSH P,1
	MOVEI 1,TTCIND
	CALL TCOY		;PRINT INDICATOR
	POP P,1
	JRST TC1B

;SECOND LEVEL - HANDLE DEVICE IDEOSYNCRACIES AND CHAR ACCOUNTING

TCOY:	CALL XLINK		; DO LINKS IF ANY
TCOY1:	CAIL 1,177
	JRST TCOUT		;RUBOUT
	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 FOR SPACING OF HDX TERM
		CAIGE 1,40	;IS CONTROL CHAR AND MODE 2?
		TRNN 3,3B33
		RET		;NO, NO ECHO
		JRST TTCO1]	;YES, ECHO CONTROL FN
	CAIGE 1,40
	JRST TTCO1		;CONTROL GROUP
	CAIL 1,140
	JRST TTCO2		;LOWER CASE GROUP
TTCO6:	CALL TTCAOS		;AOS THE POSITION, DO CRLF** IF NEEDED
	JRST TCOUT		;THEN OUTPUT THIS SPACING CHARACTER

;LOWER CASE GROUP

TTCO2:	MOVE 3,TTFLGS(2)	;DEVICE CHARACTERISTICS
	TLNE 3,(TTLCBT)		;HAS LOWER CASE?
	JRST TTCO6		;YES
	SUBI 1,40		;INDICATE LOWER CASE AND CONVERT
	TRNN 3,40		;INDICATE LC?
	JRST TTCO6		;NO.
	PUSH P,1
	MOVEI 1,TTLIND		;INDICATION CHARACTER
	CALL TCOUT
	AOS TTLPOS(2)
	POP P,1
	JRST TTCO6

; ACCOUNT SPACING PERFORMED BY HDX TERMINAL

TTCOHA:	PUSH P,3
	CAIL 1,40		; SPACING CHARACTER
	  CALL TTCAOS		; YES. COUNT POS, DO CRLF** IF NEEDED
				; EOL IS TREATED LIKE CR. SOMEWHERE 
				;  THERE SHOULD BE A LINEFEED GENERATED
				;  FOR LOCAL HDX TTY'S.
	CAIE 1,37		; EOL?
	CAIN 1,15		; CR
	 HLLZS TTLPOS(2)	; CLEAR HORIZ POSITION
	MOVSI 3,1
	CAIN 1,12
	 ADDM 3,TTLPOS(2)
	CAIN 1,14
	 HRRZS TTLPOS(2)
	CAIE 1,10		;BACKSPACE?
	JRST TCOHA1		;NO
	MOVE 3,TTLPOS(2)	;YES. WHERE ARE WE ON LINE?
	TRNE 3,-1		;AT LEFT MARGIN ALREADY?
	SOS TTLPOS(2)		;NO, COUNT BACK ONE TO THE LEFT
TCOHA1:	POP P,3
	RET

;SUBR TO COUNT HORIZ POS, ADD A CRLF** IF NEEDED.

TTCAOS:	AOS 3,TTLPOS(2)		;SPACING CHARACTER
	LDB 4,[POINT 7,TTFLGS(2),17] ;GET RIGHT MARGIN
	JUMPE 4,R		;0 MEANS NEVER FOLD
	CAIL 4,0(3)		;CHECK FOR OVERFLOW
	RET			;NO OVERFLOW. RETURN TO HANDLE CHAR.
	PUSH P,1		;LINE OVERFLOW, DO CR AND CONTINUATION
	MOVEI 1,15
	CALL TTSM5		;DO CR
	MOVEI 1,12
	CALL TTSM2		;DO LF
	MOVEI 1,2		;COUNT 2 *'S
	HRRM 1,TTLPOS(2)
	MOVEI 1,52
	CALL TCOUT
	CALL TCOUT
	POP P,1
	JRST TTCAOS		; NOW HANDLE THE ORIGINAL CHAR.

;CONTROL GROUP
;FOR EACH CHARACTER, ACTION IS CONTROLLED BY TWO BITS:
; 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

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)
	JRST @TTCTAB(1)		;DISPATCH TO FORMAT ROUTINE

;DISPATCH TABLE FOR FORMAT EFFECTING CONTROL CHARACTERS

NC=TCOUT	;DISPATCH FOR NON-FORMAT CONTROLS

TTCTAB:	NC	;@
	NC	;A
	NC	;B
	NC	;C
	NC	;D
	NC	;E
	NC	;F
	NC	;G

	TTSM4	;H - BACKSPACE
	TTSM1	;I - TAB
	TTSM2	;J - LINE FEED
	NC	;K
	TTSM3	;L - FORM
	TTSM5	;M - CARRIAGE RETURN
	NC	;N
	NC 	;O

	NC	;P
	NC	;Q
	NC	;R
	NC	;S
	NC	;T
	NC	;U
	NC	;V
	NC	;W

	NC	;X
	NC	;Y
	NC	;Z
	NC	;[ AND ALTMODE
	NC	;\
	NC	;]
	NC	;^
	TTSM6	;_, EOL

;TAB
;TAB STOPS ARE INDICATED BY BITS CORRESPONDING TO LINE POSITIONS
;THERE ARE 108 STOPS (3 WORDS)

TTSM1:	PUSH P,3
	MOVEI 7,1		;7 WILL CONTAIN SKIP DISTANCE ( >0 )
	HRRZ 3,TTLPOS(2)	;OLD POSITION
	ADDI 3,1		;MOVE AT LEAST ONE
	IDIVI 3,^D36		;36 TAB STOPS / WORD
TTSM11:	CAILE 3,2		;BEYOND END OF LINE?
	JRST TTSM15		;YES
	HRRZ 5,TTMOD1(2)	;TAB TABLE FOR THIS LINE
	ADDI 5,0(3)
	MOVE 5,0(5)		;GET BITS
	LSH 5,0(4)		;GET TO PRESENT POSITION
	JFFO 5,TTSM12		;FIND NEXT STOP
	ADDI 7,^D36		;NOT IN THIS WORD - UPDATE COUNT AND
	SUBI 7,0(4)
	MOVEI 4,0		;START AT BEGINNING OF NEXT WORD
	AOJA 3,TTSM11

TTSM12:	ADDI 7,0(6)		;ADD IN NUMBER SKIPPED, THIS WORD
TTSM15:	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,11		;SEND REAL TAB
	CALL TCOUT
	MOVE 4,7		;PLUS RUBOUTS TO KILL TIME
	IDIVI 4,4		;ASSUME FOUR SPACES PER RUBOUT
	HRRZ 3,TTYPE(2)		;GET TERMINAL TYPE INDEX
	LDB 1,TTTBPD		;PADDING FOR TAB ON THAT TYPE
	IMULI 4,(1)		;FOR EACH FOUR POSITIONS
	JUMPLE 4,TTSM14
	MOVEI 1,177
TTSM16:	CALL TCOUT
	SOJG 4,.-1
TTSM14:	ADDB 7,TTLPOS(2)	;UPDATE POSITION
	RET

TTSM13:	MOVEI 1,40		;SIMULATE WITH SPACES
	MOVEI 4,0(7)
	JRST TTSM16

;LINE FEED

TTSM2:	MOVSI 3,1		;INCREMENT PAGE POSITION
	ADDB 3,TTLPOS(2)
	HLRZS 3
	LDB 4,[POINT 7,TTFLGS(2),10]
	CAMG 4,3		; BEYOND PAGE?
	 PUSHJ P,TCOPZ		; POTENTIAL PAUSE
	CALL TCOUT
	HRRZ 3,TTYPE(2)
	LDB 5,TTLFPD		;LF PADDING
	MOVEI 1,177		;PAD WITH RUBOUTS
	JRST TTSM31

;FORM FEED

TTSM3:	HLRZ 4,TTLPOS(2)	;PRESENT PAGE POSITION
	PUSH P,4
	PUSH P,3
	PUSHJ P,TCOPZ		; DO PAUSE IF WANTED
	POP P,3
	POP P,4
	HRRZS TTLPOS(2)		;RESET
	PUSH P,3
	LDB 3,[POINT 7,TTFLGS(2),10] ;PAGE SIZE
	IDIVI 4,0(3)
	SUBM 3,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
	HRRZ 3,TTYPE(2)
	LDB 5,TTFFPD		;FF PADDING
TTSM33:	MOVEI 1,177		;PAD WITH RUBOUTS
	JRST TTSM31

TTSM32:	MOVEI 1,12		;SIMULATE WITH LINE FEEDS
TTSM31:	JUMPE 5,R
	CALL TCOUT
	SOJA 5,TTSM31

; PAUSE FOR DISPLAYS

TCOPZ:	JUMPL 6,R		; NEVER ON ECHOS
	PUSH P,1
	MOVE 1,TTYPE(2)		; GET TERMINAL TYPE
	MOVE 1,TTYPE0(1)
	TRNE 1,1B20		; DISPLAY?
	PUSHJ P,TTSIBE		; YES. INPUT BUFFER EMPTY
	 JRST POP1		; NO TO EITHER QUESTION. RETURN.
	MOVEI 1,7
	MOVEI 5,8
	PUSHJ P,TTSM31		; TYPE OUT SOME BELLS
	SETZ 3,
	PUSHJ P,TCI0		; INPUT A CHARACTER (BINARY MODE)
POP1::	POP P,1
	RET			; AND RETURN

;BACKSPACE

TTSM4:	HRRZ 4,TTLPOS(2)	;REDUCE LINE POSITION
	JUMPE 4,.+2		;IF NOT AT BEGINNING OF LINE
	SOS TTLPOS(2)
	TLNN 3,200000		;REAL OR SIMULATED
	JRST TCOUT
	MOVEI 1,15		;SIMULATE WITH CR AND SPACES (UGH)
	CALL TCOUT
	HRRZ 4,TTLPOS(2)
	MOVEI 1,40
	JUMPE 4,R
	CALL TCOUT
	SOJA 4,.-2

;CARRIAGE RETURN

TTSM5:	HRRZ 4,TTLPOS(2)	;SAVE OLD POSITION
	HLLZS TTLPOS(2)		;RESET LINE POSITION
	CALL TCOUT
	IFDEF IMPCHN,<
	CAIL 2,NVTLO
	CAILE 2,NVTHI
	 SKIPA
	  CALL NVTXCR>		; REMEMBER CR OUTPUT
	HRRZ 3,TTYPE(2)
	LDB 5,TTCRPD		;CR PADDING
	MOVE 1,TTYPE0(3)	;CHECK TO SEE IF NON-PROPORTIONAL
	TLNE 1,(1B3)		;PADDING FOR TI733
	JRST TTSM33		;YES. GO SEND RUBOUTS.
	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
	MOVEI 1,15		;NOW SEND CAR-RET'S
	JRST TTSM31		;PAD WITH MORE CR'S

;EOL

TTSM6:	MOVEI 1,15		;BECOMES CR, LF
	CALL TTSM5
	MOVEI 1,12
	JRST TTSM2

;OUTPUT ONE CHARACTER TO SPECIFIED TTY LINE
;CHARACTER IN 1, LINE NUMBER IN 2

TCOUT:	MOVEI 3,3B29		;MODE BITS
	CAIL 2,NVTLO
	JRST TCOUTX		;NO PARITY FOR NVT
	CAIGE 1,40		;CONTROL CHARACTER, AND
	TDNN 3,TTFLGS(2)	;NOT BINARY?
	JRST TCOUTX
	MOVEI 3,0(1)
	IMULI 3,200401		;COMPUTE PARITY FOR CONTROL CHAR
	AND 3,[11111111]
	IMUL 3,[11111111]
	TLNE 3,(1B14)		;(EVEN PARITY) BIT ON?
	TRO 1,200		;YES, PUT (EVEN PARITY) BIT ON
TCOUTX:
TCOB:				;BINARY OUTPUT ENTRY POINT
	IFDEF IMPCHN,<
	CAIL 2,NVTLO		; NVT?
	CAILE 2,NVTHI
	SKIPA
	 CALL NVTCHO		; YES. PERFORM SPECIAL PROCESSING
>
TCOBQ:	SKIPE IMECHF		;IMMED ECHO CHAR?
	JRST TCEOUT		;YES
	CALL TNTCHO		; CHECK IF TELENET
	 RET			; IT WAS AND CHAR SENT
	LDB 3,TTOMAX		;CAPACITY OF OUTPUT BUFFERS
	CAMG 3,TTOCT(2)		;FULL?
	JRST TCOUT1		;YES
TCEO3:	NOSKD1
	CHNOFF DLSCHN		;MUST PREVENT DEASSIGN OF BUFFERS
	SKIPN 3,TTOIN(2)	;BUFFERS EXIST?
	JRST [	CHNON DLSCHN
		LDB 3,TTNOU	;NO, GET NUMBER TO ASSIGN
		CALL TTGTBF	;ASSIGN THEM
		 JRST [	OKSKD1
			LDB 1,TTNOU
			MOVSS 1
			HRRI 1,TTBUFW
			JSYS EDISMS ; WAIT FOR BUFFERS
			JRST TCEO3]
		CHNOFF DLSCHN
		MOVEM 3,TTOOUT(2)
		JRST .+1]
	TDNN 3,WRPMSK		;END OF BUFFER?
	HRR 3,1-TTSIZ(3)	;YES, GET ADDRESS OF NEXT BUFFER
	IDPB 1,3
	MOVEM 3,TTOIN(2)
	AOS TTOCT(2)
	CHNON DLSCHN		;SAFE TO TURN CHN ON AFTER AOS
	OKSKD1
	AOS NTTYOT		;COUNT ALL OUTPUT
TCEO1:
IFDEF IMPCHN,<
	CAIL 2,NVTLO		;NVT?
	CAILE 2,NVTHI
	 JRST TCEON
	CALL NTTCSO		;YES, DO OUTPUT IF POSSIBLE
	JRST TCEO4
TCEON:>
	SKIPGE TTFLGS(2)	;TEST OUTPUT ACTIVE
	JRST .+3
	MOVEM 2,TTNIT1		;SIMULATE INTERRUPT THIS LINE
	ISB DLSCHN
TCEO4:	POP P,3
	JRSTF 0(3)		;RESTORE FLAGS

;SCAN LINK WORD, SENDING CHAR TO LINES SPECIFIED BY NON-777 BYTES

XLINK:	SETCM 3,TTLINK(2)
	TDCN 3,[-1]
	 RET
TTLNK3:	PUSH P,2		;SAVE CURRENT LINE NUMBER
	SKIPE IMECHF
	SETOM 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
	MOVE 3,TTFLGS(2)	;DEST LINE MODES
	TRNE 3,3B29		;ASCII? (NOT BINARY)
	CALL TCOY1		;YES, SEND ON LINK
	POP P,1
	POP P,3
TTLNK1:	JUMPN 3,TTLNK2		;DO MORE IF ANY
	SETZM LINKF
	POP P,2			;RESTORE ORIG LINE NUMBER
	RET

;ACTION WHEN BUFFER FULL

TCOUT1:	PUSH P,1		;SAVE CHARACTER
	MOVEI 1,TCOTST		;SETUP SCHEDULER TEST WORD
	HRLI 1,0(2)		;  LINE NO,,TEST ROUTINE ADR
	JSYS EDISMS
	POP P,1
	JRST TCOUTX

;CALLED FROM SCHEDULER TO TEST FOR RUNNABLE

TCOTST:	MOVEI 2,0(1)		;LINE NUMBER TO REGULAR AC
	LDB 1,TTOMAX		;GET MAXIMUM POSSIBLE CHARS IN BUFFERS
	SKIPE FKINT(7)		;BUT IF INTERRUPT WAITING,
	 JRST TCOTS2		;DONT BOTHER TESTING FOR NVT
	CAIL 2,NVTLO		;IGNORE WARNING THRESHOLD FOR NVT
	CAILE 2,NVTHI
	 LDB 1,TTOWRN		;NOT NVT
TCOTS2:	CAMG 1,TTOCT(2)		;AT OR BELOW WAKEUP LEVEL?
	JRST 0(4)		;NO
	JRST 1(4)		;YES

; WAIT FOR N BUFFERS

TTBUFW:	CAMLE 1,TTFREC
	 JRST 0(4)
	JRST 1(4)

;ROUTINE TO GET CHARACTER FROM TELETYPE
;CONVERT FROM ASCII TO INTERNAL AND GENERATE ECHOS
;AS REQUESTED

TCI:	MOVEI 3,1B34		;BKJFN DONE ON THIS TTY?
	TDNE 3,TTFLGS(2)	;REPEAT LAST CHAR?
	JRST TCIRC		;YES
	LDB 3,[POINT 2,TTFLGS(2),29] ;DATA MODE BITS
	CALL TCI0		;GET A CHAR
IFDEF IMPCHN,<
	CAIN 1,777		; SPECIAL MARK?
	 JRST [	CALL NVTXGA##	; YES, TREAT LIKE WAKEUP
		SOS TTMCT(2)
		JRST TCI]	; AND START OVER
>
	MOVE 3,TTFLGS(2)
	TRNN 3,3B29		;BINARY?
	JRST [	ANDI 1,377	;YES
		JRST TCIR]
	PUSH P,1		;CHECK FOR DEFERRED TERM INT CHAR
	ANDI 1,177
	CAIGE 1,PSICHL		;WITHIN RANGE?
	JRST TCI3		;YES
	CAIGE 1,PSICHU
	JRST TCI2		;NO
	SUBI 1,PSICHO
TCI3:	MOVE 3,PSICH(1)		;GET CODE
	CAIN 3,NU
	JRST TCI2		;NOT DEFINED
	MOVE 1,BITS(3)
	TDNN 1,TTPSI(2)		;THIS CODE ENABLED?
	JRST TCI2		;NO
	IFDEF IMPCHN,<CALL NVTXWK##>	; TREAT AS WAKEUP FOR NVT
	MOVEM 2,0(P)		;YES, SAVE LINE NUMBER
	NOSKED
	CALL TTPSRQ		;INITIATE INTERRUPT
	OKSKED
	SKIPE FKINT(2)		;HAS BEEN PROCESSED YET?
	JSYS BLOCK1		;NO, WAIT A WHILE
	POP P,2
	JRST TCI		;GET ANOTHER CHAR, DON'T RETURN INT CHR

TCI2:	POP P,1
	MOVE 3,TTFLGS(2)
	TLNE 3,(TTLCBT)		;NO LOWER CASE ON THIS TERMINAL?
	TRNE 3,1B31		;OR 'RAISE' REQUESTED?
	CALL TTRAIS		;YES, DO IT
	ANDI 3,3B25		;ISOLATE ECHO MODE BITS
	JUMPE 3,TCIN		;NO ECHO
	TRNE 1,400		;HAS CHAR BEEN ECHOED?
	 JRST TCIN		; YES.
	IFDEF IMPCHN,<
	CALL NVTRCC		; WHAT HAS RCTE DONE TO US
	 JRST [	CALL XLINK	; DO ANY LINKED ECHOES
		JRST TCIN]
>
	CAIN 3,3B25		; SUPPRESS BREAK ECHO?
	CALL WAKCHK		; AND A WAKEUP CHAR
TCIY:	CALL TCOE		;N, DO ECHO
TCIN:	IFDEF IMPCHN,<CALL NVTXWK>	; CHECK WAKEUP IF MIGHT BE NVT
	ANDI 1,177
TCIR:	DPB 1,TTYLCH		;SAVE LAST CHAR
	RET

;ENTRY FOR BINARY INPUT

TCIB:	MOVEI 3,1B34
	TDNE 3,TTFLGS(2)	;REPEAT LAST CHAR?
	JRST TCIRC		;YES
	SETZ 3,			;USE DATA MODE 0
	CALL TCI0		;GET A CHAR
	JRST TCIR		;RETURN IT UNMODIFIED AND UNECHOED

TCIRC:	ANDCAM 3,TTFLGS(2)	;CLEAR BIT
	LDB 1,TTYLCH		;GET LAST CHARACTER
	RET

;GET ONE CHARACTER FROM INPUT BUFFER, ACCORDING TO DATA MODE IN 3

TCI0:	MOVE 1,TTYPE(2)		; GET TERMINAL TYPE
	MOVE 1,TTYPE0(1)
	TRNE 1,1B20		; SCOPE?
	 HRRZS TTLPOS(2)	; YES, CLEAR LINE COUNTER
	NOSKED
	SKIPG 1,TTICT(2)		;ANY CHARS IN BUFFER?
	JRST TCI1		;NO
	SKIPN 3,TTIOUT(2)	;GET POINTER
	BUG(HLT,<TCI - NO BUFFER POINTER BUT COUNT NON-0>)
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(3)	;NEW BUFFER
	ILDB 1,3
	MOVEM 3,TTIOUT(2)
	SOSG TTICT(2)		;REDUCE COUNT, NOW EMPTY?
	JRST [	SETZB 3,TTIOUT(2) ;YES, RELEASE BUFFERS
		EXCH 3,TTIIN(2)
		CALL TTRLBF
		JRST .+1]
	OKSKED
	RET

;ACTION IF BUFFER IS EMPTY

TCI1:	OKSKED
	HRL 3,TTFORK(2)		;CHECK FOR OTHER FORK WAITING THIS LINE
	JUMPGE 3,TCIF1		;YES
TCIF2:	DPB 3,TTYLMD		;SAVE DATA MODE THIS INPUT
	PUSH P,3
	MOVE 3,FORKX		;GET INDEX OF THIS FORK
	HRRM 3,TTFORK(2)	;RECORD THIS FORK WAITING FOR TTY
	CALL TNTGA		; PERFORM TELENET SPECIFIC ACTIONS
	 JFCL
IFDEF IMPCHN,<
	CAIL 2,NVTLO		;NETWORK TTY?
	CAILE 2,NVTHI
	SKIPA
	CALL NETCAP		;YES, CHECK ALLOCATE
>
	MOVEI 1,TCITST		;SETUP SCHEDULER TEST WORD
	HRLI 1,0(2)		;  LINE NO,,TEST ROUTINE ADR
	SKIPN TTICT(2)		;STILL EMPTY?
	JRST [	CAMN 2,CTRLTT	;WANT INPUT FROM CONTROLLING TTY?
		HRLI 1,-1	;YES. FLAG IT WITH -1
		JSYS EDISMS	;WAIT FOR INPUT TO BE READY
		SKIPGE 1	;CONTROLLER?
		MOVE 2,CTRLTT	;YES, MAKE SURE NOT DETACHED
		JUMPL B,.	;GOT DETACHED IN THE DISMISS
		JRST .+1]	;OK. BUFFER SHOULD HAVE SOME STUFF
	POP P,3			;RESTORE CURRENT MODE
	JRST TCI0		;TRY AGAIN

TCIF1:	PUSH P,2
	PUSH P,3
	HRRZ 1,TTFORK(2)	;INDEX OF WAITING FORK
	ANDI 1,7777
	CAME 1,FORKX		;SELF?
	CALL TTFRKT		;NO, GO RESOLVE CONFLICT BY HALTING FORK
	POP P,3
	POP P,2
	JRST TCIF2

;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:	CAIE 1,-1		;WAIT FOR CONTROLLING TTY?
	JRST TCITS2		;NO
	HLRZ 1,FKJOB(7)		;YES. FIND ITS NUMBER
	HLRE 1,JOBPT(1)		; ..
	JUMPL 1,0(4)		;IF DETACHED, KEEP WAITING
TCITS2:	HRRZ 2,TTFORK(1)
	TRNE 2,1B18+1B19	;WAKEUP OR BUFFER FULL?
	JRST 1(4)		;YES
	JRST 0(4)		;NO, DON'T WAKE

;'RAISE' INPUT

TTRAIS:	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

;TELETYPE MISC SERVICE CHANNEL 7 ROUTINE
;RUN EVERY SO OFTEN TO MOVE CHARACTERS FROM BIG BUFFER TO LINE BUFFERS,
;GENERATE ECHOS AND HANDLE CARRIER TRANSITIONS
;ENTERED BY ECALL  FROM SCHED, IN CLK2 BKGND STUFF

DLSCHK:	MOVEI 1,^D500		;RATE AT WHICH THIS CODE GETS RUN
	MOVEM 1,DLSTIM		; THIS MANY MS LATER
IFN NDLS,<
	CONI DLS,1		;CHECK FOR LOST PI
	ANDI 1,7
	CAIN 1,DLSCHN		;CORRECTLY SET?
	JRST .+3		;YES
	AOS DLSLPI		;NO, COUNT LOSSAGES
	CONO DLS,DLSCHN		;AND RESET IT
IFDEF BBNDLS,<			; KLUDGE FOR 113 DATASETS AT BBN
	MOVE 1,TODCLK		; TIME TO CHECK A LINE?
	CAMG 1,TTHNT2		; ..
	JRST TTHNG9		; NO.
	ADDI 1,^D15000		; YES. SET NEXT CHECK AT 15 SECONDS
	MOVEM 1,TTHNT2		;  FROM NOW
	AOS 2,TTHNL2		; NEXT LINE TO CHECK FOR HUNG
	CAIL 2,NTTYS		; ONLY ON SCANNER
	SETZB 2,TTHNL2		; WRAP AROUND LINES
	MOVE 3,TTFLGS(2)	; CHECK CARRIER ON FLAG
	HLL 3,TTMOD1(2)		; AND NON-STANDARD MODEM (DIALLER)
	MOVEI 1,TTHU0		; ROUTINE TO CALL IF BAD
	TDNN 3,[NSMODM!1]	; CARRIER NOW ON, OR SPECIAL LINE?
	SKIPE TTCS(2)		; NO. IN TRANSITION?
	SKIPA			; CARRIER ON OR IN TRANSITION
	CALL TTQAD		; NO, IT'S IDLE. CLEAR IT OUT.
TTHNG9:>
IFDEF DIALLN,<			;CHECK FOR AUTODIALLER CODE
	CALL DILCHK>		; ..
	SKIPN 1,TTHNGT		;ACTIVE LINE TO BE CHECKED?
	JRST TTHNG1		;NO
	MOVE 2,TTHNGL		;YES, GET LINE NUMBER
	CAML 1,TODCLK		;INTERRUPT OVERDUE?
	JRST TTHNG4		;NO, KEEP WAITING
	AOS TTHNGN		;YES, COUNT UNHANGS
	HRLM 2,TTHNGN		;REMEMBER LAST HUNG LINE
	MOVEM 2,TTNIT1		;SIMULATE OUTPUT INTERRUPT
	ISB DLSCHN
TTHNG1:	AOS 2,TTHNGL		;GET NEXT LINE
	CAIL 2,NTTYS
	SETZB 2,TTHNGL		;WRAPAROUND LINE NUMBERS
	MOVE 1,TODCLK
	ADDI 1,^D500		;HALF-SECOND FROM NOW
	MOVEM 1,TTHNGT		;IS TIME AT WHICH LINE IS CALLED HUNG
	SKIPL TTFLGS(2)		;LINE NOW ACTIVE?
	SETZM TTHNGT		;NO, DON'T CHECK
>; END OF TEST ON NDLS
;FALL THRU

TTHNG4:
IFN NDLS,<
	MOVE 2,TTCQLN		;BEFORE LEAVING, CHECK CONTROL ON
	MOVEI 4,10		;A FEW LINES
TTCQ3:	SKIPN 1,TTCS(2)		;ANYTHING ON THIS LINE?
	JRST TTCQ2		;NO
	HRRZ 3,TODCLK		;SEE IF NOW TIME TO DO IT
	ANDI 3,377777
	HLRZ 1,1
	SUB 1,3			;DESIRED TIME MINUS NOW
TTCQ1:	JUMPLE 1,TTCQ4		;0 OR NEGATIVE TIME LEFT TO WAIT
	CAIGE 1,200000		;GREATER THAN MAX POSSIBLE?
	JRST TTCQ2		;NO, KEEP WAITING
	SUBI 1,400000		;ACCOUNT FOR WRAPAROUND
	JRST TTCQ1		;CHECK AGAIN

TTCQ4:	HRRZ 1,TTCS(2)		;GET ADDRESS OF FUNCTION TO DO
	SETZM TTCS(2)		;CLEAR CONTROL STATE
	CALL 0(1)		;DO THE FUNCTION
TTCQ2:	ADDI 2,1		;GO TO NEXT LINE
	CAIL 2,NLINES		;WRAPAROUND
	SETZ 2,
	SOJG 4,TTCQ3		;DONE ENOUGH FOR THIS TIME?
	MOVEM 2,TTCQLN		;YES, START AT THIS LINE NEXT TIME
>; END TEST ON NDLS
	RET

;ADD ITEM TO CONTROL QUEUE

TTQAD1:	HRLI 1,^D3000		;ITEM TO BE DONE IN 3 SEC.
TTQAD:	HRLZ 3,TODCLK		;WAIT TIME IN LH OF 1
	TLZ 3,400000		;ROUTINE ADDRESS IN RH OF 1
	ADD 1,3			;COMPUTE TIME TO DO FUNCTION
	MOVEM 1,TTCS(2)
	RET

TTCH7:	SKIPG TTBIGC		;BIG BUFFER EMPTY?
	  RET			;YES, RETURN.
	AOS 3,TTBIGO		;NO, GET WORD
	CAIN 3,TTBSIZ		;WRAPAROUND IF NECESSARY
	 SETZB 3,TTBIGO
	MOVE 1,TTBBUF(3)
	SOS TTBIGC
	HLRZ 2,1		;GET LINE NUMBER
	CAIL 2,NLINES		;LEGITIMATE LINE NUMBER?
	JRST TTCH7		;NO. IGNORE THIS ONE.
	MOVEI 6,0(1)		;SAVE ALL ORIGINAL FLAGS
IFN NDLS,<
	TRNE 1,DLSCXF		;CARRIER TRANSITION?
	 JRST TT7CX		;YES
>
	TRNN 1,DLSRCF		;RECEIVER?
	 JRST TTCH7		;NO (SHOULD NOT HAPPEN) - RESUME  SCAN
	ANDI 1,377
	CALL TTCHI		; PUT THE CHARACTER WHERE IT BELONGS
	JRST TTCH7		; AND SEE IF ANY MORE TO DO
IFN NDLS,<

;CARRIER ON/OFF

TT7CX:	MOVEI 3,1		;CARRIER STATE FLAG
	TRNN 1,CARONB		;CARRIER NOW ON?
	 JRST TTCX1		;NO, OFF
	SKIPGE TTFORK(2)	;TTY ASSIGNED OR
	TDNE 3,TTFLGS(2)	;CARRIER NOT OFF BEFORE?
	  JRST [IORM 3,TTFLGS(2);YES. UPDATE FLAGS ANYHOW
		JRST TTCH7]	;AND IGNORE
	IORM 3,TTFLGS(2)	;UPDATE SOFTWARE FLAG
	MOVSI 1,(NSMODM)	;NON-STANDARD MODEM?
	TDNE 1,TTMOD1(2)
	JRST TTCH7		;YES. IGNORE. CHANGE OF FLAG IS ALL.
	MOVEI 1,TTCON		;QUEUE A CHECK TO GO IN 1 SEC.
	CALL TTQAD1
	JRST TTCH7

TTCON:	MOVEI 3,1
	TDNN 3,TTFLGS(2)	;CARRIER STILL ON?
	 RET			;NO, IGNORE IT
TNTCON::SKIPL 3,TTFORK(2)	;JOB ACTIVE HERE?
	 JRST TTCH7F		;YES, SEND BELL, OTHERWISE IGNORE
	JRST TTC7SJ		;NO, START JOB

TTCX1:	TDNN 3,TTFLGS(2)	;WAS ON BEFORE?
	 JRST TTCH7		;NO, SPURIOUS INTERRUPT
	ANDCAM 3,TTFLGS(2)	;UPDATE SOFTWARE FLAG
	MOVSI 1,(NSMODM)	;NON-STANDARD MODEM?
	TDNE 1,TTMOD1(2)	; ..
	JRST TTCH7		;YES. CHANGE OF FLAG IS ALL.
	MOVEI 1,TTCOF		;QUEUE A CHECK FOR 1 SEC.
	CALL TTQAD1
	JRST TTCH7

TTCOF:	MOVEI 3,1
	TDNE 3,TTFLGS(2)	;CARRIER STILL OFF?
	 RET			;NO, IGNORE
	MOVEI 1,TTHU0		;YES, QUEUE A HANGUP-REACTIVATE SEQUENCE
	CALL TTQAD		;TO START IMMEDIATELY
	SKIPGE TTFORK(2)	;JOB ATTACHED?
	 RET		;NO, IGNORE
>; END OF COND ON NDLS
; BUT FALLS THRU IF DLS EXISTS
TNTCOF::
NVTCOF:	MOVEI 3,^D30		;YES, INITIATE A CODE 30 INTERRUPT
	MOVE 5,TTPSI(2)
	TDNE 5,BITS(3)		;IF ITS ASSIGNED
	JRST TTPSI2
	RET			;OTHERWISE IGNORE

;HANGUP-REACTIVATE SEQUENCE

TTHU0:
IFN NDLS,<
	MOVEI 1,TTHU0		;MAYBE SAME ROUTINE AGAIN
	SKIPGE TTFLGS(2)	;OUTPUT NOT ACTIVE?
	JRST TTQAD1		;NO, RE-QUEUE THIS ROUTINE FOR 1 SEC.
IFDEF BBNDLS,<
	MOVSI 3,DLSDLB(2)	;CONSTRUCT DATAO WORD
	HRRI 3,1B27		;DIRECTED LINE+NO XMIT BITS
>
IFDEF DECDLS,<
	CALL TTECNV		;GET DC10E LINE IF ANY
	HRRI 3,0		;CLEAR DATA TERMINAL READY
	JUMPL 3,.+2>		;SKIP IF NONE
	DATAO DLS,3
	MOVE 1,[XWD ^D100,TTHU1] ;QUEUE NEXT OP TO GO IN 100 MS.
	JRST TTQAD
>; END TEST ON NDLS
IFE NDLS,<
	RET>

TTHU1:
IFN NDLS,< IFDEF BBNDLS,<
	MOVSI 3,DLSDLB(2)	;CONSTRUCT DATAO WORD TO REACTIVATE
	HRRI 3,DLSACT+1B27	;DIRECTED LINE+ACTIVATE+NO XMIT
>
IFDEF DECDLS,<
	CALL TTECNV		;GET CORRESPONDING DC10E LINE
	HRRI 3,1B29		;SET DATA TERMINAL READY
	JUMPL 3,.+2>		;SKIP IF NO DATASET CONTROL
	DATAO DLS,3
>; END TEST ON NDLS
	RET

TTHU2:
IFN NDLS,< IFDEF BBNDLS,<
	MOVSI 3,DLSDLB(2)	;WORD TO HANG UP MODEM
	HRRI 3,1B27		; ..
>
IFDEF DECDLS,<
	CALL TTECNV		;GET CORRESPONDING DC10E LINE
	HRRI 3,0		;CLEAR DATA TERMINAL READY
	JUMPL 3,.+2>		;SKIP IF NO CONTROLLER FOR DATASET
	DATAO DLS,3
>; END TEST ON NDLS
	RET

; STORE CHARACTER IN TTY INPUT BUFFER
; 1/	CHARACTER
; 2/	LINE NUMBER
; 6/	FLAGS

TTCHI:	AOS NTTYIN		;COUNT ALL INPUT
	SKIPL 3,TTADVS(2)	;ADVISE TO ANOTHER LINE?
	CALL TTAVS		;YES. GO DO IT.
	SKIPGE 3,TTFORK(2)	;ASSIGNED TO A JOB?
	JRST TTC7N		;NO
	MOVEI 4,0(1)		;CHECK FOR INTERRUPT CHAR
	ANDI 4,177		;JUST SEVEN BITS OF IT
	CAIGE 4,PSICHL		;TRANSLATE TO INTERRUPT CODE
	JRST TTCH71
	CAIGE 4,PSICHU
	JRST TTCH72		;NOT INTERRUPT CHAR
	SUBI 4,PSICHO
TTCH71:	MOVE 3,PSICH(4)
	CAIN 3,NU		;NOT USED?
	JRST TTCH72		;YES
	MOVE 5,BITS(3)		;BIT FOR THIS CODE
	TDNE 5,TTPSI(2)		;CODE ENABLED?
	JRST TTPSI1		;YES, GO INITIATE INTERRUPT

;DETERMINE ECHO STATUS

TTCH72:	LDB 3,TTYLMD		;CHECK MODE NOW IN FORCE
	JUMPE 3,[LDB 3,TTIMAX	;BINARY, SKIP ECHO TESTS
		CAMG 3,TTICT(2)	;ROOM FOR CHAR IN INPUT BUFFER?
		RET		;NO, QUIETLY FLUSH IT
		JRST TTRNE]	;YES, GO PUT IT IN
	ANDI 1,177		;ONLY 7-BIT ASCII FROM HERE ON
	LDB 3,TTIMAX		;CAPACITY OF INPUT BUFFERS
	CAMG 3,TTICT(2)		;FULL?
	JRST TTCH7F		;YES, ECHO BELL
	MOVE 3,TTFLGS(2)
	CAIN 1,15		;CR?
	MOVEI 1,EOL		;END OF LINE CHARACTER
	TRNE 3,3B33		;REGULAR FDX LINE?
	JRST TTREC4		;HDX - 'ECHO' IMMED
	ANDI 3,3B25
	JUMPE 3,TTRNE		; NO ECHOES WANTED
	CAIN 3,1B25		; IMMEDIATE ECHOES?
	 JRST TTREC4		; YES.
	HRLZ 4,TTFORK(2)	;MAYBE, GET STATUS OF FORK WAITING
	JUMPL 4,TTRNE		;DEFER IF NO FORK WAITING
	CAIN 3,3B25		; SUPPRESS BREAK ECHOES?
	CALL WAKCHK	; YES. CHECK IF WAKEUP CHARACTER
	 JRST TTREC4		; NOT, DO ECHO
	JRST TTRNE

TTREC4:	IFDEF IMPCHN,<
	CALL NVTRCC		; WHAT HAS RCTE DONE TO US?
	 JRST [	CALL XLINK
		JRST TTRNE]
>
	MOVE 3,TTFLGS(2)
	TLNE 3,(TTLCBT)		;WILL ECHO NOW.  MUST RAISE INPUT?
	TRNE 3,1B31
	CALL TTRAIS		;YES, DO IT
	TRO 1,400		;BIT TO DISABLE DEFERRED ECHO THIS CHAR
	PUSH P,6
	NOSKD1
	SETOM IMECHF		; SAY THIS AN IMMEDIATE ECHO
	CALL TCOE		;ECHO VIA NORMAL OUTPUT STREAM
	SETZM IMECHF
	OKSKD1
	POP P,6

;PUT CHAR IN BUFFER AND CHECK FOR WAKEUP

TTRNE:	CALL TTSTCH		; STORE CHARACTER IN BUFFER
	 JRST TTCH7F		; NO ROOM
	HRLZ 3,TTFORK(2)	;IF NO FORK WAITING FOR THIS LINE,
	JUMPL 3,R		;THEN SKIP WAKEUP CHECKS
	TRNE 6,TTSCF		;CHAR CAME FROM STI?
	JRST TTWKT2		;YES, ALWAYS WAKEUP
	LDB 3,TTYLMD		;CHECK MODE
	JUMPE 3,TTWKT2		;WAKE ALWAYS IF BINARY
	LDB 3,TTIMAX		;CAPACITY OF INPUT BUFFERING
	SUBI 3,40		;LESS AN ARBITRARY AMOUNT
	CAMG 3,TTICT(2)		;BUFFER NOW THAT FULL?
	JRST [	MOVEI 3,1B19	;YES, ALLOW PGM WAKEUP
		IORM 3,TTFORK(2)
		JRST .+1]
	CALL WAKCHK		; IS THIS A WAKEUP?
	 RET			; NO
TTWKT2:	HLLOS TTFORK(2)		;INDICATE WAKEUP
	AOS ISKED
	RET			; DONE

TTSTCH:	SKIPN 3,TTIIN(2)	;INPUT BUFFERS EXIST?
	JRST [	LDB 3,TTNIN	;NO, GET NUMBER TO ASSIGN
		CALL TTGTBF	;ASSIGN THEM
		 RET		; NO BUFFERS, RETURN NOSKIP
		MOVEM 3,TTIOUT(2)
		JRST .+1]
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(3)
	IDPB 1,3
	MOVEM 3,TTIIN(2)
	AOS TTICT(2)
	JRST RSKP

WAKCHK::MOVEI 3,0(1)
	ANDI 3,177
	IDIVI 3,6
	ADDI 3,TTWKTB
	HLL 3,CH6TAB(4)
	LDB 4,3			;GET FLAGS THIS CHAR
	LDB 3,[POINT 6,TTFLGS(2),23] ;GET FLAGS THIS FORK
	TDNE 3,4		;ANY THE SAME?
	 AOS 0(P)		; YES, SKIP
	RET

TTYGPI::PUSH P,ZERO		; ACCUMULATE COC TYPE WORDS HERE
	PUSH P,ZERO
	PUSH P,2		; NEED THIS ACCUMULATOR
	MOVE 1,TTPSI(2)		; GET PSI BITS
	ANDCMI 1,77		; MASK OUT EXTRANEOUS BITS
	TRZE 1,100		; IS SPACE AN INTERRUPT?
	 TRO 1,10		; YES, SET BIT 40(8)
	TRZE 1,20		; RUBOUT?
	 TRO 1,4		; SET BIT 41(8)
	LSH 1,-1		; AVOID SIGN BIT
TTGPI1:	MOVN 2,1		; COMPLEMENT ALL BUT RIGHTMOST 1
	AND 2,1			; GET JUST THAT BIT
	ANDCAM 2,1		; CLEAR IT
	MUL 2,2			; SQUARE IT
	LSH 3,1			; FILL THE GAP
	IORB 3,-1(P)
	IORB 2,-2(P)
	JUMPN 1,TTGPI1		; LOOP TILL ALL ARE DONE
	LSHC 2,1
	IOR 2,-2(P)
	IOR 3,-1(P)
	LSHC 2,1
	MOVE 1,2
	POP P,2
	SUB P,BHC+2
	RET

TTCH7F:	MOVEI 1,207		;INPUT BUFFER FULL,
	CAIL 2,NVTLO		;IF NETWORK TERMINAL,
	MOVEI 1,007		;ONLY 7 BITS OF CHARACTER
	CALL TCEO2		;ECHO BELL
	RET			; DONE
; TYPE MESSAGE VIA ECHO BUFFER
TTC7SM:
	MOVE 3,1		;MOVE STRING ADDRESS
	HRLI 3,440700		;MAKE IT A BYTE POINTER
TTC7SN:
	ILDB	1,3		;GET A BYTE
	JUMPE 1,R		;DONE IF NULL
	PUSH P,3
	PUSHJ P,TCEO2
	POP P,3
	JRST TTC7SN		;DO THEM ALL

;RECEIVED CHARACTER ON UNASSIGNED LINE

TTC7N:	ANDI 1,177
	CAIE 1,003		;CONTROL-C?
	JRST TTCH7F		;NO, SEND BELL
TTC7SJ:	CAIE 2,CTYLIN		;CTY AND OTY IF CHECKDSK FINISHED
	CAMN 2,OTYLIN
	JRST [	SKIPE SYSIFG	;CHKDSK AND SYS INI FINISHED?
		JRST TTC7SK	;CHECKDSK IS FINISHED
		MOVEI	1,[ASCIZ /DISK VERIFY IN PROGRESS
/]
		JRST TTC7SM]	;GO TELL HIM THE NEWS
	MOVE 1,[CHKDSE]		;ANY CHECKDSK ERRORS ?
	TDNE 1,FACTSW
	JRST	[MOVEI 1,[ASCIZ /FILESYSTEM WORK IN PROGRESS
/]
		JRST TTC7SM]	;GO BREAK IT TO HIM
	SKIPL AUTONX		;AUTO JOBS ALL STARTED ?
	JRST [MOVEI 1,[ASCIZ /TENEX RESTARTING, WAIT...
/]
		JRST TTC7SM]
	SKIPN ENTFLG		;  AND SYSTEM PERMITTING ENTRIES ?
	JRST	[MOVEI 1,[ASCIZ /TENEX NOT AVAILABLE
/]
		JRST	TTC7SM]	;TELL HIM(HER?)

IFNDEF RTICLK,<		;NO NEED TO CHECK IF H'WARE TIME AVAIL.
	SKIPL TADSEC##		;IS TIME ALREADY SET?
	 JRST TTC7SK		;YES. LET THIS JOB FLY.
	MOVE 1,TODCLK		;NUMBER OF MS WE HAVE BEEN UP.
	CAMG 1,[^D<15*60*1000>]	;ALLOW 15 MIN. FOR OPERATOR OR SETTIM
	SKIPN DBUGSW##		;IF SYSTEM IS ATTENDED
	CAIA
	 JRST [	MOVEI 1,[ASCIZ /WAITING FOR TIME TO BE SET...
/]
		JRST TTC7SM]
	>

TTC7SK:	TLNN 3,1		;REALLY UNASSIGNED?
	JRST TTCH7F		;NO, IGNORE
	MOVSI 1,-2		;YES, SET TO JOB STARTING STATE
	HLLM 1,TTFORK(2)
	CALL TTCIBF
	PUSH P,2		;SAVE LINE NUMBER
	MOVE 1,2		;COMPUTE BIT FOR DATASET HANGUP
	IDIVI 1,^D36		; ..
	MOVE 2,BITS(2)		; ..
	ANDCAM 2,TTHUR(1)	;CLEAR THE TWO STATE BITS FOR HANGUP
	ANDCAM 2,TTHUS(1)	; ..
	POP P,2			;RESTORE LINE NUMBER
	MOVEI 1,JOBSRT		;REQUEST SCHEDULER- START JOB
	HRLI 1,0(2)		;ON SPECIFIED TTY LINE
	CALL SCDRQ7
	RET

;RECEIVED TERMINAL PSI CHARACTER

TTPSI1:	ANDI 1,177		;JUST 7 BITS
	LDB 4,TTIIN(2)		;GET LAST INPUT CHAR
	TDNN 5,TTDPSI(2)	;NOT DEFERRED CHAR?
	JRST TTPSI2		;YES, INTERRUPT IMMED
	CAIN 4,0(1)		;DEFERRED. SAME AS LAST CH TYPED?
	JRST TTPSI3		;YES. TREAT AS IMMED INT, CLR INPUT BFR
	HLLOS TTFORK(2)		;WAKE UP PGM SO IT CAN SEE INT
	AOS ISKED
	LDB 3,TTIMAX		;MUST PUT DEFERRED CHAR IN BUFFER
	ADDI 3,1		;1 RESERVED FOR INT CHAR
	CAMG 3,TTICT(2)		;IS ROOM?
	JRST [	IFDEF IMPCHN,<
		PUSH P,1	; SAVE CH
		LDB 1,TTIIN(2)	; GET CH BEING SMASHED
		CALL NVTXWK	; TAKE ANY ACTION NEEDED IF WAKEUP
		POP P,1		; GET CH BACK
		>
		DPB 1,TTIIN(2)	;NO, SMASH CHAR ON TOP OF LAST ONE
		RET]
	JRST TTRNE		;PUT IN BUFFER W NO ECHOS

TTPSI3:	PUSH P,3		;PRESERVE THE INTERRUPT CODE
	CALL TTCIBF		;CLEAR THE INPUT BUFFER
	POP P,3			;RESTORE INTERRUPT CODE
TTPSI2:	IFDEF IMPCHN,<
	PUSH P,3
	HRLZ 4,TTFORK(2)	; ANY FORK WAITING?
	JUMPL 4,[
		CALL NVTXGA	; IMMEDIATE, SEND BREAK RESET NOW
		JRST TTPS2D]
	MOVEI 1,777
	CALL TTSTCH		; PUT MARK TO SEND DEFERRED BREAK RESET
	 JFCL
	AOS TTMCT(2)
TTPS2D:	POP P,3>
	CALL TTPSRQ		;REQUEST INTERRUPT FROM PSI SYSTEM
	AOS TTINTS		;COUNT INTERRUPTS
	RET

;ROUTINE TO PUT CHAR IN ECHO BUFFER - CALLED FROM TCO

TCEOUT:	CALL TNTCHE		; CHECK IF TELENET
	 RET			; IT WAS AND CHARACTER SENT
	LDB 3,TTOMAX		;OUTPUT BUFFER CAPACITY
	ADDI 3,2		;PLUS RESERVE FOR ECHO
	CAMLE 3,TTOCT(2)	;OUTPUT BUFFER FULL?
	JRST TCEO3		;NO, GO PUT IN OUTPUT BUFFER

TCEO2:	CALL TNTCHE		; DO TELENET ECHO OUTPUT
	 RET			; IT WAS TELENET SO ALL DONE
	MOVE 3,TTECT(2)		;BUFFER FULL?
	CAIL 3,<TTSIZ-1>*4
	RET			;YES - IGNORE CHARACTER
	NOSKD1
	CHNOFF DLSCHN
	SKIPN 3,TTEIN(2)	;BUFFERS EXIST?
	JRST [	CHNON DLSCHN
		MOVEI 3,1	;NO, ASSIGN 1
		CALL TTGTBF
		 JRST [	OKSKD1
			RET]
		CHNOFF DLSCHN
		MOVEM 3,TTEOUT(2)
		JRST .+1]
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(3)
	IDPB 1,3
	MOVEM 3,TTEIN(2)
	AOS TTECT(2)
	CHNON DLSCHN
	OKSKD1
	JRST TCEO1

;TYPE (SHORT) MESSAGE VIA ECHO BUFFER

TTEMES:	PUSH P,1		;GIVEN BYTE POINTER TO STRING IN 1
TTEM1:	ILDB 1,0(P)		;LINE NUMBER IN 2
	JUMPE 1,[POP P,1	;NULL TERMINATES
		RET]
	CALL TCEO2		;OUTPUT VIA ECHO BUFFER
	JRST TTEM1

IFDEF DECDLS,<
;ROUTINE TO FIND DC10E CORRESPONDING TO GIVEN DATA LINE

TTECNV:	PUSH P,2
	ANDI 2,77
	IDIVI 2,10
	ADD 3,DCTAB(2)
	JUMPL 3,.+2
	MOVSI 3,DLSDLB(3)	;SET UP FOR DATAO FROM 3
	POP P,2
	RET
>

;DLS CHANNEL INTERRUPT SERVICE
;CALLED WITH JSYS FROM CHANNEL SEQUENCE

DLSSV:	XWD XDLSSV,.+1
IFN KIFLG,<
	CLSB DLSCHN>		;CLEAR REQUEST DUE TO SOFTWARE
	SKIPL TTNIT1
	JRST TTNITS
IFN NDLS,<
	CONSZ DLS,330		;PI REQ, CAR XITION, XMIT, RECV
	JRST DLSSV2
>; END TEST ON NDLS
	CONI TTY,1		;CONSOLE TTY
	TRNE 1,7		;PI ASSIGNED?
	TRNN 1,50		;AND SERVICE NEEDED?
	JRST @XDLSSV		;NO (MAY BE IN DDT WITH FLAG ON)
	JRST TTYSV
IFN NDLS,<

;SERVICE DLS

DLSSV2:	DATAI DLS,1
	IFDEF DECDLS,<
	 TRNN 1,DLSRCF>		;IF NOT RECEIVER FLAG,
	IFDEF BBNDLS,<
	 TRNE 1,DLSXMF>		;IF TRANSMITTER FLAG,
	DATAO DLS,[400+DLSACT]	;RELEASE SCANNER
	IFDEF BBNDLS,<
	 CONO DLS,110+DLSCHN>	;RESET SCANNER TO 0 AND RELEASE
	HLRZ 2,1		;LINE NUMBER
	CAML 2,LOLIN		;WITHIN PROPER RANGE OF LINES?
	CAML 2,HILIN
IFDEF BBNDLS,<
	JRST DLSSV3>		;UNDEFINED LINE
IFDEF DECDLS,<			;MAY BE A DC10E LINE
	JRST [	IDIVI 2,10	;CONVERT TO GROUP AND LINE IN GROUP
		HRRE 2,DCTAB1(2) ;SEE IF THIS IS A DC10E GROUP
		JUMPL 2,DLSSV3	;NO. JUMP TO IGNORE.
		ADDI 2,0(3)	;YES. CONVERT TO DATA LINE
		TRO 1,DLSCXF	;GIVE CARRIER TRANSITION FLAG
		HRLI 1,0(2)	;PUT DATA LINE NUMBER IN DATAI WD
		JRST .+1]
>
>; END TEST ON NDLS
TTYSV1:	TRNN 1,DLSRCF+DLSCXF	;RECEIVER OR XITION
	JRST DLSSV1
	MOVEI 3,TTBSIZ
	CAMG 3,TTBIGC		;BUG BUF OVERFLOW?
	JRST DLSSV1		;YES, IGNORE CHAR
	AOS 3,TTBIGI		;PUT WORD IN BIG BUFFER
	CAIN 3,TTBSIZ
	SETZB 3,TTBIGI		;WRAPAROUND
	MOVEM 1,TTBBUF(3)
	AOS TTBIGC		;COUNT CONTENTS
DLSSV1:	IFDEF DECDLS,<
	 TRNN 1,DLSRCF>		;IF NOT RECEIVER FLAG,
	IFNDEF DECDLS,<
	 TRNE 1,DLSXMF>		;TRANSMITTER
	JSP 4,TTSND
DLSSV3:	UNBRK DLS

;INITIATED INTERRUPT TO START OUTPUT ON LINE

TTNITS:	MOVEI 1,0
	MOVE 2,TTNIT1		;LINE NUMBER
	SETOM TTNIT1
	JSP 4,TTSND		;DO OUTPUT
	JRST DLSSV3

;CONSTANTS

WRPMSK:	XWD 770000,TTSIZ-1	;MASK FOR WRAPAROUND OF CHAR POINTER

;SERVICE INTERRUPT FROM CONSOLE TTY
;CONSTRUCT WORD LIKE SCANNER DATAI

TTYSV:	MOVEI 1,0
	CONSO TTY,40		;INPUT DONE
	JRST .+3
	DATAI TTY,1
	TROA 1,DLSRCF		;SCANNER RECEIVER BIT
	CONSO TTY,10		;OUTPUT DONE
	JRST .+3
	TRO 1,DLSXMF		;SCANNER TRANSMITTER
	CONO TTY,200+DLSCHN	;TURN OFF OUTPUT DONE
	HRLI 1,CTYLIN		;PSEUDO-LINE NUMBER
	MOVEI 2,CTYLIN
	JRST TTYSV1

DLSVSP:	IOWD NDLSPD,DLSPDL	;INTERRUPT LEVEL STACK POINTER

;SEND CHARACTER TO TTY LINE,
;FROM ECHO BUFFER IF NOT EMPTY, OTHERWISE
;FROM OUTPUT BUFFER IF NOT EMPTY; OTHERWISE
;CLEAR OUTPUT-ACTIVE FLAG

TTSND:
IFN NDLS,<
	CAMN 2,TTHNGL		;LINE BEING CHECK FOR OUTPUT INTERRUPTS?
	SETZM TTHNGT		;YES, MAKE CHECK OK
>
	SKIPE TTECT(2)		;CHECK ECHO BUFFER
	JRST TTSNDE
	SKIPE TTOCT(2)		;CHECK OUTPUT BUFFER
	JRST TTSNDO
	MOVSI 3,400000
	ANDCAM 3,TTFLGS(2)	;CLEAR OUTPUT-ACTIVE
	MOVEM P,DLSVAP		;SETUP STACK
	MOVE P,DLSVSP
	CALL TTRLOB		;RELEASE OUTPUT BUFFERS, SINCE EMPTY
	MOVE P,DLSVAP
	JRST TTSND1

TTSNDE:	SKIPN 3,TTEOUT(2)	;GET POINTER
	BUG(HLT,<TTY ECHO OUTPUT - NO BUFFER BUT COUNT NON-0>)
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(3)
	MOVEM 3,TTEOUT(2)	;WRAP POINTER
	ILDB 3,TTEOUT(2)
	SOS TTECT(2)
	JRST TTSND2

TTSNDO:	SKIPN 3,TTOOUT(2)	;GET BUFFER POINTER
	BUG(HLT,<TTY OUTPUT - NO BUFFER BUT COUNT NON-0>)
	TDNN 3,WRPMSK
	HRR 3,1-TTSIZ(3)
	MOVEM 3,TTOOUT(2)	;WRAP POINTER
	ILDB 3,TTOOUT(2)
	SOS TTOCT(2)
TTSND2:	ANDI 3,377
	CAIE 2,CTYLIN		;IS CONSOLE TTY?
	JRST TTSND5		;NO
	DATAO TTY,3		;YES
	JRST TTSND4

TTSND5:
IFN NDLS,<
	HRLI 3,DLSDLB(2)	;DIRECTED LINE BIT
	IORI 3,DLSACT		;ACTIVATE BIT
	DATAO DLS,3
>; END TEST ON NDLS
IFE NDLS,<
	BUG(CHK,<OUTPUT TO DLS AT TTSND>) >
TTSND4:	MOVSI 3,400000
	IORM 3,TTFLGS(2)	;SET OUTPUT-ACTIVE
TTSND1:	JRST 0(4)

	END

