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 / SIMTEL / CPMUG / CPMUG078.ARK / SWAPCOPY.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  14KB  |  679 lines

  1. ;SWAPCOPY.ASM.....A single drive copy program.
  2. ;    November 1980 
  3. ;by    John M. Kodis, Buffalo, New York.
  4. ;
  5. ;Allows files to be transfered from one diskette to
  6. ;another in a system with only a single drive.
  7. ;
  8. ;Allows ambiguous file specifications.
  9. ;Allows transfer of files larger than available memory,
  10. ;and transfer of multiple files in a single pass.
  11. ;
  12. ;Allows use of dissimiliar media (i.e., to copy
  13. ;programs from a single density master diskette
  14. ;to a double density working diskette).
  15.  
  16. ;Further documentation in SWAPCOPY.DOC
  17. ;
  18. ;No Hardware dependencies
  19. ;
  20. ;Developed using CP/M 2.0, but uses only those bdos calls
  21. ;which are supported under CP/M 1.4. 
  22. ;
  23. ;
  24. ;    Disk to disk file transfer program.
  25. ;
  26. ;    At the command level, the command:
  27. ;
  28. ;    SWAPCOPY FILENAME.EXT <cr>
  29. ;
  30. ;    will copy the file A:FILENAME.EXT from diskette
  31. ;    to diskette, prompting as necessary to allow the
  32. ;    diskette in drive A to be swapped.
  33. ;
  34. boot    equ       0    ;system reboot
  35. bdos    equ       5    ;bdos entry point
  36. memtop    equ       6    ;pointer to start of fbase
  37. fcb1    equ      5ch    ;first file name & source fcb
  38. fcb2    equ      6ch    ;second file name
  39. tpa    equ     100h    ;beginning of tpa
  40. ;
  41. false    equ       0
  42. true    equ     255
  43. ;
  44. cntrlc    equ       3
  45. tab    equ       9
  46. lf    equ      10
  47. cr    equ      13
  48. secsiz    equ     128    ;bytes per sector
  49. ;
  50.     org    tpa
  51. ;
  52. swapcopy:
  53.     lxi    sp,stack;set up local stack space
  54. ;
  55.     mvi    a,false
  56.     sta    done    ;we're not done yet
  57.     sta    one2go    ;nor do we have a file to go
  58.     sta    pflag
  59.     sta    qflag
  60.     sta    rflag    ;set all options false
  61.     lda    fcb2+1
  62.     call    setops
  63.     lda    fcb2+2
  64.     call    setops
  65.     lda    fcb2+3
  66.     call    setops    ;test for up to three options
  67. ;
  68.     lxi    h,buf+eofo
  69.     mvi    m,true    ;set initial eof to true
  70. ;
  71.     lhld    memtop
  72.     lxi    d,-(secsiz+freeo+8)
  73.     dad    d    ;highest availiable dma buffer
  74.     shld    buftop
  75. ;
  76.     lxi    h,buf
  77.     shld    fpbpnt    ;free space starts at buf
  78. ;
  79.     mvi    a,1
  80.     sta    names    ;initial next-names count
  81. ;
  82.     lxi    d,sourmx
  83.     call    prompt    ;ask for the source disk
  84.     call    ffname    ;get the first matching file name
  85.     call    adjpnt
  86.     call    filfpb    ;set rdma & wdma pointers, fill in file name
  87.     call    query    ;is the first file to be copied?
  88.     jnc    nxtnam    ;if not, try the next file
  89.     mvi    a,true
  90.     sta    one2go    ;if so, set 'one to go' to true, then copy it
  91. ;
  92. rdloop:    lda    fileof
  93.     ana    a
  94.     jm    wr    ;start writing when the last file has been read
  95.     lhld    rdma
  96.     call    fulbuf
  97.     jc    wr    ; or when the buffer space has been exhausted
  98. ;
  99.     lhld    eof
  100.     mov    a,m
  101.     ana    a
  102.     jz    samfil    ;if not end-of-file, we're on the same file.
  103. ;
  104.     call    adjpnt    ;Else, this is the start of a new file...
  105.     call    filfpb    ;adjust pointers & fill new fpb
  106.     xra    a
  107.     lhld    sfext
  108.     mov    m,a    ;source file extent := 0
  109.     lhld    sfcr
  110.     mov    m,a    ;source file current record := 0
  111.     lhld    dfext
  112.     mov    m,a    ;dest file extent := 0
  113.     lhld    dfcr
  114.     mov    m,a    ;dest file current record := 0
  115.     lhld    eof
  116.     mov    m,a    ;eof := false
  117.     lhld    made
  118.     mov    m,a    ;made := false
  119.     lhld    opened
  120.     mov    m,a    ;opened := false
  121.     lhld    last
  122.     mov    m,a    ;last := false
  123.     mvi    a,true
  124.     sta    fpbusd    ;mark current fpb as used
  125.     lhld    sfcb
  126.     call    open
  127. ;
  128. samfil:    call    read
  129.     lhld    eof
  130.     mov    a,m
  131.     ana    a
  132.     jz    samnam    ;read sectors until eof or buffer full
  133. ;
  134. nxtnam:    call    ffname    ;on eof, find the next name to be considered
  135.     lxi    h,names
  136.     mov    a,m
  137.     sta    namcnt
  138. nnloop:    call    fnname    ;find next name...
  139.     lxi    h,namcnt
  140.     dcr    m
  141.     jnz    nnloop    ;as many times as necessary.
  142.     lxi    h,names
  143.     inr    m    ;then bump the count for the next pass
  144. ;
  145.     lda    fileof
  146.     ana    a    ;if all matching file names have been copied
  147.     jm    wr    ;(or passed over), start writing.
  148.     call    query    ;is the first file to be copied?
  149.     jnc    nxtnam    ;if not, try the next file
  150.     mvi    a,true
  151.     sta    one2go    ;if so, set 'one to go' to true, then copy it
  152.     lda    fpbusd
  153.     ana    a    ;if the current fpb is unused, use it
  154.     jz    samnam
  155.     lhld    rdma    ;else set up the next fpb, and use it
  156.     mov    a,m
  157.     inx    h
  158.     mov    h,m
  159.     mov    l,a
  160.     shld    fpbpnt    ;next block starts just past rdma
  161.     jmp    rdloop
  162. ;
  163. samnam:    lhld    rdma
  164.     call    bump    ;rdma := rdma + secsiz
  165.     jmp    rdloop
  166. ;
  167. wr:    lda    one2go    ;anything for the destination disk?
  168.     ana    a
  169.     jz    fini    ;if not, we're done.
  170.     lxi    h,buf
  171.     shld    fpbpnt    ;fpbpnt := buf
  172.     call    adjpnt
  173.     lxi    d,destmx
  174.     call    prompt    ;prompt(destmx)
  175. ;
  176. wrnext:    lhld    made
  177.     mov    a,m
  178.     ana    a
  179.     jnz    a$m    ;if already made, don't make it again
  180. ;
  181.     mvi    m,true    ;if not made, set made := true
  182.     lhld    opened
  183.     mvi    m,true    ;then set opened := true,
  184.     call    make    ;then make the file.
  185. ;
  186. a$m:    lhld    opened
  187.     mov    a,m
  188.     ana    a
  189.     jnz    a$op    ;if already opened, don't open it again
  190.     mvi    m,true
  191.     lhld    dfcb
  192.     call    open    ;if not open, open it & set opened := true
  193. ;
  194. a$op:    lhld    rdma
  195.     mov    e,m
  196.     inx    h
  197.     mov    d,m    ;de gets rdma
  198.     lhld    wdma
  199.     mov    a,e
  200.     cmp    m    ;compare least signifigant bytes
  201.     jnz    nequal
  202.     inx    h
  203.     mov    a,d
  204.     cmp    m
  205.     jz    equal    ;is wdma equal to rdma?
  206. ;
  207. nequal:    call    write    ;if not, write a sector
  208.     lhld    wdma
  209.     call    bump    ;wdma := wdma + secsiz
  210.     jmp    a$op
  211. ;
  212. equal:    call    close    ;when wdma = rdma, close the file
  213.     lhld    eof
  214.     mov    a,m
  215.     ana    a    ;done with file?
  216.     jz    skprpt    ;if not, don't report the transfer yet.
  217.     lda    rflag
  218.     ana    a    ;is the 'Report' option set?
  219.     jz    skprpt    ;if not, don't report the file transfer.
  220. ;
  221.     lda    pflag
  222.     ana    a
  223.     cnz    crlf    ;if 'Print' is on, we need a new line
  224.     lxi    d,cpydmx
  225.     call    print    ;print 'Copied '
  226.     lhld    dfcb
  227.     call    pfname    ;print the file name
  228.     call    crlf    ;start a new line
  229. ;
  230. skprpt:    lhld    wdma
  231.     call    fulbuf    ;if the whole buffer has been written,
  232.     jc    wrexit    ;try to read another some more in
  233. ;
  234.     lhld    rdma    ;else, set up to write the next file
  235.     mov    e,m
  236.     inx    h
  237.     mov    d,m
  238.     xchg        ;hl points to next fpb
  239.     shld    fpbpnt    ;set up the file param. block pointer
  240.     lhld    last
  241.     mov    a,m
  242.     sta    done
  243.     ana    a
  244.     jnz    fini    ;if the last file has been written, we're done
  245.     call    adjpnt
  246.     jmp    wrnext    ;else adjust pointers, then write the next file
  247. ;
  248. wrexit:    lda    done
  249.     ana    a    ;shall we exit or read more files?
  250.     jnz    fini    ;we're done, so exit
  251. ;
  252.     lxi    b,freeo
  253.     lxi    d,buf
  254.     lhld    fpbpnt
  255.     call    ldir    ;move the last fpb to the start of the buffer
  256. ;
  257.     lxi    h,buf
  258.     shld    fpbpnt
  259.     call    adjpnt
  260.     call    filfpb    ;set up the pointers at the start of the buffer
  261. ;
  262.     lxi    d,sourmx
  263.     call    prompt    ;ask for the source disk
  264.     jmp    rdloop
  265. ;
  266. fini:    lxi    d,systmx
  267.     call    prompt    ;prompt for system disk
  268.     lxi    d,normal
  269. abort:    call    print
  270.     rst    boot
  271. ;
  272. namsiz    equ    12    ;size of a disk file name (1+8+3)
  273. fcbsiz    equ    36    ;size of a file control block
  274. sfcbo    equ    0    ;offset to source fcb
  275. sfexto    equ    12    ;offset to source file extent
  276. scro    equ    32    ;offset to source file current record
  277. dfcbo    equ    36    ;offset to destination file control block
  278. dfexto    equ    48    ;offset to destination file extent
  279. dcro    equ    68    ;offset to destination file current record
  280. rdmao    equ    72    ;offset to read zone pointer
  281. wdmao    equ    74    ;offset to write zone pointer
  282. madeo    equ    76    ;offset to file-made flag
  283. openo    equ    77    ;offset to file-open flag
  284. eofo    equ    78    ;offset to end-of-file flag
  285. lasto    equ    79    ;offset to last-file flag
  286. freeo    equ    80    ;offset to start of freespace
  287. ;
  288. adjpnt:    lhld    fpbpnt    ;compute and save the...
  289.     lxi    d,sfexto
  290.     dad    d
  291.     shld    sfext    ;    pointer to source file extent
  292.     lxi    d,scro-sfexto
  293.     dad    d
  294.     shld    sfcr    ;    pointer to source file current record,
  295.     lxi    d,dfcbo-scro
  296.     dad    d
  297.     shld    dfcb    ;    pointer to dest fcb,
  298.     lxi    d,dfexto-dfcbo
  299.     dad    d
  300.     shld    dfext    ;    pointer to dest file extent,
  301.     lxi    d,dcro-dfexto
  302.     dad    d
  303.     shld    dfcr    ;    pointer to dest file current record,
  304.     lxi    d,rdmao-dcro
  305.     dad    d
  306.     shld    rdma    ;    pointer to read dma zone,
  307.     inx    h
  308.     inx    h
  309.     shld    wdma    ;    pointer to write dma zone,
  310.     inx    h
  311.     inx    h
  312.     shld    made    ;    pointer to file made flag,
  313.     inx    h
  314.     shld    opened    ;    pointer to file-open flag
  315.     inx    h
  316.     shld    eof    ;    pointer to end-of-file flag,
  317.     inx    h
  318.     shld    last    ;    pointer to the 'last-file' flag,
  319.     inx    h
  320.     shld    fspace    ;and the pointer to the start of free space.
  321.     ret
  322. ;
  323. filfpb:    lhld    fpbpnt
  324.     xchg
  325.     lhld    fileof    ;get offset into directory bufffer
  326.     mvi    h,0
  327.     dad    h
  328.     dad    h
  329.     dad    h
  330.     dad    h
  331.     dad    h    ;multiply by 32
  332.     lxi    b,dirbuf
  333.     dad    b    ;hl points to file name
  334.     lxi    b,namsiz
  335.     push    h
  336.     push    b
  337.     call    ldir    ;move file name to source fcb
  338.     pop    b
  339.     lhld    dfcb
  340.     xchg
  341.     pop    h
  342.     call    ldir    ;move file name to destination fcb
  343.     lhld    fspace
  344.     xchg
  345.     lhld    rdma
  346.     mov    m,e
  347.     inx    h
  348.     mov    m,d    ;point rdma to start of free space
  349.     inx    h
  350.     mov    m,e
  351.     inx    h
  352.     mov    m,d    ;point wdma to start of free space
  353.     ret
  354. ;
  355. bump:    mvi    a,secsiz
  356.     add    m
  357.     mov    m,a    ;add sector size to l.s. byte of address
  358.     rnc
  359.     inx    h
  360.     inr    m    ;if carry, increment m.s. byte of address
  361.     ret
  362. ;
  363. fulbuf:    mov    e,m
  364.     inx    h
  365.     mov    d,m    ;de gets address to be compared
  366.     lhld    buftop
  367.     mov    a,l
  368.     sub    e
  369.     mov    a,h
  370.     sbb    d
  371.     ret        ;return with carry set if @(de) > buftop
  372. ;
  373. setops:    cpi    'P'
  374.     jnz    isitq
  375.     sta    pflag    ;set 'Print' flag
  376. isitq:    cpi    'Q'
  377.     jnz    isitr
  378.     sta    qflag    ;set 'Query' flag
  379. isitr:    cpi    'R'
  380.     rnz
  381.     sta    rflag    ;set 'Report' flag
  382.     ret
  383. ;
  384. query:    lda    qflag
  385.     ana    a
  386.     stc
  387.     rz        ;copy all files if not querying
  388.     lda    pflag
  389.     ana    a
  390.     cnz    crlf    ;if 'Printing', a new line is needed
  391.     lxi    d,copymx
  392.     call    print    ;print 'Copy '
  393.     lda    fileof
  394.     add    a
  395.     add    a
  396.     add    a
  397.     add    a
  398.     add    a    ;get 32 * file offset
  399.     lxi    h,dirbuf
  400.     add    l
  401.     mov    l,a
  402.     adc    h
  403.     sub    l
  404.     mov    h,a    ;point hl to filename
  405.     call    pfname    ;print the filename
  406.     lxi    d,qmark
  407.     call    print    ;print '?'
  408.     lxi    h,askbuf
  409.     mvi    m,127
  410.     xchg
  411.     mvi    c,linef
  412.     call    bdos    ;get a response to the question
  413.     mvi    e,lf
  414.     call    co
  415.     lxi    h,askbuf+1
  416.     mov    a,m
  417.     ana    a
  418.     rz        ;if no response, return with carry clear.
  419. skipbl:    inx    h
  420.     mov    a,m
  421.     cpi    ' '
  422.     jz    skipbl
  423.     cpi    tab
  424.     jz    skipbl    ;skip leading blanks and tabs
  425.     ani    (not 20h) and 255
  426.     sui    'Y'
  427.     stc
  428.     rz        ;if first non-blank is 'Y', copy the file
  429.     cmc
  430.     ret
  431. ;
  432. pfname:    mvi    a,8
  433.     call    pathl    ;print 8 characters in the name,
  434.     mvi    e,'.'
  435.     call    co    ;print a period,
  436.     mvi    a,3    ;print the 3 characters in the extension.
  437. ;
  438. pathl:    inx    h
  439.     mov    e,m
  440.     call    co    ;print the character @+(hl)
  441.     dcr    a
  442.     jnz    pathl    ;repeat (a) times
  443.     ret
  444. ;
  445. ;    system interface routines
  446. ;
  447. cif    equ       1    ;console input function #
  448. cof    equ       2
  449. printf    equ       9    ;print buffer function #
  450. linef    equ      10    ;line input function #
  451. cstsf    equ      11    ;get console status function #
  452. resetf    equ      13    ;select & write enable drive A
  453. openf    equ      15    ;open file function #
  454. closef    equ      16    ;close file function #
  455. sfff    equ      17    ;search for first function #
  456. sfnf    equ      18    ;search for next function #
  457. deletef    equ      19    ;delete file function #
  458. readf    equ      20    ;sequential file read
  459. writef    equ      21    ;sequential file write
  460. makef    equ      22    ;create & open a new file
  461. dmaf    equ      26    ;set dma address function #
  462. ;
  463. open:    mvi    c,openf
  464.     xchg
  465.     call    bdos
  466.     inr    a
  467.     jz    openng
  468.     lda    pflag
  469.     ana    a
  470.     rz
  471.     mvi    e,'O'
  472.     jmp    co
  473. openng:    lxi    d,cantop
  474.     jmp    abort
  475. ;
  476. close:    mvi    c,closef
  477.     lhld    dfcb
  478.     xchg
  479.     call    bdos
  480.     lhld    opened
  481.     mvi    m,false
  482.     lda    pflag
  483.     ana    a
  484.     rz
  485.     mvi    e,'C'
  486.     jmp    co
  487. ;
  488. read:    lhld    rdma
  489.     mov    e,m
  490.     inx    h
  491.     mov    d,m
  492.     call    setdma
  493.     mvi    c,readf
  494.     lhld    fpbpnt
  495.     xchg
  496.     call    bdos
  497.     lhld    eof
  498.     mov    m,a
  499.     ana    a
  500.     rnz
  501.     lda    pflag
  502.     ana    a
  503.     rz
  504.     mvi    e,'r'
  505.     jmp    co
  506. ;
  507. write:    lhld    wdma
  508.     mov    e,m
  509.     inx    h
  510.     mov    d,m
  511.     call    setdma
  512.     mvi    c,writef
  513.     lhld    dfcb
  514.     xchg
  515.     call    bdos
  516.     ana    a
  517.     jnz    cantwr
  518.     lda    pflag
  519.     ana    a
  520.     rz
  521.     mvi    e,'w'
  522.     jmp    co
  523. cantwr:    lxi    d,space
  524.     jmp    abort
  525. ;
  526. make:    mvi    c,deletef
  527.     lhld    dfcb
  528.     xchg
  529.     call    bdos
  530.     mvi    c,makef
  531.     lhld    dfcb
  532.     xchg
  533.     call    bdos
  534.     inr    a
  535.     jz    makeng
  536.     lda    pflag
  537.     ana    a
  538.     rz
  539.     mvi    e,'M'
  540.     jmp    co
  541. makeng:    lxi    d,wrprot
  542.     call    print
  543.     lxi    d,nodir
  544.     jmp    abort
  545. ;
  546. setdma:    mvi    c,dmaf
  547.     jmp    bdos
  548. ;
  549. reset:    mvi    c,resetf
  550.     jmp    bdos
  551. ;
  552. ;
  553. crlf:    mvi    e,cr
  554.     call    co
  555.     mvi    e,lf
  556. co:    push    h
  557.     push    psw
  558.     mvi    c,cof
  559.     call    bdos
  560.     pop    psw
  561.     pop    h
  562.     ret
  563. ;
  564. print:    mvi    c,printf
  565.     jmp    bdos
  566. ;
  567. ffname:    lxi    d,dirbuf
  568.     call    setdma
  569.     mvi    c,sfff
  570.     lxi    d,fcb1
  571.     call    bdos
  572.     sta    fileof
  573.     inr    a
  574.     rnz
  575.     lxi    d,nofile
  576.     jmp    abort
  577. ;
  578. fnname:    lxi    d,dirbuf
  579.     call    setdma
  580.     mvi    c,sfnf
  581.     lxi    d,fcb1
  582.     call    bdos
  583.     sta    fileof
  584.     add    a
  585.     sbb    a    ;a:=255 if fileof=255, else 0
  586.     lhld    last
  587.     mov    m,a
  588.     ret
  589. ;
  590. prompt:    lda    pflag
  591.     ana    a
  592.     push    d
  593.     cnz    crlf
  594.     pop    d
  595.     call    print
  596. clear:    mvi    c,cstsf
  597.     call    bdos
  598.     ana    a
  599.     jz    wait
  600.     mvi    c,cif
  601.     call    bdos    ;if there's a char waiting, get it & ignore it.
  602.     jmp    clear
  603. wait:    mvi    c,cif
  604.     call    bdos    ;get the next char
  605.     cpi    cntrlc
  606.     jz    boot
  607.     cpi    cr
  608.     jnz    badch    ;explain the procedure
  609.     call    reset
  610.     ret
  611. ;
  612. badch:    lxi    d,explan
  613.     jmp    prompt
  614. ;
  615. ldir:    mov    a,m
  616.     stax    d
  617.     inx    h
  618.     inx    d
  619.     dcx    b
  620.     mov    a,c
  621.     ora    b
  622.     jnz    ldir
  623.     ret
  624. ;
  625. ;    console messages
  626. ;
  627. sourmx:    db    'Insert SOURCE disk.', cr, lf, '$'
  628. destmx:    db    'Insert DESTINATION disk.', cr, lf, '$'
  629. systmx:    db    'Insert SYSTEM disk.', cr, lf, '$'
  630. copymx:    db    'Copy $'
  631. cpydmx:    db    'Copied $'
  632. qmark:    db    '?  $'
  633. explan:    db    'To continue, hit the ''RETURN'' key.', cr, lf
  634.     db    'To abort, hit control ''C''.', cr, lf, '$'
  635. normal:    db    'Copy complete.$'
  636. nofile:    db    cr, lf, 'No source files', cr, lf, '$'
  637. nodir:    db    cr, lf, 'Directory space exhausted', cr, lf, '$'
  638. cantop:    db    cr, lf, 'Can''t reopen file.', cr, lf, '$'
  639. space:    db    cr, lf, 'Data space exhausted', cr, lf, '$'
  640. wrprot:    db    cr, lf, 'Write protected?', cr, lf, '$'
  641. ;
  642. ;    data areas
  643. ;
  644. sfcb:    ds    0
  645. fpbpnt:    ds    2    ;pointer to start of the file param. block
  646. sfext:    ds    2    ;pointer to source file extent byte
  647. sfcr:    ds    2    ;pointer to source file current record byte
  648. dfcb:    ds    2    ;pointer to destination file control block
  649. dfext:    ds    2    ;pointer to dest file extent byte
  650. dfcr:    ds    2    ;pointer to dest file current record byte
  651. buftop:    ds    2    ;pointer to top of free memory
  652. rdma:    ds    2    ;pointer to next read dma zone
  653. wdma:    ds    2    ;pointer to next write dma zone
  654. made:    ds    2    ;pointer to file made flag
  655. opened:    ds    2    ;pointer to file open flag
  656. eof:    ds    2    ;pointer to end of file flag
  657. last:    ds    2    ;pointer to last file flag
  658. fspace:    ds    2    ;pointer to start of free buffer space
  659. fileof:    ds    1    ;file offset. index into dirbuf
  660. done:    ds    1    ;all files copied flag
  661. names:    ds    1    ;number of the next file to be copied
  662. namcnt:    ds    1    ;copy of 'names'. used as a counter
  663. pflag:    ds    1    ;'Print' option flag
  664. qflag:    ds    1    ;'Query' option flag
  665. rflag:    ds    1    ;'Report' option flag
  666. fpbusd:    ds    1    ;current fpb has been used flag
  667. one2go:    ds    1    ;there is a file to be transfered flag
  668. ;
  669.     ds     64    ;32 level stack
  670. stack:    ds      0
  671. ;
  672. dirbuf:    ds    secsiz    ;buffer for searching the directory
  673. ;
  674. askbuf:    ds    129    ;buffer for response to query
  675. ;
  676. buf:    ds      0    ;buffer starts here and extends to fbase
  677. ;
  678.     end    swapcopy
  679.