Google
 

Trailing-Edge - PDP-10 Archives - BB-R598A-RM_1983 - swskit-v3/nvt/rvt.mac
There is 1 other file named rvt.mac in the archive. Click here to see a list.
	.TITLE	RVT
	.IDENT	/X02.13/

	.PSECT	RVT,RO,I

;
; COPYRIGHT (C) 1979
; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
; VERSION X02.0
;
; R. E. CALDWELL	15-DEC-79
;
; MODIFIED BY:
;
;	R. E. CALDWELL 	11-JAN-80
;	
;		RCXXX -- CORRECTLY HANDLE CARRIAGE CONTROL FOR RPR FUNCTIONS.
;
;	J. FORECAST	16-MAY-80
;
;		JFXXX -- CORRECT BUFFER PROBLEM FOR LARGE READS
;			 CORRECT CARRIAGE CONTROL FOR PROMPTING WHEN BUFFER
;				STARTS WITH <LF><CR>
;			 CORRECT READ WITH TIMEOUT
;
;	J. FORECAST	21-MAY-80
;
;		JFXXX -- CORRECT I/O STATUS BLOCK RETURNS FOR READS
;			 SOME CODE CLEANUP
;
;	J. FORECAST	23-MAY-80
;
;		JFXXX -- CORRECT UNSOLICITED CHARACTER AST SUPPORT FOR AME
;
;	J. FORECAST	27-MAY-80
;
;		JFXXX -- SAVE AND RESTORE TERMINAL CHARACTERISTICS AROUND
;			 A REMOTE SESSION.
;
;	J. FORECAST	28-MAY-80
;
;		JFXXX -- ATTACH FOR UNSOLICITED CTRL/C IF INITIAL ATTACH FAILS
;			 ALLOW STAGGERED ATTACH FOR REMOTE TERMINALS
;
;	J. FORECAST	29-MAY-80
;
;		JFXXX -- USE CORRECT ERROR MESSAGE WHEN TRYING TO CONNECT TO
;			 AN RSX SYSTEM
;
;	J. FORECAST	5-JUN-80
;
;		JFXXX -- CORRECT TERMINATOR SIZE FOR EOF HANDLING
;
;	J. FORECAST	13-JUN-80
;
;		JFXXX -- ADD PMR CONNECT CAPABILITY
;
;	J. FORECAST	16-JUN-80
;
;		JFXXX -- USE IO.RTT WHENEVER POSSIBLE
;
;	J. FORECAST	23-JUN-80
;
;		JFXXX -- FIX STAGGERED ATTACH WHEN TF.RVT DEFINED
;
;	J. FORECAST	12-NOV-80
;
;		JFXXX -- DROP UNSOLICITED INPUT BEFORE LINK ESTABLISHED
;
;	J. FORECAST	12-NOV-80
;
;		JFXXX -- FIX CARRIAGE CONTROL
 
;
; REMOTE VIRTUAL TERMINAL
;
; THIS PROGRAM RUNS ON A LOCAL NODE (M/M-PLUS ONLY) TO ALLOW A TERMINAL
; TO APPEAR TO BE LOCALLY ATTACHED TO A REMOTE VAX/VMS NODE.
;
;
; NOTE: IN AN EFFORT TO MAKE THIS CODE MORE UNDERSTANDABLE TO ONE WHO
; UNDERSTANDS VMS AND NOT RSX , SYMBOLIC NAMES EXCEEDING THE RSX MACRO-11
; LENGTH FOR SYMBOLICS HAVE BEEN USED.
;
; MACRO LIBRARY CALLS
 
	.MCALL	QIO$,DIR$,ASTX$S,EXST$S,MRKT$,DSAR$S
	.MCALL	GMCR$,QIOW$,QIOW$S,STSE$S,ALUN$
	.MCALL	CLEF$S,SETF$S,QIO$S,GLUN$S,WSIG$S
	.MCALL	GNDW$,CLSW$S,GLNW$
	.MCALL	DSCW$S,ABTW$
	.MCALL	OPNW$,SPAW$
	.MCALL	SNDW$,RECW$,REC$S,SND$S,SND$
	.MCALL	NETDF$,CRBDF$,TTSYM$
	NETDF$			; DEFINE NET SYMBOLICS
	CRBDF$			; DEFINE CON BLOCK SYMBOLICS
	TTSYM$			; DEFINE TT SYMBOLICS
 
;
; REMOTE DEVICE PROTOCOL DEFINITIONS
;
 
	.MACRO	.BLKL	A
	.BLKW	2*A
	.ENDM

	.MACRO	.BLKQ	A
	.BLKW	4*A
	.ENDM

	.MACRO	.LONG 	A
	.WORD	A,0
	.ENDM

	.ASECT
.=0

R.OPC:	.BLKW	1		; OP CODE
R.MOD:	.BLKW	1		; OP CODE MODIFIER
R.RID:	.BLKL	1		; REFERENCE ID
R.UNIT:				; DEVICE UNIT NUMBER
R.SIZE:	.BLKW	1		; SIZE OF MESSAGE (ACP/DRIVER ONLY)

R.HLEN = .			; LENGTH OF HEADER
R.PARM = .			; OFFSET TO PARAMETER BLOCK

R.PRM1:	.BLKL	1		; PARAMETER 1
R.PRM2:	.BLKL	1		; PARAMETER 2
R.PRM3:	.BLKL	1		; PARAMETER 3
R.PRM4:	.BLKL	1		; PARAMETER 4
R.PRM5:	.BLKL	1		; PARAMETER 5
R.PRM6:	.BLKL	1		; PARAMETER 6
 
;
; RESPONSE FROM REMOTE PACKET DEFINITIONS
;
;	RESPONSE PACKET OPCODES
;
 
RP.ATN = -1			; ATTENTION
RP.END = -2			; I/O REQUEST COMPLETE
RP.LOG = -3			; ERROR LOG

. = R.PARM			; POINT TO PARAMETER 1

R.STA:	.BLKQ	1		; END PACKET STATUS

;
; TERMINAL SPECIFIC PARAMETER DEFINITIONS
;
; READ/WRITE REQUESTS
 
. = R.PARM			; POINT TO PARAMETER 1
 
R.CNT:	.BLKL	1		; BYTE COUNT
R.WCC:				; WRITE CARRIAGE CONTROL
R.TMO:	.BLKL	1		; READ TIMEOUT
R.WDAT:				; WRITE DATA
R.TRM:	.BLKB	1		; BYTE OF SIZE + TERMINATOR MASK
				; WORD OF SIZE + PROMPT STRING

; 
; SET MODE/CHARACTERISTICS REQUEST
;
 
. = R.PARM			; POINT TO PARAMETER 1
 
R.CHA:				; CHARACTERISTIC
R.ASTP:	.BLKL	1		; AST PARAMETER
	.BLKL	1		;
R.SPD:	.BLKL	1		; LINE SPEED
R.FILL:	.BLKL	1		; FILL SPECIFIER
R.PAR:	.BLKL	1		; PARITY FLAGS
 
;
; READ REQUEST END PACKET
;
 
. = R.PARM			; POINT TO PARAMETER 1
 
	.BLKQ	1		; I/O STATUS
R.RDAT:	.BLKW	1		; WORD OF SIZE + READ DATA
 
;
; SENSE MODE/CHARACTERISTICS END PACKET
;

. = R.PARM			; POINT TO PARAMETER 1
 
	.BLKQ	1		; I/O STATUS
R.SCHA:	.BLKQ	1		; SENSED CHARACTERISTICS

;
; ATTENTION PACKET MODIFIERS
;

RA.UNS = 0			; UNSOLICITED DATA
RA.HUP = 1			; MODEM HANGUP
RA.CTC = 2			; CONTROL/C
RA.CTY = 3			; CONTROL/Y
	.PSECT	RVT

;
; EQUATED SYMBOLS
;
$MXBUF == 1024.			; MAXIMUM USER BUFFER SIZE
$MXMSG == $MXBUF+R.RDAT		; MAX LINK MESSAGE SIZE
$BFLVL == 1			; BUFFERING LEVEL
CTLC = 3			; CONTROL C
CTLY = 31			; CONTROL Y
CTLZ = 32			; CONTROL Z
CR = 15				; CARRIAGE RETURN
LF = 12				; LINE FEED

;
; DEFINE VALUE OF TF.RVT
;
; NOTE: IF TERMINAL DRIVER SUPPORTS CONTROL Y AST THEN
;	DEFINE TF.RVT = 100 IF NOT DEFINED IN TTSYM.
;
; BY DEFAULT ASSUME DRIVER DOES NOT SUPPORT CONTROL Y AST.
;

TF.RVT = 0

;
; OPCODES
;

READ = 1			; READ
WRITE = 2			; WRITE
SETM = 3			; SET MODE
SENM = 4			; SENSE MODE
CANCL = 5			; CANCEL I/O
BCST = 6			; BROADCAST
PRMPT = 400			; PROMPT

;
; LUN ASSIGNMENTS
;
 
TERM = 5			; TI LUN
NDATA = 1			; LUN FOR NETWORK DATA QUEUE
LINK = 2			; LUN FOR LINK

;
; DEFINE SUPPORTED VMS I/O FUNCTION MODIFIERS
;

IO$MNOECHO = 100
IO$MTIMED = 200
IO$MFILTR = 1000
;IO$MPURGE = 4000
IO$MCVTLOW = 400
IO$MNFORMAT = 400
IO$MCC = 400
IO$MCY = 200
IO$MHANGUP = 1000
IO$MCANCTRLO = 100

; 
; DEFINE SUPPORTED STATUS RETURNS
;

SS$NORMAL = 1
SS$PARTESCAPE = 774
SS$ABORT = 54
SS$BADESCAPE = 74
SS$CANCEL = 4060
SS$CTC = 3121
SS$CTY = 3021
SS$TIMEOUT = 1054
SS$HANGUP = 1314

; 
; DEFINE VALUE FOR TERMINAL DEVICE
;

DC$TERM = 102

;
; DEFINE SUPPORTED TERMINAL DEVICES
;

DT$L120 = 41
DT$L180 = 3
DT$L36 = 40
DT$L3X = 40
DT$TTYUNKN = 0
DT$V05 = 1
DT$V52 = 100
DT$V55 = 101
DT$V100 = 140
DT$V5X = 100

; 
; LOCAL MACROS
;

	.MACRO	CALLR A
	JMP	A
	.ENDM

	.MACRO	XQT,DPB
	 JSR	R5,XQTDIR
	  .WORD	DPB
	.ENDM	XQT

	.MACRO	SAVRG,LIST
	.IRP	$$$REG,<LIST>
	MOV	$$$REG,-(SP)
	.ENDR
	.ENDM	SAVRG

	.MACRO	RESRG,LIST
	.IRP	$$$REG,<LIST>
	MOV	(SP)+,$$$REG
	.ENDR
	.ENDM	RESRG
RVT:				; REFERENCE LABEL
	CLRB	LNKFLG		; NO LOGICAL LINK JUST YET
	CALL	SETUP		; SETUP LINK AND TERMINAL
	BCS	20$		; IF CS, SETUP FAILED
	XQT	SAVQIO		; SAVE TERMINAL CHARACTERISTICS
	CLEF$S	#3		; CLEAR EFN
	MOV	#$BFLVL,R5	; BUFFERING LEVEL
10$:
	CALL	LNKRCV		; HANG A LINK READ
	SOB	R5,10$		; PRIME ALL BUFFERS
	STSE$S	#3		; STOP - ALL FURTHER PROCESSING IS
				; ASYNCHRONOUS
	DSAR$S			; NO MORE AST'S

	XQT	KILQIO		; KILL ANY OUTSTANDING TERMINAL I/O
	XQT	RSTQIO		; RESTORE TERMINAL CHARACTERISTICS

	TSTB	LNKFLG		; LINK EXIST ?
	BEQ	20$		; IF EQ, NO
	CLSW$S	#NDATA,#1	; CLOSE NETWORK
	MOV	XSTAT,-(SP)	; SAVE LASTEST EXIT STATUS
	CALL	ERR18		; INDICATE CONTROL HAS RETURNED TO LOCAL NODE
	MOV	(SP)+,XSTAT	; RESTORE EXIT STATUS
20$:
	EXST$S	XSTAT		; EXIT WITH WORST STATUS
;+
; <XQTDIR>
;
; XQTDIR
;
; SUBROUTINE TO EXECUTE A FIXED DIRECTIVE AND RECOVER FROM DYNAMIC STORAGE
; ALLOCATION FAILURE.
;-

XQTDIR:
	DIR$	(R5)		; EXECUTE THE DIRECTIVE
	BCC	20$		; IF CC, SUCCESS
	CMPB	$DSW,#IE.UPN	; DSR ALLOCATION FAILURE?
	BNE	10$		; IF NE, NO ... REAL ERROR
	WSIG$S			; WAIT A BIT
	BR	XQTDIR		;  THEN TRY AGAIN
10$:	SEC			; INDICATE ERROR
20$:	BIT	(R5)+,R5	; POP RETURN LINK LEAVING 'C' ALONE
	RTS	R5		; DONE
;+
; <SETUP>
;
; SETUP
;
; SUBROUTINE TO ESTABLISH ENVIRONMENT AND SET UP THE LINK TO 
; THE REQUESTED NODE
;
;-

SETUP:
	CALL	GTCMDL		; GET COMMAND LINE
	BCS	110$		; IF CS, FAILED - FATAL
	MOV	LNODE,R0	; GET LENGTH OF NODE NAME STRING
	BEQ	10$		; IF EQ, CONNECT TO HOST
	ADD	NODPTR,R0	; POINT PAST END OF NODE NAME STRING
	CMPB	-1(R0),#':	; TERMINATED CORRECTLY?
	BEQ	10$		; IF EQ, YES
	MOVB	#':,(R0)+	; PLANT NODE NAME TERMINATORS
	MOVB	#':,(R0)+	;  ...
10$:	CLRB	(R0)+		; MAKE STRING ASCIZ
	SUB	NODPTR,R0	; COMPUTE LENGTH OF NODE NAME STRING
	MOV	R0,LNODE	;  ...
	CALL	ASGLUN		; ASSIGNED NEEDED LUNS
	BCS	110$		; IF CS, FAILED - FATAL
	XQT	OPNET		; ACCESS THE NETWORK
	TSTB	IOSB		; CHECK STATUS
	BGT	20$		; IF GT, SUCCESS
	CALLR	ERR3		; FAILED TO ACCESS NET
20$:
	XQT	GLND		; GET LOCAL NODE NAME
	MOV	#MRR18N,R0	; POINT TO LOCAL NODE NAME
30$:	CMPB	#' ,(R0)+	; BLANK ?
	BNE	30$		; REPEAT
	MOVB	#':,(R0)	; INSERT :
	MOVB	#':,-(R0)	;
	MOV	#POOL,R0	; R0 = ADDRESS OF POOL LISTHEAD
	CALL	$INIDM		; INITIALIZE THE POOL
	CMP	R2,#<$MXMSG*$BFLVL*4> ; POOL LARGE ENOUGH TO RUN ?
	BGT	40$		; IF GT, YES
	CALLR	ERR14		; INSUFFICIENT DYNAMIC MEMORY

40$:	CALL	TRMSET		; SETUP THE TERMINAL
	XQT	NTDATA		; SET UP FOR UNSOLICITED NET DATA
	TSTB	IOSB		; OK ?
	BGT	50$		; IF GT, SUCCESS
	CALLR	ERR4		; FAILES TO SET MAILBOX
50$:
	MOV	#PMRBLK,R5	; POINT TO THE CONTROL BLOCK
	MOV	NODPTR,P$NOD(R5) ; SET UP NODE NAME STRING POINTER
	CALL	$CONN		; ATTEMPT THE CONNECT
	BCC	60$		; IF CC, ALL IS OK
	CALLR	ERR5		; INDICATE ERROR
60$:
	INCB	LNKFLG		; INDICATE LINK EXISTS
	XQT	SNDCNF		; SEND CONFIGURATION MESSAGE
	TSTB	IOSB		; OK ?
	BGT	70$		; IF GT, SUCCESS
	CALLR	ERR7		; FAILED TO SEND CONFIGURATION MESSAGE
70$:
	XQT	RCVCNF		; REC CONFIGURATION AND VERIFY
	TSTB	IOSB		; OK ?
	BGT	80$		; IF GT, SUCCESS
	CMPB	IOSB,#IE.DAO	; DATA OVERRUN?
	BEQ	90$		; IF EQ, YES - ASSUME INCOMPATIBLE SYSTEM
	CALLR	ERR8		; FAILED TO REC CONF MESSAGE
80$:	
	CMPB	#1,CNFBUF	; IS IT A CONFIGURATION MESSAGE
	BEQ	100$		; IF EQ, YES
90$:	CALLR	ERR17		; ISSUE ERROR MESSAGE

100$:	BIT	#4,CNFBUF+6	; DOES REMOTE SPEAK VMS PROTOCOL
	BEQ	90$		; IF EQ, NO
	MOVB	LBUF+G.LUNU,INIMSG+R.UNIT	; SET TERMINAL UNIT NUMBER
	XQT	SNDINI		; SEND INITIALIZE SEQUENCE
	TSTB	IOSB		; OK ?
	BGT	110$		; IF GT, SUCCESS
	CALL	ERR9		; FAILED TO SEND INITIALIZE SEQUENCE
110$:
	RETURN			; RETURN TO CALLER
;+
; <GTCMDL>
;
; GET COMMAND LINE AND NODE NAME
;
; -
GTCMDL:				; REFERENCE LABEL
	DIR$	#GMCR		; GET COMMAND LINE
	BCS	30$		; IF CS, FAILED - PROMPT AND USE DEFAULT NAME
10$:
	MOV	#GMCR+G.MCRB,R1	; R1 = ADDRESS OF COMMAND LINE
	MOVB	(R1)+,RVTN+0	; SAVE TASK NAME
	MOVB	(R1)+,RVTN+1	;
	MOVB	(R1)+,RVTN+2	;
	MOV	$DSW,R0		; R0 = BYTE COUNT
	SUB	#3,R0		; ADJUST BY TASK NAME LENGTH
	BEQ	30$		; IF EQ, PROMPT FOR NODE NAME
	CMPB	#' ,(R1)	; BLANK ?
	BNE	20$		; IF NE, PROCEED
	DEC 	R0		; REDUCE COUNT
	BEQ	30$		; IF EQ NOW, PROMPT FOR NODE NAME
	INC	R1		; POSITION TO NODE NAME
20$:
	MOV	R1,NODPTR	; SAVE POINTER TO NODE NAME STRING
	MOV	R0,LNODE	; SET LENGTH OF NODE NAME
	BR	70$		; PROCEED
30$:
	MOV	#GMCR+G.MCRB,NODPTR
	MOV	NODPTR,R2	; GET POINTER TO NODE NAME
	MOV	#"$H,(R2)+	; DEFAULT NODE NAME
	MOV	#"OS,(R2)+	;  TO '$HOST'
	MOV	#"T ,(R2)+	;   ...
	MOV	#5,LNODE	; SET LENGTH OF DEFAULT NODE NAME

	XQT	NODQIO		; PROMPT FOR NODE NAME
	BCS	40$		; IF CS, FAILURE

	TSTB	IOSB		; SUCCESSFUL ?
	BGT	50$		; IF GT, YES
	CMPB	#IE.EOF,IOSB	; CTLZ ?
	BEQ	80$		; IF EQ, YES EXIT RVT
40$:	CALLR	ERR2		;

50$:	MOV	NODPTR,R2	; POINT TO NODE NAME
	MOV	IOSB+2,R1	; GET LENGTH OF NODE NAME STRING
	BEQ	70$		; IF EQ, NONE
	MOV	R1,LNODE	; FILL IN LENGTH OF NODE NAME

60$:	MOVB	(R2),R0		; CONVERT NODE NAME TO UPPER CASE
	MOVB	CVTLUP(R0),(R2)+;  ...
	SOB	R1,60$		;  ...
70$:	TST	(PC)+		; INDICATE SUCCESS
80$:	SEC			; INDICATE FAILURE
	RETURN			; RETURN TO CALLER	
;+
;
; <ASGLUN>
;
; SUBROUTINE TO ASSIGN NEEDED LUNS
;
;-
ASGLUN:
	MOV	#NDATA,ALUN+A.LULU	; SET LUN IN DPB
	MOV	#"NS,ALUN+A.LUNA	; SET DEVICE IN DPB
	DIR$	#ALUN			; ASSIGN THE LUN
	BCS	10$			; IF CS, ERROR

	MOV	#LINK,ALUN+A.LULU	; SET LUN IN DPB
	DIR$	#ALUN			; ASSIGN THE LUN
	BCC	10$			; IF CC, SUCCESS

	CALL	ERR3			; FAILED TO ASSIGN LUN
10$:	RETURN				; RETURN TO CALLER
;+
; <TRMSET>
;
; SETUP THE TERMINAL
;
;-
TRMSET:				; REFERENCE LABEL
	MOV	#IO.GTS,QIOW+Q.IOFN	; SET I/O FUNCTION
	MOV	#GTSBUF,QIOW+Q.IOPL	; SET BUFFER ADDRESS
	MOV	#8.,QIOW+Q.IOPL+2	; AND BYTE COUNT
	XQT	QIOW			; ISSUE THE GTS FUNCTION
	BCC	20$			; IF CC, SUCCESS
10$:	CALL	ERR19			; INDICATE THE ERROR
	BR	30$			; PROCEED
20$:	TSTB	IOSB			; SUCCESS ?
	BLE	10$			; IF LE, NO
	MOV	#GTSBUF,R0		; POINT TO BUFFER
	MOV	(R0),R1			; GET FUNCTIONS SUPPORTED
	BIC	#^C<F1.BTW!F1.UIA!F1.ESQ!F1.LWC!F1.RPR>,R1
	CMP	R1,#F1.BTW!F1.UIA!F1.ESQ!F1.LWC!F1.RPR
	BNE	10$			; IF NE, NOT ENOUGH SUPPORT
;
; THE FOLLOWING TEST WILL BE ENABLED AS SOON AS TTDRV IS CHANGED.
;
;	BIT	#F2.FDX,2(R0)		; IS IT FDX TERMINAL DRIVER
;	BEQ	10$			; IF EQ, NO 
	BIT	#F2.SCH,2(R0)
	BEQ	10$
	BIT	#F2.GCH,2(R0)
	BEQ	10$
30$:	CALL	ATTACH			; ATTACH THE TERMINAL
	BCC	40$			; IF CC, SUCCESSFUL
	CALL	ERR6			; TELL USER WE FAILED
40$:
	MOV	#SF.GMC,QIOW+Q.IOFN	; SET I/O FUNCTION
	MOV	#CHABUF,QIOW+Q.IOPL+0	; SET BUFFER ADDRESS
	MOV	#CHASIZ,QIOW+Q.IOPL+2	; AND SIZE
	XQT	QIOW			; GET TERMINAL CHARACTERISTICS
	TSTB	IOSB			; GET STATUS
	BLE	70$			; IF LE, FAILED USE DEFAULT
	MOV	#CHABUF,R0		; POINT TO CHARACTERISTICS BUFFER
	MOV	#CHACNT,R1		; COUNTER
	MOV	#CHATRA,R2		; POINT TO CHARACTERISTICS TRANSLATE TABLE
	MOV	#CNFCHA,R3		; POINT TO CNFDTA CHARACTERISTIC BUFFER
50$:	MOV	R3,R4			; SAVE R3
	MOVB	1(R2),CHAOFF		; GET CHARACTERISTIC OFFSET
	MOVB	2(R2),CHAMSK		; GET MASK
	TSTB	1(R0)			; SET THIS CHARACTERISTICS ?
	BEQ	60$			; IF EQ, NO
	ADD	CHAOFF,R3		; POINT TO CORRECT BYTE
	BISB	CHAMSK,(R3)		; SET THE BIT
60$:	TST	(R0)+			; POINT TO NEXT
	ADD	#3,R2
	MOV	R4,R3			; RESTORE R3
	SOB	R1,50$			; REPEAT
	MOVB	CHAWID+1,CNFWID		; SET WIDTH
	MOVB	CHALPP+1,CNFLPP		; AND PAGE LENGTH
	MOVB	CHATTP+1,R0		; R0 = TERMINAL TYPE
	ASL	R0			; MAKE WORD INDEX
	MOVB	TRMTRA+1(R0),CNFTRM	; SET TERMINAL TYPE
70$:	GLUN$S	#TERM,#LBUF		; GET LUN INFORMATION
	CLC
	RETURN				; RETURN TO CALLER
;+
; <ATTACH>
;
; SUBROUTINE TO ATTACH THE TERMINAL
;
;-
ATTACH:
	MOV	#IO.ATA!TF.NOT!TF.ESQ!TF.RVT,QIOW+Q.IOFN
	MOV	#UNSAST,QIOW+Q.IOPL	; SET UNSOLICITED CHARACTER AST
	CLR	QIOW+Q.IOPL+2		; NO SECOND PARAMETER
	MOV	#CTCAST,QIOW+Q.IOPL+4	; SET CTRL C AST
	XQT	QIOW			; ATTACH THE TERMINAL
	BCS	10$			; IF CS, FAILED
	TSTB	IOSB			; SUCCESSFUL?
	BGT	100$			; IF GT, OK
10$:	BIC	#TF.ESQ!TF.RVT,QIOW+Q.IOFN ; REMOVE ESCAPE SEQUENCE SUPPORT
	XQT	QIOW			;  AND TRY AGAIN
	BCS	20$			; IF CS, FAILED
	TSTB	IOSB			; SUCCESSFUL?
	BGT	100$			; IF GT, OK
20$:	BIC	#TF.NOT,QIOW+Q.IOFN	; REMOVE NOTIFICATION SUPPORT
	MOV	#CTCAST,QIOW+Q.IOPL	; USE STANDARD AST ENTRY POINT
	CLR	QIOW+Q.IOPL+4		; ALL CHARACTERS USE STANDARD AST
	XQT	QIOW			; TRY TO ATTACH AGAIN
	BCS	100$			; IF CS, FAILED
	TSTB	IOSB			; SUCCESSFUL?
	BGT	100$			; IF GT, OK
	SEC				; INDICATE FAILURE
100$:	RETURN
;+
; <LNKRCV>
;
; SUBROUTINE TO DO LINK RECEIVES
;
;-
LNKRCV:
	SAVRG	<R0,R1,R2>	; SAVE REGISTERS
	MOV	#POOL,R0	; R0 = ADDRESS OF POOL LISTHEAD
	MOV	#$MXMSG+4,R1	; BYTE COUNT
	CALL	$RQCB		; ALLOCATE BUFFER
	BCC	10$		; IF CC, OK
	CALL	ERR15		; INDICATE ERROR
	CALL	SETF		; SET FLAG TO WAKE UP
	BR	30$		;
10$:
	MOV	R0,R1		; COPY TO R1
	ADD	#4,R0		; R0 = A(BUFFER), R1 = A(IOSB)
20$:
	REC$S	#LINK,#1,R1,#LRAST,<R0,#$MXMSG>
	CALL	CHKRES		; CHECK RESULT
	BCS	20$		; IF CS, RETRY
30$:	RESRG	<R2,R1,R0>	; RESTORE REGISTERS
	RETURN			; RETURN TO CALLER
;+
; <LRAST>
;
; LINK RECEIVE AST HANDLER
;
LRAST:
	SAVRG	<R0>		; SAVE R0
	MOV	2(SP),R0	; R0 = ADDRESS OF IOSB AND BUFFER
	SAVRG	<R1,R2,R3,R4,R5>; SAVE MORE REGISTERS
	TSTB	(R0)		; SUCCESS ?
	BGT	10$		; IF GT, YES
	CMPB	#IE.ABO,(R0)	; ABORT ?
	BEQ	50$		; IF EQ, LET MAILBOX HANDLE
	CMPB	#IE.NLN,(R0)	; NO LINK ?
	BEQ	50$		; IF EQ, LINK HAS BEEN ABORTED

	SAVRG	<R0>		; SAVE ADDRESS OF I/O STATUS BLOCK
	MOVB	(R0),R1		; GET THE ERROR CODE
	MOV	#IOERR,R0	; POINT TO OUTPUT BUFFER
	MOV	#<3*4000>+10.,R2; SET UP CONVERSION CODE
	CALL	$CBTA		; CONVERT ERROR CODE TO ASCII
	MOVB	#'.,(R0)+	; SHOW ERROR CODE IS IN DECIMAL
	MOVB	#'),(R0)+	; PLANT TERMINATORS
	CLRB	(R0)+		;   ...
	RESRG	<R0>		; RECOVER I/O STATUS BLOCK ADDRESS

	CALL	ERR16		; INDICATE LINK ERROR
	CALL	SETF		; FORCE TASK EXIT
	MOV	#$MXMSG+4,R1	; LENGTH OF MESSAGE
	MOV	R0,R2		; R2 = BUFFER ADDRESS
	MOV	#POOL,R0	; R0 = POOL LISTHEAD
	CALL	$RLCB		; RELEASE THIS BUFFER
	BR	40$		; PROCEED
10$:	ADD	#4,R0		; POINT TO MESSAGE
	MOV	R.OPC(R0),R1	; R1 = OPCODE
	MOV	#OPCTB,R2	; R2 = ADDRESS OF OPCODE TRANSLATE TABLE
20$:	CMP	(R2)+,R1	; CORRECT OPCODE ?
	BEQ	30$		; IF EQ, YES
	TST	(R2)+		; END OF TABLE ?
	BNE	20$		; IF NE, NO
	IOT			; DEBUG
30$:	MOVB	(R2),R1		; R1 = INTERNAL OPCODE
	ASL	R1		; MAKE WORD INDEX
	CALL	@FUNDSP(R1)	; DISPATCH THIS ONE
40$:				;
	CALL	LNKRCV		; DO ANOTHER LINK RECEIVE
50$:	RESRG	<R5,R4,R3,R2,R1,R0>
	TST	(SP)+		; CLEAN UP STACK 
	ASTX$S			; EXIT THE AST
;+
; <LNKWRT>
;
; SUBROUTINE TO ISSUE LINK WRITE (XMIT)
;
; INPUT:
; 
;	R0 = ADDRESS OF IOSB AND BUFFER
;	R2 = BYTE COUNT FOR TRANSFER
;-

LNKWRT:				;
	SAVRG	<R1>		; SAVE R1
	MOV	R0,R1		; COPY IOSB ADDRESS
	ADD	#4,R0		; POINT TO BUFFER
10$:	SND$S	#LINK,#1,R1,#LWAST,<R0,R2>
	CALL	CHKRES		; CHECK RESULT
	BCS	10$		; IF CS, RETRY
	RESRG	<R1>		; RESTORE R1
	RETURN 			; RETURN TO CALLER
;+
; <LWAST>
;
; LINK XMIT (WRITE) AST HANDLER
;
;-

LWAST:				;
	SAVRG	<R0>		; SAVE R0
	MOV	2(SP),R0	; R0 = ADDRESS OF IOSB AND BUFFER
	SAVRG	<R1,R2>		; SAVE MORE REGISTERS
	MOV	R0,R2		; COPY BUFFER ADDRESS
	MOV	#$MXMSG+4,R1	; BYTE COUNT
	MOV	#POOL,R0	; POINT TO POOL LISTHEAD
	CALL	$RLCB		; RELEASE THIS BUFFER
	RESRG	<R2,R1,R0>	; RESTORE REGISTERS
	TST	(SP)+		; CLEAN UP STACK
	ASTX$S			; EXIT THE AST
;+
; <TRMRD>
;
; SUBROUTINE TO DO TERMINAL READ AND READ AFTER PROMPT.
;
; INPUT
;
;	R0 = ADDRESS OF BUFFER
;	R2 = ADDRESS OF INTERNAL OPCODE
;-
TRMRD:
	MOV	R0,R1		; COPY BUFFER ADDRESS
	CLRB	VFC		; ASSUME NO CARRIAGE CONTROL
	MOV	#RTTTAB+40,R5	; POINT PAST END OF TERMINATOR TABLE

	.REPT	16.
	CLR	-(R5)		; CLEAR OUT TERMINATOR TABLE
	.ENDR

	CLRB	RTTFLG		; ASSUME IO.RTT NOT NEEDED
	ADD	#R.TRM,R0	; POINT TO TERM MSG SIZE
	MOVB	(R0)+,R3	; BYTE COUNT FOR TERM 
	BEQ	20$		; IF EQ, NOT PRESENT
10$:	MOVB	(R0)+,(R5)+	; MOVE TERMINATOR MASK INTO TABLE
	SOB	R3,10$		;   ...
	INCB	RTTFLG		; SHOW IO.RTT REQUIRED
20$:	BIT	#PRMPT,(R2)	; READ AFTER PROMPT ?
	BEQ	40$		; IF EQ, NO
	MOV	#IO.RPR,R5	; FUNCTION IS IO.RPR
	MOVB	(R0)+,RPRCNT	; SET BYTE
	MOVB	(R0)+,RPRCNT+1	;  COUNT FOR WRITE PORTION
	MOV	RPRCNT,R4	; SET COUNT
	BEQ	40$		; IF EQ, ZERO LENGTH PROMPT - CONVERT TO READ
;
; SET UP KLUGE FOR CASE OF IO.RPR WITH EMBEDDED CARRIAGE CONTROL
;
	CLR	-(SP)		; GET SOME LOCAL WORKSPACE
	MOVB	(R0),(SP)	; GET FIRST 2 PROMPT CHARACTERS
	MOVB	1(R0),1(SP)	;  ...
	MOV	(SP)+,R3	;  ...
	CMP	R3,#<LF*400>+CR	; DOES BUFFER START WITH <CR><LF>?
	BEQ	30$		; IF EQ, YES ... EMBEDDED CARRIAGE CONTROL
	CMP	R3,#<CR*400>+LF	; DOES BUFFER START WITH <LF><CR>?
	BEQ	30$		; IF EQ, YES ... ALSO EMBEDDED CARRIAGE CONTROL
	MOVB	#'$,VFC		; SET FOR PROMPT VFC
30$:	MOV	R0,R3		; SET BUFFER ADDRESS
	BR	80$		; FINISH IN COMMON CODE	
40$:	CLR	R3		; ASSUME NO SECONDARY BUFFER
	MOV	#IO.RLB,R5	; SET FUNCTION
	TSTB	RTTFLG		; SHOULD WE USE IO.RTT?
	BEQ	50$		; IF EQ, YES
	MOV	#IO.RTT,R5	; SET FUNCTION
	MOV	#RTTTAB,R3	; POINT TO TERMINATOR TABLE
50$:	CMPB	#14,R.OPC(R1)	; READ PASS ALL ?
	BEQ	60$		; IF EQ, YES
	BIT	#IO$MFILTR,R.MOD(R1) ; FILTER CONTROL CHARACTERS?
	BEQ	70$		; IF EQ, YES
60$:	BIS	#TF.RAL,R5	; SET READ SUBFUNCTION

70$:	CLR	R4
80$:	CLR	RDTMO		; ASSUME NOT TIMED READ
	BIT	#IO$MTIMED,R.MOD(R1) ; TIMED ?
	BEQ	90$		; IF EQ, NO
	MOV	R.TMO(R1),RDTMO	; SET TIMEOUT VALUE
	BIS	#TF.TMO,R5	; SHOW TIMEOUT REQUIRED
90$:	MOV	R.CNT(R1),R2	; SET READ DATA COUNT
	BIT	#IO$MNOECHO,R.MOD(R1); READ NO ECHO ?
	BEQ	100$		; IF EQ, NO
	BIS	#TF.RNE,R5	; OR IN SUBFUNCTION
100$:	MOV	R1,R0		; COPY ADDRESS
	SUB	#4,R0		; POINT TO IOSB
	ADD	#R.RDAT+2,R1	; R1 = READ BUFFER ADDRESS
	TST	R2		; BYTE COUNT ZERO ?
	BNE	110$		; IF NE, PROCEED
	CALLR	NULLIO		; FINISH THE I/O

110$:	CMP	R2,#$MXBUF	; IS THE BUFFER SIZE TOO LARGE?
	BLOS	120$		; IF LOS, NO
	MOV	#$MXBUF,R2	; TRUNCATE THE READ
120$:	CALL	CHKTMO		; CHECK FOR ZERO TIMEOUT
	BCC	130$		; QIO$ WOULD TIMEOUT
	QIO$S	R5,#TERM,,,R0,#RDAST,<R1,R2,RDTMO,R3,R4,VFC> ; ATTEMPT FUNC
	CALL	CHKRES		; CHECK RESULT
	BCS	120$		; IF CS, RETRY
130$:	RETURN			; RETURN TO CALLER
;+
; <CHKTMO>
;
; SUBROUTINE TO CHECK IF TERMINAL READ WOULD TIMEOUT
;
; INPUT:
;
;	R0 = ADDRESS OF IOSB AND BUFFER
;	R2 = # OF BYTES TO READ
;-
CHKTMO:
	BIT	#IO$MTIMED,R.MOD+4(R0)
	BEQ	100$		; IF EQ, READ IS NOT TIMED
	TST	RDTMO		; IS A REAL TIMEOUT SPECIFIED?
	BNE	100$		; IF NE, YES

	XQT	TBFQIO		; FIND # OF CHARS IN TYPEAHEAD BUFFER
	CMPB	R2,TBFBUF+1	; ARE THERE ENOUGH CHARACTERS IN THE BUFFER?
	BLOS	100$		; IF LOS, YES

	MOV	R0,R1		; COPY ADDRESS OF IOSB
	ADD	#4,R1		; POINT TO THE BUFFER
	MOV	#RP.END,R.OPC(R1)
	CLR	R.MOD(R1)	; RETURN QIO WITH TIMEOUT ERROR
	MOV	#SS$TIMEOUT,R.STA(R1)
	CLR	R.STA+2(R1)
	CLR	R.STA+4(R1)
	CLR	R.STA+6(R1)
	CLR	R.RDAT(R1)	; NO DATA IN BUFFER
	MOV	#R.RDAT+2,R2	; LENGTH OF MESSAGE TO SEND
	CALL	LNKWRT		; ISSUE LINK WRITE
	TST	(PC)+		; INDICATE READ COMPLETED
100$:	SEC			; READ NOT YET COMPLETED
	RETURN
;+
; <TRMWRT>
;
; SUBROUTINE TO ISSUE TERMINAL WRITE
;
; INPUT:
;
;	R0 = BUFFER ADDRESS (IOSB+4)
;-
TRMWRT:
	SAVRG	<R5>		; SAVE R5
	MOV	#IO.WLB,R5	; DEFAULT TO WLB
	MOV	R0,R1		; COPY BUFFER ADDRESS
	SUB	#4,R0		; POINT TO IOSB
	MOV	R.CNT(R1),R2	; SET BYTE COUNT
	CMP	#13,R.OPC(R1)	; WRITE PASS ALL ?
	BNE	10$		; IF NE, NO
	BIS	#TF.WAL,R5	; OR IN SUBFUNCTION
	CLR	R.WCC(R1)	; NO CARRIAGE CONTROL
	CLR	R.WCC+2(R1)	;   TO INTERPRET
10$:
	BIT	#IO$MNFORMAT,R.MOD(R1) ; PASSALL ?
	BEQ	20$		; IF EQ, NO
	BIS	#TF.WAL,R5	; SET SUBFUNCTION
20$:	BIT	#IO$MCANCTRLO,R.MOD(R1)	; CANCEL CONTROL O ?
	BEQ	30$		; IF EQ, NO
	BIS	#TF.CCO,R5	; SET SUBFUNCTION
30$:	MOVB	R.WCC(R1),VFC	; GET VERTICAL FORMS CONTROL
	BNE	40$		; IF NE, FORTRAN FORMS CONTROL
	CALL	FIXVFC		; FIXUP VFC PER VMS TYPE (PREFIX)
40$:	ADD	#R.WDAT,R1	; POINTER TO WRITE DATA AREA
	TST	R2		; BYTE COUNT ZERO
	BEQ	60$		; IF EQ, YES
50$:	QIO$S	R5,#TERM,,,R0,#WTAST,<R1,R2,VFC> ; ISSUE TERMINAL I/O
	CALL	CHKRES		; CHECK RESULT
	BCS	50$		; IF CS, RETRY
60$:	MOV	R0,R1		; R1 = IOSB ADDRESS
	ADD	#4,R1		; POINT TO BUFFER
	TSTB	R.WCC(R1)	; FORTRAN CARRIAGE CONTROL ?
	BNE	70$		; IF NE, YES
	INC	R1		; POINT TO BUFFER +1 FOR SECOND CALL
	CALL	FIXVFC		; DO POSTFIX VFC
70$:	TST	R.CNT+4(R0)	; ZERO BYTE COUNT?
	BNE	80$		; IF NE, NO
	CALL	NULLIO		; FINISH UP NOW
80$:	RESRG	<R5>		; RESTORE R5
	RETURN			; RETURN TO CALLER
;+
; <FIXVFC>
;
; SUBROUTINE TO FIXUP NON FORTRAN CARRIAGE CONTROL
; 
; INPUT:
;	R1 = ADDRESS OF BUFFER (FIRST CALL) PREFIX
;	R1 = ADDRESS OF BUFFER +1 (SECOND CALL) POSTFIX
;	R5 = I/O FUNCTION CODE AND MODIFIERS
;
;-

FIXVFC:
	SAVRG	<R3>		; SAVE R3
	MOVB	R.WCC+2(R1),R3	; GET CC
	BEQ	50$		; IF EQ, NO CC FOR THIS CALL
	BMI	20$		; IF MI, SPECIAL CASE
	INC	R3		; SEND OUT LEADING CARRIAGE RETURN
10$:	QIOW$S	R5,#TERM,#2,,,,<#LFBUF,R3> ; DO I/O ; R3= COUNT OF CR + LF'S
	CALL	CHKRES		; CHECK RESULT
	BCS	10$		; IF CS, RETRY
	BR	50$		; PROCEED

20$:	BIC	#200,R3		; TURN OFF HIGH BIT
	BIT	#100,R3		; BIT 6 ON ?
	BEQ	30$		; IF EQ, NO
	BIC	#100,R3		; CLEAR BIT 6
	ADD	#128.,R3	; ADD BIAS
30$:	MOVB	R3,BBUF		; SET CHARACTER
40$:	QIOW$S	R5,#TERM,#2,,,,<#BBUF,#1> ; WRITE THE SPECIAL CHARACTER
	CALL	CHKRES		; CHECK RESULT
	BCS	40$		; IF CS, RETRY
50$:	RESRG	<R3>		; RESTORE R3
	RETURN			; RETURN TO CALLER
;+
; <NULLIO>
;
; SUBROUTINE TO HANDLE I/O WITH COUNT OF ZERO
;
; INPUT:
;
;	R0 = ADDRESS OF IOSB AND BUFFER
;
;-

NULLIO:				;
	SAVRG	<R0,R1,R2>	; SAVE SOME REGISTERS
	MOV	R0,R1		; COPY IOSB ADDRESS
	ADD	#4,R1		; POINT TO BUFFER
	MOV	#RP.END,R.OPC(R1)	; SET END STATUS
	CLR	R.MOD(R1)	; NO MODIFIER
	MOV	#SS$NORMAL,R.STA(R1)	; SET SUCCESS STATUS
	CLR	R.STA+2(R1)	;
	CLR	R.STA+4(R1)	;
	CLR	R.STA+6(R1)	;
	CLR	R.RDAT(R1)	;
	MOV	#R.RDAT+2,R2	; SET BYTE COUNT FOR LINK WRITE
	CALL	LNKWRT		; ISSUE LINK WRITE
	RESRG	<R2,R1,R0>	; RESTORE THE REGISTERS
	RETURN			; RETURN TO CALLER
;+
; <TRMSMC>
;
; SUBROUTINE TO HANDLE SETMODE OR SETCHAR FUNCTIONS
;
; INPUT:
;
; 	R0 = BUFFER ADDRESS
;
;-

TRMSMC:				;
	BIT	#IO$MHANGUP,R.MOD(R0)	; IS THIS A HANGUP ?
	BEQ	10$		; IF EQ, NO
	MOV	#EX$SUC,XSTAT	; SET ENDING STATUS
	CALLR	SETF		; HANGUP IS A LINK DISCONNECT

10$:	BIT	#IO$MCC,R.MOD(R0)	; CTRL C  ENABLE/DISABLE ?
	BEQ	40$		; IF EQ, NO
	TST	R.ASTP(R0)	; DISABLE ?
	BEQ	20$		; IF EQ, DISABLE CTLC
	TSTB	CTCFLG		; ALREADY ENABLED ?
	BNE	30$		; IF NE, YES
	INCB	CTCFLG		; ENABLE CTLC
	BR	30$		; PROCEED
20$:	CLRB	CTCFLG		; DISABLE CTLC
30$:	SUB	#4,R0		; POINT TO IOSB
	CALLR	NULLIO		; FINISH SUCCESS

40$:	BIT	#IO$MCY,R.MOD(R0)	; CTRL Y ENABLE/DISABLE ?
	BEQ	60$		; IF EQ, NO
	TST	R.ASTP(R0)	; DISABLE CTRL Y ?
	BEQ	50$		; IF EQ, YES
	TSTB	CTYFLG		; ALREADY ENABLED ?
	BNE	30$		; IF NE, YES
	INCB	CTYFLG		; ENABLE CTRL Y
	BR	30$		; FINISH SUCCES
50$:	CLRB	CTYFLG		; DISABLE CTRL Y
	BR	30$		;
60$:				; FUNCTION IS SETMODE/SETCHAR
	MOV	R0,R1		; COPY BUFFER ADDRESS
	ADD	#R.CHA+4,R1	; POINT TO CHARACTERISTICS AREA
	MOV	#CHABUF,R2	; POINT TO CHARACTERISTIC BUFFER
	MOV	#CHACNT,R3	; SET COUNT
	MOV	#CHATRA,R4	; POINT TO TRANSLATE TABLE
110$:	TSTB	(R2)+		; POINT TO VALUE OF CHA
	TSTB	(R4)+		; POINT TO OFFSET OF CHARACTERISTIC 
	MOVB	(R4)+,CHAOFF	; SAVE THE OFFSET
	MOVB	(R4)+,CHAMSK	; AND THE MASK
	MOV	R1,-(SP)	; SAVE POSITION
	ADD	CHAOFF,R1	; ADD IN OFFSET
	BITB	CHAMSK,(R1)	; SET THIS CHARACTERISTIC ?
	BEQ	120$		; IF EQ, NO
	MOVB	#1,(R2)+	; SET THE CHARACTERISTIC
	BR	130$		;
120$:	CLRB	(R2)+		; CLEAR THE CHARACTERISTIC
130$:	MOV	(SP)+,R1	; RESTORE POSITION
	SOB	R3,110$		; REPEAT
	MOV	R0,R1		; RESTORE BUFFER ADDRESS
	ADD	#R.CHA,R1	; POINT AGAIN TO CHA
	MOVB	2(R1),CHAWID+1	; SET WIDTH
	MOVB	7(R1),CHALPP+1	; AND LENGTH
	MOVB	1(R1),R2	; TERMINAL TYPE
	MOV	#TRMTRA,R3	; POINT TO TRANSLATE TABLE
	MOV	#TRMTC,R4	; R4 = NUMBER OF ENTRIES IN TABLE
140$:	CMPB	R2,1(R3)	; MATCH ?
	BEQ	150$		; IF EQ, YES
	TST	(R3)+		; NEXT ENTRY
	SOB	R4,140$		; REPEAT
	MOVB	TRMTRA,CHATTP+1	; DEFAULT TO UNKNOWN
	BR	155$		;
150$:	MOVB	(R3),CHATTP+1	; SET TERMINAL TYPE
155$:	XQT	SMCQIO		; SET CHARACTERISTICS
	BR	30$		; FINISH UP
;+
; <TRMGMC>
;
; SUBROUTINE TO DO SENSE MODE / SENSE CHAR OPERATIONS
;
; R0 = BUFFER ADDRESS
;
;-

TRMGMC:
	XQT	GMCQIO		; GET CHARACTERISTICS
	MOV	R0,R1		; GET ADDRESS OF CHARACTERISTICS AREA
	ADD	#R.SCHA,R1	;  ...
	MOV	#8.,R2		; 8 BYTES OF CHARACTERISTICS
10$:	CLRB	(R1)+		; CLEAR OUT THE AREA
	SOB	R2,10$		;  ...

	MOV	R0,R1		; SET UP ADDRESS AGAIN
	ADD	#R.SCHA+4,R1	;  ...

	MOV	#CHABUF,R2	; POINT TO BUFFER
	MOV	#CHACNT,R3	; GET NUMBER OF ENTRIES
	MOV	#CHATRA,R4	; POINT TO TRANSLATE BUFFER

20$:	MOV	R1,-(SP)	; SAVE POS
	MOVB	1(R4),CHAOFF	; SET OFFSET
	MOVB	2(R4),CHAMSK	; AND MASK
	TSTB	1(R2)		; CHAR ON ?
	BEQ	30$		; IF EQ, NO
	ADD	CHAOFF,R1	; POINT TO CORRECT BYTE TO SET
	BISB	CHAMSK,(R1)	; SET CHA
30$:	TST	(R2)+		; NEXT CHA
	ADD	#3,R4		; NEXT TRANSLATE ENTRY
	MOV	(SP)+,R1	; RESTORE POS
	SOB	R3,20$		; PROCEED
	MOV	R0,R1		; COPY ADDRESS AGAIN
	ADD	#R.SCHA,R1	; POINT TO CHARACTERISTICS AREA
	MOVB	#DC$TERM,(R1)	; INDICATE TERMINAL
	MOVB	CHAWID+1,2(R1)	; SET WIDTH
	MOVB	CHALPP+1,7(R1)	; LENGTH
	MOVB	CHATTP+1,R2	; R2=TERMINAL TYPE
	ASL	R2		; MAKE WORD INDEX
	MOVB	TRMTRA+1(R2),1(R1) ; SET TERMINAL TYPE
	MOV	#RP.END,R.OPC(R0)	; SET ENDING STATUS
	CLR	R.MOD(R0)	; CLEAR MODIFIER
	MOV	#SS$NORMAL,R.STA(R0)	; SET STATUS
	CLR	R.STA+2(R0)
	CLR	R.STA+4(R0)
	CLR	R.STA+6(R0)
	MOV	#R.RDAT+8.,R2	; BYTE COUNT FOR TRANSFER
	SUB	#4,R0		; POINT TO IOSB
	CALLR	LNKWRT		; DO A LINK WRITE
;+
; <TRMCNL>
;
; SUBROUTINE TO HANDLE CANCEL I/O REQUESTS
;
; INPUT:
;
; 	R0 = BUFFER ADDRESS
;
;-

TRMCNL:				;
	CLRB	CTCFLG		; CLEAR CONTROL C ENABLE
	QIO$S	#IO.KIL,#TERM	; KILL ALL TERMINAL I/O
	SUB	#4,R0		; POINT TO IOSB
	CALLR	NULLIO		; FINISH SUCCESS
;+
; <TRMBCT>
;
; BROADCAST TO TERMINAL (EQUIVALENT TO IO.WBT)
;

TRMBCT:				;
	MOV	R0,R1		; COPY BUFFER ADDRESS
	SUB	#4,R0		; POINT TO IOSB
	MOV	R.CNT(R1),R2	; SET BYTE COUNT
	ADD	#R.WDAT,R1	; POINT TO DATA
10$:	QIO$S	#IO.WBT,#TERM,,,R0,#WTAST,<R1,R2,#40> ; DO BREAK THROUGH WRITE
	CALL	CHKRES		; CHECK RESULT
	BCS	10$		; IF CS, RETRY
	RETURN			; RETURN TO CALLER
;+
; <RDAST>
;
; AST HANDLER FOR COMPLETED TERMINAL READ, OR READ AFTER PROMPT
;
;-

RDAST:
	SAVRG	<R0>		; SAVE R0
	MOV	2(SP),R0	; R0 = ADDRESS OF IOSB AND BUFFER
	SAVRG	<R1,R2,R3,R4>	; SAVE SOME MORE REGISTERS
	MOV 	R0,R1		; COPY IOSB ADDRESS
	ADD	#4,R0		; POINT TO BUFFER
	TSTB	R.TRM(R0)	; WAS THIS A READ WITH TERMINATOR TABLE?
	BEQ	10$		; IF EQ, NO
	BIT	#IO$MNOECHO,R.MOD(R0) ; NO ECHO MODE?
	BNE	10$		; IF NE, YES ... DON'T OUTPUT TERMINATOR
	MOV	R1,R2		; POINT TO TERMINATING CHARACTER
	INC	R2		;   ...
	CALL	ECTERM		; ECHO TERMINATOR STRING

10$:	MOV	2(R1),R.RDAT(R0)	; SET BYTE COUNT
	BIT	#IO$MCVTLOW,R.MOD(R0)	; CONVERT LOWER TO UPPER ?
	BEQ	30$		; IF EQ, NO
	MOV	R0,R2		; COPY BUFFER ADDRESS
	ADD	#R.RDAT+2,R2	; POINT TO DATA
	MOV	2(R1),R3	; COUNT
	BEQ	30$		; IF EQ, PROCEED
20$:	MOVB	(R2),R4		; TRANSLATE BYTE
	MOVB	CVTLUP(R4),(R2)+; SET BACK IN BUFFER
	SOB	R3,20$		;
30$:
	CLR	R4		; ASSUME NO TERMINATOR IN BUFFER
	MOV	#RP.END,R.OPC(R0) ; SET FOR END STATUS
	CLR	R.MOD(R0)	; NO MODIFIER
	MOV	2(R1),R2	; R2 = BYTE COUNT = OFFSET TO TERMINATOR
	ADD	#R.RDAT+2,R2	; ADD IN OVERHEAD
	MOV	R0,R3		; COPY ADDRESS
	ADD	R2,R3		; R3 = ADDRESS TO INSERT TERMINATOR
	MOVB	1(R1),(R3)	; SET TERMINATOR IN BUFFER
	BEQ	40$		; IF EQ, NO TERMINATOR
	INC	R4		; UPDATE LENGTH OF TERMINATOR
	INC	R.RDAT(R0)	;  AND COUNT OF BYTES IN BUFFER
40$:	MOVB	(R1),R2		; R2 = I/O STATUS
	CMPB	#IE.EOF,R2	; EOF
	BNE	50$		; IF NE, NO
	MOVB	#CTLZ,(R3)	; SET IN BUFFER
	MOVB	(R3),1(R1)	; AND IN STATUS
	INC	R4		; UPDATE LENGTH OF TERMINATOR
	INC	R.RDAT(R0)	;  AND COUNT OF BYTES IN BUFFER
50$:
	CALL	CNVRST		; CONVERT THE I/O STATUS
	MOV	R2,R.STA+0(R0)	; SET IN BUFFER
	MOV	2(R1),R.STA+2(R0) ; SET OFFSET TO TERMINATOR
	MOVB	1(R1),R.STA+4(R0) ; SET TERMINATOR
	MOV	R4,R.STA+6(R0)	; SET LENGTH OF TERMINATOR
	MOV	R.RDAT(R0),R2	; COUNT
	ADD	#R.RDAT+2,R2	; ADD IN OVERHEAD
	SUB	#4,R0		; POINT TO IOSB
	CALL	LNKWRT		; ISSUE LINK WRITE
	RESRG	<R4,R3,R2,R1,R0>; RESTORE THE REGISTERS
	TST	(SP)+		; CLEAN UP STACK
	ASTX$S			; EXIT THE AST
;+
; <ECTERM>
;
; ECHO TERMINATOR STRING FOR IO.RTT
;
; INPUT:
;
;	R0 = BUFFER ADDRESS
;	R1 = I/O STATUS BLOCK
;
; REGISTERS MODIFIED:
;	R2, R3
;-
ECTERM:	MOV	#TRMTAB,R2	; POINT TO CONTROL TABLE

10$:	TSTB	(R2)		; END OF TABLE?
	BEQ	30$		; IF EQ, YES
	CMPB	(R2)+,1(R1)	; IS THIS THE TERMINATOR?
	BNE	20$		; IF NE, NO
	MOVB	(R2)+,R3	; GET LENGTH OF STRING
	QIOW$S	#IO.WLB,#TERM,#2,,,,<R2,R3>
	RETURN

20$:	MOVB	(R2)+,R3	; GET LENGTH OF STRING
	ADD	R3,R2		; SKIP OVER STRING
	BR	10$		;   AND TRY AGAIN

30$:	MOV	R1,R2		; POINT TO TERMINATOR
	INC	R2		;   ...
	QIOW$S	#IO.WLB,#TERM,#2,,,,<R2,#1>
	RETURN

;
; TERMINATOR CONTROL TABLE
;
TRMTAB:	.BYTE	3,4,'^,'C,CR,LF	; ^C
	.BYTE	32,4,'^,'Z,CR,LF; ^Z
	.BYTE	0
	.EVEN
;+
; <WTAST>
;
; AST HANDLER FOR COMPLETED TERMINAL WRITES
;
;-

WTAST:				;
	SAVRG	<R0>		; SAVE R0
	MOV	2(SP),R0	; R0 = ADDRESS OF IOSB AND BUFFER
	SAVRG	<R1,R2>		; SAVE SOME MORE REGISTERS
	MOV	R0,R1		; COPY IOSB ADDRESS
	ADD	#4,R0		; POINT TO BUFFER
	MOV	#RP.END,R.OPC(R0)	; SET END STATUS
	CLR	R.MOD(R0)	; CLEAR MODIFIER
	MOVB	0(R1),R2	; I/O STATUS
	CALL	CNVRST		; CONVERT THE I/O STATUS
	MOV	R2,R.STA+0(R0)	; SET STAUS IN BUFFER
	MOV	2(R1),R.STA+2(R0); BYTE COUNT
	CLR	R.STA+4(R0)	;
	CLR	R.STA+6(R0)	;
	MOV	#R.RDAT,R2	; SET BYTE COUNT FOR LINK WRITE
	MOV	R1,R0		; R0 = IOSB ADDRESS
	CALL	LNKWRT		; ISSUE LINK WRITE
	RESRG	<R2,R1,R0>	; RESTORE THE REGISTERS
	TST	(SP)+		; CLEAN UP STACK
	ASTX$S			; EXIT THE AST
;+
; <CNVRST>
;
; SUBROUTINE TO CONVERT I/O STATUS
;
; INPUT:
;
;	R2 = I/O STATUS (RSX)
;
; OUTPUT:
;
;	R2 = I/O STATUS (VMS)
;-

CNVRST:				;
	SAVRG	<R0>		; SAVE R0
	MOV	#STATAB,R0	; R0 = ADDRESS OF STATUS TRANSLATE TABLE
10$:
	CMPB	R2,(R0)+	; MATCH ON STATUS ?
	BEQ	20$		; IF EQ, YES
	TSTB	(R0)+		; POINT TO NEXT
	TST	(R0)+		; ENTRY
	CMP	R0,#STAEND	; END OF TABLE ?
	BNE	10$		; IF NE, NO
	IOT			; DEBUG FOR NOW
20$:	TSTB	(R0)+		; POINT TO VMS STATUS
	MOV	(R0),R2		; SET STATUS TO R2
	RESRG	<R0>		; RESTORE R0
	RETURN			; RETURN TO CALLER
;+
; <UNSAST>
;
; UNSAST - UNSOLICITED AST HANDLER
;
;-
UNSAST:
	TSTB	LNKFLG		; IS THERE A LOGICAL LINK YET?
	BEQ	30$		; IF EQ, NO ... DROP THE UNSOLICITED CHARACTER
	SAVRG	<R0,R1,R2>	; SAVE SOME REGISTERS
	MOV	#POOL,R0	; R0 = ADDRESS OF LISTHEAD
	MOV	#$MXMSG+4,R1	; BYTE COUNT
	CALL	$RQCB		; GET A BUFFER
	BCC	10$		; IF CC, OK
	CALL	ERR15		; INDICATE ERROR
	CALL	SETF		; SET FLAG TO WAKE UP
	BR	20$		;
10$:	MOV	R0,R1		; COPY BUFFER ADDRESS
	ADD	#4,R1		; R1 = BUFFER ADDRESS, R0 = IOSB ADDRESS
	MOV	#RP.ATN,R.OPC(R1)	; SET OPCODE
	MOV	#RA.UNS,R.MOD(R1)	; SET MODIFIER
	MOVB	LBUF+G.LUNU,R.UNIT(R1)	; SET TERMINAL UNIT NUMBER
	MOV	#R.HLEN,R2	; SET BYTE COUNT 
	CALL	LNKWRT		; ISSUE LINK WRITE
20$:	RESRG	<R2,R1,R0>	; RESTORE THE REGISTERS
30$:	TST	(SP)+		; CLEAN UP STACK
	ASTX$S			; EXIT AST
;+
; <CTCAST>
;
; CTCAST - CONTROL/C CONTROL/Y AST HANDLER
;
;-
CTCAST:
	SAVRG	<R0>		; SAVE R0
	MOV	2(SP),R0	; R0 = CTRL C/ CTRL Y
	CMPB	#CTLC,R0	; CTRL C ?
	BNE	10$		; IF NE, MUST BE CTRL Y
	TSTB	CTCFLG		; CTRL C ENABLED ?
	BEQ	20$		; IF EQ, NO MAKE LIKE CTRL Y
	MOVB	#'C,CYECH+2	; SET TO ECHO CTLC
	XQT	ECOQIO		; ECHO THE CHARACTER
	CALL	CTCTST		; TOO MANY ?
	BCS	60$		; IF CS, YES
	INCB	CTCTIM		; INDICATE ONE HAPPENED
	MOV	#RA.CTC,CTCCTY+R.MOD ; INDICATE CTRL C
	CLRB	CTCFLG		; DISABLE / CTRL C 
	BR	40$
10$:	CMPB	#CTLY,R0	; IS IT A CTRL Y
	BNE	60$		; IF NE, IGNORE THE CHARACTER
20$:	MOVB	#'Y,CYECH+2	; SET TO ECHO CTLY
	XQT	ECOQIO		; ECHO THE QIO
	CALL	CTYTST		; TOO MANY CTY ?
	BCS	60$		; IF CS, EXIT
	INCB	CTYTIM		; INDICATE ONE HAS HAPPENED
30$:	TSTB	CTYFLG		; CTRL Y ENABLED ?
	BEQ	50$		; IF EQ, NO 
	MOV	#RA.CTY,CTCCTY+R.MOD ; INDICATE CTY
	CLRB	CTYFLG		; DISABLE CTRL Y
40$:	MOVB	LBUF+G.LUNU,CTCCTY+R.UNIT ; SET UNIT NUMBER
	XQT	SNDCC		; SEND CTRL C/Y MESSAGE
50$:	XQT	MRKT		; SCHEDULE A TIMER
60$:	RESRG	<R0>		; RESTORE R0
	TST	(SP)+		; CLEAN UP DATA
	ASTX$S			; EXIT AST

CTCTST:	TSTB	CTCTIM		; ANOTHER CTRL C BEFORE TIMER EXPIRE ?
	BNE	ASKQ		; IF NE, YES
	RETURN
CTYTST:	TSTB	CTYTIM		; ANOTHER CTRL Y BEFORE TIMER EXPIRE ?
	BNE	ASKQ		; IF NE, YES
	RETURN
ASKQ:	BISB	#100,R0		; MAKE CHARACTER OF CTRL C/Y
	MOVB	R0,CYCHAR	; MOVE TO MESSAGE
	XQT	ASKQIO		; ASK IF WE SHOULD ABORT THE SESSION
	CMPB	#IS.TMO,QIOSB	; TIMEOUT ?
	BNE	10$
	QIO$S	#IO.WLB,#TERM,,,,,<#CTLU,#CTLUC>
10$:	BICB	#40,CYREP	; CONVERT LOWER TO UPPER
	CMPB	#'Y,CYREP	; EXIT ?
	BEQ	20$		; IF EQ, YES
	CLC
	RETURN			; PROCEED 
20$:	CALL	SETF		; WAKE UP
	XQT	KILQIO		; KILL TERMINAL I/O
	XQT	ABT		; ABORT THE LINK
	SEC			; INDICATE NO MORE PROCESSING
	RETURN

MRKAST:
	CLRB	CTCTIM		; INDICATE TIMER HAS EXPIRED
	CLRB	CTYTIM		;
	TST	(SP)+		; CLEAN UP STACK
	ASTX$S			; EXIT AST
;+
; <NDAST>
;
; NDAST - NETWORK DATA AST HANDLER
;
;-
NDAST:
	XQT	GND		; GET NETWORK DATA
	TSTB	NIOSB		; ANY DATA ?
	BMI	10$		; IF MI, NO
	SAVRG	<R0,R1,R2>	; SAVE SOME REGISTERS
	MOVB	NIOSB+1,R0	; R0 = MAILBOX ID
	ASL	R0		; MAKE WORD INDEX
	CALL	@NETDSP(R0)	; DISPATCH THE FUNCTION
	RESRG	<R2,R1,R0>	; RESTORE THE REGISTERS
10$:	ASTX$S			; EXIT AST

NABO:				; NETWORK ABORT
	MOV	#ABTCOD,R0	; POINT TO OUTPUT AREA
	CLR	R1		; GET THE ERROR CODE
	BISB	NIOSB+2,R1	;  ...
	MOV	#<3*4000>+10.,R2; SET UP CONVERSION DATA
	CALL	$CBTA		; CONVERT ERROR CODE TO DECIMAL
	MOVB	#'.,(R0)+	; SHOW ERROR CODE IS DECIMAL
	CLRB	(R0)+		; PLANT TERMINATOR
	CALL	ERR13		; ISSUE MESSAGE
NDSC:
NABT:
	MOV	#EX$SUC,XSTAT	; SET EXIT STATUS
SETF:				; SET EVENT FLAG TO FORCE A WAKE UP 
				; AND THUS A TASK EXIT
	SETF$S	#3		; WAKE UP
	RETURN			; RETURN TO CALLER

CHKRES:	BCC	10$		; IF CC, OPERATION SUCCESSFUL
	WSIG$S			;
	SEC			; RETRY OPERATION
10$:	RETURN
;
; ERROR & MESSAGE HANDLER
;

ERR19:	INC	ERCNT		; INSUFFICIENT TTDRV SUPPORT
ERR18:	INC	ERCNT		; RETURN TO LOCAL
ERR17:	INC	ERCNT		; PROTOCOL NOT SUPPORTED BY REMOTE
ERR16:	INC	ERCNT		; LINK I/O ERROR
ERR15:	INC	ERCNT		; FAILED TO ALLOCATE BUFFER FOR I/O
ERR14:	INC	ERCNT		; INSUFFICIENT DYNAMIC MEMORY
ERR13:	INC	ERCNT		; NETWORK ABORT
ERR12:	INC	ERCNT		; REMOTE RECEIVER ABORT
ERR11:	INC	ERCNT		; REMOTE DISCONNECT
ERR10:	INC	ERCNT		; UNEXPECTED MAILBOX ENTRY
ERR9:	INC	ERCNT		; FAILED TO SEND INITIALIZE MESSAGE
ERR8:	INC	ERCNT		; FAILED TO RECEIVE CONF MESSAGE
ERR7:	INC	ERCNT		; FAILED TO SEND CONFIGURATION MESSAGE
ERR6:	INC	ERCNT		; FAILED TO ATTACH TERMINAL
ERR5:	INC	ERCNT		; FAILED TO ACCESS NODE
ERR4:	INC	ERCNT		; FAILED TO ACCESS NET DATA QUEUE
ERR3:	INC	ERCNT		; FAILED TO ACCESS NETWORK
ERR2:	INC	ERCNT		; FAILED TO GET NODE NAME
ERR1:	INC	ERCNT		; FAILED TO GET COMMAND LINE
	MOV	ERCNT,R1	; R1=ERROR NUMBER
	ASL	R1		; MAKE WORD INDEX
	MOV	MSGTB(R1),R0	; R0=ADDRESS OF MESSAGE
	MOV	#ERMSG+2,R2	; POINT AREA TO INSERT TEXT
	MOVB	RVTN+0,(R2)+	; SET TASK NAME IN MESSAGE
	MOVB	RVTN+1,(R2)+	;
	MOVB	RVTN+2,(R2)+	;
	MOVB	#' ,(R2)+	; INSERT BLANK
	MOVB	#'-,(R2)+	; INSERT -
	MOVB	#'-,(R2)+	; INSERT -
	MOVB	#' ,(R2)+	; INSERT BLANK
10$:	MOVB	(R0)+,R1	; INSERT MESSAGE TEXT
	CMPB	R1,#'%		; ESCAPE CHARACTER?
	BNE	30$		; IF NE, NO
	MOV	NODPTR,R1	; POINT TO NODE NAME STRING
20$:	MOVB	(R1)+,(R2)+	; COPY NODE NAME INTO ERROR MESSAGE
	BNE	20$		;  ...
	TSTB	-(R2)		; BACK UP OVER TERMINATOR
	BR	10$		; CONTINUE

30$:	MOVB	R1,(R2)+	; COPY CHARACTER INTO MESSAGE
	BNE	10$		;   ...
	SUB	#ERMSG,R2	; COMPUTE LENGTH OF MESSAGE
	MOV	R2,ERRQIO+Q.IOPL+2
	XQT	ERRQIO		; OUTPUT ERROR MESSAGE
	CLR	ERCNT		; RESET ERROR COUNTER
	MOV	#EX$SEV,XSTAT	; SET EXIT STATUS
	SEC			; AND CARRY
	RETURN			; RETURN TO CALLER
	.PSECT	RVTD,RW,D
;
; CONSTANTS AND LOCAL DATA AREAS
;
GMCR:	GMCR$			; GET COMMAND LINE
	.BLKW	4
ALUN:	ALUN$			; ASSIGN LUN
MRKT:	MRKT$	,3,2,MRKAST	; ^C/^Y TIMER
NODQIO:	QIOW$	IO.RPR,TERM,2,,IOSB,,<GMCR+G.MCRB,80.,,NODP,7,'$>
QIOW:	QIOW$	IO.WLB,TERM,2,,IOSB,,<,,'$>
ERRQIO:	QIOW$	IO.WBT,TERM,2,,IOSB,,<ERMSG,0>
KILQIO:	QIOW$	IO.KIL,TERM,5
ECOQIO:	QIOW$	IO.WBT,TERM,5,,,,<CYECH,4>
ASKQIO:	QIOW$	IO.RPR!TF.TMO,TERM,5,,QIOSB,,<CYREP,4,2,CYASK,CYASKC,'$>
TBFQIO:	QIOW$	SF.GMC,TERM,2,,IOSB,,<TBFBUF,TBFSIZ>
SMCQIO:	QIOW$	SF.SMC,TERM,2,,IOSB,,<CHABUF,CHASIZ>
GMCQIO:	QIOW$	SF.GMC,TERM,2,,IOSB,,<CHABUF,CHASIZ>
SAVQIO:	QIOW$	SF.GMC,TERM,2,,IOSB,,<SAVBUF,SAVSIZ>
RSTQIO:	QIOW$	SF.SMC,TERM,2,,IOSB,,<SAVBUF,SAVSIZ>

OPNET:	OPNW$	NDATA,1,IOSB
NTDATA:	SPAW$	NDATA,1,IOSB,,<NDAST>
SNDCNF:	SNDW$	LINK,1,IOSB,,<CNFMSG,CNFLEN>
RCVCNF:	RECW$	LINK,1,IOSB,,<CNFBUF,40.>
SNDINI:	SNDW$	LINK,1,IOSB,,<INIMSG,INILEN>
SNDCC:	SND$	LINK,1,,,<CTCCTY,R.HLEN>
GLND:	GLNW$	NDATA,1,IOSB,,<MRR18N,6>
GND:	GNDW$	NDATA,4,NIOSB,,<MBX,MBXLEN>
ABT:	ABTW$	LINK,1

PMRBLK:	.BYTE	LINK		; LOGICAL LINK
	.BYTE	1		; EVENT FLAG
	.BYTE	0		; HOP COUNT
	.BYTE	23.		; OBJECT TYPE
	.WORD	0		; POINTER TO NODE NAME STRING
	.WORD	0		; POINTER TO TASK NAME
	.WORD	0		; POINTER TO ACS STRING
;
; THE FOLLOWING TERMINAL CHARACTERISTICS ARE THE ONLY ONES THAT ARE SUPPORTED.
;

;	TC.ACR <=> TT$M_WRAP
;	TC.BIN <=> TT$M_PASSALL
;	TC.ESQ <=> TT$M_ESCAPE
;	TC.HLD <=> TT$M_HOLDSCREEN
;	TC.NEC <=> TT$M_NOECHO
;	TC.SCP <=> TT$M_SCOPE
;	TC.SMR <=> TT$M_LOWER
;	TC.8BC <=> TT$M_EIGHTBIT

;	TC.LPP <=> TT$M_PAGE
;	TC.WID <=> TERMINAL PAGE WIDTH
;	TC.TTP <=> TERMINAL TYPE
;
; DEFINE THE CHARACTERISTICS TRANSLATE TABLE
; FORMAT IS :
;
; RSX CHARACTERISTIC, OFFSET INTO RESPONSE BUFFER, VMS CHARACTERISTIC MASK
;
; POSITION IS CRITICAL AND MUST MATCH CHABUF BELOW
CHATRA:
TT$WRAP:	.BYTE	TC.ACR,1,2
TT$PASSALL:	.BYTE	TC.BIN,0,1
TT$ESCAPE:	.BYTE	TC.ESQ,0,10
TT$HOLDSCREEN:	.BYTE	TC.HLD,1,100
TT$NOECHO:	.BYTE	TC.NEC,0,2
TT$SCOPE:	.BYTE	TC.SCP,1,20
TT$LOWER:	.BYTE	TC.SMR,0,200
TT$EIGHTBIT:	.BYTE	TC.8BC,1,200


	.EVEN
CHABUF:				; TERMINAL CHA BUFFER
	.BYTE	TC.ACR,0
	.BYTE	TC.BIN,0
	.BYTE	TC.ESQ,0
	.BYTE	TC.HLD,0
	.BYTE	TC.NEC,0
	.BYTE	TC.SCP,0
	.BYTE	TC.SMR,0
	.BYTE	TC.8BC,0
CHACNT = <.-CHABUF>/2		; NUMBER OF SETTABLE ENTRIES
CHAWID:	.BYTE	TC.WID,0
CHALPP:	.BYTE	TC.LPP,0
CHATTP:	.BYTE	TC.TTP,0
CHASIZ=.-CHABUF
	.EVEN

TRMTRA:				; TERMINAL TYPE TRANSLATE TABLE
;
; NOTE ORDER IS IMPORTANT USED AS INDEX AND TRANSLATE
;
	.BYTE	T.UNK0,DT$TTYUNKN
	.BYTE	T.AS33,DT$TTYUNKN
	.BYTE	T.KS33,DT$TTYUNKN
	.BYTE	T.AS35,DT$TTYUNKN
	.BYTE	T.LA36,DT$L3X
	.BYTE	T.LA36,DT$L3X
	.BYTE	T.LA36,DT$L36
	.BYTE	T.VT05,DT$V05
	.BYTE	T.VT52,DT$V5X
	.BYTE	T.VT52,DT$V52
	.BYTE	T.VT55,DT$V55
	.BYTE	T.VT52,DT$V5X
	.BYTE	T.L180,DT$L180
	.BYTE	T.V100,DT$V100
	.BYTE	T.L120,DT$L120
TRMTC=<.-TRMTRA>/2
CNFMSG:
	.BYTE	1,1,0,0
	.WORD	4,4
CNFDAT:	.BLKL	2
.=CNFDAT
	.BYTE	DC$TERM		; (DC$TERM)
CNFTRM:	.BYTE	DT$V52		; TERMINAL TYPE - DEFAULT = VT52
CNFWID:	.WORD	80.		; WIDTH - DEFAULT = 80.
CNFCHA:	.BYTE	200,22,0	; CHARACTERISTICS - DEFAULT=
				; LOWER,SCOPE,WRAP
CNFLPP:	.BYTE	24.		; PAGE LENGTH - DEFAULT = 24.
CNFLEN=.-CNFMSG
INIMSG:	
	.WORD	RP.ATN,RA.UNS,0,0,0
INILEN=.-INIMSG
CTCCTY:	.BLKB	R.HLEN
.SAV=.
.=CTCCTY
	.WORD	RP.ATN
.=.SAV
	.EVEN

TBFBUF:	.BYTE	TC.TBF,0	; READ TYPEAHEAD BUFFER COUNT
TBFSIZ=.-TBFBUF

SAVBUF:	.BYTE	TC.ACR,0	; WRAP-AROUND MODE
	.BYTE	TC.BIN,0	; BINARY INPUT MODE
	.BYTE	TC.ESQ,0	; INPUT ESCAPE SEQUENCE RECOGNITION
	.BYTE	TC.HLD,0	; HOLD SCREEN MODE
	.BYTE	TC.NEC,0	; ECHO SUPPRESS
	.BYTE	TC.SCP,0	; SCOPE
	.BYTE	TC.SMR,0	; UPPER CASE CONVERSION
	.BYTE	TC.8BC,0	; PASS 8 BITS ON INPUT
	.BYTE	TC.TTP,0	; TERMINAL TYPE
	.BYTE	TC.WID,0	; PAGE WIDTH
	.BYTE	TC.LPP,0	; PAGE LENGTH
SAVSIZ=.-SAVBUF

IOSB:	.BLKW	2		; IO STATUS FOR GENERAL USE
QIOSB:	.BLKW	2		; IOSB FOR CTCCTY QUERY
NIOSB:	.BLKW	2		; IOSB FOR NET DATA
LNODE:	.WORD	0		; LENGTH OF NODE NAME
NODPTR:	.WORD	0		; POINTER TO NODE NAME STRING
XSTAT:	.WORD	EX$SUC		; EXIT STATUS
ERCNT:	.WORD	0		; ERROR COUNTER
RPRCNT:	.WORD	0		;
RDTMO:	.WORD	0		; READ TIMEOUT VALUE
LBUF:	.BLKW	6		; BUFFER FOR GLUN
GTSBUF:	.BLKW	4		;
LNKFLG:	.BYTE	0		; LINK STATUS BYTE
BBUF:	.BYTE	0		; TEMPORARY STORAGE
CTCTIM:	.BYTE	0		;
CTYTIM:	.BYTE	0		;
CTCFLG:	.BYTE	0		;
CTYFLG:	.BYTE	0		;
CYREP:	.ASCII	/    /		;
	.EVEN
CHAOFF:	.WORD	0
CHAMSK:	.WORD	0
VFC:	.WORD	0		; CARRIAGE CONTROL BYTE
RTTTAB:	.BLKW	16.
RTTFLG:	.WORD	0
MSGTB:	.WORD	0		; ERROR MESSAGE TABLE
	.WORD	MERR1		;
	.WORD	MERR2		;
	.WORD	MERR3		;
	.WORD	MERR4		;
	.WORD	$ERROR		;
	.WORD	MERR6		;
	.WORD	MERR7		;
	.WORD	MERR8		;
	.WORD	MERR9		;
	.WORD	MERR10		;
	.WORD	MERR11		;
	.WORD	MERR12		;
	.WORD	MERR13		;
	.WORD	MERR14		;
	.WORD	MERR15		;
	.WORD	MERR16		;
	.WORD	MERR17		;
	.WORD	MERR18		;
	.WORD	MERR19

NETDSP:				; DISPATCH FOR ENTRIES IN MAILBOX
	.WORD	-1		; ABORT
	.WORD	ERR10		; NT.CON
	.WORD	ERR10		; NT.INT
	.WORD	NDSC		; NT.DSC
	.WORD	NABT		; NT.ABT
	.WORD	NABO		; NT.ABO
	.WORD	ERR10		; NT.EVT
	.WORD	ERR10		; NT.VFY
	.WORD	ERR10		; NT.NSP

OPCTB:				; OPCODE TRANSLATE TABLE
	.WORD	61,READ		; IO$READVBLK
	.WORD	41,READ		; IO$READLBLK
	.WORD	14,READ		; IO$READPBLK
	.WORD	67,READ!PRMPT	; IO$READPROMPT
	.WORD	72,READ		; IO$TTYREADALL
	.WORD	73,READ!PRMPT	; IO$TTYREADPALL
	.WORD	60,WRITE	; IO$WRITEVBLK
	.WORD	40,WRITE	; IO$WRITELBLK
	.WORD	13,WRITE	; IO$WRITEPBLK
	.WORD	43,SETM		; IO$SETMODE
	.WORD	32,SETM		; IO$SETCHAR
	.WORD	47,SENM		; IO$SENSEMODE
	.WORD	33,SENM		; IO$SENSECHAR
	.WORD	70,CANCL	; IO$ACPCONTROL
	.WORD	-1,BCST		; 
	.WORD	0,0		; END OF TABLE

FUNDSP:				; I/O FUNCTION DISPATCH
	.WORD	-1		; TRAP
	.WORD	TRMRD		; READ TERMINAL
	.WORD	TRMWRT		; WRITE TO TERMINAL
	.WORD	TRMSMC		; SET CHARACTERISTICS
	.WORD	TRMGMC		; GET CHARACTERISTICS
	.WORD	TRMCNL		; CANCEL I/O
	.WORD	TRMBCT		; BROADCAST


STATAB:				; I/O STATUS TRANSLATE TABLE
	.BYTE	IS.SUC,0
	.WORD	SS$NORMAL	
	.BYTE	IS.TMO,0
	.WORD	SS$TIMEOUT
	.BYTE	IE.ABO,0
	.WORD	SS$ABORT
	.BYTE	IE.IES,0
	.WORD	SS$BADESCAPE
	.BYTE	IE.PES,0
	.WORD	SS$PARTESCAPE
	.BYTE	IE.DNR,0
	.WORD	SS$HANGUP
	.BYTE	IE.EOF,0
	.WORD	SS$NORMAL
STAEND = .
	.NLIST BEX

CVTLUP:				; TRANSLATE TABLE FOR LOWER TO UPPER
	.BYTE	0,1,2,3,4,5,6,7
	.BYTE	10,11,12,13,14,15,16,17
	.BYTE	20,21,22,23,24,25,26,27
	.BYTE	30,31,32,33,34,35,36,37
	.BYTE	40,41,42,43,44,45,46,47
	.BYTE	50,51,52,53,54,55,56,57
	.BYTE	60,61,62,63,64,65,66,67
	.BYTE	70,71,72,73,74,75,76,77
	.BYTE	100,101,102,103,104,105,106,107
	.BYTE	110,111,112,113,114,115,116,117
	.BYTE	120,121,122,123,124,125,126,127
	.BYTE	130,131,132,133,134,135,136,137
	.BYTE	140,101,102,103,104,105,106,107
	.BYTE	110,111,112,113,114,115,116,117
	.BYTE	120,121,122,123,124,125,126,127
	.BYTE	130,131,132,173,174,175,176,177
	.ENABL	LC
NODP:	.ASCII	<15>/Host: /	; PROMPT FOR NODE NAME
RVTN:	.ASCII	/RVT>/		; TASK NAME STRING
	.EVEN
;
; ERROR MESSAGES
;
MERR1:	.ASCIZ	/Failed to get command line/
MERR2:	.ASCIZ	/Failed to get node name/
MERR3:	.ASCIZ	/Failed to access network/
MERR4:	.ASCIZ	/Failed to access network data queue/
MERR6:	.ASCIZ	/Failed to attach terminal/
MERR7:	.ASCIZ	/Failed to send configuration message/
MERR8:	.ASCIZ	/Failed to receive configuration message/
MERR9:	.ASCIZ	/Failed to send initialize message/
MERR10:	.ASCIZ	/Unexpected mailbox entry/
MERR11:	.ASCIZ	/Remote disconnect/
MERR12:	.ASCIZ	/Remote receiver abort/
MERR13:	.ASCII	/Network link abort - Reason = /
ABTCOD:	.ASCIZ	/   ./
MERR14:	.ASCIZ	/Insufficient dynamic memory/
MERR15:	.ASCIZ	.Failed to allocate buffer for I/O.
MERR16:	.ASCII	.Link I/O error - (.
IOERR:	.BLKB	6
MERR17:	.ASCIZ	/Protocol not supported by remote node _%/
	.EVEN
MERR18:	.ASCII	/Control returned to node _/
MRR18N:	.ASCIZ	/        /			; MUST BE ON EVEN BOUNDARY
MERR19:	.ASCIZ	/Insufficient terminal driver support/
ERMSG:	.BYTE	CR,LF
	.BLKB	76.
	.BYTE	CR,LF
	.EVEN
MBX:	.BLKB	40.
MBXLEN=.-MBX
CYASK:	.ASCII	<CR><LF>/Are you repeating ^/
CYCHAR:	.BYTE	0
	.ASCII	/ to abort this remote session ? /
CYASKC = .-CYASK
CTLU:	.ASCII	/^U/<CR><LF>
CTLUC=.-CTLU
	.EVEN
CYECH:	.ASCII	<LF>/^ /<CR>
	.EVEN
CNFBUF:	.BLKB	40.
LFBUF:	.BYTE	CR
	.REPT	127.		
	.BYTE	LF			; BUFFER OF LINE FEEDS
	.ENDR
	.EVEN
POOL:	.BLKW	2			; BUFFER POOL LISTHEAD

	.END	RVT