Google
 

Trailing-Edge - PDP-10 Archives - BB-F493Z-DD_1986 - 10,7/703mon/scnser.mac
Click 10,7/703mon/scnser.mac to see without markup as text/plain
There are 13 other files named scnser.mac in the archive. Click here to see a list.
TITLE	SCNSER - TERMINAL SCANNER SERVICE  V1010
SUBTTL	R CLEMENTS/RCC/DAL/PMW/EJW/WRS/RCB	18 MAR 86
	SEARCH	F,S
IFN FTNET,<SEARCH NETPRM>
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;ALL RIGHTS RESERVED.


;
;
XP VSCNSR,1010
ENTRY SCNSER
SCNSER::
;               TABLE OF CONTENTS FOR SCNSER
;
;
;                        SECTION                                   PAGE
;    1. PARAMETER AND CONFIG DEFINITIONS..........................   3
;    2. DATA STRUCTURES
;         2.1   LINTAB AND DSCTAB.................................   5
;         2.2   LINE DATA BLOCK (LDB).............................   6
;         2.3   TTY DEVICE DATA BLOCK (DDB).......................  19
;    3. TRANSMIT INTERRUPT ROUTINE................................  20
;    4. RECEIVE INTERRUPT ROUTINE.................................  36
;    5. KI10 CONSOLE TERMINAL SERVICE.............................  70
;    6. KS10 CTY AND KLINIK TERMINAL SERVICE......................  71
;    7. FILLERS AND SIMULATION ROUTINES...........................  72
;    8. FILL CHARACTER DATA.......................................  81
;    9. TIMING ROUTINE............................................  84
;   10. CHUNK HANDLERS............................................  97
;   11. CHUNK HANDLERS
;        11.1   ALLOCATION AND DEALLOCATION....................... 100
;        11.2   CLEAR BUFFERS..................................... 102
;   12. UUO LEVEL ROUTINES FOR BUFFERED I/O....................... 103
;   13. DDT MODE CALLI'S.......................................... 110
;   14. TTCALL AND TRMOP.
;        14.1   TTCALL DISPATCH................................... 111
;        14.2   OUTCHR AND IMAGE OUTCHR........................... 113
;        14.3   OUTSTR AND RESCAN................................. 114
;        14.4   SKPINL AND SKPINC................................. 115
;        14.5   GETLIN............................................ 116
;        14.6   SETLIN, INCHSL, INCHWL, INCHRS & INCHRW........... 117
;        14.7   TRMNO. UUO........................................ 118
;        14.8   TRMOP. DISPATCH................................... 119
;        14.9   SKIPS AND CLEARS.................................. 131
;        14.10  TRMOP. I/O........................................ 132
;        14.11  TRMOP. I/O SUBROUTINES............................ 134
;        14.12  TRMOP. DATASET FUNCTIONS.......................... 135
;        14.13  TYPE INTO TTY ON BEHALF OF A USER................. 139
;        14.14  MIC  --  SET/CLEAR LDBMIC......................... 140
;        14.15  MIC  --  RETURN MIC STATUS........................ 141
;        14.16  MIC  --  READ ERROR RESPONSE TEXT................. 142
;        14.17  MIC  --  LOG ALL TERMINAL OUTPUT.................. 143
;        14.18  MIC  --  MISCELLANEOUS MIC SUBROUTINES............ 144
;   15. SUBROUTINES FOR I/O....................................... 148
;   16. COMMAND LEVEL ROUTINES.................................... 156
;   17. SUBROUTINES FOR COMCON OR UUO LEVEL....................... 171
;   18. CTY ROUTINES.............................................. 175
;   19. DDB ROUTINES.............................................. 178
;   20. ROUTINES FOR PTY.......................................... 194
;   21. IMPURE DATA............................................... 200
	SUBTTL	PARAMETER AND CONFIG DEFINITIONS

XP STTYBF,20

;DATASET TRANSACTION CODES FROM SCNSER TO/FROM XXXINT'S

XP DSTOFF,1		;DSCREC OR DSCTYP
XP DSTON,2		;DSCREC OR DSCTYP
XP DSTRNG,3		;DSCREC
XP DSTREQ,3		;DSCTYP
XP DSTINI,4		;TO AND FROM. SENDING COMPUTER WAS RESTARTED.
XP DSTSTS,5		;REQUEST DATA SET STATUS
XP DSTCRQ,10		;CALL REQUEST TO MODEM. WANT TO DIAL OUT.
XP DSTPND,20		;PRESENT NEXT DIGIT, TO AND FROM.
; NOTE - TO MODEM, 20-37 MEAN SEND DIGIT N-20
; WHERE DIGIT 17 MEANS END OF NUMBER (TO BOTH HARDWARE AND SOFTWARE)
; AND DIGIT 16 MEANS 5-SECOND DELAY TO SOFTWARE, FOR SECOND DIAL TONE.
XP DSTNAC,40		;NO ACTION -SYSINI (ONLY USER OF DSTREQ) SHOULD
			; NOT MODIFY LINE STATUS CODES (CARRIER ON/OFF)

;LINE CONTROL TRANSACTION CODES

XP LNTEHC,1	;ENABLE HUNG CHECK
XP LNTDHC,2	;DISABLE HUNG CHECK
ND	STDALT,033		;VALUE OF STANDARD ALTMODE
ND	VTAB,10			;VERTICAL TAB SPACING (MUST BE POWER OF 2)
ND	RCQMAX,^D32		;RECINT QUEUE SIZE

IFNDEF FTMLOG,<XP FTMLOG,-1>	;NON-ZERO TO INCLUDE MIC LOG CODE

;SIZE OF CHUNKS

XP IMGTIM,^D10			;MUST FIT IN LDPTIM FIELD. HUNG TIME FOR IMI


;HARDWARE PARAMETERS OTHER THAN THOSE IN THE XXXINT ROUTINES

CTY=120		;HARDWARE DEVICE NUMBER OF THE KA10 CONSOLE TERMINAL
	SUBTTL	DATA STRUCTURES -- LINTAB AND DSCTAB


;DATA STRUCTURES IN COMMON

;LINTAB:	BLOCK # OF LINES INCLUDING SCANNER,CTY AND PTY'S
;EACH WORD=	FULLWORD LDB ADDRESS

;DSCTAB:	BLOCK # OF DATASETS NEEDING TIMING
;		RH= LINKED TERMINAL LINE NUMBER FOR DATA
;		LH= TIME IN 14-17, ALSO DSCHWC,DSCSWC,DSCFAI

XP DSCHWC,400000	;WHEN LAST HEARD FROM, THE HARDWARE CARRIER WAS ON
XP DSCSWC,200000	;THE SOFTWARE CONSIDERS THE CARRIER TO BE ON OR
			; TO BE COMING ON IMMINENTLY
XP DSCFAI,100000	;CARRIER WENT OFF, BUT MAY BE BRIEF FAILURE
			; EXCEPT FOR GPO 2B MODEM, MUST QUIT IMMEDIATELY
XP DSCNCR,040000	;NEW CARRIER FLAG, ON FOR FRACTION OF SECOND FOR CLOCK SYNC
XP DSCBLI,020000	;BLIND FLAG - IGNORE EVERYTHING FOR 1 SEC AFTER CARRIER ON
XP DSCDLW,010000	;DIALLER WAIT. WAITING FOR RESULTS FROM DIALLER
XP DSCDLF,004000	;DIALLER FAIL. UNSUCCESSFUL DIALLER ATTEMPT
XP DSCDLC,002000	;DIALLER COMPLETE. SUCCESSFUL DIALLER ACTION.
XP DSCEON,001000	;END OF NUMBER. SENT ALL DIGITS TO DIALLER.
XP DSCTMM,777		;TIME MASK. MUST AGREE WITH DSTIMP POINTER.

;DEFINITIONS FOR INITIALIZATION ROUTINE IN SYSINI

XP DSCICL,DSCHWC!DSCSWC!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON!DSCTMM
XP DSCIC1,DSCHWC!DSCSWC
XP DSCIC2,DSCTMM!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON

	SUBTTL	DATA STRUCTURES -- LINE DATA BLOCK (LDB)

;PROTOTYPE LINE DATA BLOCK FOR A TTY (OR PTY) LINE

SCNLDB::
PHASE 0

LDBDDB::!XWD	ZERO5,0	;ADDRESS OF LINE'S ATTACHED DDB, IF ANY
LDBCOM::!0		;BITS WHICH USED TO BE IN LH OF LDBDDB
XP LDBCMR,400000	;SIGN BIT OF LDBCOM IS COMMAND REQUEST BIT
			; MUST BE IN WORD ZERO, FOR @U, 13-17 MUST BE ZERO
XP LDBCMF,200000	;COMMAND FORCED. MEANS TYI ATE A CONTROL C
			; WHICH WAS DESTINED FOR COMCON, OR SOME OTHER COMMAND
			; IS TO BE FORCED, VIA LDPCMX. MUST BE IN SAME
			; WORD AS LDBCMR
XP LDBCMK,100000	;FORCING KJOB COMMAND
XP LDBDET,40000		;JOB DETACHED FROM THIS LINE DURING COMMAND
			;PROCESSING.  FORCE CLEANUP OF JOB/COMMAND
			;AT NEXT TICK.
XP LDBFDX,20000		;PROCESSING A FILDAE EXIT MESSAGE. LEAVE LDBCMF ALONE.
			;BITS 9-12 ARE INDEX FOR FORCED COMMAND,
			; POINTER = LDPCMX

LDICLR::!		;ON RESTART, START CLEARING HERE
LDBATR::!0		;TERMINAL ATTRIBUTES
LAL8BT==:400000		;EIGHT-BIT TERMINAL.  MUST BE SIGN BIT.  TERMINAL
			; CAN ACCEPT AND GENERATE ASCII CODES 200-377.
LALCOS==200000		;CAN OVERSTRIKE.  USED WHEN LAL8BT OFF TO GENERATE
			; 7-BIT EQUIVALENTS FOR 8-BIT CHARACTERS.
LALDIS==:100000		;TERMINAL IS A DISPLAY.  AT A MINIMUM, THIS IMPLIES
			; THAT BACKSPACE GOES BACKWARD ON THE SCREEN, AND
			; THERE IS A WAY TO HOME AND CLEAR THE SCREEN.
			; (FORMERLY LPLDIS)
LDBOST::!0		;OUTPUT SPECIAL STATES BIT TABLE
			;BITS ARE DEFINED AT XMTDSP
LDBIST::!0		;INPUT STATE WORD
			;LH STORES THE CHARACTER BEING DEFERRED,
			;RH STORES THE REASON FOR DEFERRING IT:
	LISDCI==1	;DEFERRED CLEAR INTERRUPT
	LISQOT==2	;QUOTING A CHARACTER
	LISSWI==3	;EVALUATING A POSSIBLE SWITCH SEQUENCE
LDBBKU:!0		;COPY OF LDBECT AT LAST BREAK XMTECH
LDBBKI:!0		;COPY OF LDBTIP AT LAST BREAK RECINT
LDBTIP::!0		;T2 TO PUT CHARACTERS IN INPUT BUFFER
LDBTIT::!0		;T2 TO TAKE CHARACTERS FROM INPUT BUFFER
LDBTIC::!0		;COUNT OF ECHOED CHARACTERS IN INPUT BUFFER
LDBBKC::!0		;COUNT OF BREAK CHARACTERS IN INPUT BUFFER
LDBTOP::!0		;T3 TO PUT CHARACTERS IN OUTPUT BUFFER
LDBTOT::!0		;T2 TO TAKE CHARACTERS FROM OUTPUT BUFFER
LDBTOC::!0		;COUNT OF CHARACTERS IN OUTPUT BUFFER
LDBECT::!0		;T2 TO TAKE CHARACTERS FROM INPUT FOR ECHOING
LDBECC::!0		;COUNT OF CHARACTERS TO ECHO
LDBIEC::!0		;INVISIBLE (NOT-IN-STREAM) CHARACTERS YET TO BE ECHOED
LDBIIC::!0		;INVISIBLE (NOT-IN-STREAM) CHARACTERS ECHOED AND PENDING
LDBEOP::!0		;T3 TO PUT CHARACTERS IN ECHO OUTPUT BUFFER
LDBEOT::!0		;T2 TO TAKE CHARACTERS FROM ECHO OUTPUT BUFFER
LDBEOC::!0		;COUNT OF ECHO STREAM CHARACTERS TO OUTPUT
IFN FTPI,<
LDBOOP::!0		;BYTE POINTER TO ENQUEUE OUT-OF-BAND CHARACTERS
LDBOOT::!0		;B.P. TO DEQUEUE OUT-OF-BAND CHARACTERS
LDBOOC::!0		;COUNT OF ENQUEUED OUT-OF-BAND CHARACTERS
>
LDBCLP::!0		;COMMAND LINE POINTER (FOR COMCON)
LDBXNP::!0		;XON CLASS CHARACTER POINTER FOR OUTPUT
IFN FTXMON,<
	 0		;TWO WORD GLOBAL BYTE POINTER
>
LDBFLP::!0		;FILLER CHARACTER POINTER FOR OUTPUT
IFN FTXMON,<
	 0		;TWO WORD GLOBAL BYTE POINTER
>
LDBNNP:!0		;FILLER POINTER FOR 'NOT NOW' TEXT (BUSY/GOAWAY)
IFN FTXMON,<
	0		;TWO WORD GLOBAL BYTE POINTER
>
LDBPBK::!0		;WORD OF UP TO 4 BREAK CHARACTERS (8 BIT)
			;FOR PACKED IMAGE MODE (PIM); SET WITH TRMOP 2037
LDBHPS::!0		;HORIZONTAL POSITION COUNTER.  COUNTS UP FROM
			;MINUS CARRIAGE WIDTH TO ZERO.
LDBBCT::!0		;TOTAL COMMAND,,BREAK CHARACTER COUNT
LDBICT:!0		;TOTAL INPUT CHARACTER COUNT
LDBOCT:!0		;TOTAL OUTPUT CHARACTER COUNT
LDICLE==:.-1		;ON RESTART, CLEAR THRU HERE
;MORE OF THE PROTOTYPE LINE DATA BLOCK
LDBDCH::!0		;DEVICE CHARACTERISTICS BITS

;BITS IN LH OF LDBDCH (CARRIED IN LH OF U DURING INTERRUPT ROUTINE)
LDLIDL==:400000		;LINE IS IDLE.  IF CLEAR, WE ARE EXPECTING
			;A TRANSMIT INTERRUPT
			; MUST BE SIGN BIT.
LDLPPS==:200000		;PROMPT POSITION SET THIS LINE
LDLCRP==100000		;CONTROL-R PENDING (FOR XMTECH SYNCH PLUG)
LDLDIP==040000		;DELETE IN PROGRESS IN XMTECH (BLOCK TYICC4)
LDLCNE==:020000		;COMMAND-LEVEL NO ECHO
LDL8BI==:010000		;8-BIT INPUT MODE, DUE TO PROGRAM
LDLDLR==004000		;SUPPRESS DOLLAR SIGN ON ALTMODES.
LDLNEC==:002000		;NO ECHO, DUE TO PROGRAM
LDLFCS==:001000		;LINE INITED IN FULL CHAR SET MODE
LDLIMI==:000400		;IMAGE INPUT (KEEP NULLS)
XP LDLCOM,000200	;LINE IS AT COMMAND LEVEL
LDLBKA==:000100		;BREAK ON ALL CHARACTERS (DDTIN, TTCALL)

;*** BEGINNING OF GROUP OF BITS POINTED TO BY LDPVR1 ***
;*** BEGINNING OF 4 BITS POINTED TO BY GETLP1 FOR GETLIN ****
XP LDLSLV,000040	;SLAVE. THIS TERMINAL MAY BE ASSIGNED.
XP LDLLCT,000020	;LOWER CASE TRANSLATE TO UPPER
XP LDLTAB,000010	;LINE ACCEPTS TABS, NOT SPACES.
XP LDLLCP,000004	;LOCAL COPY (NO ECHO)
;*** END OF BITS POINTED TO BY GETLP1 ***
XP LDLFRM,000002	;LINE ACCEPTS FF AND VT (ELSE USE LF'S)
XP LDLNFC,000001	;NO FREE CARRIAGE RETURN AT 72 COLUMNS
;*** END OF GROUP FOR LDPVR1 ***
XP LDLECH,LDLNEC!LDLBKA!LDLLCP

;BITS TO BE CLEARED ON A 140 RESTART
ZZL==LDLIDL+LDLIMI+LDLNEC+LDLDLR+LDLBKA+LDLFCS+LDLCRP+LDL8BI+LDLDIP+LDLCNE
XP LDLIIF,LDLIMI+LDLFCS		;IMAGE INPUT OR FULL CHAR SET MODE
;RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO

LDRPTY==:400000		;PSEUDO-TERMINAL
LDRCTY==:200000		;CONSOLE TERMINAL
;*** START OF GROUP OF BITS POINTED TO BY LDPVR2 ***
LDROSU==:100000		;OUTPUT SUPPRESS (^O)
LDRDSD==:040000		;DATASET DATA LINE
LDR274==:020000		;LINE IS A 2741
LDRHLF==010000		;HALF DUPLEX LINE (TWX OR DC10C)
LDRRMT==:004000		;REMOTE NON-DATASET LINE
XP LDRDSR,LDRDSD+LDRRMT	;REMOTE OR DATA SET LINE (FOR PATCH)
			; SO CAN'T ATTACH TO PROJECT 1 #
;*** END OF GROUP FOR LDPVR2 ***
;	002000		;FREE
LDRSHC==:001000		;SUPPRESS HUNG CHECK -I.E. DON'T FORCE CHAR'S OUT
			;  WHEN NO XMIT FLAG.--SET BY 680 FOR SPECIAL
			;  DEVICES (E.G. 2741) & ITS OPR. TERMINAL

;BITS TO BE CLEARED ON A 400 RESTART
ZZR==LDRPTY+LDRCTY+LDRSHC+LDROSU

;DEFINITIONS OF BITS FOR GETLIN UUO, CLOSELY ASSOCIATED WITH ABOVE

GTLRDY==100		;BIT FOR GETLIN TO INDICATE WAITING BREAK CHAR
GTLT37==20		;MODEL 37 BIT (COPY OF LDLLCT)
GTLT35==10		;MODEL 35 BIT (COPY OF LDLTAB)
GTLLCP==4		;LOCAL COPY (OLD FULTWX) (COPY OF LDLLCP)
GTLXON==2		;XON IS TRUE (COPY OF L2RXON)
GTLMSK==LDR274!777	;BITS TO CLEAR ON GETLIN
LGLSET==GTLT37+GTLT35+GTLLCP+GTLXON	;MAY BE SET BY SETLIN


;BITS THAT ARE TESTED ON A CALL TO XMTCHR TO SEPARATE OUT
;THE NORMAL CASE FROM THE SPECIAL CASES.

DCHSPC==LDLIDL,,LDRHLF
;MORE OF THE PROTOTYPE LINE DATA BLOCK

LDBOFL::!
LDBBYT::!0		;A WORD OF BYTES FOR THIS LINE

;BITS	POINTER	USE
;35-28	LDPECK	ECHO CHECK FOR HALF DUPLEX LINES
;27	L1RDEM	DEFERRED ECHO BIT.  SET BY SET TERMINAL DEFER
;26	L1RDEC	ECHO MAY ECHO 1 CHARACTER IF DEFERRED
;25	L1RDEL	ECHO MAY ECHO 1 LINE IF DEFERRED
;24-22	LDPCPU	CPU NUMBER--
;21	L1RCHP	CHANGE HARDWARE PARAMETERS FLAG (MEANINGUL EVEN FOR PTYS!)
;20	L1RMIF	MIC INTERLOCK FLAG
;19-15	LDPTIM	TIMEOUT ON IMAGE INPUT
;14	L1LDEM	DEFERRED ECHO BIT FOR XMTECH.  SET/CLEARED BY XMTECH
;13	L1LQOT	TTY QUOTE ENABLED
;12	L1LQTC	QUOTE NEXT CHARACTER IN XMTECH
;11	L1LQNC	QUOTE NEXT CHARACTER IN TYICC4
;10	L1LQCC	QUOTE NEXT CHARACTER IN CCTYI
;09	L1LUNR	UNREAD IN PROGRESS
;08-06		FREE
;05-03	POHPOS	OLD HORIZONTAL POSITION. NEEDED FOR TAB SIMULATION
;02-01	LDPFLC	COUNT OF NUMBER OF FILLERS BY CLASS
;0		1 IF FRONT END FOR THIS LINE IS DOWN.
;		 USE LDBOFL AS THE SYMBOL TO SKIPGE/SKIPL ON.
L1LOFL==:400000		;THE OFF-LINE BIT
L1RDEM==:1B27		;DEFERRED ECHO MODE
L1RDEC==:1B26		;MAY ECHO ONE CHARACTER (DEFERRED ECHO ONLY)
L1RDEL==:1B25		;MAY ECHO ONE LINE (DEFERRED ECHO ONLY)
L1RCHP==:1B21		;CHANGE HDW PARMS
L1RMIF==:1B20		;MIC INTERLOCK FLAG
L1LDEM==(1B14)		;XMTECH'S DEFERRED ECHO FLAG
L1LQOT==:(1B13)		;TTY QUOTE ENABLED FLAG
L1LQTC==(1B12)		;QUOTE FLAG FOR XMTECH
L1LQNC==(1B11)		;QUOTE FLAG FOR TYICC4
L1LQCC==(1B10)		;QUOTE FLAG FOR CCTYI
L1LUNR==:(1B9)		;UNREAD IN PROGRESS
LDIBCM==477777,,600000+L1RDEM+L1RDEC+L1RDEL+L1RCHP+L1RMIF+377 ;MASK TO CLEAR
			;LDBBYT AT TTYINI. ALL ARE CLEARED EXCEPT LDPFLC
;ANOTHER BYTE WORD, FLAGS AT LEFT.
LDBBY2::!0
;BITS	POINTER	USE
;32-35		FREE
;28-31	LDPAPC	ASYNCHRONOUS PORT CHARACTERISTIC
;20-27	LDPWID	WIDTH OF TERMINAL CARRIAGE
;18-19	BITS - SEE BELOW
;9-17	LDPDSC	DATASET CONTROL TABLE INDEX BACK POINTER
;0-8	BITS - SEE BELOW

L2LDEL==:400000		;LAST CHAR IN WAS A DELETE (MUST BE SIGN BIT)
L2LCCS==200000		;LAST CHAR IN WAS A ^C
L2LHD1==100000		;XMT DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD2==040000		;RCV DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD3==020000		;IGNORING RCV INTS DUE TO ECHO CHECK ERR ON HDX LINE
L2LHD4==010000		;NEXT RCV INT WILL BE CUE AFTER ECHO CHK
L2LHD5==004000		;RECEIVE ECHO WAS IN FACT NOT SAME AS XMT CHAR
L2LSND==:002000		;SEND ALLOWED WHILE BUSY
L2LTAP==:001000		;^Q FROM KEYBOARD TURNS ON L2RXON. SET BY .TERMINAL TAPE COMMAND

L2LHDM==L2LHD1!L2LHD2!L2LHD3!L2LHD4!L2LHD5

L2LCLR==L2LDEL!L2LCCS!L2LHDM!L2LSND!L2LTAP
			;CLEARED ON INITIALIZATION

L2RXON==:400000		;XON IS TRUE (PAPER TAPE INPUT)
L2RECS==200000		;EAT COMMAND SYNC, FOR TTCALL 10
L2RWID==177400		;FIELD FOR CARRIAGE WIDTH
L2RAPC==000360		;FIELD FOR ASYNCHRONOUS PORT CHARACTERISTIC
;FREE== 000017		;FREE BITS
;ANOTHER BYTE WORD, FLAGS AT LEFT.
LDBBY3::!0
;BITS	POINTER	USE
;27-35	LDPTMR	COUNT-UP TIMER FOR AUTO-DISCONNECT
;27	L3RTMO	OVERFLOW FOR ABOVE (AUTO-DISCONNECT TIMER EXPIRED)
;19-26	LDPMXT	MAXIMUM IDLE TIME FOR AUTO-DISCONNECT LOGIC
;10	L3LCHD	COMMAND HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;9	L3LIHD	INPUT HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;8	L3LEHD	ECHO HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;7	L3LOHD	OUTPUT HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;6	L3LFHD	FILL HALF-DONE (TWO-PART CHARACTER TO BE COMPLETED)
;5	L3LCPD	COMMAND PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;4	L3LIPD	INPUT PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;3	L3LEPD	ECHO PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;2	L3LOPD	OUTPUT PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;1	L3LFPD	FILL PART-DONE (THREE-PART CHARACTER TO BE COMPLETED)
;0	L3LDMC	DEFERRED ECHO MODE CHANGED (MUST BE SIGN BIT)

L3RTMO==1B27		;AUTO-DISCONNECT LOGIC TIMEOUT FLAG

L3LCHD==(1B10)		;COMMAND HALF-DONE (TWO-PART CHARACTER)
L3LIHD==(1B9)		;INPUT HALF-DONE (TWO-PART CHARACTER)
L3LEHD==(1B8)		;ECHO HALF-DONE (TWO-PART CHARACTER)
L3LOHD==(1B7)		;OUTPUT HALF-DONE (TWO-PART CHARACTER)
L3LFHD==(1B6)		;FILL HALF-DONE (TWO-PART CHARACTER)
L3LCPD==(1B5)		;COMMAND PART DONE (THREE-PART CHARACTER)
L3LIPD==(1B4)		;INPUT PART-DONE (THREE-PART CHARACTER)
L3LEPD==(1B3)		;ECHO PART-DONE (THREE-PART CHARACTER)
L3LOPD==(1B2)		;OUTPUT PART-DONE (THREE-PART CHARACTER)
L3LFPD==(1B1)		;FILL PART-DONE (THREE-PART CHARACTER)
TPCLSH==5		;OFFSET FROM TWO-PART TO THREE-PART BITS
L3LDMC==:(1B0)		;DEFERRED ECHO MODE HAS CHANGED (FLAG FOR RECINT)
;LENGTH AND STOP SIZE AND COUNTERS

LDBLSW::!0

;BITS	POINTER	USE
;00-08	LDPLNB	PAGE (OR "FORMS") LENGTH (BASE VALUE)
;09-17	LDPSTB	STOP (AFTER N LINES) SIZE (BASE VALUE)
;18-26	LDPLNC	PAGE (OR "FORMS") COUNTER (COUNTED UP TO 0)
;27-35	LDPSTC	STOP (AFTER N LINES) COUNTER (COUNTED UP TO 0)
;
;		ABOVE ARE 8-BIT FIELDS WITH ONE-BIT OVERFLOW.
;		LDPLNC AND LDPSTC MUST BE IN RIGHT HALF WORD!
LPRLC0== 400000		;LENGTH COUNTER OVERFLOWED
LPRSC0== 000400		;STOP COUNTER OVERFLOWED



;PAGE COUNTER WORD AND PAGE FLAGS

LDBPAG::!0

;BITS	POINTER USE
;3	LDPALT	ALTMODE CONVERSION (SET TERMINAL ALT)
;16-17		FREE
;18-26	LDPPFF	#LF'S REMAINING ON F.F. SIMULATION
;27-35	LDPACR	AUTO CRLF COUNTER

LPLIRM== 400000		;LOST TRANSMIT INTERRUPT BIT
LPLXNF==:200000		;PROCESS XON/XOFF
LPLXOF== 100000		;SENT XOFF, ALWAYS SEND AN XON LATER
LPLALT==:040000		;ALTMODE CONV. (1:CONVERT 175,176 TO 033)
LPLBLK==:020000		;SUPPRESS BLANK LINES
LPLSLF== 010000		;SUPPRESS LINE FEEDS
;(FREE)==004000		;FREE BIT
;(FREE)==002000		;FREE BIT
LPLPOK== 001000		;WE ARE FORCING XMIT START VIA TOPOKE (PREVENT RACE)
LPLSTP==:000400		;AUTOMATICALLY STOP EVERY (LDPSTB) LINES OF OUTPUT
LPLSST==:000200		;NO CLRPCT ON RECEIPT OF "FREE" XON
LPLFFS==:000100		;STOP ON FORM-FEEDS
LPLSBL==:000040		;UTTER FORTH A STUPID BELL ON AUTO STOP
LPLFFF==:000020		;SIMULATE FORMFEEDS WITH MANY LINEFEEDS
LPLFFH==:000010		;SIMULATE FORMFEEDS AS HOME/ERASE SEQUENCE
;(FREE)==000004		;FREE BIT
;(FREE)==000002		;FREE BIT
;(FREE)==000001		;FREE BIT
LPRPFF== 777000		;FORM FEED SIMULATION LF COUNTER
LPRACR== 000777		;AUTO-CRLF COUNTER

LPGCLK==LPLIRM!LPLXOF!LPLBLK!LPLSLF,,LPRPFF!LPRACR ;CLEARED BY TTYKIL
LPGCLI==LPGCLK!<LPLSTP!LPLSST!LPLFFS!LPLSBL!LPLFFF!LPLFFH,,0>  ;CLEARED BY LDBINI
;FLAGS AND POINTER TO INTERRUPT SERVICE ROUTINES
LDBISR::!BLOCK	1
;13-17	CONTAIN T1 FOR @LDBISR(U)
;18-35	ADDRESS OF ISR DISPATCH TABLE
LDBISB::!BLOCK	1
;BITS	POINTER	USE
;0	N/A	1 IF THE FRONT END IS CLEVER, 0 IF DUMB
;1-4	LDPTSP	TRANSMIT SPEED
;5-8	LDPRSP	RECEIVE SPEED
;9	LDPAPL	APL MODE
;10	LDPDBK	DEBREAK FEATURE EXISTS
;11	LDPRTC	CONTROL-R, CONTROL-T COMPATIBILITY
;12	LDPTDY	USER SAID "SET TERMINAL TIDY"

LILCFE==:(1B0)		;CLEVER FRONT END
LILRSP==:(17B4)		;RECEIVE SPEED
LILTSP==:(17B8)		;TRANSMIT SPEED
LILAPL==:(1B9)		;APL MODE
LILDBK==:(1B10)		;LINE HAS DEBREAK
LILRTC==:(1B11)		;CONTROL-R, CONTROL-T ARE PASSED TO PGM
LILTDY==:(1B12)		;DO NOT EXPAND OUTPUT

;FUNCTIONS ARE DEFINED IN S.MAC (ISR??? AND IRR???)
;LDBQUE -- QUEUED PROTOCOL WORDS

LDBQUE::BLOCK	1
LDBQUH::BLOCK	1

;BITS
;WORD	1	NEXT LDB IN THE QUEUE (0 TERMINATES)
;WORD	2
;	0-17	ADDRESS OF THE QUEUE HEADER
;	18-35	NOT CURRENTLY USED

;TERMINAL TYPE WORD

LDBTTW::BLOCK	1
;0	LTLANF	ANF-10 NETWORK VIRTUAL TERMINAL (MUST BE SIGN BIT)
;1	LTLNRT	DECNET NRT/CTERM VIRTUAL TERMINAL
;2	LTLLAT	LAT-SERVER TERMINAL LINE
;3	LTLUSE	ALLOCATABLE LDB IN USE
;4-8		FREE
;9	LDLFSP	FULL SCNSER PTY
;10	LDLVDC	'VISIBLE' DELETE CHARACTER PROCESSING BIT (FOR XMTECH)
;11	LDLIDC	'INVISIBLE' DELETE CHARACTER PROCESSING BIT (FOR RICW)
;12		FREE
;13-20	LDPLCH	LAST CHAR READ BY COMCON.
;21-28	LDPPRP	POSITION OF PROMPT
;29-35	LDPTTT	TERMINAL TYPE AS SPECIFIED BY TTY TYPE COMMAND

LTLANF==:400000	;ANF NETWORK VIRTUAL TERMINAL
LTLNRT==:200000	;DECNET NRT/CTERM TTY
LTLLAT==:100000	;LAT-SERVER TTY
LTLREM==LTLANF!LTLNRT!LTLLAT	;SOME FORM OF "REMOTE" TERMINAL SERVER
LTLUSE==:040000	;ALLOCATABLE LDB IS IN USE (SEE GETLDB/FRELDB)
		; NOTE: LTLUSE ALWAYS ON FOR 'LOCAL' (E.G., CTY) LDBS

LDLFSP==:000400	;FULL SCNSER PTY
LDLVDC== 000200	;CONTROL R IN PROGRESS
LDLIDC== 000100	;CONTROL W IN PROGRESS
;FIVE WORDS FOR REMOTE STATION TERMINAL STATUS

IFN FTNET,<			;NETWORK RELATED LDB FIELDS

LDBREM::BLOCK	5		;WORDS REQUIRED FOR REMOTE TERMINALS

;			LAYOUT OF LDBREM FIELDS
;
; +0	BYTE (20)BITS-USED-BY-NETTTY, (16)LAST-DAP-STATUS-MESSAGE-SENT
; +1	BYTE (36)LAST-CHARACTERISTICS-MESSAGE-SENT
; +2	BYTE (14)SLA, (14)DLA, (8)REMOTE-LINE-NUMBER
; +3	BYTE (4)2741-ELEMENT-NUMBER, (8)DRQ-COUNT, (8)EPM-SERIAL, (16)NODE-#
; +4MCR	BYTE (9)NEXT-CHAR-TO-OUTPUT, (9)FREE, (9)JOB, (9)UNUSED
; +4VTM	BYTE (16)DELAYED-STATUS-MESSAGE, (2)0, (18)VTM-QUEUE-LINK


;DEFINE SYMBOLS FOR SOME LDBREM ENTRIES
LDBCCH==:LDBREM+1		;COMPRESSED CHARACTERISTICS WORD
LDBVTQ==:LDBREM+4		;NETVTM'S QUEUE LINK HALF-WORD

;			BITS USED IN LDBREM

;BITS USED BY BOTH NETVTM(LOCAL SET HOST) AND NETMCR(REMOTE TERMINALS)

LRLVTM==:(1B0)			;*** MUST BE SIGN BIT ***
				;  IF SET, THEN THIS IS A "LOCAL TERMINAL"
				;  THAT HAS "SET HOSTED" TO ANOTHER HOST.
LRLCON==:(1B1)			;IF SET, THEN TERMINAL IS "CONNECTED"
				;  (I.E. NCL CONNECT SEQUENCE IS COMPLETE)
LRLSTS==:(1B2)			;IF SET, THEN A "STATUS" MESSAGE IS REQUIRED
				;  SAME BIT, BUT DIFFERENT MSGS FOR VTM & MCR

;BITS USED ONLY BY NETVTM (LOCAL "SET HOST")

LRLSCH==:(1B3)			;IF SET, THEN A "CHARACTERISTICS" MESSAGE
				;  IS REQUIRED (WORKS LIKE "LRLSTS")
LRLDST==:(1B4)			;A "DELAYED" STATUS MESSAGE IS REQUIRED
				;  (USED TO OPTIMIZE MESSAGE TRAFFIC.
				;  THIS BIT HAS PRIORITY OVER LRLSTS)
LRLQED==:(1B5)			;IF SET, THEN VTM LINE HAS BEEN "QUEUED"
				;  BY "VTMENQ"
LRLDIP==:(1B6)			;IF SET, THEN WE HAVE/WANT-TO INITIATE A
				; DISCONNECT ON THIS LINE
LRLVTF==:(1B7)			;VTM TERMINAL NEEDS TO BE "FREED" (A LA FRELDB)
LRLVTZ==:(1B8)			;VTM TERMINAL IS ZAPPED
;LDBREM (CONTINUED)

;BITS USED ONLY BY NETMCR ("NORMAL" REMOTE TERMINALS .. ALA DN87)

LRLTTO==:(1B3)			;LDPCHR HAS THE NEXT CHAR TO OUTPUT. THIS IS
				; NECESSARY SINCE THERE IS NO WAY TO TELL IF
				; XMTCHR WILL GIVE A CHAR WITH OUT GETTING IT.
LRLTTW==:(1B4)			;LINE IS WAITING FOR A DATA-REQUEST
LRLSCG==:(1B5)			;^O ACTION REQUESTED (SEND CHAR GOBBLER)
LRLEPW==:(1B6)			;ECHO PIPELINE MARKER WAITING TO GO.
LRLIMO==:(1B7)			;INDICATES THAT REMOTE IS IN IMAGE MODE OUTPUT
LRLADR==:(1B8)			;USE OF THE AUTO-DIALER HAS BEEN REQUESTED
LRLXOF==:(1B9)			;AN XOFF (^S) MESSAGE HAS BEEN REQUESTED
LRLCHR==:(1B10)			;THIS TERMINAL HAS RECEIVED AT LEAST 1
				; CHARACTERISTICS MSG.  (SEE NETTTY.MAC, ROUTINE
				; SCNMCR FOR DETAILS OF THE RACES INVOLVED...)
LRLHUR==:(1B11)			;HANG-UP THE PHONE REQUESTED
LRLDSR==:(1B12)			;THE -10'S COPY OF WHAT IT THINKS CARRIER
				; SHOULD BE.  (KEPT SO WE CAN TELL IF THE -11
				; CHANGED IT WHILE WE WEREN'T LOOKING)
LRLGRT==:(1B13)			;NEED TO "GREET" THE TERMINAL (E.G., RUN INITIA)
LRLATO==:(1B14)			;INDICATES THAT THIS LINE POSSESSES THE AUTO-
				; BAUD CAPABILITY.  (SET/CLEARED BY THE ATTRIB
				; FIELD OF THE CONNECT MESSAGE)
LRLADL==:(1B15)			;INDICATES THAT THIS LINE POSSESES AN AUTO-
				; DIALER (ALSO SET BY CONNECT MESSAGE)
LRLTMO==:(1B16)			;HANG-UP REQUESTED BY AUTO-DISCONNECT TIMEOUT
;FREE==:(1B17)			;FREE BIT (FORMERLY LRLTIW, FOR 2741)
LRRSHC==:1B18			;SAYS THAT THE LINE AT THE OTHER END HAS
				;  "SET HOST CAPABILITY".  (I.E. IT CAN
				;  RESPOND TO DISCONNECT MESSAGES).  NOT
				;  SET FOR DC72 LINES. SET FOR ALL OTHERS.
LRRXFF==:1B19			;WANT TO SEND XON/XOFF STATE IN STATUS
				; MESSAGE.
LRLCLR==:LRLDSR			;BITS THAT ARE OFF ON "VIRGIN" LINES
>;END OF IFN FTNET


;DEFINITIONS FOR SUPPORT OF RSX-20F TERMINALS

IFN FTKL10!FTDECNET,<	;TTD'S ONLY ON A KL, NRT AND LAT VIA DECnet
LDBLAT::!		;REDEFINES BELOW, USED ONLY FOR LAT LINES
LDBNRT::!		;REDEFINES LDBTTD, USED ONLY FOR NRT LINES
LDBTTD::!0		;LINE INFO FOR -20F LINES
;	740000		;REMEMBERED TRANSMIT SPEED
;	036000		;REMEMBERED RECEIVE SPEED
LTLXOF==:1000		;SENT XOFF TO -20F
LTLRBS==:400		;REMOTE BIT SENT FOR -20F DATASETS
LTLCTO==:200		;NEED TO SEND FLUSH OUTPUT TO -20F
LTLAXF==:100		;AUTO-XOFF ENABLE SENT TO -20F
LTLACK==:40		;LINE WAITING FOR AN ACK
LTLXFF==:20		;SEND XON/XOFF STATUS TO -20F
>;END FTKL10!FTDECNET
IFN FTMIC,<		;IF MIC INCLUDED
;WORD FOR MIC TO USE
LDBMIC::0

;0	SET IF SOME BIT 1-14 IS SET
;1	SET IF A ^C HAS BEEN TYPED
;2	SET IF OPERATOR CHAR SEEN IN COLUMN1
;3	SET IF ERROR CHAR SEEN IN COLUMN 1
;4	SET IF A ^P HAS BEEN TYPED
;5	SET IF A ^B HAS BEEN TYPED
;6	SILENCE THIS LINE
;7	LINE IN MONITOR MODE
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;8	LINE IN USER MODE AND IN TI WAIT OR IN MONITOR MODE
;	AND CAN ACCEPT A COMMAND
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;9	LINE IS IN COLUMN 1 ON OUTPUT
;	USED FOR ERROR AND OPERATOR CHECKING
;10	SET IF A ^A HAS BEEN TYPED (ABORT)
;11	SET IF ERROR OUTPUT IS AVAILABLE
;12	SET IF ERROR OUTPUT IS BEING TAKEN
;13	SET IF MIC IS LOGGING
;14	SET IF MORE INFORMATION IS AVAILABLE VIA JOBSTS UUO
;15-21	ASCII CHAR TO BE TREATED AS OPERATOR CHAR
;		SET IN RESPONSE TO OPERATOR COMMAND
;		CLEARED IN RESPONSE TO NOOPERATOR COMMAND
;		OR ON LOGOUT
;22-28	ASCII CHAR TO BE TREATED AS ERROR CHAR
;		SET IN RESPONSE TO ERROR COMMAND
;		CLEARED IN RESPONSE TO NOERROR COMMAND
;		OR ON LOGOUT
;29-35	MIC MASTER JOB NUMBER - ENABLES MORE THAN ONE MIC TO RUN

LDLCHK==400000		;SOMETHING EXCITING HAPPENED
LDLMCC==200000		;^C TYPED
LDLOPC==100000		;OPERATOR CHARACTER SEEN IN COLUMN 1
LDLERC==40000		;ERROR CHARACTER SEEN IN COLUMN 1
LDLMCP==20000		;^P TYPED
LDLMCB==:10000		;^B TYPED
LDLSIL==4000		;THIS LINE IS .SILENCE'D
LDLMMM==2000		;LINE IN MONITOR MODE (MICGET)
LDLMTI==1000		;LINE IN INPUT READY STATE
LDLCL1==400		;CARRIAGE IS IN COLUMN 1
LDLMCA==200		;^A TYPED
LDLRSP==100		;ERROR RESPONSE
LDLRSY==:40		;RESPONSE CODE SYNC
IFN FTMLOG,<
LDLLOG==20		;MIC IS LOGGING
>
LDLMUI==10		;USER IS INTERESTING, BUT YOU NEED TO ASK JOBSTS WHY

IFN FTMLOG,<
LDBLOT::0		;LOG TAKER,,COUNT OF CHARS TO LOG
LDBLOC::0		;COUNT OF CHARACTERS TO LOG
> ;END OF FTMLOG CONDITIONAL
> ;END OF MIC CONDITIONAL
;SPECIAL CHARACTER STATUS STORAGE

;BITS IN LDBBKB
;UNUSED BITS LEFT HALF BITS = 100040
LDBBKB::0		;FIELD WIDTH AND BITS CONTROLLING USE OF BREAK SET
LDLBKM==400000		;LINE IS IN BREAK CHARACTER SET MODE (MUST BE SIGN BIT)

XP LDBCSL,<CK.CHR/<^D36/CC.WID>>+1 ;NUMBER OF WORDS REQUIRED TO STORE THE BYTES

;***KEEP TOGETHER (FOR ZEROING)***
LDBCSB::! BLOCK	LDBCSL		;RESERVE SPACE FOR SPECIAL CHARACTER CODING
LDBCC1::! BLOCK	1		;'CLEAR' OOB FLAGS FOR LOW-ORDER CONTROL CHARS
LDBCC2::! BLOCK	1		;DITTO FOR HIGH-ORDER CONTROL CHARACTERS
;***END OF KEEP TOGETHER***

LDBCHM::!0		;CHARACTERS MAPPED BY RECMAP
LMLNDS==:400000		;THE NON-DEFAULT SEQUENCE BIT (MUST BE SIGN)
LMLSSE==200000		;SWITCH SEQUENCE ENABLED

DEPHASE

LDBLEN==:<.-SCNLDB>+M.LCST##	;SIZE OF DATA BLOCK FOR A LINE
;DISPATCH TABLE FOR PTYS AND CTYS.

IFN FTKS10,<
CTYDSP::JRST	CTYTYO		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?
>

ERRDSP::POPJ	P,0		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?

;LINE SPEED MNEMONICS

LS0000==:0	;ZERO BAUD
LS0050==:1	;50 BAUD
LS0075==:2	;75 BAUD
LS0110==:3	;110 BAUD
LS0134==:4	;134.5 BAUD
LS0150==:5	;150 BAUD
LS0200==:6	;200 BAUD
LS0300==:7	;300 BAUD
LS0600==:10	;600 BAUD
LS1200==:11	;1200 BAUD
LS1800==:12	;1800 BAUD
LS2400==:13	;2400 BAUD
LS4800==:14	;4800 BAUD
LS9600==:15	;9600 BAUD
;DATA POINTERS INTO LDB

LDPLCH:	POINT	8,LDBTTW(U),20		;POINTER TO LAST CHAR COMCON READ
LDPPRP:	POINT	8,LDBTTW(U),28		;POINTER TO POSITION AFTER PROMPT
LDPTTT::POINT	7,LDBTTW(U),35		;POINTER TO TTY TYPE
LDPCPU::POINT	3,LDBBYT(U),24
LDPFLC::POINT	2,LDBBYT(U),2		;POINTER TO INDEX OF FILLER CLASSES
LDPLNO::POINT	9,LDBDCH(U),35		;POINTER TO HARDWARE LINE NUMBER
LDPTIM::POINT	5,LDBBYT(U),19		;POINTER TO FIELD WHICH TIMES OUT
					; IMAGE MODE INPUT
LDPDEM::POINT	1,LDBBYT(U),^L<L1RDEM>	;POINTER TO L1RDEM BIT
LDPSTP: POINT   1,LDBOST(U),^L<(LOLSTP)>;POINTER TO OUTPUT STOPPED BIT
;LDPSSO:POINT	1,LDBOST(U),^L<(LOLSSO)>;POINTER TO SCNSER STOPPED OUTPUT BIT
LDPFRM::POINT	1,LDBDCH(U),^L<(LDLFRM)>;POINTER TO HARDWARE FORM FEED BIT
LDPTAB::POINT	1,LDBDCH(U),^L<(LDLTAB)>;POINTER TO HARDWARE TABS BIT
LDPLCT::POINT	1,LDBDCH(U),^L<(LDLLCT)>;POINTER TO LOWER CASE BIT
LDPIMI::POINT	1,LDBDCH(U),^L<(LDLIMI)>;POINTER TO IMAGE MODE FLAG
LDPPIM::POINT	1,LDBOST(U),^L<(LOLPIM)>;POINTER TO PIM MODE FLAG
LDPFCS::POINT	1,LDBDCH(U),^L<(LDLFCS)>;POINTER TO FULL CHAR SET FLAG
LDPBKA::POINT	1,LDBDCH(U),^L<(LDLBKA)>;POINTER TO BREAK ON ALL CHARS FLAG
LDPOSU:	POINT	1,LDBDCH(U),^L<LDROSU>	;POINTER TO OUTPUT SUPPRESSION (^O) BIT
LDPNFC::POINT	1,LDBDCH(U),^L<(LDLNFC)>;POINTER TO NO FREE CRLF BIT
LDPECH::POINT	1,LDBDCH(U),^L<(LDLNEC)>;POINTER TO NO ECHO BY PROGRAM BIT
LDPXNF::POINT	1,LDBPAG(U),^L<(LPLXNF)>;POINTER TO XOFFON BIT
LDPALT:	POINT	1,LDBPAG(U),^L<(LPLALT)>;POINTER TO ALTMODE CONVERSION BIT
LDPDIS::POINT	1,LDBATR(U),^L<(LALDIS)>;POINTER TO DISPLAY TERMINAL BIT
LDP8BT::POINT	1,LDBATR(U),^L<(LAL8BT)>;POINTER TO 8-BIT TERMINAL BIT
POHPOS:	POINT	3,LDBBYT(U),5		;POINTER TO LOW 3 BITS OF HPOS
					; BEFORE A TAB (FOR TAB SIMULATION)
LDPVR1:	POINT	6,LDBDCH(U),17		;POINTER TO STORE SOME OF INITIAL BITS
LDPVR2:	POINT	5,LDBDCH(U),24		;POINTER TO STORE SOME MORE OF ABOVE.
LDPCMX::POINT	4,LDBCOM(U),12		;POINTER TO INDEX OF FORCED COMMANDS
LDPWID::POINT	8,LDBBY2(U),27		;POINTER TO WIDTH OF TERMINAL CARRIAGE
LDPDSC::POINT	9,LDBBY2(U),17		;POINTER TO DATASET CONTROL TABLE INDEX
LDPAPC::POINT	4,LDBBY2(U),31		;POINTER TO APC
LDPLNB::POINT	8,LDBLSW(U),8		;TTY LENGTH BASE VALUE
LDPSTB::POINT	8,LDBLSW(U),17		;TTY STOP BASE VALUE
LDPLNC:	POINT	9,LDBLSW(U),26		;CURRENT LENGTH COUNTER
LDPSTC:	POINT	9,LDBLSW(U),35		;CURRENT STOP COUNTER
LDPSST::POINT	1,LDBPAG(U),^L<(LPLSST)>;TTY SSTOP
LDPSPE::POINT	1,LDBPAG(U),^L<(LPLSTP)>;TTY STOP (ON/OFF)

LDPPFF:	POINT	9,LDBPAG(U),26		;L.F. COUNTER FOR SIMULATION OF VT & FF
LDPDEB::POINT	2,LDBBYT(U),26		;POINTER TO DEFERRED ECHO BITS
LDPSPD::POINT	8,LDBISB(U),8		;BOTH SPEEDS
LDPRTC::POINT	1,LDBISB(U),11		;^R, ^T COMPATIBILITY
LDPRSP::POINT	4,LDBISB(U),8		;RECEIVE SPEED
LDPTSP::POINT	4,LDBISB(U),4		;TRANSMIT SPEED
LDPAPL::POINT	1,LDBISB(U),9		;APL MODE BIT
LDPDBK::POINT	1,LDBISB(U),10		;DEBREAK FEATURE EXISTS
LDP274::POINT	1,LDBDCH(U),22		;LINE IS A 2741
LDPTDY::POINT	1,LDBISB(U),12		;DO NOT EXPAND OUTPUT
LDPACR::POINT	9,LDBPAG(U),35		;AUTO CRLF POINT


IFN FTNET,<
;FIELDS IN THE LDBREM AREA.  (USED BY NETWORK LINES)

LDPSTS::POINT	16,LDBREM+0(U),35	;CONTAINS THE LAST DAP STATUS MESSAGE
LDPSLA::POINT	13,LDBREM+2(U),12	;CONTAINS OUR SOURCE LINK ADDRESS
LDPDLA::POINT	13,LDBREM+2(U),25	;CONTAINS OUR DESTINATION LINK ADDRESS
LDPRLN::POINT	10,LDBREM+2(U),35	;LINE NUMBER AT REMOTE STATION
LDPELE::POINT	4,LDBREM+3(U),3		;2741 ELEMENT NUMBER
LDPDRQ::POINT	8,LDBREM+3(U),11	;NUMBER OF DATA-REQUESTS FROM REMOTE
LDPEPM::POINT	8,LDBREM+3(U),19	;SERIAL NUMBER OF LAST EPM FROM REMOTE
LDPRNN::POINT	16,LDBREM+3(U),35	;NUMBER OF NODE OWNING THIS TTY
LDPRNF::POINT	16,LDBREM+3(F),35	; SAME AS ABOVE, EXCEPT INDEXED BY "F"

LDPCHR::POINT	9,LDBREM+4(U),8		;IF LRLTTO =1, THIS CONTAINS THE NEXT
					; OUTPUT CHARACTER
LDPJOB::POINT	9,LDBREM+4(U),26	;POINTER TO JOB (ONLY FOR CONNECTS)
LDPDST::POINT	18,LDBVTQ(U),17		;"DELAYED" STATUS FOR VTM
>;END OF IFN FTNET
IFN FTMIC,<
LDP.OP:	POINT	7,LDBMIC(U),21		;OPERATOR CHARACTER
LDP.ER:	POINT	7,LDBMIC(U),28		;ERROR CHARACTER
LDPMJN::POINT	7,LDBMIC(U),35		;MIC MASTER JOB NUMBER
> ;END IFN FTMIC
LDPFWD:	POINT	9,LDBBKB(U),11		;BREAK FIELD WIDTH
LDPQOT::POINT	1,LDBBYT(U),^L<(L1LQOT)>;TTY QUOTE
LDPDTC:	POINT	CK.WID,LDBIST(U),17	;CHARACTER DEFERRED BY SETDCS
LDPDCS:	POINT	18,LDBIST(U),35		;SPECIAL INPUT STATE CODE
LDPUNP::POINT	8,LDBCHM(U),9		;TTY UNPAUSE CHARACTER
LDPESC::POINT	8,LDBCHM(U),17		;TTY ESCAPE CHARACTER
LDPSW1::POINT	8,LDBCHM(U),25		;SWITCH SEQUENCE ONE
LDPSW2::POINT	8,LDBCHM(U),33		;SWITCH SEQUENCE TWO
LDPSWI:	POINT	16,LDBCHM(U),33		;POINTER TO BOTH OF ABOVE
LDPLCP::POINT	1,LDBDCH(U),^L<(LDLLCP)>;LOCAL COPY BIT
LDPMXT:	POINT	8,LDBBY3(U),26		;AUTO-DISCONNECT MAX. IDLE TIME
LDPTMR:	POINT	9,LDBBY3(U),35		;COUNT-UP TIMER FOR AUTO-DISCONNECT
LDP8BI:	POINT	1,LDBDCH(U),^L<(LDL8BI)>;POINTER TO 8-BIT I/O BIT
LDPCNE::POINT	1,LDBDCH(U),^L<(LDLCNE)>;POINTER TO COMMAND-LEVEL NO ECHO BIT

;BITS TO BE CLEARED ON A 140 RESTART

LDIDCM:	XWD	ZZL,ZZR			;TO CLEAR BITS IN LDBDCH
	SUBTTL	DATA STRUCTURES -- TTY DEVICE DATA BLOCK (DDB)

;PROTOTYPE SCANNER DDB. REPLICATED BY ONCE. ONE FOR EACH JOB.

	$LOW
TTYLST::			;LABEL FOR FIRST TTY DDB IN CHAIN

SCNDDB::			;GLOBAL LABEL
PHASE 0

	SIXBIT	/TTY0/		;DEVNAM (PHYSICAL NAME)
	XWD	0,STTYBF+1	;DEVCHR. SIZE OF USER BUFFER
	0			;DEVIOS
	XWD	0,SCNDSP	;DEVSER
	XWD	DVTTY+DVIN+DVOUT,<<1_A>+<1_AL>+<1_A8>+<1_PIMMOD>+<1_I>>	;DEVMOD
	0			;DEVLOG (LOGICAL NAME)
	0			;DEVBUF
	0			;DEVIAD
	0			;DEVOAD
	0			;DEVSTS
	XWD	.TYTTY,0	;DEVSTA
	0			;DEVXTR
	0			;DEVEVM
	0			;DEVPSI
	0			;DEVESE
	0			;DEVHCW
	707000,,0		;DEVCPU
	0			;DEVISN	- SPACE HELD EVEN IF XMON OFF
	0			;DEVJOB
DDBLDB::!0			;DDBLDB LINKS TO THE LDB.
DEPHASE
XP SCNDDS,.-SCNDDB
	$HIGH
BYTCNT:	POINT	12,DEVOAD(F),12

;DATA WITHIN THE DDB

;USE OF DEVIOS

;LEFT HALF
XP TTYOUW,400000	;REMEMBERS THAT IF IN IOW, IT IS FOR OUTPUT, AS
			; OPPOSED TO INPUT. I.E., WHICH INT WAKES JOB
FRCEND==:200000		;IN IMAGE INPUT, FORCE END OF FILE DUE TO TIMING
IOLBKA==100000		;TEMP INTERNAL BIT TO PRESERVE BKA OVER ^C/CONT

;RIGHT HALF
IOSABS==2000		;BREAK ON CHARACTERS SPECIFIED IN BREAK MASK TABLE
IOSBKA==1000		;BREAK ON ALL CHARACTERS
IOSTEC==400		;SUPPRESS ECHO OF DOLLAR SIGN ON ALTMOD
IOSNEC==:200		;USER (E.G. LOGIN) SUPPRESSING ECHO
IOSFCS==100		;USER WANTS ALL CHARACTERS.
	SUBTTL	TRANSMIT INTERRUPT ROUTINE

;ENTRY FROM DEVICE-DEPENDENT INTERRUPT SERVICE ROUTINE ON A
; TRANSMIT-DONE INTERRUPT. THE HARDWARE LINE NUMBER IS
; IN AC U.  ENTER AT XMTIN1 IF U IS SETUP TO THE LDB ADDRESS.


XMTINT::MOVE	U,LINTAB##(U)	;GET LINE DATA BLOCK ADDRESS
XMTIN1::SE1ENT			;ENTER SECTION 1
	MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	LDBDCH(U)	;ARE WE EXPECTING THIS?
	JRST	XMTDMC		;NO, GO UNLOCK KEYBOARD
	PUSHJ	P,XMTCHR	;GET A CHARACTER FROM THE CHUNKS
	  POPJ	P,		;END OF STRING
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR SINCE JUST SENT A CHARACTER
	MOVEI	T1,ISRTYP	;FUNCTION DESIRED FROM DEVICE DRIVER
	PJRST	@LDBISR(U)	;GO DO IT
;XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM
;	   A TERMINAL OUTPUT BUFFER
;
;CALL
;	MOVE	U,LDB ADDRESS
;	PUSHJ	P,XMTCHR
;	  <IDLE CONDITION>
;	<CHARACTER IN T3>

XMTCHR::SE1ENT			;ENTER SECTION 1
	MOVSI	T1,LDLIDL	;CLEAR THIS NOW, XMTIDL WILL SET IF NEEDED
	ANDCAM	T1,LDBDCH(U)	;DON'T LET REMOTES ECHO
XMTCH1:	SKIPE	T1,LDBOST(U)	;GET STATES WORD
	JFFO	T1,[JRST @XMTDSP(T2)] ;DISPATCH ON SPECIAL CONDITIONS
XMTCH2:	SCNOFF			;NO INTERRUPTS WHILE TAKING CHARACTERS
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN LENGTH OF OUTPUT STREAM
	JRST	ZAPBUF		;IF EMPTY STREAM.  GO RESET COUNT
	LDCHKR	T3,LDBTOT(U),XMTABO  ;TAKE NEXT CHARACTER FROM STREAM
	PUSHJ	P,TPCOUT	;FUDGE FOR TWO-PART CHARACTERS
XMTCH3:	SCNON			;HAVE CHARACTER, ALLOW OTHERS TO ACCESS
XMTCH5:	CAIN	T4,^D50		;HAVE WE REACHED THE WAKE THRESHOLD?
	PUSHJ	P,XMTWAK	;YES, GO WAKE JOB IF WAITING
XMTCH4:	TRNE	T3,CK.MET	;IS THIS A META CHARACTER?
	JRST	XMTMET		;YES, GO DISPATCH THE FUNCTION
	TRNE	T3,CK.IMG	;IS THIS AN IMAGE MODE CHARACTER?
	JRST	XMTCN7		;YES, COUNT IT AND RETURN
	ANDI	T3,CK.CHR	;CLEAR POSSIBLE PARITY BIT
	SKIPGE	T1,CHTABL(T3)	;GET SPECIAL BITS, TEST FOR UNUSUAL CHAR
	JRST	XMTSPO		;THIS MAY REQUIRE FILL OR BLANK SUPPRESS
	AOSG	LDBHPS(U)	;INCREMENT HORIZONTAL POSITION
	JRST	XMTCN7		;RETURN IF NOT END OF CARRIAGE
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	XMTCN7		;NO FREE CRLF FOR LOG FILES
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	XMTCN7		;NO, JUST SEND THE CHARACTER
	TLZ	T1,CHALT!CHUAE!CHCRE  ;OUTPUT CHARACTERS GO STRAIGHT
	TLO	T1,CHFILO	;OUTPUT FILL
	PUSHJ	P,SETCRF	;YES, GO SETUP A CRLF FILLER
	  JRST	XMTCH1		; AND SEND THE FILLER INSTEAD
	JRST	XMTCN7		;GO SEND THE CHARACTER AFTER ALL!
;COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN

XMTCNT:	CAIN	T3,12		;LINEFEED?
	PUSHJ	P,INCPCT	;BUMP PAGE COUNTER

XMTCN4:	ANDI	T3,CK.CHR!CK.IMG ;TRIM OFF FUNNY BITS
XMTCN7:
IFN	FTMIC,<
	MOVE	T4,LDBMIC(U)	;GET MIC BITS
	TLNE	T4,LDLSIL	;LINE SILENCED
	JRST	XMTCH1		;YES, EAT THE CHARACTER
>
XMTCN8:	AOS	LDBOCT(U)	;COUNT CHARACTERS OUTPUT THIS LINE
	AOS	%SCNXI		;AND TOTAL CHARACTERS OUTPUT BY SYSTEM
IFN FTRSP,<AOS	.CPNXI##>	;PER CPU AS WELL
	PJRST	CPOPJ1##	;RETURN THE CHARACTER


;HERE FOR UNUSUAL CHARACTER ON OUTPUT

XMTSPO:	MOVSI	T2,LPLBLK
	TDNE	T2,LDBPAG(U)
	PUSHJ	P,BLSUPO	;CHECK FOR TERMINAL NO BLANKS

	PUSHJ	P,ADJHP
	PUSHJ	P,SETFLO	;SETUP FILLERS IF ANY NEEDED
	  JRST	XMTCH1		;FILLS NEEDED, GO SEND THEM FIRST
	CAIN	T3,12		;IF LINE FEED
	PUSHJ	P,INCPCT	; INCREMENT PAGE COUNT
	JRST	XMTCN7		;NONE NEEDED, JUST RETURN IT
;HERE WHEN AN IMBEDDED FUNCTION (META) CHARACTER IS FOUND IN THE OUTPUT STREAM
;TO DISPATCH UPON IT AND RETURN VIA SETCHP

XMTMET:	TRNE	T3,CK.NIS	;IS THIS REALLY HERE?
	JRST	XMTCH1		;NO, SKIP IT
	CAIL	T3,CK.MET	;IS THIS IN RANGE?
	CAIL	T3,CK.MET+METLEN ;BOTH WAYS?
	JRST	XMTCH1		;NO, SKIP IT ** MAYBE STOPCD HERE? **
	PUSHJ	P,XMTME1	;CALL WORKHORSE (FOR SAVING ACS)
	  JRST	SETCHP		;GIVE NON-SKIP AFTER REQUEUEING LINE
	JRST	XMTCH1		;KEEP LOOKING FOR A CHARACTER

XMTME1:	PUSHJ	P,SAVE2##	;PRESERVE OUR REGISTERS
	MOVE	P1,METABL-CK.MET(T3)	;GET DISPATCH VALUE
	TLNN	P1,CH2PC	;NEED AN ARGUMENT?
	PJRST	(P1)		;NO, JUST DISPATCH IT
	SCNOFF			;FOR LDCHK'ING
	SOSGE	LDBTOC(U)	;IS THE ARGUMENT STILL THERE?
	JRST	ZAPBUF		;NO, GIVE UP
	LDCHKR	P2,LDBTOT(U),XMTABO	;YES, GET IT
	SCNON			;CAN ALLOW OTHERS AGAIN
	PJRST	(P1)		;NOW CALL THE ROUTINE (AND RETURN A LEVEL)

;ROUTINE TO SET USER'S VALUE OF LDLNFC DURING OUTPUT

METNFC:	DPB	P2,LDPNFC	;STORE IN LDB
	POPJ	P,		;GIVE SETCHP RETURN

;ROUTINE TO SET USER'S VALUE OF HPOS DURING OUTPUT

METHPS:	LDB	T2,LDPWID	;GET CARRIAGE WIDTH
	SUB	T2,P2		;FORM COLUMNS TO GO UNTIL RIGHT MARGIN
	MOVNM	T2,LDBHPS(U)	;STORE AS COUNT UP VALUE
	POPJ	P,		;GIVE SETCHP RETURN

;ROUTINE TO FORCE LEFT MARGIN DURING OUTPUT

METFLM:	PUSHJ	P,HPOS		;GET HPOS
	JUMPE	T2,CPOPJ1##	;DONE IF ALREADY THERE
	AOS	(P)		;SET FOR SKIP RETURN
	PJRST	METNLF		;ELSE, TYPE OUT A NEWLINE

;ROUTINE TO SET L1LDEM

METDEN:	SKIPA	T2,[IORM T1,LDBBYT(U)]	;INSTRUCTION TO SET THE BIT
METDEF:	MOVE	T2,[ANDCAM T1,LDBBYT(U)] ;INSTRUCTION TO CLEAR IT
	SCNOFF			;FIGHT RACES
	MOVSI	T1,L1LDEM	;THE BIT IN QUESTION
	XCT	T2		;SET OR CLEAR AS REQUESTED
	SCNON			;ALLOW OTHERS AGAIN
	JRST	XMTECD		;DELETE CHARACTER AND GET ANOTHER TO ECHO

;ROUTINE TO CALL SETCHP SYNCHRONOUSLY WITH OUTPUT

METCHP:	MOVSI	T1,LDLIDL	;GET IDLE BIT
	IORM	T1,LDBDCH(U)	;LIGHT IT SO FE'S WILL CALL US AGAIN
	PJRST	SETCHP		;RE-QUEUE LINE & RETURN NON-SKIP FROM XMTCHR

;ROUTINE TO START UP A CONTROL-R (RE-TYPE) FOR XMTECH

METRTS:	PUSHJ	P,METRT1	;CALL WORKHORSE
	JRST	XMTCH1		;LOOK FOR MORE OUTPUT
METRT1:	PUSHJ	P,SAVE3##	;NEED SOME EXTRA ACS
	TRC	T3,MC.RTS^!MC.RTE	;ALTER THE CHARACTER
	DPB	T3,LDBECT(U)	;SAVE FOR TURNING OFF ^R MODE WHEN DONE
	SETZB	P1,P2		;CLEAR COUNTS OF CHARACTERS PASSED
	SKIPN	T4,LDBBKU(U)	;POINT TO LAST LINE BREAK
	MOVE	T4,LDBTIT(U)	;OR BEGINNING IF NO BREAK
	MOVE	P3,T4		;SAVE BEGIN POINTER
	EXCH	T4,LDBECT(U)	;RESET TAKER, GET STOP POINTER
METRT2:	CAMN	T4,LDBECT(U)	;HAVE WE CAUGHT UP?
	JRST	METRT3		;YES, CLEAN UP
	LDCHK	T3,LDBECT(U),SONPJ1 ;GET A CHARACTER
	TRNE	T3,CK.NIS	;IF MISSING,
	AOS	P2		;COUNT ANOTHER INVISIBLE
	AOS	P1		;AND ANOTHER CHARACTER IN ANY CASE
	JRST	METRT2		;LOOP OVER ALL CHARACTERS TO BE RETYPED
METRT3:	MOVEM	P3,LDBECT(U)	;RESET ECHO TAKER AGAIN
	ADDM	P1,LDBECC(U)	;COUNT HOW MANY CHARACTERS TO RE-ECHO
	ADDM	P2,LDBIEC(U)	;AND HOW MANY WERE INVISIBLE
	MOVNS	P1		;NEGATE BECAUSE SUBM GOES WRONG WAY FOR THIS
	MOVNS	P2		; ...
	ADDM	P1,LDBTIC(U)	;THIS MANY FEWER FOR READ-IN
	ADDM	P2,LDBIIC(U)	;AND SIMILARLY FOR HOW MANY ARE INVISIBLE
	MOVSI	T1,LDLCRP	;CONTROL-R PENDING BIT
	IORM	T1,LDBDCH(U)	;LIGHT IT FOR TYICC4 & XMTECH
	SCNON			;SAFE TO ALLOW OTHERS NOW
	PUSHJ	P,PRSKL		;SPACE OVER PROMPT AND CLEAR THE LINE
	  JRST	METRT4		;NOT A DISPLAY, DO IT THE OLD WAY
	MOVEI	T3,MC.CHP	;SET TO TELL FE'S ABOUT HPOS
	PJRST	SETFCE		;STUFF IN FILL CHUNKS AND RETURN

METRT4:	MOVE	T2,FLLBSC	;BACKSLASH-THEN-CRLF
	MOVSI	T1,L2LDEL	;DELETE SEQUENCE BIT
	TDNN	T1,LDBBY2(U)	;WAS THERE AN OPENING BACKSLASH?
	IBP	T2		;NO, DON'T TYPE A CLOSING ONE
	ANDCAM	T1,LDBBY2(U)	;MAKE SURE FOR LATER
	PJRST	SETFLE		;STUFF THE SEQUENCE IN THE CHUNKS & GO

;ROUTINE TO SHUT OFF CONTROL-R PROCESSING FOR TYICC4 & XMTECH

METRTE:	MOVSI	T1,LDLCRP	;CONTROL-R PENDING BIT
	ANDCAM	T1,LDBDCH(U)	;CLEAR IT
	MOVEI	T3,"R"-100	;THIS WAS A CONTROL-R
	PJRST	XMTECD		;CHANGE TO DELETED CHARACTER AND TRY FOR XMT'S
;HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB.  THESE BITS
;ARE PLACED IN LDBOST IN SUCH A WAY THAT A JFFO INSTRUCTION CAN
;BE USED TO FIND THE CONDITION THAT NEEDS ATTENTION FIRST.

;HERE TO TYPE XOFF/XON STRINGS
XMTXFP:	ILDB	T3,LDBXNP(U)	;GET NEXT CHARACTER FROM XON/XOFF FILL POINTER
	JUMPN	T3,XMTCN8	;RETURN IT IF IT'S THERE
	MOVSI	T3,LOLXFP	;NO, GET BIT THAT BROUGHT US HERE
	ANDCAM	T3,LDBOST(U)	;CLEAR IT
	SETZM	LDBXNP(U)	;AND THE POINTER
	JRST	XMTCH1		;AND TRY AGAIN

;HERE TO TYPE A BELL (TTY SBELL OR INPUT LOST)
XMTNBS:	MOVSI	T3,LOLNBS	;CLEAR BIT THAT GOT US HERE
	ANDCAM	T3,LDBOST(U)	;IN THE LDB
	MOVEI	T3,007		;GET A BELL (SANS PARITY)
	JRST	XMTCN8		;AND RETURN IT

;HERE FOR ECHO/FILL OUTPUT TO BE TYPED
XMTESP:	SCNOFF			;NO INTERRUPTS FOR A FEW INSTRUCTIONS
	SOSGE	LDBEOC(U)	;COUNT ANOTHER ECHO OUTPUT
	JRST	XMTES1		;DO SANITY CHECK WHEN STREAM LOOKS EMPTY
	LDCHKR	T3,LDBEOT(U),XMTES2	;GET NEXT CHARACTER FOR ECHO
	PUSHJ	P,TPCFIL	;CHECK FOR FILL EXPANSION
XMTES0:	SCNON			;ALLOW INTERRUPTS AGAIN
	TRNN	T3,CK.MET	;UNLESS A FUNCTION CHARACTER
	JRST	XMTCNT		;COUNT IT AND RETURN
	MOVE	T1,T3		;YES, COPY IT
	ANDI	T1,CK.CHR	;KEEP ONLY THE FUNCTION INDEX
	MOVE	T1,METABL(T1)	;GET THE DISPATCH
	PJRST	(T1)		;CALL THE FUNCTION

XMTES1:	SETZM	LDBEOC(U)	;DON'T GO NEGATIVE
	MOVE	T3,LDBEOT(U)	;GET TAKER
	CAME	T3,LDBEOP(U)	;MUST MATCH PUTTER
	PUSHJ	P,RCDSTP	;ERROR IF NOT EQUAL
XMTES2:	MOVSI	T3,LOLESP	;CLEAR BIT THAT GOT US HERE
	ANDCAM	T3,LDBOST(U)	;IN THE LDB
	SCNON			;ALLOW INTERRUPTS AGAIN
	JRST	XMTCH1		;TRY FOR NEXT CHARACTER

;HERE FOR 'NOT NOW' OUTPUT
XMTNNP:	ILDB	T3,LDBNNP(U)	;GET NEXT CHARACTER FROM FILL POINTER
	CAILE	T3,FLLFLG	;IS IT A REAL CHARACTER
	JRST	XMTCH4		;YES, USE IT
	SCNOFF			;AVOID RACES
	MOVSI	T2,LOLNNP	;CLEAR BIT THAT BROUGHT US HERE
	ANDCAM	T2,LDBOST(U)	;FROM THE LDB
	SETZM	LDBNNP(U)	;AND THE BYTE POINTER
	SCNON			;END OF POSSIBLE RACE
	JUMPE	T3,XMTCH1	;TRY AGAIN IF END OF STRING
	PUSHJ	P,METNLF	;TYPE CRLF IF WAS FILLER FLAG
	JRST	XMTCH1		;THEN TRY AGAIN

;HERE TO RE-EAT OUTPUT
XMTREO:	SCNOFF			;FIGHT RACES
	MOVSI	T1,LOLREO	;BIT THAT BROUGHT US HERE
	ANDCAM	T1,LDBOST(U)	;CLEAR IT
	LDB	T3,LDBTOT(U)	;GET CHARACTER TO RE-DO
	SCNON			;ALLOW OTHERS AGAIN
	PJRST	XMTCH4		;AND USE IT AGAIN

;HERE TO RE-EAT ECHO
XMTREE:	SCNOFF			;FIGHT RACES
	MOVSI	T1,LOLREE	;BIT THAT BROUGHT US HERE
	ANDCAM	T1,LDBOST(U)	;CLEAR IT
	LDB	T3,LDBECT(U)	;GET CHARACTER TO RE-DO
	MOVE	T1,T3		;COPY CHARACTER
	ANDI	T1,CK.CHR	;MASK DOWN
	MOVE	T1,CHTABL(T1)	;GET BITS
	SCNON			;ALLOW OTHERS AGAIN
	PJRST	XMTEC4		;AND USE CHARACTER AGAIN

;HERE FOR FORCED STRING OUTPUT (USED ONLY BY SEND ALL)
XMTFSP:	ILDB	T3,LDBFLP(U)	;GET NEXT CHARACTER FROM FILL POINTER
	CAILE	T3,FLLFLG	;IS IT A REAL CHARACTER?
	JRST	XMTCH4		;YES, USE IT
	SCNOFF			;AVOID RACES
	MOVSI	T2,LOLFSP!LOLSAP ;CLEAR BITS THAT BROUGHT US HERE
	ANDCAM	T2,LDBOST(U)	;FROM THE LDB
	SETZM	LDBFLP(U)	;AND THE BYTE POINTER
	SCNON			;END OF POSSIBLE RACE
	JUMPE	T3,XMTCH1	;IF NULL, JUST TRY FOR NEXT CHARACTER
	PUSHJ	P,METNLF	;TYPE A CRLF VIA THE ECHO STREAM
	MOVEI	T3,"."		;GET A DOT JUST IN CASE
	MOVSI	T2,LDLCOM	;COMMAND LEVEL BIT	
	TDNE	T2,LDBDCH(U)	;USER AT COMMAND LEVEL?
	PUSHJ	P,SETFCE	;YES, TYPE THE DOT AS WELL
	JRST	XMTCH1		;TRY FOR NEXT CHARACTER TO OUTPUT

;HERE WHEN NEW SEND ALL STRING TO BE SENT (COMCON HAD TO DEFER THE SEND)
XMTSAP:	SCNOFF			;AVOID RACES
;	MOVSI	T2,LOLSAP	;CLEAR BIT THAT BROUGHT US HERE
;	ANDCAM	T2,LDBOST(U)	;FROM THE LDB
	SOSGE	SNDCTR##	;ONE FEWER LINE WAITING
	SETZM	SNDCTR##	;DON'T LET THE COUNT GO NEGATIVE!
	MOVE	T2,SNDPTR##	;GET FILL POINTER FROM COMCON
	PUSHJ	P,SETFPT	;SET THE FILL POINTER (DOES A SCNON)
	JRST	XMTCH1		;AND TYPE FROM THE FILL POINTER


...OST==1B0	;START OF STATE BITS

DEFINE	OSTAT(NM,RTN)<
	XP LOL'NM,(...OST)
	...OST==...OST_-1
IFB<RTN>,<	IFIW	XMT'NM>
IFNB<RTN>,<	IFIW	XMT'RTN>
IF1,<IFG 1B17-...OST,<PRINTX % LDBOST LH IS FULL WITH LOL'NM>>
>

XMTDSP:
	OSTAT	XFP		;XOFF PENDING
	OSTAT	NBS		;NEED BELL SENT
	OSTAT	ESP		;ECHO STREAM PENDING
	OSTAT	FSP		;FORCED STRING PENDING
	OSTAT	SAP		;SEND ALL PENDING
	OSTAT	STP,IDL		;XOFF ON LINE
	OSTAT	SSO,IDL		;SCNSER STOPPED OUTPUT
	OSTAT	NNP		;'NOT NOW' POINTER
	OSTAT	REO		;RE-EAT OUTPUT
	OSTAT	REE		;RE-EAT ECHO
	OSTAT	PIM		;IN PIM MODE
	OSTAT	MIC		;CONTROLLED BY MIC
;HERE WHEN CHUNKS MESSED UP, TIME TO IDLE THE LINE

XMTABO:	SCNON			;RELEASE TERMINAL SERVICE INTERLOCK

;HERE TO IDLE THE LINE SINCE IT HAS NO MORE CHARACTERS LEFT TO OUTPUT

XMTIDL:	MOVSI	T1,LDLIDL	;LINE IS IDLE BIT
	IORM	T1,LDBDCH(U)	; SET IN LDB
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	; CLEAR
	HRRZ	F,LDBDDB(U)	;ADDRESS OF LINKED DDB
	JUMPE	F,CPOPJ##	;JUMP IF NO DDB
	PUSH	P,J		;SAVE J
	LDB	J,PJOBN##	;GET JOB NUMBER
	MOVE	T1,JBTSTS##(J)	;GET JOB STATUS
	TRNE	T1,JS.NTO	;HIBERING FOR NON-BLOCKING TTY OUTPUT?
	PUSHJ	P,WAKEJB##	;YES--WAKE HIM UP
	POP	P,J		;RESTORE J

XMTDMC:	HRRZ	F,LDBDDB(U)	;IF NO DDB ALL DONE
	JUMPE	F,CPOPJ##	;IF NO DDB.

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

XMTWAK:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE
	PJRST	VTMENQ##	;  QUEUE THE LINE SO WE SEND MORE DATA-REQUESTS
>
IFN FTMIC,<
	SKIPN	T1,LDBMIC(U)	;CONTROLLED BY MIC?
	JRST	XMTWK1		;IF NOT
IFN FTMLOG,<
	TLNE	T1,LDLLOG	;LOGGING
	PUSHJ	P,MLOGOF	;TIDY UP
> ;END IFN FTMLOG
	PUSHJ	P,MICWAK	;WAKE MIC
> ;END IFN FTMIC
XMTWK1:	HRRZ	F,LDBDDB(U)
	JUMPE	F,CPOPJ##
	MOVE	S,DEVIOS(F)
	TLNE	S,IOW		;IO WAIT?
	JUMPL	S,TTWAKE	;IF OUTPUT, GO WAKE JOB
	POPJ	P,		;IF INPUT, RETURN
;PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT.

XMTPIM:	SCNOFF
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN
	PJRST	ZAPPI1		;IF EXHAUSTED
	LDCHKR	T3,LDBTOT(U),XMTABO  ;TAKE A CHARACTER, RETURN STALE CHUNKS
	SCNON			;ALLOW INTERRUPTS
	CAIN	T4,^D50		;IF LESS THAN 50. CHARS LEFT
	PUSHJ	P,XMTWAK	;WAKE UP THE ATTACHED JOB
	TRNE	T3,CK.MET	;IF META,
	JRST	XMTMET		;THEN DO THE FUNCTION
	JRST	XMTCN7		;ELSE, COUNT AND RETURN THE CHARACTER

;HERE WHEN THE OUTPUT STREAM COUNT IS EXHAUSTED.  RESET IT TO ZERO
;AND SET THE LINE IDLE.  COME HERE ONLY WITH SCANNER INTERLOCK SET.

ZAPPI1:	SETZM	LDBTOC(U)	;COUNT IS PROBABLY NEGATIVE NOW
	MOVE	T2,LDBTOT(U)	;MAKE SURE PUTTER MATCHES TAKER
	CAME	T2,LDBTOP(U)	;MAKE SURE BOTH POINTERS MATCH
	PUSHJ	P,RCDSTP	;NO, DIE NOW
	SCNON			;ALLOW INTERRUPTS AGAIN
	PJRST	XMTIDL		;IDLE THE LINE
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO

XMTMIC:
IFN FTMIC,<			;IF MIC
IFN FTMLOG,<
	MOVE	T2,LDBMIC(U)
	TLNE	T2,LDLLOG	;HAS HE ASKED FOR LOG
	SKIPE	LDBLOT(U)	;HAS HE GOT A LOG TAKER
	JRST	MICLG3
	MOVE	T2,LDBTOT(U)	;MAKE COPY OF TAKER
	MOVEM	T2,LDBLOT(U)
MICLG3:
> ;END OF FTMLOG CONDITIONAL
	PUSHJ	P,HPOS		;GET HORZONTAL POSITION ON LINE
	JUMPN	T2,XMTOK	;IN COLUMN 1?
	SKIPE	T2,LDBMIC(U)	;IS HE RUNNING MIC OR
	TLNN	T2,LDLRSP!LDLRSY	;WANTS RESPONSE FEATURE
	JRST	XMTOK1		;NO - MUST NOT INTERFERE
	TLNE	T2,LDLERC	;HAS HE HAD ERROR?
	TLNE	T2,LDLMCC	;AND NOT ^C
	JRST	XMTOK1		;NO - IGNORE
	SKIPN	LDBTOC(U)	;IS THERE A CHARACTER WAITING?
	JRST	XMTOK1		;NO, IGNORE
	MOVE	T4,LDBTOT(U)	;COPY OF OUTPUT TAKER
	SCNOFF			;PROTECT CHUNK STREAM
	LDCHK	T3,LDBTOT(U),XMTABO	;PREVIEW NEXT CHARACTER
	MOVEM	T4,LDBTOT(U)	;RESTORE POINTER
	SCNON			;SAFE NOW
	LDB	T2,LDP.ER	;GET ERROR CHAR
	JUMPE	T2,XMTOK	;MUST BE ONE
	ANDI	T3,CK.CHR	;JUST 7 BITS
	CAIE	T3,"?"		;IS IT A "?"
	CAMN	T3,T2		; OR THE ERROR CHARACTER
	CAIA			;YES, HANDLE MIC'S RESPONSE
	JRST	XMTOK		;NO IGNORE
	MOVSI	T2,LDLRSY!LDLCHK;SET THE SYNC
	IORB	T2,LDBMIC(U)
	TLNN	T2,LDLRSP	;BEEN THIS WAY BEFORE
	JRST	XMTECH		;YES JUST DO ECHOING
	HRRZ	F,LDBDDB(U)
	JUMPE	F,XMTECH	;NO ATTACHED DDB
	MOVE	S,DEVIOS(F)
	MOVE	T2,LDBDCH(U)	;GET WORD WITH COMMAND WAIT BIT
	TLNN	S,IOW		;IN IO WAIT?
	TLNE	T2,LDLCOM	;OR IN COMMAND WAIT
	SKIPA			;YES TO EITHER
	JRST	XMTECH		;NO FORGET IT
	MOVSI	T2,LDLRSP
	ANDCAM	T2,LDBMIC(U)	;SAY SYNC
	PUSHJ	P,MICWAK
	JRST	XMTECH		;AND PUT THE PLUG IN
XMTOK:	MOVE	T2,LDBMIC(U)	;GET MIC BITS
XMTOK1:	TLNE	T2,LDLRSY	;WAITING FOR MIC TO TAKE RESPONCE
	JRST	XMTECH		;YES, KEEP THE PLUG IN

IFN FTMLOG,<
	SKIPN	LDBLOT(U)	;ARE WE LOGGING THIS?
	JRST	XMTCH2		;NO, GO TAKE CHARACTER NORMALLY
	SCNOFF			;NO INTERRUPTS
	SOSGE	LDBTOC(U)	;DECREMENT COUNT OF CHARACTERS AND TEST
	JRST	ZAPBUF		;IF OUTPUT STREAM NOW EMPTY
	LDCHK	T3,LDBTOT(U),XMTABO  ;TAKE A CHARACTER OUT OF THE STREAM
	AOS	LDBLOC(U)	;COUNT UP THE NUMBER TO BE LOGGED
	JRST	XMTCH3		; AND JOIN PROCESSING
> ;END IFN FTMLOG
> ;END OF IF MIC

;ENTER HERE WITH SCNOFF TO CLEAR LDBTOC AND CHECK FOR ECHO

ZAPBUF:	SETZM	LDBTOC(U)	;ZERO COUNT
	MOVE	T1,LDBTOP(U)	;GET PUTTER
	CAME	T1,LDBTOT(U)	;MUST MATCH TAKER
	PUSHJ	P,RCDSTP	; OOPS, SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE,
	PUSHJ	P,VTMENQ##	;  WE MUST BE SURE TO SEND DATA-REQUESTS
>				;  NOW THAT WE'RE OUT OF DATA.
	JRST	XMTECH		;LOOK FOR SOMETHING TO ECHO
;HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO
;NEED TO ECHO A CHARACTER THAT HAS BEEN TYPED IN.

XMTECH:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE
	JRST	XMTIDL		;  DON'T TRY TO ECHO ANYTHING.
>				;  THE CHUNKS ARE HORRIBLY MESSED UP.
	MOVE	T1,LDBDCH(U)	;SEE IF SHOULD DEFER ECHOING
	TLNE	T1,LDLCRP	;CONTROL-R SYNCH BIT SET?
	JRST	ECHCNR		;YES, GO CHECK OUT ^R THINGS
	MOVE	T1,LDBBYT(U)	;NO, GET WORD CONTAINING DEFERRED ECHO BITS
	TLNN	T1,L1LDEM	;IF NOT IN LH DEFERRED ECHO,
	TRZ	T1,L1RDEM	;THEN GIVE RH BIT TIME TO CATCH UP TO US
	SKIPL	LDBBKB(U)	;IF BREAK SET SPECIFIED, ALWAYS DEFERRED ECHO
	TRNE	T1,L1RDEM	;DEFERRED ECHO MODE SELECTED?
	TRNE	T1,L1RDEL!L1RDEC; HAS AN INPUT REQUEST BEEN MADE YET?
	TLNE	T1,L1LUNR	;AND NOT BLOCKED BY UNREAD?
	JRST	XMTIDL		;DEFERRED AND NOT REQUESTED YET
ECHCNR:	SCNOFF			;DISALLOW INTERRUPTS
	SOSGE	LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	ZAPECH		;NO, FINISH UP
	LDCHK	T3,LDBECT(U),XMTABO  ;TAKE CHARACTER FROM INPUT, SAVE CHUNKS
	TRNE	T3,CK.NIS	;INIVISIBLE CHARACTER?
	JRST	[SOS	LDBIEC(U) ;YES, COUNT ONE LESS TO ECHO
		 AOS	LDBIIC(U) ;AND ONE MORE FOR INPUT
		 JRST	XMTECI]	;REJOIN MAIN STREAM
	MOVE	T1,T3		;COPY CHARACTER
	ANDI	T1,CK.CHR	;MASK IT DOWN
	CAIN	T1,40		;A SPACE?
	PUSHJ	P,XMTACR	;YES, CHECK OUT ACR CONDITION
	PUSHJ	P,TPCECH	;SEE IF NEED TO DO EXPANSION AT THIS LEVEL
XMTECI:	MOVE	T2,LDBECT(U)	;GET ECHO TAKER
	CAMN	T2,LDBBKI(U)	;TAKING LAST BREAK?
	SETZM	LDBBKI(U)	;YES, ZAP ITS POINTER
	AOS	T2,LDBTIC(U)	;COUNT THE INPUT CHARACTERS
XMTECX:	SCNON			;ALLOW INTERRUPTS
	TRNE	T3,CK.NIS	;IS THIS STILL A REAL CHARACTER?
	JRST	XMTCH1		;NO, TRY AGAIN
	AOS	%SCNEI		;COUNT CHARACTERS ECHOED
IFN FTRSP,<AOS	.CPNEI##>	;PER CPU AS WELL
	MOVE	T4,LDBBYT(U)	;GET WORD WITH ECHO BITS AGAIN
	TRNE	T3,CK.MET	;IF NOT AN IMBEDDED FUNCTION, AND
	JRST	XMTECE		;NO, DON'T WORRY ABOUT RECEIVE ROUTINES
	PUSHJ	P,SPCHEK	;YES, GET THE CHARACTER'S CONTROL BITS
	  JRST	XMTECU		;NOT SPECIAL, GO CHECK FOR LDLLCT
	TLNE	T1,CHRIA	;DOES THIS CHARACTER HAVE A RECEIVE ROUTINE?
	TLNE	T1,CHNDFR	;AND WAS IT DEFERRED?
	JRST	XMTECE		;NO TO EITHER, DON'T CALL ITS PREPROCESSOR
	PUSHJ	P,(T1)		;YES, CALL ITS PROCESSOR NOW
	  JRST	XMTECD		;IT DIDN'T WANT TO BE STORED, GO DELETE IT
	SCNOFF			;DON'T ALLOW OTHERS IN THE CHUNKS
	DPB	T3,LDBECT(U)	;STORE THE (POSSIBLY CHANGED) CHARACTER
	PUSHJ	P,TPCECH	;CHECK FOR EXPANSION (AGAIN)
	SCNON			;ALLOW OTHERS AGAIN
	JRST	XMTECE		;IT WANTS TO BE KEPT, SO ECHO IT
XMTECU:	MOVE	T1,LDBDCH(U)	;GET BITS FOR TTY UC
	TRNN	T3,CK.IMG	;DON'T DO THIS IF IMAGE
	TLNN	T1,LDLLCT	;DOES USER WANT US TO RAISE CASE?
	JRST	XMTECE		;NO, JUST GO ECHO
	MOVE	T1,T3		;COPY CHARACTER
	ANDI	T1,CK.CH7	;QUICKLY MASK IT DOWN
	CAIGE	T1,140		;IS IT LOWER CASE?
	JRST	XMTECE		;NO, DON'T CHANGE IT
	TRC	T3,040		;YES, CHANGE ITS CASE
	DPB	T3,LDBECT(U)	;AND ALTER IT IN THE CHUNKS
XMTECE:	MOVSI	T1,LDLPPS	;PROMPT POS SET BIT
	TDNN	T1,LDBDCH(U)	;SET YET THIS LINE?
	JRST	[IORM	T1,LDBDCH(U)	;NO, BUT WE'RE ABOUT TO
		 MOVE	T1,T2	;SAVE INPUT COUNT
		 PUSHJ	P,HPOS	;GET CARRIAGE POSITION
		 DPB	T2,LDPPRP ;STORE AS PROMPT POSITION
		 MOVE	T2,T1	;RESTORE T2
		 JRST	.+1]	;REJOIN MAIN STREAM
	MOVEI	T4,L1RDEC	;CHARACTER REQUEST BIT
	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL.
	  JRST	XMTEC1		;NO, A SINGLE MUNDANE CHARACTER
	TRNE	T3,CK.MET	;IF AN IMBEDDED FUNCTION,
	JRST	(T1)		;GO DO IT
	TLNN	T1,CHBRK	;YES. IS IT A BREAK CHAR?
	JRST	XMTEC1		;NOT A BREAK
	SCNOFF			;FIGHT RACE
	MOVE	T4,LDBECT(U)	;GET CURRENT POINTER
	MOVEM	T4,LDBBKU(U)	;SAVE FOR BACK-UP LIMIT
	CAMN	T4,LDBBKI(U)	;LAST BREAK FROM OTHER SIDE?
	SETZM	LDBBKI(U)	;YES, FORGET ABOUT IT
	AOS	LDBBKC(U)	;COUNT LINES IN THE LDB
	AOS	LDBBCT(U)	;COUNT BREAK CHARACTERS INPUT
	SCNON			;ALLOW OTHERS AGAIN
	PUSHJ	P,CPRPOS	;CLEAR LDLPPS SO CAN GET NEW PROMPT POSITION
	MOVEI	T4,L1RDEC!L1RDEL;GET LINE REQUESTED BIT
XMTEC1:	ANDCAM	T4,LDBBYT(U)	;CLEAR, SINCE WE ECHOED A CHARACTER
	PUSH	P,T1		;SAVE CHARACTER BITS
	PUSH	P,T3		;AND CHARACTER
	MOVSI	T4,LDLBKA+LDLIMI;BREAK ON ALL CHARACTERS?
	TDNE	T4,LDBDCH(U)	; ..
	JRST	[PUSHJ	P,RCVWKQ	;YES, WAKE JOB
		 PUSHJ	P,CPRPOS	;CLEAR PROMPT POS AS IF BREAK
		 JRST	XMTEC2]		;AVOID EXTRA WAKE IF BREAK TOO
	PUSHJ	P,CHKTIB	;ARE THERE OVER 72. OF THEM?
	TLNE	T1,CHBRK	;OR IS IT A BREAK CHARACTER?
	PUSHJ	P,ECHBRK	;YES. WAKE THE JOB, IF ANY
XMTEC2: POP	P,T3
	POP	P,T1		;RESTORE CHARACTER BITS INTO T1
IFN FTMIC,<
	SKIPE	LDBMIC(U)	;IF MIC-CONTROLLED,
	PUSHJ	P,MICECH	;LET MIC KNOW ABOUT <CR> AND SUCH
>
	MOVSI	T2,LDLCRP	;ARE WE IN A CONTROL-R?
	TDNE	T2,LDBDCH(U)	;TEST
	JRST	XMTEC3		;YES, KEEP ECHOING
	TLNE	T1,CHBRK	;A BREAK?
	SKIPL	LDBBKB(U)	;AND A BREAK MASK SPECIFIED?
	CAIA			;NO TO EITHER
	JRST	XMTCH1		;BREAK CHARACTERS DON'T ECHO

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

XMTEC3:	TRNE	T3,CK.IMG	;IS IT IMAGE?
	TRNE	T3,CK.MET	;YES, BUT IS IT QUOTED?
	TRNA			;NO OR YES, KEEP GOING
	JRST	XMTEC7		;IMAGE, LEAVE ALONE
	MOVE	T2,LDBDCH(U)	;NO, GET LINE CHARACTERISTICS
	TLNE	T2,LDLNEC	;IS IT NON-ECHOING?
	TLNE	T2,LDLCRP	;AND NOT IN A CONTROL-R?
	TRNA			;NO, USE FILL
	JRST	XMTEC7		;YES, LEAVE ALONE
	TDNN	T2,[XWD LDLLCP,LDRHLF]	;LOCAL COPY?
	JRST	XMTEC4		;NO, COUNT UP NORMAL CHARACTER
	MOVEI	T2,L2RXON	;PAPER TAPE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	XMTEC7		;YES.  NO FILLERS, ELSE GARBLE.
XMTEC4:	MOVSI	T2,L2LDEL	;DELETE SEQUENCE BIT
	TDNE	T2,LDBBY2(U)	;BACKSLASH NEEDED?
	TLOA	T1,CHSPO!CHFIL	;YES, SAY FILL REQUIRED
	TLNE	T1,CHSPO	;SPECIAL CHARACTER OF SOME FLAVOR?
	JRST	XMTEC5		;YES, MORE EXTENSIVE HANDLING REQUIRED
	AOSG	LDBHPS(U)	;NORMAL CHARACTER, ECHO ONE CHAR POSITION
	JRST	XMTEC7		;GO DO IT
	SOS	LDBHPS(U)	;UNDO AOSG (ADJHP WILL RE-DO IT)
XMTEC5:	MOVSI	T2,LPLBLK	;THE SUPPRESS-BLANK-LINES BIT
	TDNE	T2,LDBPAG(U)	;"TTY NO BLANK" SET?
	PUSHJ	P,BLSUPI	;YES, NOTE PASSING <LF>S ET AL
	PUSHJ	P,ADJHP		;ADJUST CARRIAGE POSITION FOR ECHOED CHARACTER
	TRZ	T3,CK.MET!CK.IMG ;WE WANT TO SEE ECHOING CORRECTLY
	PUSHJ	P,SETFLI	;SET FILLERS FOR ECHOING
	  JRST XMTCH1		;OUTPUT FROM FILLER POSITION.

XMTEC7:	PUSHJ	P,ECHTST	;SEE IF CHARACTER NEEDS ECHOING
	  JRST	XMTCN4		;NOT ECHOED YET, RETURN IT
	JRST	XMTCH1		;ALREADY DONE, GET THE NEXT

;HERE TO DELETE AN INPUT CHARACTER AND TRY AGAIN
XMTECD:	TRO	T3,CK.NIS	;THIS IS NO LONGER A CHARACTER
	SCNOFF			;FIGHT RACES
	DPB	T3,LDBECT(U)	;FUDGE THE CHARACTER
	SKIPE	LDBTIC(U)	;UNLESS TSETBI'D
	AOS	LDBIIC(U)	;THERE'S ANOTHER ECHOED INVISIBLE CHARACTER
	SCNON			;ALLOW OTHERS AGAIN
	JRST	XMTCH1		;LOOK FOR ANOTHER CHARACTER TO SEND
;SUBROUTINE TO DETERMINE WHETHER CHARACTER NEEDS ECHOING
;RETURNS NON-SKIP IF NEEDS ECHO,
;SKIP RETURN IF NOT NEEDED

ECHTST:	MOVE	T1,LDBDCH(U)	;GET LEFT AND RIGHT HALF BITS
	TLNE	T1,LDLCRP	;ARE WE IN A CONTROL-R?
	POPJ	P,		;YES, ALL CHARACTERS ECHO
	TDNN	T1,[XWD LDLLCP,LDRHLF!LDR2741]	;NO, EITHER TYPE OF LOCAL COPY?
	JRST	ECHTS2		;NO, DO NORMAL CHECKS
IFN FTMIC,<
	SKIPE	T1,LDBMIC(U)	;RUNNING MIC?
	TLNE	T1,LDLMCB	;IN MIC BREAK?
	JRST	CPOPJ1##	;MIC BREAK AND LOCAL COPY, DON'T ECHO AGAIN
	JRST	ECHTS1		;NO, MIC CHARACTERS ALWAYS ECHO
> ;END IFN FTMIC
ECHTS2:
IFN FTNET,<
	TRNE	T3,CK.IMG	;IF IMAGE,
	JRST	ECHTS1		;THEN NO ECHO WAS DONE
	TRNE	T3,CK.FDE	;ONLY ECHO IF FRONT-END DIDN'T
	JRST	CPOPJ1##	;IF NOT VTM, DON'T ECHO, IF VTM, MUST ECHO HERE
> ;END IFN FTNET		;ECHO THE CHARACTER NOW
ECHTS1:	MOVE	T1,LDBDCH(U)	;BITS
	TLNN	T1,LDLCNE	;SKIP LEVEL CHECK IF NO-ECHO BY COMMAND
	TLNN	T1,LDLCOM	;CHARACTER ITSELF SHOULD BE ECHOED
	TLNN	T1,LDLNEC	;UNLESS USER LEVEL AND HE SAID NO
	POPJ	P,		;RETURN CHARACTER
	JRST	CPOPJ1##	;NO, STEP TO NEXT CHARACTER
;META-CHARACTER FUNCTION ROUTINES

;SUBROUTINE TO TYPE A CRLF VIA THE ECHO STREAM
METNLF:	MOVE	T2,FLLCRF	;GET CRLF FILL POINTER
	PJRST	SETFLE		;FORCE A CRLF TO BE OUTPUT

;ROUTINE TO ECHO A DELETE-LINE (^U) OPERATION
METDL:	PUSHJ	P,METDL1	;CALL WORKHORSE
	JRST	XMTCH1		;TYPE ANYTHING WE QUEUED UP
METDL1:	PUSHJ	P,SAVE4##	;PRESERVE A FEW
	MOVSI	T1,L2LDEL	;BACKSLASH BIT
	ANDCM	T1,LDBBY2(U)	;GET COMPLEMENT OF PREVIOUS STATE
	PUSH	P,T1		;SAVE IT FOR AFTER SETTING UP
	MOVEI	T3,CK.NIS+"U"-100	;REPLACE MC.DL WITH USED ^U
	PUSHJ	P,DELPRE	;PERFORM DELETION PREAMBLE
	POP	P,T1		;GET COMPLEMENT OF PREVIOUS L2LDEL SETTING
	ANDCAM	T1,LDBBY2(U)	;CLEAR IT IF IT WAS OFF BEFORE
	PUSHJ	P,PRSKL		;SKIP PROMPT AND KILL REST OF LINE
	  SKIPA	T3,["U"-100]	;NOT A DISPLAY, ECHO OLD WAY WITH ^U<CRLF>
	JRST	METDL2		;DONE WITH PROMPT, GO PERFORM DELETION
	PUSHJ	P,ECHTST	;OLD WAY, SEE IF WE WERE ECHOING
	  SKIPA	T2,FILXUP	;YES, GET POINTER TO \^U<CRLF>
	JRST	METDL2		;NO, DON'T BOTHER
	MOVSI	T1,L2LDEL	;THE BACKSLASH BIT
	TDNN	T1,LDBBY2(U)	;WAS IT ON?
	IBP	T2		;NO, DON'T NEED BACKSLASHES
	PUSHJ	P,SETFLE	;SEND ^U<CRLF>
METDL2:	CAIE	P1,DELEND	;DO WE OWN THE INPUT STREAM?
	JRST	METDL3		;NO, MUST DO THIS THE HARD WAY
	PUSHJ	P,RIDLN		;YES, JUST DUMP THE LINE
	JRST	METDL5		;AND GO HANDLE CLEAN-UP
METDL3:	PUSHJ	P,DELSFX	;FIND ANOTHER TO DELETE
	  JRST	METDL5		;DONE WITH THE LINE, GO CLEAN UP
	SCNOFF			;EXCLUDE OTHERS WHILE WE TWIDDLE CHUNKS
	SKIPLE	LDBTIC(U)	;AVOID CONFLICT WITH TSETBI
	PUSHJ	P,DELMID	;DELETE IT
	SCNON			;SAFE TO ALLOW OTHERS FOR A WHILE
	JRST	METDL3		;LOOP UNTIL THE LINE IS GONE
METDL5:	MOVSI	T1,L2LDEL	;GET DELETION BIT
	ANDCAM	T1,LDBBY2(U)	;DON'T CONFUSE ANYONE ELSE, WE'RE DONE
	MOVSI	T1,LDLVDC	;VISIBLE DELETE CHARACTER FLAG
	ANDCAM	T1,LDBTTW(U)	;YES, OUR DELETE WAS VISIBLE
	PJRST	DELFIN		;FINISH UP DELETION AND RETURN


;SUBROUTINE TO SKIP OVER THE PROMPT (IF ANY) AND KILL THE LINE
PRSKL:	PUSHJ	P,TTVID		;SEE IF A VIDEO TERMINAL
	  POPJ	P,		;NO, CAN'T DO IT
	HLRZ	T1,TCRTAB##+1(T1)	;GET ERASE TO EOL TABLE
	JUMPE	T1,CPOPJ##	;IF NOT THERE, CAN'T DO IT
	PUSH	P,T1		;SAVE TABLE ADDRESS
	PUSHJ	P,HPOS		;GET CURRENT POSITION
	LDB	T3,LDPPRP	;AND POSITION TO MATCH
	MOVSI	T1,LDLPPS	;PROMPT POS SET BIT
	TDNN	T1,LDBDCH(U)	;PROMPT FOUND FOR THIS LINE YET?
	CAIN	T2,(T3)		;AND POSITIONS DON'T MATCH?
	CAIA			;PROMPT IS OK
	SETZ	T3,		;NO, FAKE IT AS ZERO
	PUSH	P,T3		;SAVE COUNT OF POSITIONS TO SKIP
	MOVE	T1,-1(P)	;RETRIEVE TABLE ADDRESS
	MOVE	T2,(T1)		;GET <CR> POINTER
	PUSHJ	P,SETFLE	;AND PUT THAT IN THE CHUNKS
	PUSHJ	P,SCNBOL	;MAKE SURE AT LEFT MARGIN
	ADDM	T3,LDBHPS(U)	;ACCOUNT FOR CHARACTERS TO SKIP
PRSKL1:	SOSG	(P)		;AT LEAST ONE MORE TO SKIP?
	JRST	PRSKL2		;NO, FINISH UP
	MOVE	T1,-1(P)	;YES, GET TABLE ADDRESS
	MOVE	T2,1(T1)	;GET CURSOR RIGHT SEQUENCE
	PUSHJ	P,SETFLE	;ENTER IT INTO THE STREAM
	JRST	PRSKL1		;LOOP OVER PROMPT LENGTH
PRSKL2:	POP	P,T2		;RESTORE COUNT
	POP	P,T1		;AND TABLE ADDRESS
	SKIPN	T2		;IF ONE LEFT OF PROMPT POSITION
	SKIPA	T2,2(T1)	;YES, GET CURSOR RIGHT + KILL LINE
PRSKL3:	MOVE	T2,3(T1)	;NO, GET KILL LINE ONLY
	AOS	(P)		;SET UP SKIP RETURN FOR CALLER
	PJRST	SETFLE		;STORE STRING IN CHUNKS AND RETURN SUCCESS

;HERE TO DELETE A WORD (^W)
METDW:	MOVEI	T3,CK.NIS+"W"-100	;GET A USED ^W FOR REPLACEMENT
	PUSHJ	P,METDW1	;DELETE THE WORD
	JRST	XMTCH1		;AND TRY FOR ANOTHER CHARACTER
METDW1:	PUSHJ	P,SAVE4##	;PRESERVE OUR DISPATCH REGISTERS
	PUSHJ	P,DELPRE	;TAKE CARE OF DELETE CHARACTER PREAMBLE
	TLNN	T1,-1		;CAN WE ERASE TO EOL?
	JRST	METDW2		;NO, LEAVE ECHO DISPATCH ALONE
	MOVEI	P2,METDWE	;YES, USE DIFFERENT ECHO ROUTINE
	PUSHJ	P,SETFLC	;GET OUR FILLER CLASS
	MOVE	P3,FILLHP(T2)	;KEEP ITS FILL POINTER AROUND
METDW2:	PUSHJ	P,DELSFX	;ZAP ANY TRAILING NIS CHARACTERS
	  JRST	METDWX		;NOTHING TO DELETE
	CAIE	T3,11		;IS IT A TAB
	CAIN	T3,40		;OR A SPACE?
	JRST	[PUSHJ	P,DELONE	;YES, ZAP THE CHARACTER
		 JRST	METDW2]	;AND LOOP OVER TRAILING WHITESPACE
	TLNE	T1,CHPUNC	;IS IT ALPHANUMERIC?
	JRST	METDW4		;NO, GO TEST TERMINATION
METDW3:	PUSHJ	P,DELONE	;DELETE THE CHARACTER
	PUSHJ	P,DELSFX	;TRIM ANY NIS CHARACTERS
	  JRST	METDWX		;NOTHING MORE TO DELETE
	TLNN	T1,CHPUNC	;IF IT'S STILL ALPHANUMERIC,
	JRST	METDW3		;THEN KEEP DELETING FROM WORD
METDW4:	MOVSI	T2,LDLVDC	;VISIBLE DELETE CHARACTER FLAG
	TDNE	T2,LDBTTW(U)	;STILL ON?
	PUSHJ	P,DELONE	;YES, SO HAVEN'T DONE ANYTHING YET, GET THIS ONE
METDWX:	CAIE	P2,METDWE	;DID ECHO DELETION USE OUR SPECIAL ROUTINE?
	PJRST	DELFIN		;NO, GO FINISH UP
	PUSHJ	P,TTVID		;YES, GET CHARACTERISTICS AGAIN
	  TDZA	T2,T2		;CLEAR AC IF NONE
	HLRZ	T2,TCRTAB##+1(T1)	;OTHERWISE GET EOL TABLE ADDRESS
	MOVE	T2,3(T2)	;GET KILL TO EOL BYTE POINTER
	PUSHJ	P,SETFLE	;STORE IN ECHO/FILL STREAM
	PJRST	DELFIN		;NOW GO FINISH UP

;HERE TO DELETE A CHARACTER (BACKSPACE)
METBS:	MOVEI	T3,CK.NIS+"H"-100	;GET A USED BACKSPACE
	PUSHJ	P,METBS1	;CALL WORKHORSE ROUTINE
	JRST	XMTCH1		;AND TRY FOR MORE CHARACTERS TO OUTPUT
METBS1:	PUSHJ	P,SAVE4##	;PRESERVE OUR DISPATCH REGISTERS
	PUSHJ	P,DELPRE	;SETUP DELETE ROUTINE
	MOVEI	P2,METDWE	;USE BACKSPACING ECHO ROUTINE
	PUSHJ	P,SETFLC	;GET OUR FILL CLASS
	MOVE	P3,FILLHP(T2)	;AND SET BACKSPACE STRING FOR ECHO ROUTINE
	PJRST	METDC2		;NOW ACT LIKE RUBOUT

;HERE TO DELETE A CHARACTER (RUBOUT)
METDC:	MOVEI	T3,CK.NIS+177	;GET A USED RUBOUT
	PUSHJ	P,METDC1	;CALL WORKHORSE ROUTINE
	JRST	XMTCH1		;AND TRY FOR MORE CHARACTERS TO OUTPUT
METDC1:	PUSHJ	P,SAVE4##	;PRESERVE OUR DISPATCH REGISTERS
	PUSHJ	P,DELPRE	;SETUP DELETE AND ECHO ROUTINES
METDC2:	PUSHJ	P,DELSFX	;ZAP ANY NIS CHARACTERS
	  PJRST	DELFIN		;NOTHING TO DELETE
	PUSHJ	P,DELONE	;GOT ONE, DELETE IT
	PJRST	DELFIN		;CLEAN UP
;ECHO ROUTINES FOR DELETE WORD/CHARACTER

;SUBROUTINE TO USE BACKSPACES, MUST EVENTUALLY BE FOLLOWED BY AN ERASE TO EOL
METDWE:	MOVEI	T3,010		;LOAD A BACKSPACE
	PUSHJ	P,SETFCE	;SET FOR CHARACTER ECHO
	MOVE	T2,P3		;GET OUR BACKSPACE FILLER
	PUSHJ	P,SETFLE	;PUT INTO FILL/ECHO STREAM
	SOJG	P4,METDWE	;LOOP FOR WIDTH OF CHARACTER
	POPJ	P,		;RETURN TO DELONE

;SUBROUTINE TO USE TCRTAB BACKSPACE TABLE
METDCT:	HRRZI	T2,8(P3)	;COPY TABLE POINTER
	SUB	T2,P4		;POINT TO RIGHT ENTRY
	MOVE	T2,(T2)		;PICK UP BYTE POINTER
	PJRST	SETFLE		;PUT INTO FILL/ECHO STREAM AND RETURN

;SUBROUTINE TO ECHO DELETION FOR HARDCOPY TERMINALS
METDCR:	MOVSI	T1,L2LDEL	;BIT FOR DELETION IN PROGRESS
	TDNN	T1,LDBBY2(U)	;FIRST DELETION ECHO?
	JRST	[IORM	T1,LDBBY2(U)	;YES, SET BIT
		 MOVE	T2,FLLBSP	;GET BACKSLASH POINTER
		 PUSHJ	P,SETFLE	;SEND A BACKSLASH
		 JRST	.+1]	;REJOIN
	PUSHJ	P,SETFCE	;OUTPUT CHARACTER VIA ECHO STREAM
	SOJG	P4,.-1		;LOOP FOR WIDTH OF CHARACTER
	POPJ	P,		;RETURN TO DELONE
;SPECIAL ROUTINES FOR DELETE WORD/CHARACTER

;SUBROUTINE TO SET UP FOR DELETE WORD/CHARACTER
DELPRE:	SCNOFF			;MUSN'T LET ANYONE ELSE IN
	MOVSI	T1,LDLDIP	;DELETE-IN-PROGRESS FLAG
	IORM	T1,LDBDCH(U)	;LIGHT FOR TYICC4
	DPB	T3,LDBECT(U)	;SAVE ALTERED CHARACTER FOR READERS
	SKIPE	LDBTIC(U)	;MAKE SURE THERE'S STILL A STREAM
	AOS	LDBIIC(U)	;COUNT ANOTHER INVISIBLE CHARACTER
	MOVEI	P1,DELMID	;ROUTINE TO DELETE FROM THE MIDDLE
	MOVE	T1,LDBECT(U)	;SEE WHERE WE ARE
	CAME	T1,LDBTIP(U)	;ARE WE AT THE END?
	JRST	DELPR1		;NO, WE GUESSED RIGHT
	MOVEI	T1,L1RMIF	;YES, GET THE RECINT INTERLOCK FLAG
	TDNE	T1,LDBBYT(U)	;IS IT IN USE?
	JRST	DELPR1		;YES, STILL CAN'T DELETE FOR REAL
	IORM	T1,LDBBYT(U)	;NO, OBTAIN IT
	MOVEI	P1,DELEND	;AND USE ROUTINE TO DELETE FROM THE END
DELPR1:	SCNON			;ALLOW OTHERS IN AGAIN
	PUSHJ	P,STOPCM	;STOP COMCON FROM INTERFERING
	MOVSI	T1,LDLVDC	;VISIBLE DELETE CHARACTER BIT
	IORM	T1,LDBTTW(U)	;LIGHT IT FOR LATER
	PUSHJ	P,TTVID		;SEE IF VIDEO TERMINAL
	  TDZA	T1,T1		;NO, HAS NO TABLES
	MOVE	T1,TCRTAB##+1(T1) ;YES, GET ITS TABLES
	MOVEI	P2,METDCR	;ASSUME HARDCOPY ECHO
	TRNN	T1,-1		;DO WE HAVE A DELETE SEQUENCE?
	POPJ	P,		;NO, WE'RE ALL DONE
	MOVEI	P2,METDCT	;YES, USE THE TABLE TO DELETE
	HRRZ	P3,T1		;AND COPY THE TABLE ADDRESS
	POPJ	P,		;NOW WE'RE DONE

;SUBROUTINE TO BACK UP OVER ANY NOT-IN-STREAM CHARACTERS
;ON SKIP RETURN, HAS CHAR TO BE DELETED IN T3 AND CHTABL BITS IN T1
;ON NON-SKIP, THERE ARE NO MORE CHARACTERS AVAILABLE TO DELETE
DELSFX:	SKIPN	LDBTIC(U)	;ANY MORE TO BE DELETED?
	JRST	[PUSHJ	P,INPCHK	;MAYBE NOT, DO SANITY CHECK
		   JRST	DELSFX		;THERE'S ANOTHER
		 POPJ	P,]		;NO, GIVE DEPLETION RETURN
	LDB	T3,LDBECT(U)	;YES, GET CHARACTER TO ZAP
	TRNE	T3,CK.NIS	;IF NOT A REAL CHARACTER
	JRST	[PUSHJ	P,DELONE	;DELETE IT
		 JRST	DELSFX]	;AND LOOK FOR NEXT
	PUSHJ	P,SPCHEK	;SEE IF SPECIAL TO SOMEONE
	  JFCL			;OK IF NOT
	TLNE	T1,CHBRK	;IF A BREAK,
	POPJ	P,		;WE CAN'T DELETE IT
	TRC	T3,CK.IMG!CK.MET ;IMAGE OR META
	TRCN	T3,CK.IMG!CK.MET ;IS IT BOTH?
	JRST	DELSF1		;YES, GET DIFFERENT BITS
	TRZ	T3,CK.FDE!CK.IMG	;CLEAR MISLEADING BITS
	TRNE	T3,CK.MET	;META CHARACTER?
	SKIPA	T1,METABL-CK.MET(T3)	;YES, GET META BITS
	MOVE	T1,CHTABL(T3)	;NO, GET ALL ITS BITS
	JRST	CPOPJ1##	;AND RETURN GOODNESS

DELSF1:	TRZ	T3,CK.FDE	;CLEAR BIT WE DON'T CARE ABOUT
	JRST	CPOPJ1##	;RETURN GOODNESS
;SUBROUTINE TO DELETE ONE CHARACTER FROM THE END OF THE INPUT STREAM
;PRESERVES T3
;CALLED UNDER SCNOFF
DELEND:	PUSH	P,T3		;AS ADVERTISED
	PUSHJ	P,DELCHR	;REMOVE A CHARACTER
	  PUSHJ	P,RCDSTP	;SHOULDN'T GET THIS FAR IF NO CHARACTER IN STREAM
	JRST	T3POPJ##	;RESTORE CHARACTER JUST DELETED AND RETURN

;SUBROUTINE TO DELETE ONE CHARACTER FROM THE MIDDLE OF THE INPUT STREAM
;PRESERVES T3 MODULO THE CK.NIS BIT
;CALLED UNDER SCNOFF
DELMID:	SOSGE	LDBTIC(U)	;ONE LESS ECHOED CHARACTER
	PJRST	RCDSTP		;SHOULDN'T GET THIS FAR IF NONE
	TROE	T3,CK.NIS	;WE'RE MAKING AN INVISIBLE CHARACTER
	SOSA	LDBIIC(U)	;IF WAS, IS ONE LESS ECHOED
	DPB	T3,LDBECT(U)	;ELSE UPDATE IN CHUNKS
	AOS	LDBECC(U)	;ONE MORE TO ECHO
	AOS	LDBIEC(U)	;AND IT'S INVISIBLE
	SETO	T1,		;AMOUNT TO BACKSPACE ECHO TAKER
	ADJBP	T1,LDBECT(U)	;GET A BACKSPACED POINTER
	HRRZI	T2,CK.BDY##(T1)	;SEE IF BACKED INTO HEADER WORD
	TRNE	T2,CK.BDY##	;DID WE?
	JRST	DELMD1		;NO, ALMOST DONE
	SSX	T2,MS.SCN	;YES, SET SCNSER DATA SECTION
	HLRZ	T1,CK.BTH##(T2)	;GET BACK POINTER
	JUMPE	T1,DELMD2	;BETTER BE THERE
	ADD	T1,[POINT CK.WID,CK.BDY##,35]	;POINT TO END OF PREVIOUS CHUNK
DELMD1:	MOVEM	T1,LDBECT(U)	;STORE BACKSPACED POINTER
	POPJ	P,		;DONE WITH DELETION

;HERE TO CHECK IF DELETING TOO FAR
DELMD2:	MOVE	T1,LDBTIT(U)	;GET TYPEIN TAKER
	IBP	T1		;BUMP IT
	CAME	T1,LDBECT(U)	;ARE WE BACKING UP TO A PLACE WE UNDERSTAND?
	STOPCD	CLRSTP,DEBUG,DELMBD,	;++DELMID WENT BAD
	MOVE	T1,LDBTIT(U)	;YES, GET POINTER AGAIN
	JRST	DELMD1		;AND GO FOR IT

;CLEAN UP AFTER DELETION
DELFIN:	PUSHJ	P,DELSFX	;MAKE SURE OF SUFFIX
	  TRN			;DON'T CARE IF NO MORE
	MOVSI	T1,LDLVDC	;VISIBLE DELETE CHARACTER FLAG
	TDNE	T1,LDBTTW(U)	;IS IT ON?
	CAIE	P2,METDCR	;AND WAS THIS HARDCOPY DELETION?
	JRST	DELFN1		;NO TO EITHER, PRESS ON
	MOVE	T2,FLLBSC	;YES, GET POINTER TO BACKSLASH - CRLF
	MOVSI	T1,L2LDEL	;BIT FOR DELETION SEQUENCE
	TDNN	T1,LDBBY2(U)	;OPENING BACKSLASH TYPED?
	IBP	T2		;NO, SO DON'T TYPE A CLOSING ONE
	PUSHJ	P,SETFLE	;TYPE END OF DELETION STRING
	ANDCAM	T1,LDBBY2(U)	;CLEAR BACKSLASH FLAG FOR NEXT TIME
DELFN1:	MOVSI	T1,LDLDIP	;DELETE-IN-PROGRESS FLAG
	ANDCAM	T1,LDBDCH(U)	;NOT ANY MORE
	MOVEI	T3,MC.CHP	;THE SETCHP CHARACTER
	PUSHJ	P,SETFCE	;TELL FE'S ABOUT HPOS CHANGE AFTER WE'RE DONE
	CAIE	P1,DELEND	;DID WE GET THE "MIC" INTERLOCK?
	POPJ	P,		;NO, WE'RE DONE
	PJRST	RECINU		;YES, GIVE UP THE INTERLOCK AND RETURN
;SUBROUTINE TO DELETE ONE CHARACTER, COMPLETE WITH ECHO/FILL
;CALLED WITH CHARACTER TO BE DELETED IN T3
DELONE:	SCNOFF			;DELETION ROUTINES NEED THIS
	SKIPG	LDBTIC(U)	;DID TSETBI SNEAK IN?
	JRST	SONPPJ		;YES, WE HAVE NOTHING LEFT TO DO
	TRNE	T3,CK.NIS	;IF ALREADY A NON-CHARACTER,	
	JRST	[PUSHJ	P,(P1)	;DELETE IT FROM THE CHUNKS
		 JRST	SONPPJ]	;AND WE'RE DONE
	PUSHJ	P,(P1)		;REAL CHARACTER, REMOVE IT FROM THE STREAM
	SCNON			;ALLOW OTHERS AGAIN
	MOVSI	T2,LDLVDC	;VISIBLE DELETE CHARACTER FLAG
	ANDCAM	T2,LDBTTW(U)	;NOTE WE DELETED SOMETHING REAL
	TRC	T3,CK.MET!CK.IMG ;QUOTE BITS
	TRCN	T3,CK.MET!CK.IMG ;IS IT QUOTED?
	JRST	DEL1Q		;YES, HANDLE DELETION OF QUOTED CHARACTER
	ANDI	T3,CK.CHR	;TRIM FUNNY BITS
	CAIN	T3,11		;IS IT A TAB?
	JRST	DEL1T		;YES, TABS GET SPECIAL HANDLING
	MOVEI	P4,1		;ASSUME A WIDTH OF ONE
	CAIL	T3,40		;IS IT A PRINTING
	CAIL	T3,177		; CHARACTER?
	JRST	DEL1C		;NO, CONTROL CHARACTERS ARE DIFFERENT
DEL1A:	PUSH	P,T3		;SAVE CHARACTER TO ECHO
	MOVE	T2,P4		;COPY WIDTH
	PUSHJ	P,BACKUP	;ADJUST HPOS
	POP	P,T3		;RESTORE CHARACTER
DEL1EX:	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTIC BITS
	TLNE	T2,LDLNEC	;IF USER SAID NO ECHO,
	TLNE	T2,LDLCOM	;AND AT USER LEVEL,
	PJRST	(P2)		;NO, SIMPLE CASE, JUST CALL ECHOER AND RETURN
	POPJ	P,		;YES, DON'T ECHO THIS

DEL1C:	TRNE	T3,CK.PAR	;REGULAR CONTROL CHARACTER?
	JRST	DEL1E		;NO, GO HANDLE EIGHT-BIT
	MOVE	T1,CHTABL(T3)	;GET CONTROL BITS
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS
	CAIE	T3,STDALT	;UNLESS IT'S ESCAPE,
	TLZ	T1,CHALT	;IT'S NOT AN ALTMODE
	TLNE	T2,LDLDLR	;USER SUPPRESSING THIS CRUFT?
	TLZ	T1,CHUAE!CHALT!CHCRE ;YES, CLEAR IT OUT
	TLNN	T1,CHUAE!CHCRE!CHALT	;EITHER FORM OF UPARROW ECHO INVOLVED?
	POPJ	P,		;NO, DIDN'T ECHO BEFORE, SO DON'T NOW
DEL1C1:	PUSH	P,T3		;SAVE ACTUAL CHARACTER
	MOVEI	T2,2		;THIS HAS A WIDTH OF TWO,
	TLNE	T1,CHALT	;UNLESS IT'S ESCAPE
	MOVEI	T2,1		;THEN IT HAS A WIDTH OF ONE
	PUSHJ	P,BACKUP	;SO ADJUST HPOS THAT MANY
	TLNE	T1,CHALT	;IF THIS IS ESCAPE,
	JRST	DEL1CE		;ECHO AS DOLLAR
	MOVEI	T3,"^"		;GET AN UPARROW TO ECHO
	PUSHJ	P,DEL1EX	;SHOW ITS DELETION
	POP	P,T3		;RESTORE CONTROL CHARACTER
	TRC	T3,100		;CONVERT TO PRINTABLE FORM
	MOVEI	P4,1		;WIDTH OF ONE
	PJRST	DEL1EX		;ECHO THIS AND RETURN

DEL1CE:	POP	P,T3		;RESTORE THE ESCAPE
	MOVEI	T3,"$"		;GET ITS DOLLARSIGN
	PJRST	DEL1EX		;ECHO IT AND RETURN

DEL1T:	SCNOFF			;FIGHT RACES
	SKIPN	T4,LDBBKU(U)	;START FROM LAST BREAK
	MOVE	T4,LDBTIT(U)	;CLOSE ENOUGH
	LDB	P4,LDPPRP	;ASSUME THIS WAS THE PROMPT
	EXCH	T4,LDBECT(U)	;STORE NEW START POINTER, REMEMBER END
DEL1T1:	CAMN	T4,LDBECT(U)	;HIT THE END YET?
	JRST	DEL1T3		;YES, QUIT COUNTING
	LDCHK	T3,LDBECT(U),DEL1T3	;GET ANOTHER CHARACTER
	TRNE	T3,CK.NIS	;REAL CHARACTER?
	JRST	DEL1T1		;NO, IGNORE
	ANDI	T3,CK.CHR	;TRIM FUNNY BITS
	CAIE	T3,11		;A TAB?
	JRST	DEL1T2		;NO, GO COUNT NORMAL CHARACTER
	TRZ	P4,7		;YES, CLEAR FRACTIONAL TAB STOP
	ADDI	P4,10		;BUMP TO NEXT TAB STOP
	JRST	DEL1T1		;LOOP OVER LINE CONTENTS
DEL1T2:	MOVE	T1,CHTABL(T3)	;GET CONTROL BITS OF NORMAL CHARACTER
	TRNE	T1,CHUAE	;IF ^X FORM
	ADDI	P4,1		;THEN COUNT THE UPARROW
	AOJA	P4,DEL1T1	;COUNT ANOTHER COLUMN AND LOOP
DEL1T3:	SCNON			;ALLOW OTHERS AGAIN
	MOVEI	T2,10(P4)	;GET NEXT TAB STOP VALUE
	TRZ	T2,7		;BACK OFF TO TAB STOP
	SUBB	T2,P4		;GET COUNT FOR BACKSPACING
	PUSHJ	P,BACKUP	;ADJUST HPOS THAT MANY
	MOVEI	T3," "		;LOAD A SPACE FOR ECHO ROUTINES
	PJRST	DEL1EX		;ECHO DELETION OF (P4) SPACES AND RETURN

DEL1E:	MOVE	T1,CHTABL(T3)	;GET CHARACTER BITS
	MOVSI	T2,LDL8BI	;8-BIT INPUT MODE (DUE TO PROGRAM)?
	TDNN	T2,LDBDCH(U)	;TEST IT
	TLNN	T1,CH2PC	;OR NOT AN EXPANDABLE CHARACTER?
	JRST	DEL1A		;YES, BACK TO NORMAL CASE AFTER ALL
	MOVE	T2,CHREQV-200(T3) ;GET CHARACTER EXPANSION STRING
	TLNN	T2,-1		;THREE CHARACTER EXPANSION?
	AOJA	P4,DEL1E1	;NO, IT'S EXACTLY TWO
	TRNN	T2,767000	;YES, IS ITS MIDDLE A BACKSPACE?
	JRST	[HLRZ	T3,T2	;YES, THE LAST CHARACTER IS ALL WE ECHOED,
		 JRST	DEL1A]	;SO PRETEND THAT'S WHAT WE'RE DELETING
	ADDI	P4,2		;NO, IT'S A THREE-WIDE CHARACTER
DEL1E1:	MOVE	T2,P4		;COPY THE WIDTH
	PUSH	P,T3		;SAVE THE CHARACTER
	PUSHJ	P,BACKUP	;ADJUST HPOS
	POP	P,T3		;RESTORE CHARACTER
	CAIN	P2,METDCR	;IF HARDCOPY ECHO,
	MOVEI	P4,1		;THEN ONLY TYPE THE CHARACTER ONCE (IT EXPANDS)
	PJRST	DEL1EX		;ECHO A (P4) WIDTH DELETION AND RETURN

DEL1Q:	CAIE	P2,METDCR	;IF NOT HARDCOPY ECHO,
	JRST	DEL1Q1		;THEN JUST DELETE BY WIDTH
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS BITS
	PUSH	P,T3		;SAVE THE REAL CHARACTER
	MOVEI	T3,26		;GET AN ^V
	SETZ	T1,		;THIS IS NOT ESCAPE
	TLNN	T2,LDLDLR	;UNLESS USER SUPPRESSED UPARROW ECHO,
	PUSHJ	P,DEL1C1	;ECHO THE ^V
	POP	P,T3		;RESTORE OUR CHARACTER
	PUSHJ	P,SPCHEK	;GET ITS BITS
	TRZ	T3,CK.MET	;CLEAR THE META BIT
	MOVEI	P4,1		;ASSUME A WIDTH OF ONE
	TLNN	T1,CHUAE	;IS IT A CONTROL CHARACTER?
	JRST	DEL1A		;NO, HANDLE LIKE A NORMAL CHARACTER
	MOVE	T2,LDBDCH(U)	;YES, GET DOLLAR BIT AGAIN
	TLNE	T2,LDLDLR	;ARE WE DOING UPARROW ECHO?
	PJRST	DEL1C1		;YES, DO IT
	POPJ	P,		;NO, DON'T BOTHER ME

DEL1Q1:	SETZ	P4,		;ASSUME IT WAS INVISIBLE
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS WORD
	TLNN	T2,LDLDLR	;DID THE ^V ECHO?
	ADDI	P4,2		;YES, COUNT TWO CHARACTERS
	PUSHJ	P,SPCHEK	;GET BITS FOR OUR CHARACTER
	TLNN	T1,CHUAE	;IS IT A CONTROL CHARACTER?
	AOJA	P4,DEL1A	;NO, JUST DELETE (P4) CHARACTERS AND RETURN
	TLNE	T2,LDLDLR	;YES, DID IT ECHO?
	POPJ	P,		;NO, NOTHING DID, DON'T BOTHER ME
	ADDI	P4,2		;YES, WE ECHOED 4 WIDE
	PJRST	DEL1A		;DELETE (P4) CHARACTERS AND RETURN
;SUBROUTINE TO HANDLE AUTO-CRLF
XMTACR:	MOVSI	T1,LDLCOM	;SEE IF USER AT COMMAND LEVEL
	TDNE	T1,LDBDCH(U)	;AND IF SO,
	POPJ	P,		;IGNORE ACR
	LDB	T4,LDPACR	;GET AUTO-CRLF SETTING
	JUMPE	T4,CPOPJ##	;DO NOTHING IF NOT SET
	PUSHJ	P,HPOS		;GET CURRENT HPOS
	CAIGE	T2,(T4)		;SEE IF HIT MARGIN
	POPJ	P,		;NO, IGNORE
	MOVEI	T1,40		;GET A SPACE AGAIN
	PUSHJ	P,TOPGCB	;READ OUR STATUS BYTE
	TRNE	T2,CC.NSA	;IF NO SPECIAL ACTION,
	POPJ	P,		;IGNORE
	TRC	T3,040^!015	;CONVERT TO CR
	DPB	T3,LDBECT(U)	;STUFF BACK FOR READERS
	POPJ	P,		;RETURN AFTER MUNGING

;ROUTINE TO CHECK IDLENESS WHEN OUT OF CHARACTERS TO ECHO
ZAPECH:	SETZM	LDBECC(U)	;FIX UP
	MOVE	T2,LDBTIP(U)	;MESSED UP
	CAME	T2,LDBECT(U)	;CHECK POINTERS
	PUSHJ	P,RCDSTP	;SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
	JRST	XMTIDL

;SUBROUTINE TO CHECK IF WAKEUP SHOULD OCCUR BECAUSE OF NUMBER OF CHARS

CHKTIB:	CAILE	T2,TTIBRK##	;EXCEEDED ARBITRARY MAX?
	JRST	CPOPJ1##	;YES, ALWAYS BREAK
CHKTIF:	SKIPL	LDBBKB(U)	;BREAK SET SPECIFIED?
	POPJ	P,		;NO, DON'T BREAK BECAUSE OF NUMBER OF CHARS
	PUSH	P,T2		;SAVE POSITION
	LDB	T2,LDPFWD	;GET FIELD WIDTH
	SKIPN	T2		;WIDTH SET?
	MOVEI	T2,1		;NO, USE ONE
	CAMG	T2,(P)		;AT END OF FIELD
	AOS	-1(P)		;YES, WAKEUP
	JRST	T2POPJ##	;RETURN

ECHBRK:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST RCVWAK		;NO. WAKE JOB IF ANY.
	PJRST	COMSET		;YES. SET COMMAND REQUEST.

RCVWKQ:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST	RCVWAK		;NO. WAKE JOB.
	POPJ	P,0		;YES. DON'T MAKE COMMAND FOR LDLBKA


;ROUTINE TO QUEUE FOR A CHANGE HARDWARE PARAMETER MESSAGE

SETCH1:	AOS	(P)		;SKIPPING SETCHP
SETCHP::SE1ENT			;ENTER SECTION 1
	MOVEI	T1,L1RCHP
	IORM	T1,LDBBYT(U)	;MARK THAT ISRCHP MUST BE CALLED
	PJRST	TOPOKE		;ADD TO QUEUE

CLRIRM::SE1ENT			;ENTER SECTION 1
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR IN LDB
	POPJ	P,		;RETURN
TOREQ::	SE1ENT			;ENTER SECTION 1
	MOVSI	T1,LDLIDL
	IORM	T1,LDBDCH(U)
;;	PJRST	TOPOKE

;ROUTINE TO PLACE AN LDB INTO THE START OUTPUT QUEUE.  SCANNED
;AT CLOCK LEVEL ONCE PER TICK.
;CALL
;	MOVEI	U,LDB ADDRESS
;	PUSHJ	P,TOPOKE
;	<RETURN HERE ALWAYS>
;USES T1,T2

TOPOKE::SE1ENT			;ENTER SECTION 1
	MOVEI	T1,LDRPTY	;PTY BIT
	TDNE	T1,LDBDCH(U)	;IS THIS A PTY?
	PJRST	PTYPE##		;YES, DON'T QUEUE OUTPUT
	MOVSI	T1,LPLPOK	;OUTPUT BEING STARTED BIT
	TDNE	T1,LDBPAG(U)	;CHECK BEFORE WE GET THE INTERLOCK
	POPJ	P,		;  JUST FOR EFFICIENCY'S SAKE
	SCNOFF			;NO INTERRUPTS
	TDNE	T1,LDBPAG(U)	;...
	JRST	SONPPJ		;YES, BY SOMEONE ELSE
	SKIPL	LDBDCH(U)	;LINE ALREADY ACTIVE?
	JRST	[MOVEI T2,L1RCHP ;YES, DON'T QUEUE UNLESS
		 TDNN T2,LDBBYT(U) ;A A HARDWARE PARAMETER HAS CHANGED
		 JRST SONPPJ
		 JRST .+1]
	IORM	T1,LDBPAG(U)	;NO.  INDICATE LDB IS GOING INTO THE QUEUE
	HLRZ	T1,LDBQUH(U)	;GET THE QUEUE HEADER ADDRESS
	MOVE	T2,1(T1)	;LAST ENTRY OF CURRENT QUEUE
	SKIPN	T2		;NON-NULL QUEUE?
	MOVEI	T2,-LDBQUE(T1)	;POINT TO QUEUE HEADER WORD
	MOVEM	U,LDBQUE(T2)	;STORE ADDRESS OF ARGUMENT LDB AT END
	MOVEM	U,1(T1)		;UPDATE LATEST ENTRY
	SETZM	LDBQUE(U)	;MAKE SURE LIST TERMINATESS
	JRST	SONPPJ		;ALLOW INTERRUPTS AND RETURN
;ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE
;CALLED FROM DEVICE DRIVERS TO FIND LINES THAT ARE WAITING TO DO OUTPUT.
;CALL
;	MOVE	T1,ADDRESS OF LIST HEADER
;	PUSHJ	P,TOTAKE
;	  <IF EMPTY QUEUE>
;	<LDB ADDRESS IN U>
;
;USES T2.

TOTAKE::SE1ENT			;ENTER SECTION 1
	SKIPN	0(T1)		;IF QUEUE IS EMPTY NOW
	POPJ	P,		; AVOID INTERLOCK
	SCNOFF
TOTAK1:	MOVSI	T2,LPLPOK	;HAS OUTPUT BEEN STARTED?
	MOVE	U,0(T1)		;POINT TO FIRST LDB IN LIST
	JUMPE	U,SONPPJ	;IF NONE
	ANDCAM	T2,LDBPAG(U)	;CLEAR 'IN QUEUE' BIT
	SKIPN	T2,LDBQUE(U)	;NEXT LDB IN LIST, END OF LIST?
	SETZM	1(T1)		;YES, CLEAR TAIL POINTER TOO
	MOVEM	T2,0(T1)	;ADVANCE LIST
	SKIPGE	LDBDCH(U)	;IS OUTPUT ALREADY GOING?
	JRST	SONPJ1		;LINE IDLE, GIVE GOOD RETURN
	MOVEI	T2,L1RCHP
	TDNN	T2,LDBBYT(U)	;NEED TO SEND CHANGE PARAMETER MESSAGE?
	JRST	TOTAK1		;NO, SKIP TO NEXT
;	JRST	SONPJ1		;YES, RETURN THE LINE
;
;ROUTINE TO ALLOW SCANNER INTERRUPTS AGAIN AND SKIP RETURN

SONPJ1::AOSA	0(P)		;SKIP RETURN
SONTPJ::POP	P,T1		;ADJUST THE STACK (RESTORE T1?)
SONPPJ::SCNON			;ALLOW SCANNER INTERRUPTS
	POPJ	P,		;AND RETURN
	SUBTTL	RECEIVE INTERRUPT ROUTINE

;HERE FROM DEVICE-DEPENDENT INTERRUPT ROUTINE ON A RECEIVE INTERRUPT.
;AT THIS POINT, T3(28-35) HAS RECEIVED CHARACTER, U HAS PHYSICAL LINE #
;AS INDEX INTO LINTAB

RECINT::SE1ENT			;ENTER SECTION 1
	MOVE	U,LINTAB##(U)	;LOAD LDB ADDRESS
RECPTY::MOVEI	T2,L1RMIF	;MIC INTERLOCK FLAG
	SCNOFF			;LOCK OTHER CPU
	TDNE	T2,LDBBYT(U)	;IS MIC TYPING ON THIS LINE?
	JRST	RECQUE		;LINE INTERLOCKED, QUEUE THE CHARACTER
	IORM	T2,LDBBYT(U)	;SET THE INTERLOCK BIT
	SCNON			;ALLOW INTERRUPTS
	PUSHJ	P,RECINI	;PROCESS THE INTERRUPT
RECINU:	SCNOFF			;SIGH. GOTTA DO THIS INTERLOCKED
	SKIPE	RCQCNT		;ANY CHARACTERS QUEUED UP?
	PJRST	RECUNQ		;YES, TRY TO UN-QUEUE THEM
	MOVEI	T2,L1RMIF	;"MIC" INTERLOCK FLAG
	ANDCAM	T2,LDBBYT(U)	;CLEAR INTERLOCK
	JRST	SONPPJ		;RELEASE SCNSER AND DISMISS INTERRUPT
;RECQUE - QUEUE UP AN INPUT CHARACTER FOR A LINE THAT IS INTERLOCKED
;
;CALLED WITH CHAR IN T3 AND SCNSER INTERLOCK

RECQUE:	AOS	RCQHIT		;COUNT TOTAL INTERLOCKS HIT
	AOS	T2,RCQPTR	;ADVANCE THE QUEUE PUTTER
	CAIG	T2,RCQEND	;FALLEN OFF THE END?
	JRST	.+3		;NO, STILL WITHIN THE QUEUE BUFFER
	MOVEI	T2,RCQBEG	;YES, WRAP THE PUTTER AROUND TO THE START
	MOVEM	T2,RCQPTR	;OF THE QUEUED CHARACTER BUFFER
	CAMN	T2,RCQTKR	;HIT THE TAKER YET?
	JRST	RECQU9		;YES, BUTTS, GO FALL OVER
	HRRZM	T3,(T2)		;NO, STILL ROOM, STASH THE CHARACTER
	HRLM	U,(T2)		;AND THE LDB WHICH OWNS IT
	AOS	RCQCNT		;COUNT UP CHARACTERS QUEUED
	JRST	SONPPJ		;AND GET OUT OF HERE

;CHARACTER QUEUE FULL

RECQU9:	SOS	RCQPTR		;BACK UP THE PUTTER
	AOS	T2,RQFCNT	;COUNT OF TIMES HERE
	CAIE	T2,1		;FIRST TIME HERE
	JRST	SONPPJ		;NO, DON'T CLUTTER UP THE DISK SPACE
	STOPCD	SONPPJ,DEBUG,RQF;++ RECINT QUEUE FULL
;RECUNQ - UN-QUEUE THE QUEUED CHARACTERS FROM RECINT
;
;CALLED WITH BOTH SCNSER AND MIC (L1RMIF) INTERLOCK SET

RECUNP:	SCNOFF			;GET SCNSER INTERLOCK
	SKIPG	RCQCNT		;REALLY ANYTHING QUEUED?
	JRST	RECUSZ		;NAW, NOTHING TO DO

;TRY TO PROCESS CHARACTER QUEUE

RECUNQ:	MOVE	T2,RCQTKR	;COPY OF QUEUE TAKER
	ADDI	T2,1		;ADVANCE TO NEXT ENTRY
	CAILE	T2,RCQEND	;FALLEN OFF OF END YET?
	MOVEI	T2,RCQBEG	;YES, WRAP THE TAKER BACK TO THE BEGINING
	SKIPN	T1,(T2)		;GET FIRST ENTRY IN CHARACTER QUEUE
	JRST	RECUNX		;EMPTY, TOSS IT AND LOOK FOR MORE
	HLRZ	T1,T1		;POSITION LDB ADDRESS
	CAIE	T1,(U)		;THE LDB WE'RE INTERESTED IN?
	JRST	RECUSQ		;NO (BLETCH) SCAN THE QUEUE THEN
	PUSH	P,T3		;SAVE ORIGINAL CALLER'S CHARACTER
	HRRZ	T3,(T2)		;GET QUEUED CHARACTER
	SETZM	(T2)		;CLEAR OUT SO WE NEVER SEE IT AGAIN
	MOVEM	T2,RCQTKR	;ADVANCE THE QUEUE TAKER
	SOS	RCQCNT		;ONE LESS CHARACTER IN THE QUEUE

;PROCESS THE QUEUED CHARACTER (L1RMIF STILL SET)

RECUNT:	SCNON			;WE CAN SAFELY ALLOW INTERRUPTS NOW
	PUSHJ	P,RECINI	;PROCESS QUEUED CHARACTER
	POP	P,T3		;RESTORE STACK
	JRST	RECUNP		;AND CHECK REST OF THE QUEUE

;HERE WHEN THE QUEUE STARTS OFF WITH A HOLE

RECUNX:	MOVEM	T2,RCQTKR	;ADVANCE THE QUEUE TAKER
	SOSE	RCQCNT		;COUNT DOWN THE CHARACTERS QUEUED
	JRST	RECUNQ		;AND CHECK THE REST OF THE QUEUE
				;EMPTY, FALL INTO RECUNZ

;JUST EMPTIED THE QUEUE, VALIDITY CHECK IT

RECUNZ:	MOVEI	T2,L1RMIF	;"MIC" INTERLOCK
	ANDCAM	T2,LDBBYT(U)	;CLEAR LINE INTERLOCK
	MOVE	T2,RCQPTR	;THE QUEUE PUTTER
	CAIGE	T2,RCQBEG	;SOSED AT UNFORTUNATE MOMENT?
	MOVEI	T2,RCQEND	;YES, REALLY STILL AT END THEN
	CAMN	T2,RCQTKR	;PUTTER MATCH TAKER?
	JRST	SONPPJ		;YES, ALL SET, JUST GO AWAY
	STOPCD	.+1,DEBUG,RQD	;++ RECINT QUEUE DISCREPANCY
	MOVE	T2,RCQTKR	;GET THE TAKER
	MOVEM	T2,RCQPTR	;AND MAKE THE PUTTER MATCH
	JRST	SONPPJ		;AND SEE WHAT HAPPENS
;STILL SCNOFF'ED

;HERE WHEN FIRST ENTRY IN RECINT'S QUEUE IS NOT FOR THIS LINE. THE
;QUEUE MUST BE SCANNED FOR CHARACTERS WHICH DO BELONG TO THIS LINE
;IN ORDER TO PRESERVE CHARACTER SYNCHRONY.

RECUSQ:	PUSH	P,RCQCNT	;COUNT OF CHARACTERS QUEUED UP
RECUSS:	SOSG	0(P)		;MORE TO CHECK?
	JRST	RECUSY		;NO, NOTHING FOR THIS LINE, GET OUT
	ADDI	T2,1		;YES, ADVANCE TAKER TO NEXT CANDIDATE
	CAILE	T2,RCQEND	;FALLEN OFF THE END YET?
	MOVEI	T2,RCQBEG	;YES, WRAP AROUND TO THE FRONT
	SKIPN	T1,(T2)		;FETCH COPY OF THIS QUEUE ENTRY
	JRST	RECUSS		;EMPTY ENTRY, CHECK REST OF QUEUE
	HLRZ	T1,T1		;POSITION ADDRESS OF LDB
	CAIE	T1,(U)		;OUR LDB?
	JRST	RECUSS		;NOPE, SKIP THIS ENTRY THEN TOO

;AN EMBEDDED QUEUE ENTRY FOR THIS LINE, GET AND DELETE IT

	MOVEM	T3,0(P)		;SAVE REAL T3 FOR CALLER
	HRRZ	T3,(T2)		;FETCH QUEUED CHARACTER TO BE RECINT'ED
	SETZM	(T2)		;NOTE THE CHARACTER PROCESSED
	JRST	RECUNT		;PROCESS QUEUED CHARACTER

;NOTHING TO DO, RELEASE INTERLOCK AND DISMISS "INTERRUPT"

RECUSY:	POP	P,T1		;UNWIND THE STACK BY 1
RECUSZ:	MOVEI	T2,L1RMIF	;THE "MIC" INTERLOCK FLAG
	ANDCAM	T2,LDBBYT(U)	;CLEAR THE INTERLOCK
	JRST	SONPPJ		;AND RELEASE SCNSER INTERLOCK
;RECINI - DO THE ACTUAL INPUT CHARACTER PROCESSING

RECINI:				;PROCESS ONE INPUT CHARACTER
	AOS	LDBICT(U)	;COUNT INPUT CHARACTERS THIS LINE
	AOS	%SCNRI		;AND INPUT CHARACTERS FOR THE SYSTEM
IFN FTRSP,<AOS	.CPNRI##>	;PER CPU AS WELL

RECINM:	ANDI	T3,CK.CHR!CK.FDE ;JUST 8 BITS OF CHARACTER.
				; CLEAR ANY DEVICE DEPENDENT BITS
IFN FTNET,<			;IF NETWORK
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE,
	JRST	VTMREC##	;  GO HANDLE NVT CHARS SPECIAL
>
	MOVSI	T1,L1LOFL	;PUT TERMINAL ON LINE
	ANDCAM	T1,LDBOFL(U)	;SINCE SOMEONE IS THERE
	MOVE	T1,LDBTTW(U)	;LINE TYPE FLAGS
	MOVE	T1,LDBDCH(U)	;GET LINE CHARACTERISTICS
	SKIPL	LDBTTW(U)	;ANF-10 KNOWS WHAT IT IS DOING, PROCESS CHAR
		.CREF	LTLANF	;(CREF REFERENCE TO REAL SYMBOL)
	TRNN	T1,LDRDSD	;IS IT A DATASET LINE?
	JRST	RECINN		;NO.  PROCESS CHARACTER
	LDB	T1,LDPDSC	;GET DATASET TABLE INDEX
	MOVE	T1,DSCTAB##(T1)	;GET DATASET DATA
	TLNE	T1,DSCBLI	;WANT TO IGNORE INTERRUPTS?
	  POPJ	P,		;YES,
RECINN:
	MOVEI	T1,ST.NRT	;THE STAND ALONE (NO REMOTE) BIT
	TDNE	T1,STATES##	;IS THE SYSTEM STAND ALONE?
	JRST	[HRR	T1,LDBDCH(U)	;YES, GET CHARACTERISTICS
		TRNN	T1,LDRDSR	;IS THE TERMINAL REMOTE/DATASET?
		JRST	RECIN1		;NO, LOCAL, ALLOW IT
		HRRZ	T1,LDBDDB(U)	;REMOTE, BUT IS IT ALREADY IN USE?
		JUMPN	T1,RECIN1	;YES, ALLOW IT TO CONTINUE TO WORK
		JRST	BEATIT]		;NO, DUMP IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

RECIN1:	SKIPN	LDBIST(U)	;ARE WE DOING SOMETHING SPECIAL?
	JRST	RECIN2		;NO, SKIP OVERHEAD
	PUSHJ	P,RECDCS	;YES, HANDLE IT
	  POPJ	P,		;DON'T STORE
RECIN2:	MOVE	T1,LDBOST(U)	;GET STATE BITS IN LH.
	TLNE	T1,LOLPIM	;PIM MODE?
	JRST	REPIM		;YES, GO TO PIM CODE
	SKIPL	LDBBY3(U)	;HAS THE STATUS OF DEFERRED ECHO CHANGED?
	JRST	RECIN3		;NO, DON'T MUNG IT
	MOVSI	T1,L3LDMC	;YES, GET THE CHANGE BIT
	ANDCAM	T1,LDBBY3(U)	;CLEAR FOR NEXT TIME
	PUSH	P,T3		;SAVE THE INCOMING CHARACTER
	MOVEI	T3,MC.DEN	;ASSUME TURNING IT ON
	MOVE	T2,LDBBYT(U)	;GET DEFERRED ECHO BITS
	TRNN	T2,L1RDEM	;RIGHT ASSUMPTION?
	MOVEI	T3,MC.DEF	;NO, CLEARING IT
	PUSHJ	P,RECINA	;DO IT TO IT
	POP	P,T3		;RESTORE OUR INPUT CHARACTER
RECIN3:	MOVE	T1,LDBDCH(U)	;CARRY DEVICE BITS IN LH.
	SKIPG	TTFREN##	;ANY SPACE FOR CHARACTERS?
	JRST	RCHLT1		;NO. SHUT IT DOWN.
	TLNN	T1,LDLIMI	;IN IMAGE INPUT MODE?
	JRST	RECIN4		;NO.
	MOVEI	T1,IMGTIM	;YES. RESET TIMEOUT FIELD TO MAX
	DPB	T1,LDPTIM	; ..
	TRO	T3,CK.IMG	;MARK IN NINTH BIT.
	JRST	RECINA		;AND GO STORE IN BUFFER. NO BREAK.
RECIN4:	SKIPL	LDBATR(U)	;EIGHT-BIT TERMINAL?
	TRZ	T3,CK.PAR	;NO, CLEAR PARITY FOR SEVEN-BIT ASCII
	PUSHJ	P,RECMAP	;MAP CHARACTERS IF NECESSARY
	  POPJ	P,		;DON'T STORE
IFN FTPI,<
	PUSHJ	P,RECOOB	;SEE IF AN OUT-OF-BAND CHARACTER OF SOME SORT
	  POPJ	P,		;YES, AND COMPLETELY PROCESSED
>
RECIN5:	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL. SET T1 UP.
	  JRST RECINA		;NON-SPECIAL. GO STORE
	TLNE	T1,CHRIA	;DOES THIS CHAR NEED SPECIAL RCV HANDLING?
	TLNN	T1,CHNDFR	;CAN CHARACTER BE DEFERRED?
	JRST	RECINA		;YES, JUST STORE NORMALLY FOR NOW
	PUSHJ	P,(T1)		;CALL CHARACTER'S SPECIAL PROCESSOR
	  POPJ	P,		;DON'T STORE RETURN
				;FALL INTO ORDINARY CHAR HANDLER
;HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER + CK.??? BITS

RECINA:	MOVE	T2,LDBTIC(U)	;COUNT CHARACTERS LINE HAS INPUT
	ADD	T2,LDBECC(U)	;PLUS LEFT TO ECHO
	PUSH	P,T1		;SAVE CHARACTER BITS
	CAIG	T2,TTIWRN##	;TIME TO WARN HIM?
	JRST	RWARNX		;NO, STUFF CHARACTER INTO CHUNKS
	CAIGE	T2,TTIMAX##	;IF HE IS WAY OVER, OR
	SKIPG	TTFREN##	;WE ARE OUT OF CHUNKS
	JRST	RECHLT		;THROW AWAY THE INPUT CHARACTER
	PUSHJ	P,PTBTCH##	;CHECK IF OLD PTY OR BATCH
	  JRST	RWARNX		; CAN'T SEND XOFF
	PUSHJ	P,SNDXOF	;SEND XOFF
RWARNX:	SCNOFF
	STCHK	T3,LDBTIP(U),RECINE  ;STORE CHARACTER
	AOS	LDBECC(U)	;COUNT CHARACTER TO ECHO
	POP	P,T1		;RESTORE T1
	TLNE	T1,CHBRK!CHCRET	;BREAK CHARACTER (OR LIKELY TO BECOME ONE)?
	PUSHJ	P,SETBKI	;YES, NOTE PLACE FOR RIDLN
	SCNON
	SETZ	S,		;FOR RECIN6
RECIN6:	TLNN	T1,CHCNC	;IS THIS CHARACTER A CONTROL C?
	TLO	S,L2LCCS	;NO. PREPARE TO CLEAR L2LCCS BIT
	TRNN	T3,CK.IMG	;IF NOT A QUOTED CHARACTER,
	TRNN	T3,CK.MET	;SKIP THIS IF A META CHARACTER
	ANDCAM	S,LDBBY2(U)	;CLEAR DELETE AND CONTROL C FLAGS
IFN FTPI,<
	PUSHJ	P,TORCCT	;GET INPUT COUNT
	CAIE	T1,1		;ONLY DO THE FOLLOWING IF IT JUST WENT NON-ZERO
	PJRST	TOPOKE		;OTHERWISE JUST GET ECHO STARTED
	HRRZ	F,LDBDDB(U)	;GET DDB POINTER
	JUMPE	F,TOPOKE	;SKIP PSI IF NONE
	SKIPE	DEVPSI(F)	;IF WANTING INTERRUPTS,
	PUSHJ	P,PSIAVL##	;WARN THAT INPUT IS AVAILABLE
> ;END IFN FTPI
	PJRST	TOPOKE		;QUEUE TO GET ECHO STARTED

RECINE:	POP	P,T1		;ADJUST STACK
	SCNON			;RELEASE TERMINAL SERVICE INTERLOCK
	MOVSI	S,L2LCCS	;CRUFTY BIT
	JRST	RECIN6		;RETURN, CLEARING CRUFTY BIT
;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKU

SETBKU:	MOVE	T2,LDBECT(U)	;LOCATION OF INPUT PUTTER
	MOVEM	T2,LDBBKU(U)	;SAVE IT
	POPJ	P,


;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKI

SETBKI:	MOVE	T2,LDBTIP(U)	;LOCATION OF INPUT PUTTER
	MOVEM	T2,LDBBKI(U)	;SAVE IT
	POPJ	P,
;HERE TO SEE IF ANY INPUT CHARACTERS NEED TO BE MAPPED

RECMAP:	MOVSI	T2,LMLSSE	;SWITCH-SEQUENCE ENABLED BIT
	TDNN	T2,LDBCHM(U)	;IS IT?
	JRST	RECMP1		;NO, DON'T COMPARE AGAINST IT
	MOVEI	T2,LISSWI	;PRE-SET INPUT STATE FOR SWITCH SEQUENCE
	LDB	T1,LDPSW1	;GET SWITCH-SEQUENCE ONE
	XOR	T1,T3		;FORM DIFFERENCES
	TRNN	T1,CK.CHR	;IS THIS IT?
	PJRST	SETDCS		;YES, SET FOR RECDCS AND GIVE DON'T-STORE RETURN
RECMP1:	AOS	(P)		;NO, FROM HERE ON WE'LL SKIP-RETURN
	MOVE	T1,T3		;GET A COPY OF THE CHARACTER
	ANDI	T1,CK.CHR	;KEEP ONLY USEFUL BITS
	LDB	T2,LDPUNP	;GET THE UNPAUSE CHARACTER
	CAMN	T2,T1		;IS THIS IT?
	JRST	RECMPQ		;YES, STORE AS ^Q
	LDB	T2,LDPESC	;NOT UNPAUSE, GET THE ESCAPE CHARACTER
	CAMN	T2,T1		;IS THIS IT?
	JRST	RECMPA		;YES, STORE AS ESCAPE
;ADD ANY NEW MAPPED CHARACTER TESTS HERE
	POPJ	P,		;NOT TO BE MAPPED, RETURN IT UNCHANGED

RECMPQ:	SKIPA	T1,["Q"-100]	;UNPAUSE == ^Q
RECMPA:	MOVEI	T1,STDALT	;ESCAPE == STDALT
	DPB	T1,[POINT 8,T3,35] ;UPDATE RECEIVED CHARACTER
	POPJ	P,		;RETURN THE MAPPED VERSION
;HERE TO CHECK OUT THE POSSIBILITY OF HAVING AN OUT-OF-BAND CHARACTER

IFN FTPI,<
RECOOB:	TRNN	T3,CK.MET	;IS IT NOT A FUNCTION CHARACTER?
	SKIPL	LDBBKB(U)	;AND IS SPECIAL-CHARACTER MODE ENABLED?
	JRST	CPOPJ1##	;NO, GIVE CONTINUE RETURN
	MOVE	T1,T3		;YES, COPY THE CHARACTER
	ANDI	T1,CK.CHR	;KEEP ONLY RELEVANT BITS
	PUSHJ	P,TOPGCB	;GET THE CORRESPONDING BITS IN T2
	TRNN	T2,CC.OOB	;IS IT AN INTERRUPT CHARACTER?
	JRST	CPOPJ1##	;NO, GIVE CONTINUE RETURN
	TRNN	T2,CC.CLR	;IS IT A 'CLEAR' CHARACTER?
	JRST	RECOB2		;NO, DON'T HANDLE AS ONE
	TRNN	T2,CC.DFR	;IS IT DEFERRED CLEAR?
	JRST	RECOB1		;NO, HANDLE IMMEDIATE CLEAR
	MOVEI	T2,LISDCI	;LINE INPUT STATE=DEFERRED-CLEAR INTERRUPT
	PJRST	SETDCS		;SETUP DEFERRED CHARACTER STATE AND RETURN
				;  (NON-SKIP RETURN BECAUSE DONE WITH THIS
				;   CHARACTER FOR NOW)
RECOB1:	PUSHJ	P,TSETI1	;CLEAR TYPEAHEAD
	JRST	RECOB4		;GO ENTER CHARACTER IN OOB STREAM AND RETURN NON-SKIP
RECOB2:	TRNE	T2,CC.DFR	;IS THIS A 'HELLO' OOB?
	AOS	(P)		;YES, GIVE SKIP RETURN AS WELL AS OOB PSI
RECOB4:	SCNOFF			;MUST HAVE INTERLOCK
	HRRZ	T1,LDBDDB(U)	;GET DDB (IF ANY)
	JUMPE	T1,SONPPJ	;IT WENT AWAY
	EXCH	T1,F		;FOR BYTE POINTER
	PUSH	P,J		;PRESERVE FOR CALLER
	LDB	J,PJCHN##	;GET THE TARGET TO SIGNAL
	EXCH	T1,F		;RESTORE F
	JUMPE	J,JPOPJ##	;GIVE UP IF NO JOB/JCH FOR PSI
	STCHK	T3,LDBOOP(U),RECOB5	;STORE THE CHARACTER FOR PSISER
	AOS	LDBOOC(U)	;COUNT IT UP
	SCNON			;RETURN INTERLOCK
	SIGNAL	C$OOB		;RAISE THE INTERRUPT FOR THE USER
	  TRNA			;DON'T UNREAD IF DOESN'T WANT
	PUSHJ	P,SETUNR	;LIGHT UNREAD BIT
	JRST	JPOPJ##		;RESTORE J AND RETURN TO RECIN3

;HERE IF AN ERROR OCCURS TRYING TO STORE THE OOB CHARACTER
RECOB5:	POP	P,J		;RESTORE J
	JRST	SONPPJ		;GIVE UP
> ;END OF IFN FTPI
;HERE TO HANDLE DEFERRED CHARACTERS ON NEXT RECEIVE

RECDCS:	LDB	T2,LDPDCS	;GET THE REASON CODE
	JUMPE	T2,RECDC1	;PROCEED WITH CHARACTER IF NONE
	SETZ	T4,		;GET A ZERO
	DPB	T4,LDPDCS	;CLEAR STATUS (IN CASE IT NEEDS TO BE SET AGAIN)
	PUSHJ	P,@DCSDSP(T2)	;CALL THE ROUTINE APPROPRIATE TO OUR STATE CODE
	  POPJ	P,		;RETURN BLINDLY ON IGNORE RETURN
	JRST	RECDCS		;CHECK FOR NEW STATUS ON CONTINUE RETURN

RECDC1:	SETZM	LDBIST(U)	;CLEAR TO SPEED UP RECINT
	JRST	CPOPJ1##	;GIVE CONTINUE RETURN

DCSDSP:	IFIW	CPOPJ##		;STATE ZERO NEVER USED
	IFIW	DCSDCI		;DEFERRED CLEAR INTERRUPT
	IFIW	DCSQOT		;QUOTED CHARACTER
	IFIW	DCSSWI		;SWITCH SEQUENCE

DCSDCI:	LDB	T2,LDPDTC	;GET THE PREVIOUS CHARACTER
	XOR	T2,T3		;SEE WHAT'S DIFFERENT
	SKIPL	LDBATR(U)	;CHECK 8-BIT
		.CREF	LAL8BT	;SYMBOLIC REFERENCE
	TRZ	T2,CK.PAR	;IGNORE PARITY IF 7-BIT
	TRNN	T2,CK.CHR	;ARE THEY THE SAME?
	PJRST	RECOB1		;YES, THIS IS NOW A CLEAR OOB
	XOR	T2,T3		;NO, RESTORE PREVIOUS
	PUSH	P,T3		;AND THE CHARACTER
	MOVE	T3,T2		;MOVE PREVIOUS CHARACTER
	PUSHJ	P,RECIN5	;RECEIVE AS SOMETHING OTHER THAN OOB
	POP	P,T3		;RESTORE NEW CHARACTER
	JRST	CPOPJ1##	;GIVE SKIP RETURN

DCSQOT:	LDB	T2,LDPDTC	;GET THE PREVIOUS CHARACTER
	ANDI	T2,CK.FDE	;WANT ONLY THIS BIT
	AND	T2,T3		;KEEP ONLY IF BOTH WERE ECHOED
	ANDI	T3,CK.CHR	;MASK DOWN TO CHARACTER ALONE
	TRO	T3,CK.IMG!CK.MET(T2) ;TURN ON QUOTING BITS (AND MAYBE CK.FDE)
	PJRST	RECIN5		;STORE AND RETURN

DCSSWI:	LDB	T2,LDPDTC	;GET THE PREVIOUS CHARACTER
	XOR	T2,T3		;SEE WHAT'S DIFFERENT
	SKIPL	LDBATR(U)	;IF 7-BIT,
		.CREF	LAL8BT
	TRZ	T2,CK.PAR	;TRUNCATE
	TRNN	T2,CK.CHR	;ARE THEY THE SAME?
	JRST	RECOOB		;YES, GIVE IT UNLESS OOB
	LDB	T2,LDPSW2	;NO, GET SEQUENCE'S SECOND CHARACTER
	XOR	T2,T3		;SEE WHAT'S DIFFERENT
	SKIPL	LDBATR(U)	;IF 7-BIT,
		.CREF	LAL8BT
	TRZ	T2,CK.PAR	;TRUNCATE
	TRNN	T2,CK.CHR	;ARE THEY THE SAME?
	JRST	DCSSW1		;YES, WE HAVE A BINGO
	PUSH	P,T3		;NO, MUST DELIVER BOTH.  SAVE CURRENT
	LDB	T3,LDPDTC	;GET FIRST PORTION AGAIN
	PUSHJ	P,RECMP1	;MAP IF NECESSARY
	  TRNA			;PROPAGATE DON'T STORE RETURN
IFN FTPI,<
	PUSHJ	P,RECOOB	;SEE IF IT'S OUT-OF-BAND
	  TRNA			;DON'T STORE
>
	PUSHJ	P,RECIN5	;STORE FIRST CHARACTER
	POP	P,T3		;RESTORE CURRENT
	JRST	CPOPJ1##	;GIVE CONTINUE RETURN

DCSSW1:	PUSH	P,T3		;PRESERVE ACTUAL SW2 RECEIVED
	MOVEI	T3,CK.MET	;META FLAG USED FOR NXTOOB
	PUSHJ	P,RECOB4	;STORE AS HELLO OOB
	LDB	T3,LDPDTC	;GET ACTUAL CHARACTER DEFERRED
	PUSHJ	P,SPCHEK	;GET ITS BITS
	  TRN			;IGNORE SKIP RETURN
	PUSHJ	P,RECINA	;STORE AS NORMAL
	POP	P,T3		;RESTORE RECEIVED CHARACTER
	PUSHJ	P,SPCHEK	;GET ITS BITS
	  TRN			;IGNORE SPECIAL RETURN
	PJRST	RECINA		;STORE THIS ONE TOO AND RETURN

;HERE TO SET UP DEFERRED CHARACTER STATUS FOR SWITCH SEQUENCE, QUOTING, AND OOB

SETDCS:	DPB	T2,LDPDCS	;STORE REASON CODE
	DPB	T3,LDPDTC	;DEFERRING THIS CHARACTER (IN CASE NEEDED)
	POPJ	P,		;RETURN
;HERE ON RECEIVE INTERRUPT OF A CONTROL-A CHARACTER

IFN	FTMIC,<			;IF UNDER MIC CONTROL THEN ^A = ^C
RICA:	PUSHJ	P,MICCHK	;DOES MIC WANT TO HERE FROM US?
	  JRST	CPOPJ1##	;NO, GIVE 'NORMAL' RETURN
	;PJRST	RICC		;YES, FALL INTO ^C ACTION ROUTINE
> ;END IFN FTMIC


;HERE ON RECEIVE INTERRUPT OF A CONTROL-C CHARACTER

RICC:	PUSH	P,T1		;SAVE CHARACTER BITS
IFN	FTMIC,<			;IF MIC
	SKIPE	T1,LDBMIC(U)	;IS MIC RUNNING FOR US?
	PUSHJ	P,MICRIC	;YES - EXTRA GOODIES
> ;END OF IFN MIC
	PUSH	P,T3		;RIDLN CLOBBERS T3
	PUSHJ	P,RIDLN		;DO THE CONTROL-U FUNCTION
	POP	P,T3		;RECOVER ^C FOR ECHO
	HRRZ	F,LDBDDB(U)
	JUMPE	F,RICC2
	LDB	J,PJOBN##
	LDB	T1,LDPDEB	;DEFERRED ECHO BITS
	DPB	T1,JBYDEB##	;SAVE IN JOB TABLE
RICC2:	MOVSI	T1,L2LCCS	;SEE IF SECOND CONTROL C
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RICC1		;NO
	MOVSI	T1,LOLSTP+LOLSSO;YES - CLEAR STOP BIT
	ANDCAM	T1,LDBOST(U)
IFN FTKL10,<
	HRRZ	T1,LDBISR(U)	;GET ISR DISPATCH
	CAIE	T1,TTDDSP##	;IS THIS A -20F LINE
	JRST	RICC2B		;NO
	MOVSI	T1,LTLXFF	;YES, SET BIT TO INFORM -20F
	IORM	T1,LDBTTD(U)	;
	JRST	RICC2A		;SKIP REMOTE CHECK
>;END IFN FTKL10
RICC2B:
IFN FTNET,<
	SKIPL	LDBTTW(U)	;ANF NETWORK VIRTUAL TERMINAL?
		.CREF	LTLANF	;(CREF REFERENCE TO REAL SYMBOL)
	JRST	RICC2A		; NO, DON'T SET LRRXFF
	MOVEI	T1,LRRXFF	;TELL FE ABOUT XON/XOFF STATUS
	IORM	T1,LDBREM(U)	;
>;END IFN FTNET
RICC2A:	PUSHJ	P,CNCCHK	;YES. AM I ALLOWED TO BELIEVE THE CONTROL-C?
	  JRST RICC1		;SLAVE, OR NOT SECOND. JUST STORE
	PUSHJ	P,TTHALT	;JACCT AND TWO ^C^C
	HRRZ	F,LDBDDB(U)	;GET ATTACHED JOB
	JUMPE	F,RICC3		;MAKE SURE THERE IS ONE
	MOVE	T1,DEVMOD(F)	;IS OWNING JOB ATTACHED TO TERMINAL,
	TLNE	T1,TTYATC	;OR JUST USING TERMINAL AS IO DEVICE?
	JRST	RICC3		;ATTACHED. OK TO DO CONTROL C
	MOVEI	S,IODERR	;NOT ATTACHED
	IORB	S,DEVIOS(F)	;GIVE JOB AN ERROR BIT
	PUSHJ	P,TTWAKE	;AND WAKE IT UP
	SETZM	DEVNAM(F)	;MAKE IT INVISIBLE TO DEVSRC
	PUSH	P,U		;SAVE U IN CASE DDB IS KILLED
	PUSHJ	P,PTYDET	;GET LINE FREE OF DDB
	POP	P,U		;RESTORE U
RICC3:	POP	P,T1		;RESTORE STACK LEVEL
	PUSHJ	P,TSETI1	;FORCE ACTION. CLEAR BUFFERS
	PUSHJ	P,TSETBO	;BOTH INPUT AND OUTPUT. COMCON HAS
				; BEEN FLAGGED BY CNCCHK
	MOVEI	T1,JS.NTO	;PARTIAL BUFFER REMAINING
	SKIPE	F		;MAKE SURE THERE WAS A DDB (ELSE JOB# IS JUNK)
	ANDCAM	T1,JBTSTS##(J)	;CLEAR BIT
	MOVE	T2,FILXCP	;GET ^C ECHO
	PUSHJ	P,SETFLE	;PUT INTO ECHO STREAM NOW (SO TYPES BEFORE DOT)
	POPJ	P,		;DISCARD CHARACTER

RICC1:	MOVSI	T1,L2LCCS	;SET "^C LAST IN" BIT
	IORM	T1,LDBBY2(U)	;NOT SECOND. STORE BIT.
RICC5:	POP	P,T1		;RESTORE CHARACTER FLAGS
	JRST	CPOPJ1##	;AND TREAT AS RECEIVED CHARACTER
;HERE ON RECEIPT OF A ^D CHARACTER

RICD:	MOVEI	T1,JS.BPT	;GET THE BREAKPOINT ENABLED BIT
	LDB	T2,LDPLNO	;GET LINE NUMBER
IFE FTMP,<CAIE T2,TCONLN##>
IFN FTMP,<
	CAILE	T2,FRCLIN##	;IS IT A CTY?
	CAILE	T2,TCONLN##	;...
>
	JRST	RICD1		;NO
	TDNN	T1,JBTSTS##+0	;AND SOMEONE TYPE A "SET EDDT ON" COMMAND?
	JRST	RICD1		;NO
	MOVEM	17,CDSAV+17	;SAVE 17
	MOVEI	17,CDSAV	;PLACE TO SAVE ACS
	BLT	17,CDSAV+16	;SAVE THEM
	XCT	.CPDDT##	;ENTER EDDT (MAYBE)
	MOVSI	17,CDSAV	;RESTORE ALL ACS
	BLT	17,17		;AND
CDPAT::	POPJ	P,		;PATCH TO JFCL TO PASS ^D TO COMCON

;HERE FOR RANDOM "TIMESHARING" ^D - TRY TO FORCE A .BPT COMMAND

RICD1:	HRRZ	F,LDBDDB(U)	;GET DDB
	JUMPE	F,CPOPJ1##	;MAKE SURE THERE IS ONE
	LDB	T2,PJOBN##	;GET JOB NUMBER
	JUMPE	T2,CPOPJ1##	;CAN'T BE THE NULL JOB
	TDNN	T1,JBTSTS##(T2)	;IS JS.BPT TURNED ON?
	JRST	CPOPJ1##	;NO
	MOVEI	T1,TTFCXB	; FORCE A .BPT COMMAND
	PJRST	TTFORC		;AND LET COMCON WORRY ABOUT IT


	$LOW			;MAKE CD ADDRESSABLE BEFORE HIGHIN REACHED
CDSAV:	BLOCK	20		;PLACE TO SAVE ACS AT CD BREAKPOINT
	$HIGH
;HERE ON CONTROL H (BACKSPACE) TO DETERMINE HOW TO TREAT
;IN THE VARIOUS CASES LIKE APL ETC.

RIBSP:	LDB	T2,LDPAPL	;GET APL BIT
	JUMPN	T2,CPOPJ1##	;JUST STORE IN BUFFER (THIS APL)
	JRST	RIDEL		;NOT APL, TREAT LIKE RUBOUT
;HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M)

RICM:	MOVEI	T2,L2RXON	;IS XON TRUE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	CPOPJ1##	;YES. NOTHING SPECIAL. STORE.
	TRC	T3,15^!MC.NL	;NO. CHANGE IT TO A NEWLINE
	PJRST	RICRET		;GET NEW BITS AND GIVE CONTINUE RETURN

;HERE ON RECEIVE INTERRUPT OF A CONTROL O

RICO:	MOVEI	T1,LDROSU	;COMPLEMENT STATE OF OUTPUT SUPPRESS BIT
	XORM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
	PUSHJ	P,TSETBO	;CLEAR OUTPUT BUFFER
	MOVE	T2,FILXOP	;GET ^O ECHO
	PUSHJ	P,SETFLE	;SET TO ECHO
	POPJ	P,		;DISCARD CHARACTER
;HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON)

RICQ:	MOVSI	T2,L2LTAP	;HAS TERMINAL TAPE COMMAND BEEN TYPED?
	TDNE	T2,LDBBY2(U)	; ..
	JRST	RICQ7		;YES, HANDLE PAPER TAPE MODE
	MOVE	T2,LDBPAG(U)	;GET TERMINAL PAGING CONTROL
	TLNN	T2,LPLXNF	;PROCESSING XON/XOFF?
	PJRST	CPOPJ1##	;NO, DON'T DO ANYTHING SPECIAL WITH ^Q
	TLNN	T2,LPLSST	;IS TTY SSTOP SET?
	JRST	RICQ2		;NO, ALWAYS CLEAR STOP COUNTER ON ^Q
	MOVSI	T2,LOLSTP	;YES, BE PICKY ABOUT CURRENT STATE
	TDNE	T2,LDBOST(U)	;IS THE LINE STOPPED BY ^S?
	JRST	RICQ3		;YES, JUST CLEAR XOFF, LEAVE STOP COUNTER ALONE
	MOVSI	T2,LOLSSO	;NO. GET STOPPED-BY-SCNSER BIT
	TDNN	T2,LDBOST(U)	;IS TERMINAL OUTPUT "STOP"PED?
	JRST	RICQ4		;NO, IGNORE THE XON
RICQ2:	PUSHJ	P,CLRPCT	;RESET STOP COUNTER
	MOVSI	T2,LOLSTP+LOLSSO;CLEAR STOP BIT(S) FOR TERMINAL OUTPUT
RICQ3:	ANDCAM	T2,LDBOST(U)	;..
	MOVEI	T1,ISRCHP	;TELL REMOTE STATION ABOUT ^Q
	PUSHJ	P,@LDBISR(U)
RICQ4:	PJRST	TOPOKE		;AND GO START OUTPUT AGAIN

RICQ7:	MOVEI	T1,L2RXON	;TURN ON BIT IN LINE CHAR WORD
	IORM	T1,LDBBY2(U)	; ENTER HERE FOR OTHER BITS TOO
	MOVEI	T1,ISRCHP
	PUSHJ	P,@LDBISR(U)	;TELL REMOTE STATION ABOUT THE ^Q.
	PJRST	CHKXN1
IFN FTMIC,<			;IF MIC

;HERE ON RECEIVE INTERRUPT OF CONTROL P (PROCEED)

RICP:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	CPOPJ1##	;NO - JUST RETURN
	TLO	T2,LDLCHK!LDLMCP;YES - SET UP ^P FLAG
RICB2:	MOVEM	T2,LDBMIC(U)	;PUT WORD BACK
RICB3:	PJRST	MICWAK		;WAKE UP MIC

;HERE ON RECEIVE INTERRUPT OF CONTROL B (BREAK)

RICB:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	CPOPJ1##	;NO TREAT AS ORDINARY CHAR
	TLO	T2,LDLCHK!LDLMCB;YES - SET UP ^B FLAG
	JRST	RICB2		;AND TREAT AS ^P
> ;END OF IF MIC

;HERE ON A CONTROL T
RICT:	PUSHJ	P,DOCTLT	;PROCESS THE CONTROL-T
	  JRST	CPOPJ1##	;WE WANT TO STORE IT
	  JRST	[PUSHJ P,CLRPCT
		 JRST TTFORC]	;WE WANT TO DO USESTAT
	JRST	RIBUSY		;LINE ALREADY HAS A COMMAND

DOCTLT:	LDB	T2,LDPRTC	;GET BIT FOR TERMINAL RTCOMPAT
	JUMPN	T2,CPOPJ##	;IF IT IS =1 GIVE NON-SKIP RETURN
	MOVE	T2,LDBDCH(U)	;GET DEVICE FLAGS
	TLNE	T2,LDLSLV	;SLAVE?
	POPJ	P,		;YES--DO NOT FORCE CONTROL-T
	HRRZ	F,LDBDDB(U)	;GET LINKED DDB ADDRESS
	JUMPE	F,RICT1		;FORCE COMMAND IF ZERO
	MOVE	T2,DEVMOD(F)	;GET DEVICE BITS
	TLNN	T2,TTYATC	;CONTROLLING TERMINAL?
	JRST	CPOPJ##		;NO--JUST STORE THE CONTROL-T
RICT1:	MOVEI	T1,TTFCXW	;FORCE USESTAT
	SKIPL	LDBCOM(U)	;COMMAND ALREADY PENDING?
	JRST	CPOPJ1##	;NO--GIVE SINGLE SKIP
	JRST	CPOPJ2##	;YES--GIVE DOUBLE SKIP
;HERE ON A CONTROL R

RICR:	LDB	T2,LDPRTC	;RTCOMPATABILITY IN EFFECT?
	JUMPN	T2,CPOPJ1##	;JUMP IF SO, STORE CHARACTER IN THE INPUT BUFFER
	PUSHJ	P,FULLCQ	;COMMAND OR FULL CHARACTER SET?
	  JRST	CPOPJ1##	;YES, STORE CHARACTER
	TRC	T3,<"R"-100>^!MC.RTS	;CHANGE INTO .TYPE BEGIN FUNCTION
	PJRST	RICRET		;GET NEW BITS AND GIVE CONTINUE RETURN
;HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF)

RICS:	MOVSI	T2,L2LTAP	;HAS TERMINAL TAPE COMMAND BEEN TYPED?
	TDNE	T2,LDBBY2(U)	; ..
	JRST	RICS7		;YES, HANDLE PAPER TAPE MODE
	PUSH	P,T1		;SAVE CHARACTER BITS (FOR RICC5)

	MOVSI	T1,LOLSTP	;GET THE "STOPPED BY ^S BIT"
	PUSHJ	P,STPOIS	;STOP OUTPUT (BUT DON'T RESET STOP COUNTER YET)
	  JRST	RICC5		;TTY NO XONXOF - TREAT AS NORMAL CHARACTER
	MOVE	T1,LDBPAG(U)	;GET PAGING CONTROL
	TLNN	T1,LPLSST	;"TTY SSTOP" SET?
	PUSHJ	P,CLRPCT	;NO, RESET STOP COUNTER (IF ANY)
	JRST	TPOPJ##


RICS7:	MOVEI	T1,L2RXON	;THE "XON IS TRUE" FLAG
	ANDCAM	T1,LDBBY2(U)	;CLEAR IT
	MOVEI	T1,ISRCHP
	PJRST	@LDBISR(U)	;TELL REMOTE STATION ABOUT THE ^S.



STPOIP:				;STOP OUTPUT IN PROGRESS
	PUSHJ	P,CLRPCT
STPOIS:	MOVSI	T2,LPLXNF	;HAS "TTY XONXOF" BEEN ENABLED?
	TDNN	T2,LDBPAG(U)	;...
	POPJ	P,		;NO, DON'T DO ANYTHING SPECIAL
	IORM	T1,LDBOST(U)	;NO MORE OUTPUT UNTIL XON IS TYPED
	PJRST	SETCH1		;SKIP & TELL FE'S TO STOP NOW

BEATIT:	SKIPA	T2,[POINT 9,GAWTXT]
RIBUSY:	MOVE	T2,[POINT 9,BSYTXT]
	PJRST	SETNNP

BSYTXT:	BYTE	(9)102,165,163,171,FLLFLG
GAWTXT:	BYTE	(9)123,164,141,156,144,040,141,154,157,156,145,FLLFLG
;HERE ON RECEIVE INTERRUPT OF CONTROL V (QUOTE)

RICV:	LDB	T2,LDPQOT	;IS QUOTING ENABLED?
	JUMPE	T2,CPOPJ1##	;NO, JUST STORE NORMALLY
	MOVEI	T2,LISQOT	;LINE INPUT STATE=QUOTING
	PJRST	SETDCS		;SET DEFERRED CHARACTER STATUS
;ROUTINES TO IMPLEMENT 'TERMINAL PAGE N'

CLRPCT::SE1ENT			;ENTER SECTION 1
	LDB	T2,LDPSTB	;BASIC "STOP" SIZE
	CAIN	T2,1		;IF "TTY STOP 1",
	MOVEI	T2,2		;THEN ALLOW AT LEAST ONE LINE TO PRINT
	MOVNI	T2,-1(T2)	;NEGATIVE SO COUNTER COUNTS UP TO 0
				; ALSO OFFSET BY ONE TO ALLOW TIME TO STOP
				; FURTHER, IF NO VALUE SET (I.E., "0")
				; THEN THIS GIVES US ^D254 LINES BEFORE
				; WE MUST CHECK AGAIN
	ANDI	T2,377		;MASK TO ONLY 8-BIT'S WORTH
	DPB	T2,LDPSTC	;RESET "STOP" COUNTER
	POPJ	P,

INCPCT:	MOVEI	T2,001001	;TWO NINE-BIT INCREMENTS
	ADDB	T2,LDBLSW(U)	;INCREMENT LENGTH AND STOP COUNTERS
	TRNN	T2,LPRLC0!LPRSC0;EITHER COUNTER "OVERFLOW"?
	POPJ	P,		;NO, NOTHING SPECIAL HERE THEN

;EITHER TOP OF NEW FORM, OR TIME TO AUTOMATICALLY STOP OUTPUT

	LDB	T1,LDPLNB	;BASIC "LENGTH" SIZE
	MOVNI	T1,-1(T1)	;NEGATIVE SO COUNTER COUNTS UP TO 0
	ANDI	T1,377		;MASK TO ONLY 8-BIT'S WORTH
	TRNE	T2,LPRLC0	;LENGTH COUNTER HIT 0?
	DPB	T1,LDPLNC	;YES, RESET LENGTH COUNTER
	TRNN	T2,LPRSC0	;STOP COUNTER HIT 0?
	POPJ	P,		;NO, JUST LENGTH COUNTER, NOTHING SPECIAL

;TIME TO AUTOMATICALLY STOP OUTPUT

	MOVE	T1,LDBPAG(U)	;GET THE PAGING CONTROL FLAGS
	LDB	T2,LDPSTB	;AND THE BASIC STOP SIZE
	TLNE	T1,LPLSTP	;USER WANT TO AUTOMATICALLY STOP OUTPUT?
	CAIG	T2,0		;YES, A STOP SIZE SPECIFIED?
	PJRST	CLRPCT		;NO, IGNORE THEN

IFN FTNET,<
	SKIPL	T1,LDBREM(U)	;IF VTM + SET HOST
	.CREF	LRLVTM		;(PUT TESTED BIT IN CREF)
>
	PUSHJ	P,PTBTCH##	;CHECK FOR BATCH PTY
	  PJRST	CLRPCT		;DISABLE AUTO STOP FOR BATCH OR VTM LINES
	MOVSI	T1,LOLSSO	;GET "SCNSER STOPPED OUTPUT" BIT
	PUSHJ	P,STPOIP	;IF AT LIMIT, STOP OUTPUT, CLEAR COUNT
	  PJRST	CLRPCT		;STPOIP NON-SKIPS IF TERMINAL NO PAGE
	MOVSI	T2,LOLNBS	;NEED BELL SENT STATE BIT
	MOVE	T1,LDBPAG(U)	;GET PAGE CONTROL
	TLNN	T1,LPLSBL	;WANT BELL ON AUTO STOP?
	POPJ	P,		;NO BELL
	IORM	T2,LDBOST(U)	;SET THE STATE BIT
	PJRST	TOPOKE		;ENSURE OUTPUT WILL BE DONE
;PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING

REPIM:	MOVSI	T2,LPLXNF	;THE PROCESS XON/XOFF BIT
	TDNN	T2,LDBPAG(U)	;HAS SET TERMINAL XONXOF BEEN SET?
	JRST	REPIM0		;NO, DON'T LOOK FOR XON/XOFF
	MOVE	T2,T3		;SAVE CHARACTER
	ANDI	T3,CK.CHR	;CLEAR POSSIBLE JUNK BITS
	SKIPL	LDBATR(U)	;8-BIT TERMINAL?
	ANDI	T3,CK.CH7	;NO, ONLY 7 VALID DATA BITS
	CAIN	T3,21		;IS CHARACTER AN XON?
	JRST	RICQ		;YES, TREAT AS NON PIM XON
	CAIN	T3,23		;IS CHARACTER AN XOFF?
	JRST	RICS		;TREAT AS NON PIM XOFF IF SO
	MOVE	T3,T2		;RESTORE CHARACTER AS RECEIVED
REPIM0:	MOVE	T2,LDBTIC(U)	;# OF CHARS INPUT
	CAIL	T2,TTPWRN##	;TIME TO WARN HIM?
	JRST	[CAIL	T2,TTPMAX##	;YES, OVER MAXIMUM LIMIT?
		JRST	RCHLT1		;YES, PIM LIMIT EXCEEDED
		PUSHJ	P,SNDXOF	;NO, STILL HOPE, SEND XOFF
		PUSHJ	P,RCVWAK	;AND GET USER'S ATTENTION
		JRST	REPIM2]		;ACCEPT THIS CHARACTER
	CAIL	T2,TTPBRK##	;TIME TO WAKE UP USER?
	PUSHJ	P,RCVWAK	;YES, NUDGE HIM
REPIM2:	MOVE	T2,TTFREN##	;COUNT OF FREE CHUNKS IN SYSTEM
	CAIGE	T2,5		;STILL WITHIN REASONABLE LIMITS?
	JRST	RCHLT1		;NO, SHUT IT DOWN
	TRO	T3,CK.IMG	;MARK IMAGE-CHARACTER BIT
	SCNOFF			;NO INTERRUPTS
	STCHK	T3,LDBTIP(U),SONPPJ  ;PLACE CHARACTER IN BUFFER
	AOS	LDBTIC(U)	;INCREMENT COUNT
	MOVE	T2,LDBTIP(U)
	MOVEM	T2,LDBECT(U)	;MAKE CHAR LOOK ECHOED
	SCNON			;ALLOW INTERRUPTS
	SKIPN	T2,LDBPBK(U)	;GET AND TEST BREAK CHARACTER WORD
	JRST	RCVWAK		;NOTHING SPECIFIED, BREAK ON ALL
	ANDI	T3,CK.CHR	;CLEAR IMAGE-CHARACTER BIT FOR TEST
REPIM5:	LSHC	T1,9		;GET TEST CHARACTER
	XOR	T1,T3		;XOR WITH RECEIVED CHAR
	TRNE	T1,400		;7 OR 8 BIT COMPARE?
	 TRNE	T1,177		;7 BIT, MATCH?
	  TRNN	T1,377		;8 BIT, MATCH?
	   JRST	RCVWAK		;YES, BREAK CHAR, WAKE AND DISMISS
	JUMPN	T2,REPIM5	;NO, TRY NEXT
	JRST	CPOPJ##		;DONE, DISMISS INTERRUPT.
SNDXOF::SE1ENT			;ENTER SECTION 1
	MOVSI	T1,LPLXOF	;GET THE "XOFF HAS BEEN SENT" BIT
	TDNN	T1,LDBPAG(U)	;HAVE WE SENT ONE?
	JRST	SNDXF2		;NO, ALWAYS SEND THE FIRST XOFF
	MOVE	T1,LDBTIC(U)	;INPUT CHARACTER COUNT
	ADD	T1,LDBECC(U)	;PLUS THOSE NOT-QUITE-FULLY-INPUT
	IDIVI	T1,TTYMIC##	;ROUGHLY-MODULO TTYMIC?
	JUMPN	T2,CPOPJ##	;NO, DON'T SEND GOBS OF XOFFS
	MOVSI	T1,LPLXOF	;YES, SEND ANOTHER XOFF
				; (IN CASE THE UGLY RACE BIT US THE FIRST
				;  TIME AND THE PREVIOUS XOFF(S) GOT LOST)
SNDXF2:	IORM	T1,LDBPAG(U)	;SET THE BIT SO WE DON'T SEND TOO MANY
	PUSH	P,T3		;ISR WILL CLOBBER THIS
	MOVEI	T3,IRRCSL	;CODE TO SAY BUFFER LOW
	MOVEI	T1,ISRREM	;
	PUSHJ	P,@LDBISR(U)	;NOW CALL ISR
	  SKIPA	T2,FLPPXF	;ISR DID'T SEND IT. WE MUST
	JRST	T3POPJ##	;XOFF SENT, POP T3 AND RETURN
	PUSHJ	P,SETXNP	;SET FILLER
	PUSHJ	P,TOPOKE	;MAKE SURE IT GETS OUT
	JRST	T3POPJ##	;RESTORE T3 AND RETURN
;HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY

RICU:	PUSHJ	P,FULLCQ	;BREAK ON ALL CHARACTERS?
	  JRST	CPOPJ1##	;YES. STORE THE ^U IN BUFFER
	TRC	T3,<"U"-100>^!MC.DL	;CONVERT TO DELETE-LINE
	PJRST	RICRET		;GET NEW BITS AND GIVE CONTINUE RETURN
RIDLN:	PUSHJ	P,STOPCM	;STOP COMCON
	SCNOFF			;NO INTERRUPTS
RIDLN1:	SKIPN	T1,LDBBKI(U)	;ANY BREAK POSITION SAVED?
	JRST	RIDLN3		;NONE THERE. CHECK FOR ECHOED CHARS
	CAME	T1,LDBTIP(U)	;ANYTHING TO DELETE ?
	PUSHJ	P,DELCHR	;DELETE 1 CHAR
	  JRST	SONPPJ		;NOTHING LEFT TO DELETE
	JRST	RIDLN1		;LOOP OVER LINE
RIDLN3:	SKIPN	T1,LDBBKU(U)	;ANY BREAK POSITION SAVED?
	JRST	TSETI2		;NONE THERE.  JUST CLEAR THE BUFFER
	CAME	T1,LDBTIP(U)	;ANYTHING TO DELETE?
	PUSHJ	P,DELCHR	;DELETE 1 CHAR
	  JRST	SONPPJ		;NOTHING LEFT
	JRST	RIDLN3		;LOOP OVER LINE

DELCHR:	SOSGE	T3,LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	[SETZM	LDBECC(U)	;CLEAR ECHO COUNT
		MOVSI	T1,L3LEHD!L3LEPD ;BITS THAT MIGHT BE ON FOR OUR CHAR
		ANDCAM	T1,LDBBY3(U)	;MAKE SURE THEY'RE NOT
		SOSL	LDBTIC(U)	;CHECK FOR ECHOED INPUT
		JRST	[SETO	T4,	;SET VISIBILITY FLAG
			JRST	DELCH3]	;ERASE THESE TOO
		SETZB	T3,LDBTIC(U)	;CLEAR INPUT COUNT
		SETZM	LDBIIC(U)	;CLEAR INVISIBLE COUNT
		SETZM	LDBIEC(U)	;FOR BOTH SIDES
		MOVE	T1,LDBTIP(U)
		MOVEM	T1,LDBECT(U)	;ENSURE EMPTY ECHO STREAM
		PUSHJ	P,INPCHI	;MAKE SURE IT'S CONSISTENT
		  JRST	DELCHR		;TRY SOME MORE IF NOT
		POPJ	P,]		;RETURN
DELCH3:	LDB	T1,LDBTIP(U)	;GET CHARACTER TO BE WIPED
	TRNE	T1,CK.NIS	;IF INVISIBLE CHARACTER
	JRST	[SKIPL	T3	;YES, DOING ECHO STREAM?
		SOSA	LDBIEC(U)	;YES, DECREMENT INVISIBLE CHAR COUNT
		SOS	LDBIIC(U)	;NO, INPUT, DECREMENT ITS COUNT
		JRST	DELCH4]	;REJOIN
	TRNE	T1,CK.FDE	;NOT INVISIBLE, NEED TO ECHO?
	SETO	T4,		;ECHOED CHARACTER, SET FLAG
DELCH4:	SETO	T1,		;AMOUNT TO BACK UP
	ADJBP	T1,LDBTIP(U)	;GET NEW COPY OF BYTE POINTER
	MOVEI	T2,CK.BDY##(T1)	;SEE IF HIT HEADER WORD
	TRNN	T2,CK.BDY##	;WELL...
	JRST	[SSX	T2,MS.SCN	;SET SECTION NUMBER
		HLRZ	T1,CK.BTH##(T2)	;BACKUP
		JUMPE	T1,DELCH6	;TEST FOR ERROR ON ZERO POINTER
		ADD 	T1,[POINT CK.WID,CK.BDY##,35] ;MAKE INTO BYTE POINTER
		JRST	.+1]
DELCH5:	MOVEM	T1,LDBTIP(U)	;STORE ADJUSTED POINTER
	JUMPG	T3,CPOPJ1##	;IF NO ECHO STREAM INTACT
	MOVEM	T1,LDBECT(U)	;NO, MAKE SURE IT STARTS CORRECTLY
	JRST	CPOPJ1##

DELCH6:	SKIPG	T3		;IF ECHO STREAM IS OK,
	SKIPA	T1,LDBTIT(U)	;NO, GET TYPEIN TAKER
	MOVE	T1,LDBECT(U)	;YES, GET ECHO TAKER
	MOVE	T2,T1		;COPY IT
	IBP	T2		;GET BUMPED COPY
	CAME	T2,LDBTIP(U)	;BACKING UP TO A PLACE WE UNDERSTAND?
	STOPCD	CLRSTP,DEBUG,DELCBD,	;++DELCHR WENT BAD
	JRST	DELCH5		;YES, GO FOR IT
RECHLT:	POP	P,T1		;RESTORE T1
RCHLT1::SE1ENT			;ENTER SECTION 1
	MOVEI	T3,IRRCNS	;CODE FOR CHAR NOT STORED
	MOVEI	T1,ISRREM
	PUSHJ	P,@LDBISR(U)	;TELL THE ISR CHAR NOT STORED
	  TRNA			;FE WANTS BELL SENT
	JRST	RCHLT2		;FE WANTS NO BELL
	MOVSI	T2,LOLNBS	;NEED BELL SENT FLAG
	IORM	T2,LDBOST(U)	;LIGHT STATUS FLAG (LEAVE POSSIBLE XOFF POINTER ALONE)
RCHLT2:	PUSHJ	P,TOPOKE	;START TYPING IF NEEDED (USUALLY NOT NEEDED)
	PJRST	ECHBRK		;TRY TO WAKE JOB, THEN
				;DISMISS INTERRUPT, JUNKING CHARACTER
;HERE ON A RUBOUT OR CONTROL W AT INTERRUPT LEVEL

RICW:	PUSHJ	P,FULLCQ	;BKA OR FCS?
	  JRST	CPOPJ1##	;YES. STORE FOR READER
	TRC	T3,<"W"-100>^!MC.DW	;CONVERT TO DELETE-WORD
	PJRST	RICRET		;GET NEW BITS AND GIVE CONTINUE RETURN


RIDEL:	PUSHJ	P,FULLCQ	;BKA OR FCS?
	  JRST	CPOPJ1##	;YES. STORE FOR READER
	MOVEI	T2,L2RXON	;PAPER TAPE IN EFFECT?
	TDNE	T2,LDBBY2(U)	;YES, DISCARD RUBOUT
	POPJ	P,		;YES. DISCARD RUBOUT
	MOVE	T1,T3		;COPY CHARACTER THAT BROUGHT US HERE
	ANDI	T1,CK.CHR	;MASK OFF CRUFTY BITS
	CAIE	T1,010		;WAS IT BACKSPACE?
	TRCA	T3,177^!MC.DC	;NO, MAKE IT META-RUBOUT
	TRC	T3,010^!MC.BS	;YES, MAKE IT META-BS
	JRST	RICRET		;MUST DEFER TO XMTECH

;SUBROUTINE TO ADJUST HORIZONTAL POSITION WHEN ERASING CHARACTERS
;CALL WITH T2 = NUMBER OF POSITIONS TO BACKUP, RETURNS CPOPJ, T2 INTACT

BACKUP:	PUSH	P,T2		;SAVE T2
	MOVEI	T3,10		;BACKSPACE
BACKU1:	PUSHJ	P,ADJHP		;BACKUP 1 CHARACTER
	SOJG	T2,BACKU1	;LOOP FOR ALL
	JRST	T2POPJ		;RESTORE T2 AND RETURN

;SUBROUTINE TO DETERMINE IF THE CURRENT TERMINAL IS A VIDEO TERMINAL
; I.E., SPECIFIED AS SUCH BY THE USER TYPING A TTY TYPE COMMAND
; RETURNS CPOPJ IF NOT, CPOPJ1 IF SO, T1 POINTS AT CHARACTERISTICS TABLE
; ENTRY FOR THE TERMINAL TYPE

TTVID:	MOVSI	T1,LDLLCP	;LOCAL COPY BIT
	TDZE	T1,LDBDCH(U)	;LINE DOING OWN ECHOING
	POPJ	P,		;YES, AVOID VIDEO STUFF (T1=0)
	LDB	T1,LDPTTT	;GET TERMINAL TYPE AS SET BY COMMAND
	JUMPE	T1,CPOPJ##	;GO IF NONE SPECIFIED
	TRZE	T1,100		;CUSTOMER DEFINED TERMINAL TYPE ?
	MOVNI	T1,(T1)		;YES, NEGATIVE TABLE INDEX
	LSH	T1,1		;2 WORDS PER ENTRY
	SKIPE	TCRTAB##+1(T1)	;SKIP IF NOT A VIDEO TERMINAL
	AOS	(P)		;IT IS!
	POPJ	P,		;RETURN
;HERE ON ANY OF THE THREE ALTMODES, TO DECIDE ON CONVERSION TO STDALT
RIALT:	PUSHJ	P,RIALTO
	JRST	CPOPJ1##

RIALTO:	MOVEI	T2,(T3)		;GET A COPY OF THE CHAR.
	ANDI	T2,CK.CHR	;ISOLATE CHAR (REMOVE IMAGE/ECHO BITS)
	CAIN	T2,STDALT	;CHECK FOR TRUE ESC
	POPJ	P,
	MOVEI	T1,0		;NO, ASSUME DATA CHAR
	MOVSI	T2,LPLALT	;CONVERT OLD ALTMODES?
	TDNN	T2,LDBPAG(U)	;TEST IT
	JRST	RIALT2		;YES, SO GO DO IT
	MOVE	T2,LDBDCH(U)	;LINE FLAG BITS
	TLNE	T2,LDLLCT	;NO, BUT SHOULD WE CONVERT TTY UC?
	TRC	T3,040		;YES, SO CHANGE IT
	POPJ	P,		;ALL DONE
RIALT2:	MOVEI	T3,STDALT	;YES USE THE STANDARD ALTMODE
	MOVE	T1,CHTABL(T3)	;NOW A BREAK, SO GET ITS BITS
	POPJ	P,		;STORE WHATEVER THIS DECIDED ON
;RECEIVE INTERRUPT ROUTINE FOR LINE CONTROL TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH
;  TRANSACTION CODE IN T3,
;  PHYSICAL LINE # IN U (IDX FOR LINTAB, LDBDCH, ETC)
;    U'S RANGE CHECKED BY INTERRUPT ROUTINE
;  AC'S & PDL SETUP


LNCREC::SE1ENT			;ENTER SECTION 1
	MOVE	U,LINTAB##(U)
	CAIN	T3,LNTEHC	;DISPATCH ON CHARACTER CODE IN T3
	JRST	LNREHC		;ENABLE HUNG CHECK
	CAIE	T3,LNTDHC
	POPJ	P,		;ILLEGAL CODE--IGNORE

	MOVEI	T3,LDRSHC	;DISABLE HUNG CHECK
	IORM	T3,LDBDCH(U)	;  TURN ON LDRSHC
	POPJ	P,

LNREHC:	MOVEI	T3,LDRSHC	;TURN OFF LDRSHC
	ANDCAM	T3,LDBDCH(U)
	POPJ	P,
;RECEIVE INTERRUPT ROUTINE FOR DATASET TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH TRANSACTION CODE IN
; T3, DSCTAB INDEX IN U, RANGE ALREADY CHECKED BY INTERRUPT
; ROUTINE, AC'S AND PDL SET UP.


DSCREC::SE1ENT			;ENTER SECTION 1
	MOVE	T2,DSCTAB##(U)	;GET TABLE ENTRY FIRST
	TLNE	T2,DSCBLI	;IGNORE INTERRUPTS?
	POPJ	P,0		;YES. DO SO.
IFN FTPI,<PUSHJ P,SIGDSC>	;SIGNAL, DATA SET STATUS CHANGE
	CAIN	T3,DSTRNG	;DISPATCH ON CODES
	JRST	DSRRNG		;RING FROM DATAPHONE
	CAIN	T3,DSTON	;CARRIER ON?
	JRST	DSRON		;YES.
	CAIN	T3,DSTPND	;DIALLER WANT ANOTHER DIGIT
	JRST	DSRPND		;YES

	CAIN	T3,DSTOFF	;OFF INTERRUPT?
	TLNN	T2,DSCHWC	;YES. DID I THINK HE WAS ON?
	POPJ	P,0		;NO. FORGET IT.
	TLNN	T2,DSCSWC	;DO I THINK HE SHOULD BE ON?
	JRST	DSROF1		;NO. JUST GO CLEAR HIM OUT.
	MOVEI	T1,5		;YES. TIME OUT IN CASE OF BRIEF FAILURE
	DPB	T1,DSTMPL	;STORE IN TIME BYTE.
	MOVSI	T1,DSCHWC	;CLEAR THE CARRIER BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCFAI	;AND FLAG POSSIBLE FAILURE CONDITION
	IORM	T1,DSCTAB##(U)	; ..
	POPJ	P,0		;LET CLOCK TIME HIM OUT NOW.
DSROF1::SE1ENT			;ENTER SECTION 1
	MOVSI	T1,DSCHWC!DSCSWC!DSCIC2
	ANDCAM	T1,DSCTAB##(U)	;CLEAR ALL THESE BITS IN TABLE
	HRRZ	T1,DSCTAB##(U)	;GET TERMINAL NUMBER FOR THIS MODEM
	CAMN	T1,DSDUNI##	;DIALLER CODE USED BY IT?
	SETOM	TTYDDL##	;YES. CLEAR INTERLOCK TO FREE IT.

	MOVEI	T3,DSTOFF	;AND SEND OFF-COMMAND TO DEVICE
DSCCAL::SE1ENT			;ENTER SECTION 1
	HRRZ	T2,DSCTAB##(U)	;T2 := LINE NUMBER
	MOVEI	T1,ISRDSC	;DATASET CONTROL FUNCTION
	MOVE	T2,LINTAB##(T2)	;LDB ADDRESS
	PJRST	@LDBISR(T2)	;DISPATCH TO INTERRUPT SERVICE

;SUBROUTINE TO SIGNAL DATA SET STATUS CHANGE
; ENTER T3=TRANSACTION CODE
IFN FTPI,<
SIGDSC::SE1ENT			;ENTER SECTION 1
	HRRZ	T1,T2		;T1 := LINE NUMBER
	MOVE	T1,LINTAB##(T1)	;GET LDB ADDRESS
	HRRZ	F,LDBDDB(T1)	;GET ADDRESS OF DDB
	MOVE	T4,J		;SAVE J
	JUMPE	F,SIGDS1	;ALL DONE IF ZERO
	LDB	J,PJOBN##	;GET JOB NUMBER
	JUMPE	J,SIGDS1	;JUMP IF JOB 0 (CAN THAT HAPPEN?)
	HRROI	T1,C$DSET	;GET CONDITION TO SIGNAL
	PUSHJ	P,PSIJOB##	;NOTIFY ENTIRE JOB OF CONDITION (EACH JCH)
SIGDS1:	MOVE	J,T4		;RESTORE J
	POPJ	P,		;RETURN
> ;END IFN FTPI
;STILL IN FTMODM
DSRON:
	TLNN	T2,DSCDLW	;IN DIALLER WAIT?
	JRST	DSRON1		;NO.
	MOVSI	T1,DSCDLW!DSCEON	;YES. CLEAR FLAGS FOR DIALLER
	ANDCAM	T1,DSCTAB##(U)	;IN TABLE IN CORE
	SETOM	TTYDDL##	;FREE UP DIALLER CODE
	MOVSI	T1,DSCDLC	;SET SUCCESSFUL COMPLETION BIT
	IORB	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	PUSH	P,T2		;SAVE OLD STATUS
	PUSHJ	P,DSCWAK	;WAKE THE JOB, IF ANY STILL THERE.
	POP	P,T2		;RESTORE OLD BITS
DSRON1:
;		LOCAL LINES. THIS ALLOWS USER TO GET SIGN ON MESSAGE
	HRRZ	T1,DSCTAB##(U)	;GET REAL LINE NUMBER
	MOVE	T1,LINTAB##(T1)	;GET ADDRESS OF LDB
	MOVE	T1,LDBDCH(T1)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A REAL DATASET LINE?
	JRST	DSRON2		;NO--LOCAL TERMINAL JUST CAME UP
	TLNE	T2,DSCHWC	;HE CAME ON. IS THAT NEWS TO ME?
	POPJ	P,0		;I THOUGHT HE WAS ON. FORGET IT.
	TLNN	T2,DSCSWC	;DO I WANT HIM ON?
	JRST	DSROF1		;NO. GO FORCE HIM OFF.

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVSI	T1,DSCTMM+DSCFAI;YES. CLEAR TIME AND FAILURE BITS
	ANDCAM	T1,DSCTAB##(U)	;IN THE TABLE (STILL IN T2)
	MOVSI	T1,DSCHWC	;MARK THAT HE CAME ON
	IORM	T1,DSCTAB##(U)	;IN TABLE
	TLNE	T2,DSCFAI+DSCDLW;WAS ALL THIS A BRIEF FAILURE?
	POPJ	P,0		;YES. JUST DISMISS, HE'S BACK.
	MOVSI	T1,DSCBLI+DSCNCR;NO. NEW GUY. SET BLIND AND DELAY BITS
	HRRZ	F,T2		;GET JUST LINTAB INDEX
	MOVE	F,LINTAB##(F)	;LDB
	HRRZ	F,LDBDDB(F)	;DDB
	JUMPE	F,DSRN1A	;GO IF NO DDB
	MOVE	T4,DEVMOD(F)	;CHARACTERS
	TLNN	T4,TTYATC	;IF CONSOLE
	TRNN	T4,ASSCON!ASSPRG;AND NOT ASSIGNED
DSRN1A:	TLO	T1,^D60		;SET TIME OUT
	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
DSRON2:	HRRZ	U,T2		;GET JUST LINTAB INDEX
	MOVE	U,LINTAB##(U)	;GET LDB ADDRESS FOR LINE
	PUSHJ	P,TSETBI	;CLEAR INPUT BUFFER
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE,
	PUSHJ	P,VTMDSO##	;  TURN CARRIER AND QUEUE LINE FOR SERVICE
>
	MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	DEBUGF##
	POPJ	P,
	HRRZ	F,LDBDDB(U)	;GET DDB
	JUMPN	F,CPOPJ##	;DO NOT RUN INITIA IF THERE IS A
				; JOB ON THE LINE
	MOVEI	T1,TTFCXH	;GET HELLO COMMAND INDEX
	JRST	TTFORC		;FORCE HELLO COMMAND
DSRRNG:	MOVE	T1,STATES##	;PHONE RINGING. MAY I ANSWER?
	TRNE	T1,ST.NRL	;CHECK THE SCHEDULE COMMAND WORD
	POPJ	P,0		;NOT ALLOWED. IGNORE.
	PUSH	P,U		;SAVE PTR TO DSCTAB
	HRRZ	U,DSCTAB##(U)	;GET REAL LINE NUMBER
	MOVE	U,LINTAB##(U)	;GET ADR OF LDB
	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A DATASET LINE?
	JRST	UPOPJ##		;NO
	HRRZ	F,LDBDDB(U)	;DDB PTR
	JUMPE	F,DSRRN2	;NO JOB, ALL OK
	MOVE	T1,DEVMOD(F)	;DEVICE BITS
	TLNN	T1,TTYATC	;CONTROLLING TTY?
	JRST	DSRRN2		;NO, SO NO JOB
				;IF WE GET HERE, WE HAVE RING ON LINE
				; WITH A JOB, WHICH IS NOT SUPPOSED TO
				; HAPPEN.  TO PREVENT SECURITY PROBLEMS,
				; WE DETATCH THE JOB
	PUSHJ	P,DSCDET	;DETACH OR KILL IF NOT LOGGED IN.
DSRRN2:	POP	P,U		;RESTORE DSCTAB PTR
	MOVEI	T3,0		;CLEAR VARIOUS
	DPB	T3,DSTMPL	; TIMERS
	MOVSI	T1,DSCFAI+DSCTMM;CLEAR THE MOMENTARY FAILURE BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCSWC+^D30	;TURN ON ALLOW BIT, AND TIME.
DSRRN1:	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	MOVEI	T3,DSTON	;SEND A TURN-ON COMMAND TO DEVICE-
	PJRST	DSCCAL		; DEPENDENT ROUTINE, AND DISMISS


DSCDET:	MOVEI	T1,TTFCXD	;DO THE DETACH BY
	PJRST	TTFORC		; FORCING A .BYE
DSRPND:	TLNE	T2,DSCEON	;SENT ALL DIGITS?
	POPJ	P,0		;YES. IGNORE REQUEST
	MOVEI	T1,^D60		;ONE MINUTE FROM SENDING DIGIT
	DPB	T1,DSTMPL	;INTO TIME-OUT OF DATASET
	MOVSI	T1,DSCEON	;FLAG END OF NUMBER SENT, IF TRUE.
	ILDB	T3,TTYDDA##	;GET ANOTHER DIGIT
	CAIN	T3,17		;END OF NUMBER CODE?
	JRST	DSRPN1		;YES
	ADDI	T3,DSTPND	;CONVERT TO TRANSACTION CODE FOR XXXINT
	PJRST	DSCCAL		;AND SEND IT OUT


DSRPN1:	IORM	T1,DSCTAB##(U)	;SET FLAG IN TABLE
	POPJ	P,0		;DON'T SEND NUMBER

	SUBTTL	KS10 CTY AND KLINIK TERMINAL SERVICE

IFN FTKS10,<
CT0INT::SKIPN	.CPFEF##	;HAS FRONT END INTERRUPTED ?
	JRST	.-1		;ON THROUGH SKIP CHAIN
	WRPI	CLRCTY##	;CLEAR THE INTERRUPT
	SETZM	.CPFEF##	;CLEAR THE FLAG
	JSR	SCNSAV##	;SAVE AC'S ETC.
	MOVE	T3,KLIIWD	;GET KLINIK INPUT WORD
	TRNN	T3,KLIIVL	;IS THERE INPUT?
	  JRST	CTYIN1		;NO--PROCEED
	SETZM	KLIIWD		;YES--CLEAR IT
	MOVEI	U,KLILIN##	;GET KLINIK LINE NUMBER
	PUSHJ 	P,RECINT	;PASS TO SCNSER
CTYIN1:	MOVE	U,LINTAB+KLILIN## ;LDB FOR KLINIK LINE
	SKIPL	LDBDCH(U)	;IS KLINIK OUTPUT ACTIVE?
	SKIPE	KLIOWD		;YES--IS OUTPUT WORD AVAILABLE?
	JRST	CTYIN2		;NO--PROCEED
	MOVEI	U,KLILIN##	;KLINIK LINE NUMBER
	PUSHJ	P,XMTINT	;SEE IF MORE TO TYPE
CTYIN2:	SKIPN	T3,CTYIWD	;ANY CTY INPUT?
	  JRST	CTYIN3		;NO--PROCEED
	SETZM	CTYIWD		;YES--CLEAR IT
	MOVEI	U,CTYLIN##	;CTY LINE NUMBER
	PUSHJ	P,RECINT	;PASS TO SCNSER
CTYIN3:	MOVE	U,LINTAB+CTYLIN## ;GET LDB ADR FOR CTY
	SKIPL	LDBDCH(U)	;IS CTY TYPING ?
	SKIPE	CTYOWD		;AND IS OUTPUT WORD FREE ?
	JRST	CTYIN4		;NOT TYPING OR STILL BUSY
	MOVEI	U,CTYLIN##	;LINE NUMBER FOR CTY
	PUSHJ	P,XMTINT	;TRY TO TYPE MORE STUFF
CTYIN4:	POPJ	P,		;RETURN
>;END IFN FTKS10
	SUBTTL	FILLERS AND SIMULATION ROUTINES

;ROUTINE TO SET UP FILLERS FOR OUTPUT CHARACTERS
;CALL WITH
;	MOVE	T3,CHARACTER
;	MOVE	T1,CHTABL(T3)
;	PUSHJ	P,SETFLO
;	  <CHARACTER NEEDS FILLERS, ALREADY SETUP>
;	<CHARACTER NEEDS NO FILL>


SETFLO:	TLZ	T1,CHUAE+CHALT+CHCRE	;THESE ECHO MODES NOT USED ON OUTPUT
	TLO	T1,CHFILO	;FLAG OUTPUT-FILLER REQUEST
	JRST	SETFL2		;REST OF ROUTINE SAME AS ON INPUT

;ROUTINE TO SET FILLER POINTER FOR INPUT CHARACTERS (ECHOING)

SETFLI:	TLNE	T1,CHALT	;IS THIS A POSSIBLE ALTMODE?
	PUSHJ	P,RIALTO	;YES, SEE IF IT IS A REAL ALTMODE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;COMMON CODE FOR SETFLI/SETFLO

SETFL2:	MOVSI	T2,L2LDEL	;BACKSLASH BIT
	TDNE	T2,LDBBY2(U)	;NEED ONE?
	JRST	[ANDCAM	T2,LDBBY2(U)	;YES, CLEAR BIT
		 MOVE	T2,FLLBSP	;GET BACKSLASH POINTER
		 PUSHJ	P,SETFLE	;PUT INTO ECHO/FILL STREAM
		 AOS	LDBHPS(U)	;COUNT UP FOR HPOS
		 JRST	.+1]	;REJOIN
	MOVE	T2,LDBHPS(U)	;GET HORIZONTAL POSITION COUNTER
	MOVE	T4,LDBDCH(U)	;GET DEVICE BITS
	TLNE	T4,LDLDLR	;USER WANT DOLLAR SUPPRESSED?
	TLZ	T1,CHALT+CHUAE+CHCRE	;YES. DO SO.
	TLNE	T1,CHUAE	;WILL ^X BE ADDED?
	ADDI	T2,2		;YES. ADD 2 TO HPOS
	TLNE	T1,CHALT	;IS IT GETTING A DOLLARSIGN?
	ADDI	T2,1		;YES. COUNT IT.
	JUMPLE	T2,SETFI1	;IF NOT AT END OF SCREEN
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	SETFI1		;IT IS, NO FREE CRLF
	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	SETFI1		;NO. FORGET IT.
;	PJRST	SETCRF		;YES, FALL INTO SETCRF

;SETCRF -- ROUTINE TO SETUP A FREE CRLF POINTER

SETCRF:	PUSHJ	P,SCNBOL	;RESET LINE COUNTERS IN ANY CASE
	SKIPGE	LDBTTW(U)	;IS THIS AN ANF NETWORK VIRTUAL TERMINAL?
		.CREF	LTLANF	;(CREF REFERENCE TO REAL SYMBOL)
	JRST	SETCR5		;YES, THEN NO FILLER (THE REMOTE COMPUTER
				; WILL SUPPLY THE FREE <CR><LF>, WE NEED
				; MERELY NOTE THAT A NEW LINE IS STARTING)
	MOVE	T2,FLLCRF	;GET CRLF FILL POINTER
SETCR3:	PUSHJ	P,SETFLE	;SETUP THE APPROPRIATE FILLER POINTER
	MOVSI	T2,LDLLCP	;DON'T ECHO INPUT CHARACTER AFTER FREE CRLF
	TLNN	T1,CHFILO	; BUT IF OUTPUT, DON'T EAT A CHARACTER
	TDNN	T2,LDBDCH(U)	;IF LOCAL COPY IS SET
	PUSHJ	P,REEAT		;YES, RE-EAT THIS CHARACTER
	POPJ	P,		;NON-SKIP RETURN (NEEDED CRLF)

SETCR5:	MOVE	T2,T3		;SCRATCH COPY OF CHARACTER
	ANDI	T2,CK.CH7	;JUST SEVEN-BIT ASCII
	CAIL	T2,40		;IS CHARACTER A
	CAIL	T2,177		; NORMAL PRINTING ASCII GRAPHIC?
	TLNE	T1,CHALT!CHUAE	;NO, CONTROL, IF EITHER "$" OR "^X" FORM
	AOS	LDBHPS(U)	;THEN COUNTS AS A PRINTING CHARACTER
	TLNE	T1,CHUAE	;IN ADDITION, IF "^X" FORM
	AOS	LDBHPS(U)	; THEN COUNTS AS TWO PRINTING CHARACTERS
	PUSHJ	P,INCPCT	;COUNT LINES OUTPUT FOR TTY PAGE N
	MOVE	T4,LDBOST(U)	;GET LEFT-HALF CHARACTERISTICS
	TLNN	T4,LOLSSO	;DID INCPCT HIT A PAGE BREAK?
	JRST	CPOPJ1##	;NO, JUST OUTPUT THE FIRST CHARACTER
;HERE IF THE FREE <CR><LF> THAT WE KNOW THE REMOTE IS ABOUT TO OUTPUT
;(AS SOON AS IT SEES THE CHARACTER IN T3) WILL ALSO BREAK THE PAGE LIMIT.
;WE MUST SUPPLY THE FREE <CR><LF> AND THEN STOP IN ORDER TO MAKE THE
;REMOTE BEHAVE THE SAME AS LOCALLY-OWNED TERMINALS. THIS RELYS ON THE
;FACT THAT XMTSPC WILL FORCE OUT THE FILLER POINTER EVEN IF THE LINE
;IS XOFFED - A DUBIOUS FEATURE AT BEST.

	PUSHJ	P,SCNBOL	;OOPS - RE-CLEAR HORIZONTAL POSITION

;TECHNICALLY, INCPCT SHOULD BE UNDONE, SINCE THE <CR><LF> COMING WILL
;LEAVE IT OFF BY ONE, BUT THE XON NEEDED TO GET OUT OF THE STUCK STATE
;WILL RESET THE PAGE COUNTER, SO . . .

	MOVE	T2,FLLCRP	;WANT JUST A <CR><LF> - THE
				; -11 WILL PROVIDE ANY FILL NEEDED.
	JRST	SETCR3		;GO OUTPUT A NEW LINE


;HERE TO FORCE THE RE-EAT OF A CHARACTER AFTER FREE CRLF

REEAT:	MOVSI	T2,LOLREO	;ASSUME FOR OUTPUT
	TLNN	T1,CHFILO	;WAS IT?
	MOVSI	T2,LOLREE	;NO, FOR ECHO
	IORM	T2,LDBOST(U)	;SET FOR AFTER WE COME BACK
	POPJ	P,		;AND RETURN TO CALLER
SETFI1:	TLNN	T1,CHFIL	;THIS CHAR NEED FILLERS?
	JRST	SETFI2		;NO.
	MOVE	T2,T3		;SAVE CHARACTER
	ANDI	T2,CK.CHR	;MASK DOWN
	MOVE	T2,CHTABL(T2)	;ORIGINAL BITS
	TLNN	T2,CHFIL	;CHARACTER REALLY NEED FILL?
	PJRST	SETFCE		;NO, JUST TYPE VIA FILL/ECHO STREAM AND RETURN
	PUSH	P,T3		;SAVE THE CHARACTER
				;*** CHAR MUST BE AT 0(P) FOR SIMULATORS ***
				;*** EVEN THOUGH THIS IS BAD PRACTICE
	ANDI	T3,CK.CHR	;TRIM FUNNY BITS
	MOVE	T4,LDBDCH(U)	;GET DEVICE BITS (USED BY MOST FILL ROUTINES)
	CAIG	T3,15		;NEED TO CALL ROUTINE FOR IT?
	JRST	@SETFLD-10(T3)	;YES. GO DO IT.
	CAIL	T3,21		;CONTROL Q THRU T?
	JRST	SETFI6		;YES. THEY HAVE SPECIAL HANDLERS TOO
	PUSHJ	P,SETFLC	;GET FILL CLASS
	JUMPE	T2,ZFLPOP	;NO. USER WANT FILLER SUPPRESSED?
	SKIPA	T2,FILLP1	;NO. ASSUME ONE FILLER IS ENOUGH
ZFLPOP:	MOVEI	T2,0		;POINTER FOR NO FILLERS
FLLPOP:	PUSHJ	P,FLLCHO	;CHARACTER TO TYPE BEFORE STRING
SCCHPJ:	POP	P,T3		;RESTORE CHARACTER (MAYBE WITHOUT TYPING IT)
	PJRST	SETFLE		;TYPE THE FILLER POINTER AND RETURN NON-SKIP
				; TO SHOW FILL WAS NEEDED

SETFI2:	TLNN	T1,CHUAE+CHALT+CHCRE	;ECHO AS ^X OR $ ?
	JRST	CPOPJ1##	;NO. NOTHING SPECIAL. JUST SEND.
	TLNE	T1,CHALT	;ALTMODE?
	JRST	SETFI3		;YES.
	MOVE	T2,FLLUPA	;GET POINTER TO UPARROW CONST
	PUSHJ	P,SETFLE	;TYPE IT
	TRC	T3,100		;CONVERT TO PRINTABLE FORM
	MOVEI	T2,2		;WIDTH OF ^X
	ADDM	T2,LDBHPS(U)	;UPDATE HPOS
	TLNN	T1,CHCRE	;ALSO NEED <CR><LF>?
	PJRST	SETFCE		;NO, JUST TYPE ADJUSTED CHARACTER
	PUSHJ	P,SETFCE	;YES, TYPE MODIFIED CHARACTER
	PJRST	METNLF		;TYPE CRLF FILL AND RETURN

SETFI3:	MOVE	T2,FLLDLR	;GET POINTER TO DOLLARSIGN GRAPHIC
	AOS	LDBHPS(U)	;ADVANCE HORIZONTAL POSITION
	PJRST	SETFLE		;SET FILLER POINTER AND RETURN
SETFI6:	TLNN	T4,LDLDLR	;ECHOING GRAPHICS INHIBITED?
	TLNE	T1,CHFILO	;IS THIS FOR INPUT OR OUTPUT OF ^Q-^T?
	JRST	SETFI7		;NO GRAPHICS. JUST THROW ON A RUBOUT.
	MOVEI	T2,2		;LENGTH OF PRINT REPRESENTATION
	ADDM	T2,LDBHPS(U)	;ADD TO HORIZONTAL POSITION COUNTER
	MOVE	T2,STFLT2-21(T3);GET ECHO POINTER FOR CONTROL Q-T
	JRST	FLLPOP		;STORE FILLER AND RETURN

SETFI7:	PUSHJ	P,SETFLC	;GET FILL CLASS
	SKIPE	T2		;FILL 0?
	MOVE	T2,FILLP1	;NO, USE A FILLER
	PJRST	FLLPOP		;STORE FILLER AND GO HOME

FLLCHO:	TLNE	T1,CHFILO	;IS THIS FOR OUTPUT?
	PJRST	SETFCE		;YES, ALWAYS TYPE IT
	PUSH	P,T1		;NO, SAVE FLAGS
	MOVE	T1,-2(P)	;GET PREVIOUS CHARACTER
	ANDI	T1,CK.IMG!CK.FDE;KEEP ONLY BITS WE CARE ABOUT
	IOR	T3,T1		;MERGE INTO OUR CHARACTER
	PUSHJ	P,ECHTST	;DOES CHARACTER NEED ECHO?
	  PUSHJ	P,SETFCE	;YES, TYPE IT
	JRST	TPOPJ##		;AND RETURN, RESTORING FLAGS
;SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE

SETFLC:
IFN FTNET,<
	SKIPL	LDBTTW(U)	;ANF NETWORK TERMINAL DOES ITS OWN FILL
		.CREF	LTLANF	;(CREF REFERENCE TO REAL SYMBOL)
>
	PUSHJ	P,PTBTCH##	;ELSE, CHECK FOR REGULAR PTY
	  TDZA	T2,T2		;IT IS, USE FILLER CLASS 0
	LDB	T2,LDPFLC	;ELSE GET FILL CLASS FROM LDB
	POPJ	P,		; AND RETURN



;ROUTINE TO SETUP AN "XON CLASS" FILLER POINTER
;CALL
;	MOVE	T2,FILL POINTER
;	PUSHJ	P,SETXNP
;	<ALWAYS RETURN HERE>

SETXNP::SE1ENT			;ENTER SECTION 1
	SCNOFF			;GET SCNSER INTERLOCK
IFN FTXMON,<
	TLNE	T2,-1		;IF REAL BYTE POINTER
	TLO	T2,(1B12)	;INDICATE EXTENDED BYTE POINTER
	HLLZM	T2,LDBXNP(U)	;STORE FIRST WORD
	HRRZM	T2,LDBXNP+1(U)	;STORE SECOND WORD TO ACCESS SECTION 0
>
IFE FTXMON,<
	MOVEM	T2,LDBXNP(U)	;JUST STORE
>
	JUMPE	T2,SONPPJ	;IGNORE IF NULL
	MOVSI	T2,LOLXFP	;XOFF PENDING BIT
	IORM	T2,LDBOST(U)	;SET IN STATES WORD
	JRST	SONPPJ		;RELEASE INTERLOCK AND RETURN


;ROUTINE TO SETUP A FILLER POINTER. SETS LOLFSP IF APPROPRIATE.
;CALL
;	MOVE	T2,FILLER POINTER
;	PUSHJ	P,SETFLP