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 / UNERA31.ARC / UNERA31.A86 next >
Text File  |  1991-10-05  |  19KB  |  765 lines

  1. ; DATE 02/16/84  16:16       last update
  2. ; 02/16/84 the program has been converted to support both CP/M-86 ver 3.1
  3. ; and CCP/M-86 ver 3.1.
  4. ; MP/M is not supported but only because I don't have a way to test this
  5. ; version on the MPM operating system.
  6.  
  7.     TITLE    'UNERA     FOR CP/M-86 VER3.1'
  8.  
  9. ; UNERA31.A86
  10. ; by: H.H. Van Tassell, 120 Hill Hollow Rd, Watchung NJ  07060 (201)755-5272
  11. ;
  12. ; This is a program to recover erased files in CP/M-86 and is modelled on the
  13. ; UNERA program for CP/M-80 on SIG/M volume 76. See volumes 76 and 44 for 
  14. ; author credits and more information.
  15. ; The program reads the directory, sector by sector, listing filenames that
  16. ; have been erase by placing an 0E5H as byte 0. The extent number is also
  17. ; listed. NO check is made to determine if the disk space has been re-allocated
  18. ; to another file after the file was erased. After listing the file names, the 
  19. ; user is asked if recovery is desired. A page of help is displayed if the
  20. ; program is invoked with // as the file name.
  21.  
  22. ; The direct BIOS disk call data structure was choosen for conversion to 
  23. ; CP/M-86 versions 3.0 and higher (CONCURRENT and PLUS).
  24. ;
  25. ; TO GENERATE PROGRAM:
  26. ;    RASM86 UNERA $SZPZ
  27. ;    LINK86 UNERA [data[add [100]]]
  28. ;
  29.  
  30. ;
  31. SLINES    EQU    22            ;LINES ON CONSOLE LESS 2
  32.  
  33. FALSE    EQU    0
  34. TRUE    EQU    NOT FALSE
  35.  
  36. CR    EQU    13
  37. LF    EQU    10
  38. TAB    EQU    9
  39.  
  40. CONIN    EQU    1        ;READ CONSOLE
  41. DCONIN    EQU    6        ;DIRECT CONSOLE READ
  42. RESET    EQU    13        ;SYSTEM RESET
  43. SELDSK    EQU    14        ;SELECT DISK
  44. GETDR    EQU    25        ;GET DRIVE
  45. DIRBIOS    EQU    50        ;DIRECT BIOS CALLS
  46.  
  47. ; DIRECT BIOS CALL PARAMETER BLOCK DATA STRUCTURE
  48. ;
  49. BPB_FUNC EQU    BYTE PTR 0[BX]
  50. BPB_CX     EQU    WORD PTR 1[BX]
  51. BPB_DX     EQU    WORD PTR 3[BX]
  52.  
  53. ; DISK BIOS CALLS DATA STRUCTURE
  54. ;
  55. SELECT_DISK    EQU  WORD PTR 0[BX]
  56. SET_TRACK    EQU  WORD PTR 2[BX]
  57. SET_DMASEG    EQU  WORD PTR 4[BX]
  58. SET_DMAOFF    EQU  WORD PTR 6[BX]
  59. SET_SECTOR    EQU  WORD PTR 8[BX]
  60. READ_SECTOR    EQU  WORD PTR 10[BX]
  61. WRITE_SECTOR    EQU  WORD PTR 12[BX]
  62. SECTOR_XLAT    EQU  WORD PTR 14[BX]
  63.  
  64.  
  65. TBUF    EQU    80H        ;TRANSIT DEFAULT BUFFER
  66. FCB    EQU    5CH        ;DEFAULT FILE CONTROL BLOCK
  67.                                     
  68. DRV_DPB        equ    31    ;BDOS call 31
  69.  
  70.  
  71. BIO_SELDSK     equ    9        ;BIOS function number
  72. BIO_READ      equ    10        ;BIOS function number
  73. BIO_WRITE      equ    11        ;BIOS function number
  74.  
  75. ; PARTIAL DATA STRUCTURE OF DPH
  76. ;
  77. LOG_SEQN    equ    byte ptr 6    ;to force reset of permanent media
  78. DPB_PTR31    equ    word ptr 8    ;offset of DPB pointer in DPH (v3.1)
  79. DPB_PTR11    equ    word ptr 10    ;offset in version 1.1
  80. DPB_SIZE    equ    17        ;size of Disk Parameter Block
  81.  
  82.  
  83. ; DPB DATA STRUCTURE 
  84. ;
  85. SPT        equ    word ptr 0[bx]
  86. BSH        equ    byte ptr 2[bx]
  87. BLM        equ    byte ptr 3[bx]
  88. EXM        equ    byte ptr 4[bx]
  89. DSM        equ    word ptr 5[bx]
  90. DRM        equ    word ptr 7[bx]
  91. AL0        equ    byte ptr 9[bx]
  92. AL1        equ    byte ptr 10[bx]
  93. CKS        equ    word ptr 11[bx]
  94. OFF        equ    word ptr 13[bx]
  95. PHYSHF        equ    byte ptr 15[bx]
  96. PHYMSK        equ    byte ptr 16[bx]
  97.  
  98.  
  99. BIOS_PTR      equ    dword ptr .28h    ;loc of BIOS entry in SYSDAT
  100. UDA_SEG          equ    word ptr .4eh    ;loc of UDA seg in system data area
  101.  
  102. ;------- for CCP/M -3.1 ----------------
  103. S_SYSDAT    equ    154        ;get system data area
  104. P_PDADR        equ    156        ;get PDA address
  105.  
  106. CCPM_31    equ    1431h            ;CCP/M-86 version number
  107.  
  108. P_UDA        equ    word ptr 10h    ;User Data Area
  109. ;-----------------------------------------
  110.  
  111.  
  112.     CSEG
  113.  
  114.     MOV    CX,DS        ;USING DATA SEGMENT
  115.     MOV    SS,CX        ;SET UP LOCAL STACK
  116.     LEA    SP,STACK    
  117.  
  118.     CALL    HELLO
  119.     CALL    PCHECK
  120.     CALL    TRYFIX
  121.     CMP    FIXCNT,0    ;WERE ANY FIXABLE FILES FOUND?
  122.     JZ    NO_RECOVER
  123.     CALL    RECOVER        ;YES, GO RECOVER EM
  124. NO_RECOVER:
  125.     CALL    BYE
  126. EXIT:
  127.     MOV    CL,SELDSK            ;RETURN TO CURRENT DISK
  128.     MOV    DL,BYTE PTR CURDR
  129.     INT    224
  130.     MOV    CL,RESET            ;RESET SYSTEM
  131.     INT    224
  132. QUIT:
  133.     MOV    CL,0
  134.     MOV    DL,0
  135.     INT    224
  136.  
  137. ; SAY WHO WE ARE
  138. HELLO:
  139.     MOV    DX,OFFSET HMSG            ;POINT TO HELLO MESSAGE
  140.     CALL    PRINT
  141.     RET
  142.  
  143. ; CHECK FOR VALID PARAMETERS
  144. PCHECK:
  145.     CALL    FCBCHK            ;MAKE SURE FILE IS SPECIFIED
  146.     CALL    CPMCHK            ;CHECK CP/M VERSION
  147.     RET
  148.  
  149. ; ASK IF THEY WANT TO RECOVER THE REVIEWED FILES
  150. RECOVER:
  151.     MOV    DX,OFFSET RVMSG        ;ASK IF RECOVERY WANTED
  152.     CALL    PRINT
  153.     MOV    CL,CONIN        ;GET ANSWER
  154.     INT    224
  155.     AND    AL,5FH            ;MAKE UPPER CASE
  156.     CMP    AL,'Y'
  157.     JNE    EXIT            ;EXIT UNLESS YES
  158.     MOV    VIEW_EM,0        ;RESET THE VIEW FLAG
  159.     MOV    FIX_EM,0FFH        ;SET THE FIX EM FLAG
  160.     MOV    AL,BYTE PTR MAXSEC    ;RESTORE MAXDIR
  161.     MOV    BYTE PTR MAXDIR,AL
  162.     MOV    SECTOR,0        ;SECTOR 
  163.     MOV    FIXCNT,0        ;AND FIXCOUNT
  164.     CALL    TRYFIX            ;AND FIXEM
  165.     RET
  166.  
  167. ; LOOK THROUGH THE DIRECTORY TRYING TO MATCH FCB FILENAME
  168. TRYFIX:
  169.     CALL    NXTSECT            ;GET A DIRECTORY SECTOR
  170.     JNZ    TRY_MORE        ;RETURNS ZERO SET IF NO MORE
  171.     RET
  172. TRY_MORE:
  173.     CALL    CHKENT            ;CHECK IT OUT AND MAYBE FIX
  174.     JMPS    TRYFIX            ;KEEP IT UP TILL DONE
  175.  
  176. ; SIGN OFF 
  177. BYE:
  178.     CMP    FIXCNT,0        ;CHECK FOR ACTIVITY    
  179.     JE    NOFIND
  180.     MOV    DX,OFFSET BMSG        ;WARN EM
  181.     CALL    PRINT
  182.     RET
  183. NOFIND:
  184.     MOV    DX,OFFSET NFMSG        ;SAY NOTHING FOUND
  185.     CALL    PRINT
  186.     RET
  187.  
  188. ; MAKE SURE A LEGAL FILENAME WAS FOUND
  189. FCBCHK:
  190.  
  191. ; scans tbuffer at 80h for a / as indication of help wanted
  192. ; returns with ZF set if '/' is found in buffer
  193. ;
  194.     push es ! push ds ! pop es    ;save ES, ES=DS
  195.     xor    cx,cx
  196.     mov    di,80h            ;point to tbuffer @ 80h
  197.     mov    cl,byte ptr[di]        ;CX=length of tbuf string
  198.     inc    cx
  199.     mov    al,'/'
  200.     repnz    scasb            ;scan for /
  201.     pop    es            ;ZF set if help signal
  202.     jz    help
  203.  
  204.     CMP    BYTE PTR .FCB+1,' '    ;IS 1ST BYTE A NON BLANK
  205.     JBE    NO_NAME
  206.  
  207.  
  208.     MOV    CL,GETDR        ;GET CURRENT DRIVE
  209.     INT    224
  210.     MOV    BYTE PTR CURDR,AL    ;SAVE IT
  211.  
  212.     MOV    AL,BYTE PTR .FCB    ;SEE IF DEFAULT DRIVE SPEC
  213.     CMP    AL,0
  214.     JZ    DEFAULT            ;YES, NO DEC
  215.     DEC    AL            ;ELSE DEC IT
  216.     PUSH    AX
  217.     MOV    CL,SELDSK        ;SELECT DISK
  218.     MOV    DL,AL
  219.     INT    224
  220.     POP    AX
  221.     JMPS    NOT_DEFAULT
  222. DEFAULT:
  223.     MOV    AL,CURDR
  224. NOT_DEFAULT:
  225.     MOV    BYTE PTR .FCB,AL    ;PUT IT BACK AND
  226.     MOV    DRIVE,AL
  227.  
  228.     ADD    AL,'A'            ;MAKE IT ASCII
  229.     MOV    BYTE PTR FILNAM0,AL    ;AND PUT IT IN FILNAM DATA
  230.     RET
  231. NO_NAME:
  232.     MOV    DX,OFFSET NOFMSG    ;CANT FIND A FILE NAME
  233.     CALL    PRINT
  234.     JMP    QUIT
  235.  
  236. ; GIVE EM SOME HELP AND QUIT
  237. HELP:
  238.     MOV    DX,OFFSET HLPMSG
  239.     CALL     PRINT
  240.     JMP    QUIT
  241.  
  242. IS_MPM:
  243.     MOV    DX,OFFSET MPMSG
  244.     CALL    PRINT
  245.     JMP    EXIT
  246.  
  247. UNK_VER:
  248.     MOV    DX,OFFSET WVMSG
  249.     CALL    PRINT
  250.     JMP    EXIT
  251.  
  252. ; CHECKS CPM VERSION AND INITIALIZES THINGS
  253. CPMCHK:
  254.     MOV    CL,12            ;GET VERSION NUMBER
  255.     INT    224
  256.     MOV    CPM_VERSION,AX        ;SAVE IT
  257.     TEST    AH,01H            ;IS IT MP/M ?
  258.     JNZ     IS_MPM
  259.     CMP    AL,22H            ;IS IT VERSION 11
  260.     JE    VER_11
  261.     CMP    AL,31H            ;IS IT VERSION 31
  262.     JE    VER_31
  263.     JMP    UNK_VER            ;UNKNOWN VERSION
  264.  
  265. VER_11:
  266.     MOV    CALL_TBL,OFFSET TABLE11
  267.     JMPS    VER_OK
  268. VER_31:
  269.     MOV    CALL_TBL,OFFSET TABLE31
  270. VER_OK:
  271.     MOV    CL,BYTE PTR .FCB    ;GET DRIVE
  272.     XOR    CH,CH
  273.     XOR    DX,DX            ;FIRST SELECTION
  274.     MOV    BX,CALL_TBL
  275.     CALL    SELECT_DISK        ;SELECT DISK
  276.     CMP    BX,0            ;IS DISK OK
  277.     JNZ    DISKOK            ;TELL IF NOT OK
  278.     CALL    ILDISK
  279. DISKOK:                    ;A CALL TO DISK SELECT COPYS
  280.     CMP    BYTE PTR CPM_VERSION,31H ! JE SETUP31
  281. SETUP11:
  282.     MOV    AX,ES:WORD PTR [BX]    ;XLAT TABLE ADDRESS IN BX
  283.     MOV    XLAT_ADR,AX
  284.     MOV    CL,31            ;GET DISK PARAMETERS
  285.     INT    224
  286.     MOV    AX,ES:WORD PTR 13[BX]    ;GET DIRECTORY TRACK
  287.     MOV    DX,ES:WORD PTR 7[BX]    ;DX=DRM
  288.     MOV    CL,2            ;SHIFT RIGHT TWICE
  289.     JMPS    COM_SETUP
  290. SETUP31:
  291.     MOV    BX,OFFSET DPB        ;THE DPB TO LOCAL STORAGE
  292.     MOV    AX,SPT
  293.     MOV    SEC_PER_TRK,AX
  294.     MOV    AL,4
  295.     MOV    CL,PHYSHF        ;GET PHYSICAL SHIFT
  296.     CMP    CL,0 ! JZ SSSD        ;PHYSHF IS ZERO FOR SSSD
  297.     SHL    AL,CL            ;SHIFT LEFT ? TIMES GIVES
  298. SSSD:
  299.     MOV    DIR_PER_SEC,AL        ;NUMBER DIR ENTRYS/SECTOR
  300.  
  301.     MOV    AX,OFF            ;GET DIRECTORY TRACK
  302.     MOV    DX,DRM            ;GET NUMBER OF DIR ENTRYS-1
  303.     MOV    CL,PHYSHF
  304.     ADD    CL,2            
  305. COM_SETUP:
  306.     INC    DX            ;ACCOUNT FOR -1
  307.     SHR    DX,CL            ;SHIFT RIGHT ? TIMES = SECTORS
  308.     MOV    MAXDIR,DX        ;SAVE NUMBER OF DIR SECTORS
  309.     MOV    MAXSEC,DX
  310.  
  311.     MOV    TRACK,AX        ;SAVE DIRECTORY TRACK
  312.     MOV    SECTOR,0        ;ZERO SECTOR COUNT
  313.     MOV    FIXCNT,0
  314.  
  315.     MOV    CX,DS
  316.     MOV    DMASEG,CX
  317.     MOV    BX,CALL_TBL
  318.     CALL    SET_DMASEG        ;SET DMA SEGMENT TO DATA SEG
  319.     MOV    CX,DMAOFF
  320.     MOV    BX,CALL_TBL
  321.     CALL    SET_DMAOFF        ;SET DMA TO DIR_BUF
  322.     RET
  323.  
  324. ; READS NEXT SECTOR (GROUP OF DIRECTORY ENTRIES)
  325. ; RETURN WITH ZERO SET IF NO MORE
  326. NXTSECT:
  327.     CMP    MAXDIR,0
  328.     JNZ    DO_SECT
  329.     RET                ;RET WITH ZERO SET
  330. DO_SECT:
  331.     MOV    CX,TRACK        ;SET TRACK
  332.     MOV    BX,CALL_TBL
  333.     CALL    SET_TRACK
  334.     MOV    CX,SECTOR
  335.     MOV    BX,CALL_TBL
  336.     CALL    SECTOR_XLAT        ;RETURNS XLATED SECT IN BX
  337.     MOV    CX,BX
  338.     MOV    BX,CALL_TBL
  339.     CALL    SET_SECTOR
  340.     MOV    BX,CALL_TBL
  341.     CALL    READ_SECTOR
  342.     AND    AL,1            ;REVERSE SENSE OF ERROR FLAG
  343.     XOR    AL,1            ;RETURN WITH ZERO SET IF BAD READ
  344.     RET                
  345.  
  346. ; CHECK THE CURRENT GROUP DIRECTORY ENTRIES AGAINST ARGUMENT
  347. ; IF MATCH, REWRITE SECTOR WITH REACTIVATED FIRST BYTE
  348. CHKENT:
  349.     MOV    REWRT,0            ;ASSUME NO REWRITE
  350.     MOV    CL,DIR_PER_SEC        ;# ENTRIES TO CHECK
  351.     MOV    BX,OFFSET DIR_BUF    ;THIS IS WHERE THEY ARE AT...
  352. CKLOOP:
  353.     CMP    BYTE PTR [BX],0E5H    ;IS IT UNUSED?
  354.     JNE     CKINC            ;NO, GO DO ANOTHER    
  355.     CMP    BYTE PTR 1[BX],0E5H    ;IF THIS IS AN E5 THEN ITS
  356.     JE    CKINC            ;...NOT A DIR NAME    
  357.     CMP    BYTE PTR 1[BX],00H    ;IF THIS IS AN 00 THEN ITS
  358.     JE    CKINC            ;...NOT A DIR NAME    
  359.     PUSH    BX
  360.     CALL    COMPAR            ;COMPARE WITH ARGUMENT
  361.     POP    BX
  362.     JNZ    CKINC            ;JMP IF ZERO NOT SET, NO MATCH
  363.     CMP    FIX_EM,0FFH        ;SHOULD WE FIX EM?
  364.     JNE    NO_FIX
  365.     MOV    BYTE PTR [BX],0        ;ELSE, REACTIVATE IT
  366.     MOV    REWRT,0FFH        ;SET REWRITE FLAG
  367. NO_FIX:
  368.     INC    FIXCNT            ;BUMP FIX COUNTER
  369.     CMP    VIEW_EM,0FFH        ;IS THE VIEW FLAG SET?
  370.     JNE    CKINC            ;NO,JMP OVER THE SHOW-OFF
  371.     PUSH    BX
  372.     CALL    SHOWIT            ;ELSE, TELL EM HOW GOOD YOU ARE
  373.     POP    BX
  374. CKINC:                    ;DO ANOTHER ENTRY    
  375.     ADD    BX,32
  376.     DEC    CL            ;ONE LESS TO DO    
  377.     JNZ    CKLOOP            ;GO DO IT
  378.     CMP    REWRT,0            ;NEED REWRITE 
  379.     JZ    CKDONE            ;NO, THEN DONE WITH CHECK
  380.  
  381. ; WRITE DIRECTORY ENTRY BACK TO THE DISK
  382.     MOV    CX,TRACK        ;SET TRACK
  383.     MOV    BX,CALL_TBL
  384.     CALL    SET_TRACK
  385.     MOV    CX,SECTOR
  386.     MOV    BX,CALL_TBL
  387.     CALL    SECTOR_XLAT        ;RETURNS XLATED SECT IN BX
  388.     MOV    CX,BX
  389.     MOV    BX,CALL_TBL
  390.     CALL    SET_SECTOR
  391.     MOV    BX,CALL_TBL
  392.     CALL    WRITE_SECTOR
  393.     CMP    AL,0    
  394.     JZ    CKDONE
  395.     JMP    ERRWRT            ;WOOPS
  396. CKDONE:
  397.     DEC    MAXDIR            ;REDUCE SECTORS LEFT
  398.     INC    SECTOR            ;BUMP TO NEXT SECTOR
  399.     RET
  400.  
  401. ; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT
  402. ; RETURN WITH ZERO FLAG SET IF MATCH IS MADE
  403. COMPAR:
  404.     MOV    CL,11            ;COMP 11 CHARS.
  405.     INC    BX            ;BX POINTS TO DIR ENTRY
  406.     MOV    SI,FCB+1        ;SI POINT TO FCB ARGUMENT
  407. CPLOOP:
  408.     MOV    AL,[BX]            ;GET DIR CHAR
  409.     AND    AL,7FH            ;STRIP PARITY
  410.     CMP    [SI],AL            ;ARE FCB & DIR ENTRY THE SAME?
  411.     JE    DO_MORE
  412.     CMP    BYTE PTR[SI],'?'    ;IF FCB IS A ?, ANY THING GOES
  413.     JE    DO_MORE
  414.     RET                ;RETURN ZERO NOT SET IF NOT SAME
  415. DO_MORE:
  416.     INC    BX
  417.     INC    SI
  418.     DEC    CL
  419.     JNZ    CPLOOP            ;LOOP FOR 11 CHARS.
  420.     RET                ;RET WITH ZERO SET IF SAME
  421.  
  422. ; MOVE FILE NAME TO DATA AREA AND SHOW IT ON CONSOLE
  423. ; ENTRY BX POINTS TO NAME-1 IN DIR_BUF
  424. SHOWIT:
  425.     PUSH    DS            ;MAKE SURE ES IS CORRECT
  426.     POP    ES
  427.     MOV    SI,BX            ;POINT TO FILE NAME
  428.     INC    SI            ;NOW ITS CORRECT
  429.     MOV    DI,OFFSET FILNAM1    ;PUT IT THERE
  430.     MOV    CX,8            ;FIRST MOVE NAME
  431.     CALL    MOVEIT            ;USE ROUTINE TO STRIP HI BIT
  432.     INC    DI            ;JUMP OVER DOT
  433.     MOV    CX,3            ;MOVE TYPE
  434.     CALL    MOVEIT
  435.     MOV    AL,[SI]            ;GET EXTENT
  436.     ADD    AL,'0'            ;MAKE IT ASCII
  437.     MOV    BYTE PTR FILNAM2,AL    ;PUT IN AWAY
  438.     MOV    DX,OFFSET FILNAM    ;GET READY TO PRINT
  439.     CMP    FIXCNT,1        ;IS IT THE FIRST RECOVERY?
  440.     JNE    NOT_FIRST
  441.     MOV    DX,OFFSET RCMSG        ;GIVE PRAMBLE
  442. NOT_FIRST:
  443.     CALL    PRINT
  444.     INC    LINES            ;BUMP LINE COUNT
  445.     CMP    LINES,SLINES
  446.     JB    NO_WAIT
  447.     CALL    WAIT
  448. NO_WAIT:
  449.     RET
  450.  
  451. ; MOVE CX BYTES FROM DS:SI TO ES:DI AND STRIP HI BIT
  452. MOVEIT: MOV     AL,[SI]
  453.     AND    AL,7FH
  454.     MOV    ES:[DI],AL
  455.     INC DI ! INC SI
  456.     LOOP    MOVEIT
  457.     RET
  458.  
  459. ; PRINT MESSAGE POINTED TO BY DX, terminated with either a 0 
  460. PRINT:    MOV    BX,DX
  461. PRN_LP:    MOV    DL,[BX]
  462.     CMP    DL,0 ! JE PRN_RET
  463.     INC    BX
  464.     MOV    CL,2
  465.     PUSH    BX
  466.     INT    224
  467.     POP    BX
  468.     JMPS    PRN_LP
  469. PRN_RET: RET
  470.  
  471. ; SPECIFIED ILLEGAL DISK
  472. ILDISK:
  473.     MOV    DX,OFFSET ILMSG
  474.     CALL    PRINT
  475.     JMP    EXIT
  476.  
  477. ; ERROR ON DISK WRITE
  478. ERRWRT:
  479.     MOV    DX,OFFSET WMSG
  480.     CALL    PRINT
  481.     JMP    EXIT
  482.  
  483. ; DISPLAY WAIT MESSAGE AND WAIT FOR KEY PRESS
  484. WAIT:
  485.     MOV    DX,OFFSET WTMSG0
  486.     CALL    PRINT
  487.     CALL    KEYPRESS
  488.     MOV    DX,OFFSET WTMSG1
  489.     CALL    PRINT
  490.     MOV    LINES,0
  491.     RET
  492.  
  493. ; WAIT FOR A KEY PRESS AND RETURN IT IN AL
  494. KEYPRESS:
  495.     MOV    CL,DCONIN        ;DIRECT CONSOLE IO
  496.     MOV    DL,0FFH            ;REQUEST AN INPUT CHECK
  497.     INT    224
  498.     CMP    AL,0
  499.     JE    KEYPRESS
  500.     RET
  501.  
  502. ; DIRECT BIOS CALL FOR CP/M-86 VERSION 1.1
  503. ;
  504. SELECT_DISK11:
  505.     MOV    AL,9            ;BIOS FUCN 9
  506.     JMPS    BIOS            ;RETURNS DPH ADDR IN ES:BX
  507. SET_TRACK11:
  508.     MOV    AL,10
  509.     JMPS    BIOS
  510. SET_DMASEG11:
  511.     MOV    AL,17
  512.     JMPS    BIOS
  513. SET_DMAOFF11:
  514.     MOV    AL,12
  515.     JMPS    BIOS
  516. SET_SECTOR11:
  517.     MOV    AL,11
  518.     JMPS    BIOS
  519. READ_SECTOR11:
  520.     MOV    AL,13
  521.     JMPS    BIOS
  522. WRITE_SECTOR11:
  523.     MOV    AL,14
  524.     JMPS    BIOS
  525. SECTOR_XLAT11:
  526.     MOV    AL,16
  527.     MOV    DX,XLAT_ADR        ;RETURN XLATED SECTOR IN BX
  528.     JMPS    BIOS
  529. BIOS:
  530.     MOV    BX,OFFSET BPB        ;FILL IN BIOS PARAMETER BLOCK
  531.     MOV    BPB_FUNC,AL
  532.     MOV    BPB_CX,CX
  533.     MOV    BPB_DX,DX
  534.     MOV    CL,DIRBIOS        ;BDOS FUNC 50
  535.     MOV    DX,BX
  536.     INT    224            ;CALL IT
  537.     RET
  538.  
  539.  
  540.  
  541. ; DIRECT BIOS CALLS FOR CP/M-86 VERSION 3.1
  542. ;
  543. SET_SECTOR31:
  544.     mov    sector,cx
  545.     ret
  546.  
  547. SET_TRACK31:
  548.     mov    track,cx
  549.     ret
  550.  
  551. SECTOR_XLAT31:
  552.     mov    bx,cx
  553.     ret
  554.  
  555. SET_DMASEG31:            ;DMA IS SET IN CPMCHK ROUTINE
  556. SET_DMAOFF31:
  557.         ret
  558.  
  559. ;++++++++++++++++++++++++++++++++++++++
  560. SELECT_DISK31:    ;selects a drive
  561. ;------
  562. ; resets login sequence number of drive to 0, to force
  563. ; permanent media to be logged in again on disk reset
  564. ;    Entry:    CL = drive to select
  565. ;        DL = 0 if initial select, else 1
  566.  
  567.     push es ! push ds        ;save context
  568.     push cx                ;save drive
  569.     call getsu            ;set up DS and ES
  570.     pop cx                ;restore drive
  571.     mov ax,BIO_SELDSK        ;do the BIOS SELDSK call
  572.     callf BIOS_ptr            ;call indirect BIOS
  573.     mov LOG_SEQN[bx],0        ;force disk reset: 0 login sequence no.
  574.  
  575.     pop es ! push es        ;get DS into ES
  576.     mov di,offset dpb        ;setup dest of dpb
  577.     mov si,DPB_PTR31[bx]        ;get the info from DPH
  578.     mov cx,DPB_SIZE
  579.     rep movsb            ;copy DPB into local storage
  580.     pop ds ! pop es            ;restore context
  581.     ret
  582.  
  583. READ_SECTOR31:    ;reads a physical sector
  584. ;----
  585.     mov bx,BIO_READ
  586.     jmp biosiopb
  587.  
  588. WRITE_SECTOR31:    ;writes a physical sector
  589. ;-----
  590.     mov bx,BIO_WRITE
  591.  
  592. biosiopb:    ;put the IOPB on the stack, call BIOS
  593.     push ds                ;ds will contain SYSDAT seg
  594.     push es                ;es will contain UDA seg
  595.                     ;push iopb onto stack
  596.     mov ah,mcnt
  597.     mov al,drive
  598.     push ax                ;drive and multi-sector count
  599.     push track            ;track #
  600.     push sector            ;sector # = 0
  601.     push dmaseg            ;track buffer DMA segment
  602.     push dmaoff            ;track buffer DMA offset = 0
  603.  
  604.     call getsu            ;set up DS-SYSDAT and ES-UDA
  605.     mov ax,bx            ;set I/O function into AX
  606.     callf BIOS_ptr            ;call indirect the BIOS
  607.                     ;AL,BL = return status
  608.     add sp,10            ;restore stack
  609.     pop es                ;restore original ES
  610.     pop ds                ;ditto for DS
  611.     ret
  612.  
  613. ;======
  614. GETSU:    
  615. ;======
  616.     CMP     CPM_VERSION,CCPM_31    ;IS IT CCP/M?
  617.     JNE    GETSU10
  618. getsu14:        ;get sysdat and uda addrs for CCP/M ver 1431
  619. ;-----
  620. ;    entry:    DS = local data seg
  621. ;    exit:    DS = SYSDAT seg, ES=UDA seg (for call to XIOS)
  622.  
  623.     mov ax,udaaddr            ;get the saved value
  624.     or ax,ax            ;set flags
  625.     jz getsu14a            ;uninitialized, go do the OS call
  626.       mov es,ax            ;we've been here before, just load regs
  627.       mov ds,sysaddr
  628.       ret
  629. getsu14a:
  630.     mov cl,S_SYSDAT            ;will return system data seg in ES
  631.     int 224 
  632.     mov sysaddr,es            ;save system data segment
  633.  
  634.     mov cl,P_PDADR            ;will return PDA address in BX
  635.     int 224
  636. ;    mov pdaddr,bx            ;and save it
  637.     mov ax,es:P_UDA[bx]        ;grab UDA_seg
  638.     mov udaaddr,ax            ;save for future calls
  639.     push ax                ;save uda_seg
  640.     mov ds,sysaddr
  641.     pop es                ;restore uda_seg
  642.     ret
  643.  
  644. ;----------------
  645. getsu10:    ;get sysdat and uda addrs
  646. ;-----
  647. ;    entry:    DS = local data seg
  648. ;    exit:    DS = SYSDAT seg, ES=UDA seg (for call to BIOS)
  649.  
  650.     mov ax,udaaddr            ;get the saved value
  651.     or ax,ax            ;set flags
  652.     jz getsu10a            ;uninitialized, go do the OS call
  653.       mov es,ax            ;we've been here before, just load regs
  654.       mov ds,sysaddr
  655.       ret
  656. getsu10a:
  657.     mov cl,DRV_DPB            ;will return segment of SYSDAT in ES
  658.     int 224
  659.     mov ax,es:UDA_seg        ;grab UDA_seg
  660.     mov udaaddr,ax            ;save for future calls
  661.     push ax                ;save uda_seg
  662.     mov ax,es
  663.     mov sysaddr,ax            ;save for future calls
  664.     mov ds,ax
  665.     pop es                ;restore uda_seg
  666.     ret
  667.  
  668. ; ***** DATA STORAGE AREA*****************
  669.     DSEG
  670.  
  671.  
  672. HLPMSG    DB    CR,LF,LF
  673.     DB    'USAGE: A>UNERA Dr:FILENAME.TYP',CR,LF,LF
  674.     DB    TAB,'Filename and/or type may be wildcards.',CR,LF
  675.     DB    TAB,'Wildcards may be either ? or *',CR,LF,LF
  676.     DB    TAB,'CAUTION! use the * wildcard with care.',CR,LF
  677.     DB    TAB,'Using *.* will recover ALL erased filenames.',CR,LF,LF
  678.     DB    TAB,'The recoverable file(s) matching the FILNAME.TYP',CR,LF
  679.     DB    TAB,'will be listed, you then have an option to quit.',CR,LF,LF
  680.     DB    TAB,'Be SURE to check recovered files before using to',CR,LF
  681.     DB    TAB,'confirm that they are OK and function properly.',CR,LF
  682.     DB    TAB,'If possible, make a CRC check on recovered files.',CR,LF,LF
  683.     DB    TAB,'HINT: for best results use UNERA immediately after',CR,LF
  684.     DB    TAB,'making an unwanted erasure, else the space may be',CR,LF
  685.     DB    TAB,'re-allocated to another file and recovery is impossible.'
  686.     DB    CR,LF,0
  687.  
  688. HMSG    DB    CR,LF,'UNERA ver 3.1 (2-16-84) for CP/M-86, CP/M-86+ & CCP/M-86   // for HELP',0
  689. WMSG    DB    CR,LF,'ERROR OCCURED DURING DISK WRITE - ABORTED',0
  690. ILMSG    DB    CR,LF,'SPECIFIED AN ILLEGAL DISK DRIVE - ABORTED',0
  691. BMSG    DB    CR,LF,'PLEASE! check recovered files before using them',0
  692. NOFMSG    DB    CR,LF,'NO FILE NAME SPECIFIED - ABORTED',0
  693. NFMSG    DB    CR,LF,'FILE NOT FOUND',0
  694. WVMSG    DB    CR,LF,'Only CP/M-86 ver 1.1 & 3.1 Plus and CCP/M ver 3.1 are Supported',0
  695. MPMSG    DB    CR,LF,'THE MP/M OPERATING SYSTEM IS NOT SUPPORTED',0
  696. RVMSG    DB    CR,LF,'Do you wish to recover the File(s) (Y/N)? ',0
  697. WTMSG0    DB    CR,LF,'  Press any key to continue ',0
  698. WTMSG1    DB    CR,'                             ',CR,0
  699.  
  700.  
  701. RCMSG    DB    CR,LF,LF,'Recovered File(s) will be on '
  702. FILNAM0    DB    'X: User 0'
  703. FILNAM    DB    CR,LF
  704. FILNAM1    DB    'FILENAME.TYP - Extent # '
  705. FILNAM2    DB    'X',0
  706.  
  707.  
  708. TABLE11    DW    OFFSET SELECT_DISK11    ;DIRECT BIOS CALLS FOR CP/M-11
  709.     DW    OFFSET SET_TRACK11
  710.     DW    OFFSET SET_DMASEG11
  711.     DW    OFFSET SET_DMAOFF11    
  712.     DW    OFFSET SET_SECTOR11
  713.     DW    OFFSET READ_SECTOR11    
  714.     DW    OFFSET WRITE_SECTOR11      
  715.     DW    OFFSET SECTOR_XLAT11    
  716.  
  717. TABLE31    DW    OFFSET SELECT_DISK31    ;DIRECT BIOS CALLS FOR CP/M-31
  718.     DW    OFFSET SET_TRACK31
  719.     DW    OFFSET SET_DMASEG31
  720.     DW    OFFSET SET_DMAOFF31    
  721.     DW    OFFSET SET_SECTOR31
  722.     DW    OFFSET READ_SECTOR31    
  723.     DW    OFFSET WRITE_SECTOR31      
  724.     DW    OFFSET SECTOR_XLAT31    
  725.  
  726. CURDR    DB    0            ;CURRENT DRIVE HERE
  727. LINES    DB    2            ;LINES PRINTED ON SCREEN COUNTER
  728. FIX_EM    DB    0            ;FIX FLAG
  729. VIEW_EM DB    0FFH            ;VIEW FLAG
  730.  
  731. BPB    RS    5            ;SPACE FOR BIOS PARAMETER BLOCK
  732.  
  733. CALL_TBL RW    1            ;ADDRESS OF BIOS CALL TABLE GOES HERE
  734. XLAT_ADR RW    1            ;ADDRESS OF TRANSLATION TABLE
  735.  
  736. FIXCNT    RB    1            ;NUMBER OF FIXES
  737. REWRT    RB    1            ;WRITE BACK TO DISK FLAG
  738. MAXDIR    RW    1
  739. MAXSEC    RW    1
  740.  
  741. DIR_PER_SEC    DB    4        ;number directory entrys per sector
  742. SEC_PER_TRK    DW    26
  743.  
  744. CPM_VERSION    DW    0        ;cpm version
  745.  
  746. sysaddr        dw    0        ;save location for sysdat addr
  747. udaaddr        dw    0        ;save location for process uda addr
  748.  
  749. mcnt    db    1            ;multi-sector count
  750. drive    rb    1            ;drive number (A:=1)
  751. track    rw    1            ;track number
  752. sector    rw    1            ;sector number
  753. dmaseg    rw    1            ;DMA segment for data
  754. dmaoff    dw    offset dir_buf        ;DMA offset for data
  755.  
  756. dpb    rb    DPB_SIZE
  757.  
  758.     RW    32            ;32 WORD LOCAL STACK
  759. STACK    RW    1
  760.  
  761. dir_buf    rs    0000            ;4K data buffer [add[100]] at link
  762.  
  763.     END
  764.