home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug081.ark / BACKUP.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  27.3 KB  |  1,115 lines

  1. ; DISK DIRECTORY AND BACKUP PROGRAM
  2. ;COPYRIGHT 1980, G. YOUNG, INC.'
  3. ;UPDATED 10/12/81
  4. * THE PRIMARY PURPOSE OF THIS PROGRAM IS TO BACKUP HARD DISKS ON TO
  5. * MULTIPLE FLOPPIES.  FIRST, IT EXTRACTS THE DIRECTORIES FROM ALL OF
  6. * THE HARD DISKS, SORTS BY TYPE AND FILE NAME, AND PRINTS A CONSOLIDATED
  7. * DIRECTORY.  THEN IT DELETES DUPLICATE FILES FROM THE CONSOLIDATED
  8. * DIRECTORY, DELETES UNWANTED TYPES (PRN, BAK, ETC), AND UNWANTED
  9. * FILES TO CREATE A LIST OF FILES TO BACKUP.  THESE ARE COPIED TO
  10. * MULTIPLE FLOPPIES AS NEEDED WHILE PRODUCING AN INDEX OF WHAT FILES ARE
  11. * ON EACH DISKETTE.  RESTART CAPABILITY IS PROVIDED TO BEGIN THE BACKUP
  12. * AT ANY FILE.
  13.  
  14. * WRITTEN BY GARY YOUNG, BOX 3218, NO. HOLLYWOOD, CA 91609
  15.  
  16.     TITLE    '*** HARD DISK BACKUP PROGRAM ***'
  17.     ORG    100H
  18.     JMP    START
  19.     DB    'COPYRIGHT 1980, G. YOUNG, INC.'
  20. RECSIZE    EQU    12        ;RECORD SIZE AS FOLLOWS
  21.                 ; TYPE   = 3 BYTES
  22.                 ; FILE     = 8 BYTES
  23.                 ; DISKID = 1 BYTES
  24. NODRV    EQU    3        ;SCAN DRIVES A: B: AND C:
  25. DRIVES    DB    'ABC'        ;DRIVE NOS FOR THE HARD DISKS
  26. BACKUPDRV    EQU    'D'    ;BACKUP FLOPPY DRIVE NO
  27. NOSKIP    EQU    6        ;NUMBER OF FILES IN SKIP LIST
  28. SKIPTYPE DB    'PRNHEXSYMBAK$$$TMP'   ;FILES TO NOT BACK UP
  29. IDSIZE        EQU    1    ;ID NOW MEANS A:, B:, C:, ETC
  30. LINESPAGE    EQU    60    ;LINES PER PAGE
  31. RECLINE        EQU    4    ;ENTRIES PER LINE
  32. START    LXI    SP,STACK+80
  33.     LXI    H,RAM        ;SET UP TABLE ADDRESS
  34.     SHLD    TABADDR
  35.     LXI    H,0000H
  36.     SHLD    TABCNT
  37.     XRA    A        ;THE TABLE REFERS TO THE REMAINING AREA
  38.     STA    ABORT        ;OF RAM TO HOLD AS MANY DIRECTORY ENTRIES
  39.     STA    EOF        ;AS POSSIBLE
  40.     LXI    D,SIGNON    ;PRINT SIGNON MESSAGE
  41.     CALL    OUTPUT
  42. *MSG1    LXI    D,DATEMSG    ;GET CURRENT DATE FOR REPORTS
  43. *    CALL    QUESTION    ;PRINT MSG AND GET REPLY
  44. *    CPI    8        ;8 CHAR MUST HAVE BEEN ENTERED
  45. *    JNZ    MSG1        ;REPEAT QUESTION IF NOT
  46. *    LXI    H,INREC        ;MOVE DATE FROM INREC
  47. *    IF YOU DO NOT HAVE A CLOCK/DATE BOARD, REMOVE THE * FROM THE ABOVE
  48. *    LINES AND ASTERISK THE NEXT 2 LINES WHICH CALL THE CLOCK TO GET THE
  49. *    DATE
  50.     CALL    GETDATE        ;GET DATE FROM CLOCK BOARD
  51.     LXI    H,DATETIME+1
  52.     MVI    B,8        ;MOVE THE DATE TO A HOLD AREA
  53.     LXI    D,DATE        ;TO "DATE"
  54.     CALL    MOVE
  55.     CALL    EXTRACT        ;GET DIRECTORY ENTRIES
  56.     LDA    ABORT        ;SEE IF TOO MANY ENTRIES FOR MEMORY SIZE
  57.     ORA    A        ;SHOULD BE ZERO TO BE OK
  58.     JZ    NOMORE
  59.     LXI    D,TABFULL    ;REPORT WILL NOT BE COMPLETE
  60.     CALL    OUTPUT        ;MEMORY FULL ERROR
  61. NOMORE    CALL    SORT        ;SORT THE MEMORY TABLE BY TYPE, FILE
  62.                 ;NAME, THEN DISK ID
  63.     MVI    A,RECSIZE    ;SETUP TO REMOVE DUPLICATE ENTRIES
  64.     STA    COMPSIZE    ;COMPARE ON ALL CHAR
  65.     CALL    KILLDUPS    ;REMOVE DUPLICATE ENTRIES
  66.     CALL    REPORT        ;PRINT ALL ENTRIES
  67.     MVI    A,11        ;REMOVE FILES THAT ARE ON MULTIPLE DISKS
  68.     STA    COMPSIZE
  69.     CALL    KILLDUPS
  70.     CALL    SELECT        ;RESTRICT THE FILES TO BACKUP
  71. MSG3    LXI    D,BACKQUS    ;ASK IF YOU WANT BACKUP FUNCTION
  72.     CALL    QUESTION
  73.     CPI    1
  74.     JNZ    MSG3
  75.     LDA    INREC
  76.     CPI    'N'
  77.     JZ    FINISHED
  78.     CPI    'Y'
  79.     JNZ    MSG3
  80.     CALL    BACKUP        ;BACKUP THOSE FILES REPORTED ON
  81. FINISHED    MVI    C,0
  82.     JMP    BDOS        ;RESET AND RETURN TO CPM
  83. *
  84. * THE EXTRACT ROUTINE SCANS ALL THE DRIVES IN THE DRIVE TABLE
  85. * WHEN COMPLETE, IT ASKS FOR THE NEXT DRIVE ID
  86. * WHEN THE HARD DISK IS UP, IT WILL NOT ASK FOR THE DRIVE ID BUT
  87. * WILL AUTOMATICALLY SCAN THE THREE HARD DISKS AND FINISH WITHOUT
  88. * EVER ASKING FOR THE DRIVE ID.
  89. *
  90. * THE DUMMYFCB SETS UP A SKELETON TO READ ALL FILES ON THE DIRECTORY
  91. *
  92. DUMMYFCB    DB    0,'????????????',0,0,0,0,0,0,0,0,0
  93.         DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  94. EXTRACT    LXI    H,DRIVES    ;GET ADDRESS OF THE DRIVE TABLE
  95.     SHLD    ADDR1        ;TO SCAN
  96.     MVI    A,NODRV+1    ;SET UP COUNTER FOR THE NUMBER TO SCAN
  97.     STA    MAX1
  98. NEXTDRV    LDA    MAX1        ;SEE IF THERE ARE MORE DRIVES TO SCAN
  99.     DCR    A
  100.     STA    MAX1        ;RETURN WHEN ALL HAVE BEEN SCANNED
  101.     RZ
  102.     LHLD    ADDR1        ;GET ADDRESS OF DRIVE TABLE
  103.     MOV    A,M        ;GET DRIVE CHARACTER
  104.     STA    RDISK
  105.     ANI    0FH        ;CONVERT A=1...P=15
  106.     STA    DUMMYFCB    ;SET IN DR OF DUMMYFCB
  107.     INX    H        ;SET FOR NEXT READ OF DRIVE TABLE
  108.     SHLD    ADDR1
  109.     LXI    D,DISKBUF    ;SET A DMA ADDRESS FOR DIRECTORY ENTRIES
  110.     MVI    C,1AH
  111.     CALL    BDOS        ;SET DMA
  112.     LXI    D,DUMMYFCB    ;GET FIRST DIRECTORY ENTRY
  113.     MVI    C,11H
  114.     CALL    BDOS        ;GET DIRECTORY
  115.     INR    A
  116.     JZ    NEXTDRV        ;NO MORE ENTRIES ON THIS DRIVE
  117.     JMP    GETFCB        ;EXTRACT DATA FROM FCB
  118. NEXTFCB    LXI    D,DUMMYFCB    ;GET NEXT ENTRY AFTER THE FIRST
  119.     MVI    C,12H
  120.     CALL    BDOS
  121.     INR    A
  122.     JZ    NEXTDRV        ;NO MORE DIRECTORIES ON THIS DISK
  123. GETFCB    LXI    D,32        ;EACH ENTRY IS 32 BYTES LONG
  124.     LXI    H,DISKBUF    ;DIRECTORY RECORD IS IN DISKBUF
  125.     CPI    1        ;FIRST ENTRY IN RECORD???
  126.     JZ    FORMREC        ;YES
  127.     DAD    D        ;ADD 32 TO ADDRESS IN RECORD
  128.     CPI    2        ;SECOND ENTRY IN RECORD???
  129.     JZ    FORMREC
  130.     DAD    D        ;ADD 64 TO ADDRESS OF RECORD
  131.     CPI    3        ;THIRD ENTRY IN RECORD???
  132.     JZ    FORMREC
  133.     DAD    D        ;ADD 96 TO ADDRESS OF RECORD
  134. FORMREC    INX    H        ;PASS DRIVE BYTE
  135.     LXI    D,RFILE        ;MOVE FILE NAME
  136.     MVI    B,8        ;MOVE 8 CHARACTERS
  137.     CALL    MOVE
  138.     LXI    D,8        ;POSITION PAST NAME TO TYPE
  139.     DAD    D
  140.     LXI    D,RTYPE        ;MOVE TYPE
  141.     MVI    B,3        ;MOVE 3 CHARACTERS
  142.     CALL    MOVE
  143.     INX    H        ;POSITION TO THE EXTENT NUMBER
  144.     INX    H
  145.     INX    H
  146.     MOV    A,M        ;GET THE EXTENT
  147. *    ORI    30H        ;DIAGNOSTIC DISPLAY
  148. *    STA    RDISK+1
  149. *    LXI    D,RTYPE
  150. *    CALL    OUTPUT
  151. *    LDA    RDISK+1
  152. *    ANI    0FH
  153.     LXI    H,RTYPE        ;STRIP OFF THE HIGH BIT SET BY
  154.     MVI    B,11        ;THE VERSION PROGRAM
  155. STRIP    MOV    A,M
  156.     ANI    07FH
  157.     MOV    M,A
  158.     INX    H
  159.     DCR    B
  160.     JNZ    STRIP
  161.     LXI    H,RTYPE        ;SKIP OVER JUNK DISK ENTRIES
  162.     MVI    B,11        ;CONTAINING NONPRINTING CHARACTERS
  163. NONPRNT MOV    A,M
  164.     CPI    20H        ;ANY CHAR LESS THAN A BLANK
  165.     JC    NEXTFCB        ;GO TO NEXT ONE IF SO
  166.     INX    H
  167.     DCR    B
  168.     JNZ    NONPRNT
  169. FIRSTEXT    EQU    $    ;GOT THE FIRST EXTENT
  170.     LHLD    TABADDR        ;GET MEMORY TABLE ADDRESS
  171.     LXI    D,RTYPE        ;GET MEMORY RECORD ADDRESS
  172.     XCHG            ;RTYPE (HL) TO TABADDR (DE)
  173.     MVI    B,RECSIZE    ;MOVE RECSIZE BYTES
  174.     CALL    MOVE
  175.     LHLD    TABADDR        ;INCREMENT FOR NEXT ENTRY
  176.     LXI    D,RECSIZE        ;RECSIZE BYTES IN RECORD
  177.     DAD    D
  178.     SHLD    TABADDR        ;SAVE NEW ADDRESS
  179.     MVI    M,1AH        ;SET AN END-OF-TABLE INDICATOR
  180.     LHLD    TABCNT        ;GET RECORD COUNT
  181.     INX    H
  182.     SHLD    TABCNT        ;INCREMENT RECORD COUNT
  183.     LHLD    TABADDR        ;SEE IF NEW ADDRESS IS GREATER
  184.     XCHG            ;THAN THE TOP OF TPA-128
  185.     LHLD    BDOS+1        ;HL=TOP...DE=TABLE+RECSIZE
  186.     LXI    B,-128
  187.     DAD    B        ;SUBTRACT 128 FROM TOP
  188.     CALL    COMPREG        ;COMPARE REGISTER VALUES
  189.     JNC    NEXTFCB        ;THERE IS ROOM FOR MORE
  190.     MVI    A,1        ;NO MORE ROOM...ABORT NOW
  191.     STA    ABORT
  192.     RET
  193.  
  194.  
  195. * THE FOLLOWING ROUTINE IS A BUBBLE SORT.  IN PSEUDOBASIC
  196. * IS WOULD BE DONE AS FOLLOWS:
  197. *SORT    ADDR1=BOTTOM(RAM)-RECSIZE (RECSIZE IS COUNT OF BYTES IN ONE RECORD)
  198. *    MAX1=0
  199. *LOOP1    MAX1=MAX1+1
  200. *    ADDR1=ADDR1+RECSIZE    (FIRST TIME THIS WOULD BE THE BOTTOM)
  201. *    IF MAX1>TABCNT-1 THEN GO TO SORTED
  202. *    ADDR2=ADDR1
  203. *    MAX2=MAX1
  204. *LOOP2    MAX2=MAX2+1
  205. *    ADDR2=ADDR2+RECSIZE
  206. *    IF MAX2>TABCNT THEN GO TO LOOP1
  207. *    IF TABLE(ADDR1)<TABLE(ADDR2) THEN GO TO LOOP2
  208. *    TEMP=TABLE(ADDR1)
  209. *    TABLE(ADDR1)=TABLE(ADDR2)
  210. *    TABLE(ADDR2)=TEMP
  211. *    GO TO LOOP2
  212. *SORTED    RETURN
  213. *
  214. *NOW THAT THIS LOGIC IS INTUITIVELY OBVIOUS, HERE'S THE NOT SO
  215. *OBVIOUS CODE:
  216.  
  217. SORT    LXI    D,SORTMSG    ;PUT OUT A MESSAGE SO THE USER DOES
  218.     CALL    OUTPUT        ;NOT THINK THIS CRASHED WHILE SORTING
  219.     LXI    H,0000        ;INITIALIZE COUNT
  220.     SHLD    MAX1        ;SINCE IT WILL DECREMENT FIRST
  221.     LXI    D,-RECSIZE    ;SUBTRACT RECSIZE FROM THE BEGINNING
  222.     LXI    H,RAM        ;OF THE TABLE SINCE IT WILL ADD
  223.     DAD    D        ;RECSIZE TO IT FIRST
  224.     SHLD    ADDR1
  225. LOOP1    LHLD    ADDR1        ;GET THE CURRENT ADDRESS
  226.     LXI    D,RECSIZE        ;INCREMENT IT BY RECSIZE
  227.     DAD    D        ;PAST THE NEXT ENTRY
  228.     SHLD    ADDR1
  229.     LHLD    MAX1        ;SEE IF THE COUNT HAS REACHED THE LIMIT
  230.     INX    H        ;INCREMENT THE COUNTER
  231.     SHLD    MAX1
  232.     XCHG            ;MOVE TO DE TO COMPARE TO LIMIT
  233.     LHLD    TABCNT
  234.     DCX    H        ; IS MAX1 > TABCNT - 1 ???
  235.     CALL    COMPREG        ;COMPARE DE (CURRENT COUNT) TO HL (TABCNT-1)
  236.     JC    SORTED        ;FINISHED WHEN MAX1 > TABCNT-1
  237.     LHLD    ADDR1        ;SETUP FOR THE INNER LOOP
  238.     SHLD    ADDR2
  239.     LHLD    MAX1
  240.     SHLD    MAX2
  241. LOOP2    LHLD    ADDR2        ;START WITH ONE ENTRY GREATER THEN
  242.     LXI    D,RECSIZE        ;THE OUTER LOOP AND INCREMENT
  243.     DAD    D        ;BY RECSIZE EACH TIME PAST THE NEXT RECORD
  244.     SHLD    ADDR2        ;POINTER TO THE CURRENT RECORD
  245.     LHLD    MAX2        ;LIKEWISE SEE IF THE COUNTER FOR THE
  246.     INX    H
  247.     SHLD    MAX2
  248.     XCHG
  249.     LHLD    TABCNT
  250.     CALL    COMPREG
  251.     JC    LOOP1        ;WHEN FINISHED, INCREMENT OUTER LOOP
  252.     LHLD    ADDR2
  253.     XCHG            ;ADDR2 NOW IN DE
  254.     LHLD    ADDR1
  255.     CALL    COMPARE        ;COMPARE STRINGS POINTED TO BY DE/HL
  256.     JNC    LOOP2        ;TABLE(HL) < TABLE (DE)
  257. * EXCHANGE THE TWO ENTRIES VIA A TEMPORARY RECORD
  258.     LXI    D,TEMP
  259.     LHLD    ADDR1
  260.     MVI    B,RECSIZE
  261.     CALL    MOVE        ;TEMP=TABLE(ADDR1)
  262.     XCHG            ;ADDR1=DESTINATION
  263.     LHLD    ADDR2        ;ADDR2=SOURCE
  264.     CALL    MOVE        ;TABLE(ADDR1)=TABLE(ADDR2)
  265.     XCHG            ;ADDR2 = DESTINATION
  266.     LXI    H,TEMP
  267.     CALL    MOVE        ;TABLE(ADDR2)=TEMP
  268.     JMP    LOOP2
  269. SORTED    RET            ;FINISHED SORTING
  270.  
  271.  
  272. * REPORT PRINTS THE SORTED CONSOLIDATED DIRECTORY ENTRIES.  
  273. * LINESPAGE IS THE NUMBER OF LINES PER PAGE AND RECLINE IS THE
  274. * NUMBER OF 20 BYTE ENTRIES PER LINE.  EACH TYPE BEGINS ON A 
  275. * NEW PAGE.
  276.  
  277. REPORT    LHLD    TABCNT        ;SET COUNT OF ENTRIES
  278.     INX    H        ;PLUS ONE
  279.     SHLD    LASTTYPE    ;INIT LASTTYPE TO INVALID DATA
  280.     SHLD    MAX1        ;TO DECREMENT FIRST
  281.     LXI    H,RAM-RECSIZE    ;SET STARTING ADDRESS
  282.     SHLD    ADDR1
  283.     CALL    HEADING
  284. NEXTPRT    LHLD    ADDR1
  285.     LXI    D,RECSIZE    ;SET TO ADD THE REC LENGTH
  286.     DAD    D
  287.     SHLD    ADDR1
  288.     LHLD    MAX1        ;DECREMENT COUNT TO SEE WHEN DONE
  289.     DCX    H
  290.     SHLD    MAX1
  291.     LXI    D,0000        ;SEE IF REACHED ZERO YET
  292.     CALL    COMPREG
  293.     JZ    TOPPAGE        ;GO TO TOP OF NEXT PAGE
  294.     LHLD    ADDR1        ;CURRENT TYPE = LAST TYPE?
  295.     MVI    B,3        ;COMPARE 3 CHARACTERS
  296.     LXI    D,LASTTYPE
  297.     CALL    COMPARE
  298.     JNZ    SKIP3        ;NEW TYPE ON NEW PAGE
  299. PRNTNOW    LDA    MAX2        ;DECREMENT RECORDS PER LINE
  300.     DCR    A
  301.     STA    MAX2
  302.     JZ    NEWLINE        ;LINE FULL, GO TO NEW LINE
  303.     CALL    FORMAT
  304.     LXI    D,PRNTREC
  305.     CALL    LIST
  306.     JMP    NEXTPRT
  307. SKIP3    LDA    LINECNT
  308.     DCR    A
  309.     JZ    NEWPAGE
  310.     DCR    A
  311.     JZ    NEWPAGE
  312.     DCR    A
  313.     JZ    NEWPAGE
  314.     STA    LINECNT
  315.     LXI    D,CRLFLFLF
  316.     CALL    LIST
  317.     JMP    CHKTYPE
  318. NEWPAGE    CALL    HEADING
  319. CHKTYPE    LXI    D,LASTTYPE    ;SET LAST TYPE TO CURRENT TYPE
  320.     LHLD    ADDR1
  321.     MVI    B,3
  322.     CALL    MOVE
  323. SETCNT    MVI    A,RECLINE+1
  324.     STA    MAX2
  325.     JMP    PRNTNOW
  326. NEWLINE    LXI    D,CRLF
  327.     CALL    LIST
  328.     LDA    LINECNT
  329.     DCR    A
  330.     STA    LINECNT
  331.     JZ    NEWPAGE        ;PAGE FULL
  332.     JMP    SETCNT
  333. TOPPAGE    RET
  334.  
  335.  
  336. * THE PURPOSE OF SELECT IS TO CREATE A FINAL LIST OF FILES TO
  337. * BACKUP.  SINCE BACKING UP 26 MEG CAN BE QUITE LONG, THIS REDUCES
  338. * THE LIST TO ONLY NECCESSARY FILES.   IT ALSO ALLOWS A RESTART
  339. * AT ANY FILE.  IT WILL DELETE DUPLICATE FILE NAMES (FILES ON A:
  340. * WILL BE USED SINCE THAT IS ASSUMED TO BE THE LATEST), AND
  341. * WILL DELETE THE FILE TYPES LISTED IN THE SKIP TABLE.  THEN IT
  342. * WILL LIST EACH TYPE AND ASK IF YOU DO WANT TO BACK UP ALL OF
  343. * THIS TYPE (Y), SKIP BACKING UP OF THE ENTIRE TYPE (N), OR
  344. * SELECT CERTAIN FILES (S) TO BACK UP.  IF THE SELECT OPTION IS
  345. * CHOSEN, EACH FILE NAME WILL BE PRINTED AND YOU BE ASKED TO
  346. * BACK UP THE FILE (Y), IGNORE THE FILE DURING THE BACKUP
  347. * (N), OR CONTINUE (C) TO BACKUP ALL OF THE REMAINING FILES
  348. * WITHIN THIS TYPE WITHOUT ASKING ANY FURTHER NAMES (USED FOR 
  349. * RESTART).  AFTER THE LIST HAS BEEN REDUCED, IT WILL BE LISTED
  350. * BEFORE THE BACKUP ACTUALLY BEGINS.
  351.  
  352. KILLDUPS EQU    $    ;KILL DUPLICATE ENTRIES FROM MULTIPLE EXTENTS
  353.     LXI    H,RAM
  354.     SHLD    ADDR1            ;SET THE START OF THE TABLE
  355. NEXTEQUAL    LHLD    ADDR1        ;CHECK EACH ENTRY AGAINST THE NEXT
  356.     LXI    D,RECSIZE
  357.     DAD    D
  358.     SHLD    ADDR2
  359. NEXTCHK    MOV    A,M            ;CHECK FOR END OF TABLE
  360.     CPI    1AH
  361.     RZ
  362.     XCHG
  363.     LHLD    ADDR1            ;COMPARE ADDR1 WITH ADDR2
  364.     LDA    COMPSIZE
  365.     MOV    B,A
  366.     CALL    COMPARE
  367.     JNZ    SAVELAST
  368.     PUSH    H            ;SAVE CURRENT POSITION
  369.     LHLD    ADDR2            ;SET UP FOR MOVING LIST
  370.     SHLD    ADDR1            ;DOWN ONE ENTRY
  371.     LXI    D,RECSIZE
  372.     DAD    D            ;MOVE THIRD ENTRY TO THE SECOND
  373.     SHLD    ADDR2
  374.     CALL    MOVELIST
  375.     LHLD    TABCNT
  376.     DCX    H
  377.     SHLD    TABCNT
  378.     POP    H            ;RESTORE CURRENT POSITION
  379.     SHLD    ADDR1            ;NOW COMPARE 1ST & 3RD
  380.     JMP    NEXTEQUAL
  381. SAVELAST    LHLD    ADDR2        ;MAKE NEW ONE THE CURRENT ONE
  382.     SHLD    ADDR1
  383.     JMP    NEXTEQUAL        ;COMPARE
  384.  
  385. SELECT    EQU    $
  386. NOWSELECT    EQU    $        ;LET USER ELIMINATE SOME
  387.     LXI    H,RAM-RECSIZE        ;INITIALIZE
  388.     SHLD    ADDR1
  389.     SHLD    LASTTYPE        ;MAKE SURE LASTTYPE DOES NOT MATCH
  390. NEXTENTRY    LHLD    ADDR1        ;GET NEXT RECORD IN TABLE
  391.     LXI    D,RECSIZE
  392.     DAD    D
  393.     SHLD    ADDR1            ;INCREMENT TABLE ENTRY
  394. CHKNEXT    MOV    A,M            ;CHECK FOR THE END OF THE TABLE
  395.     CPI    1AH            ;CNTL-Z IS AT END
  396.     JZ    LISTBKUP        ;LIST THE FINAL TABLE
  397.     LXI    D,LASTTYPE        ;SEE IF THE CURRENT TYPE IS THE
  398.     LHLD    ADDR1            ;LAST TYPE
  399.     MVI    B,3
  400.     CALL    COMPARE
  401.     JZ    CHKSELECT        ;TYPES MATCH, CHECK FILE SELECT
  402.     CALL    MOVE            ;TYPES DON'T MATCH, MAKE THE
  403.                     ;LAST TYPE = CURRENT TYPE NOW
  404.     MVI    C,NOSKIP+1        ;SEE IF THE NEW TYPE IS IN THE
  405.     LXI    D,SKIPTYPE        ;LIST OF FILE TYPES TO SKIP
  406.     MVI    B,3
  407. NEXTSKIP    DCR    C        ;DECREMENT NO OF FILES TO SKIP
  408.     JZ    FORMQUS            ;FILE IS GOOD
  409.     LHLD    ADDR1
  410.     CALL    COMPARE
  411.     JZ    SKIPALLTYPE        ;FILE WAS ON THE SKIP LIST
  412.     INX    D            ;INCREMENT TO NEXT SKIP FILE
  413.     INX    D
  414.     INX    D
  415.     JMP    NEXTSKIP
  416. FORMQUS    LXI    D,QTYPE            ;FORM THE QUESTION ABOUT WHETHER
  417.     LHLD    ADDR1            ;TO SKIP THIS FILE TYPE OR NOT
  418.     MVI    B,3            ;MOVE THE FILE TYPE TO THE 
  419.     CALL    MOVE            ;QUESTION PRINT LINE
  420.     XRA    A
  421.     STA    SELFLAG            ;RESET THE SELECT FLAG
  422. REASK1    LXI    D,QUEST1
  423.     CALL    QUESTION        ;ASK THE QUESTION ABOUT THE TYPE
  424.     CPI    1            ;ONE CHARACTER RESPONSE ALLOWED
  425.     JNZ    REASK1
  426.     LDA    INREC            ;GET THE RESPONSE
  427.     CPI    'N'
  428.     JZ    SKIPALLTYPE
  429.     CPI    'Y'
  430.     JZ    SAVEALLTYPE
  431.     CPI    'S'            ;S=SELECT CERTAIN FILES FROM THIS
  432.     JNZ    REASK1            ;TYPE
  433.     MVI    A,1            ;SET THE SELECT FLAG
  434.     STA    SELFLAG            ;TO ASK THE NEXT QUESTION
  435. ASKFILE    LHLD    ADDR1            ;FORMAT A QUESTION TO ASK IF THIS
  436.     LXI    D,QTYPE2        ;PARTICULAR FILE IS TO BE SAVED
  437.     MVI    B,3
  438.     CALL    MOVE
  439.     LXI    D,QFILE2        ;MOVE THE FILE NAME TO THE QUESTION
  440.     INX    H
  441.     INX    H            ;POSITION PAST THE FILE TYPE
  442.     INX    H            ;IN THE TABLE
  443.     MVI    B,8
  444.     CALL    MOVE            ;MOVE THE NAME
  445.     LXI    D,8            ;POSITION PAST NAME TO THE
  446.     DAD    D            ;DISK ID
  447.     LXI    D,QDISK2        ;MOVE THE DISK ID
  448.     MVI    B,IDSIZE
  449.     CALL    MOVE    
  450. REASK2    LXI    D,QUEST2        ;ASK THE FILE QUESTION
  451.     CALL    QUESTION
  452.     CPI    1            ;ONLY A 1 CHAR RESPONSE ALLOWED
  453.     LDA    INREC
  454.     JNZ    REASK2
  455.     CPI    'C'            ;CONTINUE WITH THE REST OF THE
  456.     JZ    SAVEALLTYPE        ;FILES WITHIN THIS TYPE - RESTART
  457.     CPI    'Y'            ;SAVE THIS PARTICULAR FILE
  458.     JZ    NEXTENTRY
  459.     CPI    'N'
  460.     JNZ    REASK2
  461.     LHLD    ADDR1            ;SHORTEN THE LIST BY ONE ENTRY
  462.     LXI    D,RECSIZE
  463.     DAD    D
  464.     SHLD    ADDR2            ;SKIP THE LAST ONE
  465.     CALL    MOVELIST        ;MOVES THE LIST DOWN FROM ADDR1
  466.                     ;TO ADDR2
  467.     LHLD    ADDR1
  468.     JMP    CHKNEXT            ;CHECK NEXT ENTRY
  469. CHKSELECT    LDA    SELFLAG        ;CHECK THE SELECT FLAG
  470.     ORA    A            ;IF NOT ZERO, ASK THE QUESTION
  471.     JNZ    ASKFILE            ;ABOUT EACH FILE
  472.     JMP    NEXTENTRY
  473. SKIPALLTYPE    CALL    FINDTYPE    ;FIND THE NEXT TYPE NOT MATCHING
  474.     CALL    MOVELIST        ;THIS ONE AND MOVE THE LIST DOWN
  475.     LHLD    ADDR1
  476.     JMP    CHKNEXT            ;TO SKIP THIS TYPE
  477. SAVEALLTYPE    CALL    FINDTYPE    ;SAVE ALL OF THIS TYPE
  478.     LHLD    ADDR2            ;RESET THE ADDRESS TO THE NEXT
  479.     SHLD    ADDR1            ;TYPE
  480.     JMP    CHKNEXT
  481. MOVELIST    LHLD    ADDR2        ;MOVE THE TABLE FROM ADDR2 DOWN
  482.     XCHG                ;TO ADDR1 THEREBY ELIMINATING
  483.     LHLD    ADDR1            ;UNWANTED ENTRIES
  484. MOVENEXT    LDAX    D        ;AND MAKING MORE ROOM FOR THE
  485.     MOV    M,A
  486.     CPI    1AH
  487.     RZ
  488.     INX    H
  489.     INX    D
  490.     JMP    MOVENEXT
  491. FINDTYPE    LHLD    ADDR1        ;FIND THE NEXT ENTRY
  492.     SHLD    ADDR2            ;WITH A TYPE DIFFERENT
  493. FINDIT    LHLD    ADDR2            ;THAN THE CURRENT TYPE
  494.     LXI    D,RECSIZE
  495.     DAD    D
  496.     SHLD    ADDR2
  497.     MOV    A,M            ;STOP AT END OF THE TABLE
  498.     CPI    1AH
  499.     RZ
  500.     XCHG
  501.     LHLD    ADDR1
  502.     MVI    B,3
  503.     CALL    COMPARE
  504.     RNZ
  505.     JMP    FINDIT            ;ADDR2 WILL HAVE THE ADDRESS OF
  506.                     ;THE NEXT TYPE WHEN FINISHED
  507. LISTBKUP    EQU    $        ;LIST THE FILES TO BE BACKED
  508.     SHLD    ADDR2            ;SAVE THE END OF THE TABLE FOR LATER
  509.     LXI    H,RAM-RECSIZE
  510.     SHLD    ADDR1
  511.     CALL    HEADING2
  512. NEXTONE    LHLD    ADDR1            ;PRINT THE NEXT TABLE ENTRY
  513.     LXI    D,RECSIZE
  514.     DAD    D
  515.     SHLD    ADDR1            ;INCREMENT TO THE NEXT ENTRY
  516.     MOV    A,M            ;CHECK FOR THE END OF THE
  517.     CPI    1AH            ;TABLE
  518.     RZ
  519.     CALL    FORMAT            ;FORMAT ENTRY
  520.     LXI    D,PRNTREC
  521.     CALL    LIST            ;PRINT IT
  522.     LDA    MAX2            ;SEE MORE WILL FIT ON THIS LINE
  523.     DCR    A
  524.     STA    MAX2
  525.     JZ    LINEFULL
  526.     JMP    NEXTONE
  527. LINEFULL    LXI    D,CRLF
  528.     CALL    LIST
  529.     LDA    LINECNT
  530.     DCR    A
  531.     STA    LINECNT
  532.     JZ    PAGEFULL
  533.     JMP    SETLINE
  534. PAGEFULL    CALL    HEADING2
  535.     MVI    A,LINESPAGE
  536.     STA    LINECNT
  537. SETLINE    MVI    A,RECLINE
  538.     STA    MAX2
  539.     JMP    NEXTONE
  540. HEADING2    LXI    D,HEAD2
  541.     CALL    LIST
  542.     LXI    D,CRLF
  543.     CALL    LIST
  544.     MVI    A,LINESPAGE
  545.     STA    LINECNT
  546.     MVI    A,RECLINE
  547.     STA    MAX2
  548.     RET
  549.  
  550.  
  551.  
  552. * BACKUP IS USED TO BACKUP THE FILES IN THE CREATED LIST.  IT
  553. * WILL NOT BACK UP ANY FILE THAT WILL NOT FIT ON ONE DISK ENTIRELY.
  554. * THE FILES THAT IT BACKS UP WILL COME FROM ANY OF THE HARD DISKS,
  555. * BUT NOT NECCESSARILY IN DISK ORDER, BUT RATHER ALPHABETICAL FILE
  556. * NAME ORDER.  IT WILL PROMPT FOR THE FLOPPY DISK ID AND PRINT A 
  557. * REPORT SHOWING THE FLOPPY ID AND THE FILES COPIED FOR INDEX.
  558. * IF THE FILE WILL NOT FIT ON A DISK, IT WILL BE DELETED FROM THE
  559. * DISK, THAT DISK CLOSED AND REMOVED, AND PROMPTED FOR A NEW DISK
  560. * TO RECEIVE THE FILE.  BLANK 1024 BYTE SECTORED DISKS SHOULD BE
  561. * USED FOR BEST PERFORMANCE.  WHEN ONE DISKETTE IS FULL, IT WILL
  562. * PROMPT FOR A NEW ONE SO MANY DISKETTES CAN BE USED TO BACKUP
  563. * THE HARD DISKS.  IF IT IS NECESSARY TO ABORT DURING THIS PROCESS,
  564. * USE THE RESTART CAPABILITY PROVIDED IN "SELECT".  THE AREA
  565. * FOR THE DISK BUFFER IS ALL OF RAM FROM THE END OF THE TABLE
  566. * TO THE START OF BDOS.
  567.  
  568. BACKUP    EQU    $
  569.     CALL TOPOFFORM
  570.     LHLD    ADDR2        ;GET THE CURRENT END OF TABLE
  571.     INX    H        ;PLUS ONE FOR THE START OF THE
  572.     SHLD    ADDR3        ;READ/WRITE BUFFER
  573.     LXI    H,RAM        ;SET THE ADDRESS OF THE FIRST ENTRY
  574.     SHLD    ADDR1
  575.     LXI    D,RECSIZE    ;SET AN ADDRESS FOR THE SECOND ENTRY
  576.     DAD    D        ;NEXT ENTRY = CURRENT + RECSIZE
  577.     SHLD    ADDR2        ;LATER, USE MOVELIST TO MOVE THE LIST
  578.                 ;DOWN FROM ADDR2 TO ADDR1 AFTER EACH FILE
  579.                 ;HAS BEEN COPIED.  THIS IS SO THAT THE
  580.                 ;RAM BUFFER WILL EXPAND AS THE FILES ARE
  581.                 ;COPIED SO THAT COPYING WILL BE FASTER.
  582.     CALL    MOUNT
  583.     JMP    PASSMOVE
  584. NEXTFILE    EQU    $
  585.     CALL    MOVELIST
  586.     INX    H        ;NEW START OF READ/WRITE BUFFER
  587.     SHLD    ADDR3
  588.     XRA    A        ;RESET THE FLAG FOR FILES TOO BIG
  589.     STA    TOOBIG        ;TO FIT ON ONE FLOPPY
  590. PASSMOVE    LXI    H,RAM    ;THE TABLE SHRINKS SO THE CURRENT 
  591.                 ;ENTRY IS ALWAYS AT "RAM" BUT THE
  592.                 ;READ/WRITE BUFFER GROWS
  593.     MOV    A,M
  594.     CPI    1AH
  595.     JZ    DISMOUNT    ;FINISHED
  596. FORMFCB    LXI    D,HDFCB        ;CLEAR THE FCB
  597.     MVI    B,36
  598.     XRA    A
  599. ZEROFCB    STAX    D
  600.     INX    D
  601.     DCR    B
  602.     JNZ    ZEROFCB
  603.     LXI    H,RAM        ;GET ADDRESS OF TABLE ENTRY
  604.     LXI    D,HDTYPE    ;MOVE IN THE TYPE
  605.     MVI    B,3
  606.     CALL    MOVE
  607.     INX    H
  608.     INX    H        ;POSITION TO NAME
  609.     INX    H
  610.     LXI    D,HDFILE    ;MOVE THE FILE NAME
  611.     MVI    B,8
  612.     CALL    MOVE
  613.     LXI    D,8
  614.     DAD    D        ;POSITION TO DISK ID, A:, B: ETC
  615.     MOV    A,M
  616.     ANI    0FH        ;CONVERT A=1...P=15
  617.     STA    HDFCB
  618.     LXI    D,FPFCB        ;COPY THE HDFCB TO THE FLOPPY FCB
  619.     LXI    H,HDFCB
  620.     MVI    B,36
  621.     CALL    MOVE
  622.     MVI    A,BACKUPDRV    ;SET THE RECEIVING FLOPPY DRIVE NUMBER
  623.     ANI    0FH        ;CONVERT D: TO 4
  624.     STA    FPFCB
  625.     LXI    D,HDFCB        ;OPEN THE HD FILE
  626.     MVI    C,0FH
  627.     CALL    BDOS        ;OPEN THE INPUT FILE
  628.     INR    A
  629.     JZ    NOTFOUND
  630.     LXI    D,FPFCB        ;DELETE THE FILE ON FLOPPY IF IT
  631.     MVI    C,13H        ;EXISTS
  632.     CALL    BDOS
  633.     LXI    D,FPFCB        ;CREATE THE FILE ON FLOPPY 
  634.     MVI    C,16H
  635.     CALL    BDOS        ;MAKE FILE
  636.     INR    A
  637.     JZ    DISKFULL
  638.     LXI    H,RAM
  639.     CALL    FORMAT
  640.     LXI    D,PRNTREC
  641.     CALL    OUTPUT
  642. COPYLOOP    CALL    LOADBUFF    ;LOAD MEMORY WITH FILE
  643.     CALL    WRITEBUF        ;WRITE MEMORY FILE
  644.     LDA    EOF            ;DISPLAY THE STATUS
  645.     ADI    30H
  646.     MOV    E,A            ;CONSOLE OUTPUT
  647.     MVI    C,2
  648.     CALL    BDOS
  649.     LDA    EOF
  650.     CPI    1
  651.     JZ    ENDOFFILE
  652.     CPI    2
  653.     JZ    DISKFULL
  654.     JMP    COPYLOOP
  655. ENDOFFILE    LXI    D,FPFCB        ;CLOSE FLOPPY FILE
  656.     MVI    C,10H
  657.     CALL    BDOS            ;CLOSE
  658.     LXI    H,RAM
  659.     CALL    PRINTFILE    ;WRITE FILE NAME ON INDEX LIST
  660.     JMP    NEXTFILE
  661. DISKFULL    LXI    D,FPFCB
  662.     MVI    C,13H        ;DELETE FILE ON FLOPPY
  663.     CALL    BDOS
  664.     LDA    TOOBIG            ;IS THIS THE SECOND FLOPPY
  665.     ORA    A            ;IT HAS TRIED TO COPY TO?
  666.     JZ    FIRSTTRY        ;NO, FIRST FLOPPY. RETRY
  667.     LXI    D,BIGMSG        ;YES, SECOND FLOPPY. SEND MESSAGE
  668.     CALL    LIST            ;WARNING THAT THIS FILE CANNOT
  669.     LXI    H,RAM
  670.     CALL    FORMAT            ;BE BACKED UP WITH THIS PROGRAM
  671.     LXI    D,PRNTREC
  672.     CALL    LIST            ;PRINT THE FILE NAME ALSO
  673.     CALL    MOUNT
  674.     JMP    NEXTFILE
  675. FIRSTTRY    INR    A        ;SET INDICATOR THAT IT HAS TRIED
  676.     STA    TOOBIG            ;ONCE ALREADY TO COPY IT
  677.     CALL    MOUNT        ;GET NEW DISK
  678.     JMP    FORMFCB
  679. NOTFOUND LXI    H,RAM
  680.     CALL    FORMAT
  681.     LXI    D,NFMSG
  682.     CALL    OUTPUT
  683.     LXI    D,PRNTREC
  684.     CALL    OUTPUT
  685.     RET
  686. DISMOUNT CALL    BELL
  687.     LXI    D,DMNTMSG    ;DISMOUNT FLOPPY
  688.     CALL    QUESTION
  689.     CALL    TOPOFFORM
  690.     RET
  691.  
  692.  
  693.  
  694. * ASSORTED ROUTINES
  695.  
  696. PRINTFILE    CALL    FORMAT
  697.     LXI    D,PRNTREC    ;PRINT THE FILE ENTRY
  698.     CALL    LIST
  699.     LDA    MAX2
  700.     DCR    A
  701.     STA    MAX2        ;ENTRIES PER LINE COUNTER
  702.     RNZ
  703.     LXI    D,CRLF        ;GO TO NEW LINE
  704.     CALL    LIST
  705.     MVI    A,RECLINE
  706.     STA    MAX2
  707.     RET
  708.  
  709. HEADING3    LXI    D,CRLFLFLF    ;INDEX HEADING NOT AT TOP OF FORM
  710.     CALL    LIST
  711.     LXI    D,IDISKNO        ;MOVE THE DISK ID NO TO HEADING
  712.     LXI    H,VOLSER
  713.     MVI    B,3
  714.     CALL    MOVE
  715.     LXI    D,IDATE
  716.     LXI    H,DATE
  717.     MVI    B,8
  718.     CALL    MOVE
  719.     LXI    D,INDEX
  720.     CALL    LIST
  721.     LXI    D,CRLF
  722.     CALL    LIST
  723.     MVI    A,RECLINE
  724.     STA    MAX2
  725.     MVI    A,LINESPAGE
  726.     STA    LINECNT
  727.     RET
  728.  
  729. TOPOFFORM    MVI    E,0CH    ;POSITION PRINTER TO TOP OF FORM
  730.     MVI    C,5
  731.     JMP    BDOS
  732.  
  733. MOUNT    CALL    BELL
  734.     LXI    D,MNTMSG
  735.     CALL    QUESTION
  736.     CPI    3
  737.     JNZ    MOUNT
  738.     LXI    H,INREC
  739.     LXI    D,ENDLIT
  740.     MVI    B,3
  741.     CALL    COMPARE
  742.     JZ    FINISHED
  743.     LXI    D,VOLSER
  744.     LXI    H,INREC
  745.     MVI    B,3
  746.     CALL    MOVE        ;MOVE VOLSER ID TO VOLSER
  747.     MVI    C,0DH        ;DO A SYSTEM RESET TO  CHANGE DISKS
  748.     CALL    BDOS
  749. ERA    LXI    D,ERASE
  750.     CALL    QUESTION
  751.     CPI    1
  752.     JNZ    ERA
  753.     LDA    INREC
  754.     CPI    'N'
  755.     JZ    NOERA
  756.     CPI    'Y'
  757.     JNZ    ERA
  758.     MVI    A,BACKUPDRV
  759.     ANI    0FH
  760.     STA    DUMMYFCB
  761.     MVI    C,13H
  762.     LXI    D,DUMMYFCB
  763.     CALL    BDOS        ;DELETE ALL FILES ON FLOPPY
  764. NOERA    EQU    $
  765.     CALL    HEADING3
  766.     LXI    D,FPFCB        ;CLEAR THE FCB TO CREATE A FILE NAME
  767.     MVI    B,36
  768.     XRA    A
  769. CLRFCB    STAX    D
  770.     INX    D
  771.     DCR    B
  772.     JNZ    CLRFCB
  773.     MVI    A,BACKUPDRV    ;SET UP THE DRIVE AS THE BACKUP
  774.     ANI    0FH        ;CONVERT D: TO 4
  775.     STA    FPFCB
  776.     LXI    H,DATE        ;CREATE A NULL FILE WITH THE DATE AS
  777.     LXI    D,FPFCB+1    ;THE FILE NAME AND THE 3 DIGIT
  778.     MVI    B,8
  779.     CALL    MOVE
  780.     LXI    H,VOLSER        ;3 DIGIT VOLSER AS THE FILE TYPE
  781.     LXI    D,FPFCB+9
  782.     MVI    B,3        ;THIS FILE WILL BE USED TO IDENTIFY
  783.     CALL    MOVE        ; THE DISK AND MARK THE DATE
  784.     LXI    D,FPFCB
  785.     MVI    C,16H        ;CREATE THE FILE
  786.     CALL    BDOS
  787.     INR    A
  788.     JZ    MOUNT        ;DISK FULL?
  789.     LXI    D,FPFCB
  790.     MVI    C,10H        ;CLOSE THE FILE
  791.     CALL    BDOS
  792.     RET
  793.  
  794. LOADBUFF    EQU    $    ;THIS ROUTINE LOADS AS MUCH OF
  795.     LXI    H,0000        ;MEMORY WITH THE FILE AS POSSIBLE
  796.     SHLD    MAX1
  797.     LHLD    ADDR3        ;NEW TOP OF TABLE +2
  798.     SHLD    TEMP
  799.     XRA    A
  800.     STA    EOF        ;CLEAR EOF FLAG
  801. LOADNEXT    LHLD    TEMP
  802.     XCHG            ;SET DMA ADDRESS
  803.     MVI    C,1AH
  804.     CALL    BDOS
  805.     LXI    D,HDFCB        ;READ HARD DISK
  806.     MVI    C,14H
  807.     CALL    BDOS
  808.     ORA    A
  809.     JNZ    HDEOF        ;EOF?
  810.     LHLD    MAX1
  811.     INX    H        ;INCREMENT RECORD COUNT
  812.     SHLD    MAX1
  813.     LHLD    TEMP        ;SEE IF NEXT RECORD WOULD EXCEED THE
  814.     LXI    D,128        ;TPA AREA
  815.     DAD    D
  816.     SHLD    TEMP
  817.     DAD    D        ;WILL THE NEXT RECORD OVERWRITE BDOS?
  818.     XCHG
  819.     LHLD    BDOS+1        ;FIND THE TOP OF MEMORY
  820.     CALL    COMPREG        ;COMPARE REGISTERS
  821.     RC            ;RETURN IF MEMORY ALREADY FULL
  822.     JMP    LOADNEXT    ;GET ANOTHER RECORD
  823. HDEOF    MVI    A,1        ;SET FILE EOF
  824.     STA    EOF
  825.     RET
  826.  
  827. BELL    EQU    $
  828.     MVI    C,9
  829.     LXI    D,MSG
  830.     CALL    BDOS
  831. BEEP    MVI    C,5        ;BELL ON PRINTER
  832.     MVI    E,07H
  833.     CALL    BDOS
  834.     MVI    C,2        ;07H ON CRT
  835.     MVI    E,07H
  836.     CALL    BDOS
  837.     MVI    C,0BH
  838.     CALL    BDOS        ;GET CONSOLE STATUS
  839.     ORA    A
  840.     JZ    BEEP
  841.     MVI    C,01
  842.     CALL    BDOS        ;GET THE DUMMY CHAR
  843.     RET
  844. MSG    DB    0DH,0AH,0AH,'PRESS ANY KEY TO CONTINUE'
  845.     DB    0DH,0AH,0AH,'$'
  846.  
  847. WRITEBUF    EQU    $    ;WRITE FROM THE MEMORY BUFFER
  848.     LHLD    ADDR3
  849.     SHLD    TEMP
  850.     LHLD    MAX1        ;ALLOW FOR FILES THAT HAVE NO 
  851.     LXI    D,0000        ;RECORDS SUCH AS RESTART
  852.     CALL    COMPREG
  853.     RZ
  854. WRITENEXT    LHLD    TEMP
  855.     XCHG            ;SET DMA ADDRESS
  856.     MVI    C,1AH
  857.     CALL    BDOS
  858.     LXI    D,FPFCB
  859.     MVI    C,15H        ;WRITE SEQUENTIAL
  860.     CALL    BDOS
  861.     ORA    A
  862.     JNZ    FPFULL        ;FLOPPY DISK FULL
  863.     LHLD    MAX1        ;DECREASE RECORD COUNT
  864.     DCX    H
  865.     SHLD    MAX1
  866.     LXI    D,0000        ;CHECK FOR NO MORE TO WRITE
  867.     CALL    COMPREG
  868.     RZ
  869.     LHLD    TEMP
  870.     LXI    D,128        ;INCREMENT WRITE ADDRESS
  871.     DAD    D
  872.     SHLD    TEMP
  873.     JMP    WRITENEXT
  874. FPFULL    MVI    A,2        ;FULL DISKETTE
  875.     STA    EOF
  876.     RET
  877.  
  878. FORMAT    LXI    D,PRNTYPE    ;FORMAT THE ENTRY FROM THE TABLE
  879.     MVI    B,3        ;FORMAT TO THE PRINT FORMAT
  880.     CALL    MOVE        ;THE TABLE ADDRESS IS ASSUMMED TO BE
  881.     LXI    D,3        ;IN HL. FIRST MOVE THE TYPE
  882.     DAD    D        ;NOW POSITION TO THE FILE NAME
  883.     LXI    D,PRNFILE    ;MOVE THE FILE NAME
  884.     MVI    B,8
  885.     CALL    MOVE
  886.     LXI    D,8        ;POSITION TO THE DISK ID
  887.     DAD    D
  888.     LXI    D,PRNTREC    ;MOVE THE DISK ID TO THE LINE
  889.     MVI    B,IDSIZE
  890.     CALL    MOVE
  891.     RET
  892.  
  893. COMPREG    MOV    A,H        ;COMPARE HL TO DE
  894.     CMP    D
  895.     RNZ
  896.     MOV    A,L
  897.     CMP    E
  898.     RET
  899.  
  900. OUTPUT    PUSH    D        ;PUT OUT A CRLF
  901.     LXI    D,CRLF
  902.     MVI    C,09
  903.     CALL    BDOS
  904.     POP    D        ;NOW PUT OUT THE MESSAGE
  905. OUT1    MVI    C,09
  906.     JMP    BDOS
  907.  
  908. HEADING    LXI    D,HEAD1
  909.     CALL    LIST
  910.     LXI    D,DATE
  911.     CALL    LIST
  912.     LXI    D,TABFULL
  913.     LDA    ABORT
  914.     ORA    A
  915.     CNZ    LIST
  916.     MVI    A,LINESPAGE
  917.     STA    LINECNT
  918.     LXI    D,CRLF
  919.     CALL    LIST
  920.     LXI    D,CRLF
  921.     JMP    LIST
  922.  
  923. LIST    PUSH    H        ;THIS DIFFERS FROM OUTPUT
  924.     PUSH    B        ; IN THAT LIST GOES TO THE
  925.     PUSH    D        ;LIST DEVICE AND OUTPUT GOES
  926. LIST1    LDAX    D        ;TO THE CONSOLE DEVICE
  927.     CPI    '$'
  928.     JZ    LIST2
  929.     INX    D
  930.     PUSH    D
  931.     MOV    E,A
  932.     MVI    C,5
  933.     CALL    BDOS
  934.     POP    D
  935.     JMP    LIST1
  936. LIST2    POP    D
  937.     POP    B
  938.     POP    H
  939.     RET
  940.  
  941.  
  942. QUESTION    CALL    OUTPUT    ;PUT OUT THE QUESTION
  943.     LXI    D,INBUF
  944.     MVI    C,0AH        ;INPUT THE REPLY
  945.     CALL    BDOS
  946.     LDA    INCNT        ;SEE IF ANYTHING WAS ENTERED
  947.     RET
  948.  
  949. MOVE    PUSH    H        ;MOVE DATA POINTED TO IN HL
  950.     PUSH    D        ;TO THE AREA POINTED TO IN DE
  951.     PUSH    B        ;BY THE BYTE COUNT IN B
  952. MOVE1    MOV    A,M
  953.     ANI    7FH        ;RESET THE HIGH ORDER BIT BECAUSE IT
  954.                 ;MAY HAVE BEEN TURNED ON FOR THE TYPE
  955.     STAX    D
  956.     INX    H
  957.     INX    D
  958.     DCR    B
  959.     JNZ    MOVE1
  960.     POP    B        ;RESTORE THE TOTAL ENVIRONMENT
  961.     POP    D
  962.     POP    H
  963.     RET
  964.  
  965. COMPARE    PUSH    H        ;COMPARE THE STRINGS POINTED TO IN HL
  966.     PUSH    D        ;TO THE STRING POINTED TO IN DE
  967.     PUSH    B        ;FOR A LENGTH OF B CHARACTERS
  968. COMP1    LDAX    D        ; JC IF HL > DE
  969.     CMP    M        ; JZ IF HL = DE
  970.     JNZ    COMP2        ;JNC IF HL < DE
  971.     INX    H
  972.     INX    D
  973.     DCR    B
  974.     JNZ    COMP1
  975. COMP2    POP    B
  976.     POP    D
  977.     POP    H
  978.     RET
  979.  
  980.  
  981. ; THIS ROUTINE READS THE COMPUTIME CLOCK AND FORMATS THE TIME AND DATE
  982. GETDATE    EQU    $
  983.     MVI    A,16        ;RAISE THE HOLD SIGNAL
  984.     OUT    C2
  985.     MVI    A,50        ;DELAY AT LEAST 50 MILLISECONDS
  986. WAIT50 DCR    A
  987.     JNZ    WAIT50
  988.     LXI    H,DATETIME    ;SET MESSAGE START.  NOTE 1ST CHAR IS SPACE
  989.     MVI    A,42        ;GET MONTH TENS CHAR
  990.     CALL    GETTIME
  991.     MVI    A,41        ;GET MONTH UNITS CHAR
  992.     CALL    GETTIME
  993.     INX    H        ;SKIP SLASH
  994.     MVI    A,40        ;GET DAY TENS CHAR
  995.     CALL    GETTIME
  996.     ANI    0F3H        ;DROP LEAP YEAR INDICATOR
  997.     MOV    M,A
  998.     MVI    A,39        ;GET DAY UNITS CHAR
  999.     CALL    GETTIME        
  1000.     INX    H        ;SKIP SLASH
  1001.     MVI    A,44        ;GET YEAR TENS CHAR
  1002.     CALL    GETTIME
  1003.     MVI    A,43        ;GET YEAR UNITS CHAR
  1004.     CALL    GETTIME
  1005.     INX    H        ;SKIP BLANK
  1006.     MVI    A,37        ;GET HOUR TENS CHAR
  1007.     CALL    GETTIME
  1008.     ANI    0F3H        ;DROP AM/PM AND 24HR INDICATORS
  1009.     MOV    M,A
  1010.     MVI    A,36        ;GET HOUR UNITS CHAR
  1011.     CALL    GETTIME
  1012.     INX    H        ;SKIP COLON
  1013.     MVI    A,35        ;GET MINUTES TENS CHAR
  1014.     CALL    GETTIME
  1015.     MVI    A,34        ;GET MINUTES UNITS CHAR
  1016.     CALL    GETTIME
  1017.     INX    H        ;SKIP COLON
  1018.     MVI    A,33        ;GET SECONDS TENS CHAR
  1019.     CALL    GETTIME
  1020.     MVI    A,32        ;GET SECONDS UNITS CHAR
  1021.     CALL    GETTIME
  1022.     XRA    A
  1023.     OUT    C2        ;LOWER HOLD SIGNAL
  1024.     RET
  1025. C1    EQU    254        ;CLOCK ADDRESS PORT
  1026. C2    EQU    253        ;CLOCK DATA OUTPUT PORT
  1027. GETTIME    INX    H        ;ADVANCE TO NEXT PRINT POSITION
  1028.     OUT    C1
  1029.     MVI    A,6        ;DELAY AT LEAST 6 MILLISECONDS
  1030. WAIT6    DCR    A
  1031.     JNZ    WAIT6
  1032.     IN    C1
  1033.     ORI    30H        ;CONVERT TO ASCII
  1034.     MOV    M,A
  1035.     RET
  1036. DATETIME DB    ' 00/00/00 HH:MM:SS$'
  1037.  
  1038.  
  1039. SIGNON    DB    'HARD DISK CATALOG AND BACKUP '
  1040.     DB    '10/13/81A$'
  1041. DATEMSG    DB    'ENTER 8 CHAR DATE FOR REPORTS MM/DD/YY: $'
  1042. ERASE    DB    'ERASE FLOPPY DISK FIRST (Y/N)? $'
  1043. TABFULL    DB    'MEMORY FULL...REPORT NOT COMPLETE$'
  1044. BACKQUS    DB    'BEGIN BACKUP PROCEDURE (Y/N)? $'
  1045. SORTMSG    DB    'SORTING...$'
  1046. NFMSG    DB    'FILE NOT FOUND...ABORTING$'
  1047. DMNTMSG    DB    'DISMOUNT BACKUP DISK AND ENTER RETURN$'
  1048. MNTMSG    DB    'MOUNT DISKETTE FOR BACKUP AND ENTER '
  1049.     DB    '3 CHAR DISK ID OR "END": $'
  1050. ENDLIT    DB    'END'
  1051. VOLSER    DS    3
  1052. QUEST1    DB    'BACKUP ALL FILES OF TYPE '
  1053. QTYPE    DS    3
  1054.     DB    ', (Y/N/S)? $'
  1055. QUEST2    DB    'BACKUP FILE NAMED '
  1056. QDISK2    DS    1
  1057.     DB    ':'
  1058. QFILE2    DS    8
  1059.     DB    '.'
  1060. QTYPE2    DS    3
  1061.     DB    ', (Y/N/C)? $'
  1062. HEAD2    DB    0CH,'THE FOLLOWING FILES WILL BE COPIED TO DISKETTES$'
  1063. PRNTREC    DS    1
  1064.     DB    ':'
  1065. PRNFILE    DS    8
  1066.     DB    '.'
  1067. PRNTYPE    DS    3
  1068.     DB    '    $'
  1069. CRLFLFLF    DB    0DH,0AH,0AH,0AH,'$'
  1070. INDEX    DB    'THE FOLLOWING FILES ARE ON DISKETTE NO. '
  1071. IDISKNO    DS    3
  1072.     DB    ' AS OF '
  1073. IDATE    DS    8
  1074.     DB    '$'
  1075. CRLF    DB    0DH,0AH,'$'
  1076. HEAD1    DB    0CH,'CONSOLIDATED INDEX BY FILE TYPE AS OF $'
  1077. DATE    DS    8
  1078.     DB    '   $'
  1079. BIGMSG    DB    0DH,0AH,'FILE TOO LARGE TO FIT ON ONE DISKETTE '
  1080.     DB    'SO NOT BACKED UP **** $'
  1081. HDFCB    DS    1
  1082. HDFILE    DS    8
  1083. HDTYPE    DS    3
  1084.     DS    24
  1085. FPFCB    DS    36
  1086. TOP    DB    0CH,'$'
  1087. INBUF    DB    30
  1088. INCNT    DS    1
  1089. INREC    DS    30
  1090. STACK    DS    80
  1091. EOF    DS    1
  1092. ABORT    DS    1
  1093. LINECNT    DS    1
  1094. LASTTYPE DS     3
  1095. LASTFILE DS    8
  1096. TABADDR    DS    2
  1097. TABCNT    DS    2
  1098. SELFLAG    DS    1
  1099. TOOBIG    DS    1
  1100. ADDR1    DS    2
  1101. ADDR2    DS    2
  1102. ADDR3    DS    2
  1103. MAX1    DS    2
  1104. MAX2    DS    2
  1105. RTYPE    DS    3
  1106. RFILE    DS    8
  1107. RDISK    DS    3
  1108.     DB    '$'
  1109. TEMP    DS    RECSIZE
  1110. DISKBUF    DS    128
  1111. COMPSIZE DS    1
  1112. RAM    EQU    $
  1113. BDOS    EQU    05H
  1114.     END    100H
  1115.