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] ' 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