home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / UTILS / HDUTL / NEWBACK.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  39KB  |  1,598 lines

  1. ; NEWBACK - DISK DIRECTORY AND BACKUP PROGRAM - 11/20/83
  2. ;
  3. ;            COPYRIGHT 1980, GARY YOUNG
  4. ;
  5. ; THE PRIMARY PURPOSE OF THIS PROGRAM IS TO BACKUP HARD DISKS ON TO
  6. ; MULTIPLE FLOPPIES.  FIRST, IT EXTRACTS THE DIRECTORIES FROM ALL OF
  7. ; THE HARD DISKS, SORTS BY TYPE AND FILE NAME, AND PRINTS A CONSOLIDATED
  8. ; DIRECTORY.  THEN IT DELETES DUPLICATE FILES FROM THE CONSOLIDATED
  9. ; DIRECTORY, DELETES UNWANTED TYPES (PRN, BAK, ETC), AND UNWANTED
  10. ; FILES TO CREATE A LIST OF FILES TO BACKUP.  THESE ARE COPIED TO
  11. ; MULTIPLE FLOPPIES AS NEEDED WHILE PRODUCING AN INDEX OF WHAT FILES
  12. ; ARE ON EACH DISKETTE.  RESTART CAPABILITY IS PROVIDED TO BEGIN THE
  13. ; BACKUP AT ANY FILE.
  14. ;                    - Gary Young
  15. ;
  16. ;=======================================================================
  17. ;
  18. ; 11/20/83  Reformatted for standard display.  Saved 14k source code by
  19. ;   v2.4    removing superfluous spaces in favor of tabs.
  20. ;                    - Irv Hoff
  21. ;
  22. ; 08/20/83  1 - Clock for Sierra Data Sciences SBC-100 BIOS
  23. ;   v2.3    2 - Option to have no Clock this allows more space in memory
  24. ;         for Directory entries
  25. ;        3 - Backup all CP/M 2.2 user areas
  26. ;        4 - Fixed bug that caused crashed system when nothing to
  27. ;         backup            - Alex Soya
  28. ;
  29. ; 07/01/83  Added features to mark files that have been backed up on the
  30. ;   v2.2    floppy bye eather setting the 'T3' byte of the FCB for Mo-
  31. ;        ular computers or setting the 'F4' byte for other computers.
  32. ;        This is done at assembly time by setting the MOLEC equate
  33. ;        for either.            - Ron Stevenson
  34. ;
  35. ; 06/23/83  Corrected problem in code for backing up to copying to drive
  36. ;   v2.1    'P'.  Original code stripped off too many bits which would
  37. ;        not allow program to see drive 'P' no matter what.  Cleaned
  38. ;        up some of the code.    - Ron Stevenson
  39. ;
  40. ; 06/13/83  Added code at begining for setting up the drive to backup
  41. ;   v2.0    from as well as to.  You are now prompted as to which drives
  42. ;        you want backup and then which drive to put the stuff on.
  43. ;                    - Ron Stevenson
  44. ;
  45. ;=======================================================================
  46. ;
  47.     ORG    100H
  48. ;
  49. ;
  50.     JMP    START
  51. ;
  52.     DB    'COPYRIGHT 1980, G. YOUNG, INC.'
  53. ;
  54. YES:    EQU    0FFH
  55. NO:    EQU    0
  56. ;
  57. MOLEC:    EQU    YES        ;yes for molecular, no for others
  58. CLOCK:    EQU    NO        ;yes if clock is installed.
  59. SIERRA: EQU    NO        ;yes if sierra data sc. sbc-100 board
  60. COMPUT: EQU    NO        ;yes if computime clock board
  61. USERS:    EQU    YES        ;yes if option to back up all user areas
  62. ;
  63. ;
  64. ;
  65. RECSIZ:    EQU    12        ;record size as follows
  66.                 ; type     = 3 bytes
  67.                 ; file     = 8 bytes
  68.                 ; diskid = 1 bytes
  69. NOSKIP:    EQU    6            ;number of files in skip list
  70. SKPTYP:    DB     'PRNHEXSYMBAK$$$TMP'     ;files to not back up
  71. IDSIZE:    EQU    1        ;id now means a:, b:, c:, etc
  72. LINSPG:    EQU    60        ;lines per page
  73. RECLIN:    EQU    4        ;entries per line
  74. ;....
  75. ;
  76. ;
  77. ;***********************************************************************
  78. ;
  79. ;
  80. START:    LXI    SP,STACK+80
  81.     LXI    H,RAM        ;set up table address
  82.     SHLD    TABADDR
  83.     LXI    H,0000H
  84.     SHLD    TABCNT
  85.     XRA    A        ;the table refers to the remaining area
  86.     STA    ABORT        ;..of ram to hold as many directory en-
  87.     STA    EOF        ;.. tries as possible
  88.     STA    GOTONE        ;flag shows no file found yet if zero
  89. ;
  90. START1: LXI    D,SIGNON    ;print signon message
  91.     CALL    OUTPUT
  92.     LXI    D,DRIVMSG    ;ask for the drive letters to backup
  93.     CALL    QUESTION
  94.     CPI    0        ;ck to see if anything was added
  95.     JZ    START1        ;if not start over
  96.     ADI    1
  97.     STA    MAX1
  98. ;
  99.      IF    USERS
  100.     STA    MAX3        ;used to restore max1 later
  101.      ENDIF            ;USERS
  102. ;
  103.     MOV    B,A        ;setup count for move
  104.     LXI    H,INREC     ;data to move
  105.     LXI    D,DRIVES    ;where to put the date
  106.     CALL    MOVE
  107.     XCHG
  108.     DCR    B        ;correct the count befor cking
  109. ;
  110. STRT:    MOV    A,M        ;get a drive char
  111.     CPI    'Q'             ;ck it for good char
  112.     JP    START1        ;no good if positive
  113.     INX    H        ;point to next
  114.     DCR    B        ;dec count
  115.     JNZ    STRT        ;loop
  116.     MVI    M,'$'           ;store end-of-string char at end
  117.     LXI    D,BKUPMSG    ;ask for the drive letter to store it to
  118.     CALL    QUESTION
  119.     CPI    1
  120.     JNZ    START1        ;if no input then exit program
  121.     LDA    INREC        ;get drive letter to store to
  122.     STA    BACKUPDRV
  123. ;
  124. START2: LXI    D,CORRMSG    ;verify all data is correct
  125.     CALL    OUTPUT
  126.     LXI    D,DRIVES    ;get drives to backup
  127.     CALL    OUT1        ;output drive letter chain
  128.     LXI    D,CORRMSG1
  129.     CALL    OUT1
  130.     LDA    BACKUPDRV    ;get drive to backup to back again
  131.     MOV    E,A
  132.     MVI    C,CONOUT
  133.     CALL    BDOS        ;output drive to backup to out
  134.     LXI    D,CORRY$N    ;get correct message
  135.     CALL    QUESTION    ;and get responce
  136.     CPI    1
  137.     JNZ    START2
  138.     LDA    INREC        ;get answer
  139.     CPI    'Y'
  140.     JNZ    START1
  141. ;
  142.      IF    USERS
  143.     LXI    D,USRMSG    ;ask if all users to back up
  144.     CALL    QUESTION
  145.     CPI    1
  146.     JNZ    START1        ;thats what you get for a wrong answer
  147.     LDA    INREC        ;get answer
  148.     CPI    'Y'             ;do all user areas
  149.     JNZ    NOUSRS        ;
  150.     MVI    A,0        ;set user 0 meaning do them all
  151.     JMP    DONUSR
  152. ;
  153. NOUSRS:    MVI    A,17        ;set user 17 meaning do only what we are
  154. ;
  155. DONUSR:    STA    CURUSER
  156.      ENDIF            ;USERS
  157. ;
  158.      IF    NOT CLOCK
  159. MSG1:    LXI    D,DATEMSG    ;get current date for reports
  160.     CALL    QUESTION    ;print msg and get reply
  161.     CPI    8        ;8 char must have been entered
  162.     JNZ    MSG1        ;repeat question if not
  163.     LXI    H,INREC     ;move date from inrec
  164.      ENDIF            ;NOT CLOCK
  165. ;
  166.      IF    CLOCK
  167.     CALL    GETDATE     ;get date from clock board
  168.     LXI    H,DATETIME+1
  169.      ENDIF            ;CLOCK
  170. ;
  171.     MVI    B,8        ;move the date to a hold area
  172.     LXI    D,DATE        ;to "date"
  173.     CALL    MOVE
  174. ;
  175.      IF    USERS
  176. REPEAT: LDA    CURUSER     ;get user number
  177.     CPI    16        ;check if we do them all
  178.     JNC    GOON        ;no users greater than 15
  179.     MOV    E,A        ;valid user so set it.
  180.     MVI    C,32        ;set user function
  181.     CALL    BDOS        ;tell cp/m to do some work !
  182.     LXI    D,USRNOMS    ;send user id message
  183.     CALL    OUTPUT
  184.     LDA    CURUSER
  185.     CALL    CONVRT
  186.     MOV    A,B        ;send id to console
  187.     STA    USERID
  188.     MOV    A,C
  189.     STA    USERID+1
  190.     LXI    D,USERID
  191.     CALL    OUT1
  192.      ENDIF            ;USERS
  193. ;
  194. GOON:    CALL    EXTRACT     ;get directory entries
  195.     LDA    ABORT        ;see if too many entries for memory size
  196.     ORA    A        ;should be zero to be ok
  197.     JZ    NOMORE
  198.     LXI    D,TABFULL    ;report will not be complete
  199.     CALL    OUTPUT        ;memory full error
  200. ;
  201. NOMORE: LDA    GOTONE        ;no file found fix
  202.     ORA    A
  203.     JNZ    ALLOK
  204.     LXI    D,NOFILS    ;no files message
  205.     CALL    OUTPUT
  206.     JMP    FINISHED    ;as nothing to do we are done
  207. ;
  208. ALLOK:    CALL    SORT        ;sort by type, file name and disk id
  209.     MVI    A,RECSIZ    ;setup to remove duplicate entries
  210.     STA    COMPSIZE    ;compare on all char
  211.     CALL    KILLDUPS    ;remove duplicate entries
  212.     CALL    REPORT        ;print all entries
  213.     MVI    A,11        ;remove files that are on multiple disks
  214.     STA    COMPSIZE
  215.     CALL    KILLDUPS
  216.     CALL    SELECT        ;restrict the files to backup
  217. ;
  218. MSG3:    LXI    D,BACKQUS    ;ask if you want backup function
  219.     CALL    QUESTION
  220.     CPI    1
  221.     JNZ    MSG3
  222.     LDA    INREC
  223.     CPI    'N'
  224.     JZ    FINISHED
  225.     CPI    'Y'
  226.     JNZ    MSG3
  227.     CALL    BACKUP        ;backup those files reported on
  228. ;
  229. FINISHED:
  230.     MVI    C,0
  231. ;
  232.      IF    USERS
  233.     LDA    CURUSER
  234.     INR    A
  235.     CPI    16        ;;get user and see if another one to do
  236.     JNC    DONE        ;all done so lets go
  237.     STA    CURUSER     ;else do next user
  238.     LDA    MAX3        ;restore drive pointer
  239.     STA    MAX1        ;so we do all drives in next user area.
  240.     LXI    H,RAM        ;restore all the required pointers
  241.     SHLD    TABADDR     ;and things.
  242.     LXI    H,0000H
  243.     SHLD    TABCNT
  244.     XRA    A
  245.     STA    ABORT
  246.     STA    EOF
  247.     STA    GOTONE
  248.     JMP    REPEAT        ;until done
  249.      ENDIF            ;USERS
  250. ;
  251. DONE:    JMP    BDOS        ;reset and return to cpm
  252. ;
  253. ; the extract routine scans all the drives in the drive table when com-
  254. ; plete, it asks for the next drive id when the hard disk is up, it will
  255. ; not ask for the drive id but will automatically scan the three hard
  256. ; disks and finish without ever asking for the drive id.
  257. ;
  258. ; the dummyfcb sets up a skeleton to read all files on the directory
  259. ;
  260. DUMMYFCB:
  261.     DB    0,'????????????',0,0,0,0,0,0,0,0,0
  262.     DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  263. ;
  264. EXTRACT:LXI    H,DRIVES    ;get address of the drive table
  265.     SHLD    ADDR1        ;to scan
  266. ;    MVI    A,NODRV+1    ;set up counter for the number to scan
  267. ;    STA    MAX1
  268. ;
  269. NEXTDRV:LDA    MAX1        ;see if there are more drives to scan
  270.     DCR    A
  271.     STA    MAX1        ;return when all have been scanned
  272.     RZ
  273.     LHLD    ADDR1        ;get address of drive table
  274.     MOV    A,M        ;get drive character
  275.     STA    RDISK
  276.     ANI    1FH        ;convert a=1...p=16
  277.     STA    DUMMYFCB    ;set in dr of dummyfcb
  278.     INX    H        ;set for next read of drive table
  279.     SHLD    ADDR1
  280.     LXI    D,DISKBUF    ;set a dma address for directory entries
  281.     MVI    C,1AH
  282.     CALL    BDOS        ;set dma
  283.     LXI    D,DUMMYFCB    ;get first directory entry
  284.     MVI    C,11H
  285.     CALL    BDOS        ;get directory
  286.     INR    A
  287.     JZ    NEXTDRV     ;no more entries on this drive
  288.     JMP    GETFCB        ;extract data from fcb
  289. ;
  290. NEXTFCB:LXI    D,DUMMYFCB    ;get next entry after the first
  291.     MVI    C,12H
  292.     CALL    BDOS
  293.     INR    A
  294.     JZ    NEXTDRV     ;no more directories on this disk
  295. ;
  296. GETFCB: LXI    D,32        ;each entry is 32 bytes long
  297.     LXI    H,DISKBUF    ;directory record is in diskbuf
  298.     CPI    1        ;first entry in record???
  299.     JZ    FORMREC     ;yes
  300.     DAD    D        ;add 32 to address in record
  301.     CPI    2        ;second entry in record???
  302.     JZ    FORMREC
  303.     DAD    D        ;add 64 to address of record
  304.     CPI    3        ;third entry in record???
  305.     JZ    FORMREC
  306.     DAD    D        ;add 96 to address of record
  307. ;
  308. FORMREC:INX    H        ;pass drive byte
  309.     LXI    D,RFILE     ;move file name
  310.     MVI    B,8        ;move 8 characters
  311.     CALL    MOVE
  312.     LXI    D,8        ;position past name to type
  313.     DAD    D
  314.     LXI    D,RTYPE     ;move type
  315.     MVI    B,3        ;move 3 characters
  316.     CALL    MOVE
  317. ;
  318.      IF    NOT MOLEC
  319.     PUSH    H        ;save it for a min
  320.     LXI    H,RFILE+4    ;get file name to ck for 'F4' taged
  321.     MOV    A,M
  322.     POP    H        ;get it back
  323.      ENDIF            ;NOT MOLEC
  324. ;
  325.     ANI    80H        ;ck to see if we should backup this file
  326.     JNZ    NEXTFCB     ;by checking 'T3' for molecular computers
  327.                 ;or 'F4' for other computers
  328.     INX    H        ;position to the extent number
  329.     INX    H
  330.     INX    H
  331.     MVI    A,0FFH
  332.     STA    GOTONE        ;set flag that we have at least on entry
  333.     MOV    A,M        ;get the extent
  334. ;    ORI    30H        ;diagnostic display
  335. ;    STA    RDISK+1
  336. ;    LXI    D,RTYPE
  337. ;    CALL    OUTPUT
  338. ;    LDA    RDISK+1
  339. ;    ANI    0FH
  340.     LXI    H,RTYPE     ;strip off the high bit set by
  341.     MVI    B,11        ;the version program
  342. ;
  343. STRIP:    MOV    A,M
  344.     ANI    07FH
  345.     MOV    M,A
  346.     INX    H
  347.     DCR    B
  348.     JNZ    STRIP
  349.     LXI    H,RTYPE     ;skip over junk disk entries
  350.     MVI    B,11        ;containing nonprinting characters
  351. ;
  352. NONPRNT:MOV    A,M
  353.     CPI    20H        ;any char less than a blank
  354.     JC    NEXTFCB     ;go to next one if so
  355.     INX    H
  356.     DCR    B
  357.     JNZ    NONPRNT
  358. ;
  359. FIRSTEXT:
  360.     LHLD    TABADDR     ;get memory table address
  361.     LXI    D,RTYPE     ;get memory record address
  362.     XCHG            ;rtype (hl) to tabaddr (de)
  363.     MVI    B,RECSIZ    ;move recsiz bytes
  364.     CALL    MOVE
  365.     LHLD    TABADDR     ;increment for next entry
  366.     LXI    D,RECSIZ    ;recsiz bytes in record
  367.     DAD    D
  368.     SHLD    TABADDR     ;save new address
  369.     MVI    M,1AH        ;set an end-of-table indicator
  370.     LHLD    TABCNT        ;get record count
  371.     INX    H
  372.     SHLD    TABCNT        ;increment record count
  373.     LHLD    TABADDR     ;see if new address is greater
  374.     XCHG            ;than the top of tpa-128
  375.     LHLD    BDOS+1        ;hl=top...de=table+recsiz
  376.     LXI    B,-128
  377.     DAD    B        ;subtract 128 from top
  378.     CALL    COMPREG     ;compare register values
  379.     JNC    NEXTFCB     ;there is room for more
  380.     MVI    A,1        ;no more room...abort now
  381.     STA    ABORT
  382.     RET
  383. ;.....
  384. ;
  385. ;
  386. ; the following routine is a bubble sort.  in pseudobasic this would be
  387. ; done as follows:  sort   addr1=bottom(ram)-recsiz (recsiz is count of
  388. ; bytes in one record)
  389. ;
  390. ;    MAX1=0
  391. ;LOOP1:    MAX1=MAX1+1
  392. ;    ADDR1=ADDR1+RECSIZ     (first time this would be the bottom)
  393. ;    IF MAX1>TABCNT-1 THEN TO TO SORTED
  394. ;    ADDR2=ADDR1
  395. ;    MAS2=MAX1
  396. ;LLOP2:    MAX2=MAX2+1
  397. ;    ADDR2=ADDR2+RECSIZ
  398. ;    IF MAX2>TABCNT THEN GO TO LOOP1
  399. ;    IF TABLE(ADDR1)<TABLE(ADDR2)THEN GO TO LOOP2
  400. ;    TEMP=TABLE(ADDR1)
  401. ;    TABLE(ADDR1)=TABLE(ADDR2)
  402. ;    TABLE(ADDR2)=TEMP
  403. ;    GO TO LOOP2
  404. ;
  405. ;SORTED:RETURN
  406. ;
  407. ; now that this logic is intuitively obvious, here'S THE NOT SO OBVIOUS
  408. ; code:
  409. ;
  410. SORT:   LXI     D,SORTMSG       ;put out a message so the user does
  411.         CALL    OUTPUT          ;not think this crashed while sorting
  412.         LXI     H,0000          ;initialize count
  413.         SHLD    MAX1            ;since it will decrement first
  414.         LXI     D,-RECSIZ       ;subtract recsiz from the beginning
  415.         LXI     H,RAM           ;of the table since it will add
  416.         DAD     D               ;recsiz to it first
  417.         SHLD    ADDR1
  418. ;
  419. LOOP1:  LHLD    ADDR1           ;get the current address
  420.         LXI     D,RECSIZ        ;increment it by recsiz
  421.         DAD     D               ;past the next entry
  422.         SHLD    ADDR1
  423.         LHLD    MAX1            ;see if the count has reached the limit
  424.         INX     H               ;increment the counter
  425.         SHLD    MAX1
  426.         XCHG                    ;move to de to compare to limit
  427.         LHLD    TABCNT
  428.         DCX     H               ; is max1 > tabcnt - 1 ???
  429.         CALL    COMPREG         ;compare de (current count) to hl (tabcnt-1)
  430.         JC      SORTED          ;finished when max1 > tabcnt-1
  431.         LHLD    ADDR1           ;setup for the inner loop
  432.         SHLD    ADDR2
  433.         LHLD    MAX1
  434.         SHLD    MAX2
  435. ;
  436. LOOP2:  LHLD    ADDR2           ;start with one entry greater then
  437.         LXI     D,RECSIZ        ;the outer loop and increment
  438.         DAD     D               ;by recsiz each time past the next record
  439.         SHLD    ADDR2           ;pointer to the current record
  440.         LHLD    MAX2            ;likewise see if the counter for the
  441.         INX     H
  442.         SHLD    MAX2
  443.         XCHG
  444.         LHLD    TABCNT
  445.         CALL    COMPREG
  446.         JC      LOOP1           ;when finished, increment outer loop
  447.         LHLD    ADDR2
  448.         XCHG                    ;addr2 now in de
  449.         LHLD    ADDR1
  450.         CALL    COMPARE         ;compare strings pointed to by de/hl
  451.         JNC     LOOP2           ;table(hl) < table (de)
  452. ;
  453. ;
  454. ; exchange the two entries via a temporary record
  455. ;
  456.         LXI     D,TEMP
  457.         LHLD    ADDR1
  458.         MVI     B,RECSIZ
  459.         CALL    MOVE            ;temp=table(addr1)
  460.         XCHG                    ;addr1=destination
  461.         LHLD    ADDR2           ;addr2=source
  462.         CALL    MOVE            ;table(addr1)=table(addr2)
  463.         XCHG                    ;addr2 = destination
  464.         LXI     H,TEMP
  465.         CALL    MOVE            ;table(addr2)=temp
  466.         JMP     LOOP2
  467. ;.....
  468. ;
  469. ;
  470. SORTED: RET                     ;finished sorting
  471. ;
  472. ;
  473. ; report prints the sorted consolidated directory entries.  linspg is
  474. ; the number of lines per page and reclin is the number of 20 byte en-
  475. ; tries per line.  each type begins on a new page.
  476. ;
  477. REPORT: LHLD    TABCNT          ;set count of entries
  478.         INX     H               ;plus one
  479.         SHLD    LASTTYPE        ;init lasttype to invalid data
  480.         SHLD    MAX1            ;to decrement first
  481.         LXI     H,RAM-RECSIZ    ;set starting address
  482.         SHLD    ADDR1
  483.         CALL    HEADING
  484. ;
  485. NEXTPRT:LHLD    ADDR1
  486.         LXI     D,RECSIZ        ;set to add the receive length
  487.         DAD     D
  488.         SHLD    ADDR1
  489.         LHLD    MAX1            ;decrement count to see when done
  490.         DCX     H
  491.         SHLD    MAX1
  492.         LXI     D,0000          ;see if reached zero yet
  493.         CALL    COMPREG
  494.         JZ      TOPPAGE         ;go to top of next page
  495.         LHLD    ADDR1           ;current type = last type?
  496.         MVI     B,3             ;compare 3 characters
  497.         LXI     D,LASTTYPE
  498.         CALL    COMPARE
  499.         JNZ     SKIP3           ;new type on new page
  500. ;
  501. PRNTNOW:LDA     MAX2            ;decrement records per line
  502.         DCR     A
  503.         STA     MAX2
  504.         JZ      NEWLINE         ;line full, go to new line
  505.         CALL    FORMAT
  506.         LXI     D,PRNTREC
  507.         CALL    LIST
  508.         JMP     NEXTPRT
  509. ;
  510. SKIP3:  LDA     LINECNT
  511.         DCR     A
  512.         JZ      NEWPAGE
  513.         DCR     A
  514.         JZ      NEWPAGE
  515.         DCR     A
  516.         JZ      NEWPAGE
  517.         STA     LINECNT
  518.         LXI     D,CRLFLFLF
  519.         CALL    LIST
  520.         JMP     CHKTYPE
  521. ;
  522. NEWPAGE:CALL    HEADING
  523. ;
  524. CHKTYPE:LXI     D,LASTTYPE      ;set last type to current type
  525.         LHLD    ADDR1
  526.         MVI     B,3
  527.         CALL    MOVE
  528. ;
  529. SETCNT: MVI     A,RECLIN+1
  530.         STA     MAX2
  531.         JMP     PRNTNOW
  532. ;
  533. NEWLINE:LXI     D,CRLF
  534.         CALL    LIST
  535.         LDA     LINECNT
  536.         DCR     A
  537.         STA     LINECNT
  538.         JZ      NEWPAGE         ;page full
  539.         JMP     SETCNT
  540. ;
  541. TOPPAGE:RET
  542. ;.....
  543. ;
  544. ;
  545. ; the purpose of select is to create a final list of files to backup.
  546. ; since backing up 26 meg can be quite long, this reduces the list to
  547. ; only neccessary files.  it also allows a restart at any file.  it will
  548. ; delete duplicate file names (files on a: will be used since that is
  549. ; assumed to be the latest), and will delete the file types listed in
  550. ; the skip table.  then it will list each type and ask if you do want to
  551. ; back up all of this type (y), skip backing up of the entire type (n),
  552. ; or select certain files (s) to back up.  if the select option is
  553. ; chosen, each file name will be printed and you be asked to back up the
  554. ; file (y), ignore the file during the backup (n), or continue (c) to
  555. ; backup all of the remaining files within this type without asking any
  556. ; further names (used for restart).  after the list has been reduced, it
  557. ; will be listed before the backup actually begins.
  558. ;
  559. KILLDUPS:
  560.         LXI     H,RAM
  561.         SHLD    ADDR1           ;set the start of the table
  562. ;
  563. NEXTEQUAL:
  564.     LHLD    ADDR1           ;check each entry against the next
  565.         LXI     D,RECSIZ
  566.         DAD     D
  567.         SHLD    ADDR2
  568. ;
  569. NEXTCHK:
  570.     MOV     A,M             ;check for end of table
  571.         CPI     1AH
  572.         RZ
  573.         XCHG
  574.         LHLD    ADDR1           ;compare addr1 with addr2
  575.         LDA     COMPSIZE
  576.         MOV     B,A
  577.         CALL    COMPARE
  578.         JNZ     SAVELAST
  579.         PUSH    H               ;save current position
  580.         LHLD    ADDR2           ;set up for moving list
  581.         SHLD    ADDR1           ;down one entry
  582.         LXI     D,RECSIZ
  583.         DAD     D               ;move third entry to the second
  584.         SHLD    ADDR2        
  585.         CALL    MOVELIST
  586.         LHLD    TABCNT
  587.         DCX     H
  588.         SHLD    TABCNT
  589.         POP     H               ;restore current position
  590.         SHLD    ADDR1           ;now compare 1st & 3rd
  591.         JMP     NEXTEQUAL
  592. ;
  593. SAVELAST:
  594.         LHLD    ADDR2           ;make new one the current one
  595.         SHLD    ADDR1
  596.         JMP     NEXTEQUAL       ;compare
  597.  
  598. SELECT: EQU     $
  599. ;
  600. NOWSELECT:
  601.         LXI     H,RAM-RECSIZ    ;initialize
  602.         SHLD    ADDR1
  603.         SHLD    LASTTYPE        ;make sure lasttype does not match
  604. ;
  605. NEXTENTRY:
  606.     LHLD    ADDR1           ;get next record in table
  607.         LXI     D,RECSIZ
  608.         DAD     D
  609.         SHLD    ADDR1           ;increment table entry
  610. ;
  611. CHKNEXT:
  612.     MOV     A,M             ;check for the end of the table
  613.         CPI     1AH             ;cntl-z is at end
  614.         JZ      LISTBKUP        ;list the final table
  615.         LXI     D,LASTTYPE      ;see if the current type is the
  616.         LHLD    ADDR1           ;last type
  617.         MVI     B,3
  618.         CALL    COMPARE
  619.         JZ      CHKSELECT       ;types match, check file select
  620.         CALL    MOVE            ;types don'T MATCH, MAKE THE
  621.                 ;last type = current type now
  622.     MVI    C,NOSKIP+1    ;see if the new type is in the
  623.     LXI    D,SKPTYP    ;list of file types to skip
  624.     MVI    B,3
  625. ;
  626. NEXTSKIP:
  627.     DCR    C        ;decrement no of files to skip
  628.     JZ    FORMQUS     ;file is good
  629.     LHLD    ADDR1
  630.     CALL    COMPARE
  631.     JZ    SKIPALLTYPE    ;file was on the skip list
  632.     INX    D        ;increment to next skip file
  633.     INX    D
  634.     INX    D
  635.     JMP    NEXTSKIP
  636. ;
  637. FORMQUS:
  638.     LXI    D,QTYPE     ;form the question about whether
  639.     LHLD    ADDR1        ;to skip this file type or not
  640.     MVI    B,3        ;move the file type to the
  641.     CALL    MOVE        ;question print line
  642.     XRA    A
  643.     STA    SELFLAG     ;reset the select flag
  644. ;
  645. REASK1: LXI    D,QUEST1
  646.     CALL    QUESTION    ;ask the question about the type
  647.     CPI    1        ;one character response allowed
  648.     JNZ    REASK1
  649.     LDA    INREC        ;get the response
  650.     CPI    'N'
  651.     JZ    SKIPALLTYPE
  652.     CPI    'Y'
  653.     JZ    SAVEALLTYPE
  654.     CPI    'S'             ;s=select certain files from this
  655.     JNZ    REASK1        ;type
  656.     MVI    A,1        ;set the select flag
  657.     STA    SELFLAG     ;to ask the next question
  658. ;
  659. ASKFILE:LHLD    ADDR1        ;format a question to ask if this
  660.     LXI    D,QTYPE2    ;particular file is to be saved
  661.     MVI    B,3
  662.     CALL    MOVE
  663.     LXI    D,QFILE2    ;move the file name to the question
  664.     INX    H
  665.     INX    H        ;position past the file type
  666.     INX    H        ;in the table
  667.     MVI    B,8
  668.     CALL    MOVE        ;move the name
  669.     LXI    D,8        ;position past name to the
  670.     DAD    D        ;disk id
  671.     LXI    D,QDISK2    ;move the disk id
  672.     MVI    B,IDSIZE
  673.     CALL    MOVE
  674. ;
  675. REASK2: LXI    D,QUEST2    ;ask the file question
  676.     CALL    QUESTION
  677.     CPI    1        ;only a 1 char response allowed
  678.     LDA    INREC
  679.     JNZ    REASK2
  680.     CPI    'C'             ;continue with the rest of the
  681.     JZ    SAVEALLTYPE    ;files within this type - restart
  682.     CPI    'Y'             ;save this particular file
  683.     JZ    NEXTENTRY
  684.     CPI    'N'
  685.     JNZ    REASK2
  686.     LHLD    ADDR1        ;shorten the list by one entry
  687.     LXI    D,RECSIZ
  688.     DAD    D
  689.     SHLD    ADDR2        ;skip the last one
  690.     CALL    MOVELIST    ;moves the list down from addr1
  691.                 ;to addr2
  692.     LHLD    ADDR1
  693.     JMP    CHKNEXT     ;check next entry
  694. ;
  695. CHKSELECT:
  696.     LDA    SELFLAG     ;check the select flag
  697.     ORA    A        ;if not zero, ask the question
  698.     JNZ    ASKFILE     ;about each file
  699.     JMP    NEXTENTRY
  700. ;
  701. SKIPALLTYPE:
  702.     CALL    FINDTYPE    ;find the next type not matching
  703.     CALL    MOVELIST    ;this one and move the list down
  704.     LHLD    ADDR1
  705.     JMP    CHKNEXT     ;to skip this type
  706. ;
  707. SAVEALLTYPE:
  708.     CALL    FINDTYPE    ;save all of this type
  709.     LHLD    ADDR2        ;reset the address to the next
  710.     SHLD    ADDR1        ;type
  711.     JMP    CHKNEXT
  712. ;
  713. MOVELIST:
  714.     LHLD    ADDR2        ;move the table from addr2 down
  715.     XCHG            ;to addr1 thereby eliminating
  716.     LHLD    ADDR1        ;unwanted entries
  717. ;
  718. MOVENEXT:
  719.     LDAX    D        ;and making more room for the
  720.     MOV    M,A
  721.     CPI    1AH
  722.     RZ
  723. ;
  724.     INX    H
  725.     INX    D
  726.     JMP    MOVENEXT
  727. ;
  728. FINDTYPE:
  729.     LHLD    ADDR1        ;find the next entry
  730.     SHLD    ADDR2        ;with a type different
  731. ;
  732. FINDIT: LHLD    ADDR2        ;than the current type
  733.     LXI    D,RECSIZ
  734.     DAD    D
  735.     SHLD    ADDR2
  736.     MOV    A,M        ;stop at end of the table
  737.     CPI    1AH
  738.     RZ
  739.     XCHG
  740.     LHLD    ADDR1
  741.     MVI    B,3
  742.     CALL    COMPARE
  743.     RNZ
  744.     JMP    FINDIT        ;addr2 will have the address of
  745.                 ;the next type when finished
  746. LISTBKUP:
  747.     SHLD    ADDR2        ;save the end of the table for later
  748.     LXI    H,RAM-RECSIZ
  749.     SHLD    ADDR1
  750.     CALL    HEADING2
  751. NEXTONE:
  752.     LHLD    ADDR1        ;print the next table entry
  753.     LXI    D,RECSIZ
  754.     DAD    D
  755.     SHLD    ADDR1        ;increment to the next entry
  756.     MOV    A,M        ;check for the end of the
  757.     CPI    1AH        ;table
  758.     RZ
  759.     CALL    FORMAT        ;format entry
  760.     LXI    D,PRNTREC
  761.     CALL    LIST        ;print it
  762.     LDA    MAX2        ;see if more will fit on this line
  763.     DCR    A
  764.     STA    MAX2
  765.     JZ    LINEFULL
  766.     JMP    NEXTONE
  767. ;
  768. LINEFULL:
  769.     LXI    D,CRLF
  770.     CALL    LIST
  771.     LDA    LINECNT
  772.     DCR    A
  773.     STA    LINECNT
  774.     JZ    PAGEFULL
  775.     JMP    SETLINE
  776. ;
  777. PAGEFULL:
  778.     CALL    HEADING2
  779.     MVI    A,LINSPG
  780.     STA    LINECNT
  781. ;
  782. SETLINE:
  783.     MVI    A,RECLIN
  784.     STA    MAX2
  785.     JMP    NEXTONE
  786. ;
  787. HEADING2:
  788.     LXI    D,HEAD2
  789.     CALL    LIST
  790.     LXI    D,CRLF
  791.     CALL    LIST
  792.     MVI    A,LINSPG
  793.     STA    LINECNT
  794.     MVI    A,RECLIN
  795.     STA    MAX2
  796.     RET
  797. ;.....
  798. ;
  799. ;
  800. ; backup is used to backup the files in the created list.  it will not
  801. ; back up any file that will not fit on one disk entirely.  the files
  802. ; that it backs up will come from any of the hard disks, but not necces-
  803. ; sarily in disk order, but rather alphabetical file name order.  it
  804. ; will prompt for the floppy disk id and print a report showing the
  805. ; floppy id and the files copied for index.  ; if the file will not fit
  806. ; on a disk, it will be deleted from the disk, that disk closed and re-
  807. ; moved, and prompted for a new disk to receive the file.  blank 1024
  808. ; byte sectored disks should be used for best performance.  when one
  809. ; diskette is full, it will prompt for a new one so many diskettes can
  810. ; be used to backup the hard disks.  if it is necessary to abort during
  811. ; this process, use the restart capability provided in 'SELECT'.  the
  812. ; area for the disk buffer is all of ram from the end of the table to
  813. ; the start of 'BDOS'.
  814. ;
  815. BACKUP: CALL    TOPOFFORM
  816.     LHLD    ADDR2        ;get the current end of table
  817.     INX    H        ;plus one for the start of the
  818.     SHLD    ADDR3        ;read/write buffer
  819.     LXI    H,RAM        ;set the address of the first entry
  820.     SHLD    ADDR1
  821.     LXI    D,RECSIZ    ;set an address for the second entry
  822.     DAD    D        ;next entry = current + recsiz
  823.     SHLD    ADDR2        ;later, use movelist to move the list
  824.                 ;down from addr2 to addr1 after each file
  825.                 ;has been copied.  this is so that the
  826.                 ;ram buffer will expand as the files are
  827.                 ;copied so that copying will be faster.
  828.      IF    USERS
  829.     LDA    CURUSER     ;we only mount if the user is 0 or
  830.     CPI    17        ;if no user option asked for
  831.     JZ    OKMOUNT
  832.     CPI    1        ;if we do not do users
  833.     JNC    NOMNT
  834.      ENDIF            ;USERS
  835. ;
  836. OKMOUNT:CALL    MOUNT
  837. ;
  838. NOMNT:    JMP    PASSMOVE
  839. ;
  840. NEXTFILE:
  841.     CALL    MOVELIST
  842.     INX    H        ;new start of read/write buffer
  843.     SHLD    ADDR3
  844.     XRA    A        ;reset the flag for files too big
  845.     STA    TOOBIG        ;to fit on one floppy
  846. ;
  847. PASSMOVE;
  848.     LXI    H,RAM        ;the table shrinks so the current
  849.                 ;entry is always at "ram" but the
  850.                 ;read/write buffer grows
  851.     MOV    A,M
  852.     CPI    1AH
  853.     JZ    DISMOUNT    ;finished
  854. ;
  855. FORMFCB:
  856.     LXI    D,HDFCB     ;clear the fcb
  857.     MVI    B,36
  858.     XRA    A
  859. ;
  860. ZEROFCB:
  861.     STAX    D
  862.     INX    D
  863.     DCR    B
  864.     JNZ    ZEROFCB
  865.     LXI    H,RAM        ;get address of table entry
  866.     LXI    D,HDTYPE    ;move in the type
  867.     MVI    B,3
  868.     CALL    MOVE
  869.     INX    H
  870.     INX    H        ;position to name
  871.     INX    H
  872.     LXI    D,HDFILE    ;move the file name
  873.     MVI    B,8
  874.     CALL    MOVE
  875.     LXI    D,8
  876.     DAD    D        ;position to disk id, a:, b: etc
  877.     MOV    A,M
  878.     ANI    1FH        ;convert a=1...p=16
  879.     STA    HDFCB
  880.     LXI    D,FPFCB     ;copy the hdfcb to the floppy fcb
  881.     LXI    H,HDFCB
  882.     MVI    B,36
  883.     CALL    MOVE
  884.     LDA    BACKUPDRV    ;set the receiving floppy drive number
  885.     ANI    1FH        ;convert floppy drive to number
  886.     STA    FPFCB
  887.     LXI    D,HDFCB     ;open the hd file
  888.     MVI    C,0FH
  889.     CALL    BDOS        ;open the input file
  890.     INR    A
  891.     JZ    NOTFOUND
  892.     LXI    D,FPFCB     ;delete the file on floppy if it
  893.     MVI    C,13H        ;exists
  894.     CALL    BDOS
  895.     LXI    D,FPFCB     ;create the file on floppy
  896.     MVI    C,16H
  897.     CALL    BDOS        ;make file
  898.     INR    A
  899.     JZ    DISKFULL
  900.     LXI    H,RAM
  901.     CALL    FORMAT
  902.     LXI    D,PRNTREC
  903.     CALL    OUTPUT
  904. ;
  905. COPYLOOP:
  906.     CALL    LOADBUFF    ;load memory with file
  907.     CALL    WRITEBUF        ;write memory file
  908.     LDA    EOF            ;display the status
  909.     ADI    30H
  910.     MOV    E,A            ;console output
  911.     MVI    C,2
  912.     CALL    BDOS
  913.     LDA    EOF
  914.     CPI    1
  915.     JZ    ENDOFFILE
  916.     CPI    2
  917.     JZ    DISKFULL
  918.     JMP    COPYLOOP
  919. ;
  920. ENDOFFILE:
  921.     LXI    D,FPFCB     ;close floppy file
  922.     MVI    C,10H
  923.     CALL    BDOS        ;close
  924. ;
  925.      IF     MOLEC
  926.     LXI    H,HDFCB+11    ;tag 'T3' byte to indicate backuped
  927.      ENDIF            ;MOLEC
  928. ;
  929.      IF    NOT MOLEC
  930.     LXI    H,HDFCB+4    ;tag 'F4' byte to indicate backuped
  931.      ENDIF            ;NOT MOLEC
  932.  
  933.     MOV    A,M        ;get 'T3' byte for taging on molecular
  934.                 ;or 'F4' byte for other computers
  935.     ORI    80H        ;set the bit
  936.     MOV    M,A        ;put it back in hdfcb
  937.     LXI    D,HDFCB     ;setup for attribute setting
  938.     MVI    C,1EH
  939.     CALL    BDOS        ;write it on the disk
  940.     LXI    H,RAM
  941.     CALL    PRINTFILE    ;write file name on index list
  942.     JMP    NEXTFILE
  943. ;
  944. DISKFULL:
  945.     LXI    D,FPFCB
  946.     MVI    C,13H        ;delete file on floppy
  947.     CALL    BDOS
  948.     LDA    TOOBIG        ;is this the second floppy
  949.     ORA    A        ;it has tried to copy to?
  950.     JZ    FIRSTTRY    ;no, first floppy. retry
  951.     LXI    D,BIGMSG    ;yes, 2nd floppy. send message
  952.     CALL    LIST        ;warning that this file cannot
  953.     LXI    H,RAM
  954.     CALL    FORMAT        ;be backed up with this program
  955.     LXI    D,PRNTREC
  956.     CALL    LIST        ;print the file name also
  957.     CALL    MOUNT
  958.     JMP    NEXTFILE
  959. ;
  960. FIRSTTRY:
  961.     INR    A        ;set indicator that it has tried
  962.     STA    TOOBIG        ;once already to copy it
  963.     CALL    MOUNT        ;get new disk
  964.     JMP    FORMFCB
  965. ;
  966. NOTFOUND:
  967.     LXI    H,RAM
  968.     CALL    FORMAT
  969.     LXI    D,NFMSG
  970.     CALL    OUTPUT
  971.     LXI    D,PRNTREC
  972.     CALL    OUTPUT
  973.     RET
  974. ;.....
  975. ;
  976. ;
  977. DISMOUNT:
  978.     CALL   BELL
  979. ;
  980.      IF    USERS
  981.     LDA    CURUSER     ;only dismount if we are all done
  982.     CPI    15
  983.     JC     NODISMS
  984.      ENDIF            ;USERS
  985. ;
  986.     LXI    D,DMNTMSG    ;dismount floppy
  987.     CALL    QUESTION
  988.     CALL    TOPOFFORM
  989. ;
  990. NODISMS:RET
  991. ;.....
  992. ;
  993. ;
  994. ; assorted routines
  995. ;
  996. PRINTFILE:
  997.     CALL    FORMAT
  998.     LXI    D,PRNTREC    ;print the file entry
  999.     CALL    LIST
  1000.     LDA    MAX2
  1001.     DCR    A
  1002.     STA    MAX2        ;entries per line counter
  1003.     RNZ
  1004.     LXI    D,CRLF        ;go to new line
  1005.     CALL    LIST
  1006.     MVI    A,RECLIN
  1007.     STA    MAX2
  1008.     RET
  1009. ;.....
  1010. ;
  1011. ;
  1012. HEADING3:
  1013.     LXI    D,CRLFLFLF    ;index heading not at top of form
  1014.     CALL    LIST
  1015.     LXI    D,IDISKNO    ;move the disk id no to heading
  1016.     LXI    H,VOLSER
  1017.     MVI    B,3
  1018.     CALL    MOVE
  1019.     LXI    D,IDATE
  1020.     LXI    H,DATE
  1021.     MVI    B,8
  1022.     CALL    MOVE
  1023.     LXI    D,INDEX
  1024.     CALL    LIST
  1025.     LXI    D,CRLF
  1026.     CALL    LIST
  1027.     MVI    A,RECLIN
  1028.     STA    MAX2
  1029.     MVI    A,LINSPG
  1030.     STA    LINECNT
  1031.     RET
  1032. ;.....
  1033. ;
  1034. ;
  1035. TOPOFFORM:
  1036.     MVI    E,0CH        ;position printer to top of form
  1037.     MVI    C,5
  1038.     JMP    BDOS
  1039. ;.....
  1040. ;
  1041. ;
  1042. MOUNT:    CALL    BELL
  1043.     LXI    D,MNTMSG
  1044.     CALL    QUESTION
  1045.     CPI    3
  1046.     JNZ    MOUNT
  1047.     LXI    H,INREC
  1048.     LXI    D,ENDLIT
  1049.     MVI    B,3
  1050.     CALL    COMPARE
  1051.     JZ    FINISHED
  1052.     LXI    D,VOLSER
  1053.     LXI    H,INREC
  1054.     MVI    B,3
  1055.     CALL    MOVE        ;move volser id to volser
  1056.     MVI    C,0DH        ;do a system reset to  change disks
  1057.     CALL    BDOS
  1058. ;
  1059. ERA:    LXI    D,ERASE
  1060.     CALL    QUESTION
  1061.     CPI    1
  1062.     JNZ    ERA
  1063.     LDA    INREC
  1064.     CPI    'N'
  1065.     JZ    NOERA
  1066.     CPI    'Y'
  1067.     JNZ    ERA
  1068.     LDA    BACKUPDRV
  1069.     ANI    1FH
  1070.     STA    DUMMYFCB
  1071.     MVI    C,13H
  1072.     LXI    D,DUMMYFCB
  1073.     CALL    BDOS        ;delete all files on floppy
  1074. ;
  1075. NOERA:    CALL    HEADING3
  1076.     LXI    D,FPFCB     ;clear the fcb to create a file name
  1077.     MVI    B,36
  1078.     XRA    A
  1079. ;
  1080. CLRFCB: STAX    D
  1081.     INX    D
  1082.     DCR    B
  1083.     JNZ    CLRFCB
  1084.     LDA    BACKUPDRV    ;set up the drive as the backup
  1085.     ANI    1FH        ;convert floppy drive to number
  1086.     STA    FPFCB
  1087.     LXI    H,DATE        ;create a null file with the date as
  1088.     LXI    D,FPFCB+1    ;the file name and the 3 digit
  1089.     MVI    B,8
  1090.     CALL    MOVE
  1091.     LXI    H,VOLSER    ;3 digit volser as the file type
  1092.     LXI    D,FPFCB+9
  1093.     MVI    B,3        ;this file will be used to identify
  1094.     CALL    MOVE        ; the disk and mark the date
  1095.     LXI    D,FPFCB
  1096.     MVI    C,16H        ;create the file
  1097.     CALL    BDOS
  1098.     INR    A
  1099.     JZ    MOUNT        ;disk full?
  1100.     LXI    D,FPFCB
  1101.     MVI    C,10H        ;close the file
  1102.     CALL    BDOS
  1103.     RET
  1104. ;.....
  1105. ;
  1106. ;
  1107. LOADBUFF:
  1108.     LXI    H,0000        ;memory with the file as possible
  1109.     SHLD    MAX1
  1110.     LHLD    ADDR3        ;new top of table +2
  1111.     SHLD    TEMP
  1112.     XRA    A
  1113.     STA    EOF        ;clear eof flag
  1114. ;
  1115. LOADNEXT:
  1116.     LHLD    TEMP
  1117.     XCHG            ;set dma address
  1118.     MVI    C,1AH
  1119.     CALL    BDOS
  1120.     LXI    D,HDFCB     ;read hard disk
  1121.     MVI    C,14H
  1122.     CALL    BDOS
  1123.     ORA    A
  1124.     JNZ    HDEOF        ;eof?
  1125.     LHLD    MAX1
  1126.     INX    H        ;increment record count
  1127.     SHLD    MAX1
  1128.     LHLD    TEMP        ;see if next record would exceed the
  1129.     LXI    D,128        ;tpa area
  1130.     DAD    D
  1131.     SHLD    TEMP
  1132.     DAD    D        ;will the next record overwrite bdos?
  1133.     XCHG
  1134.     LHLD    BDOS+1        ;find the top of memory
  1135.     CALL    COMPREG     ;compare registers
  1136.     RC            ;return if memory already full
  1137.     JMP    LOADNEXT    ;get another record
  1138. ;
  1139. HDEOF:    MVI    A,1        ;set file eof
  1140.     STA    EOF
  1141.     RET
  1142. ;.....
  1143. ;
  1144. ;
  1145. BELL:    MVI    C,9
  1146.     LXI    D,MSG
  1147.     CALL    BDOS
  1148. ;
  1149. BEEP:    MVI    C,5        ;bell on printer
  1150.     MVI    E,07H
  1151.     CALL    BDOS
  1152.     MVI    C,2        ;07h on crt
  1153.     MVI    E,07H
  1154.     CALL    BDOS
  1155.     MVI    C,0BH
  1156.     CALL    BDOS        ;get console status
  1157.     ORA    A
  1158.     JZ    BEEP
  1159.     MVI    C,01
  1160.     CALL    BDOS        ;get the dummy char
  1161.     RET
  1162. ;.....
  1163. ;
  1164. ;
  1165. MSG:    DB    0DH,0AH,0AH,'PRESS ANY KEY TO CONTINUE'
  1166.     DB    0DH,0AH,0AH,'$'
  1167. ;
  1168. WRITEBUF:
  1169.     LHLD    ADDR3
  1170.     SHLD    TEMP
  1171.     LHLD    MAX1        ;allow for files that have no
  1172.     LXI    D,0000        ;records such as restart
  1173.     CALL    COMPREG
  1174.     RZ
  1175. ;
  1176. WRITENEXT:
  1177.     LHLD    TEMP
  1178.     XCHG            ;set dma address
  1179.     MVI    C,1AH
  1180.     CALL    BDOS
  1181.     LXI    D,FPFCB
  1182.     MVI    C,15H        ;write sequential
  1183.     CALL    BDOS
  1184.     ORA    A
  1185.     JNZ    FPFULL        ;floppy disk full
  1186.     LHLD    MAX1        ;decrease record count
  1187.     DCX    H
  1188.     SHLD    MAX1
  1189.     LXI    D,0000        ;check for no more to write
  1190.     CALL    COMPREG
  1191.     RZ
  1192.     LHLD    TEMP
  1193.     LXI    D,128        ;increment write address
  1194.     DAD    D
  1195.     SHLD    TEMP
  1196.     JMP    WRITENEXT
  1197. ;
  1198. FPFULL: MVI    A,2        ;full diskette
  1199.     STA    EOF
  1200.     RET
  1201. ;.....
  1202. ;
  1203. ;
  1204. FORMAT: LXI    D,PRNTYPE    ;format the entry from the table
  1205.     MVI    B,3        ;format to the print format
  1206.     CALL    MOVE        ;the table address is assummed to be
  1207.     LXI    D,3        ;in hl. first move the type
  1208.     DAD    D        ;now position to the file name
  1209.     LXI    D,PRNFILE    ;move the file name
  1210.     MVI    B,8
  1211.     CALL    MOVE
  1212.     LXI    D,8        ;position to the disk id
  1213.     DAD    D
  1214.     LXI    D,PRNTREC    ;move the disk id to the line
  1215.     MVI    B,IDSIZE
  1216.     CALL    MOVE
  1217.     RET
  1218. ;.....
  1219. ;
  1220. ;
  1221. COMPREG:
  1222.     MOV    A,H        ;compare hl to de
  1223.     CMP    D
  1224.     RNZ
  1225.     MOV    A,L
  1226.     CMP    E
  1227.     RET
  1228.  
  1229. OUTPUT: PUSH    D        ;put out a crlf
  1230.     LXI    D,CRLF
  1231.     MVI    C,09
  1232.     CALL    BDOS
  1233.     POP    D        ;now put out the message
  1234. ;
  1235. OUT1:    MVI    C,09
  1236.     JMP    BDOS
  1237. ;.....
  1238. ;
  1239. ;
  1240. HEADING:
  1241.     LXI    D,HEAD1
  1242.     CALL    LIST
  1243.     LXI    D,DATE
  1244.     CALL    LIST
  1245.     LXI    D,TABFULL
  1246.     LDA    ABORT
  1247.     ORA    A
  1248.     CNZ    LIST
  1249.     MVI    A,LINSPG
  1250.     STA    LINECNT
  1251.     LXI    D,CRLF
  1252.     CALL    LIST
  1253.     LXI    D,CRLF
  1254.     JMP    LIST
  1255. ;
  1256. LIST:    PUSH    H        ;this differs from output
  1257.     PUSH    B        ; in that list goes to the
  1258.     PUSH    D        ;list device and output goes
  1259. ;
  1260. LIST1:    LDAX    D        ;to the console device
  1261.     CPI    '$'
  1262.     JZ    LIST2
  1263.     INX    D
  1264.     PUSH    D
  1265.     MOV    E,A
  1266.     MVI    C,5
  1267.     CALL    BDOS
  1268.     POP    D
  1269.     JMP    LIST1
  1270. LIST2    POP    D
  1271.     POP    B
  1272.     POP    H
  1273.     RET
  1274. ;.....
  1275. ;
  1276. ;
  1277. QUESTION:
  1278.     CALL    OUTPUT        ;put out the question
  1279.     LXI    D,INBUF
  1280.     MVI    C,0AH        ;input the reply
  1281.     CALL    BDOS
  1282.     LDA    INCNT        ;see if anything was entered
  1283.     RET
  1284. ;.....
  1285. ;
  1286. ;
  1287. MOVE:    PUSH    H        ;move data pointed to in hl
  1288.     PUSH    D        ;to the area pointed to in de
  1289.     PUSH    B        ;by the byte count in b
  1290. ;
  1291. MOVE1:    MOV    A,M
  1292. ;    ani    7fh        ;reset the high order bit because it
  1293.                 ;may have been turned on for the type
  1294.     STAX    D
  1295.     INX    H
  1296.     INX    D
  1297.     DCR    B
  1298.     JNZ    MOVE1
  1299.     POP    B        ;restore the total environment
  1300.     POP    D
  1301.     POP    H
  1302.     RET
  1303. ;.....
  1304. ;
  1305. ;
  1306. COMPARE:
  1307.     PUSH    H        ;compare the strings pointed to in hl
  1308.     PUSH    D        ;to the string pointed to in de
  1309.     PUSH    B        ;for a length of b characters
  1310. ;
  1311. COMP1:    LDAX    D        ; jc if hl > de
  1312.     CMP    M        ; jz if hl = de
  1313.     JNZ    COMP2        ;jnc if hl < de
  1314.     INX    H
  1315.     INX    D
  1316.     DCR    B
  1317.     JNZ    COMP1
  1318. ;
  1319. COMP2:    POP    B
  1320.     POP    D
  1321.     POP    H
  1322.     RET
  1323. ;.....
  1324. ;
  1325. ;
  1326. ; this routine reads the computime clock and formats the time and date
  1327. ;
  1328.      IF    COMPUT AND CLOCK
  1329. GETDATE:
  1330.     MVI    A,16        ;raise the hold signal
  1331.     OUT    C2
  1332.     MVI    A,50        ;delay at least 50 milliseconds
  1333. ;
  1334. WAIT50: DCR     A
  1335.     JNZ    WAIT50
  1336.     LXI    H,DATETIME    ;set message start.  1st char is space
  1337.     MVI    A,42        ;get month tens char
  1338.     CALL    GETTIME
  1339.     MVI    A,41        ;get month units char
  1340.     CALL    GETTIME
  1341.     INX    H        ;skip slash
  1342.     MVI    A,40        ;get day tens char
  1343.     CALL    GETTIME
  1344.     ANI    0F3H        ;drop leap year indicator
  1345.     MOV    M,A
  1346.     MVI    A,39        ;get day units char
  1347.     CALL    GETTIME     
  1348.     INX    H        ;skip slash
  1349.     MVI    A,44        ;get year tens char
  1350.     CALL    GETTIME
  1351.     MVI    A,43        ;get year units char
  1352.     CALL    GETTIME
  1353.     INX    H        ;skip blank
  1354.     MVI    A,37        ;get hour tens char
  1355.     CALL    GETTIME
  1356.     ANI    0F3H        ;drop am/pm and 24hr indicators
  1357.     MOV    M,A
  1358.     MVI    A,36        ;get hour units char
  1359.     CALL    GETTIME
  1360.     INX    H        ;skip colon
  1361.     MVI    A,35        ;get minutes tens char
  1362.     CALL    GETTIME
  1363.     MVI    A,34        ;get minutes units char
  1364.     CALL    GETTIME
  1365.     INX    H        ;skip colon
  1366.     MVI    A,33        ;get seconds tens char
  1367.     CALL    GETTIME
  1368.     MVI    A,32        ;get seconds units char
  1369.     CALL    GETTIME
  1370.     XRA    A
  1371.     OUT    C2        ;lower hold signal
  1372.     RET
  1373. ;.....
  1374. ;
  1375. ;
  1376. C1:    EQU    254        ;clock address port
  1377. C2:    EQU    253        ;clock data output port
  1378. ;
  1379. GETTIME:
  1380.     INX    H        ;advance to next print position
  1381.     OUT    C1
  1382.     MVI    A,6        ;delay at least 6 milliseconds
  1383. ;
  1384. WAIT6:    DCR    A
  1385.     JNZ    WAIT6
  1386.     IN    C1
  1387.     ORI    30H        ;convert to ascii
  1388.     MOV    M,A
  1389.     RET
  1390.      ENDIF            ;COMPUT AND CLOCK
  1391. ;.....
  1392. ;
  1393. ;
  1394. ; this routine reads the time and day on the sierra data sciences bios
  1395. ; clock.  the julian date from the sirra bios is converted to real date.
  1396. ; (why use a julian date sierra ?  does not save any memory anyway ????)
  1397. ;
  1398.      IF    SIERRA AND CLOCK
  1399. DINM:    DB    31,28,31,30,31,30,31,31,30,31,30,31
  1400. MONTH:    DB    1
  1401. YEAR:    DB    0
  1402. TEMDAY: DW    0
  1403. ;
  1404. GETDATE:LDA    64        ;get year
  1405.     STA    YEAR
  1406.     CALL    CONVRT        ;make it decimal
  1407.     MOV    A,B
  1408.     STA    DATETIME+7
  1409.     MOV    A,C
  1410.     STA    DATETIME+8
  1411.     LDA    YEAR        ;we need to know if this a leap year
  1412.     SUI    80        ;will only work post 1980 !!!!
  1413. ;
  1414. LEAP:    SUI    4        ;you need to change this in year 2000
  1415.     JZ    AJUS        ;it is a leapyear
  1416.     JNC    LEAP        ;do it until we know
  1417.     JMP    STIM
  1418. ;
  1419. AJUS:    MVI    A,29
  1420.     STA    DINM+1        ;29 days in feb this year
  1421. ;
  1422. STIM:    LXI    B,DINM        ;point to days in month table
  1423.     LHLD    65        ;copy date local
  1424.     SHLD    TEMDAY
  1425. ;
  1426. SLOOP:    LDAX    B        ;get no of days in this month
  1427.     MOV    D,A
  1428.     LDA    TEMDAY
  1429.     SUB    D
  1430.     JNC    SIER1        ;we still have too many days
  1431.     STA    TEMDAY        ;keep low day here till later
  1432.     LDA    TEMDAY+1    ;get high day
  1433.     CPI    1        ;still set ?
  1434.     JNZ    GOTMON        ;no, we got the month
  1435.     XRA    A        ;high date done
  1436.     STA    TEMDAY+1
  1437.     JMP    NXMON
  1438. ;
  1439. SIER1:    STA    TEMDAY
  1440. ;
  1441. NXMON:    INX    B        ;next month
  1442.     LDA    MONTH
  1443.     INR    A
  1444.     STA    MONTH
  1445.     JMP    SLOOP
  1446. ;
  1447. GOTMON:    LDA    TEMDAY
  1448.     ADD    D        ;correct days
  1449.     CALL    CONVRT        ;we got the day so put in string
  1450.     MOV    A,B
  1451.     STA    DATETIME+4
  1452.     MOV    A,C
  1453.     STA    DATETIME+5
  1454.     LDA    MONTH
  1455.     CALL    CONVRT
  1456.     MOV    A,B
  1457.     STA    DATETIME+1
  1458.     MOV    A,C
  1459.     STA    DATETIME+2
  1460.     LDA    67        ;get the hour
  1461.     CALL    CONVRT
  1462.     MOV    A,B
  1463.     STA    DATETIME+10
  1464.     MOV    A,C
  1465.     STA    DATETIME+11
  1466.     LDA    68        ;minutes
  1467.     CALL    CONVRT
  1468.     MOV    A,B
  1469.     STA    DATETIME+13
  1470.     MOV    A,C
  1471.     STA    DATETIME+14    ;i know this code is not elegant
  1472.     LDA    69
  1473.     CALL    CONVRT
  1474.     MOV    A,B
  1475.     STA    DATETIME+16
  1476.     MOV    A,C
  1477.     STA    DATETIME+17    ;finaly
  1478.     RET
  1479.      ENDIF            ;SIERRA AND CLOCK
  1480. ;.....
  1481. ;
  1482. ;
  1483.      IF    SIERRA OR USERS
  1484. CONVRT: MVI    B,030H        ;convert binary to decimal routine
  1485.     MVI    C,030H        ;for nos from 0 to  99 b=tens,c=ones
  1486. ;
  1487. CON1:    SUI    10        ;a holds value to convert
  1488.     JC    CON2
  1489.     INR    B
  1490.     JMP    CON1
  1491. ;
  1492. CON2:    ADI    10        ;correct it
  1493. ;
  1494. CON3:    SUI    1
  1495.     RC            ;we are done
  1496.     INR    C        ;do ones
  1497.     JP    CON3
  1498.      ENDIF            ;SIERRA OR USERS
  1499. ;
  1500. DATETIME: DB    ' 00/00/00 HH:MM:SS$'
  1501. DRIVES:   DB    'ABCDEFGHIJKLMNOP'      ;drive nos for the hard disks
  1502. BACKUPDRV:DS    1            ;backup floppy drive letter
  1503.  
  1504.  
  1505. SIGNON:      DB    1AH,'HARD DISK CATALOG AND BACKUP   v2.3 11/20/83$'
  1506. DRIVMSG:  DB    0AH,'Enter Letter of Drives to Backup from as '
  1507.       DB    '"ABCD..ect." $'
  1508. BKUPMSG:  DB    0AH,'Enter Letter of Floppy Drive to Backup to $'
  1509. CORRMSG:  DB    0AH,'Backing up Drives  $'
  1510. CORRMSG1: DB    '  to Floppy Drive  $'
  1511. CORRY$N:  DB    0AH,'is this Correct (Y/N)? $'
  1512. DATEMSG:  DB    0AH,'Enter 8 Char Date for Reports MM/DD/YY: $'
  1513. USRMSG:   DB    0AH,'Backup all user areas (Y/N)? $'
  1514. NOFILS:   DB    0AH,'NO files to backup here !! $'
  1515. USRNOMS:  DB    0AH,'Starting Backup procedure in user area : $'
  1516. USERID:   DB    '00$$$' 
  1517. ERASE:      DB    0AH,07H,'ERASE Floppy Disk First (Y/N)? $'
  1518. TABFULL:  DB    0AH,07H,'MEMORY FULL...REPORT NOT COMPLETE$'
  1519. BACKQUS:  DB    0AH,'Begin Backup Procedure (Y/N)? $'
  1520. SORTMSG:  DB    0AH,'SORTING...$'
  1521. NFMSG:      DB    0AH,07H,'FILE NOT FOUND...ABORTING$'
  1522. DMNTMSG:  DB    'DISMOUNT BACKUP DISK AND ENTER RETURN$'
  1523. MNTMSG:   DB    'MOUNT DISKETTE FOR BACKUP AND ENTER '
  1524.       DB    '3 CHAR DISK ID OR "END": $'
  1525. ENDLIT:   DB    'END'
  1526. VOLSER:   DS    3
  1527. QUEST1:   DB    'BACKUP ALL FILES OF TYPE '
  1528. QTYPE:      DS    3
  1529.       DB    ', (Y/N/S)? $'
  1530. QUEST2:   DB    'BACKUP FILE NAMED '
  1531. QDISK2:   DS    1
  1532.       DB    ':'
  1533. QFILE2:   DS    8
  1534.       DB    '.'
  1535. QTYPE2:   DS    3
  1536.       DB    ', (Y/N/C)? $'
  1537. HEAD2:      DB    0CH,'THE FOLLOWING FILES WILL BE COPIED TO DISKETTES$'
  1538. PRNTREC:  DS    1
  1539.       DB    ':'
  1540. PRNFILE:  DS    8
  1541.       DB    '.'
  1542. PRNTYPE:  DS    3
  1543.       DB    '    $'
  1544. CRLFLFLF: DB    0DH,0AH,0AH,0AH,'$'
  1545. INDEX:      DB    'THE FOLLOWING FILES ARE ON DISKETTE NO. '
  1546. IDISKNO:  DS    3
  1547.       DB    ' AS OF '
  1548. IDATE:      DS    8
  1549.       DB    '$'
  1550. CRLF:      DB    0DH,0AH,'$'
  1551. HEAD1:      DB    0CH,'CONSOLIDATED INDEX BY FILE TYPE AS OF $'
  1552. CURUSER:  DB    16    ;current user number (local)
  1553. DATE:      DS    8
  1554.       DB    '   $'
  1555. BIGMSG:   DB    0DH,0AH,'FILE TOO LARGE TO FIT ON ONE DISKETTE '
  1556.       DB    'SO NOT BACKED UP **** $'
  1557. HDFCB:      DS    1
  1558. HDFILE:   DS    8
  1559. HDTYPE:   DS    3
  1560.       DS    24
  1561. FPFCB:      DS    36
  1562. TOP:      DB    0CH,'$'
  1563. INBUF:      DB    30
  1564. INCNT:      DS    1
  1565. INREC:      DS    30
  1566. STACK:      DS    80
  1567. EOF:      DS    1
  1568. ABORT:      DS    1
  1569. GOTONE:   DS    1    ;flag to indicate valid file found, entry made
  1570. LINECNT:  DS    1
  1571. LASTTYPE: DS    3
  1572. LASTFILE: DS    8
  1573. TABADDR:  DS    2
  1574. TABCNT:   DS    2
  1575. SELFLAG:  DS    1
  1576. TOOBIG:   DS    1
  1577. ADDR1:      DS    2
  1578. ADDR2:      DS    2
  1579. ADDR3:      DS    2
  1580. MAX1:      DS    2
  1581. MAX2:      DS    2
  1582. MAX3:      DS    2    ;used to restore max1 between users
  1583. RTYPE:      DS    3
  1584. RFILE:      DS    8
  1585. RDISK:      DS    3
  1586.       DB    '$'
  1587. TEMP:      DS    RECSIZ
  1588. DISKBUF:  DS    128
  1589. COMPSIZE: DS    1
  1590. RAM:      EQU    $
  1591. BDOS:      EQU    05H
  1592. CONIN:      EQU    01H
  1593. CONOUT:   EQU    02H
  1594. ;.....
  1595. ;
  1596. ;
  1597.       END    100H
  1598.