	.TITLE RSXIO
	.IDENT	/BL1.0/
;$DEBUG=1			; FOR DEBUGGING

;
; VERSION BL1.0
;
; Orininal AUTHOR: L. WADE 1-JUN-72
;
; MODIFIED BY:
;
;	E. POLLACK U. OF W. 19-DEC-73
;
;	D. N. CUTLER 14-SEP-75
;
; SIG mofification
;	SIG01		CHANGE DEVICE FOR WAIT TO TI	
;
;	J. CLEMENT AUGUST 1982
;		ADDED STACKED I/O FOR SUPPORT OF REQUIRE STATEMENT
;		REARRANGED LUNS FOR NEATNESS
;		DEC 1982	Added dynamic memory routines
;
; RUNOFF I/O ROUTINES
;
; MACRO LIBRARY CALLS
;
	.MCALL	QIOW$S
	.MCALL	GET$S,PUT$S,CLOSE$
;
; FILE INPUT/OUTPUT ROUTINES
;-
	.IFDF	$DEBUG
;
;	The following debuggin routines are designed to ouput
;	useful information when debugging new features
;
;	If $DEBUG is defined each input line is automatically output.
;	In addition a call to CHROUT will output the character in R1.
;	Control characters are enclosed in <>,
;
	.PSECT	$CODE,RO,I,LCL,CON
CHROUT::	MOV	R1,TEMP
	MOV	R1,-(SP)	; save for restore
	BIC	#177600,R1	; clear extra bits
	CMPNE	R1,#CR,10$	; NOT CARRIAGE RET
	QIOW$S	#IO.WAL,#1,#1,,,,<#CRM,#4>
	BR	100$
10$:	CMPNE	R1,#LF,20$	; NOT LINE FEED
	QIOW$S	#IO.WAL,#1,#1,,,,<#LFM,#4>
	BR	100$
20$:	CMPNE	R1,#TAB,30$
	QIOW$S	#IO.WAL,#1,#1,,,,<#TBM,#4>
	BR	100$
30$:	CMP	R1,#SPC		; PRINTABLE?
	BGE	40$		; YES
	MOVB	R1,CTM+1	; NO
	BISB	#'@,CTM+1
	QIOW$S	#IO.WAL,#1,#1,,,,<#CTM,#3>
	BR	100$
40$:	QIOW$S	#IO.WAL,#1,#1,,,,<#TEMP,#1>
100$:	MOV	(SP)+,R1	; Restore
	RETURN
	.PSECT	$VARS,RW,D,LCL,CON
SPACE:	.WORD	"  
TEMP:	.WORD	0
CRM:	.ASCII	/<CR>/
LFM:	.ASCII	/<LF>/
TBM:	.ASCII	/<TB>/
CTM:	.ASCII	/<@>/
	.EVEN
	.ENDC
	.PSECT	$VARS,RW,D,LCL,CON
ISTAT:	.BLKW	2
	.PSECT	$CODE,LCL,I,RO,CON
;
;	Source file input routine
;	  Get 1 line from current source file
;
FIN::	MOV	BUFADD,BUFAD	; Reset subst stack to input buffer
	CLRB	SUBSTK		; At bottom of substitute stack
	TSTNEB	EOFSW,40$	; END OF INPUT FILE?
	MOVB	LUNSTK,R0	; GET STACK POINTER
	MOV	FDBTAB(R0),R0	; NOW GET FDB BLOCK ADDRESS
	MOV	BUFADD,R1	; Input buffer address
	MOV	BF.CAD(R1),R1	; ACTUAL BUFFER
	ADD	#BFLNK+1,R1	; SKIP OVER LINKS
1$:	INC	@TRCBUF		; Next line number
	BEQ	1$		; Zero ?
	GET$S	R0,R1,#IBFSZ	; INPUT A RECORD	
	BCC	20$		; BR	IF I/O OK
	CMPEQB	#IE.EOF,F.ERR(R0),10$	; IT IS END OF FILE ON INPUT (RSX)
	MOV	#11.,R0			; Input error message
	CALL	ERMSG
	TSTNEB	LUNSTK,10$	; Is logical unit stack ok?
	JMP	WRERR3		; NO
10$:	TSTB	LUNSTK		; MORE LUNS IN STACK?
	BLE	40$		; NO MORE	
	SUB	#TRCLN,TRCBUF	; Backup to previous file
	MOVB	LUNSTK,R0	; GET POINTER	
	SUB	#2,R0		; BACK UP IN STACK
	MOVB	R0,LUNSTK	; SAVE IT	
	BR	30$
20$:	MOV	BUFADD,R1	; BUFFER HEADER ADDRESS
	MOV	F.NRBD(R0),BF.CNT(R1) ;GET BYTE COUNT OF LINE (RSX)
	MOV	BF.CAD(R1),R0	; AND GET THE BUFFER ADDRESS
	ADD	#BFLNK,R0	; Set up buffer address
	MOV	R0,BF.ADD(R1)	; SAVE ADDRESS
	INC	R0
	ADD	BF.CNT(R1),R0	; ADVANCE POINTER TO END OF CHARACTERS
	MOVB	#CR,(R0)+	; SET CR/LF AT END OF LINE (RSX)
	MOVB	#LF,(R0)+	; (RSX)
	ADD	#2,BF.CNT(R1)	;AND ADJUST BYTE COUNT	
	MOV	BF.CNT(R1),BF.MAX(R1) ; AND BUFFER SIZE
	CLR	BF.FUL(R1)	; SET POINTER TO BOTTOM OF BUFFER
	BITEQ	#DEBSW,$SWTCH,30$; No debug ?
	.ifdf	$DEBUG
	PUT$S	#TTBLK,#SPACE,#1; Another blank line
	.endc
	CALL	TTINOU		; Output whole input line
	.ifdf	$DEBUG
	PUT$S	#TTBLK,#SPACE,#1; Another blank line
	.endc
30$:	CLC
	RETURN
40$:	MOVB	#-1,EOFSW	; SET EOF
	MOV	R3,-(SP)
	MOV	BUFADD,R3	; Set nothing in buffer
	CALL	CLRBF		; Clear it
	MOV	(SP)+,R3
	MOV	#LF,R1		; AND OUTPUT END OF LINE
	SEC
	RETURN
;
;	This routine types out the whole input line
;
TTINOU::MOV	R1,-(SP)
	MOV	R2,-(SP)
	MOV	#IBUF1,R1			; Buffer header
	MOV	BF.FUL(R1),R2			; Bytes processed
	ADD	BF.CNT(R1),R2			; Plus remaining count
	SUB	#2,R2				; Remove carriage control
	BLE	TTOU1				; No data ?
	MOV	BF.CAD(R1),R1			; Actual buffer
	ADD	#BFLNK+1,R1			; Skip over links
	PUT$S	#TTBLK,R1,R2			; Output a line	
TTOU1:	MOV	(SP)+,R2			; Restore
	MOV	(SP)+,R1
	RETURN

;
;	Output 1 character
;		R1 = character
;
FOUT::	TSTNEB	$OUTSW,10$	; No output?
	MOVB	R1,@HFOUT+2	; STORE CHARACTER IN BUFFER
	INC	HFOUT+2		; INCREMENT BUFFER POINTER
	DEC	HFOUT+4		; ANY MORE ROOM IN BUFFER?
	BEQ	OUTPUT		; IF EQ NO
10$:	RETURN			; 
;
; THIS ROUTINE OUTPUTS THE CURRENT CONTENTS OF THE LINE BUFFER (RSX)
;
OUTPUT::MOV	HFOUT,LSTBLK+F.NRBD	; CALCULATE LENGTH OF LINE TO OUTPUT
	SUB	HFOUT+4,LSTBLK+F.NRBD
	BNE	10$			; Not empty ?
	BITNE	#CRSW,$SWTCH,30$	; CRLF output?
10$:	TSTNEB	$OUTSW,20$		; No output?
	BITEQ	#TTSW,$SWTCH,15$	; Not terminal output?
	BITEQ	#CRSW,$SWTCH,15$	; No CRLF output?
	BITEQB	#FD.TTY,LSTBLK+F.RCTL,15$; Not terminal device ?
	QIOW$S	#IO.WAL,#3,#1,,#ISTAT,,<#OUBUF,LSTBLK+F.NRBD>
	BCS	WRERR3			; IF CS ERROR		
	CMPNEB	#IS.SUC,ISTAT,WRERR3	; Error in output ?
	BR	20$
15$:	PUT$S	#LSTBLK,#OUBUF		; OUTPUT LINE		
	BCS	WRERR3			; IF CS ERROR		
20$:	MOV	HFOUT,HFOUT+4
	MOV	#OUBUF,HFOUT+2
30$:	RETURN
;
; I/O ERROR EXITS
;
WRERR3:	MOV	#10.,R0			; Output error message
	JMP	ILINP			; KIll  with error message

;
;	Output table of contents
;		R1	= STRING ADDRESS
;		R2	= LENGTH
;
OUTTOC:: PUT$S	#TOCBLK,R1,R2
	BCS	WRERR3
	RETURN
;	
; TERMINAL I/O ROUTINES
;
;
;	CALL	EROUT
;		R0= ASCIZ string address
;
;	CALL	TTOUT
;		R1	= STRING ADDRESS
;		R2	= LENGTH
;
EROUT::	MOV	R0,-(SP)
1$:	MOV	(SP)+,R1	; String address
	MOV	R1,R2		; DITTO
10$:	CMPNEB	(R2),#15,20$	; Not carriage return ?
	INC	R2
	MOV	R2,-(SP)	; Next sub string
	INC	(SP)		; Skip CR,LF
	MOV	#1$,-(SP)	; Next return
	BR	30$
20$:	TSTB	(R2)+		; FIND END OF STRING
	BNE	10$		; NOT FOUND
30$:	SUB	R1,R2		; LENGTH OF STRING
	DEC	R2
TTOUT::	TST	R2		; Check string length
	BLE	10$		; None ?
	PUT$S	#TTBLK,R1,R2	; OUTPUT STRING (RSX)
10$:	RETURN
;
; READ TERMINAL INPUT RECORD
;
TTC4N::	GET$S	#TTBLK		; GET A RECORD (RSX)
	CLR	TTBLK+F.NRBD	; MAKE LINE EMPTY (RSX)	
	RETURN			; 	
;
;	Wait for operator to adjust forms
;
OPRWAT::	
	BITEQ	#PAUSW,$SWTCH,10$	; DON'T WAIT FOR NEW PAPER?
	BITEQB	#FD.TTY,TTBLK+F.RCTL,10$; Device not a terminal ?
	BICB	#FD.CR,TTBLK+F.RATT	; KEEP FCS FROM ADDING LINE FEED
	MOV	#OPRTXT,R0		; Operator wake up message
	CALL	EROUT			; Output it
	BISB	#FD.CR,TTBLK+F.RATT	; RE-ENABLE CARRIAGE CONTROL
	CALL	TTC4N			; READ A CHARACTER	
10$:	RETURN				; RETURN	
	.psect	text,RO,D,LCL,CON
OPRTXT:	.ASCIZ	<7>/Adjust page & press "return"/<7>	; Wake up text
	.END
