home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-13 | 21.5 KB | 1,072 lines |
- ; PROGRAM: MCOPY
- ; AUTHOR: RICHARD CONN
- ; VERSION: 4.0
- ; DATE: 18 MAY 84
- ; PREVIOUS VERSIONS: 3.0 (16 JAN 83)
- ; PREVIOUS VERSIONS: NUMEROUS
-
- VERS equ 42 ; Use 16k buffer 14 Dec 84 jww
- ; Fix some bugs Joe Wright 28 Aug 84
- ; 1. Add check for directory full after f$make
-
- z3env SET 0F400H
-
- ;
- ; MCOPY is a program which repeatedly copies a file from drive
- ; A: onto drive B:. It prompts the user to mount a disk in drive B:,
- ; copies the file from drive A: to drive B:, verifies the copy (if not
- ; overridden), and then performs the function again.
- ;
- ; MCOPY performs its function in the following steps:
- ; 1. MCOPY determines the attributes
- ; of the destination file (if it exists) and clears them (file becomes
- ; R/W and DIR)
- ; 2. MCOPY deletes the destination file (if it exists)
- ; 3. MCOPY copies the source file to the destination
- ; 4. MCOPY determines the attributes
- ; of the source file and makes the attributes of the destination file
- ; identical to those of the source
- ; 5. MCOPY reads both the source and destination files and
- ; compares them byte-for-byte
- ;
-
- ; SPECIAL Constants
- PLIM EQU 4*16 ; SIZE OF BUFFER IN PAGES (4 * nK) [may be changed]
- ESIZE EQU 16 ; NUMBER OF BYTES/ENTRY
-
- ; CP/M Constants
- WB EQU 0 ; CP/M WARM BOOT
- BDOSE EQU WB+5 ; BDOS ENTRY POINT
- FCB EQU WB+5CH ; SPECIFIED FCB
- BUFF EQU WB+80H ; DEFAULT BUFFER AND INPUT LINE
- SDMA EQU 26 ; SET DMA ADDRESS
-
- ; ASCII Constants, et al
- ON EQU 0FFH ; ON CODE
- OFF EQU 0 ; OFF CODE
- CR EQU 0DH ; <CR>
- LF EQU 0AH ; <LF>
- CTRLC EQU 'C'-'@' ; ^C
- CTRLZ EQU 'Z'-'@' ; ^Z
- OPTC EQU '/' ; OPTION DELIMITER
-
- ;
- ; LOAD @DE MACRO
- ;
- LDED MACRO ?ADR
- XCHG
- LHLD ?ADR
- XCHG
- ENDM
-
- ;
- ; SYSLIB ROUTINES
- ;
- EXT Z3INIT,ZFNAME,GETQUIET
- EXT COMPHD,RETUD,LOGUD,PUTUD,GETUD
- EXT DIRQ,DIRPACK,DIRTDU
- EXT INITFCB,F$EXIST
- EXT CRCCLR,CRCUPD,CRCDONE
- EXT BDOS,CIN,COUT,CONDIN
- EXT F$DELETE,F$OPEN,F$MAKE,F$CLOSE,F$READ,F$WRITE
- EXT PADC,EPSTR,EPRINT
- EXT MOVEB,CAPS,CRLF
- EXT CODEND
-
- ;
- ; Environment Definition
- ;
- if z3env ne 0
- ;
- ; External ZCPR3 Environment Descriptor
- ;
- jmp start
- db 'Z3ENV' ;This is a ZCPR3 Utility
- db 1 ;External Environment Descriptor
- z3eadr:
- dw z3env
- start:
- lhld z3eadr ;pt to ZCPR3 environment
- ;
- else
- ;
- ; Internal ZCPR3 Environment Descriptor
- ;
- MACLIB Z3BASE.LIB
- MACLIB SYSENV.LIB
- z3eadr:
- jmp start
- SYSENV
- start:
- lxi h,z3eadr ;pt to ZCPR3 environment
- endif
-
- ;
- ; Start of Program -- Initialize ZCPR3 Environment
- ;
- call z3init ;initialize the ZCPR3 Env and the VLIB Env
- jmp startx
-
- ;
- ; USER-DEFINABLE INITIAL FLAG CONDITIONS
- ; THE DEFAULT CONDITIONS FOR MCOPY MAY BE READILY PATCHED BY THE USER
- ; VIA DDT FOR HIS DESIRED DEFAULT VALUES
- ;
- DVERFLG:
- DB ON ; SET VERIFY
- DINSP:
- DB OFF ; SET NO INSPECT
- DNCOPY:
- DB OFF ; SET NO MULTIPLE COPIES BY DEFAULT
- DDDISK:
- DB 'B'-'A' ; DEFAULT DESTINATION DISK IS B
- DDUSER:
- DB 0 ; DEFAULT DESTINATION USER IS 0
- BACKDIR:
- DB 'BACKUP ' ; NAME OF BACKUP DIRECTORY
-
- ;
- ; BEGINNING OF MCOPY PROGRAM
- ;
- STARTX:
- ;
- ; PRINT BANNER
- ;
- CALL EPRINT
- DB 'MCOPY Version '
- DB VERS/10+'0','.',(VERS MOD 10)+'0',0
- ;
- ; SET UP DYNAMIC BUFFERS
- ;
- LXI H,0 ; GET SP
- DAD SP
- SHLD STACK ; SAVE IT
- CALL CODEND ; DETERMINE FREE SPACE
- SHLD INLINE ; PTR TO INPUT LINE
- INR H
- SHLD FCBT ; PTR TO FCB TEMP
- INR H
- SHLD FCBS ; PTR TO SOURCE FCB
- INR H
- SHLD FCBD ; PTR TO DEST FCB
- INR H
- SHLD FREEBUF ; FREE SPACE BUFFER
-
- ;
- ; SET DEFAULT FLAGS
- ;
- CALL GETQUIET ; GET QUIET FLAG
- STA QUIET
- LDA DVERFLG ; VERIFY
- STA VERFLG
- LDA DINSP ; INSPECT
- STA INSP
- LDA DNCOPY ; MULTIPLE COPIES
- STA NCOPY
-
- ;
- ; CHECK FOR BACKUP DIRECTORY AND ESTABLISH IT AS DEFAULT
- ; IF NO BACKUP DIRECTORY, SELECT DEFAULT STORED
- ;
- LXI H,BACKDIR ; PT TO DIRECTORY NAME
- CALL DIRTDU
- JZ DEFBACK ; NAME NOT FOUND, SO SELECT DEFAULT
- MOV A,B ; SET DEST DISK
- STA DDISK
- MOV A,C ; SET DEST USER
- STA DUSER
- JMP BACKSET
- DEFBACK:
- LDA DDDISK ; GET DEFAULT DEST DISK
- STA DDISK ; SET DEST DISK
- LDA DDUSER ; GET DEFAULT DEST USER
- STA DUSER ; SET DEST USER
- ;
- ; OBTAIN AND SAVE CURRENT USER AND DISK
- ;
- BACKSET:
- CALL PUTUD ; SAVE POSITION
- CALL RETUD ; GET USER/DISK
- MOV A,B ; SAVE DISK
- STA CDISK
- LHLD INLINE ; INPUT LINE SAVE BUFFER
- XCHG ; ... IN DE
- LXI H,BUFF+1 ; PT TO COMMAND LINE CHAR COUNT
- MVI B,128 ; SAVE 128 BYTES (ARBITRARY)
- CALL MOVEB
- XCHG ; HL PTS TO INPUT LINE
- ;
- ; SET OTHER FLAGS
- ;
- XRA A ; A=0
- STA EXIST ; TURN OFF EXIST TEST
- ;
- ; CHECK FOR EMPTY COMMAND LINE AND PROCESS COMMAND MODE IF SO
- ; ON ENTRY, HL PTS TO FIRST CHAR OF STRING FROM CLINE
- ;
- START1:
- MOV A,M ; GET CHAR
- ORA A ; EOL?
- JZ MHELP ; PRINT HELP MESSAGE IF NO INPUT
- INX H ; PT TO NEXT
- CPI ' ' ; JUST SPACES?
- JZ START1
- ;
- ; COMMAND LINE WAS NOT EMPTY -- CHECK FOR HELP REQUEST
- ;
- DCX H ; PT TO FIRST CHAR
- CPI '/' ; IF OPENING OPTION, MUST BE HELP
- JZ MHELP
- ;
- ; SEE IF OPTIONS ARE AVAILABLE IN THE COMMAND LINE
- ;
- SHLD MFPTR ; SET PTR TO FIRST CHAR OF FILE NAME SPECS
- ;
- ; SKIP TO END OF FILE NAME SPECS
- ;
- START2:
- MOV A,M ; SKIP TO <SP> OR EOL
- INX H ; PT TO NEXT
- CPI ' '+1 ; <SP> OR LESS?
- JNC START2
- ORA A ; AT EOL?
- JZ MCOPY0 ; PERFORM DEFAULT MCOPY FUNCTION IF AT EOL
- ;
- ; SCAN FOR OPTION
- ;
- OPTION:
- MOV A,M ; GET OPTION CHAR
- ORA A ; EOL?
- JZ MCOPY0 ; DO MCOPY
- INX H ; PT TO NEXT
- PUSH H ; SAVE PTR
- LXI H,OPTTAB ; PT TO OPTION TABLE
- CALL CMDER ; PROCESS COMMAND
- POP H ; GET PTR
- JMP OPTION
-
- ;
- ; COMMAND PROCESSOR -- COMMAND LETTER IN A, HL PTS TO TABLE
- ;
- CMDER:
- PUSH B ; SAVE BC
- MOV B,A ; COMMAND IN B
- CMDER1:
- MOV A,M ; GET COMMAND LETTER
- ORA A ; DONE?
- JZ CMDER2
- CMP B ; MATCH?
- JNZ CMDER3
- CMDER2:
- INX H ; PT TO ADDRESS
- MOV E,M ; GET IT IN DE
- INX H
- MOV D,M
- XCHG ; HL PTS TO COMMAND ADDRESS
- POP B ; RESTORE BC
- PCHL ; RUN COMMAND
- CMDER3:
- INX H ; SKIP TO NEXT ENTRY IN TABLE
- INX H
- INX H
- JMP CMDER1
-
- ; OPTION COMMAND TABLE
- OPTTAB:
- DB ' ' ; DONE
- DW OPTS
- DB OPTC ; SKIP OPTC
- DW OPTS
- DB 'E' ; EXIST TEST
- DW OPTE
- DB 'I' ; INSPECT
- DW OPTI
- DB 'M' ; MULTIPLE COPY
- DW OPTM
- DB 'Q' ; QUIET
- DW OPTQ
- DB 'V' ; VERIFY
- DW OPTV
- DB 0 ; END OF TABLE
- DW OHELP
-
- ; INVALID OPTION CHAR -- CLEAR STACK (RET ADR AND HL) AND PRINT HELP
- OHELP:
- POP H ; CLEAR RET ADR
- POP H ; CLEAR HL
-
- ; PRINT HELP MESSAGE
- MHELP:
- CALL EPRINT
- DB CR,LF,'Syntax:'
- DB cr,lf,' MCOPY dir:=dir:filename.typ,... o...'
- db cr,lf,'Options:'
- DB cr,lf,' E -- Existence Test'
- DB cr,lf,' I -- Inspect Files'
- DB cr,lf,' M -- Multiple Copy'
- DB cr,lf,' Q -- Toggle Quiet'
- DB cr,lf,' V -- No Verify'
- DB 0
- RET ; RETURN TO ZCPR3
-
- ; VERIFY FLAG TOGGLE OPTION
- OPTV:
- LDA VERFLG ; GET FLAG
- CMA ; FLIP IT
- STA VERFLG ; PUT FLAG
- ; SKIP OPTION
- OPTS:
- RET
-
- ; EXIST TEST TOGGLE OPTION
- OPTE:
- LDA EXIST ; GET FLAG
- CMA ; FLIP IT
- STA EXIST ; PUT FLAG
- RET
-
- ; NCOPY FLAG TOGGLE OPTION
- OPTM:
- LDA NCOPY ; GET FLAG
- CMA ; FLIP IT
- STA NCOPY ; PUT FLAG
- RET
-
- ; INSPECT FLAG TOGGLE OPTION
- OPTI:
- LDA INSP ; GET FLAG
- CMA ; FLIP IT
- STA INSP ; PUT FLAG
- RET
-
- ; QUIET FLAG TOGGLE OPTION
- OPTQ:
- LDA QUIET ; GET FLAG
- CMA ; FLIP IT
- STA QUIET ; PUT FLAG
- RET
-
- ;
- ; **** MCOPY of COMMAND LINE ****
- ;
- MCOPY0:
- LHLD FREEBUF ; STACK RESET
- SPHL
- LDA NCOPY ; MULTIPLE COPIES?
- ORA A ; 0=NO
- JZ NOPAUSE
- CALL SAKCHK ; STRIKE ANY KEY CHECK
- JZ CPM ; WARM BOOT IF ABORT
- NOPAUSE:
- CALL COPY ; DO THE COPY
- CPM:
- LHLD STACK ; RESET STACK
- SPHL
- RET ; RETURN TO OPSYS
- CPMA:
- CALL EPRINT
- DB CR,LF,'Abort',0
- JMP CPM
-
- ;
- ; **** Begin Multiple Copy Procedure ****
- ;
- COPY:
- LHLD MFPTR ; PT TO FIRST FILE NAME
- SHLD NXTPTR ; SET PTR TO NEXT FILE NAME
- XRA A ; A=0
- STA VERCNT ; ZERO ERROR COUNT
- LDA EXIST ; IF EXIST, THEN MUST NOT BE QUIET
- ORA A ; 0=NO EXIST
- JZ MCOPY
- XRA A ; SET NO QUIET
- STA QUIET
- ;
- ; **** MAIN COPY LOOP ****
- ;
- MCOPY:
- LHLD NXTPTR ; GET PTR TO NEXT FILE NAME
- MOV A,M ; GET FIRST CHAR
- CPI ' '+1 ; DONE IF <SP> OR LESS
- JNC MCOPY1 ; CONTINUE WITH PROCEDURE
- ;
- ; MCOPY OF FILE SPECS IS NOW DONE
- ; DONE WITH COPY PROCEDURE -- CONTINUE?
- ;
- COPYT:
- LDA VERFLG ; VERIFY?
- ORA A ; 0=NO
- JZ COPYT1
- CALL CRLF ; NEW LINE
- LDA VERCNT ; GET ERROR COUNT
- CALL PADC ; PRINT AS DECIMAL
- CALL EPRINT
- DB ' Errors',0
- COPYT1:
- LDA NCOPY ; MULTIPLE COPIES?
- ORA A ; 0=NO
- RZ
- CALL SAKCHK ; CHECK FOR STRIKE OF ANY KEY
- RZ ; RETURN IF ABORT
- JMP COPY ; COPY AGAIN FROM THE BEGINNING
- ;
- ; BEGIN COPY OF FILE GROUP
- ;
- MCOPY1:
- CPI ',' ; SKIP COMMA SEPARATOR IF THERE
- JNZ MCPY0
- INX H ; PT TO CHAR AFTER COMMA
- MCPY0:
- MOV A,M ; GET NEXT CHAR
- CPI ' '+1 ; CHECK FOR ERROR
- JC FORMERR
- CALL GETUD ; RETURN HOME
- LDED FCBS ; PT TO SOURCE FCB
- MVI A,0 ; DIR BEFORE DU
- CALL ZFNAME ; EXTRACT FILE NAME DATA
- CALL DUCVRT ; CONVERT DU INTO BC
- MOV A,M ; GET DELIMITER
- CPI '=' ; IF '=', WE HAVE A NEW DISK/USER
- JNZ MCOPY2 ; FORM IS DIRS:FN.FT IF NO '='
- ;
- ; FORM IS DIRD:=DIRS:FN.FT, SO SET DEST DISK/USER
- ;
- MOV A,B ; GET DISK
- STA DDISK ; SET NEW DEFAULT DISK
- MOV A,C ; GET USER
- STA DUSER ; SET NEW DEFAULT USER
- ;
- ; NOW DERIVE DIRS:FN.FT FORM AFTER THE '='
- ;
- MCPY2:
- INX H ; PT TO CHAR BEYOND '='
- MOV A,M ; GET CHAR
- CPI ' '+1 ; FORMAT ERROR?
- JC FORMERR
- LDED FCBS ; LOAD FCB
- MVI A,0 ; DIR BEFORE DU
- CALL ZFNAME ; GET SOURCE NAME
- CALL DUCVRT ; CONVERT TO DU IN BC
- ;
- ; SAVE PTR TO NEXT CHAR AFTER DIRS:FN.FT, AND SET SOURCE DISK/USER
- ;
- MCOPY2:
- SHLD NXTPTR ; SAVE PTR TO NEXT CHAR
- MOV A,B ; GET DISK
- STA SDISK ; SET NEW DEFAULT DISK
- MOV A,C ; GET USER
- STA SUSER ; SET NEW DEFAULT USER
- MCPY22:
- LDA DDISK ; DEST DIR MUST NOT EQUAL SOURCE DIR
- MOV B,A
- LDA SDISK
- CMP B
- JNZ MCPYOK
- LDA DUSER
- MOV B,A
- LDA SUSER
- CMP B
- JNZ MCPYOK
- CALL EPRINT
- DB CR,LF,'Src=Dest Err',0
- RET
- MCPYOK:
- CALL EPRINT
- DB CR,LF,'Copy ',0
- LDA SDISK ; GET NUMBER
- ADI 'A' ; CONVERT TO LETTER
- CALL COUT ; PRINT
- LDA SUSER ; PRINT USER NUMBER
- CALL PADC
- MVI A,':' ; SEPARATOR
- CALL COUT
- MVI A,' '
- CALL COUT
- LHLD FCBS ; PRINT FILE SPEC
- INX H ; PT TO FILE NAME
- CALL PRFN
- CALL EPRINT
- DB ' to ',0
- LDA DDISK ; GET NUMBER
- ADI 'A' ; CONVERT TO LETTER
- CALL COUT ; PRINT
- LDA DUSER ; PRINT USER NUMBER
- CALL PADC
- MVI A,':'
- CALL COUT
- MVI C,13 ; RESET DISK SYSTEM
- CALL BDOS
- CALL LOGS ; LOG IN SOURCE USER/DISK
- LDED FCBS ; PT TO SOURCE FCB
- CALL INITFCB ; INIT FCB
- LHLD FREEBUF ; PT TO BUFFER AREA
- MVI A,0C0H ; SELECT NON-SYS AND SYS FILES
- CALL DIRQ ; LOAD DIR, SELECT FILES, SORT, ETC
- JZ TPAOVFL ; TPA OVERFLOW ERROR?
- LDA INSP ; INSPECT FILES?
- ORA A ; 0=NO
- CNZ INSPF ; INSPECT FILES IF OPTION SELECTED
- MOV A,B ; CHECK FOR ANY FILES TO COPY
- ORA C ; 0=NONE
- JNZ MCPY24
- MCPY23:
- CALL EPRINT
- DB CR,LF,' NO Files -- ^C to Abort ',0
- CALL CIN ; GET RESPONSE
- CPI 'C'-'@' ; ABORT?
- JZ COPYT ; END TEST
- JMP MCOPY ; CONTINUE WITH NEXT
- MCPY24:
- PUSH H ; SAVE PTR AND COUNT
- PUSH B
- LXI D,ESIZE ; SKIP TO END OF LOADED FILES AND MARK BEGINNING OF
- ; WORK AREA
- MCPY25:
- DAD D ; PT TO NEXT
- DCX B ; COUNT DOWN
- MOV A,B ; DONE?
- ORA C
- JNZ MCPY25
- MVI A,PLIM ; SET PAGE LIMIT
- STA PAGLIM
- SHLD WORKBF ; SAVE PTR TO BEGINNING OF WORK BUFFER
- LDA BDOSE+2 ; GET BASE PAGE OF BDOS
- SUI 10 ; GET BELOW BASE PAGE OF CCP
- SUB H ; COMPUTE SIZE OF BUFFER AREA
- CPI PLIM ; PLIM PAGES LEFT?
- JNC PAGOK
- STA PAGLIM ; SET PAGE LIMIT
- PAGOK:
- POP B ; RESTORE PTRS
- POP H
- ;
- ; MAIN COPYING LOOP
- ; FILE NAMES ARE PTED TO BY HL AND BC=NUMBER OF FILES
- ;
- MCPY26:
- PUSH H ; SAVE REGS
- PUSH B
- CALL ABORTCK ; CHECK FOR ABORT
- MCPY27:
- CALL MCOPYX ; COPY SOURCE (HL) TO DESTINATION USING WORK BUFFER
- CALL PRDONE ; PRINT DONE MESSAGE
- CALL ABORTCK ; CHECK FOR ABORT
- LDA LSTCPY ; LAST FILE COPIED?
- ORA A ; 0=NO
- JZ MCPY28
- LDA VERFLG ; VERIFY?
- ORA A ; 0=NO
- CNZ MCOPYV ; DO VERIFY
- MCPY28:
- POP B ; GET REGS
- POP H
- LXI D,ESIZE ; PT TO NEXT FILE
- DAD D ; HL PTS TO NEXT FILE
- DCX B ; COUNT DOWN
- MOV A,B
- ORA C
- JNZ MCPY26
- JMP MCOPY ; COPY NEXT FILE SPEC
- ;
- ; CHECK FOR ABORT
- ;
- ABORTCK:
- CALL CONDIN ; CONDITIONAL INPUT
- RZ
- CPI CTRLC ; ABORT?
- JZ CPMA
- RET
- ;
- ; PRINT DONE MESSAGE
- ;
- PRDONE:
- LDA QUIET ; CHECK FOR QUIET
- ORA A ; NZ=QUIET
- RNZ
- CALL EPRINT
- DB ' Done',0
- RET
- ;
- ; COPY SOURCE FILE PTED TO BY HL TO DESTINATION
- ;
- MCOPYX:
- XRA A ; SET NO COPY OF LAST FILE
- STA LSTCPY ; SET FLAG
- LDED FCBS ; SET SOURCE FCB
- MVI B,12 ; 12 BYTES
- CALL MOVEB
- CALL INITFCB ; INIT SOURCE FCB
- LDED FCBD ; SET DESTINATION FCB
- MVI B,12 ; 12 BYTES
- CALL MOVEB
- CALL DRW ; CLEAR ATTRIBUTES IN FCB
- CALL INITFCB ; INIT DESTINATION FCB
- CALL LOGD ; LOG IN DESTINATION
- CALL EPRINT
- DB CR,LF,' File ',0
- LHLD FCBD ; PRINT FILE NAME
- INX H ; PT TO FILE NAME
- CALL PRFN
- LDED FCBD ; PT TO FCB
- CALL F$EXIST ; DOES DEST EXIST?
- JZ FNF ; FILE NOT FOUND IF ZERO
- LDA QUIET ; QUIET?
- ORA A ; 0=NO
- JNZ FFND
- CALL EPRINT
- DB ' Replace',0
- FFND:
- CALL EATEST ; EXIST APPROVED TEST?
- RZ ; NOT APPROVED, SO ABORT
- CALL DESTRW ; MAKE DESTINATION R/W IF NOT ALREADY
- CALL F$DELETE ; DELETE FILE
- CALL INITFCB ; REINIT FCB
- JMP FNF1 ; CREATE NEW FILE AND CONTINUE
- FNF:
- LDA QUIET ; QUIET?
- ORA A ; 0=NO
- JNZ FNF1
- CALL EATEST ; EXIST APPROVED?
- RZ ; NO?
- FNF1:
- CALL EPRINT
- DB ' ...',0
- MVI A,0FFH ; SET COPY OF LAST FILE
- STA LSTCPY ; SET FLAG
- CALL F$MAKE ; CREATE NEW FILE
- inr a ; check for full directory
- jz dirful ; report it
- ;
- ; OPEN SOURCE FILE IN PREP FOR COPY
- ;
- CALL CRCCLR ; CLEAR CRC VALUE
- CALL LOGS ; LOG IN SOURCE DISK
- LDED FCBS ; INIT FCB
- CALL INITFCB
- CALL F$OPEN ; OPEN FILE
- ;
- ; THIS LOOP, WHICH STARTS AT MCPYX, COPIES THE FILE FROM SOURCE TO DEST
- ;
- MCPYX:
- CALL LOGS ; LOG IN SOURCE
- LDED FCBS ; PT TO SOURCE FCB
- LHLD WORKBF ; PT TO BUFFER TO COPY INTO
- CALL LOAD ; LOAD FILE INTO WORKBF
- LDA BCNT ; IF COUNT=0, THEN DONE
- ORA A
- JZ MC2DONE
- ;
- ; COPY TO DISK
- ;
- MCPYD:
- CALL LOGD ; LOG IN DESTINATION
- LHLD WORKBF ; PT TO BUFFER
- MCPYD1:
- CALL SETDMA ; SET DMA ADDRESS PTED TO BY HL
- LXI D,128 ; INCR HL BY 128
- DAD D ; HL PTS TO NEXT BLOCK
- LDED FCBD ; WRITE TO DESTINATION FILE
- CALL F$WRITE
- ORA A ; OK?
- JNZ MCPYDERR
-
- ; COUNT DOWN TO NEXT BLOCK
- LDA BCNT ; GET BLOCK COUNT
- DCR A ; COUNT DOWN
- STA BCNT
- JNZ MCPYD1
- LDA CONT ; CONTINUE?
- ORA A ; CONT IF NOT ZERO
- JNZ MCPYX
- ;
- ; END OF COPY LOOP
- ;
- MC2DONE:
- CALL LOGS ; LOG IN SOURCE
- LDED FCBS ; CLOSE SOURCE
- CALL F$CLOSE
- CALL LOGD ; LOG IN DESTINATION
- LDED FCBD ; CLOSE DESTINATION
- CALL F$CLOSE
- CALL CRCDONE ; GET CRCK VALUE
- SHLD CRCVAL ; SAVE CRC VALUE
- ;
- ; SET ATTRIBUTES OF DESTINATION TO BE THE SAME AS THOSE OF SOURCE
- ;
- CALL LOGS ; LOG IN SOURCE DRIVE
- LDED FCBS ; FIND SOURCE
- MVI C,17 ; SEARCH FOR FIRST
- CALL BDOS
- RLC ; MULTIPLY BY 32 TO GET OFFSET
- RLC
- RLC
- RLC
- RLC
- ANI 0E0H ; MASK OUT LSB
- MOV L,A ; VALUE IN L
- MVI H,0
- LXI D,BUFF ; ADD IN BUFFER BASE
- DAD D
- XCHG ; PT TO FCBT IN DE
- LHLD FCBT
- XCHG
- MVI B,16 ; MOVE 16 BYTES
- CALL MOVEB
- CALL LOGD ; LOG IN DESTINATION DRIVE
- CALL INITFCB ; INIT FCB PTED TO BY DE (FCBT)
- MVI C,30 ; SET FILE ATTRIBUTES
- CALL BDOS
- RET ; MCOPYX RETURN
-
- ;
- ; CONVERT Z3 FCB DU INTO DU IN BC
- ;
- DUCVRT:
- PUSH H ; SAVE REGS
- PUSH D
- LDAX D ; GET DISK
- ORA A ; CURRENT?
- JNZ DUCV1
- LDA CDISK ; GET CURRENT
- INR A ; ADD 1 FOR A=1
- DUCV1:
- DCR A ; A=0
- MOV B,A
- LXI H,13 ; OFFSET TO USER
- DAD D
- MOV C,M ; GET USER
- POP D ; RESTORE REGS
- POP H
- RET
-
- ; FORMAT ERROR
- FORMERR:
- CALL EPRINT
- DB CR,LF,' Error: ',0
- CALL EPSTR ; PRINT ERROR
- RET
-
- ; TPA OVERFLOW
- TPAOVFL:
- CALL EPRINT
- DB CR,LF,'TPA Ovfl',0
- JMP CPM
-
- ; WRITE ERROR
- MCPYDERR:
- CALL EPRINT
- DB CR,LF,'Disk Full',0
- JMP CPM
-
- ; Directory Full Error
- dirful:
- call eprint
- db cr,lf,'Directory Full',0
- jmp cpm
-
- ; TEST FOR EXISTENCE REQUIREMENT AND GET USER RESPONSE
- EATEST:
- LDA EXIST ; EXISTENCE TEST ON?
- ORA A ; 0=NO
- JZ EAT1
- CALL EPRINT
- DB ' -- (Y/N)? ',0
- CALL CIN ; GET RESPONSE
- CALL CAPS
- CPI CR ; YES?
- JZ EAT1 ; COPY IF SO
- CALL COUT
- CPI 'N' ; NO?
- JNZ EAT1 ; COPY IF NOT NO
- XRA A ; ZERO FOR NOT APPROVED
- RET
- EAT1:
- MVI A,0FFH ; SET NZ FOR APPROVED
- ORA A ; SET FLAGS
- RET
- ;
- ; MAKE DESTINATION FCB ENTRY R/W AND DIR
- ;
- DRW:
- PUSH D
- LHLD FCBD ; CLEAR ATTRIBUTES OF DEST
- LXI D,9
- DAD D
- POP D
- MOV A,M ; GET IT
- ANI 7FH ; CLEAR IT
- MOV M,A
- INX H ; SAME TO NEXT
- MOV A,M ; GET IT AND CLEAR IT
- ANI 7FH
- MOV M,A
- RET
- DESTRW:
- CALL DRW ; MAKE ATTRIBUTES R/W AND NON-SYS
- LDED FCBD ; SET ATTRIBUTES
- MVI C,30
- CALL BDOS
- RET
-
- ;
- ; LOAD BUFFER PTED TO BY HL FROM FILE WHOSE FCB IS PTED TO BY DE
- ; ON OUTPUT, BCNT=NUMBER OF BLOCKS LOADED (UP TO 128) AND
- ; CONT=0 IF DONE OR 128 IF NOT DONE
- ;
- LOAD:
- XRA A ; A=0
- STA BCNT ; SET BLOCK COUNT
- STA CONT ; TURN OFF CONTINUATION FLAG
-
- ; MAIN COPY LOOP
- MCPY:
- CALL SETDMA ; SET DMA TO BLOCK PTED TO BY HL
- CALL F$READ ; READ BLOCK
- ORA A ; END OF FILE?
- RNZ ; RETURN
- PUSH D ; SAVE PTR TO FCB
- XCHG ; SAVE PTR TO DESTINATION BUFFER IN DE
- LHLD BDOSE+1 ; GET TOP OF TPA
- XCHG ; ... IN DE, DEST IN HL
- MOV A,H ; IF SAME PAGE, WE ARE IN OVERFLOW
- CMP D ; D MUST BE > H
- JNC TPAOVFL ; OVERFLOW IF D<=H
- MVI B,128 ; UPDATE CRC FOR 128 BYTES
- MCPYCRC:
- MOV A,M ; GET BYTE
- CALL CRCUPD ; UPDATE CRC
- INX H ; PT TO NEXT
- DCR B ; COUNT DOWN
- JNZ MCPYCRC
- POP D ; GET PTR TO FCB
- LDA BCNT ; GET BLOCK COUNT
- INR A ; INCREMENT IT
- STA BCNT ; SET IT
- MOV B,A ; BLOCK COUNT IN B
- LDA PAGLIM ; GET PAGE LIMIT
- ADD A ; DOUBLE IT FOR BLOCKS
- CMP B ; BUFFER FULL?
- JNZ MCPY
- STA CONT ; SET CONTINUATION FLAG
- RET
-
- ;
- ; SET DMA ADDRESS TO THAT PTED TO BY HL
- ;
- SETDMA:
- PUSH H ; SAVE REGS
- PUSH D
- PUSH B
- XCHG ; ADDRESS IN DE
- MVI C,SDMA
- CALL BDOSE
- POP B ; RESTORE REGS
- POP D
- POP H
- RET
-
- ;
- ; VERIFY PHASE
- ;
- MCOPYV:
- LDA QUIET ; CHECK FOR QUIET
- ORA A ; NZ=QUIET
- JNZ MCPYV
- CALL EPRINT
- DB ' Verify ...',0
- MCPYV:
- CALL CRCCLR ; CLEAR CRCK VALUE
- CALL LOGD ; LOG IN DESTINATION
- LDED FCBD ; CLEAR DESTINATION FCB
- CALL INITFCB ; INIT FCB
- CALL F$OPEN ; OPEN FILE
-
- ; **** MAIN VERIFY LOOP ****
- VERLOOP:
- LHLD WORKBF ; LOAD INPUT BUFFER FROM DESTINATION
- LDED FCBD
- CALL LOAD ; LOAD AND COMPUTE CRC VALUE
- LDA BCNT ; DONE IF NO BYTES LOADED
- ORA A
- JZ VERCRC
- LDA CONT ; CONTINUE?
- ORA A ; 0=NO
- JNZ VERLOOP
- ; VERIFY DONE
- VERCRC:
- LHLD CRCVAL ; GET OLD CRC VALUE
- XCHG ; ... IN DE
- CALL CRCDONE ; UPDATE COMPLETE
- CALL COMPHD ; COMPARE HL TO DE
- JZ PRDONE ; PRINT DONE MESSAGE OR FALL THRU TO ERROR MSG
-
- ; VERIFY ERROR
- VERERR:
- LXI H,VERCNT ; INCREMENT ERROR COUNT
- INR M
- CALL EPRINT
- DB ' Error',0
- RET
-
- ;
- ; **** MCOPY Utilities ****
- ;
-
- ;
- ; CHECK TO SEE IF USER WANTS TO CONTINUE
- ;
- SAKCHK:
- CALL EPRINT
- DB ' ^C to Quit - ',0
- CALL CIN ; GET RESPONSE
- CALL CRLF ; NEW LINE
- CALL CAPS ; CAPITALIZE
- CPI 'C'-'@' ; ^C?
- RET
- ;
- ; ALLOW USER TO INSPECT FILES FOR COPY
- ; FIRST FILE NAME PTED TO BY HL, BC = NUMBER OF FILES
- ; ON EXIT, BC = NUMBER OF SELECTED FILES
- ;
- INSPF:
- CALL EPRINT
- DB CR,LF,' Inspect -- '
- db 'Yes, No (def), Skip Rest'
- db 0
- PUSH H ; SAVE PTR TO FIRST FILE
- PUSH B ; SAVE FILE COUNT
- LXI D,ESIZE ; ENTRIES ARE ESIZE BYTES APART
- INSPF0:
- MOV A,M ; MARK FILE FOR NO COPY
- ANI 7FH ; CLEAR MSB FOR NO COPY
- MOV M,A
- DAD D ; PT TO NEXT
- DCX B ; COUNT DOWN
- MOV A,B ; DONE?
- ORA C
- JNZ INSPF0
- POP B ; RESTORE AND SAVE AGAIN
- POP H
- PUSH H
- PUSH B
- INSPF1:
- PUSH H ; SAVE PTR TO FILE
- INX H ; PT TO FN
- CALL CRLF ; NEW LINE
- CALL PRFN ; PRINT IT
- POP H ; GET PTR TO FILE
- CALL EPRINT
- DB ' - (Y/N/S)? ',0
- CALL CIN ; GET RESPONSE
- CALL CAPS ; CAPITALIZE
- CALL COUT ; ECHO
- CPI 'S' ; SKIP?
- JZ INSPFA
- CPI 'Y' ; Yes?
- JNZ INSPF2
- MOV A,M ; GET USER NUMBER
- ORI 80H ; MARK FILE
- MOV M,A ; SET USER NUMBER
- INSPF2:
- LXI D,ESIZE ; PT TO NEXT FILE
- DAD D
- DCX B ; COUNT DOWN
- MOV A,B ; DONE?
- ORA C
- JNZ INSPF1
- INSPFA:
- POP B ; GET COUNT
- POP H ; GET PTR TO FIRST FILE
- JMP DIRPACK ; REPACK DIRECTORY
-
- ;
- ; LOG IN SOURCE USER/DISK
- ;
- LOGS:
- LDA SUSER ; USER
- MOV C,A ; ... IN C
- LDA SDISK ; DISK
- MOV B,A ; ... IN B
- JMP LOGUD ; LOG IN USER/DISK
-
- ;
- ; LOG IN DESTINATION USER/DISK
- ;
- LOGD:
- LDA DUSER ; USER
- MOV C,A ; ... IN C
- LDA DDISK ; DISK
- MOV B,A ; ... IN B
- JMP LOGUD ; LOG IN USER/DISK
-
- ;
- ; PRINT FILE NAME
- ;
- PRFN:
- PUSH H ; SAVE REGS
- PUSH B
- MVI B,8 ; PRINT 8 CHARS
- CALL PRFN1
- MVI A,'.' ; DOT
- CALL COUT
- MVI B,3 ; PRINT 3 CHARS
- CALL PRFN1
- POP B ; GET REGS
- POP H
- RET
- PRFN1:
- MOV A,M ; GET CHAR
- INX H ; PT TO NEXT
- CALL COUT ; PRINT IT
- DCR B ; COUNT DOWN
- JNZ PRFN1
- RET
-
- ;
- ; **** BUFFERS ****
- ;
-
- ; POINTERS
- MFPTR: DS 2 ; PTR TO FIRST CHAR OF NEXT FN SPEC
- NXTPTR: DS 2 ; PTR TO NEXT FN SPEC IN LINE
- WORKBF: DS 2 ; PTR TO BEGINNING OF WORK BUFFER
-
- ; FLAGS COPIED FROM DEFAULTS
- VERFLG: DS 1 ; VERIFY
- INSP: DS 1 ; INSPECT
- QUIET: DS 1 ; QUIET
- NCOPY: DS 1 ; MULTIPLE COPY
-
- ; DISKS AND USERS
- CDISK: DS 1 ; CURRENT DISK
- SDISK: DS 1 ; SOURCE DISK
- SUSER: DS 1 ; SOURCE USER
- DDISK: DS 1 ; DESTINATION DISK
- DUSER: DS 1 ; DESTINATION USER
-
- ; CRC VALUE
- CRCVAL: DS 2 ; CRC CHECK VALUE
-
- ; FCBS
- FCBS: DS 2 ; SOURCE FCB
- FCBD: DS 2 ; DESTINATION FCB
- FCBT: DS 2 ; PTR TO TEMPORARY FCB FOR ATTRIBUTE SETTINGS
-
- ; COUNTS AND FLAGS
- PAGLIM: DS 1 ; MAX NUMBER OF PAGES IN WORK BUFFER
- LSTCPY: DS 1 ; LAST FILE WAS COPIED FLAG
- EXIST: DS 1 ; TEST FOR EXISTENCE FLAG
- VERCNT: DS 1 ; ERROR COUNT
- BCNT: DS 1 ; BLOCK COUNT
- CONT: DS 1 ; CONTINUE FLAG (0=NO, 0FFH=YES)
-
- ; DYNAMIC BUFFERS
- INLINE:
- DS 2 ; INPUT LINE BUFFER
- FREEBUF:
- DS 2 ; FREE SPACE BUFFER
- STACK:
- DS 2 ; OPSYS STACK PTR
-
- END