	.TITLE	C2I
	.MCALL	QIO$S,QIOW$S,QIO$,DIR$,ASTX$S,DSAR$S,ENAR$S
	.MCALL	EXIT$S
	.LIST	MEB
;
;	C2 DATA ACQUISITION HEADER
;
;
;BUFFER HEADER (1 PER INPUT LUN)
;
BH.QUE	= 0				;NEXT HEADER BUFFER
BH.TYP	= 2				;HEADER TYPE
BH.OOP	= 4				;BYTE OUTPUT OPTION
BH.AOP	= 5				;ANALYSIS OPTION
BH.IMN	= 6				;INPUT MINIMUM COUNT, FOR ANALYSIS
BH.BCT	= 10				;BYTE #OF BUFFERS
BH.ICT	= 11				;NUMBER OF BUFFS IN INPUT QUE
BH.OCT	= 12				;NUMBER OF BUFFS IN OUTPUT QUE
BH.ACT	= 13				;NUMBER OF BUFFS IN ANALYSIS QUE
BH.CNT	= 14				;TOTAL # OF INPUT BUFFS
BH.BSQ	= 16				;POINTS TO BUFFER STATUS
BH.BOQ	= 20				;POINTS TO OUTPUT CONTROL BUFFER
BH.QIO	= 22				;BUFFER QIO$ FOR INPUT (14 WORDS 30 BYTES)
BH.BEG	= 52				;BEGIN COMMAND LIST
BH.END	= 54				;END COMMAND LIST
BH.SIZ	= 70				;LAST WORD IN BUFFER HEADER
;
;BUFFER STATUS
;
BS.QUE	= -2				;POINTS TO NEXT ENTRY IN QUE
BS.STS	= 0				;2 WORD I/O STATUS
BS.CNT	= 2				;BYTE COUNT FOR I/O
BS.ANL	= 4				;0 IF IN ANALYSIS QUE
BS.ANQ	= 6				;ADDRESS OF NEXT ENTRY IN ANL QUE
BS.ADD	= 10				;DATA BUFFER DOUBLE WORD ADDRESS
BS.BHQ	= 14				;POINTS BACK TO HEADER
BS.SIZ	= 20
;
;DATA BUFFER
;
BF.TYP	= 0				;BUFFER TYPE DEFINITION
BF.ICT	= 2				;INPUT TOTAL COUNT
BF.OCT	= 4				;OUTPUT TOTAL COUNT
BF.ACT	= 6				;ANALYSIS TOTAL COUNT
BF.CNT	= 10				;WORD COUNT
BF.DAT	= 12				;START OF DATA
;
;OUTPUT BUFFER
;
BO.QUE	= 0				;NEXT OUTPUT BUFFER
BO.OLN	= 2				;LOGICAL UNIT NUMBER
BO.OOP	= 3				; NON ZERO IF OUTPUT DESIRED
BO.OCT	= 4				;OUTPUT COUNT
BO.SIZ	= 6

;
;	CLIST DEFINITIONS
;
CL.BSZ	= 4				;MINIMUM BUFFER SIZE REQUIRED
CL.OFF	= 6				;OFFSET TO EXTRA INFO
CL.MSK	= 8.				;CLIST CRATE MASK
CL.SIZ	= 10.				;CLIST SIZE (# OF BYTES)
CL.BEG	= 12.				;CLIST BEGIN (FIRST EXECUTABLE CODE)

	.PSECT	SW.SYS,D,RW,OVR,GBL
	.BLKW	1
INCRUN:	.BLKW	6
MTDIS:	.BLKW	1
	.PSECT
;
;	C2 HEADERS (FIXED)
;
C2.BHQ::	.WORD	0		;POINTS TO FIRST BUFFER HEADER
C2.BOQ::	.WORD	0		;POINTS TO FIRST BUFFER OUTPUT BLOCK
C2.BAQ::	.WORD	0		;POINTS TO FIRST BUFFER STATUS BLOCK IN ANALYSIS
C2.BAE:	.WORD	C2.BAQ			;LAST IN ANALYSIS
C2.ACT::	.WORD	0		;NUMBER OF BUFFS ANALYZED
C2.OER:	.WORD	0			;NUMBER OF BAD OUTPUTS
C2.RUN::	.WORD	0		;RUN #
TERINI:	.WORD	0			;STATUS INDICATOR
ENDCNT:	.WORD	0			;COUNTS FLUSHED INPUT BUFFS
					;0	= END RUN (NON 0	= RUN)
;
;	SUBROUTINE WITH COROUTINE TO SAVE R5-R0+ SET UP R5-R3
;		R5	= HEADER
;		R4	= STATUS BUFFER
;		R3	= DATA BUFFER
;
C2SAV:	MOV	R3,-(SP)		;SAVE R3-R0
	MOV	R2,-(SP)
	MOV	R1,-(SP)
	MOV	R0,-(SP)
	MOV	10(SP),-(SP)		;SET UP RETURN ADDRESS
	MOV	R4,12(SP)		;SAVE R4
	MOV	14(SP),R4		;R4	= STATUS BUFF.
	MOV	R5,14(SP)		;SAVE R5
	MOV	BS.BHQ(R4),R5		;R5	= BUFF HEADER
	MOV	BS.ADD(R4),R3		;R3	= DATA BUFFER 
	JSR	PC,@(SP)+		;RETURN TO CALLER, THEN HERE
	MOV	(SP)+,R0		;RESTORE R0 TO R5
	MOV	(SP)+,R1
	MOV	(SP)+,R2
	MOV	(SP)+,R3
	MOV	(SP)+,R4
	MOV	(SP)+,R5
	ASTX$S				;RETURN FROM AST
	ENAR$S				;IF REJECTED RETURN TO HERE
	RTS	PC			;IF NOT AST NORMAL RETURN

;
;	AST ENTRY WHEN DATA BUFFER INPUT DONE
;
C2I::	JSR	PC,C2SAV		;SET UP R5 TO R3
	DECB	BH.ICT(R5)		;DECREMENT INPUT COUNT
	INC	BH.CNT(R5)		;INCREMENT # OF BUFFERS INPUT
	MOV	BH.CNT(R5),BF.ICT(R3)	;AND PUT INTO BUFFER
	MOV	BS.CNT(R4),BF.CNT(R3)	;PUT INTO DATA BUFFER
	MOVB	BS.STS(R4),BF.TYP+1(R3)	;SAVE ERROR TYPE FOR USER
;
;****	INSERT ERROR MESSAGES HERE LATER
;
	CMPB	BH.AOP(R5),#1		;CHECK ANALYSIS OPTION
	BLT	OUTTST			;NO ANALYSIS
	BEQ	ANAL			;MUST ANALYZE
	CMPB	BH.ICT(R5),#1		;CHECK STAT OF INPUT QUE
	BGT	2$			;IT IS GOOD WITH 2 ENTRIES
	INCB	BH.IMN(R5)		;NOT GOOD, REQUIRE MORE BUFFS IN QUE
	CMPB	BH.IMN(R5),BH.BCT(R5)	;COMPARE REQUIRED #INPUT WITH TOT#BUFFS
	BLT	2$			;IT IS LESS
	DECB	BH.IMN(R5)		;NOW IS MAX - 1
2$:
	CMPB	BH.ICT(R5),BH.IMN(R5)	;CHECK IF ENOUGH IN INPUT TO ANALYZE
	BLT	NOANAL
ANAL:	CLR	BS.ANQ(R4)		;THIS IS LAST IN ANALYSIS QUE
	MOV	R4,@C2.BAE		;INSERT STATUS BUFFER INTO END OF QUE
	MOV	R4,C2.BAE		;NOW IS LAST ENTRY
	ADD	#BS.ANQ,C2.BAE		;POINTS TO LAST ENTRY QUE
	INC	C2.ACT			;NUMBER ANALYZED
	MOV	C2.ACT,BF.ACT(R3)	;ANALYSIS NUMBER TO BUFFER
	INCB	BH.ACT(R5)		;ANALYSIS COUNT
	CLRB	BS.ANL(R4)		;IN ANALYSIS QUE
	BR	OUTTST
NOANAL:	CLR	BF.ACT(R3)		;NO ANALYSIS
	TSTB	BH.ACT(R5)		;TEST IF ANY IN ANALYSIS NOW
	BNE	OUTTST			;YES
	DECB	BH.IMN(R5)		;NO, LOWER MINIMUM
	BGT	OUTTST
	INCB	BH.IMN(R5)		;IS NOW 1
OUTTST:	CMPB	BH.OOP(R5),#1		;TEST OUTPUT OPTION
	BLT	NOOUT			;NO OUTPUT
	TST	MTDIS			; DISABLED?
	BNE	NOOUT			; YES
	BEQ	OUT			;MUST OUTPUT
	TSTB	BS.ANL(R4)		;TEST ANALYSIS STAT
	BEQ	NOOUT			;IN ANALYSIS SO NO OUTPUT

OUT:	INCB	BH.OCT(R5)		;INCRMENT OUTPUT COUNT
;;	MOV	#OQIO,R1		;QIO TABLE
	MOV	BH.BOQ(R5),R2		;OUTPUT QUE ADDRESS
	INC	BO.OCT(R2)		;INCREMENT OUTPUT COUNT
	MOV	BO.OCT(R2),BF.OCT(R3)	;AND PUT IN BUFFER
;;	MOVB	BO.OLN(R2),Q.IOLU(R1)	;LUN INTO QIO
;;	MOV	R3,Q.IOPL(R1)		;BUFFER ADDRESS
	MOV	BS.CNT(R4),R0		;BUFFER SIZE LESS HEADER
	ADD	#BF.DAT,R0		;TOTAL BUFFER SIZE 
	CMP	R0,#14.			;IS IT MINIMUM SIZE?
	BGE	1$			;YES
	MOV	#14.,R0			;NO, MAKE IT MIN.
1$:
;;;	MOV	R0,Q.IOPL+2(R1)		;PUT INTO IOPKT
;;	MOV	R4,Q.IOSB(R1)		;ADDRESS OF STATUS BUFFER
;;	DIR$	R1,ERROR		;EXECUTE OUTPUT QIO
	QIO$S	#IO.WLB,BO.OLN(R2),,,R4,#C2OUT,<R3,R0>
RETN:	RTS	PC
NOOUT:	CLR	BF.OCT(R3)		;NO OUTPUT
	TST	BS.ANL(R4)		;IS BUFF IN ANALYSIS
	BEQ	RETN			;YES, DO NOT RESTART INPUT

;
;	SECTION TO QUE BUFFERS FOR INPUT
;
C2STRT:	TST	TERINI			;ARE WE IN END MODE
	BEQ	RUNDWN			;YES,DO NOT CONTINUE
	MOV	R5,R1			;WILL BE QIO
	ADD	#BH.QIO,R1		;POINTS TO QIO
	INCB	BH.ICT(R5)		;INCREMENT INPUT COUNT
	CLR	BF.ICT(R3)		;NO INPUT COUNT TILL INPUT
	MOV	R4,Q.IOSB(R1)		;IN/OUT STATUS
	MOV	R3,Q.IOPL(R1)		;BUFFER ADDRESS
	ADD	#BF.DAT,Q.IOPL(R1)	;NOW POINTS TO DATA
	DIR$	R1,ERROR		;EXECUTE QIO
	RTS	PC
RUNDWN:	DEC	ENDCNT			;DECREMENT RUNDOWN COUNT
	BNE	10$			;NOT ZERO YET
	MOV	C2.BOQ,R2		;GET OUTPUT HEADER
1$:	MOVB	BO.OLN(R2),R0		;GET LUN
	QIO$S	#IO.WLB,R0,,,,,<#ENDBUF,#14.>,ERROR	;WRITE AN END BUFFER
	MOV	(R2),R2			;NEXT OUTPUT HEADER
	BNE	1$			;AGAIN IF MORE TO DO
10$:	RETURN

OQIO:	QIO$	IO.WLB,,,,,C2OUT	; QIO BLOCK FOR C2 OUTPUT
; 
;	AST ENTRY WHEN OUTPUT DONE
; 
C2OUT:	JSR	PC,C2SAV		; SET UP R3-R5
; 
; ****	HERE ISSUE ERROR MESSAGES LATER
; 
	CMPB	(R4),#IS.SUC		; WAS IT SUCCESS?
	BEQ	1$			; YES
	CMPB	(R4),#IE.EOT		; END OF TAPE?
	BEQ	2$			; YES
	INC	C2.OER			; INCREMENT OUTPUT ERROR COUNT
	BR	1$
2$:	MOV	R5,-(SP)		; SAVE CHAN POINTER
	CALL	KILLER			; KILL THIS RUN
	MOV	(SP)+,R5		; THIS CHAN
1$:	DECB	BH.OCT(R5)		; DECREMENT # OF BUFFS IN OUTPUT
	TSTB	BS.ANL(R4)		; STILL IN ANALYSIS?
	BEQ	RETN			; YES
	BR	C2STRT			; NO, INSERT INTO INPUT QUE

; 
;	SUBROUTINE TO DECLARE ANALYSIS OF CURRENT BUFFER DONE
; 
RBTS::	DSAR$S				; DISABLE AST RECOGNITION
	MOV	C2.BAQ,-(SP)		; CURRENT ANALYSIS BUFFER
	BNE	1$			; BUFFER IS IN ANALYSIS
	ENAR$S				; REENABLE AST RECOGNITION
	TST	(SP)+			; POP STACK
	RTS	PC
1$:	JSR	PC,C2SAV		; SIMULATE AST + REMOVE FROM INPUT QUE
	DECB	BH.ACT(R5)		; ONE FEWER BUFF IN ANAL.
	INCB	BS.ANL(R4)		; SET ANAL STAT TO ENDED OK
	MOV	BS.ANQ(R4),C2.BAQ	; MOVE NEXT BUFFER UP IN ANAL QUE
	BNE	2$			; NOT LAST ONE
	MOV	#C2.BAQ,C2.BAE		; SET TO POINT TO LAST ENTRY IN LIST
2$:	TSTB	BS.STS(R4)		; IS IT OUT OF OUTPUT QUE?
	BNE	C2STRT			; YES, PUT INTO INPUT QUE
	RTS	PC			; NO, EXIT
; 
;	REJECTION ERROR ROUTINE
; 
ERROR:	MOV	$DSW,R0			; PUT ERROR CODE IN R0
	BPT
	RTS	PC

IN.ILN	= 0
IN.CLS	= 2
IN.BCT	= 4
IN.BSZ	= 6
IN.OLN	= 10
IN.OOP	= 12
IN.ALN	= 14
IN.AOP	= 16
IN.ERR	= 20
;
;	CALL CSET(INLUN,CLIST,BUFFCOUNT,BUFFSIZE,OUTLUN,OPTION,
;		  ALUN, ANALOPT,LERR)
;
;	LERR	= 1	SUCCESS	IS.SUC
;		= 2	BUFFER SIZE TOO BIG (MAX 2048.)
;		= 3	INADEQUATE SPACE FOR BUFFERS
;		= 4	BUFFER TOO SMALL
;		= 5	BUFFER SIZE HAS ODD #BYTES
;		= 177600	BAD CLIST
;		= "400 + DSW	ATTACH DIRECTIVE REJECTED
;		> 128		ATTACHEMENT OF INPUT REJECTED
;		= "1000 + STS	ATTACHMENT FOR OUTPUT REJECTED
;		= "1400 + DSW	OUPUT ATTACH DIRECTIVE REJECTED
;
C2SET::	MOV	#^RET ,-(SP)		;SET UP FOR TRACEBACK
	MOV	#^RC2S,R4
	JSR	R4,NAM$			;TRACEBACK SET UP ROUTINE
	MOV	#9.,R0			;NUMBER OF PARAM
	JSR	PC,R5CHEK		;CHECK THEM
	MOV	#177600,@IN.ERR(R5)	;SET ERROR 4
	MOV	IN.CLS(R5),R0		;R0	= CLIST
	CMP	(R0),#104777		;IS FIRST WORD OF CLIST CORRECT?
	BNE	11$			;NO, EXIT WITH ERROR STATUS
	TST	2(R0)			;IS SECOND WORD CORRECT?
	BNE	11$			;NO, EXIT WITH ERROR STATUS
	TST	CL.BEG(R0)		;IS START OF CLIST OK?
	BGE	11$			;NO, IT IS POSITIVE
	CMP	CL.SIZ(R0),#4096.	;IS SIZE TOO BIG?
	BHI	11$			;YES
	CMP	CL.SIZ(R0),#10		;TOO SMALL?
	BLT	11$			;YES
	MOV	#IE.DAO,@IN.ERR(R5)	;*** BUFFER TOO SMALL
	CMP	@IN.BSZ(R5),CL.BSZ(R0)	;BUFFER SIZE > MINIMUM?
	BLT	11$			;NO
	QIOW$S	#IO.ATT,@IN.ILN(R5),#1,,#ISB,,<CL.MSK(R0)>,ERRDSW	;ATTACH THE INPUT UNIT
	MOV	ISB,@IN.ERR(R5)		;STATUS TO USER
	CMPB	ISB,#IS.SUC		;SUCCESS?
	BNE	11$			;NO
	MOV	@IN.BSZ(R5),R3		;R3	= BUFFER SIZE
	MOV	#4,@IN.ERR(R5)		;ERROR 4
	CMP	R3,#14.			;BUFF SIZE TOO SMALL?
	BLT	11$			;YES
	MOV	#2,@IN.ERR(R5)		;ERROR 2
	CMP	R3,#2048.		;SIZE TOO BIG?
	BHI	11$			;YES
	MOV	#5,@IN.ERR(R5)		;ERROR 5
	BIT	#1,R3			;ODD NUMBER OF BYTES?
	BNE	11$			;YES
	ADD	#BS.SIZ,R3		;ADD ON STATUS HEADER SIZE
	MUL	@IN.BCT(R5),R3		;MULTIPLY BY NUMBER OF BUFFS
	BMI	11$			;TOO MANY BUFFERS
	BCS	11$			;TOO MANY BUFFERS
	ADD	#BH.SIZ,R3		;ADD ON THE HEADER SIZE
	BCS	11$			;ALSO TOO LARGE
	MOV	C2.BOQ,R2		;NOW SEARCH FOR OUTPUT HEADER
3$:	CMPB	BO.OLN(R2),@IN.OLN(R5)	;IS OUTPUT LUN IN USE
	BEQ	4$			;YES, DO NOT RESERVE SPACE
	MOV	(R2),R2			;GET NEXT OUTPUT HEADER
	BNE	3$			;NOT AT END SO CONTINUE
	QIOW$S	#IO.ATT,@IN.OLN(R5),#1,,#ISB,,<>,ERRDSW	;ATTACH THE OUTPUT UNIT
	CMPB	ISB,#IS.SUC		;WAS IT OK!
	BEQ	13$			;YES
	ADD	#1000,ISB		;SET UP FOR OUTPUT ERR CODE
	MOV	ISB,@IN.ERR(R5)		;NO, BAD
	RETURN
13$:	ADD	#BO.SIZ,R3		;RESERVE SPACE FOR NEW OUTPUT HEADER
	BCC	4$			;OK, NO ERROR
11$:	RETURN
4$:	CLC
	MOV	#3,@IN.ERR(R5)		;NOT ENOUGH SPACE ERROR
	JSR	PC,BREQW		;R3	= HEADERS IF NO ERROR
	BCS	11$			;NO
	MOV	#1,@IN.ERR(R5)		;CLEAR ERROR PARAMETER
	MOV	C2.BHQ,BH.QUE(R3)	;PUT THE CURRENT HEADER
	MOV	R3,C2.BHQ		;AT THE BEGIN OF THE HEADER QUE
	MOV	R3,R4
	ADD	#BH.SIZ,R4		;R4	= EITHER OUTPUT OR INPUT STAT BUFFER
	TST	R2			;OUTPUT HEADER REQUIRED?
	BNE	6$			;NO
	MOV	R4,R2			;WILL BE OUT HEADER
	ADD	#BO.SIZ,R4		;R4	= FIRST INPUT STAT. BUFF.
	MOV	C2.BOQ,(R2)		;PUT THE NEW OUPUT STATUS BUFF.
	MOV	R2,C2.BOQ		;AT THE HEAD OF THE OUPUT STAT. QUE
	MOV	@IN.OLN(R5),BO.OLN(R2)	;INSERT UNIT #
6$:	MOV	R2,BH.BOQ(R3)		;OUTPUT STAT BUFF. INTO HEADER
	TST	@IN.OOP(R5)		; OUTPUT DESIRED?
	BEQ	7$			; NO
	INCB	BO.OOP(R2)		; YES
7$:	SUB	#BS.QUE,R4		;NOW POINTS TO STATUS
	MOV	#"C2,BH.TYP(R3)		;HEADER TYPE
	MOVB	@IN.BCT(R5),R2		;R2	= BUFFER COUNT
	MOVB	R2,BH.BCT(R3)		;SAVE COUNT IN HEADER
	MOVB	R2,BH.IMN(R3)		;MINIMUM NUMBER OF BUFFS IN INPUT
	ASRB	BH.IMN(R3)		;IS INITIALLY HALF TOT BUFFER COUNT.
	MOV	R3,R1			;WILL POINT TO QIO
	ADD	#BH.QIO,R1		;NOW R1 POINTS TO INPUT QIO$
	MOV	#006001,(R1)		;INSERT DIC INTO QIO$
	MOV	#IO.RBC!200,Q.IOFN(R1)	;INPUT FUNCTION 
	MOVB	@IN.ILN(R5),Q.IOLU(R1)	;INPUT LUN
	MOV	#C2I,Q.IOAE(R1)		;INSERT AST ADDRESS
	MOV	@IN.BSZ(R5),Q.IOPL+2(R1)	;BUFFER SIZE
	SUB	#BF.DAT,Q.IOPL+2(R1)		;NOW IS SIZE LESS HEADER
	MOV	IN.CLS(R5),R0			;POINTS TO CLIST
	MOV	CL.SIZ(R0),Q.IOPL+6(R1)		;COMMAND LIST SIZE
	MOV	CL.MSK(R0),Q.IOPL+12(R1)	;COMMAND LIST CRATE MASK
	ADD	#CL.BEG,R0			;POINTS TO START OF CLIST
	MOV	R0,Q.IOPL+4(R1)			;COMMAND LIST
	MOV	#-1,Q.IOPL+10(R1)		;TIMEOUT COUNT
	MOVB	@IN.OOP(R5),BH.OOP(R3)		;OUTPUT OPTION
	MOVB	@IN.AOP(R5),BH.AOP(R3)	;ANALYSIS OPTION
	MOV	@IN.BSZ(R5),R1		;BUFFER SIZE TO WORK WITH
	ADD	#BS.SIZ,R1		;STATUS HEADER + BUFFER TOTAL SIZE
	MOV	R3,R5			;R5	= BUFFER HEADER
	ADD	#BH.BSQ,R3		;R3	= STATUS QUE
12$:	MOV	R4,(R3)			;PUT FIRST STATUS INTO STAT QUE
	MOV	R4,R3
	ADD	#BS.QUE,R3		;R3	= POINTER TO NEXT STATUS BUFF.
	MOV	R4,R0			;WILL BE DATA BUFF
	ADD	#BS.SIZ+BS.QUE,R0	;R0	= DATA BUFF POINTER
	MOV	C2.BHQ,BS.BHQ(R4)	;SAVE REVERSE POINTER
	DECB	(R4)			;SET NOT IN I/O QUE
	DECB	BS.ANL(R4)		;SET NOT IN ANAL QUE
	MOV	R0,BS.ADD(R4)		;SAVE BUFFER ADDRESS
	MOVB	BH.QIO+Q.IOLU(R5),BF.TYP(R0)	;SET UP DATA TYPE
	ADD	R1,R4			;POINTS TO NEXT STS BUFF
	SOB	R2,12$			;CONTINUE TILL ALL SET UP
	RTS	PC			;ALL DONE!
ISB:	.WORD	0,0			;2 WORD STATUS BLOCK
ERRDSW:	MOV	#400,ISB		;SET UP DIRECTIVE REJECTED CODE
	MOVB	$DSW,ISB		;SET UP ERROR CODE
	RETURN

;
;	ROUTINE TO END C2 DATA ACQUISITION
;
C2MESS:	CLR	-(SP)			; 2'ND WORD OF MESSAGE BLOCK
	MOV	R0,-(SP)		; ADDRESS IF ASCIZ TEXT
	MOV	SP,R0			; POINTS TO MESSAGE BLOCK
	CLR	R1			; NON ERROR TYPE
	JSR	PC,$ERRLG		; OUTPUT MESSAGE
	CMP	(SP)+,(SP)+		; POP STACK
	RETURN
ENDMES:	.ASCIZ	/END   RUN/
BEGMES:	.ASCIZ	/BEGIN RUN/
RUNMES:	.ASCIZ	/CONTINUE RUN/
STPMES:	.ASCIZ	/STOP RUN/

	.EVEN
KILLER:	CLR	TERINI			;MAKE SURE WE ARE IN END MODE
	MOV	#C2.BHQ,R5		;GET FIRST BUFFER HEADER ADDRESS
	CLR	ENDCNT			;NOW CLEAR END COUNTER
1$:	MOV	(R5),R5			;GET FIRST HEADER
	BNE	2$			; YES, MORE
	RETURN
2$:	MOVB	BH.QIO+Q.IOLU(R5),R0	;LUN FOR INPUT
	QIO$S	#IO.KIL,R0		;KILL MIOP CHANNEL
	MOVB	BH.BCT(R5),R0		;NUMBER OF BUFFS THIS CHAN
	ADD	R0,ENDCNT		;TOTAL NUMBER OF BUFFS
	BR	1$			;CONTINUE
ENDBUF:	.WORD	-1,-1,-1,-1,-1,-1,-1
;
;
;
C2END::	DSAR$S				;DISABLE AST RECOGNITION
	TST	TERINI			;TEST IF RUN IN PROGRESS
	BNE	13$			;YES, WE CAN END IT
	JMP	FAILUR			;NO, DO NOT END
13$:	CALL	KILLER			; KILL ALL CHANS
4$:	MOV	#ENDMES,R0		; END RUN MESSAGE
	CALL	C2MESS			; OUTPUT
	BR	SUCCES			;GIVE SUCCESSFUL END

;
;	ROUTINE TO BEGIN D2 DATA ACQUISITION
;
C2BEG::	DSAR$S				;DISABLE AST RECOGNITION
	TST	TERINI			;TEST STATUS
	BNE	FAILUR			;SKIP BEGIN
	TST	ENDCNT			;BUFFS STILL IN USE?
	BNE	FAILUR			;YES
	MOV	#BEGMES,R0		; BEGIN MESSAGE TO OUTPUT
	CALL	C2MESS			; OUTPUT IT
	DEC	TERINI			;ENABLE START MODE
	CLR	C2.ACT			;CLEAR ANALYSIS COUNT
	MOV	#C2.BOQ,R2		;GET OUTPUT QUE
	TST	INCRUN			; DO WE INCREMENT RUN#?
	BNE	1$			; NO
	INC	C2.RUN			; YES
1$:	MOV	(R2),R2			;GET OUTPUT HEADER
	BEQ	3$			;NO MORE TO DO
	CLR	BO.OCT(R2)		;CLEAR OUTPUT COUNT
2$:	MOV	C2.RUN,BEGBUF+2		;PUT IN RUN #
	TST	MTDIS			; TAPE DISABLED?
	BNE	1$			; YES
	TSTB	BO.OOP(R2)		; THIS UNIT DISABLED?
	BEQ	1$			; YES
	QIO$S	#IO.WLB,BO.OLN(R2),,,,,<#BEGBUF,#14.>,ERROR	;WRITE BEGIN BUFFER
	BR	1$
3$:	MOV	#C2.BHQ,R5		;AGAIN GO DOWN LIST TO START THEM
4$:	MOV	(R5),R5			;GET HEADER
	BEQ	SUCCES			;NO MORE
	MOV	BH.BEG(R5),R0		;START CLIST
	BEQ	6$			;NONE TO DO
;	NOW EXECUTE THE BEGIN COMMAND LIST
	QIOW$S	#IO.RBC,BH.QIO+Q.IOLU(R5),#1,,,,<R0,CL.SIZ(R0),R0,#0,,CL.MSK(R0)>
6$:	CLR	BH.CNT(R5)		;CLEAR INPUT COUNT
	MOV	BH.BSQ(R5),R4		;GET FIRST STATUS BUFFER
5$:	MOV	BS.ADD(R4),R3		;BUFFER ADDRESS
	JSR	PC,C2STRT		;START INPUT
	MOV	BS.QUE(R4),R4		;GET NEXT STATUS
	BNE	5$			;CONTINUE TILL ALL BUFFS IN INPUT
	BR	4$			;NEXT HEADER
SUCCES:
	ENAR$S				;REENABLE AST
	CLC				;SUCCESS
C2RUN::	MOV	#RUNMES,R0
	CALL	C2MESS
	RETURN
C2STP::	MOV	#STPMES,R0
	CALL	C2MESS
	RETURN
FAILUR:	ENAR$S
	SEC				;FAILURE
	RETURN
BEGBUF:	.ASCII	'C2'
	.WORD	0,0,0,0,0,0

;
;	ROUTINE TO TEST STATUS OF DATA ACQUISITION
;
;	CALL ASTAT(ISTAT)
;		ISTAT	= 0	BUFFER READY
;		ISTAT	= 1	NO BUFFER TO ANALYZE
;		ISTAT	= 4	RUN ENDED
;		ISTAT	= 5	RUN ENDED NO BUFFERS TO ANALYZE
;
ASTAT::	MOV	#1,R0
	CALL	R5CHEK			;CHECK THE PARAMETERS
	CLR	@(R5)
	TST	TERINI			;CHECK IF END DATA
	BNE	1$			;NO
	BIS	#4,@(R5)		;4 INDICATES END DATA
1$:	TST	C2.BAQ			;CHECK IF ANY IN ANAL QUE
	BNE	2$			;YES
	BIS	#1,@(R5)		;SET BIT TO SAY NO
2$:	CALL	KBYES			;ALLOW INPUT
	RETURN

; 
;	CALL	BTRAN(IARRAY,IWORD,ISIZE)
;		TRANSFER DATA FROM DATA BUFFER TO IARRAY STARTING FROM
;		IWORD, TRANSFER ISIZE # OF WORDS.
;		IWORD	= 1 IS FIRST DATA WORD
;			= 0 IS THE DATA LENGTH
;			= -1 IS THE OUTPUT COUNT
;			= -2 IS THE ANALYSIS COUNT
;			= -3 IS THE INPUT COUNT
;			= -4 IS THE BUFFER TYPE
; 
BTRAN::	MOV	#^RAN ,-(SP)		; SET UP FOR TRACEBACK
	MOV	#^RBTR,R4
	JSR	R4,NAM$
	MOV	#3,R0			; 3 PARAM IN CALL
	JSR	PC,R5CHEK		; CHEK EM
	MOV	C2.BAQ,R1		; ANALYSIS QUE
	BEQ	2$			; NONE, SO EXIT
	MOV	BS.ADD(R1),R0		; BUFFER ADDRESS
	MOV	(R5)+,R2		; ARRAY ADDRESS
	MOV	@(R5)+,R3		; WORD# REQUESTED
	ASL	R3			; NOW IS BYTE NUMBER
	BVS	2$			; BAD WORD #
	MOV	R3,R1			; SAVE IT
	ADD	#BF.DAT-2,R3		; WORD IN BUFFER
	BLT	2$			; R3 IS TOO SMALL!!
	MOV	@(R5),R4		; NUMBER OF WORDS REQUESTED
	DEC	R4
	BLT	2$			; BAD COUNT
	ASL	R4			; NOW IS BYTE NUMBER
	BVS	2$
	ADD	R4,R1			; LAST WORD IN BUFFER
	BCS	2$			; BAD # OF WORDS + WORD #
	CMP	R1,BF.CNT(R0)		; IS FINAL WORD TOO BIG?
	BGT	2$			; YES
	ADD	R3,R0			; STARTING ADDRESS
	MOV	@(R5),R4		; COUNT
1$:	MOV	(R0)+,(R2)+		; MOVE 1 WORD
	SOB	R4,1$			; CONTINUE TILL DONE
	RTS	PC
2$:	
	JMP	BPARM
; 
;	IDATA	= IBR(IWORD)		GETS 1 WORD FROM DATA BUFFER
; 
IBR::	MOV	#^R  ,-(SP)		; SET UP FOR TRACEBACK
	MOV	#^RIBR,R4
	JSR	R4,NAM$
	MOV	#1,R0
	JSR	PC,R5CHEK		; CHECK NUMBER OF PARAM
	MOV	C2.BAQ,R1		; GET BUFFER HEADER
	BEQ	2$			; NO BUFFERS IN ANALYSIS
	MOV	BS.ADD(R1),R0		; BUFFER ADDRESS
	MOV	@(R5),R3		; WORD # REQUESTED
	ASL	R3			; NOW IS BYTE #
	BVS	2$			; BAD #
	CMP	R3,BF.CNT(R0)		; TOO BIG?
	BGT	2$			; YES
	ADD	#BF.DAT-2,R3		; POINTS TO DATUM
	BLT	2$			; TOO SMALL
	ADD	R3,R0			; BYTE # IN DATA BUFFER
	MOV	(R0),R0			; GET WORD
	RTS	PC			; RETURN
2$:	JMP	BPARM

;
;	CALL	FLUSH
;			THIS FLUSHES OUT UNUSED ANALYSIS BUFFFERS
;
FLUSH::	TST	TERINI			;TEST IF IN END RUN MODE
	BNE	10$			;NO, DO NOT FLUSH
5$:	CALL	RBTS			;FLUSH OUT 1 BUFFER
	TST	C2.BAQ			;ARE THERE ANY MORE?
	BNE	5$			;YES, CONTINUE TILL DONE
10$:	TST	MTDIS			; TAPING DISABLED?
	BEQ	11$			; NO
	RETURN
11$:	MOV	#C2.BOQ,R2		; GET HEADER
12$:	MOV	(R2),R2			; GET OUTPUT HEADER
	BNE	13$			; INPUT AVAILABLE
	RETURN
13$:	MOV	BO.OLN(R2),R0		; LOGICAL UNIT #
	TSTB	BO.OOP(R2)		; UNIT DISABLED?
	BEQ	12$			; YES
	MOV	#3,R1			; NUMBER OF EOF
14$:	QIOW$S	#IO.EOF,R0,#1		; WRITE AN EOF
	SOB	R1,14$			; CONTINUE TILL DONE
	MOV	#2,R1			; NO OF EOF TO SPACE OVER
15$:	QIOW$S	#IO.SPB,R0,#1,,,,<#-1>	; SPACE BACK OVER EOF
	SOB	R1,15$
	BR	12$
	.END
