home *** CD-ROM | disk | FTP | other *** search
- ;
- ; COPYFILE.ASM ver 1.5
- ; by Keith Petersen, W8SDZ
- ; (revised 10/18/80)
- ;
- ;This program will copy files of any length from one drive to
- ;another, with up to 16k buffering. It was created for very
- ;long files (megabyte length), which are not properly handled
- ;by CP/M 2.x PIP. This version offers selective copying of
- ;files - something not available with PIP. The destination
- ;files will have NO attributes set, which is useful for
- ;copying from CP/M 2.x to 1.4 disks.
- ;
- ;10/18/80 Modified to strip attributes from file name before
- ; creating new file (to eliminate BDOS error on R/O
- ; files on CP/M 2.x). Corrected error in stack
- ; location. (KBP)
- ;
- ;10/10/80 Modified to make compatible with CP/M 1.4 or 2.x.
- ; Added: echo to prompt input, allow upper or lower
- ; case answer, reask if improper answer, more comments
- ; to file. (KBP)
- ;
- ;10/09/80 Modified to allow operator to scan and select which
- ; files will be transfered if wildcard options are used.
- ; This will allow transfer of selected file from a full
- ; disk without having to transfer all files and then
- ; erase the ones that were not to be transfered. Also
- ; modified to have transfers default to DIR files only
- ; and if files with SYS attribute are to be transfered the
- ; use of the /S option is required. (by Robert Arrington)
- ;
- ;COMMANDS:
- ; COPYFILE [drive:]<filename.filetype> <destination drive:>[/S]
- ;
- ; Requires the use of the /S option if transfer
- ; of files with SYS attribute is wanted.
- ;
- ;EXAMPLES:
- ; COPYFILE MYFILE.ASM B:
- ; gets MYFILE.ASM from default disk and copies to B:
- ; COPYFILE A:MYFILE.ASM B:
- ; gets MYFILE.ASM from A: and copies to B:
- ; COPYFILE B:*.* A:
- ; gets all files from B: and copies to A:
- ;
- ;All normal ambiguous file names are allowed.
- ;
- ;DEFINE WRITE BUFFER SIZE
- ; (presently set for 16k. If you have less space
- ; available in the TPA, reduce accordingly).
- ;
- BSIZE EQU 16*1024 ;<--NOW SET FOR 16k
- ;
- ;BDOS/CBIOS EQUATES
- ;
- WBOOT EQU 0 ;WARM BOOT ENTRY ADRS
- RDCON EQU 1 ;READ CONSOLE (WITH ECHO)
- WRCON EQU 2 ;WRITE CHARACTER TO CONSOLE
- BDOS EQU 5 ;CP/M BDOS ENTRY ADRS
- PRINT EQU 9 ;PRINT STRING (DE) UNTIL '$'
- OPEN EQU 15 ;OPEN DISK FILE
- SRCHF EQU 17 ;SEARCH DIR FOR FIRST OCCUR.
- SRCHN EQU 18 ;SEARCH DIR FOR NEXT OCCUR.
- READ EQU 20 ;READ SEQUENTIAL FILE
- CDISK EQU 25 ;RETURN CURRENT DISK
- STDMA EQU 26 ;SET DMA ADDRESS
- FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK
- FCBEXT EQU FCB+12 ;EXTENT BYTE IN FCB
- FCBRNO EQU FCB+32 ;RECORD NUMBER IN FCB
- FCB2 EQU 6CH ;DEFAULT 2ND FILE CONTROL BLOCK
- ;
- ; Program starts here
- ;
- ORG 100H
- ;
- MACLIB SEQIO ;NAME OF MACRO LIBRARY USED
- ;
- START: LDA FCB+1
- CPI ' ' ;SEE IF FILENAME THERE
- JNZ SIGNON
- CALL ILPRT ;PRINT:
- DB CR,LF,'++NO FILE NAME SPECIFIED++',0
- RET ;EXIT TO CP/M
- ;
- SIGNON: LXI SP,STACK ;SET STACK POINTER
- CALL ILPRT ;PRINT:
- DB CR,LF,'COPYFILE ver 1.5',CR,LF
- DB 'multiple file copy program',CR,LF,0
- LDA FCB ;GET DRIVE NAME
- ORA A ;SEE IF DEFAULT DRIVE
- CZ GETDRV ;IF DEFAULT, GET DRIVE NAME
- STA SRCDRV ;SAVE FOR LATER
- MOV B,A ;SAVE FOR LATER COMPARE
- LDA FCB2+2 ;GET OPTION REQUEST
- CPI 'S' ;SYS FILES WANTED?
- JNZ SNDDRV ;NO, SKIP SYS FLAG SET
- STA SYS ;SET SYS FLAG
- ;
- SNDDRV: LDA FCB2 ;GET SECOND DRIVE NAME
- STA DESTDR ;SAVE IT FOR LATER
- ORA A ;SEE IF DEFAULT DRIVE
- JZ ABORT ;DEFAULT NOT ALLOWED
- CMP B ;SEE IF DRIVE NAMES THE SAME
- JNZ MORE ;NOT THE SAME, CONTINUE
- ;
- ABORT: CALL EXIT
- DB '++DRIVE NAME ERROR++$'
- ;
- GETDRV: MVI C,CDISK ;CURRENT DISK NAME REQUEST
- CALL BDOS ;GET IT
- INR A ;ADJUST FOR USE IN FCB
- RET
- ;
- ;Get file name from directory and put in FCB
- ;
- MORE: CALL MFNAME ;SEE IF FILE IS IN DIRECTORY
- JNC SYSTST ;ANOTHER FILE FOUND, GET IT
- LDA MFFLG1 ;NOTHING FOUND, CHECK...
- ORA A ;... FIRST TIME FLAG
- JZ DONE ;AT LEAST ONE WAS FOUND
- CALL EXIT
- DB '++FILE NOT FOUND++$'
- ;
- DONE: CALL EXIT
- DB CR,LF,'DONE$'
- ;
- ;Check if SYS files wanted
- ;
- SYSTST: LDA SYS ;GET SAVED SYS FLAG
- CPI 'S' ;SYS WANTED?
- JZ MOVNAM ;YES, CONTINUE
- LDA SYSAT ;GET SYS ATTRIBUTE
- ANI 80H ;ISOLATE ATTR BIT
- JNZ MORE ;IT'S SYS, IGNORE IT
- ;
- ;Move filename from FCB to FNAME and print it
- ;
- MOVNAM: LXI H,FCB+1
- LXI D,FNAME
- MVI B,8 ;8 CHARS IN FILE NAME
- CALL MOVER
- LXI H,FCB+9
- LXI D,FNAME+9
- MVI B,3 ;3 CHARS IN FILE TYPE
- CALL MOVER
- CALL ILPRT ;PRINT:
- DB CR,LF,'--> FILE: '
- FNAME: DB 'XXXXXXXX.XXX',CR,LF,0
- LDA CFLAG ;GET CONTINUOUS MODE FLAG
- CPI 'C' ;IS IT SET?
- JZ DCOUT ;YES, SKIP OPTION REQUEST
- ;
- ;Ask for options
- ;
- REASK: CALL ASK ;PRINT:
- DB '(T)ransfer, (S)kip, (Q)uit, (C)ontinuous ? $'
- ;
- ASK: POP D ;GET MSG ADRS
- MVI C,PRINT
- CALL BDOS ;PRINT MSG
- MVI C,RDCON ;GET ANSWER AND ECHO IT
- CALL BDOS
- PUSH PSW ;SAVE IT
- CALL CRLF ;TURN UP A NEW LINE
- POP PSW ;GET ANSWER BACK
- ANI 5FH ;MAKE IT UPPER CASE
- CPI 'T' ;TRANSFER?
- JZ DCOUT ;YES, GO DO ONE
- CPI 'S' ;SKIP?
- JZ MORE ;YES, IGNORE THIS FILE
- CPI 'C' ;CONTINUOUS?
- JZ SETCM ;YES, SET CONTINOUS MODE
- CPI 'Q' ;QUIT?
- JNZ REASK ;NONE OF ABOVE, ASK AGAIN
- CALL EXIT
- DB '++QUITTING++$'
- ;
- ;Set continuous mode
- ;
- SETCM: STA CFLAG ;SAVE CONTINUOUS REQUEST
- ;
- ;'Declare' output file using FCB2
- ;
- DCOUT FILE OUTFILE,DESTINATION,,2,,BSIZE
- CALL ILPRT ;PRINT:
- DB 'File open on destination disk',0
- ;
- ;Open source file
- ;
- LXI D,FCB
- MVI C,OPEN
- CALL BDOS
- INR A ;CHECK FOR NO OPEN
- JNZ READLP ;NO ERROR, CONTINUE
- CALL ERXIT
- DB '++CAN''T OPEN SOURCE FILE++$'
- ;
- ;Read sector from source disk
- ;
- READLP: LXI D,80H
- MVI C,STDMA
- CALL BDOS
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- ORA A ;READ OK?
- JZ WRDISK ;YES, SEND IT TO DESTINATION
- CPI 1 ;END-OF-FILE?
- JZ TDONE ;TRANSFER DONE, CLOSE, EXIT
- CALL ERXIT
- DB '++FILE READ ERROR++$'
- ;
- ;Write sector to destination disk (with buffering)
- ;
- WRDISK: LXI H,80H ;READ BUFFER ADRS
- ;
- WRDLOP: MOV A,M ;GET BYTE FROM READ BUFFER
- PUSH H
- PUT DESTINATION ;SEND TO DISK WRITE BUFFER
- POP H
- INR L ;DONE WITH SECTOR?
- JNZ WRDLOP ;NO, GET ANOTHER BYTE
- JMP READLP ;GO GET ANOTHER SECTOR
- ;
- ;Transfer is done - close destination file,
- ;then go look for more files
- ;
- TDONE: FINIS DESTINATION ;FLUSH BUFFERS, CLOSE
- CALL ILPRT ;PRINT:
- DB 'File closed on destination disk now',0
- JMP MORE ;GET ANOTHER FILE
- ;
- ;Erase the incomplete output file, then exit
- ;
- ERXIT: ERASE DESTINATION
- ;
- ;Print message then exit to CP/M warm boot
- ;
- EXIT: POP D ;GET MSG ADRS
- MVI C,PRINT ;PRINT MESSAGE
- CALL BDOS
- CALL CRLF ;PRINT CRLF
- JMP WBOOT
- ;
- ;Inline print routine - prints string pointed to
- ;by stack until a zero is found. Returns to caller
- ;at next address after the zero terminator.
- ;
- ILPRT: XTHL ;SAVE HL, GET MSG ADRS
- ;
- ILPLP: MOV A,M ;GET CHAR
- CALL TYPE ;OUTPUT IT
- INX H ;POINT TO NEXT
- MOV A,M ;TEST
- ORA A ;..FOR END
- JNZ ILPLP
- CALL CRLF ;TURN UP A NEW LINE
- XTHL ;RESTORE HL, RET ADDR
- RET ;RET PAST MSG
- ;
- ;Turn up a new line
- ;
- CRLF: MVI A,CR ;CARRIAGE RETURN
- CALL TYPE
- MVI A,LF ;LINE FEED, FALL INTO 'TYPE'
- ;
- ;Send character in A register to console
- ;
- TYPE: PUSH B
- PUSH D
- PUSH H
- MOV E,A ;CHAR TO E FOR CP/M
- MVI C,WRCON ;WRITE TO CONSOLE
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;
- ;Multi-file access subroutine. Allows processing
- ;of multiple files (i.e. *.ASM) from disk. This
- ;routine builds the proper name in the FCB each
- ;time it is called. Carry is set if no more names
- ;can be found. The routine is commented in Pseudo
- ;code, each Pseudo code statement is in <<...>>
- ;
- MFNAME: ;<<init DMA address and FCB>>
- MVI C,STDMA
- LXI D,80H
- CALL BDOS
- XRA A
- STA FCBEXT
- STA FCBRNO
- ;<<if first time>>
- LDA MFFLG1
- ORA A
- JZ MFN01
- ;<<save the requested name>>
- ;Save original request
- LXI H,FCB
- LXI D,MFREQ
- MVI B,12
- CALL MOVER
- LDA FCB
- STA MFCUR ;SAVE DISK IN CURR FCB
- ;<<SRCHF requested name>>
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- ;<<else>>
- JMP MFN02
- ;
- MFN01: ;<<SRCHF current name>>
- LXI H,MFCUR
- LXI D,FCB
- MVI B,12
- CALL MOVER
- MVI C,SRCHF
- LXI D,FCB
- CALL BDOS
- ;<<SRCHN requested name>>
- LXI H,MFREQ
- LXI D,FCB
- MVI B,12
- CALL MOVER
- MVI C,SRCHN
- LXI D,FCB
- CALL BDOS
- ;<<endif>>
- MFN02: ;<<return carry if not found>>
- INR A
- STC
- RZ
- ;<<move name found to CURR>>
- DCR A
- ANI 3
- ADD A
- ADD A
- ADD A
- ADD A
- ADD A
- ADI 81H
- MOV L,A
- MVI H,0
- PUSH H ;SAVE NAME POINTER
- LXI D,9 ;READY TO ADD 9 TO...
- DAD D ;...POINT TO SYS ATTR
- MOV A,M ;GET IT
- STA SYSAT ;SAVE FOR LATER
- POP H ;GET NAME POINTER BACK
- PUSH H ;SAVE IT AGAIN
- LXI D,MFCUR+1
- MVI B,11
- CALL MOVER
- ;<<move name found to FCB>>
- POP H
- LXI D,FCB+1
- MVI B,11
- CALL MOVER
- ;<<make copy of name found to FCB2>>
- LXI H,FCB+1
- LXI D,FCB2+1
- MVI B,11
- CALL MOVER
- ;<<setup FCB>>
- XRA A
- STA FCBRNO ;ZERO RECORD NUMBER
- STA FCBEXT ;ZERO EXTENT NUMBER
- STA MFFLG1 ;TURN OFF 1ST TIME SW
- LDA SRCDRV ;GET SOURCE DRIVE NAME
- STA FCB ;PUT IT IN FCB1
- LDA DESTDR ;GET DESTINATION DRIVE NAME
- STA FCB2 ;PUT IT IN FCB2
- ;<<return>>
- RET
- ;------------------------------------------------
- ;
- ;Move subroutine - move (B) bytes from (HL) to (DE)
- ;
- MOVER: MOV A,M
- ANI 7FH ;STRIP ATTRIBUTES
- STAX D
- INX H
- INX D
- DCR B
- JNZ MOVER
- RET
- ;
- CFLAG: DB 0 ;CONTINUOUS TRANSFER FLAG
- SYS: DB 0 ;SYS FILE FLAG
- SYSAT: DB 0 ;FILE SYS ATTRIBUTE STORED HERE
- SRCDRV: DB 0 ;SOURCE DRIVE NAME SAVED HERE
- DESTDR: DB 0 ;AND DESTINATION DRIVE NAME HERE
- ;
- ;Multi-file access work area
- ;
- MFFLG1: DB 1 ;1ST TIME SW
- MFREQ: DS 12 ;REQ NAME
- MFCUR: DS 12 ;CURR NAME
- ;
- DS 100 ;ROOM FOR STACK
- STACK: EQU $ ;STACK POINTER SET HERE
- ;
- ;Org write buffer to even page boundry
- ORG ($+255) AND 0FF00H
- BUFFERS:EQU $ ;WRITE BUFFER STARTS HERE
- ;
- END
-