; FLOPPY DISK COPY PROGRAM ; COPYRIGHT 1982, G. YOUNG, INC. ; UPDATED 10/9/82 * * TO EXECUTE, ENTER THE PROGRAM NAME FOLLOWED BY THE FILE MASK: * A>FLOPCOPY *.COM * * THE PRIMARY PURPOSE OF THIS PROGRAM IS TO COPY A FLOPPY DISK ON * SYSTEMS THAT HAVE ONLY ONE FLOPPY DISK AND A HARD DISK. THIS IS DONE * BY READING THE DIRECTORY ON THE FLOPPY AND CREATING A LIST OF FILES TO * TO BE COPIED, THEN COPY ALL THE FILES TO THE HARD DISK. A BLANK * DISK IS THEN INSERTED AND THE FILES ARE COPIED TO THE BLANK FLOPPY * AND DELETED OFF THE HARD DISK. THIS PROCEDURE IS USED INSTEAD OF * THE "SINGLE.COM" PROGRAM BECAUSE THERE IS MORE THAN 1 FILE SO "SINGLE" * CANNOT BE USED WITHOUT MODIFICATIONS AND EVEN THEN MANY, MANY DISKETTE * MOUNTS WOULD HAVE TO BE DONE. THIS WAY, ONLY 1 DISKETTE MOUNT NEEDS * TO BE DONE FOR EACH DISK THAT IS COPIED. * 8/26/82...IF DISKETTE IS FULL, ASK FOR ANOTHER, DO NOT ABORT * THIS ALLOWS COPYING DOUBLE DENSITY DISKS ON TO MULTIPLE SINGLE DENSITY DISKS * 10/9/82 ASK FOR SOURCE/DESTINATION/HARD DISK DRIVE # AND NOT HARD CODED * WRITTEN BY GARY YOUNG, BOX 3218, NO. HOLLYWOOD, CA 91609 TITLE '*** FLOPPY DISK COPY PROGRAM ***' BDOS EQU 5 RECSIZE EQU 12 BOOT EQU 0 ORG 100H JMP START DB 'COPYRIGHT 1982, G. YOUNG, INC.' START LXI SP,STACK+80 LDA 5DH ;SEE IF A MASK WAS ENTERED CPI 20H ;BUFFER WILL BE BLANK IF NOT JZ NOMASK MVI C,0DH ;DISK RESET CALL BDOS LXI H,RAM ;SET UP TABLE ADDRESS SHLD TABADDR LXI H,0000H SHLD TABCNT XRA A ;THE TABLE REFERS TO THE REMAINING AREA STA ABORT ;OF RAM TO HOLD AS MANY DIRECTORY ENTRIES STA EOF ;AS POSSIBLE LXI D,SIGNON ;PRINT SIGNON MESSAGE CALL OUTPUT LXI D,SRCFLPMSG ;GET SOURCE DRIVE CALL QUESTION ORA A JZ QUEST2 LDA INREC STA SRCFLP QUEST2 LXI D,DESTFLPMSG CALL QUESTION ORA A JZ QUEST3 LDA INREC STA SRCFLP QUEST3 LXI D,HDMSG CALL QUESTION ORA A JZ QUEST4 LDA INREC STA HDTEMP QUEST4 LDA HDTEMP ANI 0FH STA HDTEMP LDA SRCFLP ANI 0FH STA SRCFLP LDA DESTFLP ANI 0FH STA DESTFLP CALL EXTRACT ;GET DIRECTORY ENTRIES LDA ABORT ;SEE IF TOO MANY ENTRIES FOR MEMORY SIZE ORA A ;SHOULD BE ZERO TO BE OK JZ NOMORE LXI D,TABFULL ;REPORT WILL NOT BE COMPLETE CALL OUTPUT ;MEMORY FULL ERROR NOMORE CALL SORT CALL KILLDUPS ;REMOVE ENTRIES FROM MULTIPLE EXTENTS LDA SRCFLP ;FLOPPY IS THE SOURCE DRIVE STA SRCE LDA HDTEMP ;HARD DISK IS THE DESTINATION STA DEST CALL CPYFILE AGAIN LXI D,MNTBLANK CALL QUESTION MVI C,0DH CALL BDOS LDA HDTEMP STA SRCE LDA DESTFLP STA DEST CALL CPYFILE MSG3 LXI D,ANOTHER CALL QUESTION ORA A JZ WIPEOUT LDA INREC CPI 'N' JZ WIPEOUT CPI 'Y' JNZ MSG3 JMP AGAIN WIPEOUT CALL ERASE JMP BOOT ;RESET AND RETURN TO CPM NOMASK LXI D,ERRNOMSK CALL OUTPUT JMP BOOT * * THE EXTRACT ROUTINE SCANS THE DIRECTORY ON THE FLOPPY DISK * AND CREATES A LIST OF FILES TO BE COPIED. AFTERS SORTING, * DUPLICATE ENTRIES RESULTING FROM MULTIPLE EXTENT ENTRIES WILL * BE REMOVED. * * THE DUMMYFCB SETS UP A SKELETON TO READ ALL FILES ON THE DIRECTORY * TO BE MODIFIED BY THE SKELATON SETUP IN THE CALL (EX: FLOPCOPY *.ASC). * DUMMYFCB DB 0,'????????????',0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 EXTRACT EQU $ LXI D,DUMMYFCB ;COPY THE MASK SET UP BY CCP LXI H,5CH ;OVER THE DUMMY FCB TO LIMIT WHAT IS COPIED MVI B,12 CALL MOVE LDA SRCFLP ;FORCE THE DRIVE TO BE FLOPPY DRIVE STA DUMMYFCB ORI 40H STA RDISK LXI D,DISKBUF ;SET A DMA ADDRESS FOR DIRECTORY ENTRIES MVI C,1AH CALL BDOS ;SET DMA LXI D,DUMMYFCB ;GET FIRST DIRECTORY ENTRY MVI C,11H CALL BDOS ;GET DIRECTORY INR A RZ JMP GETFCB ;EXTRACT DATA FROM FCB NEXTFCB LXI D,DUMMYFCB ;GET NEXT ENTRY AFTER THE FIRST MVI C,12H CALL BDOS INR A RZ GETFCB LXI D,32 ;EACH ENTRY IS 32 BYTES LONG LXI H,DISKBUF ;DIRECTORY RECORD IS IN DISKBUF CPI 1 ;FIRST ENTRY IN RECORD??? JZ FORMREC ;YES DAD D ;ADD 32 TO ADDRESS IN RECORD CPI 2 ;SECOND ENTRY IN RECORD??? JZ FORMREC DAD D ;ADD 64 TO ADDRESS OF RECORD CPI 3 ;THIRD ENTRY IN RECORD??? JZ FORMREC DAD D ;ADD 96 TO ADDRESS OF RECORD FORMREC INX H ;PASS DRIVE BYTE LXI D,RFILE ;MOVE FILE NAME MVI B,8 ;MOVE 8 CHARACTERS CALL MOVE LXI D,8 ;POSITION PAST NAME TO TYPE DAD D LXI D,RTYPE ;MOVE TYPE MVI B,3 ;MOVE 3 CHARACTERS CALL MOVE INX H ;POSITION TO THE EXTENT NUMBER INX H INX H LXI H,RTYPE ;STRIP OFF THE HIGH BIT SET BY MVI B,11 ;THE VERSION PROGRAM STRIP MOV A,M ANI 07FH MOV M,A INX H DCR B JNZ STRIP LXI H,RTYPE ;SKIP OVER JUNK DISK ENTRIES MVI B,11 ;CONTAINING NONPRINTING CHARACTERS NONPRNT MOV A,M CPI 20H ;ANY CHAR LESS THAN A BLANK JC NEXTFCB ;GO TO NEXT ONE IF SO INX H DCR B JNZ NONPRNT FIRSTEXT EQU $ ;GOT THE FIRST EXTENT LHLD TABADDR ;GET MEMORY TABLE ADDRESS LXI D,RTYPE ;GET MEMORY RECORD ADDRESS XCHG ;RTYPE (HL) TO TABADDR (DE) MVI B,RECSIZE ;MOVE RECSIZE BYTES CALL MOVE LHLD TABADDR ;INCREMENT FOR NEXT ENTRY LXI D,RECSIZE ;RECSIZE BYTES IN RECORD DAD D SHLD TABADDR ;SAVE NEW ADDRESS MVI M,1AH ;SET AN END-OF-TABLE INDICATOR LHLD TABCNT ;GET RECORD COUNT INX H SHLD TABCNT ;INCREMENT RECORD COUNT LHLD TABADDR ;SEE IF NEW ADDRESS IS GREATER XCHG ;THAN THE TOP OF TPA-128 LHLD BDOS+1 ;HL=TOP...DE=TABLE+RECSIZE LXI B,-128 DAD B ;SUBTRACT 128 FROM TOP CALL COMPREG ;COMPARE REGISTER VALUES JNC NEXTFCB ;THERE IS ROOM FOR MORE MVI A,1 ;NO MORE ROOM...ABORT NOW STA ABORT RET * COPY THE FILE FROM ONE DISK TO ANOTHER * THIS CODE WAS TAKEN FROM BACKUP.ASM SO HDFCB REFERS TO THE SOURCE DISK * AND FPFCB REFERS TO THE DESTINATION DISK REGARDLESS OF FLOPPY OR HARD. CPYFILE EQU $ LHLD ADDR2 ;GET THE CURRENT END OF TABLE INX H ;PLUS ONE FOR THE START OF THE SHLD ADDR3 ;READ/WRITE BUFFER LXI H,RAM ;SET THE ADDRESS OF THE FIRST ENTRY SHLD ADDR1 JMP PASSMOVE NEXTFILE EQU $ LHLD ADDR1 LXI D,RECSIZE DAD D SHLD ADDR1 PASSMOVE LHLD ADDR1 MOV A,M CPI 1AH RZ FORMFCB LXI D,HDFCB ;CLEAR THE FCB MVI B,36 XRA A ZEROFCB STAX D INX D DCR B JNZ ZEROFCB LHLD ADDR1 ;GET ADDRESS OF TABLE ENTRY LXI D,HDTYPE ;MOVE IN THE TYPE MVI B,3 CALL MOVE INX H INX H ;POSITION TO NAME INX H LXI D,HDFILE ;MOVE THE FILE NAME MVI B,8 CALL MOVE LXI D,8 DAD D ;POSITION TO DISK ID, A:, B: ETC LDA SRCE STA HDFCB LXI D,FPFCB ;COPY THE HDFCB TO THE FLOPPY FCB LXI H,HDFCB MVI B,36 CALL MOVE LDA DEST STA FPFCB LHLD ADDR1 CALL FORMAT LXI D,PRNTREC CALL OUTPUT LXI D,HDFCB ;OPEN THE SOURCE FILE DRIVE MVI C,0FH CALL BDOS INR A JZ NOTFOUND LXI D,FPFCB ;SEE IF THE FILE IS ON THE DESTINATION DRV MVI C,0FH CALL BDOS ;DUMMY OPEN INR A JZ MAKEIT ;NOT THERE...MAKE IT LHLD ADDR1 ;SET THE DRIVE BYTE (#12) TO '*' TO MARK LXI D,RECSIZE-1 ;THE FILE AS ALREADY BEING THERE SO THAT DAD D ;THE ERASE ROUTINE WILL NOT ERASE IT MVI A,'*' ;LATER WHEN REMOVING FILES MOV M,A HUH2 LXI D,ALRDYEXT ;FILE ALREADY EXISTS ON DESTINATION. ASK IF CALL QUESTION ;YOU WANT TO COPY THE NEW SOURCE OVER THE CPI 1 ;EXISTING COPY JNZ HUH2 LDA INREC CPI 'Y' JZ ERAIT ;ERASE IT CPI 'N' ;NO, USE THE COPY ALREADY ON THE DESTINATION JZ NEXTFILE JMP HUH2 ERAIT EQU $ LXI D,FPFCB ;DELETE THE FILE ON FLOPPY IF IT MVI C,13H ;EXISTS CALL BDOS MAKEIT EQU $ LXI D,FPFCB ;CREATE THE FILE ON FLOPPY MVI C,16H CALL BDOS ;MAKE FILE INR A JZ DISKFULL COPYLOOP CALL LOADBUFF ;LOAD MEMORY WITH FILE CALL WRITEBUF ;WRITE MEMORY FILE LDA EOF CPI 1 JZ ENDOFFILE CPI 2 JZ DISKFULL JMP COPYLOOP ENDOFFILE LXI D,FPFCB ;CLOSE FLOPPY FILE MVI C,10H CALL BDOS ;CLOSE JMP NEXTFILE DISKFULL LXI D,FPFCB MVI C,13H ;DELETE FILE ON FLOPPY CALL BDOS LXI D,DSKFULL ;PRINT DISK FULL MESSAGE CALL QUESTION MVI C,0DH ;RESET DISKS CALL BDOS JMP FORMFCB NOTFOUND LHLD ADDR1 CALL FORMAT LXI D,NFMSG CALL OUTPUT LXI D,PRNTREC CALL OUTPUT RET ERASE EQU $ HUH LXI D,ERAMSG ;ASK IF YOU WANT THEM ERASED CALL QUESTION ORA A JZ ERAALL LDA INREC CPI 'Y' JZ ERAALL CPI 'N' RZ JMP HUH ERAALL EQU $ LXI H,RAM ;SET THE ADDRESS OF THE FIRST ENTRY SHLD ADDR1 JMP PASSMOVEX ERANEXT EQU $ LHLD ADDR1 LXI D,RECSIZE DAD D SHLD ADDR1 PASSMOVEX LHLD ADDR1 MOV A,M CPI 1AH RZ LXI D,RECSIZE-1 ;SEE IF THE DRIVE INDICATOR IS SET TO '*' DAD D ;MEANING THE FILE WAS ALREADY ON THE HARD DISK MOV A,M ;SO IT WILL NOT BE DELETED CPI '*' JZ ERANEXT ;YES, IT WAS THERE, SO DO NOT ERASE IT FORMFCBX LXI D,HDFCB ;CLEAR THE FCB MVI B,36 XRA A ZEROFCBX STAX D INX D DCR B JNZ ZEROFCBX LHLD ADDR1 LXI D,HDTYPE ;MOVE IN THE TYPE MVI B,3 CALL MOVE INX H INX H ;POSITION TO NAME INX H LXI D,HDFILE ;MOVE THE FILE NAME MVI B,8 CALL MOVE LXI D,8 DAD D ;POSITION TO DISK ID, A:, B: ETC LDA HDTEMP STA HDFCB LHLD ADDR1 CALL FORMAT LXI D,PRNTREC CALL OUTPUT LXI D,HDFCB ;DELETE THE FILE ON FLOPPY IF IT MVI C,13H ;EXISTS CALL BDOS JMP ERANEXT * THE FOLLOWING ROUTINE IS A BUBBLE SORT. IN PSEUDOBASIC * IS WOULD BE DONE AS FOLLOWS: *SORT ADDR1=BOTTOM(RAM)-RECSIZE (RECSIZE IS COUNT OF BYTES IN ONE RECORD) * MAX1=0 *LOOP1 MAX1=MAX1+1 * ADDR1=ADDR1+RECSIZE (FIRST TIME THIS WOULD BE THE BOTTOM) * IF MAX1>TABCNT-1 THEN GO TO SORTED * ADDR2=ADDR1 * MAX2=MAX1 *LOOP2 MAX2=MAX2+1 * ADDR2=ADDR2+RECSIZE * IF MAX2>TABCNT THEN GO TO LOOP1 * IF TABLE(ADDR1)