Files
RomWBW/Source/BPBIOS/Z34RCP11/rcpcp.lib
2020-02-14 17:22:56 -08:00

245 lines
6.5 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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