mirror of https://github.com/wwarthen/RomWBW.git
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
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
|
|
|
|
|