	.TITLE	FTPCOPY	PLAIN (VANILLA FLAVORED) COPY DATA.
	.IDENT	/01-APR-83    V01.A/
;
;	Plain copying of records from input block to output block.
;
;	V01.A	twd	4/1/83	Initial release.
;
;	Subroutine used to deblock and block data in FTCOPY.  The
;	actual work is done by the MOVC5 instruction.  This
;	routine includes the padding/truncating of trailing data in both
;	records and blocks and padding output records.
;
;	The calling procedure is as follows:
;		PUSHL	# output records/block
;		PUSHL	# characters in output remainder.
;		PUSHL	# input records/block
;		PUSHL	# characters in input remainder.
;		PUSHL	destination length.
;		PUSHL	source length.
;		CALLS	#6,FT_PCOPY
;
;	Items passed in "COMMON" are:
;		FT_IN_DATA	Start of the input data array.
;		FT_OUT_DATA	Start of the output data array.
;		FTCB_B_PREC	Character to use when padding output records.
;		FTCB_B_TRAILR	Character to use when filling input trailing
;				data in records.
;		FTCB_B_TRAILB	Character to use when filling input trailing
;				data in blocks.
;		FTCB_L_BLK_READ	Number of blocks read on input.
;		FTCB_L_BLK_WRITE	Number of blocks written on output.
;		FTCB_L_REC_READ	Number of records read on input.
;		FTCB_L_REC_WRITE	Number of records written on output.
;
;		FLAG_V_OUT_COMP	Bit flag indicating that a write has just been
;				completed (=1).
;		FLAG_V_INIT_COP	Bit flag indicating that the output buffer
;				address and output record count need to be
;				initialized (this is only done once).
;
;	Registers used:
;		R0 - Holds the number of bytes in the source string.
;		R1 - Pointer to input string.
;		R2 - Not used.
;		R3 - Used as pointer to output string.
;		R4 - Not used.
;		R5 - Not used.
;		R6 - Not used.
;		R7 - Used as count of records to copy from input block.
;		R8 - Current count of records to be blocked into output block.
;		     This is initialized and kept current in this subroutine.
;		R9 - Not used.
;		R10 - Pointer to the FT control block
;		R11 - Pointer to the FT I/O block
;
	FTCBDEF		; FT CONTROL BLOCK DEFINITIONS.
;
	.PAGE
	.SUBTITLE ENTER THE COPY AND INITIALIZE VARIABLES.
;
	.ENTRY	FT_PCOPY,^M<>		; NO REGISTERS SAVED.
;
;		CHECK ON INITIALIZING THE OUTPUT POINTER AND COUNTER.
;
	BBC	#FLAG_V_INIT_COP,FTCB_W_FLAG(R10),20$	; IF INIT CLEAR, BRANCH.
;
10$:	MOVAL	FT_OUT_DATA,R3		; POINT TO THE OUTPUT DATA.
	MOVL	24(AP),R8		; # RECORDS TO PUT INTO OUTPUT BLOCK.
;
	BBSC	#FLAG_V_INIT_COP,FTCB_W_FLAG(R10),15$	; CLEAR INIT COPY BIT.
15$:	BRB	SET_PAR			; GO SET THE COPYING PARAMETERS.
;
20$:	BBS	#FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),10$	; IF OUT_COMPLETE SET,
						; BRANCH TO RE INIT.
;
;		RESTORE OLD VALUE OF OUTPUT COUNTER.
;
	MOVL	OUTPUT_COUNT,R8
;
SET_PAR:
	MOVL	16(AP),R7		; GET THE NUMBER OF RECORDS TO COPY
					; FROM THE INPUT BLOCK.
	MOVAL	FT_IN_DATA,R1		; POINTER TO INPUT BUFFER.
;
;
;		START THE MOVE PROCESS BY DECREMENTING THE COUNT OF RECORDS
;		TO COPY (R7) AND, IF 0 RECORDS, GO DIRECTLY TO ENDING THE
;		COPY AND MOVING THE TRAILING BYTES FROM THE BLOCK IF ANY.
;
START_MOV:
	SOBGEQ	R7,MOV_REC	; IF >= 0, GO MOVE NEXT RECORD.
;
	BRB	END_IN		; IF < 0, GO FINISH UP.
;
;		MOVE THE INPUT RECORD FROM THE INPUT BLOCK TO
;		THE OUTPUT RECORD IN THE OUTPUT BLOCK.
;
MOV_REC:
	MOVC5	4(AP),(R1),FTCB_B_PREC(R10),8(AP),(R3) ; MOVE DATA.
	INCL	FTCB_L_REC_READ(R10)	; INCR. COUNT OF RECORDS READ.
	INCL	FTCB_L_REC_WRIT(R10)	; INCR. COUNT OF RECORDS WRITTEN.
;
;		CHECK TO SEE IF THERE ARE TRAILING BYTES IN INPUT RECORD.
;
	TSTL	R0		; TRAILING BYTES -- R0 <> 0.
	BEQL	UPD_BUF		; IF NO TRAILING, GO UPDATE BUFFER ADDR.
;
;		GO TO TRAIL-RECORD BYTE SUBROUTINE TO DECIDE IF THE TRAILING
;		BYTES SHOULD BE KEPT OR NOT AND THEN MOVE THEM.
;
	BSBB	TRAIL_REC
;
;
;		INPUT AND OUTPUT POINTERS HAVE BEEN UPDATED IN THE MOVE - 
;		CHECK TO SEE IF THERE IS ANY MORE DATA TO MOVE.
;
UPD_BUF:
	BBSC	#FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),5$	; CLEAR THE OUTPUT
					; COMPLETED FLAG.
;
;		BRANCH TO SUB TO CHECK FOR LAST REC. TO THE OUTPUT BLOCK AND
;		CALL FT_OUTPUT IF NECESSARY.
;
5$:	BSBB	CHECK_OUT
;
	BRW	START_MOV	; GO BACK TO BEGINNING OF THE DEBLOCK LOOP.
;
	.PAGE
	.SUBTITLE	CLEAN UP AT THE END OF THE INPUT BLOCK.
;
END_IN:	
	TSTL	12(AP)		; CHECK TO SEE IF THERE ARE MORE CHARACTERS
				; IN THE INPUT BUFFER AND
	BEQL	GO_BACK		; RETURN IF NO MORE.
;
;		CHECK FOR KEEPING THE TRAILING DATA.
	BBC	#FLAG_V_TRAILB,FTCB_W_FLAG(R10),GO_BACK
;
;		MOVE THE TRAILING DATA INTO THE NEXT OUTPUT RECORD.
;
	MOVC5	12(AP),(R1),FTCB_B_TRAILB(R10),8(AP),(R3)
;
	INCL	FTCB_L_REC_WRIT(R10)	; INCR. THE COUNT OF RECORDS WRITTEN.
;
;		CHECK ON WHETHER OR NOT THE OUTPUT BLOCK HAS BEEN FILLED.
	BSBB	CHECK_OUT
;
;
;		GET READY AND RETURN TO CALL IN ROUTINE.
;
GO_BACK:
	MOVL	R8,OUTPUT_COUNT		; SAVE OUTPUT COUNTER.
;
	RET	
;
	.PAGE
	.SUBTITLE PLAIN COPY TRAILING RECORD ROUTINE.
;
;		SUBROUTINE FOR CHECKING AND KEEPING THE TRAILING RECORD BYTES.
;
;		IF TRAIL REC SET, DO NOT KEEP TRAIL BYTES IN REC.
;		ELSE - GO TO UPDATE THE BUFFER ADDRESSES.
;
TRAIL_REC:
	BBS	#FLAG_V_TRAILR,FTCB_W_FLAG(R10),10$
;
;		SOURCE STRING GREATER THAN DESTINATION - NEED TO UPDATE
;		POINTER TO NEXT "RECORD" IN THE SOURCE.
	ADDL2	R0,R1		; ADD REMAINING # BYTES TO THE POINTER.
20$:	RSB			; GO UPDATE BUFFER.
;
;		BEFORE MOVING, CHECK TO SEE IF LAST OUTPUT RECORD MOVED.
;
10$:	BSBB	CHECK_OUT
;
;		SAVE THE EXTRA BYTES IN A RECORD.
;
	MOVC5	R0,(R1),FTCB_B_TRAILR(R10),8(AP),(R3) ; MOVE EXTRA CHARACTERS.
	INCL	FTCB_L_REC_WRIT(R10)	; INCR. COUNT OF RECORDS WRITTEN.
;
;		CHECK FOR MORE CHARACTERS TO MOVE.
;
	TSTL	R0		; IF R0 <> 0 THEN MORE TO MOVE
	BEQL	20$		; RETURN.
	BRB	10$		; MOVE MORE CHARACTERS.
;
	.PAGE
	.SUBTITLE ROUTINE TO MAINTAIN OUTPUT COUNTER AND WRITE.
;
;		CHECK ON A FULL OUTPUT BUFFER
;
CHECK_OUT:
	SOBGTR	R8,10$		; DECREMENT THE OUTPUT RECORD COUNT AND
				; BRANCH IF OUTPUT BLOCK NOT FULL.
;
	MOVQ	R0,SAVE_R0	; SAVE R0 AND R1 VALUES
;
	PUSHL	R3		; PUSH THE OUTPUT STRING ADDRESS.
	PUSHL	20(AP)		; PUSH # BYTES REMAINING IN BLOCK.
	CALLS	#2,G^FT_PADEVEN	; PAD/EVEN THE OUTPUT BLOCK - PLAIN.
;
	CALLS	#0,G^FT_OUTPUT	; WRITE THE BLOCK.
;
;		RESET POINTER AND COUNTER OF DATA IN OUTPUT BLOCK.
;
	MOVAL	FT_OUT_DATA,R3	; ADDRESS OF THE OUTPUT DATA BUFFER.
	MOVL	24(AP),R8	; RESET # RECORDS IN OUTPUT BLOCK.
;
	MOVQ	SAVE_R0,R0	; RESTORE R0 AND R1 VALUES.
;
10$:	RSB		; RETURN TO CALLING LOCATION.
;
;
OUTPUT_COUNT:	.LONG	0		; SAVE AREA FOR THE OUTPUT COUNTER.
SAVE_R0:	.QUAD	0		; SAVE AREA FOR R0 AND R1.
;
	.END
