来自:fatman 时间:01-1-10 10:11:21 ID:436157 <br>下面是一位前辈写的代码<br>IDE.PAS (IDE硬盘参数检测)<br> ?Programmed by: 刘 杰 <br> ?nbsp;Designed : 04/11/92 <br> ?nbsp;Last modified: 01/26/95<br> ?请使用 Turbo Pascal 7.0 编译. <br><br>const <br> { read/write --------------------------- } <br> HDC_DATA = $01F0; <br> HDC_ERROR = $01F1; <br> HDC_SECCOU = $01F2; <br> HDC_SECNUM = $01F3; <br> HDC_CYLLOW = $01F4; <br> HDC_CYLHIGH = $01F5; <br> HDC_SDH = $01F6; <br> { read --------------------------------- } <br> HDC_STATUS : Word = $01F7; <br> HDC_ALTSTA = $03F6; <br> { write -------------------------------- } <br> HDC_COMMAND = $01F7; <br> HDC_FIXED = $03F6; <br> { commands ----------------------------- } <br> HDC_COMMAND_RESTORE = $10; <br> HDC_COMMAND_SEEK = $70; <br> HDC_COMMAND_READ = $20; <br> HDC_COMMAND_WRITE = $30; <br> HDC_COMMAND_FORMAT = $50; <br> HDC_COMMAND_READVER = $90; <br> HDC_COMMAND_DIAG = $90; <br> HDC_COMMAND_SETPAR = $91; <br> HDC_COMMAND_WRSTACK = $E8; <br> HDC_COMMAND_RDSTACK = $E4; <br> HDC_COMMAND_READPAR = $EC; <br> HDC_COMMAND_POWER = $E0; <br> HDC_FIXED_IRQ = $02; <br> HDC_FIXED_RESET = $04; <br> HDC_STATUS_ERROR = $01; <br> HDC_STATUS_INDEX = $02; <br> HDC_STATUS_ECC = $04; <br> HDC_STATUS_DRQ = $08; <br> HDC_STATUS_COMPLETE = $10; <br> HDC_STATUS_WRFAULT = $20; <br> HDC_STATUS_READY = $40; <br> HDC_STATUS_BUSY = $80; <br>type <br> TIdeTypes = record <br> Cylinders, <br> Heads, <br> Sectors: Word; <br> Name: String[38]; <br> end; <br> PIdeInfo = ^TIdeInfo; <br> TIdeInfo = record <br> genconf, <br> fixcyls, <br> remcyls, <br> heads, <br> bytetrack, { bytes per track } <br> bytesector, { bytes per sector } <br> sectors, { sectors per track } <br> byteisg, { bytes intesector gap } <br> byteplo, { bytes in sync } <br> worduniq: Word; { words unique status } <br> serial: array[1..20] of Char; <br> contype, { controller type } <br> bufsiz, { buffer size in 512 byte blocks } <br> byteecc: Word; { ECC bytes trasferred in read/write long <br>} <br> firmware: array[1..8] of Char; { firmware revision } <br> model: array[1..40] of Char; { model ID } <br> secsint, { number of sectors transferred per inte <br>rrupt } <br> dblword, { double word transfer flag } <br> writepro: Word; { write protect } <br> end; <br>const <br> IdesInDataBase = 17; <br> IdeTypes: array[1..IdesInDataBase] of TIdeTypes = <br> ((Cylinders:667; Heads:4; Sectors:33; Name:'Fujitsu M2611T (42.9 MB)'), <br> <br> (Cylinders:667; Heads:8; Sectors:33; Name:'Fujitsu M2612T (85.9 MB)'), <br> <br> (Cylinders:667; Heads:12; Sectors:33; Name:'Fujitsu M2613T (128.9 MB)') <br>, <br> (Cylinders:667; Heads:16; Sectors:33; Name:'Fujitsu M2614T (171.9 MB)') <br>, <br> (Cylinders:782; Heads:2; Sectors:27; Name:'Western Digital WD93024-A ( <br>20.6 MB)'), <br> (Cylinders:782; Heads:4; Sectors:27; Name:'Western Digital WD93044-A ( <br>41.2 MB)'), <br> (Cylinders:845; Heads:3; Sectors:35; Name:'Toshiba MK232FC (45.4 MB'), <br> <br> (Cylinders:845; Heads:7; Sectors:35; Name:'Toshiba MK234FC (106 MB'), <br> (Cylinders:965; Heads:5; Sectors:17; Name:'Quantum ProDrive 40AT (40 M <br>B)'), <br> (Cylinders:965; Heads:10; Sectors:17; Name:'Quantum ProDrive 80AT (80 M <br>B)'), <br> (Cylinders:1050; Heads:2; Sectors:40; Name:'Teac SD-340 (41 MB)'), <br> (Cylinders:776; Heads:8; Sectors:33; Name:'Conner CP-3104 (100 MB)'), <br> (Cylinders:745; Heads:4; Sectors:28; Name:'Priam 3804M (40.7 MB)'), <br> (Cylinders:980; Heads:10; Sectors:17; Name:'Western Digitial Caviar AC2 <br>80 (81 MB)'), <br> (Cylinders:560; Heads:6; Sectors:26; Name:'Seagate ST157A (42 MB)'), <br> (Cylinders:732; Heads:8; Sectors:35; Name:'ALPS ELECTRIC Co.,LTD. DR31 <br>1C (102 MB)'), <br> (Cylinders:0; Heads:0; Sectors:0; Name:'')); <br>type <br> parray = ^tarray; <br> tarray = array[1..256] of Word; <br>var <br> secbuf: parray; <br> drive: Byte; <br> drv: String[1]; <br>procedure printinfo; <br>var <br> id: TIdeInfo; <br> capacity: Word; <br> types: String; <br> i: Integer; <br> function zo(const value: Byte): String; <br> begin <br> if Boolean(value) then <br> zo := '' <br> else <br> zo := 'not'; <br> end; <br> function ToStr(value: LongInt): String; <br> var <br> S: String; <br> begin <br> Str(value, S); <br> ToStr := S; <br> end; <br> function ConvertHex(Value: Word): String; <br> const <br> hexTable: array[0..15] of Char = '0123456789ABCDEF'; <br> begin <br> ConvertHex := hexTable[Hi(Value) shr 4] + hexTable[Hi(Value) and $f] + <br> <br> hexTable[Lo(Value) shr 4] + hexTable[Lo(Value) and $f]; <br> end; <br> procedure SwapBytes(var Source, Dest; Len: Byte); assembler; <br> asm <br> push ds <br> lds si, Source <br> les di, Dest <br> mov cl, len <br> xor ch, ch <br> @1: mov ax, ds:[si] <br> xchg ah, al <br> mov es:[di], ax <br> inc si <br> inc si <br> inc di <br> inc di <br> loop @1 <br> pop ds <br> end; <br>begin <br> id := PIdeInfo(secbuf)^; <br> { get disk type by characteristics } <br> i := 1; <br> while IdeTypes.Cylinders <> 0 do <br> Begin <br> if (IdeTypes.cylinders = id.fixcyls) and <br> (IdeTypes.heads = id.heads) and <br> (IdeTypes.sectors = id.sectors) then <br> Begin <br> types := IdeTypes.name; <br> break; <br> end; <br> inc(i); <br> end; <br> { unknown disk } <br> if (IdeTypes.cylinders = 0) then <br> Begin <br> types := ' '; <br> { calculate capacity in MB } <br> capacity := (LongInt(id.fixcyls) * id.heads * id.sectors) div 2048; <br> types := types + ToStr(capacity); <br> types := types + ' Mbytes'; <br> end; <br> { swap bytes in ASCII fields except for WD disks } <br> if (i <> 4) and (i <> 5) then <br> Begin <br> SwapBytes(id.serial, id.serial, 10); <br> SwapBytes(id.firmware, id.firmware, 4); <br> SwapBytes(id.model, id.model, 20); <br> end; <br> WriteLn('Drive ', drive-2, ' :', types); <br> WriteLn('Drive ID : ', ConvertHex(id.genconf)); <br> WriteLn('Cylinders : ', id.fixcyls{, ' ' id.remcyls, ' removables'}); <br> WriteLn('Heads : ', id.heads); <br> Writeln('Sectors : ', id.sectors); <br> WriteLn('Serial No. : ', id.serial); <br> WriteLn('Firmware : ', id.firmware); <br> WriteLn('Model : ', id.model); <br>{ WriteLn('Bytes per track : ', id.bytetrack); <br> Writeln('Bytes per sector : ', id.bytesector); <br> WriteLn('Bytes of intersector gap: ', id.byteisg); <br> Writeln('Bytes of sync : ', id.byteplo); <br> WriteLn('Controller type : ', id.contype);} <br> Writeln('Buffer : ', id.bufsiz div 2, ' KBytes'); <br> WriteLn('Bytes of ECC: ', id.byteecc); <br>end; <br>procedure readsect; assembler; <br>asm <br>{ poll DRQ } <br>@1: mov dx, HDC_STATUS <br> in al, dx <br> and al, HDC_STATUS_BUSY <br> or al, al <br> jne @1 <br>{ read up sector } <br> mov cx, 256 <br> mov dx, HDC_DATA <br> les di, secbuf <br>@2: in ax, dx <br> mov es:[di], ax <br> inc di <br> inc di <br> loop @2 <br>end; <br>function DriveValid(Drive: Char; var Drv: Byte): Boolean; assembler; <br>asm <br> mov ah, 19h { Save the current drive in BL } <br> int 21h <br> mov bl, al <br> mov dl, Drive { Select the given drive } <br> sub dl, 'A' <br> les di, DRV <br> mov es:[di], dl <br> mov ah, 0Eh <br> int 21h <br> mov ah, 19h { Retrieve what DOS thinks is current } <br> int 21h <br> mov cx, 0 { Assume false } <br> cmp al, dl { Is the current drive the given drive? } <br> jne @1 <br> mov cx, 1 { It is, so the drive is valid } <br> mov dl, bl { Restore the old drive } <br> mov ah, 0eh <br> int 21h <br>@1: xchg ax, cx { Put the return value into AX } <br>end; <br>function CurDisk: Byte; assembler; <br>{ Returns current drive } <br>asm <br> mov ah, 19h <br> int 21h <br>end; <br>begin <br> Writeln('IDE ver 1.2 (c) 1995 Keenvim software workgroup, Inc.'); <br> writeln('Programmed by Mr. LiuJie'#13#10); <br> if ParamCount > 0 then <br> Begin <br> drv := ParamStr(1); <br> drv[1] := UpCase(drv[1]); <br> if not DriveValid(drv[1], Drive) or not (drv[1] in ['C'..'Z']) then <br> <br> Begin <br> WriteLn('There isn''t such drive or drive invalid!'); <br> Halt(1); <br> end; <br> end <br> else <br> drive := CurDisk; <br> { disable interrupt from drive } <br> Port[HDC_FIXED] := HDC_FIXED_IRQ; <br> { set up task file parameter } <br> Port[HDC_SDH] := $A0 + (drive shl 4); <br> { issue read parameters } <br> Port[HDC_COMMAND] := HDC_COMMAND_READPAR; <br> GetMem(secbuf, SizeOf(secbuf)); <br> { read up sector } <br> readsect; <br> { print out info } <br> printinfo; <br> FreeMem(secbuf, SizeOf(secbuf)); <br>end. <br><br> <br> <br>嘿嘿