;***************************************************************************;
;									    ;
;				  COPY.SBR				    ;
;		       AlphaBASIC XCALL to copy a file			    ;
;									    ;
;***************************************************************************;
;Copyright (C) 1988 UltraSoft Corp.  All Rights Reserved.
;
;Written by: David Pallmann
;
;Copy a file and return status.
;
;	XCALL COPY, source_file$, dest_file$, status {, size}
;
;Where:	source_file$ .......... is a string containing the full or partial
;				specification of the source file to copy.
;	dest_file$ ............ is a string containing the full or partial
;				specification of the destination file.
;	status ................ is a floating point variable.  Set to -1
;				normally, or 0 if an error occurs.
;	size .................. is an optional floating point variable.  If
;				specified, the size of the file is returned
;				in blocks.
;Notes:
;
;	o  if string literals (e.g. "TEST.DAT ") are used instead of string
;	   variables for source and destination filespecs, a trailing space
;	   (as shown two lines above) is required - else you'll receive a
;	   file specification error from AMOS.
;	o  compatible with LOKSER.
;	o  compatible with AMOS 2.0 & the extended file system.
;
;1.0(100)  01-Jun-87  created. /DFP
;1.0(101)  01-Jul-88  support random files. /DFP

	VMAJOR=1
	VMINOR=0
	VEDIT=101.

	OBJNAM	.SBR

	SEARCH	SYS
	SEARCH	SYSSYM

	BLOCKS=D5

	STRING=2
	FLOAT=4

	.OFINI
	.OFDEF	COUNT,2
	.OFDEF	TYPE1,2
	.OFDEF	ADDR1,4
	.OFDEF	SIZE1,4
	.OFDEF	TYPE2,2
	.OFDEF	ADDR2,4
	.OFDEF	SIZE2,4
	.OFDEF	TYPE3,2
	.OFDEF	ADDR3,4
	.OFDEF	SIZE3,4
	.OFDEF	TYPE4,2
	.OFDEF	ADDR4,4
	.OFDEF	SIZE4,4
	.OFSIZ	XCSIZE

	.OFINI
	.OFDEF	FROM,D.DDB+512.
	.OFDEF	TO,D.DDB+512.
;[101]	.OFDEF	MODULE,6
	.OFSIZ	MEMSIZ

START:	PHDR	-1,,PH$REE!PH$REU

CLEAR:	MOV	A4,A6
	MOV	#MEMSIZ-1,D6
10$:	CLRB	(A6)+
	DBF	D6,10$
	CLR	BLOCKS

CHECK:	CMPW	COUNT(A3),#3
	JLO	CNTERR
	CMPW	TYPE1(A3),#STRING
	JNE	TYPERR
	CMPW	TYPE2(A3),#STRING
	JNE	TYPERR
	CMPW	TYPE3(A3),#FLOAT
	JNE	TYPERR

SETUP:	LEA	A0,FROM(A4)
	MOV	ADDR1(A3),A2
	FSPEC	FROM(A4),WRT
	CALL	INIT
	LEA	A0,TO(A4)
	MOV	ADDR2(A3),A2
	FSPEC	TO(A4),WRT
	CALL	INIT

LOOKUP:	LOOKUP	FROM(A4)
	JNE	FAIL
	MOV	FROM+D.FSZ(A4),BLOCKS
	LOOKUP	TO(A4)
	BNE	10$
	DSKDEL	TO(A4)
	JNE	FAIL
10$:	CMP	FROM+D.LSZ(A4),#512.	; sequential or random file?	[101]
	JHIS	RANDOM.OPEN		;  random			[101]

SEQ.OPEN:
	OPENI	FROM(A4)
	JNE	FAIL
	OPENO	TO(A4)
	JNE	FAIL

SEQ.LOOP:
	CTRLC	CLOSE			; ^C entered			[101]
	FILINB	FROM(A4)
	TST	FROM+D.SIZ(A4)
	JEQ	CLOSE
	FILOTB	TO(A4)
	BR	SEQ.LOOP

RANDOM.OPEN:
	MOV	BLOCKS,TO+D.ARG(A4)	; set block count for DSKCTG	[101]
	DSKCTG	TO(A4)			; allocate output file		[101]
	JNE	FAIL			;  error			[101]
	OPENR	FROM(A4),#F.EXC		; open input file, exclusive	[101]
	OPENR	TO(A4),#F.EXC		; open output file, exclusive	[101]
	CLR	FROM+D.REC(A4)		; record zero of input file	[101]
	CLR	TO+D.REC(A4)		; record zero of output file	[101]
	MOV	BLOCKS,D4		; get block count
	MOV	FROM+D.BUF(A4),TO+D.BUF(A4) ; Two DDBs share same buffer [101]

RANDOM.LOOP:
	CTRLC	CLOSE			; ^C entered			[101]
	INPUT	FROM(A4)		; read block			[101]
	OUTPUT	TO(A4)			; copy block			[101]
	INC	FROM+D.REC(A4)		; next input record		[101]
	INC	TO+D.REC(A4)		; next output record		[101]
	SOB	D4,RANDOM.LOOP		; loop till done		[101]

CLOSE:	CLOSE	FROM(A4)
	CLOSE	TO(A4)
	CTRLC	FAIL

SIZE:	CMPW	COUNT(A3),#4
	BLO	DONE
	MOV	ADDR4(A3),A0
	FLTOF	BLOCKS,@A0

DONE:	SET	D0
	BR	SETVAL

FAIL:	CLR	D0

SETVAL:	MOV	ADDR3(A3),A0
	FLTOF	D0,@A0
	RTN

;error handling

CNTERR:	TYPESP	?Argument count
	BR	ERROR

TYPERR:	TYPESP	?Argument type

ERROR:	TYPECR	error in COPY.SBR
	EXIT

;do an "INIT" for the DDB @A0

INIT:	CLR	D.DVR(A0)		; 				[101]
;[101]	MOVW	D.DEV(A0),D0
;[101]	BEQ	10$
;[101]	CMPW	D0,#[DSK]
;[101]	BEQ	10$
;[101]	MOVW	D.DEV(A0),MODULE(A4)
;[101]	CLRW	MODULE+2(A4)
;[101]	MOVW	#[DVR],MODULE+4(A4)
;[101]	SRCH	MODULE(A4),A1
;[101]	BNE	10$
;[101]	MOV	A1,D.DVR(A0)
10$:	LEA	A6,D.DDB(A0)
	MOV	A6,D.BUF(A0)
	ORB	#D$INI!D$ERC,D.FLG(A0)
	RTN

	END