	.TITLE	TTYOUT - TTY SERVICE FOR TECOIO

	.IDENT	"X0217"

;
; COPYRIGHT (C) 1976 BY DIGITAL EQUIPMENT CORPORATION,
; MAYNARD, MASSACHUSETTS
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A
; SINGLE  COMPUTER  SYSTEM AND MAY BE COPIED ONLY WITH THE IN-
; CLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS  SOFTWARE,  OR
; ANY  OTHER  COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE
; MADE AVAILABLE TO ANY OTHER PERSON EXCEPT FOR  USE  ON  SUCH
; SYSTEM  AND TO ONE WHO AGREES TO THESE LICENSE TERMS.  TITLE
; TO AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL  TIMES  REMAIN
; IN DIGITAL.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITH-
; OUT  NOTICE  AND  SHOULD NOT BE CONSTRUED AS A COMMITMENT BY
; DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY  FOR
; THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT WHICH IS
; NOT SUPPLIED BY DIGITAL.
;
; ANDREW C. GOLDSTEIN   6-APR-79  21:39
; MARK H. BRAMHALL     10-APR-79  23:19

	.MCALL	GET$,QIOW$C,QIOW$S,WSIG$S,DIR$

	.PSECT	PURE,RO,D

TYPDSP:	.WORD	TOESC-TODSP	; FUNNY ALTMODE
	.WORD	TODEL-TODSP	; DELETE
	.WORD	TOAM-TODSP	; ALTMODE
	.WORD	TOCR-TODSP	; CR
	.WORD	TOFF-TODSP	; FF
	.WORD	TOVT-TODSP	; VT
	.WORD	TOLF-TODSP	; LF
	.WORD	TOTAB-TODSP	; TAB
	.WORD	TOBS-TODSP	; BS
	.WORD	TOBELL-TODSP	; BELL
	.WORD	TONULL-TODSP	; NULL

.SBTTL	PRINT - OUTPUT STRING TO CONSOLE

;+
;
; *** - PRINT	OUTPUT STRING TO CONSOLE
;
; THIS ROUTINE TYPES OUT THE DESIGNATED STRING ON THE CONSOLE TTY.
; ALL CHARACTERS ARE HANDLED AS IN THE TYPE ROUTINE (BELOW).
;
; *** - PRINTF	OUTPUT STRING TO CONSOLE WITH CASE FLAGGING
;
; THIS ROUTINE TYPES OUT THE DESIGNATED STRING ON THE CONSOLE
; WITH CASE FLAGGING AS DIRECTED BY THE EU FLAG.
;
; *** - PRINTB	OUTPUT STRING TO CONSOLE RINGING BELLS
;
; THIS ROUTINE TYPES OUT THE DESIGNATED STRING ON THE CONSOLE BEING
; SURE TO ONLY RING THE BELL FOR BELLS.
;
; INPUTS:
;
;	R3 =	POINTER TO CHARACTER STRING
;	R4 =	LENGTH OF CHARACTER STRING
;
; OUTPUTS:
;
;	NONE
;
; ALL REGISTERS ARE PRESERVED.
;
;-

	.PSECT	CODE,RO

	.ENABL	LSB

PRINTF::
	SAVE
	MOV	#TYPECF,R1	; SET UP TO CALL TYPECF
	BR	10$

PRINTB::
	SAVE
	MOV	#TYPECB,R1	; SET UP TO CALL TYPECB
	BR	10$

PRINT::
	SAVE
PRINTC::			; INTERNAL ENTRY (R0,R1,R2,R3,R4 GONE)
	MOV	#TYPEC,R1	; SET UP TO CALL TYPEC
10$:	DEC	R4		; MORE TO DO?
	BMI	20$		; NO (R4 = 0 LAST TIME THROUGH LOOP!)
	MOVB	(R3)+,R0	; PICK UP NEXT CHARACTER
	CALL	(R1)		; AND OUTPUT IT
	TSTB	CTCFLG		; CTRL C AST OCCURED?
	BEQ	10$		; NO, CONTINUE...
	MOV	#TYOBUF,BUFPT	; YES, FLUSH THE BUFFER
20$:	RETURN

	.DSABL	LSB

.SBTTL	TYPE - OUTPUT CHARACTER TO CONSOLE

;+
;
; *** - TYPE	OUTPUT CHARACTER TO CONSOLE
;
; THIS ROUTINE OUTPUTS ONE CHARACTER TO THE CONSOLE TTY. SINCE THE
; SMALL RSX TTY HANDLER IS IN USE, ALL SPECIAL CHARACTERS ARE
; CAREFULLY INTERPRETED. TABS AND FORM FEEDS ARE SPACED APPROPRIATELY,
; ALT MODES ARE CONVERTED TO "$", AND ALL OTHER CONTROL CHARACTERS
; ARE OUTPUT AS "^<CHAR>". CHARACTERS ARE BUFFERED AND FED TO THE
; HANDLER MANY AT A TIME TO CUT DOWN ON SYSTEM OVERHEAD.
;
; *** - TYPEB	OUTPUT CHARACTER TO CONSOLE RINGING BELLS
;
; THIS ENTRY IS IDENTICAL TO TYPE, EXCEPT THAT A BELL ONLY RINGS THE BELL.
;
; *** - TYPEF	OUTPUT CHARACTER TO CONSOLE WITH CASE FLAGGING
;
; THIS ENTRY IS IDENTICAL TO TYPE, EXCEPT THAT THE CHARACTER IS
; SUBJECT TO CASE FLAGGING AS CONTROLLED BY THE EU FLAG, PROVIDED
; IMAGE MODE TYPE OUT IS TURNED OFF.
;
; INPUTS:
;
;	R0 =	CHARACTER TO BE TYPED.
;
; OUTPUTS:	NONE
;
; ALL REGISTERS ARE PRESERVED.
;
;-

TYPE::
	SAVE
	CLR	R4		; SET SINGLE CHARACTER MODE
TYPEC::				; ENTRY FOR INTERNAL USE (R0,R2 GONE)
	MOV	ETYPE(R5),-(SP)	; SAVE CALLING ET FLAG
	BIC	#ET.IMG,ETYPE(R5) ; THEN ENSURE NORMAL MODE OUTPUT
	CALL	TYPEC1		; GO DO THE OUTPUT
	ASR	(SP)+		; WAS IMAGE OUTPUT SET?
	BCC	10$		; NOPE
.IIF	NE	ET.IMG-1, .ERROR ; THE ABOVE WON'T WORK
	BIS	#ET.IMG,ETYPE(R5) ; YEP, SO (RE-)SET IT
10$:	RETURN			; RETURN

TYPEF::
	SAVE
	CLR	R4		; SET SINGLE CHARACTER MODE
TYPECF:				; INTERNAL ENTRY
	BIT	#ET.IMG,ETYPE(R5) ; CHECK FOR IMAGE MODE OUTPUT
	BNE	TOCOMM		; SKIP ALL FILTERING IF ON
	TST	EUFLAG(R5)	; CHECK CASE FLAGGING MODE
	BMI	TYPEC1		; NEGATIVE MEANS NO FLAGGING
	BEQ	10$		; ZERO MEANS FLAG LOWER CASE
				; POSITIVE MEANS FLAG UPPER CASE
	CMP	R0,#100		; SEE IF UPPER CASE
	BLO	TYPEC1		; BRANCH IF NO
	CMP	R0,#140		; CHECK UPPER BOUND
	BHIS	TYPEC1		; BRANCH IF NO
	BR	20$		; FLAG IT

10$:	CMPB	R0,#140		; CHECK FOR LOWER CASE
	BLT	TYPEC1		; BRANCH IF NO
20$:	JSR	R4,TYPEPF	; TYPE PREFIX CHARACTER
	 .WORD	''		;  OF "'"
	BR	NORMAL		; THEN OUTPUT THE FLAGGED CHARACTER

TYPEB::
	SAVE
	CLR	R4		; SET SINGLE CHARACTER MODE
TYPECB::			; INTERNAL ENTRY (R0,R2 GONE)
	BIT	#ET.IMG,ETYPE(R5) ; CHECK FOR IMAGE MODE OUTPUT
	BNE	TOCOMM		; SKIP ALL FILTERING IF ON
	CMP	R0,#BELL	; A BELL?
	BEQ	TOCOMM		; YES, JUST RING THE BELL

;
; ACTUAL TYPEOUT CHECKING ROUTINE
;
	.ENABL	LSB
TYPEC1:	MOV	#TYPTAB,R2	; GET CHAR TABLE ADDRESS
	MOVB	R0,R0		; ENSURE FUNNY ESCAPE IS 177600!AM
10$:	CMP	R0,(R2)+	; TEST CHAR AGAINST TABLE ENTRY
	BHI	20$		; TOO HIGH, NOT IN TABLE
	BLO	10$		; TOO LOW, KEEP CHECKING
	ADD	TYPDSP-<TYPTAB+2>(R2),PC ; FOUND, DISPATCH
TODSP:				; REFERENCE SYMBOL ONLY
20$:	CMP	R0,#40		; SEE IF THIS IS A RANDOM CONTROL CHAR
	BLO	TOCTRL		; IF SO MAKE IT VISIBLE
	.DSABL	LSB
;
; FOR ALL NORMAL PRINTING CHARACTERS, BUMP THE TAB COUNTER
;
NORMAL:	INC	TABCNT
;
; INVISIBLE CHARACTERS ARE HANDLED THROUGH HERE
;
TOFF:				; FORM FEED
TOVT:				; VERTICAL TAB
TODEL:				; DELETE
TOLF:				; LINE FEED
TONULL:				; NULL
TOCOMM:	CALL	TYPEBF		; STUFF CHAR INTO BUFFER
TOEXT:	TST	R4		; SEE IF THIS IS A TYPE OR PRINT CALL
	BNE	10$		; STILL WITHIN A PRINT CALL
	CALL	TYPEBC		; TYPE OR ECHO - OUTPUT THE CHARACTER NOW
10$:	RETURN			; AND EXIT

;
; TO HERE TO HANDLE BACKSPACE
;
TOBS:	DEC	TABCNT		; BUMP DOWN THE TAB COUNT
	BGE	TOCOMM		; STOP AT ZERO
;
; TO HERE TO HANDLE CARRIAGE RETURN
;
TOCR:	CLR	TABCNT		; ZERO THE TAB COUNTER
	BR	TOCOMM		; AND OUTPUT A REAL CR

;
; TO HERE TO HANDLE ALT MODE
;
TOAM:	MOV	#'$,R0		; CONVERT TO DOLLAR SIGN
	BR	NORMAL		; AND OUTPUT

;
; TO HERE TO HANDLE ESCAPE AS ESCAPE
;
TOESC:	MOV	#AM,R0		; CONVERT TO REAL ESCAPE
	BR	TOCOMM		; AND OUTPUT A REAL ESCAPE
;
; TO HERE TO HANDLE HORIZONTAL TAB
;
TOTAB:	ADD	#10,TABCNT	; TTY HANDLER IS DOING TABS - JUST
	BIC	#7,TABCNT	; TRACK THE POSITION
	BR	TOCOMM


;
; TO HERE TO HANDLE BELL
;
TOBELL:	CALL	TYPEBF		; OUTPUT REAL BELL
				; THEN OUTPUT "^G"
;
; TO HERE TO HANDLE RANDOM CONTROL CHARACTERS
;
TOCTRL:	JSR	R4,TYPEPF	; TYPE PREFIX CHARACTER
	 .WORD	'^		;  OF "^"
	BR	NORMAL		; THEN OUTPUT THE PREFIXED CHARACTER

;
; THIS ROUTINE STUFFS A CHARACTER INTO THE TYPE OUT BUFFER AND
; OUTPUTS THE BUFFER WHEN IT IS FULL.
;
TYPEBF::
	BIT	#ET.IMG,ETYPE(R5) ; BINARY MODE OUTPUT?
	BNE	10$		; YES, SKIP WRAP CHECKING
	CMP	TABCNT,TTLNSZ	; CHECK THE CHARACTER COUNT ON THIS LINE
	BLE	10$		; OK IF LESS THAN
	BIT	#ET.TRN,ETYPE(R5) ; SEE IF TRUNCATE MODE IS ON
	BNE	20$		; IF YES, FLUSH THE CHARACTER
	MOV	#1,TABCNT	; OTHERWISE, WRAP THE LINE
10$:	MOVB	R0,@BUFPT	; STASH AWAY THE CHAR
	INC	BUFPT		; BUMP THE POINTER
	CMP	BUFPT,#TYOBUF+TYOBL
	BLO	20$		; SEE IF THE BUFFER IS FULL
	CALL	TYPEBC		; IF SO, OUTPUT IT
20$:	RETURN
;
; ROUTINE TO OUTPUT CONTENTS OF TYPEOUT BUFFER TO THE TTY. CHARACTERS ARE
; BUFFERED WHEN FEASIBLE TO CUT DOWN ON QIO OVERHEAD.
;
	.ENABL	LSB
TYPENC::MOV	R0,-(SP)	; SAVE R0
	BR	10$		; JOIN COMMON CODE

TYPEBC::MOV	R0,-(SP)	; SAVE R0
	MOV	#IO.WLB!10,R0	; SET UP FOR IMAGE MODE WRITE
	BIT	#ET.IMG,ETYPE(R5) ; CHECK FOR IMAGE MODE
	BNE	20$		; IT IS IMAGE MODE
10$:	MOV	#IO.WLB,R0	; SET UP FOR NORMAL WRITE
20$:	MOV	R2,-(SP)	; SAVE R2
	MOV	BUFPT,R2	; GET TYPE OUT BUFFER POINTER
	SUB	#TYOBUF,R2	; COMPUTE NUMBER OF CHARACTERS PRESENT
	BLOS	70$		; IF NONE, SKIP THE CALL
	TSTB	CTOFLG		; SEE IF CANCEL CONTROL-O REQUESTED
	BNE	25$		; BRANCH IF YES
	BIT	#ET.CCO,ETYPE(R5) ; ALSO CHECK ET FLAG
	BEQ	30$		; BRANCH IF NO
25$:	BIS	#IO.CCO,R0	; SET CANCEL SUBFUNCTION
30$:	CLRB	CTOFLG
	BIC	#ET.CCO,ETYPE(R5) ; CONTROL O CANCEL IS SINGLE SHOT
	BIS	#2,OUTDNE(R5)	; INDICATE TERMINAL OUTPUT DONE (+2)
	QIOW$S	R0,#TTYLUN,#TTYEFN,,#IOSTAT,,<#TYOBUF,R2,>
	BCC	50$		; BRANCH IF DIRECTIVE OK
	CMP	@#$DSW,#IE.UPN	; OUT OF NODES?
	BNE	60$		; IF NOT, JUST FORGET IT
40$:	WSIG$S			; WAIT A WHILE
	BR	20$		; AND TRY AGAIN

50$:	TSTB	IOSTAT		; CHECK I/O STATUS
	BGT	60$		; BRANCH IF OK
	CMPB	IOSTAT,#IE.NOD	; OUT OF OTHER NODES?
	BEQ	40$		; BRANCH IF SO
60$:	MOV	#TYOBUF,BUFPT	; RE-INIT BUFFER POINTER
70$:	MOV	(SP)+,R2	; RESTORE REGISTERS
	MOV	(SP)+,R0
	RETURN
	.DSABL	LSB
;
; PRINT A PREFIX, CONVERT ORIGINAL CHARACTER (R4<>0 FOR TYPEC1 CALL!)
;
TYPEPF:	MOV	R0,-(SP)	; SAVE ORIGINAL CHARACTER
	MOV	(R4)+,R0	; GET FLAG CHARACTER
	CALL	TYPEC1		; OUTPUT IT
	MOV	(SP)+,R0	; GET CHARACTER BACK
	BIC	#40,R0		; CONVERT CHARACTER TO UPPER CASE
	BIS	#100,R0		; AND TO A NORMAL GRAPHIC
	RTS	R4		; AND RETURN
;
; ATTACH THE TERMINAL
;
	.ENABL	LSB
TTATT::	MOV	R0,-(SP)
	MOV	#ATTACH,R0
	BR	10$
;
; DETACH THE TERMINAL
;
TTDET::	MOV	R0,-(SP)
	MOV	#DETACH,R0
10$:	DIR$	R0
	BCC	20$
	CMP	@#$DSW,#IE.UPN
	BNE	20$
	WSIG$S
	BR	10$
20$:	MOV	(SP)+,R0
	RETURN
	.DSABL	LSB



	.END

