home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol073
/
put.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
17KB
|
876 lines
TITLE 'BUFFERED INTER-USER COPY ROUTINE FOR CP/M'
*****************************************************************
* *
* A UTILITY PROGRAM TO FACILITATE COPYING FILES *
* BETWEEN USER AREAS *
* *
*****************************************************************
;
; First publication data:
;
; Electronic publication by :- "Software Tools" RCPM System
; Sydney, Australia
;
; Print publication by :- Dr Dobbs Journal, Palo Alto, USA
;
; Copyright (c) 1981/82
;
; Angus Bliss Bill Bolton
; P.O. Box 293, Software Tools
; Hamilton, P.O. Box 80,
; NSW, 2303, Newport Beach,
; AUSTRALIA NSW, 2106,
; AUSTRALIA
;
; This program is made available for public distribution
; for NON-COMMERCIAL use only. All commercial rights
; retained by the authors.
;
; Version list (latest version first)
; -----------------------------------
; 1.6 Fix problem with zero length files writing
; a file as large as buffer. Fix problem of
; large files being truncated to 32K in
; some multifile transfers. Tidy up for
; publication - Angus Bliss 29/Apr/82
;
; 1.5 Initial release version. Large file transfer
; bug fixed and other minor internal changes
; mode - Bill Bolton 3/Feb/82
;
; 1.4 Overwrite options added, user abort added,
; filename show added and lots more comments
; added - Bill Bolton 2/Feb/82
;
; 1.3 Transfer to $$$ file first then rename after
; succesful close (like PIP) added - Bill Bolton
; 1/Feb/82
;
; 1.2 Wildcard file transfer added. - Bill Bolton
; 31/Jan/82
;
; 1.1 Converted to 8080 code for greater portability
; (now that the Godbout 8085/8088 card has given
; 8080 code a new lease of life) and presentation-
; tidied up. - Bill Bolton 30/Jan/82
;
; 1.0 Original code in Xitan Z80 source. - Angus Bliss
; Aug/82
;
VERSION EQU 16 ;VERSION NUMBER
CNTRLC EQU 3 ;CP/M 'PANIC' CHARACTER
ACR EQU 0DH
ALF EQU 0AH
WBOOT EQU 0 ;CP/M WARM BOOT ENTRY
BDOS EQU 0005H ;CP/M BDOS ENTRY POINT
FCB EQU 05CH ;CP/M FILE CONTROL BLOCK
FCB0 EQU 06CH
TBUF EQU 080H ;CP/M COMMAND LINE BUFFER
CI EQU 1 ;BDOS CONSOLE IN
CO EQU 2 ;BDOS CONSOLE OUT
DIRECT EQU 6 ;BDOS DIRECT CONSOLE
B$PRINT EQU 9 ;BDOS CONSOLE MESSAGE
VERS EQU 12 ;BDOS RETURN VERSION NUMBER
B$OPEN EQU 15 ;BDOS OPEN FILE
B$CLOSE EQU 16 ;BDOS CLOSE FILE
SRCH$1ST EQU 17 ;BDOS SEARCH FOR FILE
SRCH$NXT EQU 18 ;BDOS SEARCH FOR NEXT (AMBIG) FILE
DELET EQU 19 ;BDOS DELETE FILE
B$READ EQU 20 ;BDOS SEQUENTIAL READ
B$WRITE EQU 21 ;BDOS SEQUENTIAL WRITE
MAKE EQU 22 ;BDOS CREATE NEW FILE
REN EQU 23 ;BDOS RENAME FILE
DMA EQU 26 ;BDOS SET NEW DMA
ATTRIB EQU 30 ;BDOS SET FILE ATTRIBUTES
USER EQU 32 ;BDOS SET/GET USER
;
ORG 100H ;FOR CP/M
;
START:
LXI SP,STACK ;SET A STACK
LXI D,MSG1
MVI C,B$PRINT
CALL BDOSE ;ANNOUNCE OURSELF
MVI C,VERS ;CHECK VERSION
CALL BDOS ;USES HL REGISTER
MOV A,L
CPI 2
JC ERROR3 ;WRONG CP/M VERSION
LDA TBUF ;PARAMETER COUNT
CPI 0 ;NO PARAMETER
JZ ERROR1
LXI H,FCB-1 ;TAKE A COPY OF FCB
LXI D,FCB2-1 ;@ TBUF
LXI B,33 ;LENGTH OF A FILENAME
LDIR1:
INX H ;ADJUST POINTERS
INX D
MOV A,M ;GET A BYTE
STAX D ;PUT A BYTE
DCX B ;ADJUST COUNT
MOV A,B
ORA C ;ZERO YET
JNZ LDIR1 ;NO
LXI H,TBUF ;YES
MVI B,0
MOV C,M ;GET COUNT
INX H ;STEP OVER ANY SOURCE
DCR C
INX H ; DRIVE IDENTIFIER ON
DCR C
INX H ; FILE NAME
DCR C
MVI A,':' ;DRIVE DELIMITER
CCIR1:
INX H
CMP M ;MATCH
JZ GO$ON1
DCR C
JZ NOT$FOUND1 ;YES
JMP CCIR1
;
GO$ON1:
DCX H ;ADJUST PTR
MOV A,M
CPI 'G'+1 ; A >= CHAR <= G
JNC NOT$FOUND1
CPI 'A'
JC NOT$FOUND1
ANI 7 ;MAKE 0 TO 7
STA DEST$DRV
STA FCB2
NOT$FOUND1:
LXI H,FCB
MVI C,11 ;GET LENGTH OF FILE NAME
MVI A,'?' ;WILDCARD
CCIR2:
INX H ;LOOP TO SEARCH FOR WILDCARD
CMP M
JZ GO$ON2
DCR C
JZ NOT$FOUND2
JMP CCIR2
;
GO$ON2:
MVI A,0FFH
STA WILD ;SET MULTIFILE FLAG
NOT$FOUND2:
LXI H,TBUF ;YES
MVI B,0
MOV C,M ;GET COUNT
MVI A,'-' ;OPTION SPECIFIER
CCIR3:
INX H ;LOOP TO SEARCH FOR OPTIONS
CMP M
PUSH H
CZ OPTION
POP H
DCR C
JNZ CCIR3
JMP NOT$FOUND3
;
OPTION:
PUSH PSW ;FOUND THE FLAG
OPT$1:
INX H ;NOW LOOK FOR AN OPTION
MOV A,M
CPI 'W'
JZ OVER$WRITE
CPI 'N'
JZ NO$QUERY
POP PSW
RET
;
OVER$WRITE:
MVI A,0FFH
STA O$W
JMP OPT$1 ;LOOK FOR ANOTHER ONE
;
NO$QUERY:
MVI A,0FFH
STA N$Q
JMP OPT$1 ;LOOK FOR ANOTHER ONE
;
NOT$FOUND3:
LXI H,6DH ;FROM USER
CALL NSCAN ;GET NUMBER
JC ERROR2 ;INVALID USER
STA FUSER ;FROM USER
LXI H,75H ;TO USER
CALL NSCAN
JC ERROR2
STA TUSER ;TO USER
MVI E,0FFH
MVI C,USER ;GET CURRENT USER
CALL BDOSE
STA CUSER ;SAVE IT
LDA FUSER ;FROM USER
MOV E,A ;PUT IN E
MVI C,USER
CALL BDOSE ;SET THE USER
LXI H,FCB
LDA WILD
ORA A ;SINGLE FILE ONLY ?
JZ COPY$FCB ;YES
LXI D,FCB
MVI C,SRCH$1ST
CALL BDOSE
CPI 0FFH ;FOUND?
JZ ERROR4 ;NO
DIR$MATCH:
ADD A ;MULTIPLY BY 5
ADD A
ADD A
ADD A
ADD A
LXI H,TBUF ;POINT TO DIRECTORY BUFFER
MOV E,A
MVI D,0
DAD D ;HL < POINTER TO MATCHED FILE
COPY$FCB:
PUSH H
MVI C,12
LXI D,FCB1
LDA FCB
MOV M,A ;STUFF SRC DRIVE IDENT INTO FCB
C$FCB$1:
MOV A,M ;COPY FCB TO FCB1 (READ FCB)
STAX D
INX H
INX D
DCR C
JNZ C$FCB$1
POP H
C$FCB$2:
MVI C,11
LXI D,FCB2
LDA DEST$DRV
STAX D ;STUFF DEST DRIVE IDENT INTO FCB
INX H
INX D
C$FCB$3:
MOV A,M ;COPY FCB TO FCB1 (WRITE FCB)
ANI 7FH ;RESET ANY FILE ATTRIBUTES
STAX D
INX H
INX D
DCR C
JNZ C$FCB$3
READ$FILE:
LXI H,FCB1
CALL SHOW
LXI D,FCB1 ;CP/M DEFAULT
MVI C,B$OPEN
CALL BDOSE ;OPEN OUR SOURCE
CPI 255
JZ ERROR4 ;OPEN FAILURE
CALL BUFSIZ ;CALCULATE BUFFER SIZE
XRA A ;INITIATE REGISTERS
STA ACOUNT ;SECTOR COUNT
LDA COUNT
MOV B,A ;SECTOR COUNT
;
READ: LXI D,BUFSTART ;B HAS SECTOR CNT
READ1: MVI C,DMA
CALL BDOSE ;SET DMA ADDRESS
PUSH D ;SAVE DMA ADDR.
LXI D,FCB1
MVI C,B$READ
CALL BDOSE ;READ A SECTOR
POP D ;RESTORE DMA
CPI 1
JZ FINISH
CPI 0
JNZ ERROR5 ;READ ERROR
MOV A,E ;BUMP POINTER
ADI 80H
MOV E,A
MVI A,0
ADC D
MOV D,A ;BY 128 BYTES
LDA ACOUNT
INR A
STA ACOUNT ;SECTORS READ
DCR B ;ADJUST COUNT
JNZ READ1 ;NO
CALL WRITE ;FULL, SO EMPTY IT
XRA A ;RESET REGISTERS
STA ACOUNT ;SECTOR COUNT
LDA COUNT
MOV B,A ;SECTOR COUNT
JMP READ
;
FINISH:
MVI A,0FFH
STA EOF ;FINISHED THIS FILE
LDA COUNT
SUB B
MOV B,A
CALL WRITE
LXI D,FCB2
MVI C,B$CLOSE ;CLOSE DESTINATION
CALL BDOSE
CPI 255
JZ ERROR9 ;CLOSE FAILURE
CALL RENAME ;RENAME $$$ TO TYP
LDA WILD
ORA A ;MORE FILES?
JZ DONE
LXI H,BUFSTART
SHLD BUFPT ;RESET BUFFER POINTER
XRA A
STA OPEN ;RESET FILE OPEN FLAG
STA EOF ;WON'T BE EOF ON NEXT FILE
LXI H,FCB1 ;POINT TO INTERNAL FCBS
MVI C,64 ;LENGTH OF 2 * FCB
XRA A
FCB$FILL1:
MOV M,A ;RESET MEMORY
INX H ;ADJUST POINTER
DCR C ;DONE ?
JNZ FCB$FILL1 ;NO
LDA FUSER
MOV E,A ;SAVE DIRECTORY POINTER TIL LATER
MVI C,USER
CALL BDOSE ;RESET TO SOURCE USER
LXI D,TBUF ;RESET DMA
MVI C,DMA
CALL BDOSE
LXI D,FCB
MVI C,SRCH$1ST ;START SEARCH FOR NEXT
CALL BDOSE ; WILDCARD MATCH (TEDIOUS)
LDA F$COUNT ;NO FILES DONE SO FAR
INR A ;JUST DONE ANOTHER ONE
STA F$COUNT ;KEEP FOR NEXT TIME
STA D$COUNT ;INITIALISE LOOP COUNTER
SEARCH$LOOP:
LXI D,0
MVI C,SRCH$NXT ;SEARCH FOR NEXT WILDCARD MATCH
CALL BDOSE
STA DIR$POINT
CPI 0FFH ;NO MORE MATCH ?
JZ DONE ;YES
LDA D$COUNT ;NO, GET LOOP COUNT
DCR A ;ONE SEARCH DONE
STA D$COUNT
JNZ SEARCH$LOOP ;SEARCH AGAIN
MVI C,DIRECT
MVI E,0FFH
CALL BDOSE
CPI CNTRLC ;USER WANTS ABORT ?
JZ U$ABORT ;YES
LDA DIR$POINT ;NO, A = POINTER INTO DIR SECTOR
JMP DIR$MATCH ;FOUND THE ONE WE NEEDED
;
WRITE:
LDA TUSER
MOV E,A
MVI C,USER
CALL BDOSE ;SET DESTINATION USER
LDA OPEN
CPI 0 ;FILE ALREADY OPEN ?
JNZ WRITE2 ;YES
CMA ;NO
STA OPEN ;INDICATE FILE OPEN
LXI D,FCB2
MVI C,B$OPEN
CALL BDOSE ;ATTEMPT OPEN
CPI 255
JZ WRITE0 ;NOT PRESENT
LDA FCB2+9 ;PRESENT, CHECK R/O
ANI 80H ;ISOLATE BIT
RAL ;PUT IN CARRY
JNC NOT$RO ;NOT R/O
LDA O$W
ORA A ;OVER WRITE R/O FILE ?
JNZ REMOVE$RO
JMP ERR6A ;IS R/O
;
REMOVE$RO:
LXI H,FCB2+12 ;FCB2 HAS GROUP 'GARBAGE'
XRA A ; FROM OPEN CALL WHICH
MVI C,21 ; NEEDS TO BE CLEANED OUT
CALL FILL$BLOCK ; FOR ATTRIBUTE CALL
LXI H,FCB2
MVI C,12
R$RO:
MOV A,M ;RESET ATTRIBUTES IN FILE NAME
ANI 7FH
MOV M,A
INX H
DCR C
JNZ R$RO
LXI D,FCB2
MVI C,ATTRIB
CALL BDOSE
CPI 0FFH ;THIS SHOULD NEVER HAPPEN
JZ ERROR11 ; BUT JUST IN CASE
NOT$RO:
LDA N$Q
ORA A ;NO FILE EXISTS QUERY?
JNZ WRITE0 ;YES
CALL ERROR6 ;CHECK BEFORE DELETE
CPI 'Y'
JZ WRITE1 ;CONTINUE
CPI 'y'
JZ WRITE1 ;CONTINUE
JMP ABORT ;ANSWER NOT 'Y' OR 'y'
WRITE1:
CALL CRLF
WRITE0:
LXI H,FCB2+9 ;POINT TO SECONDARY FILENAME
LXI D,TYPE
MVI C,3 ;LENGTH OF SECONDARY FILENAME
MVI B,'$' ;TEMPORARY FILE TYPE MARKER
FILL$TYPE1:
MOV A,M ;GET SECONDARY FILE NAME
STAX D ;SAVE IT FOR LATER
MOV M,B ;STUFF IN TEMP MARKERS
INX H
INX D
DCR C
JNZ FILL$TYPE1
LXI H,FCB2+12 ;ZERO FILL REST OF FCB
MVI C,24
XRA A
CALL FILL$BLOCK
LXI D,FCB2
MVI C,MAKE
CALL BDOSE ;CREATE DESTINATION FILE
CPI 255
JZ ERROR7 ;DIRECTORY FULL
;
WRITE2:
LDA ACOUNT
ORA A ;ZERO LENGTH FILE?
JZ ZEXIT ;YES, DONT WRITE TO DESTINATION
MOV B,A ;ACTUAL SECTOR COUNT
PUSH H
LXI H,BUFSTART
SHLD BUFPT ;SAVE BUFFER POINTER
POP H
WRITE3:
PUSH H
LHLD BUFPT ;GET BUFFER POINTER
XCHG ;DE <---- BUFFER POINTER
POP H
PUSH D
MOV A,E
ADI 80H
MOV E,A
MVI A,0
ADC D ;16 BIT ADD OF 1 SECTOR
MOV D,A
PUSH H
XCHG
SHLD BUFPT ;SAVE NEW BUFFER POINTER
POP H
POP D
MVI C,DMA
CALL BDOSE ;CHANGE DMA ADDRESS
LXI D,FCB2
MVI C,B$WRITE
CALL BDOSE ;WRITE A SECTOR
CPI 0
JNZ ERROR8 ;WRITE ERROR
DCR B ;DONE YET?
JNZ WRITE3 ;NO
ZEXIT: ;(COME IN HERE IF ZERO LENGTH FILE)
LDA EOF
CPI 0
RNZ ;END
LDA FUSER
MOV E,A
MVI C,USER ;SET SOURCE USER
CALL BDOSE
RET
;
FILL$BLOCK:
MOV M,A ;GENERAL BLOCK FILLER
INX H ; WITH A CONSTANT
DCR C
JNZ FILL$BLOCK
RET
;
;
RENAME:
LXI H,FCB2+9 ;START POINT
MVI C,27 ;LENGTH TO FILL
XRA A ;ZERO A
CALL FILL$BLOCK
LXI H,TYPE ;POINT TO FILE TYPE
LXI D,FCB2+9 ;SECONDARY FILE NAME
MVI C,3 ;LENGTH TO MOVE
REN$LOOP1:
MOV A,M ;STUF FILE TYPE BACK INTO FCB
STAX D
INX H
INX D
DCR C
JNZ REN$LOOP1
LXI D,FCB2
MVI C,DELET
CALL BDOSE ;KILL ORIGINAL DESTINATION FILE
LXI H,FCB2+9
MVI C,27
XRA A
CALL FILL$BLOCK ;ZERO FILL WRITE FCB YET AGAIN
LXI H,FCB2
LXI D,FCB2+16
MVI C,9
REN$LOOP2:
MOV A,M ;COPY WRITE FCB TO MAKE THE
STAX D ; SPECIAL RENAME FORMAT FCB
INX H
INX D
DCR C
JNZ REN$LOOP2
MVI A,'$' ;HL = POINTER TO FCB2 +9
MVI C,3
REN$LOOP3:
MOV M,A ;STUFF TEMP FILE MARKERS IN
INX H ; THE 'FROM' PART OF FCB
DCR C
JNZ REN$LOOP3
LXI H,TYPE ;DE = FCB2+9+16
MVI C,3
REN$LOOP4:
MOV A,M ;STUFF FILE TYP IN THE
STAX D ; 'TO' PART OF FCB
INX H
INX D
DCR C
JNZ REN$LOOP4
LXI D,FCB2
MVI C,REN ;DO THE RENAME
CALL BDOSE
CPI 0FFH ;AGAIN, THIS SHOULD NEVER HAPPEN
JZ ERROR10 ; BUT.......
RET
;
;ERROR AND MESSAGE HANDLING
;
ERROR1:
LXI D,MSG3
CALL PRINT
LXI D,MSG2
CALL PRINT
JMP ABORT
;
ERROR2:
LXI D,MSG4
CALL PRINT
LXI D,MSG2
CALL PRINT
JMP ABORT
;
ERROR3:
LXI D,MSG5
CALL PRINT
JMP ABORT
;
ERROR4:
LXI D,MSG6
CALL PRINT
JMP ABORT
;
ERROR5:
LXI D,MSG7
CALL PRINT
JMP ABORT
;
ERROR6:
LXI D,MSG8
MVI C,B$PRINT
CALL BDOSE ;PROMPT QUESTION
MVI C,CI
CALL BDOSE
RET ;RETURN WITH INPUT
;
ERR6A:
LXI D,MSG8A
CALL PRINT
JMP ABORT
;
ERROR7:
LXI D,MSG9
CALL PRINT
LXI D,MSG10
CALL PRINT
JMP ABORT
;
ERROR8:
LXI D,MSG11
CALL PRINT
JMP ABORT
;
ERROR9:
LXI D,MSG12
CALL PRINT
JMP ABORT
;
ERROR10:
LXI D,MSG16
CALL PRINT
JMP ABORT
;
ERROR11:
LXI D,MSG17
CALL PRINT
JMP ABORT
;
;
;GENERAL PURPOSE SUBROUTINES
;
PRINT:
PUSH D
CALL CRLF
POP D
MVI C,B$PRINT
CALL BDOSE ;PRINT MESSAGE
RET
;
U$ABORT:
LXI D,MSG18
CALL PRINT
JMP EOJ
;
ABORT:
LXI D,MSG13
CALL PRINT
JMP EOJ
;
CRLF:
MVI E,ACR
MVI C,CO
CALL BDOSE
MVI E,ALF
MVI C,CO
CALL BDOSE
RET
;
DONE:
CALL CRLF ;NORMAL EOJ MSG
LXI D,MSG14
MVI C,B$PRINT
CALL BDOSE
;
EOJ:
LDA CUSER ;RESET USER
MOV E,A
MVI C,USER
CALL BDOSE
JMP WBOOT
;
SHOW:
CALL CRLF
LXI D,MSG15
MVI C,B$PRINT
CALL BDOSE
MVI D,9
SHOW1: ;DISPLAY FILENAME IN READ FCB
INX H
DCR D
JNZ SHOW2
MVI E,'.' ;PRINT THE SEPARATOR
MVI C,CO
CALL BDOSE
SHOW2:
MOV A,M
CPI 0
RZ
CPI ' ' ;SKIP BLANKS
JZ SHOW1
MOV E,A
MVI C,CO
CALL BDOSE
JMP SHOW1
;
;
BUFSIZ:
LHLD BDOS+1
LXI D,-6
DAD D ;HL = POINTER TO BASE OF BDOS
LXI D,BUFSTART
ORA A ;CY=0
MOV A,L
SBB E ;SUBTRACT E FROM L
MOV L,A
MOV A,H
SBB D ;SUBTRACT D FROM H
MOV H,A
SHLD SIZEB
MVI B,7
ORA A ;RESET CARRY
BUFSIZ0:
MOV A,H ;DIVIDE HL BY 128 (WHICH
RAR ; JUST HAPPENS TO BE THE
MOV H,A ; SIZE OF A CP/M LOGICAL
MOV A,L ; SECTOR
RAR
MOV L,A
ORA A ;RESET CARRY
DCR B
JNZ BUFSIZ0
MOV A,H ;> 255 ?
CPI 0
JZ BUFSIZ1 ;NO
MVI A,255 ;YES, BIGGEST BUFFER
JMP BUFSIZ2
;
BUFSIZ1:
MOV A,L
BUFSIZ2:
STA COUNT ;NO SECTORS IN BUFFER
RET
;
BDOSE:
PUSH B ;BDOS ENTRY
PUSH D
PUSH H
CALL BDOS
POP H
POP D
POP B
RET
;
NSCAN:
LXI D,0 ;CLEAR WORK
MOV A,M ;GET CHAR
CPI '9'+1 ;IS IT A DIGIT
JNC NSCAN2 ;> 9
CPI '0'
JC NSCAN2 ;< 0
NSCAN0:
SUI '0' ;REMOVE ASCII BIAS
PUSH H ;SAVE PTR
XCHG ;GET WORK IN HL
PUSH H
POP D
DAD H
DAD H
DAD D
DAD H ;HL=HL*10
MVI D,0
MOV E,A ;NEW DIGIT
DAD D ;ADD IT IN
XCHG ;PUT WORK BACK
POP H ;RESTORE PTR
INX H ;AND STEP IT
MOV A,M
CPI '9'+1
JNC NSCAN1
CPI '0'
JC NSCAN1
JMP NSCAN0 ;LOOP
;
NSCAN1: MOV A,E ;GET NUMBER
CPI 16 ;<= 15
JNC NSCAN2
ORA A ;CLEAR CY
JMP NSCAN3
;
NSCAN2:
STC ;SET CARRY
NSCAN3:
RET ;EXIT HERE
;
MSG1 DB 'PUT Version ',VERSION/10 + '0','.'
DB VERSION MOD 10 + '0'
DB ', by Angus Bliss and Bill Bolton',ACR,ALF,'$'
;
MSG2 DB 'Usage:',ACR,ALF
DB ' A>put [d:]filename f.t [d:] [-NW] <cr>'
DB ACR,ALF
DB 'Where:',ACR,ALF
DB ' filename - is any valid CP/M file '
DB 'specifier',ACR,ALF
DB ' f - is source user area',ACR,ALF
DB ' t - is destination user area'
DB ACR,ALF
DB ' d: - is optional drive specifier'
DB ACR,ALF
DB ' - - is an option flag',ACR,ALF
DB ' N - is no query to overwrite '
DB 'existing file',ACR,ALF
DB ' W - is force overwrite of R/O '
DB 'file',ACR,ALF,ALF
DB ' Will prompt if destination '
DB 'file is already present',ACR,ALF,'$'
;
MSG3 DB 'No parameters given',ACR,ALF,'$'
;
MSG4 DB 'Invalid user number(s)',ACR,ALF,'$'
;
MSG5 DB 'Sorry - you need CP/M 2.x',ACR,ALF,'$'
;
MSG6 DB 'Open fail on source file.',ACR,ALF,'$'
;
MSG7 DB 'Read failure on source file.',ACR,ALF,'$'
;
MSG8 DB ' Destination file is present.',ACR,ALF
DB ' Continue (y) or Abort (n)?$'
;
MSG8A DB 'Destination is present and R/O.$'
;
MSG9 DB 'Open failure on destination file.$'
;
MSG10 DB 'Destination directory probably full.$'
;
MSG11 DB 'Write error on destination.$'
;
MSG12 DB 'Close fail on destination.$'
;
MSG13 DB 'ABORT - returning to CP/M.',ACR,ALF,'$'
;
MSG14 DB '**** Normal end-of-job ****',ACR,ALF,'$'
;
MSG15 DB ' Putting file : $'
;
MSG16 DB 'Rename error on destination.$'
;
MSG17 DB 'Rename error on R/O file.$'
;
MSG18 DB 'ABORT, Control C typed at console - '
DB 'returning to CP/M',ACR,ALF,'$'
;
CUSER DB 0 ;INITIATING USER
FUSER DB 0 ;FILE FROM USER
TUSER DB 0 ;FILE TO USER
SIZEB DW 0 ;BUFFER IN BYTES
BUFPT DW 0 ;DMA POINTER
COUNT DB 0 ;BUFFER SIZE IN SECTORS
ACOUNT DB 0 ;ACTUAL SECTOR COUNT
OPEN DB 0 ;FILE OPEN SWITCH
EOF DB 0 ;END OF SOURCE SWITCH
WILD DB 0 ;WILDCARD SWITCH
O$W DB 0 ;OVER WRITE SWITCH
N$Q DB 0 ;NO QUERY SWITCH
DEST$DRV DB 0 ;DESTINATION DRIVE
F$COUNT DB 0 ;FILES TRANSFERED COUNTER
D$COUNT DB 0 ;FILES TO SEARCH COUNTER
DIR$POINT DB 0 ;TEMP STORAGE FOR SEARCH NEXT
;
TYPE:
DB ' ' ;SECONDARY FILE TYPE
; FOR RENAME AFTER WRITE
FCB1: ;SOURCE FCB
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
;
FCB2: ;DESTINATION FCB
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
;
DS 32 ;16 LEVEL STACK
STACK EQU $ ;SOME STACK SPACE
;
BUFSTART EQU $+10 ;SOME LEEWAY
;
END START