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