home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug049.ark / CDOSCOPY.Z80 < prev    next >
Encoding:
Text File  |  1984-04-29  |  11.6 KB  |  561 lines

  1. ; Disk Copy Utility from CPM Users Group 
  2. ; Modified for CDOS by Trevor Marshall
  3. ;            Elec Eng Dept
  4. ;            Uni W.A.
  5. ; Jan 1980
  6. ;
  7. ; Rewritten for 2.36 CDOS (Double Density)
  8. ; Automatic disk label checking,
  9. ;   Sept 1980,  Trevor Marshall
  10. ;
  11. ;
  12.     ORG    100H
  13.     JP    COPY
  14. ; BIOS FUNCTION CALLING TABLE
  15. WBOOT:    CALL    BIOSGO
  16. CONST:    CALL    BIOSGO
  17. CONIN:    CALL    BIOSGO
  18. CONOUT:    CALL    BIOSGO
  19. LIST:    CALL    BIOSGO
  20. PUNCH:    CALL    BIOSGO
  21. READER:    CALL    BIOSGO
  22. HOME:    CALL    BIOSGO
  23. SELDSK:    CALL    BIOSGO
  24. SETTRK:    CALL    BIOSGO
  25. SETSEC:    CALL    BIOSGO
  26. SETDMA:    CALL    BIOSGO
  27. READ:    CALL    BIOSGO
  28. WRITE:    CALL    BIOSGO
  29. BIOSGO:    EX    (SP),HL         ; Get call addr in HL, save HL on stack
  30.     PUSH    DE         ; Save DE
  31.     EX    DE,HL         ; Move call addr to DE
  32.     LD    HL,(1)         ; Get BIOS entry address
  33.     ADD    HL,DE         ; Add call addr to entry addr
  34.     LD    DE,[WBOOT+3]; Get start of table
  35. ; Subtract DE from HL in 8080 code (for compatibility)
  36.     LD    A,E
  37.     CPL    
  38.     LD    E,A
  39.     LD    A,D
  40.     CPL
  41.     LD    D,A    ;Now have 1s compl of DE
  42.     INC    DE    ;2s compl
  43.     ADD    HL,DE    ;Done!
  44.     POP    DE         ; Restore DE
  45.     EX    (SP),HL         ; Restore HL, put jump addr on stack
  46.     RET             ; Jump to BIOS routine
  47. ; Original coding by:
  48. ;         L.E. HUGHES     8080SDC     77/10/29
  49. ;
  50. ; Modified by     Trevor Marshall
  51. ;        E.E.Dept
  52. ;        Uni W.A.
  53. ;
  54. ; to work with any sized CDOS system
  55. ; and to prompt for drives
  56. ;    
  57.     
  58. ;         MISC SYMBOLS
  59.     
  60. LF    EQU    0AH   ;LINE FEED
  61. CR    EQU    0DH   ;CARRIAGE RETURN
  62.     
  63. ITRK    EQU    0     ;INITIAL TRACK TO COPY
  64. LTRK    EQU    76    ;LAST TRACK TO COPY
  65.     
  66. BDOS:    EQU    5
  67. ;
  68. COPY:    LD    HL,0
  69.     ADD    HL,SP
  70.     LD    (OLDSP),HL
  71.     LD    SP,STACK+64
  72. ;
  73. ;         ALLOW USER TO MOUNT DISK(S) BEFORE PROCEEDING
  74.     
  75. AGAIN:    LD    C,96H    ;Turn drive motors off
  76.     CALL    BDOS
  77. ;
  78.     LD    HL,CRLF
  79.     CALL    WASC
  80.     LD    HL,STR1 ;PRINT 'Source Disk Drive,etc'
  81.     CALL    WASC
  82.     CALL    RACC
  83.     CP    3    ;CTL-C ABORT
  84.     JP    Z,EXIT1
  85.     CALL    WACC
  86.     SUB    'A'
  87.     JP    C,AGAIN    ;Invalid entry
  88.     CP    3
  89.     JP    NC,AGAIN
  90.     LD    (SOURCE),A
  91.     LD    HL,CRLF
  92.     CALL    WASC
  93. ; Now prompt for destination
  94.     LD    HL,STR1A
  95.     CALL    WASC
  96.     CALL    RACC
  97.     CALL    WACC
  98.     SUB    'A'
  99.     JP    C,AGAIN
  100.     CP    3
  101.     JP    NC,AGAIN
  102.     LD    (DEST),A
  103.     LD    HL,SOURCE
  104.     LD    C,(HL)
  105.     CP    A,C
  106.     JP    Z,AGAIN
  107.     LD    HL,CRLF
  108.     CALL    WASC
  109.     
  110.     
  111. ; Now we must determine whether single or double 
  112. ;  density disks are in use, and check that we
  113. ;  are not trying to copy between incompatible formats
  114. ;
  115. ; We will use the CDOS 1BH cal (Get disk allocation vec)
  116. ;   as the disk labels are read before this call returns.
  117. ; This call returns the number of clusters in DE
  118. ;
  119. ;
  120.     LD    C,0DH    ;Reset CDOS
  121.     CALL    BDOS
  122. ;
  123.     LD    A,(SOURCE) ;Select Source drive
  124.     LD    E,A
  125.     LD    C,0EH
  126.     CALL    BDOS
  127. ;
  128.     LD    C,1BH    ;Get CLUSTER.SIZE size map
  129.     CALL    BDOS    ;for first disk
  130.     LD    (ACLUSTERS),DE
  131. ;
  132.     LD    A,(DEST) ;Select Dest. drive
  133.     LD    E,A
  134.     LD    C,0EH
  135.     CALL    BDOS
  136. ;
  137.     LD    C,1BH    ;Get cluster size map
  138.     CALL    BDOS    ;for second disk
  139.     LD    (BCLUSTERS),DE ;save it
  140.     LD    HL,(ACLUSTERS) ;get it again
  141.     XOR    A
  142.     SBC    HL,DE    ;to compare them
  143.     LD    A,L
  144.     OR    A,L    ;see if HL is zero
  145.     JP    NZ,SEND.DIFF.ERROR ;no
  146. ; Now display the disks in use and branch to copy S/R
  147.     LD    A,E    ;LSB of # clusters
  148.     CP    A,0FEH    ;D/D S/S?
  149.     JP    Z,SEND.DD.MSG
  150.     CP    A,060H    ;D/D D/S
  151.     JP    Z,SEND.DS.MSG
  152.     CP    A,0F3H    ;S/D S/S
  153.     JR    Z,SEND.SD.MSG
  154.     CP    A,0F7H    ;S/D D/S
  155.     JP    Z,SEND.DS.MSG    ;Dont use this often,
  156.             ;I wont bother to tidy it up
  157.     JP    SEND.NON.STANDARD.MSG
  158. ;
  159. SEND.SD.MSG: LD    DE,SD.MSG
  160.     LD    C,9
  161.     CALL    BDOS ;Print it
  162.     LD    A,1BH    ;Max sectors/trk+1
  163.     LD    (SECTORS.PER.TRACK),A
  164.     LD    HL,80H    ;The sector size for S/D
  165.     LD    (DMA.INCR),HL
  166.     LD    HL,SDMAP-1 ;Point to sector map
  167.     LD    (SECTOR.MAP.ADDRESS),HL
  168.     JR    MAIN
  169. ;
  170. SEND.DIFF.ERROR: LD DE,DIFF.ERROR.MSG
  171. L5:    LD    C,9
  172.     CALL    BDOS
  173.     JP    AGAIN
  174. SEND.NON.STANDARD.MSG: LD DE,NON.STANDARD.ERROR.MSG
  175.     JR    L5
  176. ;
  177. ;         BEGIN SINGLE DENSITY LOOP
  178.     
  179. MAIN:    LD    DE,MSG1    ;Finish disk msg
  180.     LD    C,9
  181.     CALL    BDOS
  182. ;
  183.     LD    HL,STR4         ;PRINT HEADER
  184.     CALL    WASC
  185.     LD    HL,STR5
  186.     CALL    WASC
  187. ;
  188.     LD    A,ITRK         ;INITIAL TRACK NUMBER
  189.     LD    (TRKNO),A
  190. COPY2: 
  191. ; Check for CTL-C abort
  192.     CALL    CONST
  193.     CP    0
  194.     JP    Z,FT1
  195.     CALL    CONIN
  196.     AND    5FH
  197.     CP    3    ;CTL-C
  198.     JP    Z,COPYX
  199. FT1:    LD    A,(SOURCE) ;Select Source Disk
  200.     LD    C,A
  201.     CALL    SELDSK
  202.     LD    A,(TRKNO)    ;SET TRACK NUMBER
  203.     LD    C,A
  204.     CALL    SETTRK
  205.     LD    HL,TBUF         ;SET INITIAL DMA ADDRESS
  206.     LD    (DMAPTR),HL
  207.     LD    A,1         ;INITIAL SECTOR NUMBER
  208.     LD    (SECNO),A
  209. COPY3:    LD    A,(SECNO)    ;SET SECTOR NUMBER
  210.     LD    HL,(SECTOR.MAP.ADDRESS)
  211.     LD    D,0
  212.     LD    E,A
  213.     ADD    HL,DE
  214.     LD    C,(HL)
  215.     CALL    SETSEC
  216.     LD    HL,(DMAPTR)  ;SET DMA ADDRESS
  217.     LD    B,H
  218.     LD    C,L
  219.     CALL    SETDMA
  220.     CALL    READ         ;READ SECTOR
  221.     LD    HL,(DMAPTR)  ;ADD INCR TO DMA PTR
  222.     PUSH    DE
  223.     LD    DE,(DMA.INCR)
  224.     ADD    HL,DE
  225.     POP    DE
  226.     LD    (DMAPTR),HL
  227.     LD    HL,SECNO     ;ADD 1 TO SECTOR NUMBER
  228.     INC    (HL)
  229.     LD    A,(HL)
  230.     LD    HL,SECTORS.PER.TRACK
  231.     CP    A,(HL) ;LOOP THRU ENTIRE TRACK
  232.     JP    C,COPY3
  233.     
  234. ;         WRITE TBUF TO CURRENT TRACK ON DISK C
  235.     
  236.     LD    A,(DEST) ;Select dest dsk
  237.     LD    C,A
  238.     CALL    SELDSK
  239.     LD    A,(TRKNO)    ;SET TRACK NUMBER
  240.     LD    C,A
  241.     CALL    SETTRK
  242.     LD    HL,TBUF         ;SET DMA ADDRESS
  243.     LD    (DMAPTR),HL
  244.     LD    A,1         ;SET INITIAL SECTOR NUMBER
  245.     LD    (SECNO),A
  246. COPY4:    LD    A,(SECNO)    ;SET SECTOR NUMBER
  247.     LD    HL,(SECTOR.MAP.ADDRESS)
  248.     LD    D,0
  249.     LD    E,A
  250.     ADD    HL,DE
  251.     LD    C,(HL)
  252.     CALL    SETSEC
  253.     LD    HL,(DMAPTR)  ;SET DMA ADDRESS
  254.     LD    B,H
  255.     LD    C,L
  256.     CALL    SETDMA
  257.     CALL    WRITE         ;WRITE SECTOR
  258.     LD    HL,(DMAPTR)  ;ADD INCR TO DMAPTR
  259.     PUSH    DE
  260.     LD    DE,(DMA.INCR)
  261.     ADD    HL,DE
  262.     POP    DE
  263.     LD    (DMAPTR),HL
  264.     LD    HL,SECNO     ;ADD 1 TO SECTOR NUMBER
  265.     INC    (HL)
  266.     LD    A,(HL)
  267.     LD    HL,SECTORS.PER.TRACK
  268.     CP    A,(HL) ;LOOP THRU ENTIRE TRACK
  269.     JP    C,COPY4
  270.     
  271. ;         ADVANCE TO NEXT TRACK
  272.     
  273.     LD    A,'*'
  274.     CALL    WACC
  275.     LD    HL,TRKNO
  276.     INC    (HL)
  277.     LD    A,(HL)
  278.     CP    LTRK+1         ;LOOP THRU ENTIRE DISK
  279.     JP    C,COPY2
  280.     
  281. ;         ALL DONE SINGLE DENSITY
  282.     
  283. COPY5:    LD    HL,STR2         ;PRINT 'COPY COMPLETE'
  284.     JP    COPY6
  285. COPYX:    LD    HL,STR3         ;PRINT 'COPY ABORTED'
  286. COPY6:    CALL    WASC
  287.     JP    COPY
  288. EXIT1:    LD    HL,(OLDSP)   ;EXIT TO CP/M
  289.     LD    SP,HL
  290.     JP    0
  291.     
  292. ;         WASC - WRITE ASCII STRING TO CONSOLE
  293.     
  294. WASC:    LD    A,(HL)
  295.     OR    A
  296.     RET    Z
  297.     CALL    WACC
  298.     INC    HL
  299.     JP    WASC
  300.     
  301. ;         WACC - WRITE ASCII CHARACTER TO CONSOLE
  302.     
  303. WACC:    PUSH    HL
  304.     PUSH    DE
  305.     PUSH    BC
  306.     PUSH    AF
  307.     LD    C,A
  308.     CALL    CONOUT
  309.     POP    AF
  310.     POP    BC
  311.     POP    DE
  312.     POP    HL
  313.     RET    
  314.     
  315. ;         RACC - READ ASCII CHARACTER FROM CONSOLE
  316.     
  317. RACC:    PUSH    HL
  318.     PUSH    DE
  319.     PUSH    BC
  320.     CALL    CONIN
  321.     AND    5FH    ;Make LC=UC
  322.     POP    BC
  323.     POP    DE
  324.     POP    HL
  325.     RET    
  326.     
  327. SEND.DS.MSG: LD    A,2
  328.     LD    (SIZE.FLAG),A
  329.     LD    DE,DS.MSG
  330.     JR    V1
  331. SEND.DD.MSG: LD    A,1
  332.     LD    (SIZE.FLAG),A
  333.     LD    DE,DD.MSG
  334. V1:    LD    C,9
  335.     CALL    BDOS
  336. ;
  337. ;Calculate the 2's complement of the block capacity of disk
  338.     LD    HL,(ACLUSTERS) ;Get # on disk
  339.     ADD    HL,HL    ; x2 (16 blocks per cluster)
  340.     ADD    HL,HL    ; x4
  341.     ADD    HL,HL    ; x8
  342.     ADD    HL,HL    ; x16
  343.     EX    DE,HL    ;into DE
  344.     SCF        ;add 1 to block capacity
  345.     LD    HL,0
  346.     SBC    HL,DE    ;have 2's complement
  347.     LD    (BLOCK.CAPACITY),HL
  348. ; We cannot use the same approach for D/D disks
  349. ;   as for S/D, so we will use a LOGICAL BLOCK
  350. ;   approach. Each block is 128 Bytes, I have
  351. ;   ~32K free RAM, so will read ~28K at a time
  352. ;   (160h, 352d blocks).
  353. ;
  354. DOUBLE:    LD    DE,MSG1    ;Finish disk msg
  355.     LD    C,9
  356.     CALL    BDOS
  357. ;
  358.     LD    A,(SIZE.FLAG) ;Is it D/D or D/S ?
  359.     CP    1    ;D/D only?
  360.     JR    NZ,JJ1    ;No, D/S D/D
  361.     LD    HL,STR6    ;PRINT D/D HEADER
  362.     CALL    WASC
  363.     LD    HL,STR7
  364.     CALL    WASC
  365.     JR    JJ2
  366. ;
  367. JJ1:    LD    HL,STR8    ;PRINT D/S HEADER
  368.     CALL    WASC
  369.     LD    HL,STR9
  370.     CALL    WASC
  371. ;
  372. JJ2:    LD    HL,0    ;INITIAL BLOCK NUMBER
  373.     LD    (BLKNO),HL
  374. ;
  375. ; Begin the main (fill buffer) loop
  376. DCOPY2: LD    HL,TBUF-80H
  377.     LD    (DMAPTR),HL ;Initialize DMA ptr
  378.     LD    DE,(BLKNO) ;Block # to DE
  379.     LD    (FIRSTBLK),DE ;Save first blocK #
  380. ;
  381. ; Check for CTL-C abort
  382.     CALL    CONST
  383.     CP    0
  384.     JP    Z,DFT1
  385.     CALL    CONIN
  386.     AND    5FH
  387.     CP    3    ;CTL-C
  388.     JP    Z,COPYX    ;and abort
  389. ;
  390. ; Get enough blocks to fill buffer, one at a time
  391. DFT1:    LD    HL,(DMAPTR)  ;ADD INCR TO DMA PTR
  392.     LD    DE,80H    ;Block size is 128 bytes
  393.     ADD    HL,DE
  394.     LD    (DMAPTR),HL
  395. ; Are we at end of Buffer,
  396.     LD    DE,-8000H
  397.     ADD    HL,DE    ;C means .LT. 8000H
  398.     JR    C,DCOPY6 ;If so write the buffer
  399. ;Set DMA for DOS
  400.     LD    DE,(DMAPTR)
  401.     LD    C,1AH
  402.     CALL    BDOS
  403. ; Is this block beyond the end of disk?
  404.     LD    DE,(BLOCK.CAPACITY)
  405.     LD    HL,(BLKNO)    
  406.     ADD    HL,DE    ;see if DE & HL are .EQ.
  407.     LD    A,L
  408.     OR    A,H
  409.     JP    Z,COPY5   ;Z = done copy
  410. ; Read the block
  411.     LD    DE,(BLKNO) ;Block # to DE
  412.     LD    C,83H
  413.     LD    HL,SOURCE
  414.     LD    B,(HL) ;disk # to B
  415.     INC    B    ;For BDOS
  416.     SET    7,B    ;Set interleaved read
  417.     CALL    BDOS
  418. ; Handle error status
  419.     CP    A,1    ;I/O error
  420.     JP    Z,COPYX
  421.     CP    A,2    ;Illegal request
  422.     JP    Z,COPYX
  423.     CP    A,3    ;Illegal Block
  424.     JP    EQ,COPYX            
  425. ; Now incr the block #
  426.     LD    HL,(BLKNO)
  427.     INC    HL
  428.     LD    (BLKNO),HL
  429. ; Is this beyond the end of disk?
  430.     LD    DE,(BLOCK.CAPACITY)
  431.     ADD    HL,DE    ;see if DE & HL are .EQ.
  432.     LD    A,L
  433.     OR    A,H
  434.     JR    NZ,DFT1   ;Z = done read
  435. ; Must decr last BLKNO so write does not overrun
  436. DCOPY6:    LD    HL,(BLKNO)
  437.     DEC    HL
  438.     LD    (BLKNO),HL
  439. ;
  440. ;Write the buffer if full
  441. DCOPY3:
  442. ; Begin the main (empty buffer) loop
  443. SENDSTAR: LD    A,'*'
  444.     CALL    WACC
  445. ;
  446.     LD    HL,TBUF-80H
  447.     LD    (DMAPTR),HL ;Initialize DMA ptr
  448. ; Save last BLK # and get first #
  449.     LD    HL,(BLKNO)
  450.     LD    (LASTBLK),HL
  451. ;
  452.     LD    DE,(FIRSTBLK) ;First Block # to DE
  453.     LD    (BLKNO),DE ;Save blocK #
  454. ;
  455. ; Put enough blocks to empty buffer, one at a time
  456. DFT2:    LD    HL,(DMAPTR)  ;ADD INCR TO DMA PTR
  457.     LD    DE,80H    ;Block size is 128 bytes
  458.     ADD    HL,DE
  459.     LD    (DMAPTR),HL
  460. ; Is this beyond the end of disk?
  461. ;    LD    DE,(BLOCK.CAPACITY)
  462. ;    LD    HL,(BLKNO)    ;get the block #
  463. ;    ADD    HL,DE    ;see if DE & HL are .EQ.
  464. ;    LD    A,L
  465. ;    OR    A,H
  466. ;    JP    Z,COPY5   ;Z = done copy
  467. ; Have we written too many blocks
  468.     LD    HL,(LASTBLK)
  469.     LD    DE,(BLKNO)
  470.     XOR    A
  471.     SBC    HL,DE
  472.     JP    C,DCOPY2 ;C if BLKNO > LASTBLK
  473. ; On exit BLKNO will be LASTBLK + 1
  474. ; Which is OK for next read loop
  475. ;Set DMA for DOS
  476.     LD    DE,(DMAPTR)
  477.     LD    C,1AH
  478.     CALL    BDOS
  479. ;
  480. ; Write the block
  481.     LD    DE,(BLKNO) ;Block # to DE
  482.     LD    C,84H
  483.     LD    HL,DEST
  484.     LD    B,(HL) ;disk # to B
  485.     INC    B    ;for BDOS
  486.     SET    7,B    ;Set interleaved read
  487.     CALL    BDOS
  488. ; Handle error status
  489.     CP    A,1    ;I/O error
  490.     JP    Z,COPYX
  491.     CP    A,2    ;Illegal request
  492.     JP    Z,COPYX
  493.     CP    A,3    ;Illegal Block,done
  494.     JP    EQ,COPYX 
  495. ; Now incr the block #
  496.     LD    HL,(BLKNO)
  497.     INC    HL
  498.     LD    (BLKNO),HL
  499. ;
  500.     JR    DFT2    ;Loop for more blocks
  501. ;    
  502. ;
  503. ;         OUTPUT STRINGS
  504.     
  505. STR1:    DEFB    'Source disk drive (A to D) ?',CR,LF
  506.     DB    'Type <CR> if you make an error --- ',0
  507. CRLF:    DB    cr,lf,0
  508. STR1A:    db    'Ensure you mount the disks before'
  509.     db    'typing the : ',cr,lf
  510.       DB    'Destination drive (A to D) ? --- ',0
  511. STR2:    DEFB    CR,LF,'Copy completed',CR,LF,0
  512. STR3:    DEFB    '***** Copy aborted *****',CR,LF,0
  513. STR4:    DEFB    0DH,0AH,0AH
  514.     DB    '          1         2         3         4'
  515.     DEFB    '         5         6         7',CR,LF,0
  516. STR5:    DEFB    '01234567890123456789012345678901234567890'
  517.     DEFB    '123456789012345678901234567890123456',CR,LF,0
  518. STR6:    DB    0DH,0AH,0AH
  519.     DB    '          1',CR,LF,0
  520. STR7:    DB    '01234567890123456',CR,LF,0
  521. STR8:    DB    0DH,0AH,0AH
  522.     DB    '          1         2         3         4',CR,LF,0
  523. STR9:    DB    '01234567890123456789012345678901234567890',CR,LF,0
  524. ;    
  525. DD.MSG:    DB    0DH,0AH,'Double Density$'
  526. SD.MSG:    DB    0DH,0AH,'Single Density$'
  527. DS.MSG:    DB    0DH,0AH,'Double sided Double Density$'
  528. MSG1:    DB    ' disks mounted.$'
  529. DIFF.ERR.MSG: DB 0DH,0AH,'**** DISK LABEL ERROR ***$'
  530. NON.STANDARD.ERROR.MSG: DB 0DH,0AH,'**** DISKS ARE NON STANDARD ****$'
  531. ;
  532. ;         SECTOR MAP
  533.     
  534. SDMAP:    DB    1,7,0DH,13H,19H,5,0BH,11H,17H,3,9,0FH,15H,2
  535.     DB    8,0EH,14H,1AH,6,0CH,12H,18H,4,0AH,10H,16H
  536. ;DDMAP:    DB    1,0CH,7,2,0DH,8,3,0EH,9,4,0FH,0AH,5,10H,0BH,6
  537. ;    
  538. OLDSP:    DEFS    2
  539. STACK:    DEFS    64
  540. ACLUSTERS: DS    2    ;Clusters on DSK 1
  541. BCLUSTERS: DS    2    ;Clusters on DSK 2
  542. BLOCK.CAPACITY: DS 2    ;Blocks on the disk
  543. SIZE.FLAG: DS    1    ;D/D OR D/S ?
  544. SECTORS.PER.TRACK: DS 1
  545. DMA.INCR: DS    2
  546. SECTOR.MAP.ADDRESS: DS 2
  547. SOURCE:    DS    1    ;SOURCE DRIVE #
  548. DEST:    DS    1    ;DEST DRIVE #
  549.     
  550. TRKNO:    DEFS    1         ;TRACK NUMBER
  551. SECNO:    DEFS    1         ;SECTOR NUMBER
  552. DMAPTR:    DEFS    2         ;DMA POINTER
  553. BLKNO:    DS    2
  554. FIRSTBLK: DS    2
  555. LASTBLK: DS    2
  556. ;
  557. ; THe buffer for D/D is assumed 45 K long
  558. TBUF:    DEFS    26*128         ;TRACK BUFFER
  559.     
  560.     END    100H
  561.