mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 22:23:13 -06:00
245 lines
6.5 KiB
Plaintext
245 lines
6.5 KiB
Plaintext
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
|
||
|
||
|