IMD 1.18: 22/01/1996 6:33:02 micro cornucopia kaypro user group disk 15 hard disk utilities     15-DISK DOC) BACKUP ASM BACKUP ASMw !"#$%&'(BACKUP COM)*+,BACKUP DOC5-./0123BIGBURSTASM\456789:;<=>?BIGBURSTCOM @ABIGBURSTDOCBCDCRC COMEFGCRC DOCHCRCKLISTCRCID COMJKLFLOPCOPYASMMNOPQRSTUVWXYZ[\FLOPCOPYASM]FLOPCOPYCOM^_`FLOPCOPYDOC ab KAYPRO USERS DISK #15 Hard Disk Utilities Micro Cornucopia PO Box 223 Bend, OR 97709 This disk contains programs for easy manipulation of files on a Hard Disk system. The programs are set up for the Kaypro 10 but can be used with a Hard Disk subsystem on a Kaypro II or 4. And, since the source code is included with most of these programs you may mMAKE COMcdeMDIR ASMNfghijklmnoMDIR COMpMOVE COMqMULTCOPYASMkrstuvwxyz{|}~MULTCOPYCOM MULTCOPYDOCSWEEP38 DOCkSWEEP COMSWEEP COM`U ASMU COMUNSQ COM`odify them to suit your own needs. From the SIG/M USERS GROUP----------------------------------------------- Modified by Micro Cornucopia BACKUP.COM BACKUP.DOC BACKUP.ASM This program is a lifesaver. It allows you to back-up your hard disk on as many floppy disks as are necessary. It also creates a catalog of the files on each disk and creates a directory entry on each floppy with the date that it was created and a three letter I.D. of your choice. The program will no  t back-up duplicate files more than once and can be made to skip file types of your choice. It is very easy to use. BACKUP.DOC is the users manual for this truly fantastic program. BACKUP.ASM assembles under ASM.COM (on your Kaypro CP/M disk). FLOPCOPY.COM FLOPCOPY.DOC FLOPCOPY.ASM This program will allow you to copy a floppy disk to another floppy disk on a system with only one floppy. It uses the hard disk as a buffer and will not overwrite files on the hard disk with theExamples: MAKE ;will display help on using this ;program MOVE ;will display help on using this ;program ; ( means carriage return ) U.COM U.ASM U allows you to change user area and drive with one command. It is very easy to use. For usage examples type: U SWEEP.COM SWEEP38.DOC This is the famous disk cleanup and maintainance utility verson using MULTCOPY.COM. MULTCOPY.ASM can be assembled with ASM. MDIR.COM MDIR.ASM I have been needing this for a while. This is a directory program that displays files under ALL user areas. It sorts the entries in each area alphabetically and displays the entries next to the user number they are under in numerical order. A ^P will output the directory list to your printer for a hard record of your entire hard disk. Examples: MDIRrety of files. See CRC.DOC for information on this program.  same name (unless you tell it to). It will also detect a full disk condition so that you may copy a double sided disk onto two single sided disks. FLOPCOPY.DOC has the documentation for this program and FLOPCOPY.ASM assembles under ASM. BIGBURST.COM BIGBURST.DOC BIGBURST.ASM This program will allow you to back-up a file from your hard disk to a floppy disk even if the file is too large to fit on one floppy. It sep- erates the file and assigns each porion #3.8. Allows you to do nearly everything that you normally do with the CP/M commands: TYPE,ERA,DIR, and PIP all within this program. SWEEP38.DOC is documentation on this program. From Micro Cornucopia------------------------------------------------------ D.COM Our favorite no nonsense directory program. Shows file sizes in Kbytes and room remaining on disk but not a lot of other junk. Sorts files al- phabetically and lists them vertically. If list is larger than screen it paus ;will display all files on the ; drive you are logged on MDIR *.COM ; will display only .COM files MDIR B: ; will display all files on B: MAKE.COM MOVE.COM Two utilties for moving files between user areas. MAKE.COM will let you specify the user area to get the file from as well as the user area to move it to. MOVE.COM will only get the file from the current user area. To get documentation on usage, run the program without specifying a file name. tion an I.D. so that it may join the pieces together again when you need to copy it back to the hard disk. It makes sure that you insert the disks in the correct order. BIGBURST.DOC is an explanation of the program. BIGBURST.ASM will assemble under ASM. MULTCOPY.COM MULTCOPY.DOC MULTCOPY.ASM This utility operates in a way similar to PIP but will prompt you when the floppy is full to change floppies. It accepts ambiguous file names. See MULTCOPY.DOC for information es for a character from the key board before displaying the rest. UNSQ.COM This is an update of USQ for un-squeezing squeezed files. This version lets you use ambiguous file names. UNSQ *.* will examine each file and unsqueeze it if it is a squeezed file. If it is not a squeezed file the program will tell you and continue its search. CRC.COM CRC.DOC A cyclic redundandancy checker. This program can be used to check the integ  ; DISK DIRECTORY AND BACKUP PROGRAM ;COPYRIGHT 1980, G. YOUNG, INC.' ;UPDATED 02/06/83 ;* THE PRIMARY PURPOSE OF THIS PROGRAM IS TO BACKUP HARD DISKS ON TO ;* MULTIPLE FLOPPIES. FIRST, IT EXTRACTS THE DIRECTORIES FROM ALL OF ;* THE HARD DISKS, SORTS BY TYPE AND FILE NAME, AND PRINTS A CONSOLIDATED ;* DIRECTORY. THEN IT DELETES DUPLICATE FILES FROM THE CONSOLIDATED ;* DIRECTORY, DELETES UNWANTED TYPES (PRN, BAK, ETC), AND UNWANTED ;* FILES TO CREATE A LIST OF FILES TO BACKUP. THESE ARE COPIED TO DCR A JNZ SHIFT1 MVI M,')' INX H MVI M,20H INX H MVI M,'$' LXI D,HD2BU CALL QUESTION ORA A JZ GETTYPEQUS STA NODRV MOV B,A ;NO ERROR CHECKING IS DONE ON THE DATA LXI H,INREC LXI D,DRIVES ;SO IF YOU PUT IN DRIVE Z, IT WILL CRASH CALL MOVE ;BUT YOU WOULD NOT BE THAT STUPID??? GETTYPEQUS LDA NOSKIP MOV B,A ADD A ;MULTIPLY BY 3 ADD B LXI H,SKIPTYPE SHIFT2 INX H DCR A JNZ SHIFT2 MVI M,')' INX H MVI M,20H ;FORMAT TYPE TO SKIP QUESTION INX H MVI M,'$' LXINES PER PAGE RECLINE EQU 4 ;ENTRIES PER LINE START LXI SP,STACK+80 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 H,5DH ;SAVE THE FILE NAME FOR RESTARTING LXI D,RESTART MVI B,32 CALL MOVE ; IF CLOCK CALL GETDATE LXI H,DATETIME+1 ENDIF ; IF NOT CLOCK MSG1 LXI D,DATEMSG ;GETNCTION CALL QUESTION CPI 1 JNZ MSG3 LDA INREC CPI 'N' JZ FINISHED CPI 'Y' JNZ MSG3 CALL BACKUP ;BACKUP THOSE FILES REPORTED ON ; FINISHED LXI D,CRLF ;THIS LITTLE MANEUVER PREVENTS CALL LIST ;LOST LINES ON A BI-DIRECTIONAL ;PRINTER MVI C,0 ; Time to GO JMP BDOS ;RESET AND RETURN TO CPM ;* ;* THE EXTRACT ROUTINE SCANS ALL THE DRIVES IN THE DRIVE TABLE ;* WHEN COMPLETE, IT ASKS FOR THE NEXT DRIVE ID ;* WHEN THE HARD DISK IS UP, IT WILL NOT ASK FOR THE DRIVE ID BUT ;* WI;* MULTIPLE FLOPPIES AS NEEDED WHILE PRODUCING AN INDEX OF WHAT FILES ARE ;* ON EACH DISKETTE. RESTART CAPABILITY IS PROVIDED TO BEGIN THE BACKUP ;* AT ANY FILE. ;* RESTART CAPABILITY ADDED 6/20 ;* TO RESTART, ENTER A FILE NAME, I.E. A>BACKUP LOAD.COM ;* 10/1 ADDED A MORE EFFICIENT SHELL/METZER SORT WHICH DECREASED THE ;* SORT TIME FROM 2 MINUTES TO 2 SECONDS ;* 10/9/82 ADDED QUESTIONS TO MAKE IT MORE GENERAL PURPOSE ; ; ;10/25/83 SET UP FOR KAYPRO ; Fixed some subtle bugs ; Made it assem D,SKPMSG CALL QUESTION ORA A JZ DEFAULTTYPE STA NOSKIP LXI H,INREC LXI D,SKIPTYPE MOV B,A CALL MOVE LDA NOSKIP MVI B,0 DIVBY3 INR B DCR A JZ CNTTYPE DCR A JZ CNTTYPE DCR A JNZ DIVBY3 ;CONVERT BYTE COUNT TO TYPE COUNT CNTTYPE MOV A,B STA NOSKIP DEFAULTTYPE 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 CURRENT DATE FOR REPORTS CALL QUESTION ;PRINT MSG AND GET REPLY CPI 8 ;8 CHAR MUST HAVE BEEN ENTERED JNZ MSG1 ;REPEAT QUESTION IF NOT LXI H,INREC ;MOVE DATE FROM INREC ENDIF ; MVI B,8 ;MOVE THE DATE TO A HOLD AREA LXI D,DATE ;TO "DATE" CALL MOVE LXI D,DESTMSG ;GET DESTINATION DRIVES CALL QUESTION ORA A JZ LOGICQUS ;DEFAULT LDA INREC STA BACKUPDRV LOGICQUS LDA NODRV LXI H,DRIVES ;FORMAT THE QUESTION FOR WHICH DRIVES TO SHIFT1 INX H ;(HARD DISK DRIVES) TO BACKUP LL AUTOMATICALLY SCAN THE THREE HARD DISKS AND FINISH WITHOUT ;* EVER ASKING FOR THE DRIVE ID. ;* ;* THE DUMMYFCB SETS UP A SKELETON TO READ ALL FILES ON THE DIRECTORY ;* 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 LXI D,EXTRMSG CALL OUTPUT LXI H,DRIVES ;GET ADDRESS OF THE DRIVE TABLE SHLD ADDR1 ;TO SCAN LDA NODRV ;SET UP COUNTER FOR THE NUMBER TO SCAN INR A STA MAX1 NEXTDRV LDA MAX1 ;SEE IF THERE ARE MORE DRIVES TO SCAN DCR A ble correctly under ASM.COM ; Dana Cotant \\\ Micro Cornucopia ; PO Box 223 Bend, OR 97709 ; ; ;* WRITTEN BY GARY YOUNG, BOX 3218, NO. HOLLYWOOD, CA 91609 ; ;TITLE '*** HARD DISK BACKUP PROGRAM ***' ORG 100H JMP START DB 'COPYRIGHT 1980, G. YOUNG, INC.' TRUE EQU 0FFH FALSE EQU 0 CLOCK EQU FALSE DEBUG EQU FALSE RECSIZE EQU 12 ;RECORD SIZE AS FOLLOWS ; TYPE = 3 BYTES ; FILE = 8 BYTES ; DISKID = 1 BYTES IDSIZE EQU 1 ;ID NOW MEANS A:, B:, C:, ETC LINESPAGE EQU 66 ;LI NOMORE CALL SORT ;SORT THE MEMORY TABLE BY TYPE, FILE ;NAME, THEN DISK ID MVI A,RECSIZE ;SETUP TO REMOVE DUPLICATE ENTRIES STA COMPSIZE ;COMPARE ON ALL CHAR CALL KILLDUPS ;REMOVE DUPLICATE ENTRIES LDA RESTART CPI 20H CZ REPORT ;PRINT ALL ENTRIES MVI A,11 ;REMOVE FILES THAT ARE ON MULTIPLE DISKS STA COMPSIZE CALL KILLDUPS LDA RESTART CPI 20H CNZ POSITION ;POSITION LIST FOR A RESTART CALL SELECT ;RESTRICT THE FILES TO BACKUP MSG3 LXI D,BACKQUS ;ASK IF YOU WANT BACKUP FU   STA MAX1 ;RETURN WHEN ALL HAVE BEEN SCANNED RZ LHLD ADDR1 ;GET ADDRESS OF DRIVE TABLE MOV A,M ;GET DRIVE CHARACTER STA RDISK ANI 0FH ;CONVERT A=1...P=15 STA DUMMYFCB ;SET IN DR OF DUMMYFCB INX H ;SET FOR NEXT READ OF DRIVE TABLE SHLD ADDR1 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 JZ NEXTDRV ;NO MORE ENTRIES ON THIS DRIVE JMP GETFCB ;EXTRACABORT RET ;THIS ROUTINE IS USED TO POSITION THE LIST OF FILES FOR A RESTART POSITION LXI D,POSMSG CALL OUTPUT LXI H,RESTART+8 ;CONVERT FILE NAME TO TYP.FILENAME LXI D,REPO MVI B,3 CALL MOVE LXI H,RESTART LXI D,REPO+3 MVI B,8 CALL MOVE LXI H,RAM-RECSIZE ;SETUP FOR COMPARES SHLD ADDR1 NE1 LHLD ADDR1 LXI D,RECSIZE DAD D SHLD ADDR1 CNXT MOV A,M CPI 1AH ;EOF ON LIST? JZ LBU LHLD ADDR1 LXI D,REPO MVI B,11 CALL COMPARE JZ LBU LHLD ADDR1 LXI D,RECSIZSTRIP 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 FOet length push h ; ..it too div: xra a ; m1=m1/2 lhld m1 mov a,h rar mov h,a mov a,l rar mov l,a shld m1 ; save new m1 ; ora h ; check if done jnz ndon pop b ; finished pop d ; ..so return ret ; ...now ; ; set k1=n1-m1 ; ndon: xchg ; m1 to de lhld n1 mov a,l sub e mov l,a mov a,h sbb d mov h,a shld k1 lxi h,1 ; set and save i=j=1 shld j1 shld i1 ; ; calc & save addr offset = m1*i1 ; dcr l pop b ; length of str=i1 push b ; ..put it back lp1:T DATA FROM FCB NEXTFCB LXI D,DUMMYFCB ;GET NEXT ENTRY AFTER THE FIRST MVI C,12H CALL BDOS INR A JZ NEXTDRV ;NO MORE DIRECTORIES ON THIS DISK 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 E DAD D SHLD ADDR2 CALL MOVELIST ;TABLE MOVES DOWN SO ADDR1 IS NOT INCREMENTED LHLD ADDR1 JMP CNXT LBU SHLD ADDR2 RET SORT LXI D,SORTMSG ;PUT OUT A MESSAGE SO THE USER DOES CALL OUTPUT ;NOT THINK THIS CRASHED WHILE SORTING LHLD TABCNT SHLD N1 SHLD M1 LXI H,RECSIZE SHLD K1 LXI H,RAM SHLD J1 CALL SHELLM RET ;FINISHED SORTING ;TITLE 'IN MEMORY SHELL-metzner sort' ;sbttl 'from KILOBAUD april 1981 p164' ; ;remark 'For fixed length records stored in memory ;R 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  dad d dcx b mov a,b ora c jnz lp1 shld ml1 ; xchg ; calc & save d(j), d(i), d(i+m) pop b pop h push h push b lp2: shld dj1 shld di1 xchg dad d xchg ; HL has d(i), DE has d(i+m) ; ; compare strings and switch ; cp1: pop b ; len of string=l1 push b lp3: ldax d ; compare each byte sub m jnz neq ; not equal inx h ; if =, then next byte inx d dcx b mov a,b ora c jnz lp3 jmp nsw ; if done, don't switch ; ; change next instruction to jc for descending ;  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 MOV A,M ;GET THE EXTENT ; IF DEBUG ORI 30H ;DIAGNOSTIC DISPLAY STA RDISK+1 LXI D,RTYPE CALL OUTPUT LDA RDISK+1 ANI 0FH ENDIF ; LXI H,RTYPE ;STRIP OFF THE HIGH BIT SET BY MVI B,11 ;THE VERSION PROGRAM Put no. of records in n1 and m1. The length ;of each record is stored at k1, and the starting ;address at j1. Start sort by calling location ;"entry". To change to descending sort change the ;instruction at neq: to DAH.' ; n1: DW 0 ; number of records m1: DW 0 ; ..same here k1: DW 0 ; length of records j1: DW 0 ; starting address of strings i1: DW 0 ; ptr ml1: DW 0 ; ptr dj1: DW 0 ; ptr di1: DW 0 ;ptr ; SHELLM lhld j1 ; get start address push h ; ..save lhld k1 ; g   neq: jnc nsw ; if d(i)k ; nsw: lhld j1 inx h ; save new j=old j+1 shld j1 shld i1 xchg lhld k1 mov a,l sub e mov a,h sbb d jc div ; if j>k goto beginning and ; ..divide m1 ; ; calc new d(j), d(i) ; lhld dj1 pop d push d dad d ; new d(j)=old d(j+1) xchg lhld ml1 xchg jmp lp2 ; ; that all folks ; ;* REPORT PRINTS THE S (N), OR ; SELECT CERTAIN FILES (S) TO BACK UP. IF THE SELECT OPTION IS ; CHOSEN, EACH FILE NAME WILL BE PRINTED AND YOU BE ASKED TO ; BACK UP THE FILE (Y), IGNORE THE FILE DURING THE BACKUP ; (N), OR CONTINUE (C) TO BACKUP ALL OF THE REMAINING FILES ; WITHIN THIS TYPE WITHOUT ASKING ANY FURTHER NAMES (USED FOR ; RESTART). AFTER THE LIST HAS BEEN REDUCED, IT WILL BE LISTED ; BEFORE THE BACKUP ACTUALLY BEGINS. KILLDUPS EQU $ ;KILL DUPLICATE ENTRIES FROM MULTIPLE EXTENTS LXI D,KILLMSG CALL O LOOKING CODE FIXES DCR A ;THE LINE COUNT FOR THE THE THREE JZ NEWPAGE ;LINE FEEDS AFTER A NEW TYPE DCR A JZ NEWPAGE DCR A JZ NEWPAGE STA LINECNT LXI D,CRLFLFLF ;HERE ARE THOSE LINEFEEDS CALL LIST JMP CHKTYPE NEWPAGE CALL HEADING CHKTYPE LXI D,LASTTYPE ;SET LAST TYPE TO CURRENT TYPE LHLD ADDR1 MVI B,3 CALL MOVE SETCNT MVI A,RECLINE+1 STA MAX2 JMP PRNTNOW NEWLINE LXI D,CRLF CALL LIST LDA LINECNT DCR A STA LINECNT JZ NEWPAGE ;PAGE FULL JMP SETCNT TOPPAGE RET HE END OF THE TABLE CPI 1AH ;CNTL-Z IS AT END JZ LISTBKUP ;LIST THE FINAL TABLE LXI D,LASTTYPE ;SEE IF THE CURRENT TYPE IS THE LHLD ADDR1 ;LAST TYPE MVI B,3 CALL COMPARE JZ CHKSELECT ;TYPES MATCH, CHECK FILE SELECT CALL MOVE ;TYPES DON'T MATCH, MAKE THE ;LAST TYPE = CURRENT TYPE NOW LDA NOSKIP INR A MOV C,A ;SEE IF THE NEW TYPE IS IN THE LXI D,SKIPTYPE ;LIST OF FILE TYPES TO SKIP MVI B,3 NEXTSKIP DCR C ;DECREMENT NO OF FILES TO SKIP JZ FORMQUS ;FILE ORTED CONSOLIDATED DIRECTORY ENTRIES. ;* LINESPAGE IS THE NUMBER OF LINES PER PAGE AND RECLINE IS THE ;* NUMBER OF 20 BYTE ENTRIES PER LINE. EACH TYPE IS SEPERATED BY ;* THREE LINEFEEDS. REPORT LXI D,RPTMSG CALL OUTPUT LHLD TABCNT ;SET COUNT OF ENTRIES INX H ;PLUS ONE SHLD LASTTYPE ;INIT LASTTYPE TO INVALID DATA SHLD MAX1 ;TO DECREMENT FIRST LXI H,RAM-RECSIZE ;SET STARTING ADDRESS SHLD ADDR1 CALL HEADING NEXTPRT LHLD ADDR1 LXI D,RECSIZE ;SET TO ADD THE REC LENGTH DADUTPUT LXI H,RAM SHLD ADDR1 ;SET THE START OF THE TABLE NEXTEQUAL LHLD ADDR1 ;CHECK EACH ENTRY AGAINST THE NEXT LXI D,RECSIZE DAD D SHLD ADDR2 NEXTCHK MOV A,M ;CHECK FOR END OF TABLE CPI 1AH RZ XCHG LHLD ADDR1 ;COMPARE ADDR1 WITH ADDR2 LDA COMPSIZE MOV B,A CALL COMPARE JNZ SAVELAST PUSH H ;SAVE CURRENT POSITION LHLD ADDR2 ;SET UP FOR MOVING LIST SHLD ADDR1 ;DOWN ONE ENTRY LXI D,RECSIZE DAD D ;MOVE THIRD ENTRY TO THE SECOND SHLD ADDR2 CALL MOVELIST LH  IS GOOD LHLD ADDR1 CALL COMPARE JZ SKIPALLTYPE ;FILE WAS ON THE SKIP LIST INX D ;INCREMENT TO NEXT SKIP FILE INX D INX D JMP NEXTSKIP FORMQUS LXI D,QTYPE ;FORM THE QUESTION ABOUT WHETHER LHLD ADDR1 ;TO SKIP THIS FILE TYPE OR NOT MVI B,3 ;MOVE THE FILE TYPE TO THE CALL MOVE ;QUESTION PRINT LINE XRA A STA SELFLAG ;RESET THE SELECT FLAG REASK1 LXI D,QUEST1 CALL QUESTION ;ASK THE QUESTION ABOUT THE TYPE CPI 1 ;ONE CHARACTER RESPONSE ALLOWED JNZ REASK1 LDA INRECL COMPARE RNZ JMP FINDIT ;ADDR2 WILL HAVE THE ADDRESS OF ;THE NEXT TYPE WHEN FINISHED LISTBKUP EQU $ ;LIST THE FILES TO BE BACKED SHLD ADDR2 ;SAVE THE END OF THE TABLE FOR LATER LXI H,RAM-RECSIZE SHLD ADDR1 ; IF DEBUG ;PRINT LIST ONLY IF DEBUGGING CALL HEADING2 NEXTONE LHLD ADDR1 ;PRINT THE NEXT TABLE ENTRY LXI D,RECSIZE DAD D SHLD ADDR1 ;INCREMENT TO THE NEXT ENTRY MOV A,M ;CHECK FOR THE END OF THE CPI 1AH ;TABLE RZ CALL FORMAT ;FORMAT ENTRY LXI D,PRN ONE CALL MOVELIST ;MOVES THE LIST DOWN FROM ADDR1 ;TO ADDR2 LHLD ADDR1 JMP CHKNEXT ;CHECK NEXT ENTRY CHKSELECT LDA SELFLAG ;CHECK THE SELECT FLAG ORA A ;IF NOT ZERO, ASK THE QUESTION JNZ ASKFILE ;ABOUT EACH FILE JMP NEXTENTRY SKIPALLTYPE CALL FINDTYPE ;FIND THE NEXT TYPE NOT MATCHING CALL MOVELIST ;THIS ONE AND MOVE THE LIST DOWN LHLD ADDR1 JMP CHKNEXT ;TO SKIP THIS TYPE SAVEALLTYPE CALL FINDTYPE ;SAVE ALL OF THIS TYPE LHLD ADDR2 ;RESET THE ADDRESS TO THE NEXT SHE FILE. BLANK 1024 BYTE SECTORED DISKS SHOULD BE ;* USED FOR BEST PERFORMANCE. WHEN ONE DISKETTE IS FULL, IT WILL ;* PROMPT FOR A NEW ONE SO MANY DISKETTES CAN BE USED TO BACKUP ;* THE HARD DISKS. IF IT IS NECESSARY TO ABORT DURING THIS PROCESS, ;* USE THE RESTART CAPABILITY PROVIDED IN "SELECT". THE AREA ;* FOR THE DISK BUFFER IS ALL OF RAM FROM THE END OF THE TABLE ;* TO THE START OF BDOS. BACKUP EQU $ CALL TOPOFFORM LHLD ADDR2 ;GET THE CURRENT END OF TABLE INX H ;PLUS ONE FOR THE STA ;GET THE RESPONSE CPI 'N' JZ SKIPALLTYPE CPI 'Y' JZ SAVEALLTYPE CPI 'S' ;S=SELECT CERTAIN FILES FROM THIS JNZ REASK1 ;TYPE MVI A,1 ;SET THE SELECT FLAG STA SELFLAG ;TO ASK THE NEXT QUESTION ASKFILE LHLD ADDR1 ;FORMAT A QUESTION TO ASK IF THIS LXI D,QTYPE2 ;PARTICULAR FILE IS TO BE SAVED MVI B,3 CALL MOVE LXI D,QFILE2 ;MOVE THE FILE NAME TO THE QUESTION INX H INX H ;POSITION PAST THE FILE TYPE INX H ;IN THE TABLE MVI B,8 CALL MOVE ;MOVE THE NAME LXI DTREC CALL LIST ;PRINT IT LDA MAX2 ;SEE MORE WILL FIT ON THIS LINE DCR A STA MAX2 JZ LINEFULL JMP NEXTONE LINEFULL LXI D,CRLF CALL LIST LDA LINECNT DCR A STA LINECNT JZ PAGEFULL JMP SETLINE PAGEFULL CALL HEADING2 MVI A,LINESPAGE STA LINECNT SETLINE MVI A,RECLINE STA MAX2 JMP NEXTONE HEADING2 LXI D,HEAD2 CALL LIST LXI D,CRLF CALL LIST MVI A,LINESPAGE STA LINECNT MVI A,RECLINE STA MAX2 ENDIF ; RET ; ; ; ;* BACKUP IS USED TO BACKUP THE FILES IN THE LD ADDR1 ;TYPE JMP CHKNEXT MOVELIST LHLD ADDR2 ;MOVE THE TABLE FROM ADDR2 DOWN XCHG ;TO ADDR1 THEREBY ELIMINATING LHLD ADDR1 ;UNWANTED ENTRIES MOVENEXT LDAX D ;AND MAKING MORE ROOM FOR THE MOV M,A CPI 1AH RZ INX H INX D JMP MOVENEXT FINDTYPE LHLD ADDR1 ;FIND THE NEXT ENTRY SHLD ADDR2 ;WITH A TYPE DIFFERENT FINDIT LHLD ADDR2 ;THAN THE CURRENT TYPE LXI D,RECSIZE DAD D SHLD ADDR2 MOV A,M ;STOP AT END OF THE TABLE CPI 1AH RZ XCHG LHLD ADDR1 MVI B,3 CALRT OF THE SHLD ADDR3 ;READ/WRITE BUFFER LXI H,RAM ;SET THE ADDRESS OF THE FIRST ENTRY SHLD ADDR1 LXI D,RECSIZE ;SET AN ADDRESS FOR THE SECOND ENTRY DAD D ;NEXT ENTRY = CURRENT + RECSIZE SHLD ADDR2 ;LATER, USE MOVELIST TO MOVE THE LIST ;DOWN FROM ADDR2 TO ADDR1 AFTER EACH FILE ;HAS BEEN COPIED. THIS IS SO THAT THE ;RAM BUFFER WILL EXPAND AS THE FILES ARE ;COPIED SO THAT COPYING WILL BE FASTER. CALL MOUNT JMP PASSMOVE NEXTFILE EQU $ CALL MOVELIST INX H ;NEW START,8 ;POSITION PAST NAME TO THE DAD D ;DISK ID LXI D,QDISK2 ;MOVE THE DISK ID MVI B,IDSIZE CALL MOVE REASK2 LXI D,QUEST2 ;ASK THE FILE QUESTION CALL QUESTION CPI 1 ;ONLY A 1 CHAR RESPONSE ALLOWED LDA INREC JNZ REASK2 CPI 'C' ;CONTINUE WITH THE REST OF THE JZ SAVEALLTYPE ;FILES WITHIN THIS TYPE - RESTART CPI 'Y' ;SAVE THIS PARTICULAR FILE JZ NEXTENTRY CPI 'N' JNZ REASK2 LHLD ADDR1 ;SHORTEN THE LIST BY ONE ENTRY LXI D,RECSIZE DAD D SHLD ADDR2 ;SKIP THE LASTCREATED LIST. IT ;* WILL NOT BACK UP ANY FILE THAT WILL NOT FIT ON ONE DISK ENTIRELY. ;* THE FILES THAT IT BACKS UP WILL COME FROM ANY OF THE HARD DISKS, ;* BUT NOT NECCESSARILY IN DISK ORDER, BUT RATHER ALPHABETICAL FILE ;* NAME ORDER. IT WILL PROMPT FOR THE FLOPPY DISK ID AND PRINT A ;* REPORT SHOWING THE FLOPPY ID AND THE FILES COPIED FOR INDEX. ;* IF THE FILE WILL NOT FIT ON A DISK, IT WILL BE DELETED FROM THE ;* DISK, THAT DISK CLOSED AND REMOVED, AND PROMPTED FOR A NEW DISK ;* TO RECEIVE TH   OF READ/WRITE BUFFER SHLD ADDR3 XRA A ;RESET THE FLAG FOR FILES TOO BIG STA TOOBIG ;TO FIT ON ONE FLOPPY PASSMOVE LXI H,RAM ;THE TABLE SHRINKS SO THE CURRENT ;ENTRY IS ALWAYS AT "RAM" BUT THE ;READ/WRITE BUFFER GROWS MOV A,M CPI 1AH JZ DISMOUNT ;FINISHED FORMFCB LXI D,HDFCB ;CLEAR THE FCB MVI B,36 XRA A ZEROFCB STAX D INX D DCR B JNZ ZEROFCB LXI H,RAM ;GET ADDRESS OF TABLE ENTRY LXI D,HDTYPE ;MOVE IN THE TYPE MVI B,3 CALL MOVE INX H INX H ;POSITION TO NA LXI D,CRLF ;GO TO NEW LINE CALL LIST MVI A,RECLINE STA MAX2 RET HEADING3 LXI D,CRLFLFLF ;INDEX HEADING NOT AT TOP OF FORM CALL LIST LXI D,IDISKNO ;MOVE THE DISK ID NO TO HEADING LXI H,VOLSER MVI B,3 CALL MOVE LXI D,IDATE LXI H,DATE MVI B,8 CALL MOVE LXI D,INDEX CALL LIST LXI D,CRLF CALL LIST MVI A,RECLINE STA MAX2 MVI A,LINESPAGE STA LINECNT RET TOPOFFORM MVI E,0CH ;POSITION PRINTER TO TOP OF FORM MVI C,5 JMP BDOS MOUNT CALL BELL LXI D,MNTMSG M CALL PRINTFILE ;WRITE FILE NAME ON INDEX LIST JMP NEXTFILE DISKFULL LXI D,FPFCB MVI C,13H ;DELETE FILE ON FLOPPY CALL BDOS MVI C,23H ;GET FILE SIZE LXI D,HDFCB CALL BDOS ;SEE IF IT IS TOO BIG TO FIT ON A FLOPPY LDA HDFCB+34 ;GET THE HIGH ORDER BYTE OF THE FILE SIZE ANI 0F8H ;SEE IF THE FILE IS > 256K JNZ HUGE ;YEP, TOO BIG FOR SINGLE DENSITY FLOPPY CALL MOUNT ;NO, JUST MOUNT ANOTHER FLOPPY JMP FORMFCB HUGE LXI D,BIGMSG ;YES, SECOND FLOPPY. SEND MESSAGE CALL LIST ;WARNIA JZ MOUNT ;DISK FULL? LXI D,FPFCB MVI C,10H ;CLOSE THE FILE CALL BDOS RET LOADBUFF EQU $ ;THIS ROUTINE LOADS AS MUCH OF LXI H,0000 ;MEMORY WITH THE FILE AS POSSIBLE SHLD MAX1 LHLD ADDR3 ;NEW TOP OF TABLE +2 SHLD TEMP XRA A STA EOF ;CLEAR EOF FLAG LOADNEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,HDFCB ;READ HARD DISK MVI C,14H CALL BDOS ORA A JNZ HDEOF ;EOF? LHLD MAX1 INX H ;INCREMENT RECORD COUNT SHLD MAX1 LHLD TEMP ;SEE IF NEXTME 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 MOV A,M ANI 0FH ;CONVERT A=1...P=15 STA HDFCB LXI D,FPFCB ;COPY THE HDFCB TO THE FLOPPY FCB LXI H,HDFCB MVI B,36 CALL MOVE LDA BACKUPDRV ;SET THE RECEIVING FLOPPY DRIVE NUMBER ANI 0FH ;CONVERT D: TO 4 STA FPFCB LXI D,HDFCB ;OPEN THE HD FILE MVI C,0FH CALL BDOS ;OPEN THE INPUT FILE INR A JZ NOTFOUND LXI D,FPFCB ;DELETE THE FILE ON FLOPPY IF IT MVI C,1CALL QUESTION CPI 3 JNZ MOUNT LXI H,INREC LXI D,ENDLIT MVI B,3 CALL COMPARE JZ FINISHED LXI D,VOLSER LXI H,INREC MVI B,3 CALL MOVE ;MOVE VOLSER ID TO VOLSER MVI C,0DH ;DO A SYSTEM RESET TO CHANGE DISKS CALL BDOS ERA LXI D,ERASE CALL QUESTION CPI 1 JNZ ERA LDA INREC CPI 'N' JZ NOERA CPI 'Y' JNZ ERA LDA BACKUPDRV ANI 0FH STA DUMMYFCB MVI C,13H LXI D,DUMMYFCB CALL BDOS ;DELETE ALL FILES ON FLOPPY NOERA EQU $ CALL HEADING3 LXI D,FPFCB ;CLEAR THE FNG THAT THIS FILE CANNOT LXI H,RAM CALL FORMAT ;BE BACKED UP WITH THIS PROGRAM LXI D,PRNTREC CALL LIST ;PRINT THE FILE NAME ALSO JMP NEXTFILE NOTFOUND LXI H,RAM CALL FORMAT LXI D,NFMSG CALL OUTPUT LXI D,PRNTREC CALL OUTPUT RET DISMOUNT CALL BELL LXI D,DMNTMSG ;DISMOUNT FLOPPY CALL QUESTION CALL TOPOFFORM RET ;* ASSORTED ROUTINES PRINTFILE CALL FORMAT LXI D,PRNTREC ;PRINT THE FILE ENTRY CALL LIST LDA MAX2 DCR A STA MAX2 ;ENTRIES PER LINE COUNTER RNZ  RECORD WOULD EXCEED THE LXI D,128 ;TPA AREA DAD D SHLD TEMP DAD D ;WILL THE NEXT RECORD OVERWRITE BDOS? XCHG LHLD BDOS+1 ;FIND THE TOP OF MEMORY CALL COMPREG ;COMPARE REGISTERS RC ;RETURN IF MEMORY ALREADY FULL JMP LOADNEXT ;GET ANOTHER RECORD HDEOF MVI A,1 ;SET FILE EOF STA EOF RET BELL EQU $ MVI C,9 LXI D,MSG CALL BDOS BEEP MVI C,2 ;07H ON CRT MVI E,07H CALL BDOS MVI C,0BH CALL BDOS ;GET CONSOLE STATUS ORA A JZ BEEP MVI C,01 CALL BDOS ;GET THE 3H ;EXISTS CALL BDOS LXI D,FPFCB ;CREATE THE FILE ON FLOPPY MVI C,16H CALL BDOS ;MAKE FILE INR A JZ DISKFULL LXI H,RAM CALL FORMAT LXI D,PRNTREC CALL OUTPUT COPYLOOP CALL LOADBUFF ;LOAD MEMORY WITH FILE CALL WRITEBUF ;WRITE MEMORY FILE LDA EOF ;DISPLAY THE STATUS ADI 30H MOV E,A ;CONSOLE OUTPUT MVI C,2 CALL BDOS 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 LXI H,RACB TO CREATE A FILE NAME MVI B,36 XRA A CLRFCB STAX D INX D DCR B JNZ CLRFCB LDA BACKUPDRV ;SET UP THE DRIVE AS THE BACKUP ANI 0FH ;CONVERT D: TO 4 STA FPFCB LXI H,DATE ;CREATE A NULL FILE WITH THE DATE AS LXI D,FPFCB+1 ;THE FILE NAME AND THE 3 DIGIT MVI B,8 CALL MOVE LXI H,VOLSER ;3 DIGIT VOLSER AS THE FILE TYPE LXI D,FPFCB+9 MVI B,3 ;THIS FILE WILL BE USED TO IDENTIFY CALL MOVE ; THE DISK AND MARK THE DATE LXI D,FPFCB MVI C,16H ;CREATE THE FILE CALL BDOS INR   DUMMY CHAR RET MSG DB 0DH,0AH,0AH,'PRESS ANY KEY TO CONTINUE' DB 0DH,0AH,0AH,'$' WRITEBUF EQU $ ;WRITE FROM THE MEMORY BUFFER LHLD ADDR3 SHLD TEMP LHLD MAX1 ;ALLOW FOR FILES THAT HAVE NO LXI D,0000 ;RECORDS SUCH AS RESTART CALL COMPREG RZ WRITENEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,FPFCB MVI C,15H ;WRITE SEQUENTIAL CALL BDOS ORA A JNZ FPFULL ;FLOPPY DISK FULL LHLD MAX1 ;DECREASE RECORD COUNT DCX H SHLD MAX1 LXI D,0000 ;CHECK FOR NK ; THIS ROUTINE READS THE COMPUTIME CLOCK AND FORMATS THE TIME AND DATE GETDATE EQU $ MVI A,16 ;RAISE THE HOLD SIGNAL OUT C2 MVI A,50 ;DELAY AT LEAST 50 MILLISECONDS WAIT50 DCR A JNZ WAIT50 LXI H,DATETIME ;SET MESSAGE START. NOTE 1ST CHAR IS SPACE MVI A,42 ;GET MONTH TENS CHAR CALL GETTIME MVI A,41 ;GET MONTH UNITS CHAR CALL GETTIME INX H ;SKIP SLASH MVI A,40 ;GET DAY TENS CHAR CALL GETTIME ANI 0F3H ;DROP LEAP YEAR INDICATOR MOV M,A MVI A,39 ;GET DAY UNITS CHAR C IN THAT LIST GOES TO THE PUSH D ; LIST DEVICE AND OUTPUT GOES LIST1 LDAX D ; TO THE CONSOLE DEVICE CPI '$' JZ LIST2 INX D PUSH D MOV E,A MVI C,5 CALL BDOS POP D JMP LIST1 LIST2 POP D POP B POP H RET QUESTION CALL OUTPUT ;PUT OUT THE QUESTION LXI D,INBUF MVI C,0AH ;INPUT THE REPLY CALL BDOS LDA INCNT ;SEE IF ANYTHING WAS ENTERED RET MOVE PUSH H ;MOVE DATA POINTED TO IN HL PUSH D ;TO THE AREA POINTED TO IN DE PUSH B ;BY THE BYTE COUNT IN B MOVE1 MOV  ERASE DB 'ERASE FLOPPY DISK FIRST (Y/N)? $' TABFULL DB 'MEMORY FULL...REPORT NOT COMPLETE$' BACKQUS DB 'BEGIN BACKUP PROCEDURE (Y/N)? $' SORTMSG DB 'SORTING...$' RPTMSG DB 'PRINTING REPORTS...$' EXTRMSG DB 'EXTRACTING DIRECTORY...$' POSMSG DB 'POSITION FOR RESTART...$' KILLMSG DB 'REMOVING DUPLICATES...$' NFMSG DB 'FILE NOT FOUND...ABORTING$' DMNTMSG DB 'DISMOUNT BACKUP DISK AND ENTER RETURN$' MNTMSG DB 'MOUNT DISKETTE FOR BACKUP AND ENTER ' DB '3 CHAR DISK ID OR "END": $' ENDLIT DB 'END' VOO MORE TO WRITE CALL COMPREG RZ LHLD TEMP LXI D,128 ;INCREMENT WRITE ADDRESS DAD D SHLD TEMP JMP WRITENEXT FPFULL MVI A,2 ;FULL DISKETTE STA EOF RET FORMAT LXI D,PRNTYPE ;FORMAT THE ENTRY FROM THE TABLE MVI B,3 ;FORMAT TO THE PRINT FORMAT CALL MOVE ;THE TABLE ADDRESS IS ASSUMMED TO BE LXI D,3 ;IN HL. FIRST MOVE THE TYPE DAD D ;NOW POSITION TO THE FILE NAME LXI D,PRNFILE ;MOVE THE FILE NAME MVI B,8 CALL MOVE LXI D,8 ;POSITION TO THE DISK ID DAD D LXI D,PRNTRECALL GETTIME INX H ;SKIP SLASH MVI A,44 ;GET YEAR TENS CHAR CALL GETTIME MVI A,43 ;GET YEAR UNITS CHAR CALL GETTIME INX H ;SKIP BLANK MVI A,37 ;GET HOUR TENS CHAR CALL GETTIME ANI 0F3H ;DROP AM/PM AND 24HR INDICATORS MOV M,A MVI A,36 ;GET HOUR UNITS CHAR CALL GETTIME INX H ;SKIP COLON MVI A,35 ;GET MINUTES TENS CHAR CALL GETTIME MVI A,34 ;GET MINUTES UNITS CHAR CALL GETTIME INX H ;SKIP COLON MVI A,33 ;GET SECONDS TENS CHAR CALL GETTIME MVI A,32 ;GET SEA,M ANI 7FH ;RESET THE HIGH ORDER BIT BECAUSE IT ;MAY HAVE BEEN TURNED ON FOR THE TYPE STAX D INX H INX D DCR B JNZ MOVE1 POP B ;RESTORE THE TOTAL ENVIRONMENT POP D POP H RET COMPARE PUSH H ;COMPARE THE STRINGS POINTED TO IN HL PUSH D ;TO THE STRING POINTED TO IN DE PUSH B ;FOR A LENGTH OF B CHARACTERS COMP1 LDAX D ; JC IF HL > DE CMP M ; JZ IF HL = DE JNZ COMP2 ;JNC IF HL < DE INX H INX D DCR B JNZ COMP1 COMP2 POP B POP D POP H RET ; ; IF CLOCLSER DS 3 QUEST1 DB 'BACKUP ALL FILES OF TYPE ' QTYPE DS 3 DB ', (Y/N/S)? $' QUEST2 DB 'BACKUP FILE NAMED ' QDISK2 DS 1 DB ':' QFILE2 DS 8 DB '.' QTYPE2 DS 3 DB ', (Y/N/C)? $' HEAD2 DB 0CH,'THE FOLLOWING FILES WILL BE COPIED TO DISKETTES$' PRNTREC DS 1 DB ':' PRNFILE DS 8 DB '.' PRNTYPE DS 3 DB ' $' CRLFLFLF DB 0DH,0AH,0AH,0AH,'$' INDEX DB 'THE FOLLOWING FILES ARE ON DISKETTE NO. ' IDISKNO DS 3 DB ' AS OF ' IDATE DS 8 DB '$' CRLF DB 0DH,0AH,'$' HEAD1 DB 0CH,'CONSOLIDATED ;MOVE THE DISK ID TO THE LINE MVI B,IDSIZE CALL MOVE RET COMPREG MOV A,H ;COMPARE HL TO DE CMP D RNZ MOV A,L CMP E RET OUTPUT PUSH D ;PUT OUT A CRLF LXI D,CRLF MVI C,09 CALL BDOS POP D ;NOW PUT OUT THE MESSAGE OUT1 MVI C,09 JMP BDOS HEADING LXI D,HEAD1 CALL LIST LXI D,DATE CALL LIST LXI D,TABFULL LDA ABORT ORA A CNZ LIST MVI A,LINESPAGE STA LINECNT LXI D,CRLF CALL LIST LXI D,CRLF JMP LIST LIST PUSH H ; THIS DIFFERS FROM OUTPUT PUSH B ;CONDS UNITS CHAR CALL GETTIME XRA A OUT C2 ;LOWER HOLD SIGNAL RET C1 EQU 254 ;CLOCK ADDRESS PORT C2 EQU 253 ;CLOCK DATA OUTPUT PORT GETTIME INX H ;ADVANCE TO NEXT PRINT POSITION OUT C1 MVI A,6 ;DELAY AT LEAST 6 MILLISECONDS WAIT6 DCR A JNZ WAIT6 IN C1 ORI 30H ;CONVERT TO ASCII MOV M,A RET DATETIME DB ' 00/00/00 HH:MM:SS$' ENDIF ; SIGNON DB 'HARD DISK CATALOG AND BACKUP ' DB '10/09/82A$' RESTART DS 32 REPO DS 12 DATEMSG DB 'ENTER 8 CHAR DATE FOR REPORTS MM/DD/YY: $'    INDEX BY FILE TYPE AS OF $' DATE DS 8 DB ' $' BIGMSG DB 0DH,0AH,'FILE TOO LARGE TO FIT ON ONE DISKETTE ' DB 'SO NOT BACKED UP **** $' DESTMSG DB 'DESTINATION FLOPPY (DEFAULT=' BACKUPDRV DB 'C) $' HD2BU DB 'LOGICAL HARD DISK DRIVES TO BACKUP (DEFAULT=' DRIVES DB 'ABCDEFGHIJKLMNOP' NODRV DB 2 SKPMSG DB 'FILE TYPES TO SKIP (DEFAULT=' SKIPTYPE DB 'PRNHEXSYMBAKTMP' DS 45 NOSKIP DB 5 HDFCB DS 1 HDFILE DS 8 HDTYPE DS 3 DS 24 FPFCB DS 36 TOP DB 0CH,'$' INBUF DB 60 INCNT DS 1 INREC DS 60  2e ͻ  !   !  j ͻ  ͻ >2>B2  !  , !   (:NPY(:7 277 $Y:7 2 !   !    < !"*"2* *#"*"* â>2   PRESS * "6*#"**  Ҟ>2 ͅ !5 M  !- P  !W"* "~ʂ*M  ʂ* "H*[" ͅ *""! "!c"͵***|g}o"*}o|g"!""- x"""# xMMFwx# x*|/W}/_*M#"**{ozg"*#""*}|ڽ** ͅ *#""!W"͔ * "*+" * :=2^ R ͻ É:===2e ͻ ͔ * >2ñ ͻ :TTE SO NOT BACKED UP **** $DESTINATION FLOPPY (DEFAULT=C) $LOGICAL HARD DISK DRIVES TO BACKUP (DEFAULT=ABCDEFGHIJKLMNOPFILE TYPES TO SKIP (DEFAULT=PRNHEXSYMBAKTMPA$ $ CONSOLIDATED INDEX BY FILE TYPE AS OF $UP ALL $ FILE TOO LARGE TO FIT ON ONE DISKETTE SO NOT BACKED UP **** $2]  T  R  |}    ͻ  ͻ  :Ļ >B2 ͻ  û $ _þ ͅ  :~#  # HARD DISK CATALOG AND BACKUP 10/09/82A$ X *+" *"( >ENTER 8 CHAR DATE FOR REPORTS MM/DD/YY: $ERASE FLOPPY DISK FIRST (Y/N)? $MEMORY FULL...REPORT NOT COMPLETE$BEGIN BACKUP PROCEDURE (Y/N)? $SORTING...$PRINTING REPORTS..=22 ͅ !c"* "~*:bG S*" "H*+""*"!W""* "~z* & : 2*   ###    :C<YeN* "H*o:eYH*oY*"o**w#O*"* "~* _"!W"*#"!c" "ìH#"2!c~ʘ $»!c  ###  ~2  ! $ :7 2  <ʅ!COPYRIGHT 1980, G. YOUNG, INC.1!c"!"22 ͅ !]-  Y H!  n:27 :w !g #=t6)#6 #6$; ʘ2w G!g : G! #=¡6)#6 #6$x 2 ! G : ===x2 \: ͅ ͆> 2b :- p> 2b :- /\ :N,Ÿ́ ͻ ???????????? ͅ !g ":w <2:=2*~227#"7BACKUP LOAD.COM  MVI A,'$' ;CREATE A TEMPORARY FILE STA HDFCB+9 STA HDFCB+10 STA HDFCB+11 LXI H,MSG3A ;MARK AS "RESTORE" IN MESSAGE LXI D,MSG3 MVI B,8 CALL MOVE LXI H,MSG0A LXI D,MSG0 ;CHANGE THE PROMPT MESSAGE MVI B,10 CALL MOVE LXI D,HDFCB ;SEE IF THE TEMP FILE IS THERE ON MVI C,0FH ;THE HARD DISK CALL BDOS INR A JZ MAKEHD LXI D,HDFCB ;DELETE IT IF IT IS MVI C,13H CALL BDOS MAKEHD LXI D,HDFCB ;MAKE THE HARD DISK FILE MVI C,16H CALL BDOS LXI D,ERROR4 ;ERROR IF DIRECTOR. BACKUPDRV This is the floppy drive letter that the backup will be copied to. Set to C if you have hard disk drives A and B. NOSKIP This is the number of file types in the file skip list. SKIPTYPE This is the list of file types to skip. It is normally set to PRNHEXSYMBAKTMP to skip those six file types. LINESPAGE This is the number of lines per page and is used to print the various directories. RECLINE This is the number of file names that will appear oRG 100H JMP START DB 'COPYRIGHT 1982, G. YOUNG, INC.' START LXI SP,STACK+80 LDA TFCB+1 ;SEE IF A MASK WAS ENTERED CPI 20H ;BUFFER WILL BE BLANK IF NOT JZ INPUTERR LXI H,TFCB ;SAVE THE INPUT FILE NAME LXI D,HOLDFCB MVI B,16 CALL MOVE LXI D,HOLDFCB+16 MVI B,20 CALL CLEAR LXI H,TBUF ;SEARCH FOR /B OR /R MVI B,80 FINDSLSH MOV A,M CPI '/' JZ BORR INX H DCR B JNZ FINDSLSH INPUTERR LXI D,ERROR1 ERROR CALL OUTPUT JMP BOOT BORR INX H ;NEXT CHAR MUST BE A B OR R MOV; BIGBURST--BIG FILE BACKUP/RESTORE ; COPYRIGHT 1982, G. YOUNG, INC. ; UPDATED 10/9/82 ; ;TO EXECUTE, ENTER THE PROGRAM NAME FOLLOWED BY THE FILE MASK: ;* A>BIGBURST FILENAME.TYP/B (FOR BACKUP) OR ;* A>BIGBURST FILENAME.TYP/R (FOR RESTORE) ;* THE PURPOSE OF THIS PROGRAM IS TO BACKUP AND RESTORE FILES FROM/TO ;* A HARD DISK WHERE THE FILE IS TOO BIG TO FIT ON ONE FLOPPY DISK. ;* IT BACKS UP BY COPYING THE LARGE FILE TO MULTIPLE SMALL FILES ;* WHICH WILL FIT ON THE FLOPPY. THE FILE TYY FULL INR A JZ ERROR LOADFLP CALL GENFCB LOAD2 CALL MOUNT LXI D,FLPFCB ;SEE IF FLOPPY FILE IS ON THAT DISK MVI C,0FH CALL BDOS INR A JNZ OPEN2 ;YES, THE RIGHT ONE IS MOUNTED LXI D,MESSAGE2 ;NO, WRONG DISK IS MOUNTED CALL OUTPUT JMP LOAD2 OPEN2 LXI D,HDFCB+12 ;OPEN THE HARD DISK AGAIN MVI B,24 CALL CLEAR LXI D,HDFCB MVI C,0FH CALL BDOS LHLD RECCNT ;POSITION TO END OF FILE SHLD HDFCB+33 LXI D,HDFCB ;RANDOM READ MVI C,21H CALL BDOS COPYLOOP2 CALL LOADBUFF2 ;ACTUAn one line in the directories. The program can use the COMPUTIME board to get the date, but the code is in the program to request the date from the console. Just change the equate near the beginning of the program to CLOCK EQU TRUE to use the clock specific code. 6/23/82...RESTART CAPABILITY ADDED BY ENTERING BACKUP FILENAME.TYP THE PROGRAM WILL SKIP THE CROSSREFERENCE REPORT AND POSITION THE LIST TO FILENAME.TYP AND REPROMPT FOR FILES TO BACKUP FROM THAT POINT. EXAMPLE A,M CPI 'B' JZ QUEST1 CPI 'R' JNZ INPUTERR QUEST2 LXI D,SRCFLPMSG CALL QUESTION ORA A JNZ QUEST2A LDA SRCFLP JMP QUEST2B QUEST2A LDA INREC QUEST2B STA FLOPPY JMP RESTORE QUEST1 LXI D,DESTFLPMSG CALL QUESTION ORA A JNZ QUEST1A LDA DESTFLP JMP QUEST1B QUEST1A LDA INREC QUEST1B STA FLOPPY JMP BACKUP RESTORE LXI H,TFCB LXI D,HDFCB MVI B,12 ;CREATE A HARD DISK FCB CALL MOVE LXI D,HDFCB+12 MVI B,24 CALL CLEAR LXI H,0000 SHLD RECCNT XRA A STA FILECNT  L COPY IS DONE HERE CALL WRITEBUF2 CALL DEBUG LDA EOF CPI 2 JZ ENDOFFILE2 CPI 1 JZ DISKMPTY JMP COPYLOOP2 ENDOFFILE2 LXI D,HDFCB ;CLOSE HARD DISK MVI C,10H CALL BDOS LXI D,HOLDFCB ;SEE IF THE FILE IS THERE MVI C,0FH CALL BDOS INR A JZ RENAME ;NO, RENAME THE TEMP VERSION AS THE FINAL NAME LXI D,BAKFCB ;SEE IF THERE IS A BACKUP FILE NAME THERE MVI B,36 CALL CLEAR LXI H,HOLDFCB LXI D,BAKFCB MVI B,36 CALL MOVE LXI H,BAK LXI D,BAKFCB+9 MVI B,3 CALL MOVE ;CRLXI D,ERROR3 LDA FILECNT INR A STA FILECNT JZ ERROR ;TOO MANY FLOPPIES MVI H,0 MOV L,A SHLD MPTY LXI D,FLPFCB+9 ;SET FILE TYPE TO SEQUENCE NUMBER LXI H,64H SHLD TEMP2 CALL DIVID2 LXI H,0AH SHLD TEMP2 CALL DIVID2 LDA MPTY ADI '0' STAX D RET DEBUG LHLD RECCNT ;THIS PRINTS THE RECORD # JUST WRITTEN SHLD MPTY ;FOR DEBUG PURPOSES LXI D,DBMSG+2 LXI H,2710H SHLD TEMP2 CALL DIVID2 LXI H,03E8H SHLD TEMP2 CALL DIVID2 LXI H,64H SHLD TEMP2 CALL DIVID2 LXNFCB ;CREATE FLOPPY FCB CALL MOUNT LHLD RECCNT ;POSITION FILE SHLD HDFCB+33 LXI D,HDFCB ;RANDOM READ MVI C,21H CALL BDOS LXI D,FLPFCB ;LOOK FOR FLOPPY NAME MVI C,0FH CALL BDOS INR A JZ MAKEFLOP LXI D,FLPFCB ;DELETE IT IF IT IS THERE MVI C,13H CALL BDOS MAKEFLOP LXI D,FLPFCB ;CREATE THE FILE MVI C,16H CALL BDOS LXI D,ERROR4 INR A JZ ERROR ;DIRECTORY FULL COPYLOOP1 CALL LOADBUFF1 ;DO ACTUAL COPYING HERE CALL WRITEBUF1 CALL DEBUG LDA EOF CPI 1 JZ ENDOBDOS LXI D,HDFCB ;READ HARD DISK MVI C,14H CALL BDOS ORA A JNZ HDEOF ;EOF? LHLD MAX1 INX H ;INCREMENT RECORD COUNT SHLD MAX1 LHLD TEMP ;SEE IF NEXT RECORD WOULD EXCEED THE LXI D,128 ;TPA AREA DAD D SHLD TEMP DAD D ;WILL THE NEXT RECORD OVERWRITE BDOS? XCHG LHLD BDOS+1 ;FIND THE TOP OF MEMORY CALL COMPREG ;COMPARE REGISTERS RC ;RETURN IF MEMORY ALREADY FULL JMP LOADNEXT ;GET ANOTHER RECORD HDEOF MVI A,1 ;SET FILE EOF STA EOF RET WRITEBUF1 EQU $ ;WRITE FREATE THE BACKUP FILE NAME LXI D,BAKFCB ;DELETE IT IF IT IS THERE MVI C,13H CALL BDOS LXI H,BAKFCB LXI D,HOLDFCB+16 MVI B,16 CALL MOVE LXI D,HOLDFCB ;RENAME THE FINAL FILE NAME AS .BAK MVI C,17H CALL BDOS RENAME LXI H,HOLDFCB LXI D,HDFCB+16 ;RENAME THE TEMP FILE TO THE PERMANENT NAME MVI B,16 CALL MOVE LXI D,HDFCB MVI C,17H ;RENAME .$$$ AS .XXX (FINAL NAME) CALL BDOS LXI D,ERROR5 ;FINISHED JMP ERROR DISKMPTY LXI D,FLPFCB ;CLOSE THE CURRENT FLOPPY FILE MVI C,10H CALLI H,0AH SHLD TEMP2 CALL DIVID2 LDA MPTY ADI '0' STAX D LXI D,DBMSG CALL OUTPUT RET DIVID2 PUSH D MVI E,0 LHLD MPTY SHLD TEMP SB22 LXI B,TEMP LXI H,TEMP2 XRA A LDAX B SBB M STAX B INX B INX H LDAX B SBB M STAX B JC NEG2 INR E PUSH H LHLD TEMP SHLD MPTY POP H JMP SB22 NEG2 MOV A,E DIV2 ADI '0' POP D STAX D INX D RET MOUNT LXI H,FLPFCB+1 LXI D,MSG1 MVI B,8 CALL MOVE LXI D,MSG4 CALL MOVE LXI H,FLPFCB+9 LXI D,MSG2 MVI B,3 FFILE1 CPI 2 JZ DISKFULL JMP COPYLOOP1 ENDOFFILE1 LXI D,LASTREC ;ADD END OF ALL FILES RECORD MVI C,1AH CALL BDOS LXI D,FLPFCB MVI C,15H ;WRITE IT CALL BDOS LXI D,FLPFCB MVI C,10H ;CLOSE FLOPPY CALL BDOS LXI D,ERROR5 JMP ERROR ;FINISHED DISKFULL LXI D,FLPFCB MVI C,10H ;CLOSE FLOPPY CALL BDOS JMP CREATEFLP GENFCB LXI D,FLPFCB ;CREATE THE FLOPPY NAME MVI B,36 CALL CLEAR LXI H,HOLDFCB+1 LXI D,FLPFCB+1 MVI B,11 CALL MOVE LDA FLOPPY ANI 0FH STA FLPFCB OM THE MEMORY BUFFER LXI H,ADDR3 SHLD TEMP LHLD MAX1 ;ALLOW FOR FILES THAT HAVE NO LXI D,0000 ;RECORDS SUCH AS RESTART CALL COMPREG RZ WRITENEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,FLPFCB MVI C,15H ;WRITE SEQUENTIAL CALL BDOS ORA A JNZ FPFULL2 LHLD RECCNT INX H SHLD RECCNT LHLD MAX1 ;DECREASE RECORD COUNT DCX H SHLD MAX1 LXI D,0000 ;CHECK FOR NO MORE TO WRITE CALL COMPREG RZ LHLD TEMP LXI D,128 ;INCREMENT WRITE ADDRESS DAD D BDOS LXI D,HDFCB ;CLOSE THE HARD DISK FILE ALSO, WILL OPEN MVI C,10H ;AGAIN LATER, BUT MOUNTING THE NEW FLOPPY CALL BDOS ;REQUIRES A RESET WHICH ASSUMES ALL CLOSED JMP LOADFLP BACKUP LXI H,TFCB LXI D,HDFCB MVI B,12 CALL MOVE LXI D,HDFCB+12 MVI B,24 CALL CLEAR LXI H,0000 SHLD RECCNT LXI D,HDFCB ;MAKE SURE HARD DISK FILE IS THERE MVI C,0FH CALL BDOS INR A JNZ CLEARCNT LXI D,ERROR2 ;FILE NOT FOUND JMP ERROR CLEARCNT XRA A STA FILECNT CREATEFLP CALL GECALL MOVE LXI D,MSG5 CALL MOVE LXI D,MESSAGE1 CALL OUTPUT LXI D,INBUF MVI C,0AH CALL BDOS MVI C,0DH ;RESET THE DISK SYSTEM CALL BDOS RET CLEAR XRA A CLEAR2 STAX D INX D DCR B JNZ CLEAR2 RET ;FOR BACKUP...LOAD FROM HARD DISK, WRITE TO FLOPPY LOADBUFF1 EQU $ ;THIS ROUTINE LOADS AS MUCH OF LXI H,0000 ;MEMORY WITH THE FILE AS POSSIBLE SHLD MAX1 LXI H,ADDR3 SHLD TEMP XRA A STA EOF ;CLEAR EOF FLAG LOADNEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL    SHLD TEMP JMP WRITENEXT FPFULL2 MVI A,2 ;FULL DISKETTE STA EOF RET ;FOR RESTORE, LOAD FROM FLOPPY, WRITE TO HARD DISK LOADBUFF2 EQU $ ;THIS ROUTINE LOADS AS MUCH OF LXI H,0000 ;MEMORY WITH THE FILE AS POSSIBLE SHLD MAX1 LXI H,ADDR3 SHLD TEMP XRA A STA EOF ;CLEAR EOF FLAG LOADNEXT2 LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,FLPFCB ;READ THE FLOPPY MVI C,14H CALL BDOS ORA A JNZ HDEOF2 ;EOF? LHLD TEMP LXI D,LASTREC MVI B,26 ;SEE IF THIS IS P/B OR /R',CR,LF,LF,'$' ERROR2 DB 'FILE NOT FOUND',CR,LF,LF,'$' ERROR3 DB 'NEEDS MORE THAN 255 FLOPPY DISKS',CR,LF,LF,'$' ERROR4 DB 'DIRECTORY FULL',CR,LF,LF,'$' ERROR5 DB 'FINISHED',CR,LF,LF,'$' MSG0A DB 'CONTAINING' BAK DB 'BAK' MSG3A DB 'RESTORE ' LASTREC DB 'ENDENDENDBIGBURSTENDENDEND' MESSAGE1 DB CR,LF,LF,'MOUNT THE DISKETTE ' MSG0 DB 'TO CONTAIN ' MSG1 DS 8 DB '.' MSG2 DS 3 DB ' FOR ' MSG3 DB 'BACKUP ' DB 'AND HIT RETURN$' MESSAGE2 DB CR,LF,'FILE ' MSG4 DS 8 DB '.' MSG5 DS 3  ADDRESS DAD D SHLD TEMP JMP WRITENEXT2 FPFULL MVI A,2 ;FULL DISKETTE STA EOF RET COMPREG MOV A,H ;COMPARE HL TO DE CMP D RNZ MOV A,L CMP E RET OUTPUT PUSH D ;PUT OUT A CRLF LXI D,CRLF MVI C,09 CALL BDOS POP D ;NOW PUT OUT THE MESSAGE OUT1 MVI C,09 JMP BDOS QUESTION CALL OUTPUT ;PUT OUT THE QUESTION LXI D,INBUF MVI C,0AH ;INPUT THE REPLY CALL BDOS LDA INCNT RET MOVE PUSH H ;MOVE DATA POINTED TO IN HL PUSH D ;TO THE AREA POINTED TO IN DE PUS!COPYRIGHT 1982, G. YOUNG, INC.1l:] O!\vͼR!P~/X#D͞#~B}ROͭt:!w:U2sÖ%ͭ:GÐ:U2s!\ ͼR!"t2>$222!mͼ!` ͼ<B DE CMP M ; JZ IF HL = DE JNZ COMP2 ;JNC IF HL < DE INX H INX D DCR B JNZ COMP1 COMP2 POP B POP D POP H RET CRLF DB CR,LF,'$' ERROR1 DB 'INPUT ERROR...ENTER FILENAME.TY!<B2!v"*͘**t#"t*+"͘*"ò>2!"!v"2* THE MEMORY BUFFER LXI H,ADDR3 SHLD TEMP LHLD MAX1 ;ALLOW FOR FILES THAT HAVE NO LXI D,0000 ;RECORDS SUCH AS RESTART CALL COMPREG RZ WRITENEXT2 LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,HDFCB MVI C,15H ;WRITE SEQUENTIAL CALL BDOS ORA A JNZ FPFULL ;FLOPPY DISK FULL LHLD RECCNT INX H SHLD RECCNT LHLD MAX1 ;DECREASE RECORD COUNT DCX H SHLD MAX1 LXI D,0000 ;CHECK FOR NO MORE TO WRITE CALL COMPREG RZ LHLD TEMP LXI D,128 ;INCREMENT WRITE  E*u?*#"*"*͘>2>2!v"*͘*’*t#"t*+"͘*"[>2|}  ͞S :T~#¿# $INPUT ERROR...ENTER FILENAME.TYP/B OR /R $FILE NOT FOUND $NEEDS MORE THAN 255 FLOPPY DISKS $DIRECTORY FULL $FINISHED $CONTAININGBAKRESTORE ENDENDENDBIGBURSTENDENDEND MOUNT THE DISKETTE TO CONTAIN S .T FOR BACKUP AND HIT RETURN$ FILE $INPUT E.ROR IS NOT ON THIS DISKEAK will be deleted. When the restore is successful, it will rename TESTFILE.$$$ as TESTFILE.ASM, but you will still have the original file as a backup if neccessary. The only program modification required is to set the floppy disk drive and reassemble. It is currently set for drive C: as indicated in the line 'FLOPPY EQU 3'. If your floppy is on F: set that to 5, G: = 6, ...A:=1, B:=2, D:=4 etc. The program uses all of available memory as the copy buffer. For diagnostic purposes, the program ple has an indicator that there are no more files to load. To backup a large file, enter BIGBURST TESTFILE.ASM/B Where TESTFILE.ASM is the large file on the hard disk and the "/B" tells the program that this is a BACKUP operation. The program will make sure the file exists on the hard disk, and as you to mount a floppy. It will name the file on floppy 1 as TESTFILE.001, file on floppy 2 as TESTFILE.002, etc until the entire file is copied. To restore the large file, enter#CRC.COM 5.0 6/18/82CRCKFILE???!9" 1 M @ CRC Ver 5.0 CTL-S pauses, CTL-C aborts :] O@ ++Searching for CRCKLIST file++@ Now searching for "CRCKFILE" file++ !  1 .) F!  ͡]͸! ͔0CRCKLIST???CRCKFILE???!9" M à*,*.}|ډ!".*,{z{** u*.".G*.",!".***,}>*.#".ɯ22)! ",". <  NO FILECRC FILE$!   >. @ Checking wiTTE$SOURCE FLOPPY DRIVE (DEFAULT=C) $DESTINATION FLOPPY DRIVE (DEFAULT=C) $ 00000$rints out the record number just copied after copying each buffer. This can be removed be deleting all references to DEBUG.  A>BIGBURST TESTFILE.ASM/R Where TESTFILE.ASM is the large file on the hard disk and the "/R" tells the program that this is a RESTORE operation. The program will then tell you to mount the diskette containing TESTFILE.001. If you enter the wrong diskette, it will tell you to mount the right one. The program creates TESTFILE.$$$ until the entire process is complete. If TESTFILE.ASM already exists on the hard disk, it will be renamed TESTFILE.BAK and any other copies of TESTFILE.Bth file - ! ~T #M M 2 2 2 2 ! >2 3o: : @ ***No CRC Files found***$> ʉ ʉw#: <2 P6: .6@ Can not parse string ! ~ʽT #ñM ! > 6 #6^#6! ~T #! 4M #x] #e w~ T #>2 @ - s M@ File not found ! 4 >2 o: G: „: G: „@ *Match* 2 ! 4@ <-- is, was --> : ) > T : ) M 2 ! 4<2 ~# @ Not a space between CRC values<2 G-CATALOG??? BIGBURST.COM (BIG file BackUp/ReSTore) Copyright 1982, Gary Young, PO Box 3218, North Hollywood, CA 91609 Permission granted to copy for non-commercial and personal use. The purpose of this program is to backup and restore files from a hard disk to floppy disks where the file is too big to fit on one floppy. The program works by copying the big file to multiple files where each file has a sequence number for the file type. The last record of the last fi  @ ++ Now searching for "-CATALOG" file++ !  ) .) ! ”>.”#””͡”››tK››͸›* =: =͔="  ʳ ª~#.  ¿~  #~  .+~#0:0~#!A.O.Gy~#0M0 K MMɷ:m2 FSÄCRCKLIST$$$››tK›, › **}|!"*{z*~]*"Ü  DISK FULL: CRCFILE$!"*~ match - : ̓ : J M @ Quantity of lines failed parse test - : ̓ : ~ M @ Quantity of file(s) not found - : ̓ * d͔  ͔ 0T  Җ Wyʩ 0T 0ztiil Hit Space: KK : k Used: /k Not used: k *% DMf : remain on 1 !9" ! J> # ->! . *ͪe> # < * v K  K  K !B r+s+p+qA ?  p*A *? :]$Ž l]Q !]6 !E 6!C 6 :C *C &l ~2D U¼:E 2 :D S:E 2:D F:E 2:D V:E 2:D P:E 2 :D N2E !*#"ɯ2i2}! "!"]]2 s : ~# ++FILE NOT FOUND++$: F*}’">͇†]<  CANNOT CLOSE CRCFILE$CRCKLISTCRCSK FULL: CRCFILE$  w# !]͐ DONE$!e S!]Q !eZ @ --> FILE: XXXXXXXX.XXX CRC = oS) \<‘@ ++OPEN FAILED++ !" !" * | ʹ) \!~2 #" Ý: ) > T : ) @ ++FILE READ E --> FILE: BACKUP .ASM CRC = FE 46 --> FILE: BACKUP .COM CRC = 10 54 --> FILE: BACKUP .DOC CRC = 46 F9 --> FILE: BIGBURST.COM CRC = 23 B4 --> FILE: BIGBURST.DOC CRC = 93 21 --> FILE: BIGBURST.ASM CRC = 10 8F --> FILE: FLOPCOPY.ASM CRC = 8E B1 --> FILE: FLOPCOPY.COM CRC = F1 3E --> FILE: FLOPCOPY.DOC CRC = D2 C2 --> FILE: MULTCOPY.ASM CRC = D1 38 --> FILE: MULTCOPY.COM CRC = 0B 96 --> FILE: MULTCOPY.DOC CRC = 94 C8 --> FILE: SWEEP .COM CRC = 3C 3C --> FILE: SWEEP Using CRC Type CRC to verify all the files on this disk. Type CRC *.* F to generate CRC's for an entire disk and create a CRC file (CRCKLIST.CRC) for checking the CRC's of a copy of the disk etc. Omitting the F will suppress creation of a CRCKLIST.CRC file. *.* can be replaced with an unambiguous file name for checking just one file. C 4Ø:!4:!5(  ! I3= : [= t:\a:\=_: :] t ?]\ : ҃! 6?Î : 2   ]Q  ?\\ : DM, Q ! "= *3 ##)*= "; */ &# "! *3 #"#  !! "% >!1 . 2' \: 2 : ʩ: ƀo&"* ~ʛ*# +"# ** DMY қ** DM  *; q#p* " . ** #DM*; -e**  *; w* #" )*= *; s#r*; "; : 2 !S 6!"V * "n >!S d*S &T ) ^#V"K O!l ^#V"M :S =2S M K  a*K "G *RROR++ <* |): o% |g}o" 2  ; 0T ~T #~A > T > _h : F{͇2h2|: ʲ !\   :\2 ! \  \ ! \  \! \  \<7=Ɓo&   ]  2h2|2   ~$#~# x  : F} *}= ">͇1 ] FILE: UNSQ .COM CRC = 2E 55 --> FILE: MAKE .COM CRC = 47 C3 --> FILE: MOVE .COM CRC = 0F D9 --> FILE: MDIR .COM CRC = 9C 4E --> FILE: MDIR .ASM CRC = 19 5B --> FILE: D .COM CRC = 66 48 --> FILE: CRC .COM CRC = B2 07 --> FILE: CRC .DOC CRC = E5 81 --> FILE: 15-DISK .DOC CRC = 67 3E --> FILE: U .COM CRC = A3 25 --> FILE: U .ASM CRC = 69 2D  M "I *K  )*= ^#V"O I G  *G )*= N#F*O ? J*G #"G (*I )*= ^#V*O DM? m*I +"I JI G  *G )*= ^#V"Q *I )*= *G )*= N#Fq#p*I )*= *Q s#r*G #"G *I +"I K I  G M   !M G  :S <2S O!T *G s#r*S &l ) *M s#r*I "M ^I K  X:S <2S O!T *K s#r*S &l ) *I s#r*G "K û!" "    #* #" )*= * #" )*= N#Fq#p   * )*= * ) *= ^#VN#F? H * #" )*= ^#V";  *; ^#V" * )*= 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 DI _{ozgO{ozgi`N#Fogo&og_{_z#W OK = Y -S {-_ ! s+p+q*  ͼ 2 <2 : ! ڗ  K ! 4Á ! 6: =! ڻ * & NK ! 4œ >3  03} Z; { ) # NI 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 Q^#V"; *;  ͪ  *; q#pÝn* " ! p+q* )*= ^#V"; ! 6> ! i* &*; >OK : <2 E:/ *; ^#V*% DMf kK : *; Nf E*; ~ڻWK þE *; ~SK E = ! 6:! ':/ : = !: = : <2 * " !" >! .  * *&͵ "( * *&͵ > j*( #"( *DM*( V"( !" (   K!" }2 : <2 O:* * * "    >! = * DM** +" *( * " Ø* #" *&SK; ;* 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 S; 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 UESTION 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 EXTEN*( * " 3*1 #" " " *5 " > # R : B * +" ! +s#r( ! 6: " * ~2 * #" * +" > ʶ : 2 Ғ * +" : <2 O>ҳ ! 6* #" * ~2 p ̓: AOK = * Ͱ= * ͷ= * Ͱ= *# ͷ= * Ͱ= . g S -A >>!  ~?l W >#^ : /!:' —  ʑ #‹  W ʢ #™ i`N#FogDM!>))덑o|g =¼ DM!>)) = ^#V) ^#V|g}o HLD 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 A  T 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,DI 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 MO 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 FLE 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 SKBUF ;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 V 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 AOR 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 STAFILE 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,ERAMSENTRY 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 DDR1 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 ;FI  G ;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 ;YEEACH TIME PAST THE NEXT RECORD SHLD ADDR2 ;POINTER TO THE CURRENT RECORD LHLD MAX2 ;LIKEWISE SEE IF THE COUNTER FOR THE INX H SHLD MAX2 XCHG LHLD TABCNT CALL COMPREG JC LOOP1 ;WHEN FINISHED, INCREMENT OUTER LOOP LHLD ADDR2 XCHG ;ADDR2 NOW IN DE LHLD ADDR1 CALL COMPARE ;COMPARE STRINGS POINTED TO BY DE/HL JNC LOOP2 ;TABLE(HL) < TABLE (DE) ; ;* EXCHANGE THE TWO ENTRIES VIA A TEMPORARY RECORD ; LXI D,TEMP LHLD ADDR1 MVI B,RECSIZE CALL MOVE ;TEMP=TABLE(ADDR1) XCHG R1) ;;* TABLE(ADDR1)=TABLE(ADDR2) ;* TABLE(ADDR2)=TEMP ;* GO TO LOOP2 ;*SORTED RETURN ;* ;*NOW THAT THIS LOGIC IS INTUITIVELY OBVIOUS, HERE'S THE NOT SO ;*OBVIOUS CODE: SORT LXI H,0000 ;INITIALIZE COUNT SHLD MAX1 ;SINCE IT WILL DECREMENT FIRST LXI D,-RECSIZE ;SUBTRACT RECSIZE FROM THE BEGINNING LXI H,RAM ;OF THE TABLE SINCE IT WILL ADD DAD D ;RECSIZE TO IT FIRST SHLD ADDR1 LOOP1 LHLD ADDR1 ;GET THE CURRENT ADDRESS LXI D,RECSIZE ;INCREMENT IT BY RECSIZE DAD D ;PAST THE NEXTLE FROM ADDR2 DOWN XCHG ;TO ADDR1 THEREBY ELIMINATING LHLD ADDR1 ;UNWANTED ENTRIES MOVENEXT LDAX D ;AND MAKING MORE ROOM FOR THE MOV M,A CPI 1AH RZ INX H INX D JMP MOVENEXT ;* ASSORTED ROUTINES LOADBUFF EQU $ ;THIS ROUTINE LOADS AS MUCH OF LXI H,0000 ;MEMORY WITH THE FILE AS POSSIBLE SHLD MAX1 LHLD ADDR3 ;NEW TOP OF TABLE +2 SHLD TEMP XRA A STA EOF ;CLEAR EOF FLAG LOADNEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,HDFCB ;READ HARD S, 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 ;EXIS ;ADDR1=DESTINATION LHLD ADDR2 ;ADDR2=SOURCE CALL MOVE ;TABLE(ADDR1)=TABLE(ADDR2) XCHG ;ADDR2 = DESTINATION LXI H,TEMP CALL MOVE ;TABLE(ADDR2)=TEMP JMP LOOP2 SORTED RET ;FINISHED SORTING KILLDUPS EQU $ ;KILL DUPLICATE ENTRIES FROM MULTIPLE EXTENTS LXI H,RAM SHLD ADDR1 ;SET THE START OF THE TABLE NEXTEQUAL LHLD ADDR1 ;CHECK EACH ENTRY AGAINST THE NEXT LXI D,RECSIZE DAD D SHLD ADDR2 NEXTCHK MOV A,M ;CHECK FOR END OF TABLE CPI 1AH RZ XCHG LHLD ADDR1 ;COMP ENTRY SHLD ADDR1 LHLD MAX1 ;SEE IF THE COUNT HAS REACHED THE LIMIT INX H ;INCREMENT THE COUNTER SHLD MAX1 XCHG ;MOVE TO DE TO COMPARE TO LIMIT LHLD TABCNT DCX H ; IS MAX1 > TABCNT - 1 ??? CALL COMPREG ;COMPARE DE (CURRENT COUNT) TO HL (TABCNT-1) JC SORTED ;FINISHED WHEN MAX1 > TABCNT-1 LHLD ADDR1 ;SETUP FOR THE INNER LOOP SHLD ADDR2 LHLD MAX1 SHLD MAX2 LOOP2 LHLD ADDR2 ;START WITH ONE ENTRY GREATER THEN LXI D,RECSIZE ;THE OUTER LOOP AND INCREMENT DAD D ;BY RECSIZE DISK MVI C,14H CALL BDOS ORA A JNZ HDEOF ;EOF? LHLD MAX1 INX H ;INCREMENT RECORD COUNT SHLD MAX1 LHLD TEMP ;SEE IF NEXT RECORD WOULD EXCEED THE LXI D,128 ;TPA AREA DAD D SHLD TEMP DAD D ;WILL THE NEXT RECORD OVERWRITE BDOS? XCHG LHLD BDOS+1 ;FIND THE TOP OF MEMORY CALL COMPREG ;COMPARE REGISTERS RC ;RETURN IF MEMORY ALREADY FULL JMP LOADNEXT ;GET ANOTHER RECORD HDEOF MVI A,1 ;SET FILE EOF STA EOF RET WRITEBUF EQU $ ;WRITE FROM THE MEMORY BUFFER LHLD ADDRTS 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) DE CMP M ; JZ IF HL = DE JNZ COMP2 ;JNC IF HL < DE INX H INX D DCR B JNZ COMP1 COMP2 POP B POP D POP H RET SIGNON DB 'FLOPPY DISK COPY PROGRAM ' DB '10/9/82$' ERRNOMSK DB 'ERROR...NO FILE MASK IN COMMA!COPYRIGHT 1982, G. YOUNG, INC.1 :]  != " !" 2 2 2VZ: 2swj: 2sz: 2:2:s2s:2: ʢ\:s2 :2 ( :2 :2 Z: NY÷S????????????!\ :s2@2  2 * #" != " *  " * ~$DISKETTE STA EOF RET FORMAT LXI D,PRNTYPE ;FORMAT THE ENTRY FROM THE TABLE MVI B,3 ;FORMAT TO THE PRINT FORMAT CALL MOVE ;THE TABLE ADDRESS IS ASSUMMED TO BE LXI D,3 ;IN HL. FIRST MOVE THE TYPE DAD D ;NOW POSITION TO THE FILE NAME LXI D,PRNFILE ;MOVE THE FILE NAME MVI B,8 CALL MOVE LXI D,8 ;POSITION TO THE DISK ID DAD D LDA SRCE ORI 40H STA PRNTREC MVI A,':' STA PRNTREC+1 MVI A,'.' STA PRNTYPE-1 RET COMPREG MOV A,H ;COMPARE HL TO DE CMP D RNZ MOV A,L CB DS 36 SRCE DS 1 DEST DS 1 INBUF DB 30 INCNT DS 1 INREC DS 30 STACK DS 80 EOF DS 1 ABORT DS 1 LINECNT DS 1 LASTTYPE DS 3 LASTFILE DS 8 TABADDR DS 2 TABCNT DS 2 SELFLAG DS 1 TOOBIG DS 1 ADDR1 DS 2 ADDR2 DS 2 ADDR3 DS 2 MAX1 DS 2 MAX2 DS 2 RTYPE DS 3 RFILE DS 8 RDISK DS 3 DB '$' TEMP DS RECSIZE DISKBUF DS 128 COMPSIZE DS 1 CR EQU 0DH LF EQU 0AH RAM EQU $ END 100H ND' DB CR,LF,'COMMAND MUST BE IN THE FORMAT "FLOPCOPY *.*"' DB CR,LF,'$' TABFULL DB 'MEMORY FULL...REPORT NOT COMPLETE$' NFMSG DB 'FILE NOT FOUND...ABORTING$' DMNTMSG DB 'DISMOUNT DISKETTE AND ENTER RETURN$' ERAMSG DB 'ERASE COPIES ON THE HARD DISK (Y/N)? $' MNTBLANK DB 'MOUNT A FORMATTED BLANK DISKETTE AND ENTER RETURN$' ANOTHER DB 'WANT TO COPY THE SAME FILES ON TO ANOTHER DISKETTE (Y/N)? $' ALRDYEXT DB 'FILE ALREADY EXISTS ON DESTINATION DISK.' DB ' ENTER Y TO COPY OVER IT: $' DSKFULL DB * ###: 2!$: 2* <<ʇ*  >*wd: YNd<ʴ2z: ʩʴÓ * : YN!= " *  " * ~ ~*$* ###:2* !" != " *  " * #" * +* " * " *  " * #" * l* * Ҕ *  * ! Ô!= " *  " ~*  * "  CMP E RET OUTPUT PUSH D ;PUT OUT A CRLF LXI D,CRLF MVI C,09 CALL BDOS POP D ;NOW PUT OUT THE MESSAGE OUT1 MVI C,09 JMP BDOS QUESTION CALL OUTPUT ;PUT OUT THE QUESTION LXI D,INBUF MVI C,0AH ;INPUT THE REPLY CALL BDOS LDA INCNT ;SEE IF ANYTHING WAS ENTERED RET MOVE PUSH H ;MOVE DATA POINTED TO IN HL PUSH D ;TO THE AREA POINTED TO IN DE PUSH B ;BY THE BYTE COUNT IN B MOVE1 MOV A,M ANI 7FH ;RESET THE HIGH ORDER BIT BECAUSE IT ;MAY HAVE BEEN TURNED ON FOR T   " !* +" " * " * * w#(!" * " 2 * t* #" * " *B>2 * " * * º* +" * " Ê>2 : @2>:2>.2|}    : ~#.##FLOPPY DISK COPY PROGRAM 10/9/82$ERROR...NO FILE MASK IN COMMAND COMMAND MUST BE IN THE FORMAT "FLOPCOPY *.*" $MEMORY FULL...REPORT NOT COMPLETE$FILE NOT FOUND...ABORTING$DISMOUNT DISKETTE AND ENTER RETURTHE LIST IN MEMORY, COPY THE FILES FROM THE FLOPPY TO THE HARD DISK. 2. IF THE FILE ALREADY EXISTS ON THE HARD DISK, ASK IF YOU WANT THE FILE COPIED OVER WITH THE FLOPPY VERSION AND SET AN INDICATOR IN THE FILE LIST THAT THIS FILE WAS ALREADY THERE. THEN THE PROGRAM WILL REQUEST THE BLANK DISKETTE THAT WILL BE THE DESTINATION DISK TO BE MOUNTED. 3. USING THE FILE LIST NOW IN MEMORY, THE FILES ARE THEN COPIED FROM THE HARD DISK TO THE BLANK FLOPPY. 4. WHEN ALL FILES HAVE BEEN*. ͵Ͱ ҌB͵Ϳ MAKE USER CHANGE - Ver. 1.5 $$$ Requires CP/M version 2.0 or higher. Drive select error $$$ Bad Sector Write Error $$$ Drive is set to R/O $$$ User must be 0-31 $$$ is R/O CR to make change or any other input NOT to make change $$$ is SYS CR to make change or any other input NOT to make change $$$ = $$$????????????????P*'"c 2!m ~ $0< < # ¨{<x Ҫڪ2# x Ҫڪ2~ ?*0ڪN$ERASE COPIES ON THE HARD DISK (Y/N)? $MOUNT A FORMATTED BLANK DISKETTE AND ENTER RETURN$WANT TO COPY THE SAME FILES ON TO ANOTHER DISKETTE (Y/N)? $FILE ALREADY EXISTS ON DESTINATION DISK. ENTER Y TO COPY OVER IT: $DISKETTE FULL...MOUNT ANOTHER DISK$E:URN$ERAS. CO $ $ $ FILE TOO LARGE TO FIT ON ONE DISKETTE SO NOT BACKED UP **** $SOURCE FLOPPY DRIVE (DEFAULT=C) $DESTINATION FLOPPY DRIVE (DEFAULT=C) $HARD DISK DRIVE USED AS BUFFER (DEFAULT=A) $ COPY OVER IT: $DISKETTE FULL...MOUNT ANOTHER DISK$E:UR COPIED, THE PROGRAM WILL ASK IF ADDITIONAL COPIES ARE TO BE MADE. IF NOT, THE FILES ARE DELETED FROM THE HARD DISK. IF THE FILE WAS ALREADY ON THE HARD DISK AS DETERMINED BY INDICATOR SET PREVIOUSLY, THE FILE WILL NOT BE DELETED. THE PROGRAM IS SMART ENOUGH TO DETECT A FULL DISKETTE CONDITION. FLOPCOPY.ASM FLOPPY DISK COPY PROGRAM USING 1 DRIVE AND A HARD DISK WRITTEN BY G. YOUNG, PO BOX 3218, NORTH HOLLYWOOD, CA 91609 FLOPCOPY IS A PROGRAM USED TO COPY ONE FLOPPY DISKETTE TO ANOTHER FLOPPY IN SYSTEMS THAT HAVE ONLY ONE FLOPPY DRIVE BUT HAVE A HARD DISK. IT WORKS AS FOLLOWS: 1. READ THE DIRECTORY OF THE FLOPPY DISK USING THE MASK IN THE COMMAND TO CREATE A LIST OF FILES TO BE COPIED (EXAMPLE: FLOPCOPY *.ASC TO COPY ALL THE ASC FILES FROM ONE FLOPPY TO ANOTHER). THEN, USING  Ҫ # x Ҫڪ2:\02822:O Qgg}oCڞ:_:2\f2:_!"!!\ ?ʥ# ™*! ~k#~y*:w:e<2e\͵: 0_ͺ o&)|g,>0_ͺ|:<2s:e#2ef#2sͿ͵͉͵͉͵͉͵͇ `͵͉͵͉N͵͉g$ͺMAKE USER NUMBER CHANGE SYNTAX: DEFAULT: A>MAKE [Filename.typ] [New user #] OPTIONAL: A>MAKE [Filename.typ]N$ERAS. CO $  $ FILE TOO LARGE TO FIT ON ONE DISKETTE SO NOT BACKED UP **** $SOURCE FLOPPY DRIVE (DEFAULT=C) $DESTINATION FLOPPY DRIVE (DEFAULT=C) $HARD DISK DRIVE US$   [New user #]$$$[From user #] EXAMPLES: A>MAKE CBASIC.COM 5 A>MAKE *.BAS 5 B>MAKE A:*.HEX 15 A>MAKE B:*.* 21$$$0 A>MAKE *.ASM 3$$$* CR to continue : $$$ [Filename.typ] may be any ambiguous file reference, e.g.: *.ASM B:TEMP.* CR???.BAS C:*.COM C*.COM etc. [New user #] may be any desired user area from 0 to 31. At least one space should be between the [Filename.typ] and [New user #]. MAKE defaults to changing only files in the ACTIVE user area. Ter any user. ; ; ; ; Note: optional drive name may be specified. ; ; ; ; ; ; MDIR FILENAME.FILETYPE searches for all files that match ; ; in all user areas. ; ; ; ; MDIR S???.* returns all 4 character files with any extention ; ; in any user areas. ; ; ; ;_______________________________________________________________; ; ;07/02/80 FIXED TO ALLOW MORE THAN 256 NAMES IN DIRECTORY, ; PRINT DRIVE NAME, AND ALLOW SPECIFYING DRIVE. ; BY KEITH PEUESTED DISK NUMBER MVI C,CURDSK ;FIND OUT WHERE WE'RE LOGGED CALL BDOS STA CDSK ;SAVE IT FOR LATER POP PSW ;GET REQUESTED DISK NR. MOV E,A ;TO E FOR CP/M MVI C,SELDSK ;SELECT DISK REQUESTED CALL BDOS ; FSPEC2 MVI C,CURDSK ;FIND OUT WHERE WE'RE LOGGED CALL BDOS ADI 'A' ;MAKE PRINTABLE STA DRNAME ;PRINT HEADER CALL FSPEC3 DB CR,LF DB '.. MASTER DIRECTORY - DRIVE ' DRNAME DB 'X:' DB CR,LF,CR,LF,'$' ; FSPEC3 POP D MVI C,PRINT CALL BDOS LXI H,FCB+1 MOV A,M ;GET 1ST CHAR.his may be optionally over-ridden by specifying the user area FROM which you desire the files moved. [From user #] may be any user area 0 through 31 or may ambiguously specify the entire directory with a "*". The [New user #] should be followed immediately by the option flag "$$$" and the [From user #], e.g.: MAKE *.BAS 3$$$10 or MAKE B:*.COM 0$$$2$$$͵Ô͵Ôʇ͇    ͺ úͿ* #>~ _ͺ #.ͺ TERSEN, W8SDZ. ; ;07/30/80 FIXED TO ELIMINATE CRASH WHEN NO NAMES ARE IN ; DIRECTORY. REPLACED DECIMAL OUTPUT ROUTINE WITH ; SIMPLER ONE WHICH IS SMALLER AND ALLOWS USE OF ; ONE LESS LEADING SPACE SO DISPLAY CAN BE PRINTED ; ON A 72-CHARACTER PRINTER. (KBP) ; ;08/17/80 CORRECTED MISSING INR A IN SEARCH FIRST ROUTINE, ; WHICH CAUSED DUPLICATE LISTING OF THIRD DIRECTORY ; ENTRY. (KBP) ; BASE SET 0 ; ALTCPM EQU 0 ;PUT 1 HERE FOR H8 OR TRS-80 CP/M ; IF ALTCPM BASE SET 4200H ENDIF; MDIR.ASM ; revised 8/17/80 ; ; CP/M-2 MASTER DISK DIRECTORY PROGRAM ; by Jeff Hammersley, MD. ; ; PRINTS A COMPLETE DISK DIRECTORY INCLUDING ALL USERS, ; SORTED ALPHABETICALLY AND PRINTED 4 WIDE. ; ; Based on 'FMAP' as originally written by Ward Christensen ; and its subsequent evolution to 'SDIR' by Keith Petersen. ; ;---------------------------------------------------------------; ; ; ; Commands: ; ; ; ; MDIR returns all files on the default disk und OF NAME REQUEST STA SAVFCB ;SAVE FOR LATER ; ;MAKE DR FIELD OF FCB '?' TO FORCE RETURN OF ALL USER ENTRIES DCX H ;POINT TO DR FIELD MVI M,'?' ;STORE '?' IN FCB ; ;RETURN ALL DIRECTORY ENTRIES MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC LXI D,FCB CALL BDOS ;READ FIRST INR A ;COMPENSATE FOR LATER DCR JMP SOME ;GOT SOME (BECAUSE OF ? IN DR FIELD) ; ;READ MORE DIRECTORY ENTRIES MOREDIR MVI C,FSRCHN ;SEARCH NEXT LXI D,FCB CALL BDOS ;READ DIR ENTRY INR A ;CHECK FOR END (0FFH) JZ SPRINT ;Nb¤WxG ; NAMES EQU 1024 ;MAX NUMBER OF NAMES IN DIRECTORY ; FCB EQU BASE+5CH ;SYSTEM FCB NPL EQU 4 ;NUMBER OF NAMES PER LINE CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED DELIM EQU ':' ;FENCE (DELIMITER) CHARACTER ; ORG BASE+100H ; JMP START ;JUMP AROUND I.D. DB 'MDIR.COM 8/17/80 ' ; ;SAVE THE STACK START LXI H,0 DAD SP ;H=STACK SHLD STACK ;SAVE IT LXI SP,STACK ;GET NEW STACK LDA FCB ORA A ;ANY DRIVE SPECIFIED? JZ FSPEC2 DCR A ;CORRECT DISK NUMBER FOR CP/M PUSH PSW ;SAVE REQ  O MORE - SORT & PRINT ;POINT TO DIRECTORY ENTRY SOME DCR A ;UNDO PREV 'INR A' ANI 3 ;MAKE MODULUS 4 ADD A ;MULTIPLY... ADD A ;..BY 32 BECAUSE ADD A ;..EACH DIRECTORY ADD A ;..ENTRY IS 32 ADD A ;..BYTES LONG LXI H,BASE+80H ;POINT TO BUFFER ADD L ;POINT TO ENTRY MOV L,A ;SAVE (CAN'T CARRY TO H) ;MOVE ENTRY TO TABLE MOV A,M ;GET DR FIELD CPI 0E5H ;IS IT AN ERASED FILE ? JZ MOREDIR ;YES, IGNORE AND GET ANOTHER MOV D,H ;ENTRY TO DE MOV E,L MVI A,12 ;GET OFFSET TO EXTENT BYTE AHLD NEXTT ;SAVE UPDATED TABLE POINTER XCHG ;TABLE ENTRY TO HL LDA SAVFCB ;GET SAVED 1ST CHAR. OF FCB CPI ' ' ;WAS NAME SPECIFIED? JNZ MATCH ;YES, GO SEE IF PRESENT ;PRINT USER # PTONE MOV A,M ;GET USER NUMBER CPI 32 ;IS IT VALID ? (IE.< 32) JNC NULL ; NO, IGNORE IT ORA A ;IS IT USER 0 ? JNZ PTONE2 ;NO, SKIP NEXT ROUTINE CALL SPACE2 ;USER 0, FILL WITH SPACES JMP PTONE3 ;SKIP DECOUT PRINT ; PTONE2 PUSH H MVI H,0 MOV L,A ;NUMBER TO L FOR DECOUT CPI 10 ;LESS THAN 10? CC SPACE ;YD ;..YES LHLD COUNT ;GET COUNT DCX H MOV A,L ORA H ;ONLY 1 ENTRY? JZ DONE ;..YES, SO SKIP SORT ; SORT XRA A ;GET A ZERO STA SWITCH ;SHOW NONE SWITCHED LHLD SCOUNT ;GET COUNT DCX H ;USE 1 LESS SHLD TEMP ;SAVE # TO COMPARE SHLD SCOUNT ;SAVE HIGHEST ENTRY MOV A,L ORA H JZ DONE ;EXIT IF NO MORE LXI H,ORDER ;POINT TO ORDER TABLE ; SORTLP CALL COMPR ;COMPARE 2 ENTRIES CM SWAP ;SWAP IF NOT IN ORDER INX H ;BUMP ORDER INX H ;..TABLE POINTER PUSH H LHLD TEMP ;GET COUNT DCX ONE ;GO PRINT ONE ; WHCH MOV A,B ;GET B CPI 3 ;IS IT STILL THE FILENAME ? JC FTYP ; NO, IT IS ANY TYPE SO WE ARE DONE. MVI B,3 ;YES, LOAD UP TO FILETYPE JMP MAT1 ;RETURN FOR MORE ; NOMATCH POP H POP D ;RESTORE REGISTERS JMP NULL ;GET NEW FILENAME TO TRY ; PERIOD MVI A,'.' JMP TYPE ; FENCE CALL SPACE2 MVI A,DELIM ;FENCE CHARACTER JMP TYPE ; SPACE3 CALL SPACE ; SPACE2 CALL SPACE ; SPACE MVI A,' ' ; ;TYPE CHAR IN A TYPE PUSH B PUSH D PUSH H MOV E,A MVI C,WRCHR CALL DD L ;ADD TO GET CORRECT POINTER MOV L,A MOV A,M ;GET EXTENT BYTE ORA A ;IS EXTENT OTHER THAN ZERO ? JNZ MOREDIR ;IGNORE ALL EXTENTS BEYOND THE FIRST LHLD NEXTT ;NEXT TABLE ENTRY TO HL MVI B,12 ;ENTRY LENGTH ; TMOVE LDAX D ;GET ENTRY CHAR ANI 7FH ;REMOVE ATTRIBUTES MOV M,A ;STORE IN TABLE INX D INX H DCR B ;MORE? JNZ TMOVE SHLD NEXTT ;SAVE UPDATED TABLE ADDR LHLD COUNT ;GET PREV COUNT INX H ;ADD ONE SHLD COUNT ;RESAVE COUNT JMP MOREDIR ; ;SORT AND PRINT SPRINT LHLD COUES, ADD ONE SPACE CALL DECOUT ;PRINT USER NUMBER POP H ; PTONE3 CALL SPACE ;MAKE IT LOOK NICE INX H ;POINT TO NAME MVI B,8 ;FILE NAME LENGTH CALL TYPEIT ;TYPE FILENAME CALL PERIOD ;PERIOD AFTER FN MVI B,3 ;GET THE FILETYPE CALL TYPEIT DCR C ;ONE LESS ON THIS LINE PUSH PSW CNZ FENCE ;NO CR-LF NEEDED, DO FENCE POP PSW CZ CRLF ;CR-LF NEEDED ;SEE IF MORE ENTRIES NULL PUSH H LHLD COUNT DCX H SHLD COUNT MOV A,L ORA H POP H JNZ ENTRY ;YES, MORE JMP EXIT ; MATCH PUSH H ;ONE LESS SHLD TEMP ;SAVE COUNT MOV A,L ORA H ;DONE? POP H JNZ SORTLP ;CONTINUE ;ONE PASS OF SORT DONE LDA SWITCH ;ANY SWAPS DONE? ORA A JNZ SORT ; ;SORT IS ALL DONE - PRINT ENTRIES DONE LXI H,ORDER SHLD NEXTT ; ;PRINT AN ENTRY MVI C,NPL ;NR. OF NAMES PER LINE ; ENTRY: PUSH B MVI C,CONST ;CK STATUS OF KBD CALL BDOS ;ANY KEY PRESSED? POP B ORA A JNZ ABORT ;YES, ABORT LHLD NEXTT ;GET ORDER TABLE POINTER MOV E,M ;GET LO ADDR INX H MOV D,M ;GET HI ADDR INX H SBDOS POP H POP D POP B RET ; TYPEIT MOV A,M CALL TYPE INX H DCR B JNZ TYPEIT RET ; CRLF MVI A,CR ;CARRIAGE RETURN CALL TYPE MVI A,LF ;LINE FEED CALL TYPE MVI C,NPL ;NUMBER OF NAMES PER LINE RET ; ;DECIMAL OUTPUT ROUTINE ; DECOUT: PUSH B PUSH D PUSH H LXI B,-10 LXI D,-1 ; DECOU2: DAD B INX D JC DECOU2 LXI B,10 DAD B XCHG MOV A,H ORA L CNZ DECOUT MOV A,E ADI '0' CALL TYPE POP H POP D POP B RET ; ;COMPARE ROUTINE FOR SORT COMPR PUSNT ;GET COUNT MOV A,H ORA L ;CHECK FOR ZERO COUNT JZ NFEXIT ;NOTHING IN DIRECTORY, EXIT SHLD OCOUNT ;SAVE FOR ORDER TABLE COUNT SHLD SCOUNT ;SAVE FOR SORT COUNT LXI H,ORDER LXI D,TABLE LXI B,12 ;ENTRY LENGTH ; BLDORD MOV M,E ;SAVE LO ORD ADDR INX H MOV M,D ;SAVE HI ORD ADDR INX H XCHG ;TABLE ADDR TO HL DAD B ;POINT TO NEXT ENTRY XCHG ;NEXT ENTRY TO DE PUSH H LHLD OCOUNT ;GET COUNT DCX H ;ONE LESS SHLD OCOUNT ;SAVE NEW COUNT MOV A,L ORA H ;MORE? POP H JNZ BLDORD ;SAVE DE PUSH H ;SAVE HL LXI D,FCB ;GET FCB REQUEST INX H ;MOVE TO FN.FT INX D ; MVI B,11 ;GET NUMBER OF CHARACTERS TO COMPARE ; MAT1 LDAX D ;GET CHARACTER CPI '*' ;IS FILENAME OR FILETYPE AMBIGUOUS ? JZ WHCH ; YES, DETERMINE WHICH ONE CPI '?' ;IS IT A AMBIGUOUS CHARACTER ? JZ AMBC ; YES CMP M ;COMPARE TO MEMORY JNZ NOMATCH ;MATCH FAILURE ; AMBC INX D INX H ;GET NEW CHARACTERS DCR B ;ARE WE DONE ? JNZ MAT1 ;NO, COMPARE NEXT ; FTYP POP H POP D ;RESTORE REGISTERS JMP PT  H H ;SAVE TABLE ADDR MOV E,M ;LOAD LO INX H MOV D,M ;LOAD HI INX H MOV C,M INX H MOV B,M ;BC, DE NOW POINT TO ENTRIES TO BE COMPARED XCHG CMPLP LDAX B CMP M INX H INX B JZ CMPLP POP H RET ;COND CODE TELLS ALL ; ;SWAP ENTRIES IN THE ORDER TABLE SWAP MVI A,1 STA SWITCH ;SHOW A SWAP WAS MADE MOV C,M INX H PUSH H ;SAVE TABLE ADDR+1 MOV B,M INX H MOV E,M MOV M,C INX H MOV D,M MOV M,B POP H MOV M,D DCX H ;BACK POINTER TO CORRECT LOC'N MOV M,E RET  >   | {0^#V#N#F #7>2N#F#^q#Vpr+sq++NO FILES ON THIS DISK $ y:_* EQU 11 ;CHECK CONS STAT SELDSK EQU 14 ;SELECT DISK DRIVE FSRCHF EQU 17 ; " " FSRCHN EQU 18 ; " " CURDSK EQU 25 ;CHECK CURRENT DISK 0=A: 1=B:, ETC. BDOS EQU BASE+5 ; END ; MULTIPLE FILE COPY PROGRAM ; COPYRIGHT 1982, G. YOUNG, INC. ; UPDATED 10/9/82 ; ; TO EXECUTE, ENTER THE PROGRAM NAME FOLLOWED BY THE FILE MASK: ; A>MULTCOPY *.COM ; ; THE PURPOSE OF THIS PROGRAM IS TO COPY MULTIPLE FILES TO A FLOPPY DISK ; FROM A HARD DISK. IF YOU USED PIP FOR D:=*.COM AND THER WERE MORE ; COM FILES THAN WOULD FIT ON ONE DISK, PIP WOULD STOP WHEN THE FIRST ; DISK WAS FULL. IF MULTCOPY, WHEN ONE DISK WAS FULL, IT WOULD ASK ; YOU TO MOUNT A NEW DISK AND CONTINUE COPYIN; NFEXIT CALL ERXIT DB '++NO FILES ON THIS DISK',CR,LF,'$' ; ;ERROR EXIT ERXIT POP D ;GET MSG MVI C,PRINT JMP CALLB ;PRINT MSG, EXIT ; ;ABORT - READ CHAR ENTERED ABORT MVI C,RDCHR ;DELETE THE CHAR CALLB CALL BDOS ; ;FALL INTO EXIT ;EXIT - ALL DONE, RESTORE DISK LOG IN AND STACK EXIT LDA CDSK ;GET ORIGINAL DISK NR. MOV E,A ;TO E FOR CP/M MVI C,SELDSK ;RESTORE LOG-IN TO IT CALL BDOS LHLD STACK ;GET OLD STACK SPHL ;MOVE TO STACK RET ;..AND RETURN ; NEXTT DW TABLE ;NEXT TABLE E!9"1$*.*":] $!m~ IA0 ?))) O *&1} 12>2:\f=_\=+\Q  ~#Œ::\2>?2h2> > ·>.7:o :w>2 _ɯ2_!_LbLtLLL :] *[Bad user number]$ - file exists on destination user area. [Aborted]$[No file name given]$[File not found]$[No destination user number given]$>2 _MDIR.COM 8/17/80 !9" 1 :\6=2_A2ah .. MASTER DIRECTORY - DRIVE X: $ !]~2+6?\<Ð\<=!o~ʄT]> o~„* w#³"*#"Ä*|T""!  s#r# *+"}*+}22*+""}2!.@##*+"}:!" w*^#V#":  ~ ҏhu&o  # *+"}:|\# *?ʸ#©XxھéÏ>.>:> _~#>G. THE FLOPPY DISK DRIVE ; IS HARD CODED INTO THE PROGRAM. THE SOURCE MAY BE ANY HARD DISK. ; EXAMPLE MULTCOPY B:LN*.ASM ; CHANGED 10/9/82 TO ASK DESTINATION FLOPPY DRIVE ; WRITTEN BY GARY YOUNG, BOX 3218, NO. HOLLYWOOD, CA 91609 ;TITLE '*** MULTCOPY FILE 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 NTRY COUNT DW 0 ;ENTRY COUNT SWITCH DB 0 ;SWAP SWITCH FOR SORT SAVFCB DS 1 ;SAVED 1ST CHAR. OF FCB CDSK DS 1 ;CURRENTLY LOGGED DISK NUMBER OCOUNT DS 2 ;# NAMES TO PUT IN ORDER TABLE SCOUNT DS 2 ;# TO SORT TEMP DS 2 ;SAVE DIR ENTRY ORDER DS NAMES*2 ;ORDER TABLE (TWO BYTES PER NAME) DS 60 ;STACK AREA STACK DS 2 ;SAVE OLD STACK HERE TABLE EQU $ ;READ ENTRIES IN HERE ; ; BDOS EQUATES ; RDCHR EQU 1 ;READ CHAR FROM CONSOLE WRCHR EQU 2 ;WRITE CHR TO CONSOLE PRINT EQU 9 ;PRINT CONSOLE BUFF CONST ɯ2_!_*L This program moves a given file name(s) to any user area from current user area. For CP/M 2.x only! A>MOVE TESTFILE.COM 3 (will move file TESTFILE.COM on drive A to user area 3) A>MOVE B:TESTFILE 3 (will move file TESTFILE.COM on drive B to user area 3) A>MOVE B:*.* 3 (will move all files on drive B to user area 3) $   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,DESTFLPMSG CALL QUESTION ORA A JNZ QUEST1A LDA DESTFLP JMP QUEST1B QUEST1A LDA INREC QUEST1B STA FLOPPY CALL EXTRACT ;GET DIRECTORY ENTRIES NOMORE CALL SORT CALL KILLDUPS ;REMOVE ENTRIES FROM S 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,ST 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??? 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 MULTIPLE EXTENTS LDA 5CH ;SOURCE DISK STA SRCE LDA FLOPPY ;FLOPPY DISK IS ALWAYS THE DESTINATION ANI 0FH STA DEST LXI D,MNTBLANK CALL QUESTION MVI C,0DH CALL BDOS CALL CPYFILE 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 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 R 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 ENTRIEBDOS 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 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 DISKFULSETS 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 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 FIREFERS 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   L 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,MNTBLANK CALL QUESTION MVI C,0DH CALL BDOS JMP FORMFCB NOTFOUND LHLD ADDR1 CALL FORMAT LXI D,NFMSG CALL OUTPUT LXI D,PRNTREC CALL OUTPUT RET ; 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 REDUPS EQU $ ;KILL DUPLICATE ENTRIES FROM MULTIPLE EXTENTS LXI H,RAM SHLD ADDR1 ;SET THE START OF THE TABLE NEXTEQUAL LHLD ADDR1 ;CHECK EACH ENTRY AGAINST THE NEXT LXI D,RECSIZE DAD D SHLD ADDR2 NEXTCHK MOV A,M ;CHECK FOR END OF TABLE CPI 1AH RZ XCHG LHLD ADDR1 ;COMPARE ADDR1 WITH ADDR2 MVI B,RECSIZE CALL COMPARE JNZ SAVELAST PUSH H ;SAVE CURRENT POSITION LHLD ADDR2 ;SET UP FOR MOVING LIST SHLD ADDR1 ;DOWN ONE ENTRY LXI D,RECSIZE DAD D ;MOVE THIRD ENTRY TO THL COMPREG ;COMPARE DE (CURRENT COUNT) TO HL (TABCNT-1) JC SORTED ;FINISHED WHEN MAX1 > TABCNT-1 LHLD ADDR1 ;SETUP FOR THE INNER LOOP SHLD ADDR2 LHLD MAX1 SHLD MAX2 LOOP2 LHLD ADDR2 ;START WITH ONE ENTRY GREATER THEN LXI D,RECSIZE ;THE OUTER LOOP AND INCREMENT DAD D ;BY RECSIZE EACH TIME PAST THE NEXT RECORD SHLD ADDR2 ;POINTER TO THE CURRENT RECORD LHLD MAX2 ;LIKEWISE SEE IF THE COUNTER FOR THE INX H SHLD MAX2 XCHG LHLD TABCNT CALL COMPREG JC LOOP1 ;WHEN FINISHED, INCTHE NEXT RECORD OVERWRITE BDOS? XCHG LHLD BDOS+1 ;FIND THE TOP OF MEMORY CALL COMPREG ;COMPARE REGISTERS RC ;RETURN IF MEMORY ALREADY FULL JMP LOADNEXT ;GET ANOTHER RECORD HDEOF MVI A,1 ;SET FILE EOF STA EOF RET WRITEBUF EQU $ ;WRITE FROM THE MEMORY BUFFER LHLD ADDR3 SHLD TEMP LHLD MAX1 ;ALLOW FOR FILES THAT HAVE NO LXI D,0000 ;RECORDS SUCH AS RESTART CALL COMPREG RZ WRITENEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,FPFCB MVI C,15H ;WRITECORD) ; 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) TABCNT - 1 ??? CALS LOADBUFF EQU $ ;THIS ROUTINE LOADS AS MUCH OF LXI H,0000 ;MEMORY WITH THE FILE AS POSSIBLE SHLD MAX1 LHLD ADDR3 ;NEW TOP OF TABLE +2 SHLD TEMP XRA A STA EOF ;CLEAR EOF FLAG LOADNEXT LHLD TEMP XCHG ;SET DMA ADDRESS MVI C,1AH CALL BDOS LXI D,HDFCB ;READ HARD DISK MVI C,14H CALL BDOS ORA A JNZ HDEOF ;EOF? LHLD MAX1 INX H ;INCREMENT RECORD COUNT SHLD MAX1 LHLD TEMP ;SEE IF NEXT RECORD WOULD EXCEED THE LXI D,128 ;TPA AREA DAD D SHLD TEMP DAD D ;WILL   OW POSITION TO THE FILE NAME LXI D,PRNFILE ;MOVE THE FILE NAME MVI B,8 CALL MOVE LXI D,8 ;POSITION TO THE DISK ID DAD D LDA SRCE ORI 40H STA PRNTREC MVI A,':' STA PRNTREC+1 MVI A,'.' STA PRNTYPE-1 RET COMPREG MOV A,H ;COMPARE HL TO DE CMP D RNZ MOV A,L CMP E RET OUTPUT PUSH D ;PUT OUT A CRLF LXI D,CRLF MVI C,09 CALL BDOS POP D ;NOW PUT OUT THE MESSAGE OUT1 MVI C,09 JMP BDOS QUESTION CALL OUTPUT ;PUT OUT THE QUESTION LXI D,INBUF MVI C,0AH ;INTER RETURN$' PRNTREC DS 1 DB ':' PRNFILE DS 8 DB '.' PRNTYPE DS 3 DB ' $' CRLFLFLF DB 0DH,0AH,0AH,0AH,'$' CRLF DB 0DH,0AH,'$' BIGMSG DB 0DH,0AH,'FILE TOO LARGE TO FIT ON ONE DISKETTE ' DB 'SO NOT BACKED UP **** $' DESTFLPMSG DB 'DESTINATION FLOPPY DRIVE (DEFAULT=' DESTFLP DB 'C) $' HDFCB DS 1 HDFILE DS 8 HDTYPE DS 3 DS 24 FPFCB DS 36 FLOPPY DS 1 SRCE DS 1 DEST DS 1 INBUF DB 30 INCNT DS 1 INREC DS 30 STACK DS 80 EOF DS 1 ABORT DS 1 LINECNT DS 1 LASTTYPE DS 3 LASTFILE ~##MULTIPLE FILE COPY PROGRAM 10/9/82$ERROR...NO FILE MASK IN COMMAND COMMAND MUST BE IN THE FORMAT "MULTCOPY *.*" $FILE NOT FOUND...ABORTING$DISMOUNT DISKETTE AND ENTER RETURN$MOUNT A FORMATTED BLANK DISKETTE AND ENTER RETURN$:#. $ $ $ FILE TOO LARGE TO FIT ON ONE DISKETTE SO NOT BACKED UP **** $DESTINATION FLOPPY DRIVE (DEFAULT=C) $"MULTCOPY *.*" $FILE NOT FOUND...ABORTING$DISMOUNT DISKETTE AND ENTER RETUN$MOUNT A FORMATTED BLANK DISKETTE AND ENTER RETPUT THE REPLY CALL BDOS LDA INCNT ;SEE IF ANYTHING WAS ENTERED RET MOVE PUSH H ;MOVE DATA POINTED TO IN HL PUSH D ;TO THE AREA POINTED TO IN DE PUSH B ;BY THE BYTE COUNT IN B MOVE1 MOV A,M ANI 7FH ;RESET THE HIGH ORDER BIT BECAUSE IT ;MAY HAVE BEEN TURNED ON FOR THE TYPE STAX D INX H INX D DCR B JNZ MOVE1 POP B ;RESTORE THE TOTAL ENVIRONMENT POP D POP H RET COMPARE PUSH H ;COMPARE THE STRINGS POINTED TO IN HL PUSH D ;TO THE STRING POINTED TO IN DE PUSH !COPYRIGHT 1982, G. YOUNG, INC.1?:] ʈ !"M!"O2@2?"^Z:]:2ͶL:\2:2 lE????????????!\ :@2hx<< !x#`]###!] ~w#!] ~ #+*M] *M "M6*O#"O*M* >2@*U#"W!"SÆ*S "S*S~$“*S###:2!$:2*SͰ<9<<DS 8 TABADDR DS 2 TABCNT DS 2 SELFLAG DS 1 TOOBIG DS 1 ADDR1 DS 2 ADDR2 DS 2 ADDR3 DS 2 MAX1 DS 2 MAX2 DS 2 RTYPE DS 3 RFILE DS 8 RDISK DS 3 DB '$' TEMP DS RECSIZE DISKBUF DS 128 COMPSIZE DS 1 CR EQU 0DH LF EQU 0AH RAM EQU $ END 100H URN$:#. $ $ $ FILE TOO LARGE TO FIT ON ONE DISKETTE SO NOT BACKED UP **** $DESTINATION F$B ;FOR A LENGTH OF B CHARACTERS COMP1 LDAX D ; JC IF HL > DE CMP M ; JZ IF HL = DE JNZ COMP2 ;JNC IF HL < DE INX H INX D DCR B JNZ COMP1 COMP2 POP B POP D POP H RET SIGNON DB 'MULTIPLE FILE COPY PROGRAM ' DB '10/9/82$' ERRNOMSK DB 'ERROR...NO FILE MASK IN COMMAND' DB CR,LF,'COMMAND MUST BE IN THE FORMAT "MULTCOPY *.*"' DB CR,LF,'$' NFMSG DB 'FILE NOT FOUND...ABORTING$' DMNTMSG DB 'DISMOUNT DISKETTE AND ENTER RETURN$' MNTBLANK DB 'MOUNT A FORMATTED BLANK DISKETTE AND EN#"j:?#| Í*SͰ!"Y!"S*S "S*Y#"Y*O+*S"U*Y"[*U "U*[#"[*O\*U*S҄l*S *U!lÄ!"S*S "U~*S *U"S "U*O+"O"S*U"S*U*Sw#!"Y*W"l2?*ld*Y#"Y*l"l*2>2?*W"l*Y*lª*Y+"Y*l"lz>2?:@2>:2>.2|}   :  MULTCOPY MULTIPLE FLOPPY DISKETTE FILE COPY THE PURPOSE OF THIS PROGRAM IS TO COPY A GROUP OF FILES FROM A HARD DISK TO MULTIPLE FLOPPY DISKS. IF YOU ENTERED "PIP D:=LN*.COM" AND THERE WERE MORE COM FILES THAN WOULD FIT ON ONE FLOPPY, PIP WOULD STOP WHEN THE FIRST DISK WAS FULL. MULTCOPY WILL PROMPT FOR ANOTHER DISK WHEN THE FIRST ONE IS FULL AND CONTINUE TO COPY THE REST OF THE FILES. THE PROGRAM WILL ASK YOU FOR THE FLOPPY DISK DRIVE, BUT THE SOURCE HARD DISK MUST BE SPECIFIED IN THE COMMAND area can be specified as a second parameter. SWEEP B:FOO.COM will begin with drive B: logged in, and the cursor on the first entry in the directory which is >= FOO.COM in alphabetical order. In the latest version, both file name and file type are recognized. SWEEP B:FOO.COM 8 will log in user area 8. Selecting user area * will cause all user areas to be "swept" at once. NEW: If the starting file contains wild card symbols (* or ?), then it will be treated as a directory wild card specrun under MP?M . When running under MP/M, the calculation of remaining space in a directory produces a meaningless number and should be ignored. (This also applies to the Size function.) SWEEP is probably incompatible with extended file features (like passwords) under MP/M. Invoking SWEEP and moving about the directory. ---------------------------------------------- When SWEEP is invoked, you will see a menu of 'commands' and the first entry in the directory. You will also be given the total spay is simply not made. You will be told. You may use the delete function to delete the file, and then retry the copy. As an option, sweep will perform a CRC verification of the copy. When you are prompted for the drive and user, add a 'v' or 'V' to request verification. Thus specifying: b3 v will copy the file to drive b:, user area 3, with verification. See below for a description of the verification method. BUG: CP/M does not allow two files of the same nam. THE DEFAULT FLOPPY IS C:. EXAMPLE: MULTCOPY B:*.ASC WOULD COPY ALL ASC FILES FROM HARD DISK B: TO THE FLOPPY DRIVE (C: IN THIS VERSION) AND WOULD REQUEST MULTIPLE DISKS AS EACH GOT FULL. ification. Only those files in the selected user area will be handled. At any time, you can recover the menu of functions by typing a question mark (?). Simply typing 'x' exits the program. Note that all characters can be entered in upper or lower case. Functions that act on one file. _______________________________ C This allows you to copy the file to the drive and user area of your choice. You will be prompted for the drive and user area. Just enter 'b3', say, to transfce (in k) occupied by the files and the remaining space on the disk. SWEEP also reports the current user area in the prompt, or an asterisk if you have selected all user areas. Typing 'space' or 'return' moves you forward in the directory, typing B (or b) moves you backward. The directory is circular, so typing space at the end of the directory moves you to the beginning. (A line is skipped.) When you first invoke SWEEP, you can specify a drive and a starting place in the directory. The usere to be open on the same drive, even in different user areas. Thus, when transferring between user areas on the same drive, the target file is first named with the $ convention and then renamed. This can result in an extra file being erased. If there is too little room on the target drive, the transfer is aborted and the directory entry is erased. Any previous file of the same name in the target area is also erased.(Sorry.) D The current file is deleted. You wi/******************************************************************** SWEEP version 3.8, October 18, 1982 by Robert Fisher DePaul University 243 S. Wabash Chicago, Illinois 60604 Released to the Public Domain by the author. *********************************************************************** SWEEP is a utility program for maintaining file directories, and transferring files between drives and user areas under CP/M2.2. SWEEP will not run under CP/M 1.4, but it will er the file to drive B: user area 3. If you omit the user area, the current user area of the file is used. Any file of the same name in the target area is first erased, an exception being when you are transferring to the current drive and user area. In the latter case, the transferred file is copied with its named changed by putting a $ in the last letter of the file type. If an existing file in the target area that must be erased is marked read-only (R/O), then the cop  ll be asked if you really want it erased. If the file is read-only (R/O), then you will be given a second chance to back out. R The current file is renamed to the name you specify. Lower case will be converted to upper case, but other 'illegal' characters are not trapped. It is quite possible to give names to files that CP/M won't recognize. (You can also change them back again later, however, so no harm is done.) Responding with "*" to the prompt will put you itagged files. You will be asked whether you want to erase the tagged files or the untagged files. Any answer other than T or t means untagged. You will then be asked whether you want to be prompted or not. If you ask to be prompted, you will be asked for a Y or N on each file. Otherwise, the untagged files will be deleted. Be very careful with this one. You can wipe out an entire directory very quickly. You can abort this operation by responding A to thkes the copy function used by C, so everything said above applies here. If any key is typed while files are being transferred, the transfer is aborted after the current file. The remaining files remain tagged. After transferring a tagged file, the tag is changed to '#' so you can tell what has been sent. This is for display only, the file is otherwise considered untagged, but see the A command. The '#' can be removed with the U command, if desired. If no usein the current file name. When the substitutions are done, embedded spaces are removed. You will be asked to approve each substitution before it is actually made. Old name: SWEEP???.* New name: TEST ???.* These responses would result in SWEEP.COM being renamed TEST.COM, and SWEEP30.PLI being renamed TEST30.PLI. Other commands. --------------- B Move to previous file. Moves to last file if you are currently on the first file. L Login new drive and user n the batch wildcard renaming mode. See below. If the file is read-only, you will be asked if you still want it renamed. It will no longer be read-only after renaming. V The current file is displayed at the terminal. ^S will stop the display until any other key is typed. Otherwise, any keypress will abort. T Tag a file for later transfer. (See below.) After being tagged, the file will be marked with an asterisk,'*'. The total of all tagged files is displayed both e prompt, or typing any key in the unprompted mode (if you are quick enough). The TAGGED option is useful after a mass transfer. Use the A command to retag all the transferred files, then use the E command to erase them. The UNTAGGED option is useful if you want to clean up a disk or user area, but retain a few key files. Just tag the files you want to retain and use the E command to erase the others. R * Batch rename. You will be prompted for an "Old name:" andr area is specified, or if "*" is specified, the current user area of the file is used. You may request verification on mass transfers just as in the single file copy. Just follow the drive and user specification with a space and a 'v' or 'V'. A Retags all the files currently marked with '#'. This allows you to repeat the transfers on another disk. Useful when the same batch of files must be sent to several disks. E The E command erases all untagged files or all area. If the user area is ommitted, the current user area is used. You can specify a starting place in the directory. Responding 'b3 foo' will put you in user area 3 of drive B:, beginning at the first file >= FOO in alphabetical order. Selecting "*" for user area, logs in all user areas at once. If the starting file is a wild card specification, it is instead used to select the files to be used. Thus: l New drive (and user area): b1:*.PLI will log you into drivin units they occupy on the current disk and in units they would occupy on a single-density disk with a 1k block size. U Undo the effect of T (and take away the '*' or '#'). Commands that act on many files. -------------------------------- M Mass transfer of all tagged files to a selected drive and user area. This is the main reason for the program. If the target drive fills, the operation is aborted, with the untransferred files remaining tagged. This function invo a "New name:". In each case you may give any "ambiguous file name" in response. The logged-in directory, as currently displayed, is searched for matches with "Old name", and the files are renamed, if possible, by the formula specified in "New name". A '?' in "New name" means keep that character of the current file name, an * is equivalent to filling out the remainder of the field (filename or filetype) with "?"'s. Any other character replaces the corresponding character   e b, user area 1, and select only PLI source files. S Calculates space remaining on a drive. X Exit to CP/M. ? Redisplay menu of commands. Tags. ----- * Marks a tagged file. See M and E commands. # Marks a previously tagged file that has been transferred by the M command. It is logically untagged, and the # can be removed with the U command if it bothers you. Files marked with '#' can be retagged with the A command. Unmarked files are untagged.  answers to any prompt will result in no action being taken. Exceptions are specifying a drive you do not have (see patch points below) or an illegal file name under the R command. It is legal to include the colon when specifying a drive and user area. Thus responding "B3:" is equivalent to just "B3", and "B3:FOO.COM" is the same as "B3 FOO.COM". Copy verification is done by computing a CRC checksum while writing the file. SWEEP then reads the copied file back computing it's checksum. The teteriorate too badly with large directories. (On the order of n*log(n).) The rest of the log-on stuff is either fixed - displaying the menu - or linear in the directory size - reading the directory and compressing it after sorting. On my system, a directory of about 99 entries takes 3.5 seconds to come up. Of this, about 1.1 seconds is used in the sort with the rest split about evenly between the operations before the sort and after the sort. (Disk access is not figured here, since my system uses tant a number other than 16 (0-15). Patch the byte at location 10CH. In addition, you may want to patch: CRC_polynomial If you prefer a different choice of polynomial, patch the bytes at locations 356CH and 3570H. If you know enough to have a preference, I assume you know what values to put in.  Remarks. -------- Whenever a drive is asked for (and on start-up), the disk system is reset. This is to prevent a disk from being 'read only' under CP/M, and to allow you to repeat operations on fresh disks (e.g., finish a mass transfer after a disk fills by inserting a second disk). It also means that you should be free to switch density and/or number of sides of a disk in a particular drive. This, however, depends on how well your BIOS is written.It does mean, however that a system disk must wo checksum's are compared and you are told if they don't match. The algorithm used is based on the standard CRC-CCITT polynomial: x^16 + x^12 + x^5 + 1. The algorithm is similar to the one in D. Barker's corrections to CRCK, and it is now table driven. It is coded in 8080 assembler for speed, and is found in the file SWEEPIO.ASM. The second crc computation is done with a buffer that is offset 3 bytes from the original buffer. This is to help catch memory errors. Any CRC errors which appear buhe Intersystems CACHE BIOS with track buffering. Once the directory is read, it doesn't need to be read again. Using the standard system raises the total time to 4.9 seconds, the difference being the physical disk access.) File transfers make use of as much memory as possible to buffer data. The V command buffers only 4k (or what's available, if 4k is too much for either your file or your RAM).This allows large files to be sampled quickly, without reading in the full file. Invalid or emptybe present in drive A:. There is no logical upper limit to directory size, nor to the size of a file that may be transferred. The directory size is limited by available memory, though, as certain information must be kept on each entry. You should be able to use well over 1500 entries in a 64k system. Figure 20 bytes per entry starting at 26k and running up to within 1k, or so,of the BDOS. (Note: later versions of SWEEP are about 2k larger.) The sort is done with quicksort, so it will not dt are not flagged as bad disk sectors are probably due to bad memory. The CRC verification takes approximately 2.5 times as long as the straight copy. Patch points. ------------- Two parameters should be set for your system. If you do not have a PL/I compiler, they can be set with DDT. number_of_drives should be set to the number of drives in your system. This will eliminate SELECT errors. Patch the byte at location 107H. It is currently set to 4. max_user Set this if you w  ͤ^>2h!"h5!8|;R8D!c>WU8C ^44~Rn5og#}4w4~og@ }3>!hjU4#!cx͹T>2h!hc>ͣU,4#4#>WU!c> WUͷ8+M>͈TG!h>ͣU!ch>͚T!hUUQ}2h*h:hogY4#c>GʹU4#c>GʹU4#!cx͹T,͍52h!h͓!h̀U4 >WU4#U!h jU5L?ͻ5!h6:h9!h~#RD! WU8 ^RD!CasB*h> hS8!c>WU8 ^!hX/RD!MasB4*hMX^#V> hS8!c>WU84+*hhS8!d>WU8!@i>WU8!'d>WU8 ^R: D>sE ^ ^#V"Ji*Ji~2Xi!Vi 5͈5"h{5"Li*h^#V>ogͯX#"Ni*h^#V#"Pi!"Ri*Ni"Yi*Yi*RiY !"Ti*Ti | *Li~!TiFeTր *Pi+"Pi*Ti#"Tiæ *Li#"Li*Ri#"RiÓ *Pi|!h~# 4*h#MX"]i4*h##MX"_i4*h###MX"ai4"[i!"ci*ai*ci))6#6*h*ai++*ci))s#r!ci#{*ai*ci))^#V"ki*ai++*ci))^#V"mi*ci+"ci*ki*miYx*ki"gi*mi"ii*gi*ii>ogͯX"ei*]i*[i*eiMXqT*iiMXw4:hog)))))~4*hMXw4+*hMXc>GʹUA52h!h4 {̈́!"h"h!!i"hÁ!h~#…!"#i#"%i*h"'i*'i*%iYz4*#iMX4*%iMXx͹T4*#iMX4*%iMXx͹T4*#iMX~4*%iMXA*#i#"#i4*#iMX4*%iMXqT*%i#"%iÕ*#i"hp 4~og+"9i!7i> "3i!cX*h##~og+++!8S"1i*1i*3iMX"3i!"5i#")i*h";i*;i*)iY 4*)iMX~og"-i4UI^#V"i*in&"i*i |/*i |>*i }3>*iGjU*i>WUURiD!asB!:d>$WU8 ^RD>sE!asB!^d>WU8 ^RD!asB!nd>WU8 ^RD!asB!d>WU8 ^&RD>sE!asB!d> WU8 ^RD!asB!d>WU8 ^R*D>sE!asB!d>WU8 ^RLD>sE!asB!d>#WU8 ^RnD>sE!asB!d>WU8 ^RD>sE!asB!d>$WU8 ^RD>sE!asB!!e>-WU8 ^RD>sE!asB!Ne>3WU8 ^RD>sE!asB!e>WU8 ^RD>MX>WU8 ^4!hjU!h!hjU!chx͹T!h~#!chx͹T!chx͹TRD>sE!c>WU8C ^6!chx͹T!chx͹T!h/6!chx͹T.6!chx͹T!h?06!chx͹TDRD!XasB!c>WU8 ^!hc>ʹU!h*2h!h"2hRAD>sE ^6!chx͹TY6!chx͹Tnͬ 6!chx͹Tƒ46!chx͹T˜M-6!chx͹T­)6!chx͹Ts 6!chx͹T!h͂0!h/6!chx͹T!hY16!ch*giY *[i*giMX*]ix͹T5 *gi#"gi *]i*[i*iiMXx͹T` *ii+"ii5 *ii*giY *_i*[i*giMXqT*[i*giMX*[i*iiMXqT*[i*iiMX*_iqT*gi#"gi*ii+"ii *ci#"ci*mi*giY*ii*kiYYC*ki*ai*ci))s#r*ii*ai++*ci))s#r*gi"kiu*gi*ai*ci))s#r*mi*ai++*ci))s#r*ii"miï t 1^#V"oi*oi!(d x͹Tš!*h"qi!"si*qi*siY*si*qi>ogͯX"ui4*uiMX>WU4*uiMXU*oi *)iMX~og)))))4*)iMX~og"+i:.iJ !"-i*+i#"+i*+i))))"+i*-i >ogͯX"/i*+i*/i4+++*)iMXs#r*/i*1i+*1iͯX*1iMX"/i*+i*/i4*)iMXs#r4*)iMX^#V*5i"5i*)i#")iR+ D!]asB*h> hS8!c>WU8*5i> hS8!c>WU8 ^R^ D!jasB!c>WU8*3i> hS8!c> WU8 ^Ro D>sE ^; R D!vasB!d>WU8 ^!Bi*2Ai:Ai¢ :Aiog+"Hi!Fi> "=i!cX*h##~og+++!8*=iTVS"=iR) D>sE!{asB! d>WU8*=i> sE!asB!e>WU8 ^R:D>sE!asB!e>WU8 ^R\D>sE!asB!e>WU8 ^R~D>sE!asB!e>WU8 ^RD>sE!bsB!e>WU8 ^RD>sE! bsB!f>WU8 ^RD>sE!bsB!f>WU8 ^R%D>sE!bsB!/f>WU8!h>WU8!hUU8!'d>WU8 ^4~=2i!i 5RTD!bsB!5f>WU8 ^qD!"bsB@!ìU ^!'di>v8"i!i*i#́TG!i>ͣU!iK!ìU!Gfi>͚T¶!ci>v8|!ci>v8|ͿRD>sE ^!ik!i jx͹T B26!chx͹T"6!chx͹T6!h6_4x!ch >}8|q4#c>GʹU4 c>GʹU~!hc> ʹU4 6?46?4~=2h!h 5:h2h:h2hþ:h2h:h2h4"i!is5!"h:h2h:h2i:iog:hogY\!i͔54" i!i952h:hU*h#"h4#:hog)))))! i>GͣU! i4*hMXjU4 :hog)))))!i>ͣU!i4*hMXjU4 :hog)))))~4*hMXw4:hog)))))~4*hMXw:h4*hͣT*ui#"si*ui+"qiæ*h*siY-!"si*siÐRQD!asB!3d>WU8 ^!yi*2wi:wic:wi4w!hxi>GʹU:h2h!hh>͟U?^#V"}i*}i~og>hS!ijU*}i~og |!i{̓TG!i>ͣU!i>̓TG!i>ͣU!iUUUH^#V"i*i"i>2i*in&}2i:iog:iogY?*i:iog>w!i4*iUUUÞ^#V"i*iUU!c>WUͷ8"i!i~#ʒ*i*íTG!i> ͣU!i͡UÝ!:d>WUU^#V"i!i6!"i*in&"i*i*iY*i*i]|TG!i>ʹU!i!i T*i#"iü!iUU  U!iRD>sE ^üj~# !4*h#MX" j4~* jw4*j^#VMX* j#>GʹU4*j^#VMX* j >GʹU* j 6?* jc>GʹU*j> ͈T* jG>ʹU*j > ̓T* jG>ʹU* j6* j6?* jc>GʹU4*j^#VMX"j!j͔5* j"j!j95ʥRD>sE!'bsB!Hf>WU8!h>WU84*j^#VMX"j!'d>WU!j͓1U8*j> WU8!Wf>WU8 ^!j͵'RD!8bsB!gf>WU8 ^*j"j!jX/RD!?bsB!lf>WU8 ^4!!jjU!kX/R#D!bsB!f>WU8 ^4!kjU!k! kjU!f kx͹TT!k̀5V!kF5RyD!bsB!f> WU8 ^>é RD!bsB!f>WU8 ^4!!kjU!k!fͣTʹ4"$k!"k4+*hMX!cx͹T* *h4*hMX^#VY"h*h4+++*hMX^#VY"h*h+"h*h"k*h"&k*&k*kY 4*kMX4*k#MXqT*k#"k= *h*hY R D>sE ^!"h"R D>sE!bsB!f>)WU8 ^4!0kjU!.k!cͣT2-kR!D>sE!bs!j*j]> ͈TG!j>ʹU!cjx͹TH!j*j]> ͈TjʹU*j#"j*j#"j*j"j*j |!j*j]> ͈TcʹU*j#"jX!jj> ͣU!jkUhj~# ¤4*j^#VMX>WU!f>WU4*j^#VMXU1U!j jU!"j*j |e*j*j]> ͈T!j*j]> ͈T͹T*j*j]> ͈TG!c>͹T[*j#"j>ò^#V"j*j!f>v8"j!j~#ʽ*j*j+M|TG!j>ʹU*j*j#́TG!j>ʹU*j!j>ͰU!jf>GʹU!j6!"j*j |:j/4!j*j]>8!g>WU8 ^>*qk"k!kF5*ok 6*qk6*ok"k!k^5_%R]%D!bsB!g>WU8 ^4*Ek^#VMX"k!k͔5*qk"k!k)5NS2h4*h MXY >@ogͯX"ck:h%!"ik*ik"kkR%D>sE!bsB!g>WU8 ^*Ek"k!kX/R3&D!bsB!g>WU8!ek>WU8!k͓8!'d>WU8 ^:hW&RW&D!bsB!g>WU8 ^*qk#"mk!Kk6!Jk6:Kk'!"ak*qk~=2k!k 54*Ek^#VMX"k!k͔5!"_k*ck+"k*k*_kY/:Kk/ '*mk*ak)"k!ks5*ak@ "ak*qk"k!kN5'!Kk6*_k"c!j!jjU!fjx͹T&!"j̀5'* j~ORLD!DbsB!f>WU8 ^lRlD!KbsB!f> WU8 ^*j"$j!$jX/RD!RbsB!f>WU8 ^R D!WbsB!h>WU84*j^#VMX"&j!'d>WU!&j͓1U8* j>WU8!f>WU8* j>WU8 ^!jf>GʹU* j~TR;D!cbsB!f>WU8 ^4!*jjU!(j!jjU!fjx͹T»* j"-j!+jf5* j4*j^#VMX>GʹU* j4*j^#VMX>GʹU0RD>sE!hbsB!f> WU8 ^D!mbsB@!/j̀U ^!/B!$g>%WU8 ^4!3kjU!1k!IgͣT2)k:)kW!RW!D>sE!bsB!Jg>WU8 ^Rh!D>sE ^!*k6!"+k*h"4k*4k*+kY/:*k/!4+*+kMX!cx͹Tʸ!:-k!!!:-k!!*+k#"+ky!?":)kr"R!D>sE!bsB!dg>WU8 ^!6kX/R!"D!bsB!lg> WU8 ^4!:kjU!8k!(kjU!f(kx͹T["4"=k!;k2ho"!c(kx͹To"!*k6"R"D>sE!bsB!ug>WU8 ^!?kX/4"Ck!Ak2h 5"4!(kjU!*k6 *Ek~# "*Gk~"*Gk~og@ }3>!ekjU4*hTG!c>͹T*!j6!j*j>̓TcʹU*j#"j!j6!"j*j |:j/!j*j]>͈TG!c>͹T‰!j6!j*j>̓TcʹU*j#"j?!j>WU!f>WU!jU1UU^#V"j4"k!ks5*j"k!k952j:j>3>4 :jog)))))ͣT >|k~# 4*h#MX" k*k~* kw4*k^#VMX* k#>GʹU4*k^#VMX* k >GʹU* k 6?* kc>GʹU*k~=2k! k 54*k^#VMX"k!k͔5!k͵VRD>sE!|bsB!gf>WU8 ^*k"kk*_k#"_kó&!"ak*ok~=2k!k 5!k͔5!"_k*ck+"k*k*_kY/:Jk'*mk*ak)"k!ks5*ok"k!kV5t'!Jk6!Kk6:h'*mk*ak)"k!k5"ik*ak@ "ak*_k#"_k2'k&*ok"k!k15NS2h:h:Jk(*qk "mk*ok6*ok 6*ok"k!k)5NS2h!Kk64*h MXY >@ogͯX+"ck:Kk(!"ak"_k*ck+"k*k*_kY/:Kk/(*mk*ak)"k!ks5*ok"k!kN5u(!Kk6Ë(*mk*ak)"k!k5"kk*ak@ "ak*_k#"_k4((*ik*kkY(!Jk6R(D>sE!bsB!g>WU8 ^:Jk)R(D!bsB!g>WU8 ^*okj!'d/j>v8#́TG!`j>ͣU!^jK!/j̀U!f/j>͚T:!ujk!Dj jUReD!rbsB!f> WU8 ^D!wbsB@!/j̀U ^RD>sE ^!/j!'d/j>v8#́TG!yj>ͣU!wjK!/j̀U!f/j>͚T!jk!Pj jU!"\j*h"j*j*\jY!j͟!j3!j jU!j*\j#"\jR/D>sE ^Üj~# 84*j^#VMX>WU!f>WU4*j^#VMXU1U!j jU!"j*j |*j*j]> ͈TG!j>ʹU!cjx͹T!j*j]> ͈TjʹU*j#"jÔ!"j"j*j |R#MX"ok*ok#"qk*Gk~*okw4*Ek^#VMX*ok#>GʹU4*Ek^#VMX*ok >GʹU*ok 6*qk*ok$qT4~*qkw!hekx͹T­#*ok {͈T}gʹU:h#4*Ek^#VMX~2fk#:h2fk!sk͔5*ok"wk!uk͵Y$RV$D>sE!bsB!ek>WU8!'d>WU!yk͓1U8*ok#>WU8!f>WU8*ok >WU8!~g>WU8 ^>*ok"}k!{kF5!hekx͹T4*Ek^#VMX~!fk %*qk"k!k͵%R%D>sE!bsB!ek>WU8!'d>WU!k͓1U8!f>WU8*qk#>WU8*qk >WU   6?*ok"k!kF5)!hekx͹T)4*Ek^#VMX~!fk:hx)Rx)D>sE!bsB!h>#WU8!2h> WU8 ^4*Ek^#VMX~!fk)*ok*qkqT*ok"k!k95)*ok"k!kF5!kf54*Ek^#VMX"k!k͔5*qk"k!k15NS2h:JkJ-k~# *!h6R?*D!bsB!Rh>WU8 ^Rj*D!bsB! c*k^#VMXUU8 ^*k^#V+++|,*D!bsB@!k̀U ^!Xhk>͚T§*>!'dk>v8}2k:k*!k:k_|TcʹU!ck>v8}2k!kK|TG!l>ʹU!l*kj MXY >@ogͯX"Tl*Tl> og 8"Tl!Nl6!Ol6:Ol:Nl/4!"Rl"Ll*Tl+"_l*_l*LlY/:Nl/3*Wl*Rl"cl!als5*Rl "Rl!elN5ʚ3!Nl6*Ll"Tl*Ll#"LlS3!"Rl"Ll*Tl+"gl*gl*LlY/:Ol4!"Pl!h>T!h>TETQ"il*il*PlY/:Ol:4*Wl*Rl*Pl!Kl>GʹU!hKlx͹T*4!Ol604!kl4*Pl#"Pl3*Rl "Rl 5x44!KljU!hKlx͹Ts44!KljUx4!Ol6*Ll#"Llô363!ml15NS2hR4D>sE ^_^#V#Nͨ4WY *%o**%o{ozg4|g}o!\!l!3>ͨ4Ybhx͹T9/R-/D>sE! csB!ph>WU8 ^!9lX/!;l͂0*5l#"5l.RT/D>sE ^/^#V"=lR/D!csB!h>WU84*=l^#VMX"?l!'d>WU!?l͓1U84*=l^#VMX>WU8!f>WU84*=l^#VMX>WU8 ^<0^#V"Al*Al^#V*hY|/0R$0D>sE ^*Al6#6;0*Al^#V#r+s0^#V"Cl*Cl^#V+|r0*h*Cls#rRo0D>sE ^~0*Cl^#V+r+sV1^#V"El4+*El^#VMX!cx͹T 14+*El^#VMXc>GʹU4*El^#VMX^#V*h"h4+++*El^#VMX29 9BZ!9*9!9~#?9> ?!9&9T9x2o`y A92p`"ol:E?:u`+9-/2s`::f:\: `: ;:M:.}:::}:;:n:eʇ:E::+—::à:- :::YG::Ҿ:xGGG::GyO: Y:::n`:;:y2r`:~#z0 U:k*+!ḱTG!h>ͣU!hXh> ʹU[,!k:kog++M|TG!h>ͣU!k:kog#́TG! l>ͣU!lK!k̀U!ck>v8!ck>v8|ʝ+!lk!k̀U!fk>v8}2k:k+!hk> ͰU ,!k:kog+M|T!h> ͈TʹU!k:kog#́T!h > ͈TʹU!h> ͈T4#>ʹU!h > ͈T4 >ʹU!hK> ͈TG!c>͹T2h!Xhh>͚T},!hh>͟U:h2hý,!ch>͚T“,>2hý,!hUU!Xh> WUͷ8|ʰ,>ý,!hUUQ}2h*h:hogY,>-,D!bsB@*kjU ^*k!bh>͹T!5* >  ͨ4YͰ4Ͱ4Ͱ4Ͱ4Ͱ4Ͱ4Ͱ4Ͱ4Ͱ4Ͱ4 ͨ4Y Ͱ4ͨ4yg)Ҷ5|g}!o ª55x!ͦ5r#s#5Ͱ4Ͱ455_5go5^#V*h"hRU1D!csB!xh>WU8*h> hS8!h>WU8*h> hS8!h>WU8 ^?2^#V"Gl4+*Gl^#VMX!cx͹T1*h4*Gl^#VMX^#VY"h*h4+++*Gl^#VMX^#VY"h4+*Gl^#VMXc>GʹUR22D!"csB!h>WU8*h> hS8!h>WU8*h> hS8!h>WU8 ^*Gl"Il!Il/å44*h#MX"Yl4~*Ylw4*hMX*Yl#>GʹU4*hMX*Yl >GʹU*Yl 6*Yl 6R2D>sE ^4*hMX"[l![l͔5!]l)5NS2h*Yl#"Wl4*h0!v`_w!n`~ ;4_!^`sYY2q`G:r`<2n`=Y:^`Y͆;^;:^`^;!r`5!u`4Y:p`G:o`l;!s`';>2t`ͩ;?!o`5x;:p`!r`<_!^`>w w>+Û;!q`~5>.;G:t`x0;:q`> !s`~;5!q`4!n`5-2t`x!n`^4{;;!^`~0>0"ql*\`~2ul:s`<͖><Y:ul2vl>V̓>!vl*<5~/o :v``<>9̓>`<>*̓>N< P<*:vl!9q#=W>2wl<2xl2yl;2tl:xl_:ulf>*\`~2sl:sl9<:wlʳ<:wl2wlv>³<:yl=O:wl>>:ylO:tl>m>l >=->*k"!l!!l*kjU*kn& "k:hog*kY*k+|B->5*k}.Rj-D!bsB!c>WU8 ^!)l*2%l:%l|-:h-!(l6Ð-!(l6!&l6!"#l*h"-l*-l*#lY/:&l.4+*#lMX!cx͹Tj.:(l-4*#lMX~2h!/l͓!h̀U!1l"2&l:&lj.4+*#lMXbh>GʹU*h4*#lMX^#VY"h*h4+++*#lMX^#VY"h 5.4!'ljU!&l6*#l#"#lá-:&l.R.D!csB!ch> WU8 ^R.D>sE ^U/R.D>sE ^!"5l*h"7l*7l*5lYC/4+*5lMX!|8|{z7|XDMXogY28QYp8QY!9V+|;83333h8!!U/<|XF}8ʩ8Oʩ8 8# ʭ8‹8è8ˆ8gl8~ 88#8#8H o&&?"\`!  :wl2wl:ylO:tl>m>l<:slv>¬=:sl>]=:sl>F=:ylO:sl>>m>r<:sl2wl:ylO> >m>r<:wlʜ=:tl0y=:ylO> >æ=:yl=O:sl>>:ylO:tl>:wl2wlæ=:ylO:tl>m>l<:slV=:wl=:wl2wlv>=:yl=O:wl>>:wl=<2wlq>r<:ylO:slʹ>>:wl >:slB>>:wl*>> >m>r<:ylO:slC->D:s`@>> > >]>:slCT>> >R>]>> >B>m>m>r<:vl*ql!yl4!xl4S+-$G:ulOx*\`## ><>S̓>>+̓>>-̓>>C̓>>D̓>:/,.B!xlN*\`# Ⱦ>G:xl_:ulO x*\`# Ⱦ>!i#9w$G:s`"n!nG! 9^#n~# G*#n^#V|1G*#n*%n qT*%n nbfG*%n !(n>ͰUÀG!n>WU*#nU!(njU*#n~#¬G*#n^#V)))|G*#n6P#6*#n~#G*#n^#V))|G*#n6#6G*#n6<#6*#n6#6*#n6#6*#n6#6*#n 6*#n^#V}ͳQ}2'n*#n^#V}=H!'n44*#n^#V}SH>2'n*#n^#V}~H*%n~#~H*%n6#6*#n"@n*%n"n!6nL*#n^#V|»H*#n"Jn!"Ln!BnͿZ^#V^#Vt^:`H!HͿZ2`O!`H6H +~#w!` s#r!`4,^ICC` C C Format Overflow*`-&`!l_CO:`y\C!9GXC~#'ICICy_CO:`nC÷CCwC{C*`|ʨCj& *`*{`Y#Y> C> CC> C{=>'C!9C=~#'C{>'CCýC{=>'C{>bC*{`++|2Rm!Pm FɯD>D>2]m"^m"`m`i"bm!9"dm!Sm+Dm ~# 0D*m~D*m~tD!m>WUG3!!!`F!`"m!mͼHÜD!m>WUG3!R.!!`F!`"m!mͼHñD*m"m!mͼH!mG*m^#V!`s#r*m^#V!`s#r*m^#VkT|*`kT|GD!mYE*m^#V}G:OM*OpM4#6O͢I:O3ML*O++"OO*Ow#wOlI͇IOKvIqOlI͇IOvIN$LO*O~" 4#4#4lI͇IO~CNyNQO͛K>͈NOlI͇IO~̛K>͈NO*O~pN>OyNQO*O!*~!/2O*O|ʝN(^#V͢I͢I{zڰNzO2OzN:ONKqNN$L#úN*O|O*~O=!OO:O_L?x+-#?S?x+#?-S ?>+>-> wB ??x=9?Gͮ?&? f?:`O?`?!}`x&?`??&?F&? z?&?> ?l? Œ?x†?>?&? —?ͮ?&?x¡?>&?=Fá??x!{`??î?:`??:{`> ??>2l!}l|E:`@!{`@> @> @ @2|l!zl FB'@y<>.@= .@¼@OmBoA####WʹAO@60#u@EV@>ew#.`@eg@xu@A O@ͿAGZ+y=@x=@0 ڠ@60$â@w ¬@+6.$y=@x=@'Ax<A!9A A @ @w# Y@H !9 @+w@I`I I I/O Stack Overflow:`>I!w`"Sn!OnM;I!Nn6II:`2Nn!`6:Nn XI*{`#"{`:Nn hI!{`6#6:Nn"O"O*O^#V#"O^#VvI͂I"O͂I"O|͇I|~vI͂IyaҷIA =.:;<>[]y *OͩI IIͩI$IͩI1J o&))))\xH  J#w JII*O#MJAMJGIͩI:RJ 6WJp4I+I|J#ͩIʈJ#*tJ6?xJwIcJͩIʏJI|J#6 ˆJ.JI IʼJͩIJ#*´J6?øJwI£JͩIJIüJ#6 J%#6J*O##^ ~?J# JxCON CON RDR PUN *`}GE!mYE:`=E*m^#V}*`}G=E!mYE:`XE*m^#V}XE!mYE^#V"m!`"m*m"m!mͿZ2m!m|E^#V"m:`E:`E*mE*m5!m6:m ʱEEãEÒEE!m F*mE*m5!`6!m F:`E*m6ýEI2m:mF!`"m!"m!mͿZ!{`6#6!m6 :`F!m F^#V"m!w`"n*m"n!mNVF!`" n!" n!nͿZSFF:`F*m~ pF*{`#"{`F*m~ „F!{`6#6F:`F*m~ ¦F*`#"`!}`6#6F*m~ F*}`#"}`!}`#F!}`6#6*}`*`#Y|F!`"n!"n!nͿZFF!`6"n!9O OwNN>lI͇IO|}O~> OO"N#F#~vIq#p#w>OlI͙IO>O*~͢I!ʵO=ҧO>!*O" s#r#w=O*O }!n6 4>2n*n!4#4#4~#N#F#y#x#:n*n!!:n?PPO:n~G~#~O?~P#~~P! p! y! q<‚PO>G!$q#p#6xOo>g9x AY A Aw#AmB=1A<mB<_mBKmB ?AoWA##ʹAʙAK0Y nA0_Y nAYK0w# {AxʙAA XAͿAGZʯA+wäAxAʴAxAYÿAo>g9##AY A A YIB!lͿZ> wB BBIB ,Bx&B>dBB 5BBbBx!{`JBbB5B:`UBbB:{`IJB>2l!l|E!lÿZBC^'C^#VʴB’BBwB#FҭB#N­B#^#r+s#^#V++r+s~wB5wBC5^'Cq#pwBOC4~ B_'Cs#r#s#r#q!BÿZLST M!K ~I$€KIͩI1LK\3Kl€K$€K!~ €KI!JͩIgK uKI#TKx=GQKI>ɯ*O+͂K^#V͊K#{#z͂K6#6͊K r+s!UnF#~K!Un6P  ͊^ ͊^!Vn^r+s6 #6 !Vn4^N*O|L}=KͱK L K LO>~LL>_LN*O|ILY K=6LyBL͊^EL>~UL=UL>_Lq2O*O/"O͑KڶL{͛K͊K*O*O#:OOʟL͊K#s#rèLͤK͑KxL͛K_L͊Kr+s{L!O4*O+>|L+}olIvI~2OvI"O͇I:OMKM"   Q"n"n2nx2nO2nO!n~5ʭQ$POQ=zQ:nzQ*nGx|g}oúQ"n>wR*n"nQQ*n"nQQ*nG!9!xPR KR+R$%YgKR-R0Y:Y0T])Y)YY)Yo|gYR{`R$%Y}aR|Yz-Xo&9}O!9 w#…R60#60! 9~ R!97>?'w#¥R-!9~RR~#RºR! 9~.R+60R0R6 #R+r>o&9y>o&$[!`{#z*`*` ^xyx0[͈[_!\^#V[͂[>(̈́[yͻ[>)̈́[|e[w[L\|q[w[[[_>,̈́[͂[> _Ê^ ͊^ Ê^0:ڄ[Ä[͒[Ò[͂[|͠[}à[ [d[ [[[x͒[N #~̈́[[!\[*o!9{_z\{\ &\$\͂[>#̈́[*o>=^#V#ͬ[&\=\>: G\>?̈́[!\[[>=̈́[^#V||\}s\.))+][#F>A8\> #—\~ >.=\~ =\=È\^#V# File: Traceback:\\\\\ ]]&] ERROR FIXED OVERFLOW OVERFLOW UNDERFLOW ZERnr#q#pW*n"n!nw!nr#q#p:nG:ńX:nG:ńX:nG:ńX:nG:ńX:nG:ńX:nG:ńX lW rW yW|e. ҃Wo&:n*nDMW"n!W^#V!9*n3333!W^#V!9!33333333###~WGOW_goހ_W+~G~+N+f.zXzX ))XX}*X$*X*X*XxNY>IYyƀGOS\{ÉXD́XzÉXD́X\e. oX uXS\e. ҀX.HEg)ҋX )ҐX )ҕX )ҚX )ҟX )ҤX )ҩX )ҮX z|XDM|XXXx>2Y!>)X X=X)Xɯo>g^#V#N#FSYSPRINT     $ ' '                   90w+S6.!9W}!)SY/fS)Y=ZS|/G!S ±S>0S ¶S>-3ST]))S寕iO>`G>0 S og|TX!W>Tw#>T!9!7>?'w#QTȇeT)kTyw# qT~#ÈT~#W #T!9Oo>gyUO DIVIDE END OF FILE UNDEFINED FILE KEYNULCONCONRDRPUNLSTBADG!a~s]X]` Condition Stack Overflow$4Ox!n w#s#r#s#r!9!a s#r!aN!n +++++¬]#{]#z]++~ì]++!a5!~# ]]!aN!n +++++]#~#^+{^#z^++~]#^#V=!`~t^5:`_!`^#V"`w`.~# F^*`)))))` )| [^*w`|}*:a"{`:`*`w`w# ^*:a{ қ^ Ÿ^!#":a^Copyright (c) 1980 Digital Research, v1.3 !"#o"!o"'o2a2`**o _"oq#p##}o"%o{ozg||/=!YÿZ Y!Y"Y$Y&Y Conversion2DY!;YÿZCYDYEYGYPY2fYx2eY!]YÿZeYfYgYiY#}OD*%o~ҭY##~#fotY!YÿZYYYYY Free Space Exhausted##^#V#{_zWvZ{_zWyY4zY{Y##^#V# ##s#rs#r#s#r+++~sw#r####}*%o}|pZ*{zpZ+F+N+V+5^{vZ{zvZ}|vZ{PZPZi`~sw#r##q#p i`N#F#^#V~vZq4#p+i`##s#r|Z`Z` FREE Request Out-of-Range$ Free Space Overwrite$GKZMbkZͤ\Fͣ\Nͣ\N#Fͣ\^#V"ay2axZi&]![Zx[>  and user (and v to verify): and user: : Sorry, CP/M2.2 is required.??*1234567890 No files. . k :LSX ABC ToDEMRTUV???????????? Files occupying k(k remaining) Which******k remaining on Drive : NewSWEEP version 3.8 - October 18, 1982by Robert FisherDePaul UniversityChicago, IllinoisCommands:A: Again. Retag # files.B: Backup to last file.C: Copy file with optional verify.D: Delete file.E: ~#o>gxGUGʹUwF#"nxWU1U*n!9G_>WObk++QU~+IUy~#/2YX#"n"n`i"nW*n"n!nw`i"nVV"n*n*nV"nV"n*nMXVX*n*n|VX*nVX*n|V)))ڠVàV*nV*n))қV)ҠV:nO:nGzVzV ))үVïV:nWXDM>!=))V VV|g}oͱWV͕WVW2n"n!*}o|_``+w+w+r+s4w#w#s#r<2)o++*#os#r"#o*!o#"!o*!oDM!#ox~_#~+_+F+Nq#p*!o+"!o__=”_!+~O~#~G!>w!/x¼_y_ >O6# ³_ ʣ_=ɯ ~#fo++R_!!o~#`*#oI__&``8`  Insufficient Memory$ Invalid I/O List End of Execution$M` 8 8 8SYSIN#   Erase all tagged/untagged files.L: Login new disk and user and reset system.M: Mass copy of tagged files with optional verify.R: Rename file(s).S: Space remaining on disk.T: Tag file for transfer.U: Untag a file.V: View a file at console.X: Exit to CP/M.?: Redisplay menu.sp or cr: Next file.Drive New name or * : Cannot rename. already exists.File is R/O. Okay to rename?(Y/N)YO.K. to rename Renaming ====> . ? Old name: New name: is R/O. Delete anyway?(Y/N) Deleted. Delete? (Y/N):Eras,o will not deteriorate too badly with large directories. (On the order of n*log(n).) The rest of the log-on stuff is either fkk kk k k!kh0k3k+k:k+k+k+kfkwkfk}kkfkkkkfkkkkkfkkkikkkkkkkkkkkkokkl lkc'lh#l%l5l5lYlclYlKlYl|llll`llll`ll Invalid Format Itembt equ 0 ; prstr equ 9 ; tab equ 9 lf equ 0ah cr equ 0dh ; ;USER customization parameters maxuser equ 15 ;maximum user area (may be in range 0-31) numdrvs equ 4 ;number of drives in your system ; ;set selected drive lxi h,fcb+1 mov a,m cpi ' ' jz usage ;no parameters cpi '9'+1 jc digit ;no drive was specified ani 5fh ;make it upper case sui 'A' jc usage ;illegal character cpi numdrvs jnc usage ;too high a drive specified mov e,a lda cdrive ;put new drive into lower ne tagged or untagged files? (T/U) : Do you wish to be prompted? (Y/N) : NType A at prompt to abort.Erase ?(Y/N/A)Erasing $is R/O. File not copied. is R/O. File not copied. Out of directory spaceCopying =====> with verification CRC check failed. Error. Disk full. Warning: source = target. Re-log drive for an accurate directory. drive0123456789#****Aborted.Tagging Total of tagged files = k (k) Total of tagged files = ( hhh hhhhchQhhheh; U.COM - VERSION 1.0 ; BY ROBERT FISHER ; November 27, 1981 ; ;Select drive and user area with one command. ; ;Usage: ; U B4 ;will select drive B:, user area 4. ; ;The drive may be any valid drive letter in upper or lower case, ;and the user area may be any user area in the range 0-31. ;(But see the customization area below.) ;Either may be omitted. If both are omitted, a usage message is printed. ; ;To be useful, this program must be accessable from all drives and ;all userRm]m^m`mbmdm Stream/Record Sequen/Direct Input/Output Keyed Access P< $conmmw`mfmtmmmmmmm mmmmm mnmm nmmn.dat'n(n@n!n"nJnLnSnNnibble of cdrive ani 0f0h ;zero out old drive number ora e ;slip the new drive in sta cdrive ;this sets the drive ; ;set selected user area inx h mov a,m cpi ' ' jz warmbt ;no user area specified digit sui '0' jc usage ;non-digit cpi 10 jnc usage ;non-digit mov e,a ;move it to e to preserve it inx h mov a,m cpi ' ' jz setusr ;one-digit user sui '0' jc usage ;non-digit cpi 10 jnc usage ;non-digit mov c,a xra a ;clear the carry bit mov a,e ;get first digit backih i i02ie+hh<h> O 9i  d@iHi ./Xi-&')*+(%128dxiiiiihiGfij j!j j*j-j`j/jyj/jDj\j\jjfPj\jj areas. ;This is no problem if you are using one of the modified CCP's, but ;requires some other mechanism for a standare CCP. ; ;Check the public programs: DUPUSR21.ASM and CCPPATCH.ASM or the ;various versions of CCPZ.ASM ; ;One further note. Your BIOS must be correctly written for this ;program to work. Specifically, it must not reset the user area ;to zero on warm boot. (The California Computer System BIOS ;fails in this respect.) ; org 100h fcb equ 5ch bdos equ 5 cdrive equ 04 warm$   ral ;x2 mov e,a ral ;x4 ral ;x8 add e ;x10 add c ;add in second digit mov e,a ; setusr: mov a,e ;get it back if it's not there already cpi maxuser+1 jnc usage cmc ;clear the carry bit ; ;User area goes in upper nibble of cdrive. ral ral ral ral mov c,a lda cdrive ani 0fh ;zero out old user number ora c ;slip in new user number sta cdrive ; ; jmp warmbt ;Print USAGE message if no parameters provided, or if parameters ;are illegal. usage: lxi d,message !a{   `OE!y6$ -7rBo&))T])))!y n}x! ! n}!91.9 6-12-82File unsqueezer version %s by Richard Greenlaw 251 Colony Ct. Gahanna, Ohio 43230 Accepts redirection and pipes. Usage: usq [-count][-Fcount][-N] [file ...] Parameters are from command line or one-at-a-time from standard input and are output drives and input file names. Empty to quit. *(;s mvi c,prstr call bdos ret message db 'Drive and user selector: U.COM - Version 1.0',cr,lf db tab,tab,tab,tab,'by Robert Fisher - November 27, 1981',cr,lf,lf db 'Sample usage:',cr,lf,lf db tab,tab,'U B4',cr,lf,lf db 'selects drive B, user area 4.',cr,lf,lf db tab,tab,'U 13',cr,lf,lf db 'selects user area 13 of the current drive.',cr,lf,lf db tab,tab,'U B',cr,lf,lf db 'selects drive B, current user area.',cr,lf,lf db 'Lower case is acceptable for the drive letter.',cr,lf db 'The dr*K͞+@0;M'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o!]~ i:+_Aii_:2#~ 0i i_#~ Q0i iO{__{i?O:2r Drive and user selector: U.COM - Version 1.0 by Robert Fisher - November 27, 1981 Sample usage: U B4 selects drive B, user area 4. U 13 selects user area 13 of the current drive. U B selects drive B, current user area. Lower case is acceptable for the drive letter. The drive or the user area may be omitted. $FWcmuTOLOWETOUPPEATOFPRINTISALPHPRINTUNSQUEE!9DM! ~#fon}-! ~#fo#n&|P!:M4å!!9DM! ! ! ~#fo! !"7M}2:M>2+H>:2,H>2-H`i6#6`i~#fo! ~#fo%! ~#fo`i~#fo)~#foM `i^#Vr+s! ~#fo| *@}w! !% !Ͳ!{ !Ͳ! !Ͳ! !Ͳ!J !Ͳ`iw#w`i~#fo| ! s#rz³! 6 #6`i~#fo! ! ~#fos{ `i~#fo! 6`i^#Vr+sÊ! n} ! M ive or the user area may be omitted.',cr,lf,lf db '$' end #z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77%  ! n}w!91.9 6-12-82File unsqueezer version %s by Richard Greenlaw 251 Colony Ct. Gahanna, Ohio 43230 Accepts redirection and pipes. Usage: usq [-count][-Fcount][-N] [file ...] Parameters are from command line or one-at-a-time from standard input and are output drives and input file names. Empty to quit. *!9DM! ~#fon}- ! ~#fo#n&|… !:M4 ! ~#fo#n& |͝}29M}ʳ ! ^#Vr+s!"7M! ~#fo#n} ! ~#fo#H "7M| ! ~#fo#! !Ͳ ! ~#f!Ͳ͍,*6!! ~#fo`i~#fo)~#fo%|K*n&|g}osÅ*##4! ~#fo`i~#fo)~#fo#*###s#r! ~#fo`i~#fo)~#fo#n}! ~#fo`i~#fo)!s#r! ~#fo`i~#fo)*s#r*#n&|g}os! ~#fo`i~#fo)~#fo#n}!!Ͳ͍,! ~#fo`i~#fo)~#fo#͐,*#! ~#fo`i~#fo)~#fo###|€! ~#fo`i~#fo)~#fo#!!Ͳ͍,*#4*##n}%`i~#fo! s#r! ~#fo! ~#fo~#fo! ~#fo! ~#fo)! ~#fo! ~#fo#)~#fos#r! ^#Vr+sÞ! ~ ~#fo|! ! m#! ! ~#fom##|M! !3!ͲÄ! ~#fo*)Hʄ! !m#! !F!Ͳ! ~#fo|ʩ! !m#Ä! ͕$! %`i%! 9Can't open %s %s is not a squeezed file %s -> %s: %s has invalid decode tree size Can't create %s Write error in %s ERROR - checksum error in %s !"2L!c".L!9DM*2L|ښ*2L+"2L*4L! ~#fo `is#r!p|`i~#fo"4L*4L#|!0u"2L*4L! ~#fo "2L|!*2L++"2L*4Ls#r͐y~#fo! s#r`i6#6!l w#w!J-! s#rz>!×!o 6#6͐o͐Ҁ! ~#fo͐o)~#fon}!͐o+| ! ~#fo͐)!s#r! ^#Vr+s!l ^#Vr+s)!D ! ~#fo͐o)~#fo#s#rr! ~#fo͐o)~#fo|$! ~#fo`i^#Vr+s)! ~#fo͐o)~#fos#rr! ~#fo͐o)~#fo! {-!. !B s#r! ~#fo͐o)~#fo#n!/ s{:­! ~#fo͐o)~#fon!. s!0 !B s#r!. n&!9-!- 6! !- n}!!9-!, s!, n}a!- 6!, n& ?͐o#n}:s ! ~#fon&!|Y ! ~#fo##n}V !"7M! ~#fo! 3!! ~#fon}2+H s ! ~#fo! !Ͳ ! ~#fo`is#r`i~#fon} `i~#fon}*ʧ `i~#fon}? ! ~#fo! !Ͳ `i^#Vr+sÁ ! ~#fo8 !9 BAD COUNT %s Output drive =%s ERROR - Ignoring %s Can't accept ambiguous name %s!9DM`i! ~#foX!#|q ! ~#fo!!Ͳ! w#w!")Hdm`i͘!|ʯ ! ~#fo!!Ͳû`i͘!! s#r6L! s#r! ~#fo`i!s! ^#Vr+sn} ! 6!+H! ͹"#fo^#Vr+s`i^#Vr+s*^#Vr+sW! ~#fo! ~#fos#r! ~#fo! ~#fo~#fo)w#we! ^#Vr+s`i^#Vr+sC!9Can't open %s Z! ~#fo`i~#fo)~#fo#n}º*! ~#fo`i~#fo)~#fo#X!#|! ~#fo`i~#fo)~#fo#!zBͤ! ~#fo͐)!. ͌&#J-s#rz8!×!. ! ~#fo`i^#Vr+s)~#fo&ó!n n&!9-!o ^#Vr+sG!o w#w͐o͐lu!q 6#6͐q͐g!n n&! ~#fo͐q)~#fo͐o)!D ~#fo|Y͐q`i^#Vr+sY͐q!s s#r͐s͐V! ~#fo͐s)! ~#fo͐s#)~#fos#r!s ^#Vr+s ñ!q ^#Vr+sá!o ^#Vr+sÈ͐y͐s#r͐{͐s#r!×!u9*.*!9DM! w#w`i6#6͐|! ~#fo͐n} ! ~#fo! ^#Vr+s! ~#!6L! ͹"! ! ~#fo!3!`i͘!! s#r! ~#fo|U ! ~#fo|o ! ~#fo!!Ͳû!".H!"0H!  w#w!  ~#fo! ~#fo !  ~#fo)).H`i͘!s#r!  ~#fo)).H##`i͘!s#r!  ^#Vr+sà *7M|ʦ! ͹`iv! s#rzʓ! ~#fo*7Mғ! ~#fo|g}o! s! n&|P! n&|ڄ! n} m p { {~Ð! ^#Vr+sÄ! 6.! n&͹ *9M}ʣ! ͹û! ! ##|! !"!ͲÄ`iv! s#rzP*)H! ~#fo")H*:M}!roken pipe !9DM*n}M*!`is#r!|J*!`is#rf!9-`is#rzf͍,`i~#fo|{!ð`i~#fo|§`i6 #6*n}§! !9-`i~#foð!9!9DM!`is#r*#n}O! n} `i~#fon} *#! m#`i~#fo! ns*#! n&m##|7!!Ͳ͍,*#n&|g}o|Oô! 9-|o!9-+++|o͍,! n} ”`i~#fon} ʔ! !9-! n&!9-`i~#fo! ns!9File output error; disk full? !9DM!9-!n s͐{~#fo! &  fo͐ns`i^#Vr+sû! ~#fo n} F! ~#fo! ^#Vr+s6.`i6 #6͐|ҫ! ~#fo͐n} së! ~#fo! ^#Vr+s! ~#fo͐ns`i^#Vr+sM! ~#fo͐6͐!9!9DM! ^#Vr+sn`is{`in}*`in}?! ! !9!9DM! ~#fo#n}:w! ~#fo#n}:t! ~#fon&! n&n! ~#fo##s#rt!éþ! ~#fo#n}:ʾ! ~#fon&! n&¸! ~#fo##s#rþ!é! ^#Vr+sn`is{ʐ`in}? ! ^#Vr+sn`is{`in}.þ&͐'!9!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{b*`in}%L*! ! s#r! 6#6! s! s! s͐n}-¡'! ^#Vr+s! 4͐n}0±'! 4͐n&3+}'! 0,'!! s#r! ^#Vr+sn`is{.(! 0,! s#r! 4! ^#Vr+sn`is`in& }DE(Uʁ(Xʊ(Oʓ(C(S )6*͐~#fo|ҁ(! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 Ù(! 6Ù(! 6! ~#fo! n&! ^#Vr+s~#fo! ͎+ѯgs#rÂ)! ^#Vr+s! ^#Vr+s~#fos! r+sn}"͐#!9!9DM͐͐U.s#rz@#!͐͐s#r͐##6#6͐~#fo!9DM͐$͐>#>ʷ#>œ#>#>¨#>#>´#>#$! n&͹! n&!9-! n&!9-! n} $! !9-! n&!9-͐##^#Vr+s|u$!͐͐~#fo}.|T$!͐##6#6͐͐s#r͐^#Vr+s! ns&!9DM͐ڮ$!%͐##~#fo|$!%͐##~#fo`is#r͐͐͐~#fo}.=7*^#V#z -x28-+V+^+-*͞/:8-o&9!7:O* *p-+*|/g}/o#9t-p-#"z{7*~# ʂ- ʂ-+*&!7,2q*&:q):-=-=r:qo&7:)~:,"s!"u*|5.**s:.! ~5.6*u*+"*"*u#"u.7*͐,\!*͛-7:)~:,"s!"u*|*u.*~#º."*s*u.#"u*+"ç.7*|DM**/> !éÍ`in}*i͐n`is{>! ^#Vr+s`in}.;>͐n`is{f! ^#Vr+s`in}.cf>Í`in! ^#Vr+sn}‡þÍ!éþ͐n}£!éé!é!9!y9DM! `i'͐`iq*!9!9DM! n&*| ! n&  ! n&&!9DM! n&+|; ! n&B ! n&&!9DM`iw#w! 6#6͐ n! s{ { ! n} ‰ ! ^#Vr+s_ ! n}-¨ ! 6#6! ^#Vr+s! ^#Vr+sn! s3+| ͐ ?! nѯg`is#rè ͐͐? !9^#Vr+sÂ)! n})! 6#6! ^#Vr+s~#fo! s#r͐n}ʂ)͐|ʂ)! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s8)͐6! ! s#r! n})! ^#Vr+s!|)! ^#Vr+s! n})!0)! sÞ)͐! ^#Vr+sns{*! ^#Vr+s)! n}3*! ^#Vr+s!|3*! ^#Vr+s6 *I*! ^#Vr+s`ins_*! ^#Vr+s`ins@'͐6!9!9DM! ^#Vr+sn`is{*`in} §*͐! m#͐`in&m##|*!*y*!*!9!9DM! n&|ͯ+! n&|ͩ͐%!%͐+?`is#r͐##~#fo|ʤ%!͐͐͐.͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo6/%͐##6#6͐͐s#r!%!9!9DM͐%!͐~#fo͛/!9DM`iw#w! ~#fo͐n! ~#fo͐n}W&! ~#fo`i^#Vr+sn}T&!Ã& &! ~#fo͐n! ~#fo͐nѯgWÃ&!9!9DM`iw#w! ^#Vr+sn}ʹ&`i^#Vr+sÚ&͐&!9!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{'</~# x/ ><$/~+ x$/|}7:,*͹0:*X/}|2q ʉ//:qwz/! {w#7*!9& 6C#6O#6M/*|/!\&/!\&*|/!!l&!9~#fo%0> +͆0#~0##0xSO070 /EXECL: Too much text $!p0!*w#[0*:1u0*~0!~0!a{ ѷ! , FNxg>Goy0$!9DM! n&*|ͣ/!! n&+|ͣ!y9DM! `i'`ib+!9!9DM͐!͐͛-s#rz҂!!͐##w#w͐~#fo!9DM͐!`is#rz!͐!! s#rz!͐?͐!!!!9!9DM͐|" ð"͐+++|"!9-ð"͐##^#Vr+s|™"!͐͐~#fo-`is#r!|l"͐##^#Vr+sð"͐##͐?+s#r͐͐s#r͐^#Vr+sn&ð"!9!9DM͐`is#r͐n}"! ^#Vr+s"! ^#Vr+s͐ns! ^#V!9DM! n&|ͯ/+! n&|ͩ!9DM! n&|ͯ^+! n&|ͩ!9DM͐n}ʌ+! ^#Vr+sn&͹j+!9DM͐͐ +͐^#Vr+s͐+͐0+͐7s!&',͐ ͐͐ ͉͎͐+`is͐ ͐͐ )͎͐+`in&#&',!9!9DM`iw#w͐~#fon&3+}},͐ ?͐^#Vr+snѯg`is#r>,͐Ä,!9  !\&!7*!,&*!,&,!&="&! BL<"e=L'