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 / ENTERPRS / CPM / UTILS / S / UN33.ZIP / UN33.MAC < prev   
Text File  |  1986-02-27  |  14KB  |  600 lines

  1.  
  2.     .Z80
  3.     ASEG
  4.  
  5. ; UN33.MAC - CP/M v3.0 UTILITY FOR RECOVERING ERASED FILES - 02/27/86
  6. ;
  7. ; This program is based on UNERASE.COM in the public domain.  It has
  8. ; been modified to work with CP/M 3.0 and later, to change the user area
  9. ; of a file and to accept ambiguous files names.  It currently works
  10. ; with sector sizes of 128, 256 512 and 1024 bytes.  It is placed in the
  11. ; public domain by Advanced Logic Systems for public use.  Advanced Logic
  12. ; Systems makes no warrantee on the operation or use of this program or
  13. ; its applicability for any given application.
  14. ;
  15. ; U3 DOES NOT DOES NOT WORK WITH VERSIONS OF CP/M PRIOR TO CP/M 3.0
  16. ;
  17. ; The U3 command line takes the form:
  18. ;
  19. ;        U3 [d:]afn.aft [user area]
  20. ;
  21. ; If no user area is specified U3 recovers all erased files on drive D:
  22. ; (or the default if D: is not specified) matching afn.aft and places
  23. ; them in the current user area.  If a user area is specified, U3 moves
  24. ; all files in the current user area on drive D: (or the default if D:
  25. ; is not specified) matching afn.aft to the specified user area.
  26. ;
  27. ;
  28. ;-----------------------------------------------------------------------
  29. ;
  30. ; 02/27/86  Rewritten in standard Zilog Z80 code.  No external macro li-
  31. ;   v3.3    braries need to be found/used now.    Minor changes.    Can now
  32. ;        be assembled with a normal Z80 assember such as SLR's Z80ASM
  33. ;        or Microsoft's M80.     - Irv Hoff
  34. ;
  35. ; 12/24/84  Revised code to permit UN3 to be used to either recorver an
  36. ;   3.2     erased file or change the user area of a file.  Added ambig-
  37. ;        uous file specifications.  Revised code to work with disks
  38. ;        having more than one directory track.  Moved CP/M v3.0 ver-
  39. ;        sion chec code toa beginning of program and corrected error
  40. ;        test in NODEF.        - R. Saeks
  41. ;
  42. ; 06/16/84  Revised to work with 1024 byte sectors and to place recover-
  43. ;   v3.1    ed files in the currently logged-in user area.
  44. ;                    - R. Saeks
  45. ;
  46. ; 12/29/83  First pass at disassembly of UNERASE.COM and modifications
  47. ;   v3.0    to make it compatible with CP/M v3.0.  Did a 'select disk'
  48. ;        in DSKPRM so that if you try to recover a file from a disk
  49. ;        that is a differenta format from the one that you are cur-
  50. ;        rently logged to, it gets the right DPH.  Also changed the
  51. ;        size of the area where the number of reserved system tracks
  52. ;        is kept.  This allows the number of reserved tracks to be
  53. ;        greater than 256.        - Gale Wolfenbarger
  54. ;
  55. ;-----------------------------------------------------------------------
  56. ;
  57. ; Addresses
  58. ;
  59. BDOS    EQU    05H        ; BDOS vector address
  60. WRMBOOT    EQU    00H        ; Warm boot vector address
  61. DEFFCB    EQU    5CH        ; Address of the default FCB
  62. DEFFCB2    EQU    6CH        ; Address of the second default FCB
  63. ;
  64. ;
  65. ; BDOS functions
  66. ;
  67. DIRCALL    EQU    32H        ; CP/M 3.0 direct BIOS call
  68. DRESET    EQU    0DH        ; Reset disk system
  69. GETCUR    EQU    19H        ; Get currently logged in disk
  70. GETUSR    EQU    20H        ; Get current user
  71. CONIN    EQU    01H        ; Get a character from the console
  72. CONOUT    EQU    02H        ; Print a character to the console
  73. SETDMA    EQU    1AH        ; Set DMA function
  74. GETVER    EQU    0CH        ; Get CP/M version #
  75. GETPARM    EQU    1FH        ; Get address of disk parameters
  76. PRINT    EQU    09H        ; Print string to console
  77. ;
  78. ;
  79. ; ASCII characters
  80. ;
  81. CR    EQU    0DH        ; Carriage return
  82. LF    EQU    0AH        ; Line feed
  83. ;
  84. ;-----------------------------------------------------------------------
  85. ;
  86. ;
  87.     ORG    0100H
  88. ;
  89. ;
  90.     JP    START
  91.     DEFB    'UN 3.3 for CP/M v3.0 - 02/27/86'
  92. ;
  93. ;
  94.     ORG    0200H
  95. ;
  96. ;
  97. START:    LD    SP,START
  98.     CALL    SETUP
  99.     CALL    RDDIR
  100.     CALL    FINISH
  101.     JP    WRMBOOT
  102. ;.....
  103. ;
  104. ;
  105. SETUP:    CALL    CKVERS        ; Check for CP/M 3.0 or later
  106.     CALL    CKNAME        ; Check for valid file name
  107.     CALL    SETSRCDST    ; Set source and destination users
  108.     CALL    SETBIOS        ; Copy BIOS jump vector
  109.     RET
  110. ;.....
  111. ;
  112. ;
  113. RDDIR:    CALL    GETDIR        ; Read a directory sector
  114.     RET    Z        ; End or read error
  115.     CALL    CKENT        ; Check entries for file
  116.     JP    RDDIR
  117. ;.....
  118. ;
  119. ;
  120. FINISH:    LD    C,DRESET    ; Reset disk system
  121.     CALL    BDOS
  122.     LD    A,(NOREC)    ; Get number of directory found
  123.     OR    A
  124.     JP    Z,NOTFND    ; Non-found
  125.     LD    A,(SRCUSR)
  126.     CP    0E5H
  127.     JP    Z,RECOVMSG
  128.     LD    DE,CHGMSG
  129.     JP    PRINTMSG
  130. ;.....
  131. ;
  132. ;
  133. RECOVMSG:
  134.     LD    DE,RECMSG
  135. ;
  136. PRINTMSG:
  137.     CALL    PRTMSG        ; Print success message
  138.     RET
  139. ;.....
  140. ;
  141. ;
  142. NOTFND:    LD    DE,FILERR
  143.     CALL    PRTMSG
  144.     RET
  145. ;.....
  146. ;
  147. ;
  148. CKVERS:    LD    C,GETVER    ; Get CP/M version #
  149.     CALL    BDOS
  150.     CP    30H        ; Is it 3.0 or greater
  151.     JP    C,ONLY30    ; This version for CP/M 3.0 and later
  152.     RET
  153. ;.....
  154. ;
  155. ;
  156. CKNAME:    LD    A,(DEFFCB)    ; Get drive for file
  157.     OR    A        ; Use default?
  158.     JP    NZ,NODEF    ; No, convert to FCB format
  159.     LD    C,GETCUR    ; Get current disk
  160.     CALL    BDOS
  161.     INC    A        ; Set up for decrement
  162. ;
  163. NODEF:    DEC    A        ; Convert to FCB format
  164.     LD    (DEFFCB),A    ; Save it
  165.     LD    A,(DEFFCB+1)    ; Check for no file
  166.     CP    ' '+1
  167.     RET    NC        ; Return if ok
  168.     LD    DE,NAMERR    ; Print file error
  169.     CALL    PRTMSG
  170.     JP    WRMBOOT        ; Give up
  171. ;.....
  172. ;
  173. ;
  174. SETSRCDST:
  175.     LD    C,GETUSR    ; Get user #
  176.     LD    E,0FFH        ; Get user flag
  177.     CALL    BDOS
  178.     LD    (CURUSR),A    ; Save user #
  179.     LD    HL,DEFFCB2+1    ; Point to 1st destination char.
  180.     LD    A,' '
  181.     CP    (HL)
  182.     JP    Z,UNERASE    ; Unerase if no destination user #
  183.     LD    B,'0'
  184.     LD    C,(HL)
  185.     INC    HL
  186.     CP    (HL)
  187.     JP    Z,CHGUSR    ; Single digit ASCII user # in 'BC'
  188.     LD    B,C
  189.     LD    C,(HL)
  190.     INC    HL
  191.     CP    (HL)
  192.     JP    NZ,USRERROR    ; Two digit ASCII user # in 'BC' if zero
  193. ;
  194. CHGUSR:    LD    D,0        ; Initial value for high digit
  195.     LD    A,'0'
  196.     CP    B
  197.     JP    Z,CHGUSR1    ; Ok if high digit is '0'
  198.     INC    A        ; A = '1'
  199.     CP    B
  200.     JP    NZ,USRERROR    ; Error if high digit not '0' or '1'
  201.     LD    D,10        ; Value for high digit if '1'
  202. ;
  203. CHGUSR1:LD    A,'0'-1
  204.     CP    C
  205.     JP    NC,USRERROR    ; Error if low digit < '0'
  206.     LD    A,'9'
  207.     CP    C
  208.     JP    C,USRERROR    ; Error if low digit > 9
  209.     LD    A,C
  210.     SBC    A,'0'        ; Make low digit hex
  211.     ADD    A,D
  212.     CP    16
  213.     JP    NC,USRERROR    ; Error if user # > 15
  214.     LD    (DSTUSR),A    ; Destination user # in hex
  215.     LD    A,(CURUSR)
  216.     LD    (SRCUSR),A    ; Source user # is current user #
  217.     RET
  218. ;.....
  219. ;
  220. ;
  221. UNERASE:LD    A,(CURUSR)    ; Place file in current user
  222.     LD    (DSTUSR),A
  223.     LD    A,0E5H        ; 0E5H = erased file "USER #"
  224.     LD    (SRCUSR),A
  225.     RET
  226. ;
  227. USRERROR:
  228.     LD    DE,USRERR
  229.     CALL    PRTMSG
  230.     JP    WRMBOOT
  231. ;.....
  232. ;
  233. ;
  234. ; Set up local BIOS jump vector
  235. ;
  236. SETBIOS:LD    BC,LOCDMA    ; Get default DMA address
  237.     LD    (BCREG),BC
  238.     LD    A,12        ; Set DMA to default
  239.     LD    (FUNC),A
  240.     CALL    CALLBIOS
  241.     CALL    DSKPRM        ; Get disk parameters from BDOS
  242.     LD    A,(DEFFCB)    ; Select drive
  243.     LD    C,A
  244.     LD    B,0
  245.     LD    E,B
  246.     LD    (BCREG),BC    ; BIOS select disk function
  247.     LD    (DEREG),DE
  248.     LD    A,9        ; 'SELDSK'
  249.     LD    (FUNC),A
  250.     CALL    CALLBIOS
  251.     LD    A,H
  252.     OR    L        ; Check for drive error
  253.     JP    Z,NODRV        ; Go report it
  254.     LD    E,(HL)        ; Get DPH address
  255.     INC    HL
  256.     LD    D,(HL)
  257.     EX    DE,HL
  258.     LD    (DPHADD),HL    ; Save address to DPH
  259.     RET
  260. ;.....
  261. ;
  262. ;
  263. DSKPRM:    LD    A,(DEFFCB)
  264.     LD    E,A
  265.     LD    C,14        ; Select disk
  266.     CALL    BDOS
  267.     LD    C,GETPARM    ; Get address of disk parameters
  268.     CALL    BDOS
  269.     LD    E,(HL)        ; Get logical SPT
  270.     INC    HL
  271.     LD    D,(HL)
  272.     LD    (SPT),DE
  273.     LD    DE,6        ; Offset to DRM (# of directory entries)
  274.     ADD    HL,DE        ; Add offset
  275.     LD    E,(HL)        ; Get DRM
  276.     INC    HL
  277.     LD    D,(HL)
  278.     PUSH    DE
  279.     PUSH    HL
  280.     LD    DE,7        ; Point to PSH
  281.     ADD    HL,DE
  282.     LD    A,(HL)        ; Get it
  283.     LD    (PSH),A        ; Save it
  284.     POP    HL
  285.     POP    DE
  286.     EX    DE,HL
  287.     INC    HL        ; Add 1 for total directory entries
  288.     LD    A,(PSH)
  289.     CP    3        ; 1024 byte sectors
  290.     CALL    Z,PSH1024
  291.     LD    A,(PSH)
  292.     CP    2        ; 512 byte sectors
  293.     CALL    Z,PSH512
  294.     LD    A,(PSH)
  295.     CP    1        ; 256 byte sectors
  296.     CALL    Z,PSH256
  297.     LD    A,(PSH)
  298.     OR    A        ; 128 byte sectors
  299.     CALL    Z,PSH128
  300.     LD    A,L        ; Save # of directory sectors
  301.     LD    (DIRSEC),A
  302.     LD    HL,(SPT)    ; Logical sectors per track
  303.     LD    A,(PSH)
  304.     CP    3        ; 1024 byte sectors
  305.     CALL    Z,DIV8
  306.     LD    A,(PSH)
  307.     CP    2        ; 512 byte sectors
  308.     CALL    Z,DIV4
  309.     LD    A,(PSH)
  310.     CP    1        ; 256 byte sectors
  311.     CALL    Z,DIV2
  312.     LD    A,L        ; PHSPT = SPT for 128 byte sectors
  313.     LD    (PHSPT),A    ; Physical sectors per track
  314.     LD    HL,5        ; Add offset to # of reserved tracks
  315.     ADD    HL,DE
  316.     LD    E,(HL)        ; Get number of reserved tracks
  317.     INC    HL
  318.     LD    D,(HL)
  319.     LD    (RESTKS),DE    ; Save reserved tracks for later
  320.     RET
  321. ;.....
  322. ;
  323. ;
  324. ONLY30:    LD    DE,ERR30    ; Print message for CP/M Plus only
  325.     CALL    PRTMSG
  326.     JP    WRMBOOT
  327. ;.....
  328. ;
  329. ;
  330. GETDIR:    LD    A,(DIRSEC)    ; Get # of directory sectors
  331.     OR    A
  332.     RET    Z        ; Return if none
  333.     CALL    PHSECTRK    ; Compute cur. physical sector and track
  334.     LD    BC,(RESTKS)    ; Get number of reserved tracks in 'BC'
  335.     LD    H,0        ; Get physical track number in 'HL'
  336.     LD    A,(PHTRK)
  337.     LD    L,A
  338.     ADD    HL,BC        ; Directory track in 'HL'
  339.     LD    (BCREG),HL    ; Set track to directory
  340.     LD    A,10        ; 'SETTRK'
  341.     LD    (FUNC),A
  342.     CALL    CALLBIOS
  343.     LD    A,(PHSECT)    ; Get current physical sector
  344.     LD    C,A
  345.     CALL    TRNSEC        ; Translate sector if necessary
  346.     LD    B,0
  347.     LD    (BCREG),BC    ; Point to current sector
  348.     LD    A,11        ; 'SETSEC'
  349.     LD    (FUNC),A
  350.     CALL    CALLBIOS
  351.     LD    A,13        ; Read sector of directory
  352.     LD    (FUNC),A
  353.     CALL    CALLBIOS
  354.     AND    1
  355.     XOR    1
  356.     RET
  357. ;.....
  358. ;
  359. ;
  360. CKENT:    XOR    A        ; Zero flag
  361.     LD    (RECFLG),A
  362.     LD    A,(DVD)        ; Get number of dir. entries per sector
  363.     LD    B,A
  364.     LD    HL,LOCDMA
  365. ;
  366. CKNXT:    LD    A,(SRCUSR)
  367.     LD    D,A        ; Source user # in 'D'
  368.     LD    A,(HL)        ; Get byte
  369.     CP    D        ; Check for source user #
  370.     JP    NZ,GETNXT    ; Nope, skip
  371.     PUSH    HL
  372.     CALL    CKFIL        ; Yes check for recovery
  373.     POP    HL
  374. ;
  375. RECENT:    JP    NZ,GETNXT
  376.     LD    A,(DSTUSR)
  377.     LD    (HL),A        ; Recover/change the entry
  378.     LD    A,0FH        ; Set recovered flag
  379.     LD    (RECFLG),A
  380.     LD    A,(NOREC)    ; Increment number of records found
  381.     INC    A
  382.     LD    (NOREC),A
  383. ;
  384. GETNXT:    LD    DE,32        ; Advance to next entry
  385.     ADD    HL,DE
  386.     DEC    B        ; Decrement counter
  387.     JP    NZ,CKNXT
  388.     LD    A,(RECFLG)    ; Check for recovered/changed entry
  389.     OR    A
  390.     JP    Z,LOOP        ; Nope, continue loop
  391. ;
  392. ;
  393. ; Write sector back to disk if file rec/chg
  394. ;
  395.     CALL    PHSECTRK    ; Compute cur. physical sector and track
  396.     LD    BC,(RESTKS)    ; Get number of reserved tracks in 'BC'
  397.     LD    H,0        ; Get physical track number in 'HL'
  398.     LD    A,(PHTRK)
  399.     LD    L,A
  400.     ADD    HL,BC        ; Directory track in 'HL'
  401.     LD    (BCREG),HL    ; Set track to directory
  402.     LD    A,10        ; 'SETTRK'
  403.     LD    (FUNC),A
  404.     CALL    CALLBIOS
  405.     LD    A,(PHSECT)    ; Get current physical sector
  406.     LD    C,A
  407.     CALL    TRNSEC        ; Translate sector
  408.     LD    B,0
  409.     LD    (BCREG),BC    ; Point to current sector
  410.     LD    A,11        ; 'SETSEC'
  411.     LD    (FUNC),A
  412.     CALL    CALLBIOS
  413.     LD    BC,1        ; None deferred write
  414.     LD    (BCREG),BC
  415.     LD    A,14        ; Write
  416.     LD    (FUNC),A
  417.     CALL    CALLBIOS    ; Update directory
  418.     OR    A        ; Check for write error
  419.     JP    NZ,WRTERROR    ; Report error
  420. ;
  421. LOOP:    LD    A,(DIRSEC)    ; Decrement directory sectors
  422.     DEC    A
  423.     LD    (DIRSEC),A
  424.     LD    A,(SECTOR)    ; Increment sector
  425.     INC    A
  426.     LD    (SECTOR),A
  427.     RET
  428. ;.....
  429. ;
  430. ;
  431. CKFIL:    INC    HL        ; Check deleted entry for recovery
  432.     LD    DE,DEFFCB+1    ; Point at file to be recovered
  433.     EX    DE,HL
  434.     LD    C,11        ; Look at 11 characters
  435. ;
  436. CMPFIL:    LD    A,'?'        ; Check to see if spec is ambiguous
  437.     CP    (HL)
  438.     JP    Z,NXTCHR
  439.     LD    A,(DE)        ; Get character in name
  440.     AND    7FH        ; Turn off high bit
  441.     CP    (HL)        ; Are they equal?
  442.     RET    NZ        ; Nope go get another entry
  443. ;
  444. NXTCHR:    INC    DE        ; Yes, continue
  445.     INC    HL
  446.     DEC    C
  447.     JP    NZ,CMPFIL
  448.     RET
  449. ;.....
  450. ;
  451. ;
  452. PSH1024:LD    A,32        ; Set number of dir. entries per sector
  453.     LD    (DVD),A
  454.     JP    DIV32
  455. ;
  456. PSH512:    LD    A,16        ; Set number of dir. entries per sector
  457.     LD    (DVD),A
  458.     JP    DIV16
  459. ;
  460. PSH256:    LD    A,8        ; Set number of dir. entries per sector
  461.     LD    (DVD),A
  462.     JP    DIV8
  463. ;
  464. PSH128:    LD    A,4        ; Set number of dir. entries per sector
  465.     LD    (DVD),A
  466.     JP    DIV4
  467. ;.....
  468. ;
  469. ;
  470. ; Falls through as many "divide by 2" as needed
  471. ;
  472. DIV32:    CALL    DIV2        ; Divide 'HL' by 32
  473. DIV16:    CALL    DIV2        ; Divide 'HL' by 32
  474. DIV8:    CALL    DIV2        ; Divide 'HL' by 32
  475. DIV4:    CALL    DIV2        ; Divide 'HL' by 32
  476. DIV2:    XOR    A        ; Divide 'HL' by 2 routine
  477.     LD    A,H        ; Get high order byte
  478.     RRA            ; Shift right for a divide by 2
  479.     LD    H,A
  480.     LD    A,L        ; Get low order byte
  481.     RRA            ; Shift right for a divide by 2
  482.     LD    L,A
  483.     RET
  484. ;.....
  485. ;
  486. ;
  487. PHSECTRK:
  488.     LD    C,0        ; Set 'PHTRK' to 0
  489.     LD    A,(PHSPT)
  490.     LD    B,A        ; Phys SPT in 'B'
  491.     LD    A,(SECTOR)    ; Logical directory sector
  492. ;
  493. CKPHTRK:CP    B        ; Compute PHSECT = sectors mod PHSPT
  494.     JP    C,STSECTRK    ; And PHTRK = (sectors - PHSECT)/PHSPT
  495.     SUB    B
  496.     INC    C
  497.     JP    CKPHTRK
  498. ;...
  499. ;
  500. ;
  501. STSECTRK:
  502.     LD    (PHSECT),A
  503.     LD    A,C
  504.     LD    (PHTRK),A
  505.     RET
  506. ;.....
  507. ;
  508. ;
  509. PRTMSG:    LD    C,PRINT        ; Print string to console
  510.     JP    BDOS
  511. ;.....
  512. ;
  513. ;
  514. ; Print drive error message
  515. ;
  516. NODRV:    LD    DE,DRVERR
  517.     CALL    PRTMSG
  518.     JP    WRMBOOT
  519. ;.....
  520. ;
  521. ;
  522. ; Print write error message
  523. ;
  524. WRTERROR:
  525.     LD    DE,WRTERR
  526.     CALL    PRTMSG
  527.     JP    WRMBOOT
  528. ;.....
  529. ;
  530. ;
  531. TRNSEC:    LD    HL,(DPHADD)    ; Get translate table address
  532.     EX    DE,HL
  533.     LD    (BCREG),BC
  534.     LD    (DEREG),DE
  535.     LD    A,16        ; 'SECTRAN'
  536.     LD    (FUNC),A
  537.     CALL    CALLBIOS
  538.     LD    C,L
  539.     RET
  540. ;.....
  541. ;
  542. ;
  543. CALLBIOS: ; CP/M v3.0 direct BIOS call
  544.     LD    C,DIRCALL
  545.     LD    DE,FUN50
  546.     CALL    BDOS
  547.     RET
  548. ;.....
  549. ;
  550. ;
  551. ;-----------------------------------------------------------------------
  552. ;
  553. ; Data area
  554. ;
  555. FUN50:
  556. FUNC:    DEFB    0
  557. AREG:    DEFB    0
  558. BCREG:    DEFB    0,0
  559. DEREG:    DEFB    0,0
  560. HLREG:    DEFB    0,0
  561. ;
  562. DPHADD:    DEFB    0,0
  563. DIRSEC:    DEFB    0
  564. RESTKS:    DEFB    0,0
  565. SECTOR:    DEFB    0
  566. NOREC:    DEFB    0
  567. RECFLG:    DEFB    0
  568. PSH:    DEFB    0
  569. DVD:    DEFB    0
  570. CURUSR:    DEFB    0
  571. SPT:    DEFB    0,0
  572. PHSPT:    DEFB    0
  573. PHSECT:    DEFB    0
  574. PHTRK:    DEFB    0
  575. SRCUSR:    DEFB    0
  576. DSTUSR:    DEFB    0
  577. ;.....
  578. ;
  579. ;
  580. ; Messages
  581. ;
  582. WRTERR:    DEFB    CR,LF,'Error occurred during disk Write - ABORT','$'
  583. DRVERR:    DEFB    CR,LF,'Specified an illegal disk drive - ABORT','$'
  584. RECMSG:    DEFB    CR,LF,'File recovered','$'
  585. CHGMSG:    DEFB    CR,LF,'File user area changed','$'
  586. NAMERR:    DEFB    CR,LF,'No File Name specified - ABORT','$'
  587. FILERR:    DEFB    CR,LF,'File NOT found','$'
  588. USRERR:    DEFB    CR,LF,'Invalid User Number - ABORT','$'
  589. ERR30:    DEFB    CR,LF,'+++ UN3 ONLY WORKS FOR CP/M V3.0 OR LATER +++'
  590.     DEFB    CR,LF,'$'
  591. ;.....
  592. ;
  593. ;
  594. ; Buffer area
  595. ;
  596. LOCDMA:    DEFS    1024        ; Local DMA buffer
  597. ;
  598. ;
  599.     END
  600.