;********************************************************************* ; ; BU.ASM - BACKUP UTILITY - 12/08/1984 Version 1.0 ; (c) 1984 by Kim Levitt - MBBS HQ RCP/M ; ; Permission is granted to distribute this program, in source ; and/or object code form and the associated documentation ; file in the Public Domain for the benefit of CP/M hard disk ; system owners. If you appreciate this program, please ; consider donating $10 or more to my efforts in public domain ; software and also to keep my RCP/M system running. Please ; send donations to: Micro Bulletin Board Systems; 8033 Sunset ; Blvd., #975; Los Angeles, CA 90046. Make checks payable to: ; "Micro Bulletin Board Systems". ; ; -- Kim Levitt 12/08/84 ; ;********************************************************************* ; ; Loosely based on: ; ; NEWBACK - DISK DIRECTORY AND BACKUP PROGRAM - 11/20/83 ; (c) 1980 by GARY YOUNG ; ; (it's so different I could have almost as easily have ; started from scratch, but I did use Gary's sort routine and ; other goodies so credit where credit is due, but this entire ; program is not copyright by Gary, only parts of it. I claim ; copyright on other code I have added and the entire program ; as a whole, but offer this freely in the Public Domain. ; Kudos also to Irv Hoff, Alex Soya, Ron Stevenson and Jim ; Gronek for their contributions to the public domain BAK25KP ; program on which BU was based.) ; ;======================================================================= ; 01/16/85 ; (V1.2) If you are using RBYANC as a catalog program, then set ; the RBYANC flag to 'YES'. See 'RBYANC EQU' for details ; Fixed page length problem. Added ; top-of-forms where needed for printer. Spaced headings ; on printed list. Added 6 to left margin (ident6) and ; increased number of columns. (Makes it easier to fit ; into notebook). Added more bells, (I sometimes don't pay ; attention). Included choice of printout, compressed ; (132 columns), or normal (80 columns), and printer es- ; cape sequences, if desired . Set flag ; to activate and insert proper printer code if desired. ; DEC LA50 code included for compressed printout. ; ; Thanks for a great program !!! ; Greg Teater ; Field Service Engineer ; Digital Equipment Corp. ; 614-868-1900 x264 ; ; ; 01/01/85 Keep File-attributes, when backing up to floppy - more in ; (V1.1) synch with NSWEEP.Corrected SPACE-routine and added "xx K ; left" output for floppy. BGE (Eiben at DEC-Marlboro) ; ; 12/08/84 ; (V1.0) New universal version (stripped out hardware-specific ; code) Other improvements to point where it now works ; like it should. (Needs at least v2.2 CP/M however, as ; it uses the GETDPB and CFILSZ functions of BDOS which I ; don't believe were available in v1.4.) I also stripped ; out the selection option and a few other things, this ; beastie is so different now I changed the name to BU ; (Backup Utility). It is mainly for ZCPR/ZCPR2/ZCPR3 ; hard disk systems as it sorts things by DISK/USER ; instead of file type as in the old BAK25KP on which this ; was based. Used in conjunction with NSWP (to reset ; and/or set the A attribute bit on files and/or for ; restoring crashed files or disks from backup floppies), ; it is a pretty nifty utility to have handy. ; - Kim Levitt ; ;======================================================================= ; ; Beginning of Equates ; YES EQU 0FFH NO EQU 0 ; ; ; User-Selectable Equates ; RBYANC EQU YES ;set to 'YES' if using RBYANC as catalog program v1.2 ;volume label on floppy will have this format v1.2 ; '--BACKUP.xxx' where xxx is the output volume v1.2 ;name given at backup time. The date will also v1.2 ;be on output floppy but as the second file v1.2 ;format '+YYMMDDy.xxx'. where 'y' is the input v1.2 ;drive letter and 'xxx' is the output vol. label v1.2 ; CLOCK EQU NO ;yes if clock is installed. ; ; NOTE: If you set CLOCK YES, be sure to include the proper ; GETDATE and support routines in the IF CLOCK area at the ; end. (This hardware specific code was taken out into ; separate "overlay files" to prevent this thing from getting ; out of hand.) ; COMPRES EQU YES ;88 lines/page & 132 columns v1.2 NORMAL EQU NO ;66 lines/page & 80 columns v1.2 ; ; NOTE: Must select either COMPRESS or NORMAL but not both v1.2 ; PRNTSET EQU YES ;send printer dependent escape seq v1.2 ;check SETPRINTER v1.2 ; ;***************************************************************************** ; IF COMPRES LINSPG EQU 88 ;lines per page for consolidated list v1.2 RECLIN EQU 5 ;entries per line - consolidated list v1.2 RECLN2 EQU 5 ;entries per line - diskette list v1.2 ENDIF ; IF NORMAL LINSPG EQU 66 ;lines per page for consolidated list v1.2 RECLIN EQU 4 ;entries per line - consolidated list v1.2 RECLN2 EQU 3 ;entries per line - diskette list v1.2 ENDIF ; BASE EQU 0 ;Normal CP/M BASE = 0 ; ; Equates NOT usually User-modified ; IDSIZE EQU 1 ;id now means a:, b:, c:, etc RECSIZ EQU 13 ;record layout as follows ; diskid = 1 byte ; user# = 1 byte (binary 0-15) ; file = 8 bytes ; type = 3 bytes ; BEL EQU 07H ;console bell BS EQU 08H ;backspace BLANK EQU 20H ;space CR EQU 0DH ;carriage return LF EQU 0AH ;line feed FF EQU 0CH ;form feed ESC EQU 1BH ;escape CTRLZ EQU 1AH ;eof (also clr screen on some systems) ; BDOS EQU 05H CONINP EQU 01H CONOUT EQU 02H LSTOUT EQU 05H INPSTR EQU 0AH CONSTC EQU 0BH SYSRST EQU 0DH SELDSK EQU 0EH OPNFIL EQU 0FH CLSFIL EQU 10H SRC1ST EQU 11H FNDNXT EQU 12H DELFIL EQU 13H REDSEQ EQU 14H WRTSEQ EQU 15H MAKFIL EQU 16H SETDMA EQU 1AH GETALV EQU 1BH SETATT EQU 1EH GETDPB EQU 1FH GETUSR EQU 20H SETUSR EQU 20H CFILSZ EQU 23H ; ;======================================================================= ; ; Start of program code and data ; ORG BASE+100H ;Standard CP/M TPA location ; JMP START ; ;*********************************************************************** ; ; USER DEFINABLE DATA/CODE AREA ; ; (An escape sequence or control character may be patched in ; this location using DDT and SAVE without the need for a ; reassembly. I have allowed up to nine bytes for long escape ; sequences such as the VT100 ANSI mode clear screen/home ; cursor sequence: ESC [ 2 J ESC [ ; H. End the sequence with ; a null (00H) character.) ; CLSMSG: DB ESC,'[','2','J',ESC,'[',';','H',0;clear screen msg goes here ; SETPRINTER: DB ESC,'[4w' ;DEC LA50 16.5 char/in. v1.2 DB ESC,'[2z',0 ;DEC LA50 8 lines/in. (88 lines/page) v1.2 ; (You can set up this table to define the filetypes which you ; do not wish to have backed up..) ; ; ; ; ; NOSKIP: DB 9 ;number of filetypes in skip list SKPTYP: DB 'PRN' ;No PRINT-files DB 'HEX' ;No intermediate HEX DB 'SYM' ;No intermediate Symbols DB 'BAK' ;No BAKup's DB '$$$' ;No incompletes DB 'TMP' ;No temporaries DB 'BAD' ;No BADBLK allocations DB 'SWP' ;no FW swap-files either DB 'F$$' ;no FW intermediate Format-files DS 25 ;allow extra room so can add to SKPTYP ; ; (You may have to change the routine below but probably not) ; CLRSCRN: LXI D,CLSMSG ;This simply outputs the above string. CALL STROUT ;If you have a memory mapped display, ;you may have to write a new routine. ; RET ; ; ; Program begins executing here ; 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 en- STA EOF ;.. tries as possible STA GOTONE ;flag shows no file found yet if zero MVI E,0FFH ;Get current user # MVI C,GETUSR ;using BDOS function CALL BDOS ;so we know where we are... STA CURUSR ;save it... STA RUSR CALL CONVRT MOV A,B ;save for id to console STA USERID MOV A,C STA USERID+1 ; START1: ; CALL CLRSCRN ;clear the screen and set printer v1.2 LXI D,SIGNON ;print signon message CALL OUTPUT ; IF RBYANC ; v1.2 LXI D,SIGNON1 ;print 'RBYANC support' v1.2 CALL OUTPUT ;do it v1.2 ENDIF ;RBYANC v1.2 ; IF PRNTSET ; v1.2 LXI D,SIGNON2 ;print 'DEC printer support' may want v1.2 ;to change this to match your printer v1.2 CALL OUTPUT ;do it v1.2 ENDIF ;PRNTSET v1.2 ; LXI D,DRIVMSG ;ask for the drive letters to backup CALL QUESTION CPI 0 ;ck to see if anything was added JZ START1 ;if not start over ADI 1 STA MAX1 MOV B,A ;setup count for move LXI H,INREC ;data to move LXI D,DRIVES ;where to put the drives info CALL MOVE XCHG DCR B ;correct the count befor cking ; STRT: MOV A,M ;get a drive char CPI 'Q' ;ck it for good char JP START1 ;no good if positive CPI 'A' JC START1 ;ng if less than A also INX H ;point to next DCR B ;dec count JNZ STRT ;loop MVI M,0 ;store end-of-string char at end LXI D,BKUPMSG ;ask for the drive letter to store it to CALL QUESTION CPI 1 JNZ START1 ;if no input then exit program LDA INREC ;get drive letter to store to STA BACKUPDRV ; START2: LXI D,CORRMSG ;verify all data is correct CALL OUTPUT LXI D,DRIVES ;get drives to backup CALL STROUT ;output drive letter chain LXI D,CORRMSG1 CALL STROUT LDA BACKUPDRV ;get drive to backup to back again MOV E,A MVI C,CONOUT CALL BDOS ;output drive to backup to out LXI D,CORRY$N ;get correct message CALL QUESTION ;and get responce CPI 1 JNZ START2 LDA INREC ;get answer CPI 'Y' JNZ START1 ; LXI D,USRMSG ;ask if all users to back up CALL QUESTION CPI 1 JNZ START1 ;thats what you get for a wrong answer LDA INREC ;get answer CPI 'N' JZ NOUSRS ;No? CPI 'Y' ;do all user areas JNZ START1 ;If neither Y nor N.. MVI A,0 ;set user 0 meaning do them all JMP DONUSR ; NOUSRS: MVI A,17 ;set user 17 meaning do only what we are ; DONUSR: STA CURUSER ; LXI D,TAGMSG ;ask if should skip F4 files CALL QUESTION CPI 1 JNZ START1 ;thats what you get for a wrong answer LDA INREC ;get answer CPI 'Y' ;skip files with F4 tag? JZ SKPANS CPI 'N' JZ SKPANS JMP START1 ;oops ; SKPANS: STA TAGFLG ;either Y or N ; LXI D,SETF4Q ;ask if should set F4 after backup CALL QUESTION CPI 1 JNZ START1 ;thats what you get for a wrong answer LDA INREC ;get answer CPI 'Y' ;skip files with F4 tag? JZ SETANS CPI 'N' JZ SETANS JMP START1 ;oops ; SETANS: STA SETF4 ;either Y or N ; IF NOT CLOCK MSG1: LXI D,DATEMSG ;get 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 ;NOT CLOCK ; IF CLOCK CALL GETDATE ;get date from clock board LXI H,DATETIME+1 ENDIF ;CLOCK ; MVI B,8 ;move date to hold area LXI D,DATE ;to "date" CALL MOVE 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: LDA GOTONE ;no file found fix ORA A JNZ ALLOK LXI D,NOFILS ;no files message CALL OUTPUT JMP FINISHED ;as nothing to do we are done ; ALLOK: CALL SORT ;sort by type, file name and disk id CALL DONE MVI A,RECSIZ ;setup to remove duplicate entries STA COMPSIZE ;compare on all char CALL KILLDUPS ;eliminate duplicate entries CALL DONE CALL REPORT ;print all entries CALL DONE ; MSG3: LXI D,BACKQUS ;ask if you want backup function CALL QUESTION CPI 1 JNZ MSG3 LDA INREC CPI 'N' JZ FINISHED CPI 'Y' JNZ MSG3 CALL TOPOFFORM ; v1.2 CALL BACKUP ;backup those files reported on ; FINISHED: ; CALL TOPOFFORM LXI D,EXITBU CALL OUTPUT JMP 0000H ;Warm boot when done... ; ; the extract routine scans all the drives in the drive table when com- ; plete, it asks for the next drive id when the hard disk is up, it will ; not ask for the drive id but will 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,SCANMSG ;Tell user what's happening... CALL OUTPUT LXI H,DRIVES ;get address of the drive table SHLD ADDR1 ;to scan LDA CURUSER STA SAVCUSR ;save CURUSER ; NEXTDRV: LDA MAX1 ;see if there are more drives to scan DCR A STA MAX1 ;next user/ret when all have been scanned RZ LHLD ADDR1 ;get address of drive table MOV A,M ;get drive character STA RDISK STA DISKID ANI 1FH ;convert a=1...p=16 STA DUMMYFCB ;set in dr of dummyfcb INX H ;set for next read of drive table SHLD ADDR1 LXI D,DISKDIS ;send disk id message CALL STROUT LDA SAVCUSR STA CURUSER ;reset CURUSER ; EXTRCTL: LDA CURUSER ;get user number CPI 16 ;check if we do them all JNC EXTRCTC ;no users greater than 15 MOV E,A ;valid user so set it. MVI C,SETUSR ;set user function CALL BDOS ;tell cp/m to do some work ! LDA CURUSER STA RUSR ;save it for format and STA CURUSR ;hard disk select CALL CONVRT MOV A,B ;send id to console STA USERID MOV A,C STA USERID+1 ; EXTRCTC: LXI D,USERDIS CALL STROUT LXI D,DISKBUF ;set a dma address for directory entries MVI C,SETDMA CALL BDOS ;set dma LXI D,DUMMYFCB ;get first directory entry MVI C,SRC1ST CALL BDOS ;get directory INR A JZ NEXTUSR ;no more entries in this user # JMP GETFCB ;extract data from fcb ; NEXTFCB:LXI D,DUMMYFCB ;get next entry after the first MVI C,FNDNXT CALL BDOS INR A JZ NEXTUSR ;no more directories in this user # ; GETFCB: LXI D,32 ;each entry is 32 bytes long LXI H,DISKBUF ;directory record is in diskbuf CPI 1 ;first entry in record??? JZ FORMREC ;yes DAD D ;add 32 to address in record CPI 2 ;second entry in record??? JZ FORMREC DAD D ;add 64 to address of record CPI 3 ;third entry in record??? JZ FORMREC DAD D ;add 96 to address of record ; FORMREC: INX H ;pass drive byte LXI D,RFILE ;move file name MVI B,11 ;move 11 characters CALL MOVE ; LDA TAGFLG CPI 'Y' ;skipping 'F4' files? JNZ STRIPIT ;if not, no need to check F4 bit LDA RFILE+3 ;chk 'F4' bit ANI 80H ;ck to see if we should backup this file JZ STRIPIT ;if no F4 bit, continue JMP NEXTFCB ;else, forget this one... ; STRIPIT: LXI H,RFILE ;strip off the high bit set by MVI B,11 ;the version program CALL STRIP LXI D,SKPTYP MVI B,3 LDA NOSKIP INR A MOV C,A ; NEXTSKIP: DCR C JZ DOIT LXI H,RTYPE CALL COMPARE JZ NEXTFCB INX D INX D INX D JMP NEXTSKIP ; DOIT: LXI H,RFILE ;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: MVI A,0FFH STA GOTONE ;set flag that we have at least one entry LHLD TABADDR ;get memory table address LXI D,RDISK ;get memory record address XCHG ;rtype (hl) to tabaddr (de) MVI B,RECSIZ ;move recsiz bytes CALL MOVE LHLD TABADDR ;increment for next entry LXI D,RECSIZ ;recsiz bytes in record DAD D SHLD TABADDR ;save new address MVI M,CTRLZ ;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+recsiz 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 ; NEXTUSR: LDA CURUSER INR A CPI 16 ;get user and see if another one to do JNC NEXTDRV ;all done so lets go next disk STA CURUSER ;else do next user JMP EXTRCTL ;until done ;..... ; ; ; the following routine is a bubble sort. in pseudobasic this would be ; done as follows: sort addr1=bottom(ram)-recsiz (recsiz is count of ; bytes in one record) ; ; MAX1=0 ;LOOP1: MAX1=MAX1+1 ; ADDR1=ADDR1+RECSIZ (first time this would be the bottom) ; IF MAX1>TABCNT-1 THEN TO TO SORTED ; ADDR2=ADDR1 ; MAS2=MAX1 ;LLOP2: MAX2=MAX2+1 ; ADDR2=ADDR2+RECSIZ ; IF MAX2>TABCNT THEN GO TO LOOP1 ; IF TABLE(ADDR1) 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,RECSIZ ;the outer loop and increment DAD D ;by recsiz 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, 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,RECSIZ CALL MOVE ;temp=table(addr1) XCHG ;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 ; ; report prints the sorted consolidated directory entries. linspg is ; the number of lines per page and reclin is the number of 20 byte en- ; tries per line. each type begins on a new page. ; REPORT: ; IF PRNTSET ;user defined printer functions v1.2 LXI D,SETPRINTER ;This outputs the control setup characters v1.2 CALL LIST ;for printer, check SETPRINTER v1.2 ENDIF ; v1.2 ; LXI D,RPTING CALL OUTPUT LHLD TABCNT ;set count of entries INX H ;plus one SHLD MAX1 ;to decrement first LXI H,RAM-RECSIZ ;set starting address SHLD ADDR1 CALL HEADING ; NEXTPRT:LHLD ADDR1 LXI D,RECSIZ ;set to add the receive length DAD D SHLD ADDR1 LHLD MAX1 ;decrement count to see when done DCX H SHLD MAX1 LXI D,0000 ;see if reached zero yet CALL COMPREG RZ ;return if done LHLD ADDR1 ;current disk = last disk? LDA LASTDSK CMP M JNZ SKIP3 ;new disk, skip 3 lines INX H LDA LASTUSR CMP M JNZ SKIP3 ;new user, skip 3 lines ; PRNTNOW:MVI B,RECLIN+1 ;find # records per line v1.2 LDA MAX2 ;find which column of print is current v1.2 CMP B ;are they equal v1.2 JZ COLUMN1 ;yes, bypass tab printing v1.2 LXI D,TAB ;add spaces between file names v1.2 CALL LIST COLUMN1:LDA MAX2 ;decrement records per line DCR A STA MAX2 JZ NEWLINE ;line full, go to new line LHLD ADDR1 CALL FORMAT LXI D,PRNTREC CALL LIST JMP NEXTPRT ; SKIP3: LDA LINECNT DCR A JZ NEWPAGE DCR A JZ NEWPAGE DCR A JZ NEWPAGE STA LINECNT LXI D,CRLFLFLF CALL LIST CALL MARGIN ;add print margin v1.2 JMP CHKDISK ; NEWPAGE: CALL TOPOFFORM CALL HEADING ;print top of form message ; CHKDISK: LHLD ADDR1 MOV A,M STA LASTDSK INX H MOV A,M STA LASTUSR ; SETCNT: MVI A,RECLIN+1 STA MAX2 JMP PRNTNOW ; NEWLINE:LXI D,CRLF CALL LIST CALL MARGIN ;put in print margin v1.2 LDA LINECNT DCR A STA LINECNT JZ NEWPAGE ;page full JMP SETCNT ; KILLDUPS: LXI D,KILDUP CALL OUTPUT LXI H,RAM SHLD ADDR1 ;set the start of the table ; NEXTEQUAL: LHLD ADDR1 ;check each entry against the next LXI D,RECSIZ 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,RECSIZ DAD D ;move third entry to the second SHLD ADDR2 CALL MOVELIST LHLD TABCNT DCX H SHLD TABCNT POP H ;restore current position SHLD ADDR1 ;now compare 1st & 3rd JMP NEXTEQUAL ; SAVELAST: LHLD ADDR2 ;make new one the current one SHLD ADDR1 JMP NEXTEQUAL ;compare ; 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 CTRLZ RZ ; INX H INX D JMP MOVENEXT ; ;..... ; BACKUP: 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 LXI D,RECSIZ ;set an address for the second entry DAD D ;next entry = current + recsiz 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. MVI A,0FFH STA LASTDSK ;initialize LASTDSK for first STRTMSG ; OKMOUNT:CALL MOUNT ; NOMNT: JMP PASSMOVE ; NEXTFILE: CALL MOVELIST INX H ;new start of read/write buffer SHLD ADDR3 ; 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 CTRLZ JZ FINI ;finished ; LDA LASTDSK CMP M ;are we on a new disk? JZ FORMFCB ;nope, continue LXI D,FINIMSG CALL BCKMSG ;else say end of disk X JMP NEWDISK ;and mount a new floppy ; FORMFCB: LXI H,RAM CALL FORMAT ;Format filename now MVI A,' ' STA PRNTSIZ STA PRNTSIZ+1 STA PRNTSIZ+2 ;(clear out "size" area) MVI A,0 STA PRNTSIZ+3 ;(don't know size yet) ; LXI D,HDFCB ;clear the fcb MVI B,36 XRA A ; ZEROFCB: STAX D INX D DCR B JNZ ZEROFCB LXI H,RAM+2 ;get address of table entry LXI D,HDFILE ;move in the filename & type MVI B,11 CALL MOVE LDA RAM ANI 1FH ;convert a=1...p=16 STA HDFCB LDA RAM+1 ;get user STA CURUSR ;save it MOV E,A MVI C,SETUSR ;set it CALL BDOS 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 1FH ;convert floppy drive to number STA FPFCB ; LDA HDFCB ;get Hard disk drive SUI 1 ;convert for BDOS MOV E,A ;stick in E MVI C,SELDSK ;call Select disk CALL BDOS ;(for dumb systems w/o auto select) ; LXI D,HDFCB ;open the hd file MVI C,OPNFIL CALL BDOS ;open the input file INR A JZ NOTFOUND ; LXI D,HDFCB ;compute file size MVI C,CFILSZ ;(in sectors) CALL BDOS LDA FLSFAC ;get shift factor ADI 3 ;change from Kb shift to sect shift LXI H,1 ;set 0 bit on CALL FRS ;shift HL left A bits DCX H ;decrement 1 XCHG ;stick in DE LHLD HDFCB+33 ;get file size in sectors DAD D ;add value for round up CALL DVHL8 ;convert to K (w/floppy blocking) SHLD HDFLSZ ;save file size in K LXI H,1 ;figure KB mask CALL SHIFT DCX H MOV A,L CMA ;ignore lower FLSFAC bits MOV L,A LDA HDFLSZ ANA L STA HDFLSZ ;(we added extra for round up) ; LXI H,PRNTSIZ+3 ;initial KPTR SHLD KPTR LHLD HDFLSZ CALL KOUT ; XRA A STA HDFCB+32 ;make sure current rec cleared STA HDFCB+33 ;for sequential reading STA HDFCB+34 STA HDFCB+35 LHLD HDFLSZ ;get filesize back again... XCHG LHLD FLMXKB ;compare with max space on floppy CALL SBHLDE ;see if too big to backup JC TOOBIG ; LDA FPFCB ;get Floppy disk drive SUI 1 ;convert for BDOS MOV E,A ;stick in E MVI C,SELDSK ;call Select disk CALL BDOS ;(for dumb systems w/o auto select) ; LXI D,FPFCB ;delete the file on floppy if it MVI C,DELFIL ;exists CALL BDOS ; CALL SPACE ;get space available on floppy LHLD HDFLSZ ;if not too big, see if enuf room now XCHG LHLD FLFREE CALL SBHLDE JC DISKFUL2 ; LXI D,FPFCB ;create the file on floppy MVI C,MAKFIL CALL BDOS ;make file INR A JZ DISKFULL ; LXI H,RAM CALL FORMAT LXI D,BCKUM CALL OUTPUT LXI D,PRNTREC CALL STROUT LXI D,BCKUM2 CALL STROUT LDA BACKUPDRV STA PRNDISK MVI A,0 STA PRNFILE LXI D,PRNTREC CALL STROUT LDA RAM STA PRNDISK LDA RAM+2 STA PRNFILE LXI D,BCKUM3 CALL STROUT ; COPYLOOP: CALL LOADBUFF ;load memory with file CALL WRITEBUF ;write memory file LDA EOF CPI 1 JZ ENDOFFILE CPI 2 JZ DISKFULL JMP COPYLOOP ; ENDOFFILE: LXI D,FPFCB ;close floppy file MVI C,CLSFIL CALL BDOS ;close LXI D,FPFCB+1 ;copy attributes from HDFCB to FPFCB V1.1 LXI H,HDFCB+1 ;..we want to keep them V1.1 MVI B,13 ; V1.1 CALL MOVE ; V1.1 MVI C,SETATT ; V1.1 LXI D,FPFCB ; V1.1 CALL BDOS ;Set attributes a'la HDFCB on floppy V1.1 ; LDA SETF4 ;do we want to set attr? CPI 'Y' JNZ NOSETF4 ;if no, skip that code.. ; LXI H,HDFCB+4 ;tag 'F4' byte to indicate backuped MOV A,M ORI 80H ;set the bit MOV M,A ;put it back in hdfcb ; LDA HDFCB ;get Hard disk drive SUI 1 ;convert for BDOS MOV E,A ;stick in E MVI C,SELDSK ;call Select disk CALL BDOS ;(for dumb systems w/o auto select) ; LXI D,HDFCB ;setup for attribute setting MVI C,SETATT CALL BDOS ;write it on the disk ; NOSETF4: LXI H,RAM CALL PRINTFILE ;write file name on index list CALL DONE JMP NEXTFILE ; DISKFULL: LXI D,FPFCB MVI C,DELFIL ;delete file on floppy CALL BDOS ; DISKFUL2: LXI D,DSKFMSG CALL OUTPUT ; NEWDISK: CALL DISMOUNT ;dismount old disk CALL MOUNT ;get new disk JMP FORMFCB ; TOOBIG: LXI D,BIGMSG ;yes, 2nd floppy. send message CALL STROUT ;warning that this file cannot LXI D,PRNTREC CALL STROUT ;print the file name also JMP NEXTFILE ; NOTFOUND: LXI D,NFMSG CALL OUTPUT LXI D,PRNTREC CALL OUTPUT RET ;..... ; DONE: LXI D,DONEBU JMP STROUT ; DISMOUNT: LXI D,DMNTMSG ;dismount floppy CALL OUTPUT ;message to console LDA LINECNT ;check for full page v1.2 DCR A ; v1.2 JZ TOPOFFORM ;page full v1.2 DCR A ; v1.2 JZ TOPOFFORM ; v1.2 DCR A ; v1.2 JZ TOPOFFORM ; v1.2 STA LINECNT ; v1.2 LXI D,CRLFLFLF ;page not full put some lines in v1.2 CALL LIST ;do it v1.2 RET ; FINI: LXI D,FINIMSG CALL BCKMSG CALL DISMOUNT RET ;.... ; ; ; assorted routines ; STRIP: MOV A,M ANI 7FH MOV M,A INX H DCR B JNZ STRIP RET ; KOUT: PUSH B PUSH D PUSH H LXI B,-10 LXI D,-1 ; KOUT2: DAD B INX D JC KOUT2 LXI B,10 DAD B XCHG MOV A,H ORA L JZ KOUT3 PUSH H LHLD KPTR DCX H SHLD KPTR POP H CALL KOUT ; KOUT3: MOV A,E ADI '0' LHLD KPTR MOV M,A INX H SHLD KPTR POP H POP D POP B RET ; BCKMSG: CALL OUTPUT LXI D,BCKUMSG CALL STROUT RET ; PRINTFILE: LXI D,PRNTREC CALL LIST LDA MAX2 DCR A STA MAX2 ;entries per line counter JNZ CONTL LXI D,CRLF ;go to new line CALL LIST MVI A,RECLN2 STA MAX2 CALL MARGIN ;add left margin to paper v1.2 LDA LINECNT ;decrement line counter DCR A ;do it JZ NEWPAG1 ;page full, do top of form v1.2 STA LINECNT ;keep it RET ; CONTL: LXI D,DISSEP CALL LIST RET ;..... ; HEADING3: CALL LINCNT4 ;update the line counter v1.2 CALL MARGIN ;put print margin in v1.2 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 ;print heading on printer CALL LIST ;for files to be backed up MVI A,RECLN2 STA MAX2 LXI D,CRLFLFLF ;add some blank lines v1.2 CALL LIST ;do it v1.2 JMP MARGIN ; ;..... ; NEWPAG1: CALL TOPOFFORM ; v1.2 JMP MARGIN ;put print margin in now v1.2 ; ;..... ; MOUNT: LXI H,RAM LDA LASTDSK CMP M JZ CONTM ; MOV A,M STA LASTDSK LXI D,STRTMSG CALL BCKMSG JMP MOUNT2 ; CONTM: LXI D,CONTMSG CALL BCKMSG ; MOUNT2: LXI D,MNTMSG CALL 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 CALL CLRSCRN LXI D,BCKUM7 CALL OUTPUT LXI D,VOLSER CALL STROUT LXI D,BCKUM8 CALL STROUT MVI C,SYSRST ;do a system reset to change disks CALL BDOS LDA BACKUPDRV SUI 41H MOV E,A MVI C,SELDSK CALL BDOS MVI C,GETDPB ;Get DPB CALL BDOS INX H INX H MOV A,M ;get block shift factor SUI 3 ;-3 = kb shift factor STA FLSFAC ;save it LXI D,3 DAD D ;Get DSM MOV E,M INX H MOV D,M INX D XCHG ;swap DE/HL SHLD FLMAXS ;save it DCX H CALL DVHL8 ;DSM/8 INX H ;+1 = ALV SIZE SHLD FLALVS ;save it XCHG INX H INX H MOV D,M INX H MOV E,M ;DE = AL0+AL1 MOV A,D ;Get # of bits CALL BITS MOV B,A MOV A,E CALL BITS ADD B STA FLDIRT ;save tot # of directory blocks MVI A,0 STA FLDIRT+1 CALL SPACE ; LHLD FLFREE XCHG LHLD FLMXKB CALL SBHLDE MOV A,H ORA L JNZ ERA LXI D,EMPFL CALL OUTPUT JMP NOERA ; ERA: LXI D,ERASE CALL QUESTION CPI 1 JNZ ERA LDA INREC CPI 'N' JZ NOERA CPI 'Y' JNZ ERA LDA BACKUPDRV ANI 1FH STA DUMMYFCB MVI A,0 ;start at user 0 NXTUSD: MOV E,A MVI C,SETUSR PUSH PSW ;save user # CALL BDOS ;set user DELNFL: LXI D,FPFCB ; V1.1 LXI H,DUMMYFCB ; V1.1 MVI B,36 ; V1.1 CALL MOVE ; V1.1 MVI C,SRC1ST ;search for file V1.1 LXI D,FPFCB ; V1.1 CALL BDOS ; V1.1 CPI YES ; V1.1 JZ MORUSD ;done this user # V1.1 LXI H,FPFCB+1 ; V1.1 MVI B,11 ; V1.1 CALL STRIP ;clear attributes V1.1 MVI C,SETATT ; V1.1 LXI D,FPFCB ; V1.1 CALL BDOS ;remove them V1.1 MVI C,DELFIL ; V1.1 LXI D,FPFCB ; V1.1 CALL BDOS ;delete file on floppy V1.1 JMP DELNFL ;and look for next V1.1 MORUSD: POP PSW ;get user # INR A ;next user CPI 16 ;check if done (do 0-15) JNZ NXTUSD ;delete all files in next user # ; NOERA: LXI D,CRLF CALL STROUT MVI E,0 ;back to user 0 for floppy MVI C,SETUSR CALL BDOS CALL HEADING3 ;print heading on printer CALL CLRFCB1 ;write labels on floppy LDA DATE+6 STA FPFCB+2 ;convert MM/DD/YY date to LDA DATE+7 ;YYMMDD STA FPFCB+3 LDA DATE STA FPFCB+4 LDA DATE+1 STA FPFCB+5 ;backup volume label is a 0k file of the LDA DATE+3 ;format: "+yymmddh.vol" STA FPFCB+6 ; where: yymmdd = iso format date of backup LDA DATE+4 ; h = hard disk files are from STA FPFCB+7 ; and vol = user-supplied volume id LDA LASTDSK STA FPFCB+8 CALL VOLABEL ;add extension to date v1.2 ; IF RBYANC ; add second file '--BACKUP.xxx' to output disk to be v1.2 ; used by RBYANC. xxx= volser. Make's it easier to update v1.2 ;since RBYANC cannot delete volumes, therefore old backup v1.2 ;with only the date as volume label would remain in v1.2 ; 'MAST.CAT',this format eliminates this problem v1.2 ; ; CALL CLRFCB1 ;clear the FCB v1.2 LXI H,BCKUPLBL ;find '--BACKUP' for second volume label v1.2 LXI D,FPFCB+1 ;move it to FCB v1.2 MVI B,8 ;move 8 characters v1.2 CALL MOVE CALL VOLABEL ;make second file with format '-.vol' v1.2 ENDIF ; end RBYANC = YES v1.2 ; RET ;..... ; CLRFCB1: LXI D,FPFCB ;clear the fcb 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 1FH ;convert floppy drive to number STA FPFCB ; IF NOT RBYANC MVI A,'-' ;add '-' to front of date file v1.2 ENDIF ; IF RBYANC MVI A,'+' ;RBYANC ... put '+' in front of date v1.2 ENDIF ;RBYANC v1.2 ; STA FPFCB+1 ;date file to avoid collision with YANC v1.2 RET ; ;..... ; VOLABEL: 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,DELFIL ;delete file in case it exists CALL BDOS ;already LXI D,FPFCB MVI C,MAKFIL ;create the file CALL BDOS INR A JZ MOUNT ;disk full? LXI D,FPFCB MVI C,CLSFIL ;close the file CALL BDOS RET ; ;..... ; SPACE: ;calculates space available MVI C,GETALV ;Get Allocation Vector V1.1 CALL BDOS ; V1.1 SHLD FLALV ;and save it V1.1 LXI H,0 SHLD FLUSED ;clear used accumulator LHLD FLALVS ;get allocation vector size MOV B,H MOV C,L LHLD FLALV ;allocation vector address ALVC: MOV A,M ;get byte from ALV CALL BITS ;count # of bits on PUSH H ;save HL MVI D,0 MOV E,A LHLD FLUSED DAD D SHLD FLUSED ;add # of bits to total POP H ;get HL again INX H DCR C ;decrement low byte of count JNZ ALVC ;not done yet, keep counting DCR B ;else decrement high byte JP ALVC ;not done yet, continue LHLD FLUSED XCHG LHLD FLMAXS CALL SBHLDE ;MAX-USED=FREE CALL SHIFT SHLD FLFREE ;save FREE KB LHLD FLDIRT XCHG LHLD FLMAXS ;get MAX CALL SBHLDE ;MAX-DIR=MAX (actual) CALL SHIFT ;convert to KB SHLD FLMXKB ;save MAX KB MVI H,BLANK ; V1.1 MVI L,BLANK ; V1.1 SHLD FREEKS ;clear space-string V1.1 SHLD FREEKS+2 ; V1.1 LXI H,FREEKS+3 ;load string-pointer V1.1 SHLD KPTR ; V1.1 LHLD FLFREE ;and number to convert V1.1 CALL KOUT ; V1.1 LXI D,FREEKS ;and print string V1.1 CALL STROUT ; V1.1 RET ; SHIFT: LDA FLSFAC ;get shift factor FRS: ORA A ;check shift factor RZ ;if zero, done PUSH PSW ;else save shift factor MOV A,L RAL ;shift low byte MOV L,A MOV A,H RAL ;and high byte MOV H,A POP PSW DCR A JMP FRS ;.... ; DVHL8: PUSH PSW PUSH B MVI B,3 DIVL: MOV A,H ORA A RAR MOV H,A MOV A,L RAR MOV L,A DCR B JNZ DIVL POP B POP PSW RET ;.... ; SBHLDE: MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A RET ;.... ; BITS: CPI 0 ;if 0, zero bits RZ ;return 0 CPI 0FFH ;if not 255 JNZ BITC ;must count the bits MVI A,8 ;else, 8 bits RET BITC: PUSH B ;save BC MVI B,8 ;init count MVI C,0 ;and accumulator BITL: RAL ;move bit to test it JNC BITLC ;not on INR C ;if on, increment count BITLC: DCR B ;decrement bit count JNZ BITL ;if more to count, do it MOV A,C ;else return # of bits POP B ;restore BC RET ;all done ;.... ; LOADBUFF: 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 ; LDA HDFCB ;get Hard disk drive SUI 1 ;convert for BDOS MOV E,A ;stick in E MVI C,SELDSK ;call Select disk CALL BDOS ;(for dumb systems w/o auto select) ; LOADNEXT: LHLD TEMP XCHG ;set dma address MVI C,SETDMA CALL BDOS LXI D,HDFCB ;read hard disk MVI C,REDSEQ CALL BDOS ORA A JNZ HDEOF ;eof? LXI D,BCKUM5 CALL STROUT 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 JC HDRET ;return if memory already full JMP LOADNEXT ;get another record ; HDEOF: MVI A,1 ;set file eof STA EOF ; HDRET: LDA FPFCB ;switch back to floppy drive SUI 1 ;convert for BDOS MOV E,A ;stick in E MVI C,SELDSK ;call Select disk CALL BDOS ;(for dumb systems w/o auto select) RET ;..... ; WRITEBUF: 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,SETDMA CALL BDOS LXI D,FPFCB MVI C,WRTSEQ ;write sequential CALL BDOS ORA A JNZ FPFULL ;floppy disk full LXI D,BCKUM6 CALL STROUT 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 SHLD TEMP JMP WRITENEXT ; FPFULL: MVI A,2 ;full diskette STA EOF RET ;..... ; ; FORMAT: MOV A,M ;get disk STA PRNDISK INX H ;point to user MOV A,M CALL CONVRT MOV A,B STA PRNUSR1 MOV A,C STA PRNUSR2 INX H ;point to file name/type LXI D,PRNFILE ;format the entry from the table MVI B,8 ;format to the print format CALL MOVE ;the table address is assummed to be LXI D,8 ;in hl. first move the type DAD D ;now position to the file type LXI D,PRNTYPE ;move the file type MVI B,3 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 CALL STROUT POP D ;now put out the message JMP STROUT ;print string pointed to by DE ;..... ; TOPOFFORM: ; v1.2 LXI D,FRMFD ; v1.2 CALL LIST ; V1.2 MVI A,LINSPG ;find paper length v1.2 STA LINECNT ;reset line counter v1.2 RET ; ;..... ; ; HEADING: CALL MARGIN ;set printer margin v1.2 LXI D,HEAD1 CALL LIST LXI D,DATE CALL LIST LXI D,TABFULL LDA ABORT ORA A CNZ LIST LDA RAM ;init LASTDSK for new page STA LASTDSK LDA RAM+1 STA LASTUSR ;init LASTUSR also MVI A,RECLIN+1 STA MAX2 ; ;..... ; PAGECNT: MVI A,LINSPG ;find the number lines per page v1.2 DCR A ;minus 6 to allow header spaces etc. v1.2 DCR A ; v1.2 DCR A ; v1.2 DCR A ; v1.2 DCR A ; v1.2 DCR A ; v1.2 STA LINECNT ;reset line counter v1.2 LXI D,CRLFLFLF ;put in some spaces after header v1.2 CALL LIST CALL MARGIN RET ; ;..... ; LIST: PUSH H ;this differs from STROUT PUSH B ; in that LIST goes to the PUSH D ;list device and STROUT goes ; LIST1: LDAX D ;to the console device CPI 0 JZ LIST2 INX D PUSH D MOV E,A MVI C,LSTOUT CALL BDOS POP D JMP LIST1 LIST2 POP D POP B POP H RET ; STROUT: PUSH H ;this differs from LIST PUSH B ; in that LIST goes to the PUSH D ;list device and STROUT goes ; STROT1: LDAX D ;to the console device CPI 0 JZ STROT2 INX D PUSH D MOV E,A MVI C,CONOUT CALL BDOS POP D JMP STROT1 ; STROT2: POP D POP B POP H RET ;..... ; MARGIN: LXI D,IDENT ;find left margin value v1.2 CALL LIST ;print left margin v1.2 RET ; ;..... ; LINCNT4: LDA LINECNT ;find where it's at now v1.2 DCR A ;subtract for 4 LF's v1.2 JZ TOPOFFORM ;goto to new page v1.2 DCR A ;or subtract again v1.2 JZ TOPOFFORM ; v1.2 DCR A ; v1.2 JZ TOPOFFORM ; v1.2 DCR A ;must do this 4 times for the 3 LF's v1.2 JZ TOPOFFORM ; v1.2 STA LINECNT ;enough room on paper to start another v1.2 RET ; ;..... ; QUESTION: CALL OUTPUT ;put out the question LXI D,INBUF MVI C,INPSTR ;input the reply CALL BDOS LXI H,INBUF+2 LDA INCNT ORA A RZ ;if zero data, ret now MOV B,A CHKCAS: MOV A,M CPI 'a' JC NXTC CPI '{' JNC NXTC ANI 5FH MOV M,A NXTC: INX H DCR B JNZ CHKCAS ; 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 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 CLOCK GETDATE: ;put your GETDATE routine here RET ; ENDIF ;CLOCK ; ; ;.... ; CONVRT: MVI B,030H ;convert binary to decimal routine MVI C,030H ;for nos from 0 to 99 b=tens,c=ones ; CON1: SUI 10 ;a holds value to convert JC CON2 INR B JMP CON1 ; CON2: ADI 10 ;correct it ; CON3: SUI 1 RC ;we are done INR C ;do ones JP CON3 ; DATETIME: DB ' 00/00/00 HH:MM:SS',0 ; DRIVES: DB 'ABC' ;drive nos for the hard disks DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ;end of list ; BCKUPLBL: DB '--BACKUP',0 ; ; SIGNON: DB CR,LF,CR,LF DB '>>> Backup Utility v1.2 Jan. 22, 1985',CR,LF DB ' by Kim Levitt v1.0 Dec. 8, 1985',CR,LF DB ' based on NEWBACK by G. Young',CR,LF DB CR,LF DB 0 ; IF RBYANC SIGNON1: DB '>>> RBYANC compatible',CR,LF,0 ENDIF ; IF PRNTSET SIGNON2: DB '>>> DEC printers supported',CR,LF,0 ENDIF ; DRIVMSG: DB 'Enter Letter of Drives to Backup from as ' DB '"A","B" or "AB": ' DB 0 ; BKUPMSG: DB 'Enter Letter of Floppy Drive to Backup to: ' DB 0 ; CORRMSG: DB CR,LF DB ' >>> Backing up Drive(s): ' DB 0 ; CORRMSG1: DB ' to Floppy Drive: ' DB 0 ; CORRY$N: DB CR,LF DB 'Is this Correct (Y/N)? ' DB 0 ; IF NOT CLOCK DATEMSG: DB 'Enter 8 Char Date for Reports MM/DD/YY: ' DB 0 ENDIF ;NOT CLOCK ; ; TAGMSG: DB 'Skip files that have been backed up? (F4 bit set) (Y/N)? ',0 ; SETF4Q: DB 'Set backup attribute bit (F4) after backup? (Y/N)? ',0 ; USRMSG: DB 'Backup all user areas (Y/N)? ',0 ; NOFILS: DB BEL,BEL,BEL,CR,LF,'NO files to backup found !!',0 ; SCANMSG: DB CR,LF,'Scanning directories...',CR,LF ; DISKDIS: DB CR,' Disk: ' ; DISKID: DB '? User: ',0 ; USERDIS: DB BS,BS ; USERID: DB '00',0 ; EMPFL: DB BEL,BEL,BEL,'Floppy Disk Empty, proceeding...',0 ; ERASE: DB BEL,BEL,BEL,'ERASE Floppy Disk First (Y/N)? ',0 ; TABFULL: DB BEL,BEL,BEL,'MEMORY FULL...BACKUP NOT COMPLETE',BEL,BEL,BEL,0 ; BACKQUS: DB CR,LF,'Begin Backup Procedure (Y/N)? ',0 ; SORTMSG: DB CR,LF,'Sorting...',0 ; NFMSG: DB BEL,BEL,BEL,'File not found... ABORTING',0 ; BCKUM: DB 'Backing up: ',0 ; BCKUM2: DB ' to: ',0 ; BCKUM3: DB ' ... ',0 ; BCKUM5: DB ' read ',BS,BS,BS,BS,BS,BS,0 ; BCKUM6: DB ' write',BS,BS,BS,BS,BS,BS,0 ; BCKUM7: DB CR,LF,'Beginning backup to volume: ',0 ; BCKUM8: DB ' ...',CR,LF,0 ; KILDUP: DB CR,LF,'Eliminating duplicate entries...',0 ; RPTING: DB CR,LF,'Writing consolidated listing...',0 ; FREEKS: DB ' K left',0 ; DONEBU: DB ' done.',0 ; DMNTMSG: DB BEL,BEL,BEL,BEL,BEL,'Please dismount backup disk and label: ' ; VOLSER: DB '???',0 ;VOLUME ID stored here ; MNTMSG: DB BEL,BEL,BEL,'Mount backup disk on ' ; BACKUPDRV:DS 1 ;backup floppy drive letter ; DB ' & enter 3 char disk ID or "END": ',0 ; ENDLIT: DB 'END' ; PRNTREC: PRNDISK: DS 1 PRNUSR1: DS 1 PRNUSR2: DS 1 DB ':' PRNFILE: DS 8 DB '.' PRNTYPE: DS 3 PRNTSIZ: DB ' ',0 PRNTK: DB 'k',0 DISSEP: DB ' ',0 ; CRLFLFLF: DB CR,LF,CR,LF,CR,LF,0 INDEX: DB 'The following files are on diskette No.: ' IDISKNO: DS 3 DB ' as of ' IDATE: DS 8 DB 0 ; CRLF: DB CR,LF,0 FRMFD: DB FF,0 ; ; IF COMPRES TAB: DB ' ',0 ;tab 6 spaces between file names v1.2 IDENT: DB CR,' ',0 ;print left margin 9 spaces v1.2 ENDIF ; IF NORMAL TAB: DB '',0 ;tab 0 space between file names v1.2 IDENT: DB CR,' ',0 ;print left margin 5 spaces v1.2 ENDIF ; HEAD1: DB 'Consolidated Alphabetical Index by disk/user as of ',0; CURUSER: DB 16 ;current user number (local) ; DATE: DS 8 DB ' ',0 ; BIGMSG: DB CR,LF,BEL,BEL,BEL,'File TOO large for one diskette ' DB 'so NOT backed up: ',0 ; DSKFMSG: DB CR,LF,BEL,BEL,BEL,'Floppy disk full.',CR,LF,0 ; STRTMSG: DB CR,LF,'Starting',0 ; CONTMSG: DB CR,LF,'Continuing',0 ; FINIMSG: DB CR,LF,'Finished',0 ; BCKUMSG: DB ' backup of disk: ' LASTDSK: DB '?.',CR,LF,0 ; EXITBU: DB CR,LF,'[Exiting BU]',CR,LF,0 ; SETF4: DB 0 ; KPTR: DW 0 ; HDFCB: DS 1 HDFILE: DS 8 HDTYPE: DS 3 DS 24 ; FPFCB: DS 36 ; INBUF: DB 30 INCNT: DS 1 INREC: DS 30 ; STACK: DS 80 ; EOF: DS 1 ABORT: DS 1 GOTONE: DS 1 ;flag to indicate valid file found, entry made LINECNT: DS 1 LASTUSR: DS 1 TABADDR: DS 2 TABCNT: DS 2 SELFLAG: DS 1 ADDR1: DS 2 ADDR2: DS 2 ADDR3: DS 2 MAX1: DS 2 MAX2: DS 2 SAVCUSR: DS 2 ;used to restore max1 between users TAGFLG: DB 'Y' ;set 'Y' or 'N' to indicate if tagged files skipped CURUSR: DB 0 ;used to save current user on hard disk FLFREE: DW 0 ;Floppy available space FLMAXS: DW 0 ;Floppy maximum space FLMXKB: DW 0 ;Floppy max in kb FLUSED: DW 0 ;Floppy used space FLALV: DW 0 ;allocation vector FLALVS: DW 0 ;allocation vector size FLDIRT: DW 0 ;directory total FLSFAC: DB 0 ;shift factor HDFLSZ: DW 0 ;Hard disk file size ; RDISK: DS 1 ;disk ID RUSR: DS 1 ;user # RFILE: DS 8 ;filename RTYPE: DS 3 ;and type DB 0 ; TEMP: DS RECSIZ DISKBUF: DS 128 COMPSIZE: DS 1 ; RAM: EQU $ ; END BASE+100H