home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
ZCPR33
/
A-R
/
RCPMC.LBR
/
RCPMC.LZB
/
RCPMC.LIB
Wrap
Text File
|
2000-06-30
|
8KB
|
447 lines
;=============================================================================
;
; M C C O M M A N D
;
;============================================================================
; +++++++ NOT AN OFFICIAL RCP SEGMENT
; Command: MC
; Function: Multi Copy: Wild Card File Copier
; Author: Rob Friefeld, 4607 Colorado St., Long Beach, CA 213-434-7338
; Date: 23 Aug 1987 Version 1.0
; Comment: ERAON = YES assures all routines from rcpsubs.lib available.
; Usage: MC SOURCE [DESTINATION]
; Source is the afn to be copied and destination is an optional
; afn. If omitted, source comes to current DU:
; R/O files are copied to R/W.
;
; MC EQUATES
;
; # RECORDS TO READ ON EACH PASS (Byte value)
FILELOC EQU TPA ; Location file read in
RECBLKS EQU 255 ; About 32k buffer. Leaves transient at 8000h alone.
; SHOW REMAINING SPACE ON EXIT
MCSPA EQU YES ; Show free space
MCSP EQU MCSPA AND SPACEON
; THIS CODE IS IN PEEP, SO IT NEED NOT BE REPEATED
if [not peepon]
filcheck:
ld hl,fcb1+1
ld a,' '
cp (hl)
filcx: ret nz
call prfnf ; ROUTINE IS ELSEWHERE IN RCP
jp exit
opensource:
ld de,fcb1
ld c,openf
call bdos
inc a
jr filcx
endif ; not peepon
;
; START OF MOVE FILE
;
MLTCPY:
CALL RETSAVE ; Set up CPR return
call filcheck
call savdest ; Save destination filename
call savdu ; Save user numbers and drives
call logsu ; Log source user for search function
LD A,80H ; Flag SYS and DIR
CALL GETDIR ; Get list of afn matches
jp z,filcx ; No matches
;
; MAIN PROGRAM LOOP
;
; Enter with HL -> first file name in list.
loop:
push hl ; Save list position
ld de,fcb1+1 ; Move name to source fcb
ld bc,11
ldir
CALL INITFCB1 ; Zero out rest of fcb
pop hl ; Restore list postion
ld de,destfcb+1 ; Copy same name to dest fcb
ld bc,11
ldir ; When done, HL -> next name on list
push hl ; Save list position
ld hl,destfcb
CALL INITFCB2 ; Clean up the dest fcb
call rename ; If dest to be renamed, do it
call pfil ; Display file name
call opfiles ; Open source and dest files
jr z,lp2 ; Z = dest file exists AND don't erase it
lp1:
call r$wfiles ; Read and write files
jr z,lp3 ; 0 length file
ld a,(cflag) ; Is entire file copied
or a
jr nz,lp1 ; No
lp3: call close ; Close the destination file
lp2: pop hl ; Restore LIST pointer
ld a,(hl) ; 0 terminator
or a
IF MCSP
jp z,spaexit ; DONE
ELSE
jp z,exit
ENDIF
call crlf
jr loop
;
; Subroutines
;
; Save destination filename. Set renaming flag.
savdest:
ld bc,11 ; Dest name -> savfcb
ld hl,fcb2+1
ld de,savfcb
ldir
ld a,(savfcb) ; Is it blank?
cp ' '
jr nz,sav1 ; No, rename will be done
xor a ; Load up the flags
jr sav2
sav1: or a,-1
sav2: ld (rflag),a ; Rename flag, Z = do not rename
ld (pflag),a ; Print flag, Z = do not print dest filename
ret
savfcb: ds 11 ; Destination name template
rflag: ds 1 ; Wild card rename flag
; Rename destination file
rename:
ld a,(rflag) ; Is there anything to do?
or a
ret z ; Nope
ld b,11 ; Matched source name has been copied
ld hl,savfcb
ld de,destfcb+1
ren1: ld a,(hl)
cp '?' ; Leave wild card parts alone
jr z,ren2
ld (de),a ; Rename other parts
ren2: inc hl
inc de
djnz ren1
ret
; Save the drives and users of source + destination
savdu:
ld hl,fcb ; If drive is default, make it explicit
ld a,(hl)
or a
call z,getdefdrive ; Default
ld a,(fcb+13) ; Get and store user #'s
ld (susr),a
ld a,(fcb2+13)
ld (dusr),a
ld a,(fcb2) ; Save dest drive
ld hl,destfcb
ld (hl),a
or a
ret nz ; Fall through if dest is default
getdefdrive: ; Load default drive into @HL
push hl
ld c,inqdiskf
call bdos
pop hl
inc a
ld (hl),a
ret
; Log source or dest user
logsu: ld a,(susr)
jr log
logdu: ld a,(dusr)
log: JP SETUSR
susr: ds 1 ; Source user
dusr: ds 1 ; Dest user
opfiles:
; Open source file
opsrc:
call logsu
call opensource ; Routine in rpeep
; Open destination file
opdest:
ld de,tbuf ; Restore DMA to 80h
ld c,setdmaf
call bdos
call logdu ; Dest user
ld de,destfcb ; Check existence of destination
ld c,srchff ; Look for a file
call bdos
cp 0ffh
jr z,od1 ; No file
call file$exists ; Deal with existence of file
ret z ; Copy aborted
od1: ld c,erasef ; Delete present destination file
ld de,destfcb ; (if file ~exist, this does nothing)
call bdos
ld de,destfcb ; Make new file, same name
ld c,makef
call bdos
inc a
jp z,DIRERR ; Unable to make new file
ld de,destfcb ; Make sure file is not R/O
ld hl,9
add hl,de
res 7,(hl)
ld c,attrf
call bdos
or a,-1 ; Normal exit returns NZ
ret
; Destination file exists:
; Locate file name in temp buffer and save location
; Make sure file is not being copied to itself
; Find out if file is R/O
; Finally, do we want to erase it?
file$exists:
rrca ; Find entry into TBUF
rrca
rrca
add a,80h
ld l,a
ld h,0
ld (nxtfile),hl
ld hl,fcb ; Scan both drive/filenames
ld de,destfcb
ld b,12 ; # bytes to check
fil$ex1:
ld a,(de)
cp (hl)
jr nz,fil$ex2 ; They differ
inc hl
inc de
djnz fil$ex1
ld a,(susr) ; Names and drives same ... what about users?
ld b,a
ld a,(dusr)
cp b
jr nz,fil$ex2 ; They differ
call print ; Don't do copy
db ' ?','?'+80h
xor a
ret
fil$ex2:
ld hl,(nxtfile) ; If file R/O
inc hl ; Point to start of name
CALL ROTEST
call ERAQ
jr z,erase1
xor a
ret
erase1:
ld de,(nxtfile) ; Take care of R/O status
ld hl,destfcb
ld a,(hl) ; Get drive
ld (de),a ; Move it to file location
ld hl,9
add hl,de
res 7,(hl) ; Reset the bit
ld c,attrf ; Tell BDOS about R/O reset
call bdos
or a,-1 ; NZ return means we said "YES"
ret
; Routine to display file names
pfil:
call print
db ' Copying -->',' '+80h
ld de,fcb1
call pdsk
ld a,(susr)
call pusr
call pfn
call print
db ' to',' '+80h
ld de,destfcb
call pdsk
ld a,(dusr)
call pusr
ld a,(pflag)
or a
ret z
JR pfn
pflag: db 00 ; Flag to print dest filename
pdsk: ld a,(de) ; Print file drive DE -> fcb
add 'A'-1
pdsk0: jp CONOUT
pusr: cp 10 ; Print user number in A
jr c,pusr1
sub 10
push af
ld a,'1'
call CONOUT
pop af
pusr0: add '0'
call CONOUT
ld a,':'
jr pdsk0
pusr1: call pusr0
ld a,' '
jr pdsk0
pfn: EX DE,HL
INC HL
JP PRFN
;
; Read and write files
;
r$wfiles:
; Read source file into memory
get$fil:
call logsu ; Log source user #
xor a
ld (cflag),a ; Reset copy flag
ld b,recblks ; Zero count of records read
ld hl,fileloc ; Location of file buffer
getlp: push bc ; Save count
call setloc ; Save pointer and set DMA
ld de,fcb1
ld c,readf ; Note that readf returns A <> 0
call bdos ; when reading record after EOF.
or a ; Hence RCOUNT = 1 on one rec file
pop bc
jr nz,wrtfil ; EOF encountered, exit loop
ld hl,(filptr)
ld de,128
add hl,de
djnz getlp ; Still room
or a,-1 ; Out of room
ld (cflag),a ; Set flag copy
; Write file to destination
wrtfil: ld a,recblks ; B = recblks - (records read)
sub b ; A = records read
or a
ret z ; 0 records copied
ld b,a ; Count in B
push bc ; Has record count
call logdu ; Log dest user
pop bc
ld hl,fileloc ; Write buffer to file
wrtlp:
push bc
call setloc
ld de,destfcb
ld c,writef
call bdos
or a
pop bc
jp nz,full ; Disk full error
ld hl,(filptr) ; Move pointer along 128 bytes
ld de,128
add hl,de
djnz wrtlp ; And get next record
or a,-1 ; Force NZ on normal return
ret
; Save file pointer and set up DMA
setloc:
ld (filptr),hl
ex de,hl
ld c,setdmaF
jp bdos
; Move file pointer up a record
close:
ld de,destfcb
ld c,closef
JP bdos
; Dest filled. Erase incomplete copy and reset disk.
full:
ld c,ERASEF
ld de,destfcb
call bdos
call print
db cr,lf,'Disk ful','l'+80h
ld c,13 ; Disk reset BDOS function
call bdos
fullx: xor a
IF MCSP
jp spaexit
ELSE
jp exit
ENDIF
cflag: ds 1 ; Copy not done flag
filptr: dw 0 ; File pointer
destfcb:
ds 36 ; Temp storage for destination FCB
; END OF RCPFM.LIB
Copy not done flag
filptr: dw 0 ; File pointer
destfcb:
ds 36 ; Temp storag