home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol240 / backup.mac < prev    next >
Encoding:
Text File  |  1986-02-13  |  22.4 KB  |  1,388 lines

  1.     .z80
  2.     title    MML:BACKUP For large files extending over one floppy
  3.  
  4. ;-----------------------------------------------------------------------
  5. ; BACKUP
  6. ; Program to backup large files extending over one floppy
  7. ;
  8. ; Author:    D. Powys-Lybbe
  9. ; Written:    July 1984
  10. ;
  11. ; Procedure
  12. ; Load this program
  13. ; Respond as follows:
  14. ; > Source filename -------- ? <filename>
  15. ; > Destination disk ------- ? <diskname>
  16. ; Files copied
  17. ; > Change floppy disk
  18. ; > Press return when ready  ? <return>
  19. ;
  20. ; Requires:    Z80, Assemble with M80.COM link with LINK.COM
  21. ;
  22. ;---------------------------------------------------------------------
  23. ; REVISIONS
  24. ;
  25. ;---------------------------------------------------------------------
  26.  
  27. bdos    equ    5
  28. dfcb    equ    05ch
  29. dbuff    equ    080h
  30.  
  31.     public    d.reset, rdextent, rdblk, tstspace
  32.  
  33.  
  34. init:    ld    sp,stack
  35.     ld    c,12        ; BDOS Version Number
  36.     call    bdos
  37.     ld    (vers),a
  38.     cp    22h        ; test for 2.2
  39.     jr    z,cpm
  40.     cp    31h        ; or 3.1
  41.     jr    nz,not22
  42. cpm:    ld    a,b
  43.     cp    00h        ; CP/M
  44.     jr    nz,not22
  45.  
  46.     ld    c,25        ; BDOS Return current disk
  47.     call    bdos
  48.     ld    (ddsk),a    ; and save
  49.  
  50.     ld    de,msg1
  51.     call    string
  52.     jp    start
  53.  
  54. not22:    ld    de,msg0
  55.     call    string
  56.     ld    c,0
  57.     jp    bdos
  58.  
  59.     ds    64
  60. stack    equ    $
  61.  
  62. string:    ld    c,9        ;BDOS String output
  63.     jp    bdos
  64.  
  65. finish:    ld    c,0
  66.     jp    bdos
  67.  
  68. ucse:    cp    'a'
  69.     ret    c
  70.     cp    'z'+1
  71.     ret    nc
  72.     add    a,'A'-'a'
  73.     ret
  74.  
  75.  
  76. ;--------------------------------------------------------------------------
  77.  
  78. msg0:    db    'MUST USE CP/M 2.2 or 3.1','$'
  79.  
  80. msg1:    db    0ah,0dh,'MML:BACKUP V1.0 - Multi Floppy Disc backup of large files'
  81.     db    0ah,0dh,'$'
  82.  
  83. msg2:    db    0ah,0dh,'> Source file description ---- ? '
  84.     db    '$'
  85.  
  86. msg3:    db    0ah,0dh,'> Destination (or drive) ----- ? '
  87.     db    '$'
  88.  
  89. msg4:    db    0ah,0dh,'> Destination diskname ------- ? '
  90.     db    '$'
  91.  
  92. msg5:    db    0dh,0ah,'*** NO FILE ***','$'
  93.  
  94. msg6:    db    0dh,0ah,'*** PROGRAM ERROR ***','$'
  95.  
  96. msg7:    db    0dh,0ah,'*** Cannot create new file - perhaps disc is full','$'
  97.  
  98. msg8:    db    0dh,0ah,'*** READ ERROR','$'
  99.  
  100. msg9:    db    0dh,0ah,'*** WRITE ERROR - DISK or DIRECTORY is full','$'
  101.  
  102. msg10:    db    0dh,0ah,'*** Incorrect filename syntax','$'
  103.  
  104. msg11:    db    0dh,0ah
  105. wctxt:    db    '        .   ','$'
  106. ;         12345678 123 
  107.  
  108. msg12:    db    0dh,0ah,'COPYING:','$'
  109.  
  110. msg13:    db    0dh,0ah,'*** Incorrect disk name syntax','$'
  111.  
  112. msg14:    db    0dh,0ah,'When ready, press <RETURN> ?','$'
  113.  
  114. msg15:    db    0dh,0ah,'*** The diskette is now full, please replaces with another disk','$'
  115.  
  116. msg16:    db    0dh,0ah,'*** The diskette can not be used as it is too full.'
  117.     db    0dh,0ah,'    Please replaces with another disk','$'
  118.  
  119. msg17:    db    0dh,0ah,'*** As the diskette cannot be erased'
  120.     db    0dh,0ah,'    Please replaces with another disk','$'
  121.  
  122. msg18:    db    0dh,0ah,'*** Destination file write protected'
  123.     db    0dh,0ah,'    OK to destroy files (Y/N) ?','$'
  124.  
  125. wild:    db    0    ; set to number of wildcards outstanding
  126.  
  127. size:    dw    0    ; size of file (last record number + 1)
  128.     db    0    ; remaining to copy
  129.  
  130. free:    dw    0    ; free records on destination
  131.     db    0    ; remaining for copy
  132.  
  133. extent:    dw    0    ; records per destination physical extent
  134.     db    0    ; (should be zero)
  135.  
  136. blocks:    dw    0    ; remaining sectors in destination physical extent
  137.  
  138. vers:    db    0    ; 22h or 31h version numer
  139.  
  140. srcfcb:    ds    36    ; source FCB
  141.  
  142. dstfcb:    ds    36    ; destination FCB
  143.  
  144. erafcb:    ds    36    ; erase destination FCB
  145.  
  146. ddsk:    db    0    ; Default disk returned by BDOS
  147.  
  148. dstdpb:
  149.     ds    2    ; SPT
  150. dstbsh:    ds    2    ; BSH, BLM
  151. dstexm:    ds    1    ; EXM
  152. dstdsm:    ds    2    ; DSM
  153. dstdrm:    ds    2    ; DRM
  154. dstal:    ds    2    ; AL0,AL1
  155. lendpb    equ    $-dstdpb
  156.  
  157. cbuff:    db    16
  158. cbuff1:    db    0
  159. cbuff2:    ds    16 
  160.  
  161. ;--------------------------------------------------------------------------
  162.  
  163. ;----------------------;
  164. ; MAIN PROCESSING LOOP ;
  165. ;----------------------;
  166. start:
  167.     ld    sp,stack
  168.     ld    a,(wild)    ; test for wild card
  169.     or    a
  170.     jp    nz,dowild
  171.  
  172. ;-----------------------
  173. ; input SOURCE file name
  174. ;-----------------------
  175.  
  176.     ld    hl,srcfcb
  177.     ld    de,srcfcb+1
  178.     ld    bc,36-1
  179.     ld    (hl),0
  180.     ldir                ; fill with zeroes
  181.  
  182.     ld    hl,srcfcb+1
  183.     ld    de,srcfcb+2
  184.     ld    bc,11-1
  185.     ld    (hl),' '
  186.     ldir            ; initialise filename to blanks
  187.  
  188.     ld    de,msg2
  189.     call    string
  190.  
  191.     ld    de,cbuff
  192.     ld    c,10        ; BDOS Read console buffer
  193.     call    bdos
  194.  
  195.     ld    hl,cbuff1
  196.     ld    a,(hl)
  197.     or    a
  198.     jp    z,finish    ; <RETURN> terminates program
  199.     inc    hl
  200.  
  201.     ld    b,8+1        ; max number of bytes in filename
  202.     ld    de,srcfcb+1
  203.     ld    c,a
  204.     cp    2+1
  205.     jr    c,s.name    ; only allow drive if 3 or more chars entered
  206.     inc    hl
  207.     ld    a,(hl)
  208.     cp    ':'        ; do we have drive
  209.     dec    hl
  210.     jr    nz,s.name
  211.  
  212.     ld    a,(hl)
  213.     call    ucse
  214.     sub    'A'
  215.     jp    c,badname
  216.     cp    16
  217.     jp    nc,badname
  218.     inc    a        ; A = 1
  219.     dec    de
  220.     ld    (de),a
  221.     inc    de
  222.     inc    hl
  223.     inc    hl
  224.     dec    c
  225.     dec    c
  226. s.name:
  227.     ld    a,c
  228.     or    a
  229.     jr    z,s.eofn
  230.     ld    a,(hl)
  231.     cp    '.'
  232.     jp    z,s.Fstop
  233.     dec    b
  234.     jp    z,badname    ; too many characters entered
  235.     call    ucse
  236.     ld    (de),a
  237.     inc    hl
  238.     inc    de
  239.     dec    c
  240.     jr    s.name
  241. s.Fstop:
  242.     ld    de,srcfcb+9
  243.     inc    hl
  244.     dec    c
  245.     ld    b,3+1        ; maximum number of type characters
  246. s.type:
  247.     ld    a,c
  248.     or    a
  249.     jr    z,s.eofn
  250.     ld    a,(hl)
  251.     call    ucse
  252.     dec    b
  253.     jp    z,badname    ; too many characters entered
  254.     ld    (de),a
  255.     inc    hl
  256.     inc    de
  257.     dec    c
  258.     jr    s.type
  259.  
  260. s.eofn:                ; we have a filename
  261. ;--------------------;
  262. ; test for wild card ;
  263. ;--------------------;
  264.  
  265.     ld    hl,srcfcb+1
  266.     ld    b,11
  267. next1:    ld    a,(hl)
  268.     cp    '?'
  269.     jp    z,setwild
  270.     cp    '*'
  271.     jp    z,setwild
  272.     inc    hl
  273.     djnz    next1
  274.  
  275.     jp    s.open
  276.  
  277. ;-----------------
  278. ; open SOURCE file
  279. ;-----------------
  280. s.open:
  281.     ld    de,srcfcb
  282.     ld    c,15        ; BDOS open file
  283.     call    bdos
  284.     cp    -1
  285.     jp    z,nofile        ; no source file
  286.  
  287.     ld    de,srcfcb
  288.     ld    c,35        ; BDOS compute file size
  289.     call    bdos
  290.  
  291.     ld    hl,srcfcb+33    ; random record bytes
  292.     ld    de,size
  293.     ld    bc,3
  294.     ldir        ; and save
  295.  
  296.     ld    hl,0
  297.     ld    (srcfcb+33),hl    ; zero 3 bytes
  298.     ld    (srcfcb+34),hl    ; random record pointer
  299.  
  300. ;----------------------------
  301. ; input DESTINATION drive name
  302. ;----------------------------
  303.  
  304.     ld    hl,dstfcb
  305.     ld    de,dstfcb+1
  306.     ld    bc,36-1
  307.     ld    (hl),0
  308.     ldir                ; fill with zeroes
  309.  
  310.     ld    hl,dstfcb+1
  311.     ld    de,dstfcb+2
  312.     ld    bc,11-1
  313.     ld    (hl),' '
  314.     ldir            ; initialise filename to blanks
  315.  
  316.     ld    de,msg4
  317.     call    string
  318.  
  319.     ld    de,cbuff
  320.     ld    c,10        ; BDOS Read console buffer
  321.     call    bdos
  322.  
  323.     ld    hl,cbuff1
  324.     ld    a,(hl)
  325.     or    a
  326.     jp    z,finish
  327.     inc    hl
  328.  
  329.     ld    b,8+1        ; max number of bytes in filename
  330.     ld    de,dstfcb+1
  331.     ld    c,a
  332.     cp    1
  333.     jr    z,d.drive    ; drive only entered
  334.     inc    hl
  335.     ld    a,(hl)
  336.     dec    hl
  337.     cp    ':'        ; do we have drive
  338.     jr    nz,d.name
  339. d.drive:
  340.     ld    a,(hl)
  341.     call    ucse
  342.     sub    'A'
  343.     jp    c,baddisk
  344.     cp    16
  345.     jp    nc,baddisk
  346.     inc    a        ; A = 1
  347.     dec    de
  348.     ld    (de),a
  349.     inc    de
  350.     inc    hl
  351.     inc    hl
  352.     ld    a,c
  353.     cp    2+1
  354.     jr    c,d.dronly    ; only drive entered
  355.  
  356.     dec    c
  357.     dec    c
  358. d.name:
  359.     jp    badname        ; too many characters entered
  360.  
  361. d.dronly:            ; only drive name entered
  362.     ld    hl,srcfcb+1
  363.     ld    de,dstfcb+1
  364.     ld    bc,11
  365.     ldir            ; copy source filename
  366.  
  367.     call    maskt        ; clear any flag bits set
  368.  
  369. ;--------------------;
  370. ; test for wild card ;
  371. ;--------------------;
  372.  
  373.     ld    hl,dstfcb+1
  374.     ld    b,11
  375. next2:    ld    a,(hl)
  376.     cp    '?'
  377.     jp    z,badname
  378.     cp    '*'
  379.     jp    z,badname
  380.     inc    hl
  381.     djnz    next2
  382.  
  383. ;--------------------;
  384. ; test for srce=dest ;
  385. ;--------------------;
  386.  
  387.     ld    hl,dstfcb
  388.     ld    de,srcfcb
  389.     ld    b,12
  390. next3:    ld    a,(de)
  391.     and    7fh
  392.     cp    (hl)
  393.     jr    nz,d.init
  394.     inc    de
  395.     inc    hl
  396.     djnz    next3
  397.     jp    badname        ; same filenames
  398.  
  399. d.init:
  400.     call    setera        ; construct erase FCB
  401.     call    d.reset        ; reset disc system
  402.     jp    d.open        ; open file and copy
  403.  
  404. ;-------------------------;
  405. ; clear any flag bits set ;
  406. ;-------------------------;
  407. maskt:
  408.     ld    hl,dstfcb+1
  409.     ld    b,11
  410. nobits:    ld    a,(hl)
  411.     and    7fh
  412.     ld    (hl),a
  413.     inc    hl
  414.     djnz    nobits
  415.     ret
  416.  
  417. ;---------------------;
  418. ; construct erase FCB ;
  419. ;---------------------;
  420. setera:
  421.     ld    hl,dstfcb
  422.     ld    de,erafcb
  423.     ld    bc,36
  424.     ldir            ; copy to erafcb
  425.     ret
  426.  
  427.     page
  428. ;            --------------
  429. ;            WILD CARD COPY
  430. ;            --------------
  431.  
  432.  
  433. ;-------------------
  434. ; initiate wild card
  435. ;-------------------
  436. setwild:
  437.     xor    a
  438.     ld    (wild),a    ; set wildcard count to zero
  439.  
  440. ;---------------------;
  441. ; WILD CARD filenames ;
  442. ;---------------------;
  443.     ld    hl,srcfcb+1
  444.     ld    b,8
  445. sname:    ld    a,(hl)
  446.     cp    '*'
  447.     jr    z,astxn
  448.     inc    hl
  449.     djnz    sname
  450.     ld    b,3
  451.     jr    stype
  452.  
  453. astxn:    ld    (hl),'?'
  454.     inc    hl
  455.     djnz    astxn
  456.     ld    b,3
  457. stype:    ld    a,(hl)
  458.     cp    '*'
  459.     jr    z,astxt
  460.     inc    hl
  461.     djnz    stype
  462.     jr    sfirst
  463.  
  464. astxt:    ld    (hl),'?'
  465.     inc    hl
  466.     djnz    astxt
  467.  
  468. ;---------------------------------
  469. ; do a search FIRST of default fcb
  470. ;---------------------------------
  471. sfirst:
  472.     ld    (hl),0        ; set extend = 0
  473.                 ; (this assumes extent 0 is exists)
  474.     xor    a
  475.     ld    (wild),a
  476.  
  477.     ld    c,17        ; BDOS search for first
  478.     ld    de,srcfcb
  479.     call    bdos
  480.  
  481.     cp    -1
  482.     jp    z,nofile    ; no file found
  483.  
  484.     call    addfcb        ; copy fcb into our FCB area
  485. ;----------------------
  486. ; search for more FCB'S
  487. ;----------------------
  488. snext:
  489.     ld    c,18        ; BDOS search for next
  490.     ld    de,srcfcb
  491.     call    bdos
  492.  
  493.     cp    -1
  494.     jr    z,builtwc        ; no more files found
  495.  
  496.     call    addfcb        ; copy fcb into our FCB area
  497.  
  498.     jr    snext
  499.  
  500. ;------------------------------------
  501. ; scanned all possible FCB's
  502. ;------------------------------------
  503.  
  504. ;----------------------------
  505. ; input DESTINATION drive
  506. ;----------------------------
  507. builtwc:
  508.     ld    hl,dstfcb
  509.     ld    de,dstfcb+1
  510.     ld    bc,36-1
  511.     ld    (hl),0
  512.     ldir                ; fill with zeroes
  513.  
  514.     ld    de,msg4
  515.     call    string
  516.  
  517.     ld    de,cbuff
  518.     ld    c,10        ; BDOS Read console buffer
  519.     call    bdos
  520.  
  521.     ld    hl,cbuff1
  522.     ld    a,(hl)
  523.     or    a
  524.     jp    z,finish    ; unexpected termination
  525.     inc    hl
  526.  
  527.     ld    de,dstfcb
  528.     ld    c,a
  529.     cp    1
  530.     jr    z,d.dr
  531.     cp    2
  532.     jp    nz,baddisk    ; only 1 0r 2 characters allowed
  533.     inc    hl
  534.     ld    a,(hl)
  535.     cp    ':'        ; do we have drive
  536.     dec    hl
  537.     jp    nz,baddisk    ; 2nd character can only be a colon
  538. d.dr:
  539.     ld    a,(hl)
  540.     call    ucse
  541.     sub    'A'
  542.     jp    c,baddisk
  543.     cp    16
  544.     jp    nc,baddisk
  545.     inc    a        ; A = 1
  546.     ld    (de),a
  547.  
  548. ;---------------------------
  549. ; scanned all possible FCB's
  550. ;---------------------------
  551.  
  552.     ld    hl,srcfcb    ; construct erase FCB
  553.     ld    de,erafcb
  554.     ld    bc,36
  555.     ldir            ; copy to erafcb
  556.  
  557.     ld    a,(dstfcb)
  558.     ld    (erafcb),a    ; set destination drive
  559.  
  560.     call    d.reset        ; reset disk system
  561.  
  562.     ld    de,msg12
  563.     call    string
  564.  
  565.     jp    start
  566.  
  567. ;-----------------------------------------------------------
  568. ; copy fcb from directory entry number <A> into our FCB area
  569. ;-----------------------------------------------------------
  570. addfcb:
  571.     ld    l,a
  572.     ld    h,0
  573.     add    hl,hl
  574.     add    hl,hl
  575.     add    hl,hl
  576.     add    hl,hl
  577.     add    hl,hl
  578.  
  579.     ld    de,dbuff
  580.     add    hl,de
  581.     inc    hl        ; point to start of filename
  582.  
  583.     ex    de,hl        ; <DE> -> directory entry
  584.  
  585.     ld    hl,wild
  586.     inc    (hl)
  587.     ld    a,(hl)        ; FCB number
  588.     dec    a        ; now offset
  589.  
  590.     call    getblk        ; return in <HL> address of next FCB block
  591.  
  592.     ld    a,(srcfcb)
  593.     ld    (hl),a        ; set drive
  594.     inc    hl
  595.  
  596.     ex    de,hl
  597.     ld    bc,11
  598.     ldir            ; copy directory entry to our entry
  599.  
  600.     ret
  601.  
  602. ;-----------------------------------------
  603. ; return in <HL> address of next FCB block
  604. ;-----------------------------------------
  605. getblk:
  606.     ld    hl,fcbblk
  607.     ld    bc,12        ; size of fcb blk
  608.     or    a
  609.     ret    z
  610. nxtbk1:    add    hl,bc
  611.     dec    a
  612.     jr    nz,nxtbk1
  613.     ret
  614.  
  615.  
  616. ;----------------------
  617. ; display next filename
  618. ;----------------------
  619. dspwild:
  620.     ld    hl,srcfcb+1
  621.     ld    de,wctxt
  622.     ld    bc,8
  623.     ldir
  624.     inc    de
  625.     ld    bc,3
  626.     ldir
  627.  
  628.     ld    de,msg11
  629.     jp    string
  630.  
  631. ;---------------------
  632. ; end of wildcard copy
  633. ;---------------------
  634. nomore:
  635.     xor    a
  636.     ld    (wild),a
  637.     jp    start
  638.  
  639.     page
  640.  
  641. ;-----------------------
  642. ; copy next wildcard FCB
  643. ;-----------------------
  644. dowild:
  645.     ld    a,(wild)
  646.     or    a
  647.     jp    z,wceof        ; no more to send
  648.  
  649. ;--------------------------------
  650. ; fcbbk now contains (WILD) fcb's
  651. ;--------------------------------
  652.     ld    hl,fcbblk
  653.     ld    de,srcfcb
  654.     ld    bc,12
  655.     ldir            ; set up our default fcb
  656.  
  657.     ld    h,d
  658.     ld    l,e
  659.     inc    de
  660.     ld    (hl),0
  661.     ld    bc,36-12-1
  662.     ldir            ; and fill rest with zeroes
  663.  
  664. ;-------------------
  665. ; set up destination
  666. ;-------------------
  667.  
  668.     ld    hl,srcfcb+1
  669.     ld    de,dstfcb+1
  670.     ld    bc,36-1
  671.     ldir
  672.  
  673.     call    maskt        ; clear any flag bits set
  674.  
  675. ;-------------------------------------------
  676. ; now ripple all wild cards through to start
  677. ;-------------------------------------------
  678.     ld    hl,wild
  679.     dec    (hl)
  680.     ld    a,(hl)        ; Number of FCB's remaining in table
  681.     or    a
  682.     jr    z,openwc
  683.  
  684.     ld    de,12        ; size of fcb blk
  685.     ld    hl,0
  686.     ld    b,a
  687. upblks:    add    hl,de
  688.     djnz    upblks
  689.  
  690.     ld    b,h
  691.     ld    c,l        ; size of transfer
  692.  
  693.     ld    hl,fcbblk+12
  694.     ld    de,fcbblk
  695.     ldir            ; and copy over
  696.  
  697. openwc:
  698.     call    dspwild        ; and display
  699.  
  700. ;----------------------
  701. ; open WILD SOURCE file
  702. ;----------------------
  703.     ld    de,srcfcb
  704.     ld    c,15        ; BDOS open file
  705.     call    bdos
  706.     cp    -1
  707.     jp    z,nofile    ; no source file (or no extent 0)
  708.  
  709.     ld    de,srcfcb
  710.     ld    c,35        ; BDOS compute file size
  711.     call    bdos
  712.  
  713.     ld    hl,srcfcb+33    ; random record bytes
  714.     ld    de,size
  715.     ld    bc,3
  716.     ldir            ; and save
  717.  
  718.     ld    hl,0
  719.     ld    (srcfcb+33),hl    ; zero 3 bytes
  720.     ld    (srcfcb+34),hl    ; random record pointer
  721.  
  722. ;----------------------
  723. ; open destination file
  724. ;----------------------
  725. d.open:
  726.     call    setfree        ; calculate free space
  727.  
  728.     call    tstspace    ; check enough room in destination
  729.     jp    c,fulldisc
  730.  
  731.     ld    de,dstfcb
  732.     ld    c,22        ; BDOS Make file
  733.     call    bdos
  734.     cp    -1
  735.     jp    z,noopen
  736.  
  737.     ld    hl,0
  738.     ld    (dstfcb+33),hl
  739.     ld    (dstfcb+34),hl    ; set random record count to 0
  740.  
  741.     jp    rdextent    ; and do transfer
  742.  
  743. fulldisc:
  744.     ld    de,msg16
  745.     call    string
  746.  
  747.     call    waitcr
  748.  
  749.     call    d.reset
  750.  
  751.     jp    d.open        ; and try again
  752.  
  753.  
  754.     page
  755. ;------------------------
  756. ; Prepare destination disk
  757. ;------------------------
  758. d.reset:
  759.     ld    c,13        ; BDOS reset disk system
  760.     call    bdos
  761.  
  762.     ld    a,(ddsk)    ; default disk
  763.     ld    e,a
  764.     ld    a,(dstfcb)    ; destination disk
  765.     or    a
  766.     jr    z,seldsk
  767.     dec    a
  768.     ld    e,a
  769. seldsk:    ld    c,14        ; BDOS select disk
  770.     call    bdos
  771.     
  772.     ld    c,31        ; BDOS return DPB
  773.     call    bdos
  774.     ld    de,dstdpb
  775.     ld    bc,lendpb
  776.     ldir            ; copy DPB
  777.  
  778. ; calculate records per extent
  779.  
  780.     ld    hl,0
  781.     ld    de,128        ; records per logical extent
  782.     ld    a,(dstexm)    ; extent mask
  783.     ld    b,a
  784.     inc    b
  785. setext:    add    hl,de
  786.     djnz    setext
  787.     ld    (extent),hl    ; set records per physical extent
  788.     xor    a
  789.     ld    (extent+2),a    ; 3rd byte always zero
  790.  
  791.     ld    a,(ddsk)    ; default disk
  792.     ld    e,a
  793.     ld    c,14        ; BDOS select disk
  794.     call    bdos
  795.  
  796.     call    erase        ; erase target disk first
  797.     ret    z        ; -ok-
  798.  
  799. ;cant so start again
  800.     ld    de,msg17
  801.     call    string
  802.  
  803.     call    waitcr
  804.  
  805.     jp    d.reset
  806.  
  807. ;-----------
  808. ; erase disc
  809. ;-----------
  810.  
  811. ;-------------------------------
  812. ; do a search FIRST of erase fcb
  813. ;-------------------------------
  814. erase:
  815.     ld    a,-1
  816.     ld    (eraflag),a    ; set era query flag true
  817.  
  818.     ld    hl,erafcb+12    ; -> EX
  819.     ld    (hl),'?'
  820.     inc    hl
  821.     inc    hl
  822.     ld    (hl),'?'    ; -> S2 (just in case)
  823.  
  824.     ld    c,17        ; BDOS search for first
  825.     ld    de,erafcb
  826.     call    bdos
  827.  
  828.     cp    -1
  829.     ret    z        ; no file found
  830.  
  831. ;-----------------------
  832. ; test each erafcb entry
  833. ;-----------------------
  834. tstera:
  835.     call    tstwp        ; test for write protect
  836.     jr    z,seran        ; -no-
  837.  
  838.     call    okera
  839.     ret    nz        ; cant erase file
  840.  
  841.     call    setrw        ; make file read/write
  842.  
  843. ;----------------------
  844. ; search for more FCB'S
  845. ;----------------------
  846. seran:
  847.     ld    c,18        ; BDOS search for next
  848.     call    bdos
  849.  
  850.     cp    -1
  851.     jr    nz,tstera    ; more files found
  852.  
  853.     ld    c,19        ; BDOS Delete file
  854.     ld    de,erafcb
  855.     call    bdos
  856.     xor    a
  857.     ret
  858.  
  859. ;-------------------------------------------
  860. ; test target file for Read/Only file
  861. ; (for CP/M Plus should also check password)
  862. ;-------------------------------------------
  863. tstwp:
  864.     ld    l,a
  865.     ld    h,0
  866.     add    hl,hl
  867.     add    hl,hl
  868.     add    hl,hl
  869.     add    hl,hl
  870.     add    hl,hl
  871.  
  872.     ld    de,dbuff
  873.     add    hl,de        ; <HL> -> fcb found
  874.  
  875.     ld    a,(erafcb)
  876.     ld    (hl),a        ; set drive
  877.     ex    de,hl
  878.  
  879.     ld    hl,9
  880.     add    hl,de
  881.     ld    a,(hl)        ; t1
  882.     and    80h        ; test Read/Only
  883.     ret    z        ; -no-
  884.  
  885.     ex    de,hl
  886.     ld    de,dfcb
  887.     ld    bc,32
  888.     ldir            ; copy to default FCB
  889.  
  890.     or    -1        ; [ro] to [rw] required
  891.     ret
  892.  
  893. ;-----------------------------------
  894. ; see if ok to erase read-only files
  895. ; returns Z - Yes, NZ - NO
  896. ;-----------------------------------
  897. eraflag:    db    -1
  898. okera:
  899.     ld    hl,eraflag
  900.     ld    a,(hl)
  901.     or    a
  902.     ret    z        ; already said yes
  903.  
  904.     xor    a
  905.     ld    (hl),a
  906. waitok:
  907.     ld    de,msg18
  908.     call    string
  909.  
  910.     ld    de,cbuff
  911.     ld    c,10        ; BDOS Read console buffer
  912.     call    bdos
  913.  
  914.     ld    hl,cbuff1
  915.     ld    a,(hl)
  916.     or    a
  917.     ret    z        ; <RETURN> continues program
  918.  
  919.     cp    1
  920.     jr    nz,waitok
  921.  
  922.     inc    hl
  923.     ld    a,(hl)
  924.     cp    3
  925.     jp    z,finish    ; <CRTL-C> terminates
  926.  
  927.     cp    'Y'
  928.     ret    z
  929.     cp    'y'
  930.     ret    z
  931.  
  932.     cp    'N'
  933.     jr    z,noera
  934.     cp    'n'
  935.     jp    nz,waitok
  936. noera:    or    -1
  937.     ret            ; NON-ZERO flag
  938.  
  939. ;-----------------------------------
  940. ; set target file to Read/Write file
  941. ;-----------------------------------
  942. setrw:
  943.     ld    a,(dfcb+9)    ; t1
  944.     and    7fh        ; mask Read/Only
  945.     ld    (dfcb+9),a
  946.  
  947.     ld    a,(dfcb+6)    ; f6
  948.     and    7fh        ; Do not set byte count
  949.     ld    (dfcb+6),a
  950.  
  951.     ld    c,30        ; BDOS Set file attributes
  952.     ld    de,dfcb
  953.     call    bdos
  954.  
  955.     ld    c,17        ; BDOS search for first
  956.     ld    de,dfcb
  957.     call    bdos
  958.  
  959.     ld    hl,erafcb
  960.     ld    de,dfcb
  961.     ld    bc,32
  962.     ldir            ; copy to default FCB
  963.  
  964.     ret
  965.  
  966.  
  967.     
  968. ;----------------------------
  969. ; Calculate space on new disc
  970. ;----------------------------
  971. newdisk:
  972.     call    setfree        ; calculate free space
  973.  
  974.     ld    de,dstfcb
  975.     ld    c,22        ; BDOS Make file
  976.     call    bdos
  977.     ret
  978.  
  979. ;---------------------------------------------
  980. setfree:        ; calculate free space
  981. ;---------------------------------------------
  982.  
  983.     ld    a,(vers)
  984.     cp    31h
  985.     jp    z,tst31sp
  986.  
  987.     ld    a,(dstfcb)    ; destination disk
  988.     ld    e,a
  989.     dec    e
  990.     ld    c,14        ; BDOS select disk
  991.     or    a
  992.     call    nz,bdos        ; if not default
  993.  
  994.     ld    c,27        ; BDOS22 Get alloc vector
  995.     call    bdos
  996.     ex    de,hl        ; <DE> -> address of destination alloc
  997.  
  998.     xor    a
  999.     ld    (free),a
  1000.  
  1001.     ld    hl,(dstal)
  1002.     ld    a,h
  1003.     ld    h,l
  1004.     ld    l,a
  1005.  
  1006.     ld    a,(dstdsm)    ; assume high dstdsm = 0
  1007.     ld    c,a
  1008.     inc    c
  1009.  
  1010. loop01:    ld    b,8
  1011.     ld    a,(de)
  1012.     or    h
  1013. loop02:    add    hl,hl
  1014.     add    a,a
  1015.     jr    c,next02
  1016.     push    hl
  1017.     ld    hl,free
  1018.     inc    (hl)
  1019.     pop    hl
  1020. next02:    dec    c
  1021.     jr    z,done01    ; completed scan of alloc
  1022.     djnz    loop02
  1023.     inc    de
  1024.     jp    loop01
  1025. done01:
  1026.     ld    a,(free)    ; free data blocks
  1027.     ld    l,a
  1028.     ld    h,0
  1029.     ld    a,(dstbsh)
  1030.     ld    b,a
  1031. loop03:    add    hl,hl
  1032.     djnz    loop03
  1033.  
  1034.     ld    (free),hl    ; <HL> = number of 128 byte records
  1035.  
  1036.     xor    a
  1037.     ld    (free+2),a
  1038.  
  1039.     ld    a,(dstfcb)    ; destination disk
  1040.     or    a
  1041.     ret    z        ; if default
  1042.  
  1043.     ld    a,(ddsk)    ; default disc
  1044.     ld    e,a
  1045.     ld    c,14        ; BDOS select default disk
  1046.     call    bdos
  1047.     
  1048.     ret
  1049.  
  1050. tst31sp:
  1051.     ld    de,dbuff
  1052.     ld    c,26        ; BDOS Set DMA transfer address
  1053.     call    bdos
  1054.  
  1055.     ld    a,(ddsk)    ; default disk
  1056.     ld    e,a
  1057.     ld    a,(dstfcb)    ; destination disk
  1058.     or    a
  1059.     jr    z,getsp
  1060.     dec    a
  1061.     ld    e,a
  1062. getsp:    ld    c,46        ; BDOS Get Disk Free space
  1063.     call    bdos
  1064.  
  1065.     ld    hl,dbuff
  1066.     ld    de,free
  1067.     ld    bc,3
  1068.     ldir            ; save number of free records
  1069.  
  1070.     ret
  1071.  
  1072. waitcr:
  1073.     ld    de,msg14
  1074.     call    string
  1075.  
  1076.     ld    de,cbuff
  1077.     ld    c,10        ; BDOS Read console buffer
  1078.     call    bdos
  1079.  
  1080.     ld    hl,cbuff1
  1081.     ld    a,(hl)
  1082.     or    a
  1083.     ret    z        ; <RETURN> continues program
  1084.  
  1085.     cp    1
  1086.     jr    nz,waitcr
  1087.  
  1088.     inc    hl
  1089.     ld    a,(hl)
  1090.     cp    3
  1091.     jp    nz,waitcr
  1092.     jp    finish        ; <CRTL-C> terminates
  1093.  
  1094.  
  1095.     page
  1096.  
  1097. ;-----------------------------------------;
  1098. ; COPY RECORDS FROM SOURCE TO DESTINATION ;
  1099. ; both files are OPEN and ready to go     ;
  1100. ;-----------------------------------------;
  1101. newblk:
  1102.     call    nospace        ; open new disc
  1103. rdextent:
  1104.     call    tstspace    ; check enough room in destination
  1105.     jr    c,newblk    ; -no-
  1106.  
  1107.     ld    hl,(extent)    ; records per extent
  1108.     ld    (blocks),hl    ; maximum records to copy
  1109. ;-------------------------------------------------
  1110. ; read records for one destination physical extent
  1111. ;-------------------------------------------------
  1112. rdblk:
  1113.     ld    de,srcfcb
  1114.     ld    c,33        ; BDOS read randomly
  1115.     call    bdos
  1116.     or    a
  1117.     jp    nz,rdnodata    ; empty record
  1118.  
  1119.     ld    de,dstfcb
  1120.     ld    c,34        ;BDOS write random
  1121.     call    bdos
  1122.     or    a
  1123.     jp    nz,wrerr
  1124.  
  1125.     ld    hl,free        ; free records
  1126.     call    hl1dwn
  1127.  
  1128.     jp    nxtrec
  1129.  
  1130.  
  1131. ;------------------------------------------
  1132. rdnodata:    ; empty record test for EOF
  1133. ;------------------------------------------
  1134.  
  1135.     ld    b,a        ; save result of random read
  1136.  
  1137.     ld    hl,size        ; last record number + 1
  1138.     ld    a,(hl)
  1139.     inc    hl
  1140.     or    (hl)
  1141.     inc    hl
  1142.     or    (hl)
  1143.     jp    z,ateof        ; at eof
  1144.  
  1145.     ld    a,b        ; recover read result
  1146.     cp    04        ; test for no FCB
  1147.     jr    nz,onehole
  1148.  
  1149. ;--------------------------------------------------------
  1150. ; missing logical extent so skip 128 records (16k extent)
  1151. ;--------------------------------------------------------
  1152.  
  1153.     ld    c,128-1
  1154. nxtext:
  1155.     ld    hl,srcfcb+33
  1156.     call    hl1up        ; increment random record counter
  1157.  
  1158.     ld    hl,dstfcb+33    ; (should be the same as source)
  1159.     call    hl1up        ; increment random record pointer
  1160.  
  1161.     ld    hl,size        ; records remaining to copy
  1162.     call    hl1dwn        ; reduce by one
  1163.  
  1164.     ld    hl,(blocks)    ; remaining records in extent
  1165.     dec    hl
  1166.     ld    (blocks),hl    ; maximum records to copy
  1167.  
  1168.     dec    c
  1169.     jr    nz,nxtext    ; continue to end of extent less one
  1170.  
  1171. onehole:
  1172. nxtrec:
  1173.     ld    hl,srcfcb+33
  1174.     call    hl1up        ; increment random record counter
  1175.  
  1176.     ld    hl,dstfcb+33
  1177.     call    hl1up        ; increment random record pointer
  1178.  
  1179.     ld    hl,size        ; records remaining to copy
  1180.     call    hl1dwn        ; reduce by one
  1181.  
  1182.     ld    hl,(blocks)    ; remaining records in extent
  1183.     dec    hl
  1184.     ld    (blocks),hl    ; maximum records to copy
  1185.  
  1186.     ld    a,h
  1187.     or    l
  1188.     jp    nz,rdblk    ; and await next block
  1189.     jp    rdextent    ; read next extent
  1190.  
  1191. ;-------------------------------------------------
  1192. tstspace:    ; check enough room in destination
  1193. ;-------------------------------------------------
  1194. ;1. check space remaining on dest disk
  1195. ;2. compare with size of physical extent
  1196. ;   Return if greater or equal
  1197. ;3. compare with remaining size of source disk
  1198. ;   Return if greater or equal
  1199. ;4. if no room
  1200. ;   1. close destination file
  1201. ;   2. prompt user to change disk
  1202. ;   3. create new file with current extent
  1203. ;   4. repeat this module
  1204. ; RETURNS: Carry set if not enough space
  1205. ;-------------------------------------------------
  1206.  
  1207. ; compare space remaining on disc with physical extent size
  1208.  
  1209.     ld    de,free        ; free records
  1210.     ld    hl,extent    ; records per extent
  1211.     ld    a,(de)
  1212.     sub    (hl)
  1213.     inc    hl
  1214.     inc    de
  1215.     ld    a,(de)
  1216.     sbc    a,(hl)
  1217.     inc    hl
  1218.     inc    de
  1219.     ld    a,(de)
  1220.     sbc    a,(hl)
  1221.     ret    nc        ; space on disk for one physical extent
  1222.                 ; carry true when no space
  1223.  
  1224. ; compare space remaining on disc with remaining sectors to transfer
  1225.  
  1226.     ld    de,free        ; free records
  1227.     ld    hl,size        ; last record number + 1
  1228.     ld    a,(de)
  1229.     sub    (hl)
  1230.     inc    hl
  1231.     inc    de
  1232.     ld    a,(de)
  1233.     sbc    a,(hl)
  1234.     inc    hl
  1235.     inc    de
  1236.     ld    a,(de)
  1237.     sbc    a,(hl)
  1238.  
  1239.     ret        ; NC - space on disk for remainder of file
  1240.             ;  C - carry true when no space
  1241.  
  1242. ;---------------------------
  1243. ; insufficient space on disk
  1244. ;---------------------------
  1245. nospace:
  1246.     ld    a,(dstfcb+15)    ; destination record count byte
  1247.     or    a
  1248.     jr    z,done05    ; empty extent
  1249.  
  1250.     ld    de,dstfcb
  1251.     ld    c,16        ; close file
  1252.     call    bdos
  1253.     cp    -1
  1254.     jp    z,wrerr
  1255.  
  1256.     ld    a,(dstexm)    ; extent mask
  1257.     inc    a
  1258.     ld    b,a
  1259.     ld    hl,dstfcb+12    ; offset to 1st EX byte
  1260. loop05:    inc    (hl)
  1261.     djnz    loop05
  1262.     ld    a,(hl)
  1263.     and    00100000b    ; check for overflow
  1264.     jp    z,done05    ; -no-
  1265.     ld    a,(hl)
  1266.     and    11011111b
  1267.     ld    (hl),a
  1268.     inc    hl
  1269.     inc    hl        ; to S1
  1270.     inc    (hl)        ; and increment overflow EX
  1271. ;----------------------------------
  1272. ; open destination file on new disk
  1273. ;----------------------------------
  1274. done05:
  1275.     ld    de,msg15
  1276.     call    string
  1277.  
  1278.     call    waitcr
  1279.  
  1280.     call    d.reset
  1281.     call    newdisk
  1282.     cp    -1
  1283.     jp    z,noopen
  1284.  
  1285.     ld    hl,(srcfcb+33)
  1286.     ld    de,(dstfcb+33)    ; reset random record count
  1287.     ld    bc,3
  1288.     ldir
  1289.  
  1290.     ret
  1291.  
  1292. ;-------------------------------
  1293. ; 3 byte increment and decrement
  1294. ;-------------------------------
  1295. hl1up:    ld    b,3        ; increment 3 bytes at <HL> by one
  1296. hl1up1:    inc    (hl)
  1297.     ld    a,(hl)
  1298.     or    a
  1299.     ret    nz
  1300.     inc    hl
  1301.     djnz    hl1up1
  1302.     ret
  1303.  
  1304. hl1dwn:    ld    b,3        ; decrement 3 bytes at <HL> by one
  1305. hl1nxt:    ld    a,(hl)
  1306.     dec    (hl)
  1307.     or    a
  1308.     ret    nz
  1309.     inc    hl
  1310.     djnz    hl1nxt
  1311.     ret
  1312.  
  1313. ;------------
  1314. ; reached EOF
  1315. ;------------
  1316. ateof:    ld    de,dstfcb
  1317.     ld    c,16        ; close file
  1318.     call    bdos
  1319.     cp    -1
  1320.     jp    z,wrerr
  1321.  
  1322.     ld    de,srcfcb
  1323.     ld    c,16        ; close file
  1324.     call    bdos
  1325.  
  1326. ; done file transfer
  1327.     jp    start        ; (or finish)
  1328.  
  1329. wceof:    jp    start        ; (or finish)
  1330.  
  1331.  
  1332. ;--------;
  1333. ; ERRORS ;
  1334. ;--------;
  1335.  
  1336. nofile:    ld    de,msg5
  1337.     call    string
  1338.     ld    a,0
  1339.     ld    (wild),a
  1340.     jp    start
  1341.  
  1342. errfile:
  1343.     ld    de,msg6
  1344.     call    string
  1345.     ld    a,0
  1346.     ld    (wild),a
  1347.     jp    start
  1348.  
  1349. noopen:
  1350.     ld    de,msg7
  1351.     call    string
  1352.     ld    a,0
  1353.     ld    (wild),a
  1354.     jp    start
  1355.  
  1356. rderr:
  1357.     ld    de,msg8
  1358.     call    string
  1359.     ld    a,0
  1360.     ld    (wild),a
  1361.     jp    start
  1362.  
  1363. wrerr:
  1364.     ld    de,msg9
  1365.     call    string
  1366.     ld    a,0
  1367.     ld    (wild),a
  1368.     jp    start
  1369.  
  1370. badname:            ; too many characters entered
  1371.     ld    de,msg10
  1372.     call    string
  1373.     jp    start
  1374.  
  1375. baddisk:            ; too many characters entered
  1376.     ld    de,msg13
  1377.     call    string
  1378.     jp    start
  1379.  
  1380. ;----------------------------------------------------------------------
  1381.  
  1382.  
  1383. ;---------------------------------------------------------------------
  1384. fcbblk:    ds    12*128        ; space for up to 128 FCB entries
  1385. ;---------------------------------------------------------------------
  1386.  
  1387.     end
  1388.