📄 52.c
字号:
#include <stdlib.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <bios.h>
/* 函数 string 将按字方式表示的一串字符转换成可显示的ASCII字符串格式 */
char* string( unsigned int in_data[], int start, int end )
{
static char ret_str[40];
int loop, loop1;
for( loop = start, loop1 = 0; loop <= end; loop++ )
{
ret_str[loop1++] = ( char )( in_data[loop]/256); /*取字的高字节*/
ret_str[loop1++] = ( char )( in_data[loop]%256); /*取字的低字节*/
}
ret_str[loop1] = '\0'; /* C语言字符串以0结束*/
return ( ret_str );
}
/*计算系统SETUP项中IDE硬盘的最佳配备*/
void best_set( unsigned cyl_set, unsigned head_set, unsigned sec_set )
{
/*均为中间变量*/
unsigned int cycles, head_x, cyl_x;
unsigned long temp_size, surplus_size, min_size;
if( cyl_set > 1024 )
{
temp_size = (long)cyl_set * (long)head_set;
head_x = (int)( temp_size + 1023 ) / 1024;
/*以下部分通过增加逻辑磁头数,来减少柱面值,并选择最佳的柱面和磁头数,以使硬盘空间
和系统设置的余量最小*/
for( min_size = 1023; head_x < 17; head_x++ )
{
cyl_x = (int)( temp_size / (long)head_x );
surplus_size = temp_size - (long)head_x * (long)cyl_x;
if( surplus_size < min_size )
{
min_size = surplus_size;
head_set = head_x;
cyl_set = cyl_x;
}
}
}
printf( "最佳BIOS配备:");
printf( "%u柱面%u磁头%u扇区/道\n", cyl_set, head_set, sec_set);
}
void main( void )
{
unsigned int ide_info[256]; /*IDE硬盘信息输出*/
unsigned int info_off; /*信息缓冲区指针*/
unsigned int loop; /*循环指针*/
unsigned int hd_number = 0; /*系统硬盘寄存器*/
unsigned int space_hd; /*硬盘容量*/
union REGS registers; /*调用系统中断用之系统寄存器参数*/
unsigned int bios_cyl[2], bios_head[2], bios_sec[2];
/*柱面数,磁头数,每道扇区数*/
clrscr();
printf("IDE-INFO: IDE硬盘信息检测程序\n");
for( loop = 0; loop < 2; loop++ )
{
while( inp( 0x1f7 ) >= 0x80); /*等待硬盘控制器准备好*/
/* 1F7口读(状态寄存器)定义:
位: 0:=1命令执行出误
1:=1索引,每次磁盘回转一周,置该位
2:=1有被改正的错误,读取的数据被ECC算法改正
3:=1数据请求,在读/写命令过程中,扇区缓冲请求数据入/出服务
4:=1寻找结束,每当读/写头完成一个寻道动作时,置。
5:=1写故障,表示驱动器操作不当,读、写或查找动作被禁止
6:=1驱动器准备好,当该位和B4均为1时,硬盘准备好接受下一命令
7:=1忙
*/
outp( 0x1f6, ( loop==0 ? 0xa0 : 0xb0 ) ); /*选择硬盘驱动器0或1*/
/* 1F6口写(扇区尺寸/驱动器磁头选择寄存器)定义:
位:0-3:磁头选择
4:=0第一个硬盘驱动器
=1第二个硬盘驱动器
5-7:=101(不能为其它值) */
outp( 0x1f7, 0x10 ); /*复位硬盘驱动器磁头到0道*/
/* 1F7口写(命令寄存器),输入IDE硬盘控制命令,IDE硬盘命令有:
磁头回0道 1x 0001xxxx
读扇区 20-23 001000LR
写扇区 30-33 001100LR
读检验 40-41 0100000R
格式化磁道 50 01010000
查找 7x 0111xxxx
诊断 90 10010000
设置参数 91 10010001
读驱动器参数 EC 11101100
注:L=0: 正常状态,正常ECC功能 L=1: 长状态
R=0: 可以使用错误重试 R=1: 不使用错误重试 */
while( inp( 0x1f7) >= 0x80 );
if( inp( 0x1f7) != 0x50 )
{
if( hd_number == 0 )
{
printf("\b\b\b该计算机系统没有连接硬盘\n");
exit(0);
}
}
else
hd_number++;
}
printf( "系统共安装%1u个IDE硬盘,取得参数如下:\n", hd_number);
for( loop = 0; loop < hd_number; loop++ ) /*取系统所有IDE硬盘参数*/
{
/*取IDE硬盘驱动器信息*/
outp( 0x1f6, ( loop == 0 ? 0xa0 : 0xb0 ));
outp( 0x1f7, 0xec ); /*发送“读驱动器参数”指令*/
while( inp( 0x1f7 ) != 0x58 ); /*等待控制送回参数*/
for( info_off = 0; info_off != 256; info_off++ )
ide_info[info_off] = inpw( 0x1f0 ); /*读取送回的512字节数据*/
space_hd = (int)((long)ide_info[1] * (long)ide_info[3] * (long) ide_info[6] * 10 / 2048 );
printf("******************************************************\n");
printf("第%u个IDE硬盘容量:%6.2f兆\n\n", loop+1, (float)space_hd/10.0);
printf("产品型号--------------- :%s\n", string( ide_info, 27, 46));
printf("产品序列号------------- :%s\n", string( ide_info, 10, 19));
printf("控制器版本号----------- :%s\n", string( ide_info, 23, 26));
printf("控制器类型------------- :%04X\n", ide_info[20]);
printf("控制器缓冲区大小(字节) :%6u\n", ide_info[21] * 512 );
printf("能否双字传送----------- :%6s\n", (ide_info[48]==0 ? "不能" : "能" ));
printf("ECC校验码长度(字节)-- :%6u\n", ide_info[22]);
printf("每次传送扇区数--------- :%6u\n", ide_info[47]);
printf("硬盘物理柱面数--------- :%6u\n", ide_info[1]);
printf("物理头数--------------- :%6u\n", ide_info[3]);
printf("没道扇区数------------- :%6u\n", ide_info[6]);
/*取BIOS中有关硬盘信息(INT 13h之功能8)*/
registers.h.ah = 0x8;
registers.h.dl = 0x80 + loop;
int86( 0x13, ®isters, ®isters );
if( !registers.x.cflag ) /*如未置进位C,成功*/
{
bios_head[loop] = registers.h.dh + 1; /*BIOS返回头号自0开始*/
bios_sec[loop] = registers.h.cl & 0x3f; /*位5-0为每道扇区数*/
bios_cyl[loop] = (( registers.h.cl & 0xc0 ) << 2 ) + registers.h.ch + 2;
/*柱面号自0开始,并且FDISK保留最后一柱面,因而+2*/
printf( "BIOS逻辑柱面数--------- :%6u\n", bios_cyl[loop]);
printf( "逻辑头数--------------- :%6u\n", bios_head[loop]);
printf( "每道扇区数------------- :%6u\n", bios_sec[loop]);
}
best_set( ide_info[1], ide_info[3], ide_info[6]);
printf("******************************************************\n");
if( !loop ) getch();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -