home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / dskstruc / hdsnif21.arj / HDSNIFF.ASM next >
Assembly Source File  |  1992-04-03  |  24KB  |  926 lines

  1.     PAGE    60,132
  2. NAME    HDSNIFF
  3.     TITLE    HDSniff.Com Version 2.1
  4. Comment @
  5.  
  6. Tells you how your AT/XT hard disks were last low-level formatted.
  7.  
  8. Needs no parameters.
  9. example of use:
  10.  
  11. HdSniff
  12. or
  13. HDSniff | More
  14. or
  15. HDSniff >Temp.Dat
  16.  
  17. by Roedy Green
  18.    Canadian Mind Products
  19.    #168 - 1020 Mainland Street
  20.    Vancouver BC
  21.    Canada V6B 2T4
  22.    (604) 684-6529
  23.  
  24. This program is copyrighted, however it may be copied freely and
  25. used for any purpose except military.
  26.  
  27. Here is a typical output for an XT with one 72 MB hard disk:
  28.  
  29. ░▒▓█ HDSniff 2.1 █▓▒░
  30.  
  31. (C) Copyright 1989, 1990, 1991, 1992 Roedy Green Canadian Mind Products
  32. May be freely copied and used for non military purposes only.
  33.  
  34. Ferrets out the parameters that were used to perform
  35. the last low-level hard disk format.
  36.  
  37. All numbers are both in decimal and [hex].
  38.  
  39. Low level formatting parameters for DISK 0   [0=C: 1=D:]
  40.  
  41. XT style disk controller presumed
  42.  
  43. 1024 [400] / 918 [396] = Number of cylinders (per drive parms/per drive table)
  44. 8 [8] / 15 [F] = Number of heads (per drive parms/per drive table)
  45. 918 [396] = Starting cylinder for reduced write current
  46. 918 [396] = Starting cylinder for write precompensation
  47. 7 [7] = Maximum bits of error burst to attempt to correct (usually 7 to 11)
  48. 2 [2] = Step control byte
  49.   (bit 7 = disable retries; bit 6 = disable ECC retries)
  50.   (bits 2..0 = seek step PULSE rate, faster than track-to-track seek rate)
  51.   (approx 12 µs for modern buffered seeks, 3 ms for older unbuffered.)
  52.   Brand      Debug Init Step byte code interpreted as step pulse rate
  53.   ═════      ══════════ ═════════════════════════════════════════════
  54.   Adaptec    g=c800:ccc 3=13 µs, 2=30 µs, 5=70 µs, 4=200 µs, 0=3 ms
  55.   DTC5150CRH g=c800:5    2=12 µs, 5=70 µs, 4=200 µs, 0,1,6,7=3 ms
  56.   DTC5150XL  g=c800:5    0=5,10,20,30,40,50,60,70 µs (cannot tell which!)
  57.   IBM/Xebec        5=70 µs, 4=200 µs, 0,6,7=3 ms
  58.   Omti         g=c800:6    1=10 µs, 2=25 µs, 3=40 µs, 5=70 µs, 4=200 µs,
  59.             0,6,7=3 ms
  60.   WD-old     g=c800:5    5=70 µs, 4=200 µs, 0,6,7=3 ms
  61.   WD1002-WX1 g=c800:5    3,7=10.5 µs, 2=22.5 µs, 6=28.5 µs, 1=46.5 µs,
  62.             5=70.5 µs, 4=202.5 µs, 0=3.1 ms
  63.   WD1002-27X g=c800:5    3,7=8 µs, 1,2,4,5,6=24 µs, 0=3 ms
  64.   WD10025WX2 g=c800:5    3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,
  65.             4=210 µs, 0=3ms
  66.   WD1004-WX1 g=c800:5    3,7=12 µs, 6=27 µs, 1=51 µs, 2=63 µs, 5=75 µs,
  67.             4=207 µs, 0=3 ms
  68.   WD1004-27X g=c800:5    3,7=8 µs, 1,2,4,5,6=24 µs, 0=3 ms
  69.   WD1004A27X g=c800:5    3,7=11 µs, 1,2,4,5,6=24 µs, 0=3.3 ms
  70.   WD-XT-GEN1 g=c800:5    3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,
  71.             4=210 µs, 0=3ms
  72.   WD-XT-GEN2 g=c800:5    3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,
  73.             4=210 µs, 0=3ms
  74.  
  75. 4 [4] = Standard timeout value
  76. 25 [19] = Formatting timeout value
  77. 10 [A] = Disk check timeout value
  78. 17 [11] / 0 [0] = sectors per track (per drive parms/per drive table)
  79.    (usually 17 for MFM, 26 for RLL, 36 for ESDI)
  80.  
  81. When information gleaned from get-drive-parameters
  82. (ROM BIOS INT 13 function 08) conflicts with that gleaned from
  83. get-drive-table (INT 41), trust get-drive-parameters.
  84.  
  85. See HDSNIFF.TXT for information on interpreting these results.
  86.  
  87. To see everything before it scrolls off the screen try:
  88.   HDSniff | MORE
  89. or
  90.   HDSniff >LPT1:
  91. or
  92.   HDSniff >Temp.Dat
  93.  
  94. Purpose
  95. =======
  96.  
  97. HDSniff will tell you the parameters that were used the last
  98. time your hard disk was low-level formatted.  It displays
  99. information from hard disk BIOS INT 13 function 08 get drive
  100. parameters and from the INT 41 get drive table.  This can be
  101. useful if you need to reformat your hard disk, or if you want to
  102. ensure the formatting was done correctly.
  103.  
  104. The following parameters are often specified incorrectly during
  105. low level format and result is flaky operation.
  106.  
  107. - Starting cylinder for reduced write current.
  108. - Starting cylinder for write precompensation.
  109. - Step control byte seek step PULSE rate, faster than
  110.   track-to-track seek rate, ranging from 12 µs for modern
  111.   buffered seeks to 3 ms for older unbuffered seeks.
  112.  
  113. Interpreting HDNSNIFF Results
  114. =============================
  115.  
  116. From the drive manufacturer you must determine the number of
  117. cylinders, heads, starting reduced write cylinder and write
  118. precomp cylinder.  Many BBS's also post lists of such information.
  119. If the cylinders and heads are incorrect, you are wasting part
  120. of your disk.  If the RWC and WP are incorrect you might expect
  121. unreliable operation.
  122.  
  123. The ECC burst length should be a number between 5 and 11.
  124. Setting it smaller is more conservative.  ECC will not attempt
  125. to correct serious errors without telling you.    When ECC tries
  126. to correct serious errors it does not always succeed, but it
  127. lets you carry on without notice.  Setting the ECC burst length
  128. larger allows you to carry on and recover from serious errors,
  129. though you never hear about them unless you use HDTest.
  130.  
  131. If the step pulse rate is set too fast (lower number) you can
  132. expect slower response due to corrected seek errors.  If the
  133. pulse rate is too slow (higher number) you can expect slower
  134. response due to the disk waiting needlessly long for pulses.
  135. Sometimes there can also be seek errors.
  136.  
  137. Most AT controllers use 35 µs fixed by the motherboard BIOS.
  138. Ontrack offer a utility to override this.
  139.  
  140. It is hard to get information about the optimal pulse rates for
  141. disk drives.  As rule of thumb try 3 ms for very old drives with
  142. unbuffered seeks, 30 µs for 20 MB disks, and 18 µs for 30 to 40
  143. MB disks, and 12 µs for premium voice coil drives.
  144.  
  145. If any parameters are incorrect, you must back up everything
  146. twice, redo the low level format, the FDISK, the FORMAT C:/S/V
  147. and restore your data.
  148.  
  149. HDSNIFF currently cannot tell you the interleave.  Use Gibson
  150. SpinRite to determine the optimum interleave and correct it.
  151.  
  152. Caveats
  153. =======
  154.  
  155. Information about the size of a disk is indirectly recorded in
  156. four separate places:
  157.  
  158. 1. the drive table accessed via int 41
  159. 2. BIOS via int 13 ah=08
  160. 3. the partition table in the mini partition-selector boot on track 0
  161. 4. the BPB in the boot on track 0 of the DOS partition
  162.  
  163. Unhappily these do not all necessarily agree.
  164. HDSniff will tell you about 1 and 2.
  165. FDisk will tell you about 3.
  166. ChkDsk will tell you about 4.
  167. I have found 2 to be the most reliable, and 1 the least.
  168.  
  169. Some controllers fail to record the RWC (Reduced Write current
  170. Cylinder) and WPC (Write Precompensation Cylinder) in the drive
  171. table.    If you plan to reformat your disk, get the proper values
  172. from the disk manufacturer or from tables in OnTrack software or
  173. from tables posted on BIX.
  174.  
  175. Why Copyright?
  176. ==============
  177.  
  178. In the past all CMP software was public domain.  Now we are
  179. releasing only copyrighted software.  We did this because
  180. Rockwell International (a major American defense contractor)
  181. asked my permission to use my public domain RESTORE program to
  182. distribute their software.  I refused to bend my no military use
  183. rule.  They told me they were going to continue using it anyway.
  184. I found out legally I had no way to stop them because we did not
  185. display a copyright notice.
  186.  
  187. If there is any doubt whatsoever if your use of HDSniff
  188. constitutes military use, you must get clearance with Canadian
  189. Mind Products.
  190.  
  191. Future possible enhancements include:
  192. =====================================
  193.  
  194.  0. display the AT drive type index.
  195.  1. calculate the current interleave and suggest the optimum.
  196.  2. display the partition sizes.
  197.  3. display the cluster sizes of each partition.
  198.  4. display other partition stats such as free space,
  199.     number of directories, location of interesting tables.
  200.  5. Determine the DOS version in MSDOS.SYS and Command.com
  201.  
  202. Version 1.0 Written 1988 April 6.
  203.  
  204. Version 1.1
  205.   - added note that seek step pulse rate 2 is 30 ms
  206.  
  207. Version 1.2 1988 November 14
  208.   - added per int 13 for cyls and heads
  209.   - Determine AT vs XT then trim the display.
  210.   - added more explanation of pulse rate
  211.  
  212. Version 1.3 1989 March 31
  213.   - new version handles 80386 accelerator in XT style machine
  214.     with XT style disk controller.
  215.     Now makes XT AT determination based on ECC length.
  216.   - added Western digital XT-GEN controller documentation.
  217.   - reordered step list by speed.
  218.   - changed landing zone usual message.
  219.  
  220. Version 1.4 1989 April 6
  221.    - added further step pulse info for WD controllers
  222.    - info on interpreting results embedded in source code.
  223.  
  224. Version 1.5 1989 May 4
  225.    - added Xebec controller infor.
  226.  
  227. Version 1.6 1989 June 19
  228.    - added info on sources of info and which can be trusted
  229.    - fixed bug in HaveXT HaveAT comment
  230.  
  231. Version 1.7 1989 July 27
  232.    - suppress the discrepancy comment when there is no discrepancy.
  233.  
  234. Version 1.8 1989 Sept 26
  235.    - acknowledge ESDI drives
  236.  
  237. Version 1.9 1990 May 15
  238.    - flashier banner
  239.    - new address
  240.    - added decoding of several additional WD controllers.
  241.    - added explanation of HDSniff | MORE to output.
  242.  
  243. Version 2.0 1990 Sep 12
  244.    - added WD1002A-27X to step pulse rate list
  245.    - added DTC5150XL and DTC5150CRH
  246.  
  247. Version 2.1 1991 April 4
  248.    - fix bug that gave wrong results on second disk.
  249.      DI register was not properly preserved.
  250.    - bug discovered by James Cox, JaCoRa on BIX.
  251.  
  252. @ ; end of comment
  253.  
  254. ;===========================
  255.  
  256. CR    MACRO    ; Carriage return line feed
  257.     DB 0dh,0ah
  258.     ENDM
  259.  
  260. ;============================
  261.  
  262. EOS    MACRO    ; marks end of display string
  263.     DB 0dh,0ah,'$'
  264.     ENDM
  265.  
  266. ;============================
  267. ;    register conventions:
  268. ;    preserved across calls DS: CS: ES: SS: CX SI DI
  269. ;    trashed across calls AX BX DX
  270. ;============================
  271.  
  272. DriveTab Struc            ; Drive Table accessible Via
  273.                 ; BIOS int 41H
  274.     Max_Cyl     dw ?    ; Max number of cylinders
  275.     Max_Heads    db ?    ; Max number of heads
  276.     Red_Write_Cyl    dw ?    ; starting reduced write cylinder
  277.     Precomp_Cyl    dw ?    ; starting write precompensation
  278.     Ecc_Burst    db ?    ; max ECC burst length (bits)
  279.     Step_Control    db ?
  280.     Std_TimeOut    db ?
  281.     Fmt_TimeOut    db ?
  282.     Chk_TimeOut    db ?
  283.     Land_Zone    dw ?
  284.     Sects_Per_Track db ?
  285.     reserved    db ?    ; 1 byte reserved
  286. DriveTab Ends
  287.  
  288. ;============================
  289.  
  290. code    segment para
  291.     assume    cs:code,ds:code
  292.     org    100h
  293.  
  294. HDSniff proc    far
  295.  
  296. start:
  297.     lea    dx,Welcome$
  298.     Call    Say
  299.     mov    di,0080h    ; drive no. for c:
  300.     mov    dx,di        ; get drv parms for disk c:
  301.     mov    ax,0800h    ; ah 08 = get disk parameters
  302.     int    13h        ; into CX/DX
  303.  
  304.     mov    cl,dl        ; put drv count in cx
  305.     xor    ch,ch        ; zero high order byte of drive count
  306.     jcxz    quit        ; zero drives--exit procedure
  307.     xor    DI,DI        ; loop with DI=0,1,2...
  308. sloop:                ; loop once for each drive c: d:...
  309.     call    Sniff1
  310.     inc    DI        ; inc to next drive  D:
  311.     loop    sloop
  312.  
  313. quit:
  314.     test    byte ptr IsConflict,-1    ; Was there a conflict?
  315.     jz    NoConflict    ; no bypass message
  316.     lea    dx,Conflict$
  317.     Call    Say
  318. NoConflict:
  319.     lea    dx,Interpret$    ; note on how to interpret results
  320.     Call    Say
  321.     mov    ax,4c00h    ; exit to DOS
  322.     int    21h
  323.  
  324. ;============
  325.  
  326. Say    Proc
  327. ;    on entry DX points to a string to display terminated by $
  328. ;    displays string
  329.     Push    AX
  330.     MOV    AH,9
  331.     Int    21h
  332.     Pop    AX
  333.     ret
  334. Say    EndP
  335.  
  336. ;============
  337.  
  338. SayNum PROC Near
  339. ;    on entry displays number in AX in Decimal and [hex]
  340.     PUSH    AX
  341.     Call    SayDec
  342.     lea    dx,leftbr$
  343.     Call    Say
  344.     POP    AX
  345.     Call    SayHex
  346.     lea    dx,rightbr$
  347.     Call    Say
  348.     ret
  349. SayNum    EndP
  350.  
  351. ;============
  352.  
  353. SayDec PROC    NEAR
  354. ;    call with number in range 0..65535 in AX
  355. ;    converts it to ASCII and displays it on the screen
  356. ;    If it is 0 shows as 0.
  357. ;    leading 0's are suppressed.
  358. ;    field is exactly wide enough to hold the number.
  359. ;    No leading or trailing spaces.    DISPLAYED IN DECIMAL
  360.     PUSH    DI        ; preserve DI
  361.     MOV    BX,10d
  362.     MOV    DI,5        ; work right to left building digits at PAD
  363. SayDecLoop:
  364.     DEC    DI
  365.     XOR    DX,DX        ; DX:AX / 10
  366.     DIV    BX        ; AX=quot DX=remdr
  367.     ADD    DL,'0'        ; convert digit to ASCII
  368.     MOV    PAD[DI],DL
  369.     OR    AX,AX
  370.     JNZ    SayDecLoop
  371. SayDecDone:
  372. ;    Number is ready
  373.     lea    dx,pad[di]
  374.     call    Say        ; terminated by $
  375.     POP    DI
  376.     RET
  377. SayDec    ENDP
  378.  
  379. ;========================
  380.  
  381. SayHex PROC    NEAR
  382. ;    call with number in range 0..65535 in AX
  383. ;    converts it to ASCII and displays it on the screen
  384. ;    If it is 0 shows as 0.
  385. ;    leading 0's are suppressed.
  386. ;    field is exactly wide enough to hold the number.
  387. ;    No leading or trailing spaces.    DISPLAYED IN HEX
  388. ;    This is not the fastest way of doing HEX, but it was
  389. ;    quickest to code given I had already written SayDec.
  390.     push    di        ; preserve DI
  391.     mov    bx,10h
  392.     mov    di,5        ; work right to left buil    ding digits at PAD
  393. SayHexLoop:
  394.     dec    di
  395.     xor    dx,dx        ; DX:AX / 10h
  396.     div    bx        ; AX=quot DX=remdr
  397.     cmp    dl,9
  398.     JG    HexChar
  399.     add    dl,'0'        ; convert digit to ASCII
  400.     JMP    StoreChar
  401. HexChar:
  402.     add    dl,'A'-0ah    ; convert A..H
  403. StoreChar:
  404.     mov    pad[DI],DL
  405.     OR    AX,AX
  406.     JNZ    SayHexLoop
  407. SayHexDone:
  408. ;    Number is ready
  409.     lea    dx,pad[di]
  410.     call    Say        ; terminated by $
  411.     pop    di
  412.     ret
  413. SayHex    ENDP
  414.  
  415. ;=================================
  416.  
  417. Sniff_Max_Cyl PROC Near
  418. ;    Displays Total Cyls on one Drive
  419. ;    DI indexes drive wanted usually 0 = C: 1= D:
  420. ;    Sacrosanct ES:SI points to the drive table
  421.     mov    dx,0080h    ; get total cyls from BIOS
  422.     add    dx,di
  423.     mov    ax,0800h
  424.     int    13h
  425.     xor    ax,ax
  426.     mov    al,cl
  427.     shl    ax,1
  428.     shl    ax,1
  429.     mov    al,ch
  430.     inc    ax        ; include landing zone
  431.     inc    ax        ; max cyl # -> total cyls
  432.     push    ax        ; Save Cyl count per BIOS
  433.     Call    SayNum
  434.     mov    ax,ES:[SI].Max_Cyl ; get total cyls from drive table
  435.     pop    bx        ; total cyls per BIOS
  436.     cmp    ax,bx
  437.     je    Cyls_Agree
  438.     mov    byte ptr IsConflict,-1    ; note there was a conflict
  439.     lea    dx,Slash$    ; display both versions of truth
  440.     Call    Say
  441.     Call    SayNum
  442.     lea    dx,Max_Cyl$
  443.     Call    Say
  444.     lea    dx,Disagree$
  445.     Call    Say
  446.     Ret
  447. Cyls_Agree:
  448.     lea    dx,Max_Cyl$
  449.     Call    Say
  450.     lea    dx,Agree$
  451.     Call    Say
  452.     Ret
  453. Sniff_Max_Cyl ENDP
  454.  
  455. ;=================================
  456.  
  457. Sniff_Max_Heads PROC Near
  458. ;    Displays Total Heads on one Drive
  459. ;    DI indexes drive wanted usually 0 = C: 1= D:
  460. ;    Sacrosanct ES:SI points to the drive table
  461.     mov    dx,0080h    ; get total heads from BIOS
  462.     add    dx,di
  463.     mov    ax,0800h
  464.     int    13h
  465.     xor    ax,ax
  466.     mov    al,dh
  467.     inc    ax        ; max head # -> total head
  468.     push    ax        ; Save head count per BIOS
  469.     Call    SayNum
  470.     mov    al,ES:[SI].Max_Heads
  471.     xor    ah,ah
  472.     pop    bx        ; total heads per BIOS
  473.     cmp    ax,bx
  474.     je    heads_Agree
  475.     lea    dx,Slash$
  476.     Call    Say
  477.     Call    SayNum
  478.     Lea    dx,Max_Heads$
  479.     Call    Say
  480.     lea    dx,Disagree$
  481.     Call    Say
  482.     Ret
  483. Heads_Agree:
  484.     Lea    dx,Max_Heads$
  485.     Call    Say
  486.     lea    dx,Agree$
  487.     Call    Say
  488.     Ret
  489. Sniff_Max_Heads ENDP
  490.  
  491. ;=================================
  492.  
  493. Sniff_Red_Write_Cyl PROC Near
  494. ;    Displays reduced write cyl on one Drive
  495. ;    DI indexes drive wanted usually 0 = C: 1= D:
  496. ;    Sacrosanct ES:SI points to the drive table
  497.  
  498.     mov    ax,ES:[SI].Red_Write_Cyl
  499.     Call    SayNum
  500.     lea    dx,Red_Write_Cyl$
  501.     Call    Say
  502.     Ret
  503. Sniff_Red_Write_Cyl ENDP
  504.  
  505. ;=================================
  506.  
  507. Sniff_PreComp_Cyl PROC Near
  508. ;    Displays Precompensation Cyl on one Drive
  509. ;    DI indexes drive wanted usually 0 = C: 1= D:
  510. ;    Sacrosanct ES:SI points to the drive table
  511.     mov    ax,ES:[SI].Precomp_Cyl
  512.     Call    SayNum
  513.     lea    dx,Precomp_Cyl$
  514.     Call    Say
  515.     Ret
  516. Sniff_PreComp_Cyl ENDP
  517.  
  518. ;=================================
  519.  
  520. Sniff_Ecc_Burst PROC Near
  521. ;    Displays ECC burst length on one Drive
  522. ;    DI indexes drive wanted usually 0 = C: 1= D:
  523. ;    Sacrosanct ES:SI points to the drive table
  524.  
  525.     mov    al,ES:[SI].Ecc_Burst
  526.     xor    ah,ah
  527.     Call    SayNum
  528.     lea    dx,Ecc_Burst$
  529.     Call    Say
  530.     Ret
  531. Sniff_Ecc_Burst ENDP
  532.  
  533. ;=================================
  534.  
  535. Sniff_Step_Control_AT PROC Near
  536. ;    Displays AT Step Control Byte on one Drive
  537. ;    DI indexes drive wanted usually 0 = C: 1= D:
  538. ;    Sacrosanct ES:SI points to the drive table
  539.  
  540.     mov    al,ES:[SI].Step_Control
  541.     xor    ah,ah
  542.     Call    SayNum
  543.     lea    dx,Step_Control_AT$
  544.     Call    Say
  545.     Ret
  546. Sniff_Step_Control_AT ENDP
  547.  
  548. ;=================================
  549.  
  550. Sniff_Step_Control_XT PROC Near
  551. ;    Displays XT Step Control Byte on one Drive
  552. ;    DI indexes drive wanted usually 0 = C: 1= D:
  553. ;    Sacrosanct ES:SI points to the drive table
  554.  
  555.     mov    al,ES:[SI].Step_Control
  556.     xor    ah,ah
  557.     Call    SayNum
  558.     lea    dx,Step_Control_XT$
  559.     Call    Say
  560.     Ret
  561. Sniff_Step_Control_XT ENDP
  562.  
  563. ;=================================
  564.  
  565. Sniff_TimeOut PROC Near
  566. ;    Displays the three Timeout Values on one Drive
  567. ;    DI indexes drive wanted usually 0 = C: 1= D:
  568. ;    Sacrosanct ES:SI points to the drive table
  569.  
  570.     mov    al,ES:[SI].Std_TimeOut
  571.     xor    ah,ah
  572.     Call    SayNum
  573.     lea    dx,Std_TimeOut$
  574.     Call    Say
  575.  
  576.     mov    al,ES:[SI].Fmt_TimeOut
  577.     xor    ah,ah
  578.     Call    SayNum
  579.     lea    dx,Fmt_TimeOut$
  580.     Call    Say
  581.  
  582.     mov    al,ES:[SI].Chk_TimeOut
  583.     xor    ah,ah
  584.     Call    SayNum
  585.     lea    dx,Chk_TimeOut$
  586.     Call    Say
  587.     Ret
  588. Sniff_TimeOut ENDP
  589.  
  590. ;=================================
  591.  
  592. Sniff_Land_Zone PROC Near
  593. ;    Displays Landing Zone on one Drive
  594. ;    DI indexes drive wanted usually 0 = C: 1= D:
  595. ;    Sacrosanct ES:SI points to the drive table
  596.  
  597.     mov    ax,ES:[SI].Land_Zone
  598.     Call    SayNum
  599.     lea    dx,Land_Zone$
  600.     Call    Say
  601.     Ret
  602. Sniff_Land_Zone ENDP
  603.  
  604. ;=================================
  605.  
  606. Sniff_Sects_Per_Track PROC Near
  607. ;    Displays sectors per track on one Drive
  608. ;    DI indexes drive wanted usually 0 = C: 1= D:
  609. ;    Sacrosanct ES:SI points to the drive table
  610.     mov    dx,0080h    ; get sectors from BIOS
  611.     add    dx,di
  612.     mov    ax,0800h
  613.     int    13h
  614.     mov    al,cl
  615.     and    ax,111111b    ; mask off cyl number
  616.     push    ax        ; Save sectors per BIOS
  617.     Call    SayNum
  618.     mov    al,ES:[SI].Sects_Per_Track
  619.     xor    ah,ah
  620.     pop    bx        ; total sectors per BIOS
  621.     cmp    ax,bx
  622.     je    Sectors_Agree
  623.     lea    dx,Slash$
  624.     Call    Say
  625.     Call    SayNum
  626.     Lea    dx,Sects_Per_Track$
  627.     Call    Say
  628.     lea    dx,Disagree$
  629.     Call    Say
  630.     lea    dx,Expect_Sectors$
  631.     Call    Say
  632.     Ret
  633. Sectors_Agree:
  634.     Lea    dx,Sects_Per_Track$
  635.     Call    Say
  636.     lea    dx,Agree$
  637.     Call    Say
  638.     lea    dx,Expect_Sectors$
  639.     Call    Say
  640.     Ret
  641. Sniff_Sects_Per_Track ENDP
  642.  
  643. ;=================================
  644.  
  645. Point1    PROC    Near
  646. ;    prints out drive table for 1 drive
  647. ;    DI indexes drive wanted usually 0 = C: 1= D:
  648. ;    Compute ES:SI so that it points to the drive table
  649.     push    di        ; save di since we will be shifting it
  650.     Lea    DX,Disk_no$    ; describe which disk 0=C:
  651.     Call    Say
  652.     mov    ax,di        ; disk number decimal only
  653.     Call    SayDec
  654.     Lea    DX,Disk_noC$
  655.     Call    Say
  656.  
  657.     shl    di,1        ; multiply DI by 16 to offset
  658.     shl    di,1        ; into proper 16-byte drive table
  659.     shl    di,1
  660.     shl    di,1
  661.  
  662.     mov    al,41h
  663.     mov    ah,35h        ; get int 41 pointer to drive table
  664.     int    21h        ; ES:BX points to drive table
  665.                 ; get drive table info
  666.     mov    si,bx        ; save address in SI so wont get
  667.                 ; trashed
  668.     add    si,di        ; add on offset
  669.     pop    di
  670.     Ret
  671.  
  672. Point1    ENDP
  673.  
  674. ;=================================
  675.  
  676. Discrim PROC    Near
  677. ;    Decide if have XT or AT type controller, XT=1 or AT=0
  678. ;    DI indexes drive wanted usually 0 = C: 1= D:
  679. ;    Sacrosanct ES:SI points to the drive table
  680.     mov    al,ES:[SI].Ecc_Burst
  681.     or    al,al
  682.     Ret
  683. Discrim ENDP
  684.  
  685. ;=================================
  686.  
  687. Sniff1    PROC    Near
  688. ;    prints out drive table for 1 drive
  689. ;    DI indexes drive wanted usually 0 = C: 1= D:
  690. ;    Sacrosanct ES:SI points to the drive table
  691.     PUSH    CX
  692.                 ; WE MUST PRESERVE DI throughout!
  693.     Call    Point1        ; get pointer to drive table
  694.     Call    Discrim     ; discriminate AT vs XT via chip
  695.     JNZ    HaveXT
  696.  
  697. HaveAT:             ; We have an AT controller
  698.     lea    dx,AT$
  699.     call    Say
  700.     Call    Sniff_Max_Cyl
  701.     Call    Sniff_Max_Heads
  702.     Call    Sniff_Precomp_Cyl
  703.     Call    Sniff_Step_Control_AT
  704.     Call    Sniff_Land_Zone
  705.     Call    Sniff_Sects_Per_Track
  706.     POP    CX
  707.     RET
  708.  
  709. HaveXT:             ; We have an XT controller
  710.     lea    dx,XT$
  711.     call    Say
  712.     Call    Sniff_Max_Cyl
  713.     Call    Sniff_Max_Heads
  714.     Call    Sniff_Red_Write_Cyl
  715.     Call    Sniff_Precomp_Cyl
  716.     Call    Sniff_Ecc_Burst
  717.     Call    Sniff_Step_Control_XT
  718.     Call    Sniff_TimeOut
  719.     Call    Sniff_Sects_Per_Track
  720.     POP    CX
  721.     RET
  722.  
  723. Sniff1    ENDP
  724. ;======================================
  725.     EVEN
  726. PAD    DB    "00000$"    ; where numeric output built by SayNum
  727. ;======================================
  728. IsConflict DB    0        ; 0 = no conflict -1 = conflict
  729.                 ; between drive table and BIOS
  730. ;======================================
  731. Welcome$ Label Byte
  732.     CR
  733.     DB '░▒▓█ HDSniff 2.1 █▓▒░'
  734.     CR
  735.     CR
  736.     db '(C) Copyright 1989, 1990, 1991, 1992 Roedy Green Canadian Mind Products'
  737.     CR
  738.     db 'May be freely copied and used for non military purposes only.'
  739.     CR
  740.     CR
  741.     db 'Ferrets out the parameters that were used to perform'
  742.     CR
  743.     db 'the last low-level hard disk format.'
  744.     CR
  745.     CR
  746.     db 'All numbers are both in decimal and [hex].'
  747.     EOS
  748.  
  749. AT$    label Byte
  750.     CR
  751.     db 'AT style disk controller presumed'
  752.     CR
  753.     EOS
  754.  
  755. XT$    label Byte
  756.     CR
  757.     db 'XT style disk controller presumed'
  758.     CR
  759.     EOS
  760.  
  761. Disk_No$ Label Byte
  762.     CR
  763.     db 'Low level formatting parameters for DISK $'
  764.  
  765. Disk_NoC$ Label Byte
  766.     db '   [0=C: 1=D:]'
  767.     EOS
  768.  
  769. leftbr$ label Byte
  770.     db ' [$'
  771.  
  772. rightbr$ label Byte
  773.     db ']$'
  774.  
  775. Slash$ label Byte
  776.     db ' / $'
  777.  
  778. Max_Cyl$ Label Byte
  779.     db ' = Number of cylinders$'
  780.  
  781. Max_Heads$ label Byte
  782.     db ' = Number of heads$'
  783.  
  784. Red_Write_Cyl$ label Byte
  785.     db ' = Starting cylinder for reduced write current '
  786.     EOS
  787.     ; only applies to XT
  788.  
  789. Precomp_Cyl$ label Byte
  790.     db ' = Starting cylinder for write precompensation '
  791.     EOS
  792.  
  793. Ecc_Burst$ label Byte
  794.     db ' = Maximum bits of error burst to attempt to correct'
  795.     db ' (usually 7 to 11)'
  796.     EOS
  797.     ; only applies to XT
  798.  
  799. Step_Control_AT$ label Byte
  800.     db ' = Step control byte'
  801.     CR
  802.     db '  (bit 7 = disable retries; bit 6 = disable ECC retries)'
  803.     CR
  804.     db '  (bit 3 = more than 8 heads)'
  805.     EOS
  806.  
  807. Step_Control_XT$ label Byte
  808.     db ' = Step control byte'
  809.     CR
  810.     db '  (bit 7 = disable retries; bit 6 = disable ECC retries)'
  811.     CR
  812.     db '  (bits 2..0 = seek step PULSE rate, faster than track-to-track seek rate)'
  813.     CR
  814.     db '  (approx 12 µs for modern buffered seeks, 3 ms for older unbuffered.)'
  815.     CR
  816.     db '  Brand      Debug Init Step byte code interpreted as step pulse rate'
  817.     CR
  818.     db '  ═════      ══════════ ═════════════════════════════════════════════'
  819.     CR
  820.     db '  Adaptec    g=c800:ccc 3=13 µs, 2=30 µs, 5=70 µs, 4=200 µs, 0=3 ms'
  821.     CR
  822.     db '  DTC5150CRH g=c800:5   2=12 µs, 5=70 µs, 4=200 µs, 0,1,6,7=3 ms'
  823.     CR
  824.     db '  DTC5150XL  g=c800:5   0=5,10,20,30,40,50,60,70 µs (cannot tell which!)'
  825.     CR
  826.     db '  IBM/Xebec             5=70 µs, 4=200 µs, 0,6,7=3 ms'
  827.     CR
  828.     db '  Omti       g=c800:6   1=10 µs, 2=25 µs, 3=40 µs, 5=70 µs, 4=200 µs,'
  829.     CR
  830.     db '                        0,6,7=3 ms'
  831.     CR
  832.     db '  WD-old     g=c800:5   5=70 µs, 4=200 µs, 0,6,7=3 ms'
  833.     CR
  834.     db '  WD1002-WX1 g=c800:5   3,7=10.5 µs, 2=22.5 µs, 6=28.5 µs, 1=46.5 µs,'
  835.     CR
  836.     DB '                        5=70.5 µs, 4=202.5 µs, 0=3.1 ms'
  837.     CR
  838.     db '  WD10025WX2 g=c800:5   3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,'
  839.     CR
  840.     db '                        4=210 µs, 0=3ms'
  841.     CR
  842.     db '  WD1002-27X g=c800:5   3,7=8 µs, 1,2,4,5,6=24 µs, 0=3 ms'
  843.     CR
  844.     db '  WD1004-WX1 g=c800:5   3,7=12 µs, 6=27 µs, 1=51 µs, 2=63 µs, 5=75 µs,'
  845.     CR
  846.     DB '                        4=207 µs, 0=3 ms'
  847.     CR
  848.     db '  WD1004-27X g=c800:5   3,7=8 µs, 1,2,4,5,6=24 µs, 0=3 ms'
  849.     CR
  850.     db '  WD1004A27X g=c800:5   3,7=11 µs, 1,2,4,5,6=24 µs, 0=3.3 ms'
  851.     CR
  852.     db '  WD-XT-GEN1 g=c800:5   3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,'
  853.     CR
  854.     db '                        4=210 µs, 0=3ms'
  855.     CR
  856.     db '  WD-XT-GEN2 g=c800:5   3,7=18 µs, 6=30 µs, 1=45 µs, 2=60 µs, 5=75 µs,'
  857.     CR
  858.     db '                        4=210 µs, 0=3ms'
  859.     CR
  860.     EOS
  861.  
  862. ; Timeouts only apply to XT
  863.  
  864. Std_TimeOut$ label byte
  865.     db ' = Standard timeout value'
  866.     EOS
  867.  
  868. Fmt_TimeOut$ label byte
  869.     db ' = Formatting timeout value'
  870.     EOS
  871.  
  872. Chk_TimeOut$ label byte
  873.     db ' = Disk check timeout value'
  874.     EOS
  875.  
  876. Land_Zone$ label byte
  877.     db ' = landing zone (usually the last Cylinder+1)'
  878.     EOS
  879.     ; Drive table usually 0 in XT
  880.  
  881. Sects_Per_Track$ label byte
  882.     db ' = sectors per track$'
  883.     ; Drive table has 0 in XT, but BIOS still works
  884.  
  885. Expect_Sectors$ label byte
  886.     db '   (usually 17 for MFM, 26 for RLL, 36 for ESDI)'
  887.     EOS
  888.  
  889. Conflict$ label byte
  890.     CR
  891.     db 'When information gleaned from get-drive-parameters'
  892.     CR
  893.     db '(ROM BIOS INT 13 function 08) conflicts with that gleaned from'
  894.     CR
  895.     db 'get-drive-table (INT 41), trust get-drive-parameters.'
  896.     EOS
  897.  
  898. Agree$ label byte
  899.     EOS
  900.  
  901. Disagree$ label byte
  902.     db ' (per drive parms/per drive table)'
  903.     EOS
  904.  
  905. Interpret$ label byte
  906.     CR
  907.     db 'See HDSNIFF.TXT for information on interpreting these results.'
  908.     CR
  909.     CR
  910.     db 'To see everything before it scrolls off the screen try:'
  911.     CR
  912.     db '  HDSniff | MORE'
  913.     CR
  914.     db 'or'
  915.     CR
  916.     db '  HDSniff >LPT1:'
  917.     CR
  918.     db 'or'
  919.     CR
  920.     db '  HDSniff >Temp.Dat'
  921.     EOS
  922.  
  923. HDSniff endp
  924. code    ends
  925.     end    start
  926.