You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

245 lines
6.5 KiB

page
; Library: RCPCP for Z34RCP
; Author: Carson Wilson
; Version: 1.3
; Date: August 11, 1989
; Changes: Responds dynamically to QUIET flag, eliminating "noise."
; Version: 1.2
; Date: December 30, 1988
; Changes: Now works properly with CP/M Plus.
; Moved SETDMA to common routines.
; Author: Carson Wilson
; Version: 1.1
; Date: August 4, 1988
; Changes: Now initializes FCB1 before calling SetFStp, allowing
; stamp setting of multiple-extent files.
;
; Author: Carson Wilson
; Version: 1.0
; Date: June 15, 1988
;
; Command: CP
; Function: Copy a file from one place to another
; Syntax: If FCBSWAP false:
; CP destfile=srcfile, CP =srcfile
; If FCBSWAP true:
; CP srcfile destfile, CP srcfile
; If TESTEQ and FCBSWAP true:
; Both of the above forms work
;
; Comments: Both file specifications can include a directory specification.
; If only one file name is given, then the current directory and
; the source file name are assumed for the destination.
;
; New ZSDOS/DosDisk BDOS standard functions:
;
GetFStp equ 102 ; Get file stamp function
SetFStp equ 103 ; Set file stamp function
copy:
call retsave
call dirchek ; Test bad directory
if leftright
call fcbswap ; Exchange fcb1 with fcb2
endif
; If new is blank, make it the same name and type as old
ld de,fcb1+1 ; Point to destination file name
ld a,(de) ; Get first character
cp ' ' ; If not blank (no name)
jr nz,copy0 ; ..then branch to copy
ld hl,fcb2+1 ; Copy source name into destination FCB
ld b,11 ; Name and type are 11 bytes
call blkmov
; See if destination is same as source, and abort if so
copy0:
ld hl,fcb1 ; Set up pointers to two files
ld de,fcb2
push hl
push de
inc hl ; Point to names of files
inc de
ld b,13 ; Compare 13 bytes (name, type, and user #)
copy1: call comp
jr nz,copy2 ; If they differ, go on with copy
ld a,(cdrv) ; ZCPR current drive
inc a ; Shift to range 1..16
ld b,a ; ..and keep value in B
pop de ; Restore pointers to FCBs
pop hl
ld a,(de) ; Get drive of source file
ld c,a ; ..and save it in C
or a ; Is it default drive?
jr nz,copy1a ; Branch if drive made explicit
ld c,b ; Otherwise, copy default drive into C
copy1a: ld a,(hl) ; Get drive of destination file
or a ; Is it default drive?
jr nz,copy1b ; Branch if drive made explicit
ld a,b ; Otherwise, get current drive
copy1b: cp c ; Compare the two drives specified
jr nz,copy3 ; Branch if they are different
jp duperr ; Tell EH duplicate filespecs
copy2:
pop de ; Clean up the stack
pop hl
; Make note of the user numbers of the two files
copy3:
ld a,(fcb1+13) ; Get destination user number
ld (usrdest),a
ld a,(fcb2+13) ; Get source user number
ld (usrsrc),a
; Set up new FCB for source file and open the source
call define ; Define buffer addresses dynamically
srcfcb equ $+1
ld hl,0 ; Get address to use for new source FCB
push hl
ex de,hl ; Copy file data to new FCB
ld b,12
call blkmov
call logsrc ; Log in user number of source file
pop hl ; Initialize the source file FCB
call initfcb2
ld c,15 ; Open source file
call bdos
inc a ; Check for error
jp z,noflerr ; File not found error handler
if StpCall
call cpmver
jr nc,copy4 ; Don't do this if CP/M Plus
stpbuf equ $+1
ld de,0
call setdma ; Set DMA to date buffer
ld de,(srcfcb)
ld c,GetFStp ; Get stamp (if any) to DMA
call bdos
ld (gotstp),a ; Store result
ld de,tbuff ; Restore DMA
call setdma ; ..for search
copy4:
endif ; StpCall
; Make sure destination file does not already exist
call logdest ; Log into destination user area
call extest ; Test for existence of file in fcb1
jp z,exit ; Branch if it exists and user says no
; Create destination file
ld de,fcb1 ; Point to destination FCB
ld c,22 ; BDOS make-file function
call bdos
inc a ; Test for error (no directory space)
jp z,fulerr ; Invoke EH if not OK
; Copy source to destination
copy5: call logsrc ; Log in source user area
ld b,0 ; Initialize counter
ld de,(cbuff) ; Initialize buffer pointer
copy5a: push de ; Save address and counter
push bc
call setdma ; Set DMA to cbuff+(b*128)
ld de,(srcfcb) ; Point to source file FCB
ld c,20 ; BDOS read-sequential function
call bdos
pop bc ; Get counter and address
pop de
or a ; Read Ok?
jr nz,copy5b ; Branch if end of file
ld hl,128 ; Point DE to next buffer address
add hl,de
ex de,hl
inc b ; Increment counter
ld a,b ; See if buffer full
cp cpblocks
jr nz,copy5a ; If not, go back for more
copy5b: ld a,b ; Get count of blocks loaded into buffer
or a ; Are there any?
jr z,copy6 ; Branch if not (we are done)
push bc ; Save count
call logdest ; Log into destination user number
cbuff equ $+1 ; Pointer for in-the-code modification
ld de,0 ; Point to beginning of copy buffer
copy5c: push de ; Save buffer address
call setdma ; Set dma to buffer
ld de,fcb1 ; Point to destination file FCB
ld c,21 ; Sequential write the block
call bdos
or a ; Get result
jp nz,fulerr ; Invoke EH (disk full or write error)
pop de ; Get buffer address & balance stack
pop bc ; Get count
dec b ; Buffer empty?
jr z,copy5 ; Yes. Back for refill
push bc ; No. Save count
ld hl,128
add hl,de
ex de,hl ; DE points to next buffer address
jr copy5c ; Back for another sector to write
; Close the destination file
copy6: call logdest ; Log into destination user number
ld de,fcb1 ; Point to destination FCB
ld c,16 ; Close file
call bdos
inc a ; 0ffh --> 0 if error
jp z,fulerr ; Invoke EH
if StpCall
gotstp equ $+1
ld a,0 ; File had stamp?
dec a ; 1 --> 0 = yes
jr nz,noset ; No
ld de,(stpbuf) ; Point to buffer
call setdma ; Set DMA
call initfcb1 ; Init. for SetFStp, point to dest.
ld c,SetFStp ; Set file's stamp
call bdos ; CCP restores DMA
noset:
endif ; StpCall
ld a,(quiet)
or a
jr nz,qcpdone
call print
db ' Don','e'+80h
qcpdone:
if cpsp and spaceon
jp spaexit ; Report space remaining on destination drive
else
jp exit
endif ;cpsp and spaceon
; Log into user number of source file
logsrc:
usrsrc equ $+1 ; Pointer for in-the-code modification
ld a,0 ; Get user number
jr setusrrel ; Local jump to save code
; Log into user number of destination file
logdest:
usrdest equ $+1 ; Pointer for in-the-code modification
ld a,0 ; Get user number
setusrrel:
jp setusr
; End RCPCP.LIB