program IDE_Info; { IDEINFO.PAS -- v0.1 Reports IDE information from installed IDE hard drives. TP source code written by Scott Earnest (setech@ix.netcom.com), 1997. Based closely on C code written by Doug Merrett (dcm@mincom.oz.au), available on sites as DUG_IDE.C in DUGIDE10.ZIP. Disclaimer: Standard. It works on my system, I can't guarantee it will work on yours. Known problems: WILL NOT WORK IN A WIN95 DOS SESSION. This may have something to do with the way Win 95 intercepts low-level I/O in its DOS sessions. It will, however, work under DOS 7.0 if you boot directly to DOS without starting Win 95. Note: This code is rather sloppy and IMHO not well organized. There are very few comments, so modify at your own risk. Also intended to work with the first IDE channel only. } uses crt, dos; const ret_val : string = ''; outval : array[0..1] of byte = ($a0,$b0); var num_drv : byte; dd : array[0..255] of word; dd_off : word; loop : word; ddc : array[0..511] of char absolute dd; reg : registers; bios_cyl, bios_head, bios_sec : array[0..1] of word; { Cylinders, Heads, Sectors } function getascii (in_data : array of word; off_start, off_end : word) : string; var wk : array[0..511] of char; loop, loop1 : word; begin loop1 := 1; for loop := off_start to off_end do begin ret_val[loop1] := char(hi(in_data[loop])); inc (loop1); ret_val[loop1] := char(lo(in_data[loop])); inc (loop1); end; ret_val[0] := char(succ(off_end-off_start)*2); getascii := ret_val; end; begin assign (input,''); reset (input); assign (output,''); rewrite (output); directvideo := false; textattr := $1f; num_drv := mem[Seg0040:$75]; for loop := 0 to pred(num_drv) do begin while port[$1f7]<>$50 do ; {wait until controller not busy} port[$1f6] := outval[loop]; port[$1f7] := $ec; while port[$1f7]<>$58 do ; {wait for data ready} for dd_off := 0 to 255 do dd[dd_off] := portw[$1f0]; for dd_off := 0 to 255 do write (char(hi(dd[dd_off])),char(lo(dd[dd_off]))); { Get BIOS drive info } reg.ah := $08; { Get drive info } reg.dl := $80+loop; { Drive is 80H for Disk 0, 81H for Disk 1 } intr ($13,reg); if (reg.flags and fCarry=0) then { All OK if carry not set } begin bios_head[loop] := reg.dh+1; { Heads are from 0 } bios_sec[loop] := reg.cl and $3F; { sec is bits 5 - 0 } bios_cyl[loop] := ((reg.cl and $C0) shl 2)+reg.ch+2; { +1 because starts from 0 and +1 for FDISK leaving one out } end; writeln ('DRIVE ', loop); writeln ('Model Number______________________: ', getascii (dd, 27, 46)); writeln ('Serial Number_____________________: ', getascii (dd, 10, 19)); writeln ('Controller Revision Number________: ', getascii (dd, 23, 26)); writeln; write ('Able to do Double Word Transfer___: '); if dd[48]=0 then writeln ('No') else writeln ('Yes'); writeln ('Controller type___________________: ', dd[20]); writeln ('Controller buffer size (bytes)____: ', longint(dd[21])*512); writeln ('Number of ECC bytes transferred___: ', dd[22]); writeln ('Number of sectors per interrupt___: ', dd[47]); writeln; writeln ('Hard Disk Reports'); writeln ('Number of Cylinders (Fixed)_______: ', dd[1]); writeln ('Number of Heads___________________: ', dd[3]); writeln ('Number of Sectors per Track_______: ', dd[6]); writeln; writeln ('BIOS Reports'); writeln ('Number of Cylinders_______________: ', bios_cyl[loop]); writeln ('Number of Heads___________________: ', bios_head[loop]); writeln ('Number of Sectors per Track_______: ', bios_sec[loop]); writeln; if loop<>1 then begin writeln ('Press a key'); readkey; end; end; end.