📄 xpok.cpp
字号:
}
void PrintIdeInfo1 (WORD diskdata [256])
{
unsigned char hqtchk[512];
unsigned char *fpbak;
int i, j, zch;
int hqtliang = 0;
int p=0;
for(int i1=0;i1<256;i1++)
{
hqtchk[i1*2] = (unsigned char)diskdata [i1];
hqtchk[i1*2+1]= diskdata [i1]>>8;
}
for (i = 0; i < 32; i++)
{
if (i == 0) printf ("%04X ",i+128*hqtliang);
else printf ("%04X ",i*16+128*hqtliang);
for (j = 0; j < 16; j++)
{
fpbak=&hqtchk[i*16+j+128*hqtliang];
zch=*fpbak;
printf("%02X ",zch);
if(j==7) printf("\b-");
}
printf(" ");
for(j=0;j<16;j++)
{
if(hqtchk[i*16+j+128*hqtliang]==0x09||hqtchk[i*16+j+128*hqtliang]==0x0A||hqtchk[i*16+j+128*hqtliang]==0x0d||hqtchk[i*16+j+128*hqtliang]==0x07||hqtchk[i*16+j+128*hqtliang]==0x08)
printf(".");
else
if (hqtchk[i*16+j+128*hqtliang] == 0xFF)
printf(" ");
else putchar(hqtchk[i*16+j+128*hqtliang]);
}
printf ("\n");
}
}
//参数不用指针是为了工作于多线程
BOOL SW_InOutDriveCmd (int drive1, int InOut, BOOL lab ,BYTE Cmd[7], WORD buf[256] )
//设备号,是读还是写,读写模式,命令与参数,数据区
{
BOOL done = FALSE;
long waitLoop = 0;
int index = 0;
int RW = InOut ;
int drive = drive1 ; //设备号
WORD baseAddress = 0; //设备寄存器的基地址
WORD IDE = 0; //交换状态/IDE控制器寄存器地址
WORD portValue = 0; //辅助的变量用于读端口反回值
WORD IDEDIR = 0; //设备选择参数
WORD diskdata[256]; //数据缓冲
BOOL LAB = lab ; //设备工作模式
BYTE disk[7]; //要执行的命令与命令参数
//------------------------参数检查开始 ---------------------------------------------
if( drive > 3 ) { printf("设备号超出范围\n");return done; }//检查设备号是否超出范围
if((RW>1)||(RW<0)){ printf("InOut参数只能是 0读 或 1写\n");return done; }//检查设备号是否超出范围
if( Cmd[5]>0x0F ){ printf("Cmd[5]只能填写底4位\n");return done; }
//------------------------参数检查结束 ---------------------------------------------
//------------------- 初始化变量开始 -------------------------------------
//初始化设备所有寄存器的其始地址 与 交换状态/IDE控制器 端口地址
switch (drive / 2)
{
case 0: {baseAddress = 0x1f0; break; IDE=0x3f6;}
case 1: {baseAddress = 0x170; break; IDE=0x376;}
//case 2: baseAddress = 0x1e8; break;
//case 3: baseAddress = 0x168; break;
}
//初始化数据缓冲
if(RW==0)//如果是读
{
for (index = 0; index < 256; index++)
diskdata [index] = 0;
}
if(RW==1) //如果是写
{
for (index = 0; index < 256; index++)
diskdata [index] = buf[index];
}
//初始化要执行的命令与命令参数
disk[0] = Cmd[0]; //错误寄存器/功能
disk[1] = Cmd[1]; //扇区数寄存器
disk[2] = Cmd[2]; //扇区号寄存器
disk[3] = Cmd[3]; //柱面号寄存器底字节
disk[4] = Cmd[4]; //柱面号寄存器高字节
disk[5] = Cmd[5]; //设备选择/磁头寄存器 磁头参数只用低4位请只设低4位的值
disk[6] = Cmd[6]; //命令/状态寄存器(这里设定的是查看硬盘信息命令F8)
//初始化设备选择参数
if ((drive % 2) == 0) //如果选择是主设备
{
if(LAB)
IDEDIR=0xE0;//驱动器是LBA模式
else
IDEDIR=0xA0;//驱动器是CHS模式
}
else //如果选择是从设备
{
if(LAB)
IDEDIR=0xF0;//驱动器是LBA模式
else
IDEDIR=0xB0;//驱动器是CHS模式
}
//------------------- 初始化变量结束 -------------------------------------
//------------------- 选设备过程开始 -------------------------------------
//等待 BYS DRQ EER为0
waitLoop = 100000;
while (--waitLoop > 1)
{
if(waitLoop<4) {printf("选择设备失败0\n");return done;}
portValue=InPortB(IDE);
if ((portValue & 0x89) == 0x00) break; //BYS DRQ EER 设备不忙,不准备传数据,没有出错
}
//写选设备寄存器
OutPortB(baseAddress + 6, IDEDIR+disk[5]);
//等待 BYS DRQ EER为0
waitLoop = 100000000;
while (--waitLoop > 1)
{
if(waitLoop<4) {printf("选择设备失败1\n");return done;}
portValue=InPortB(IDE);
if ((portValue & 0x88) == 0x00) break; //BYS DRQ 设备不忙,不准备传数据.
if ((portValue & 0x01) == 0x01){ return done; }//出错退出
}
//---------------------- 选设备过程结束 ----------------------------
//---- 关中断 ----
OutPortB(IDE, 0x02); //可择 这里不要那后面的 开中断也不能要
//---- 关中断 ----
//---------------------- 写参数写命令过程开始 ------------------------
//写参数
if((disk[6]==0x20)||(disk[6]==0x30))//如果是读写扇区命令
{
OutPortB(baseAddress + 2, disk[1]);//扇区数
OutPortB(baseAddress + 3, disk[2]);//扇区号/LBA 0:7
OutPortB(baseAddress + 4, disk[3]);//柱面号寄存器底字节 /lBA 8:15
OutPortB(baseAddress + 5, disk[4]);//柱面号寄存器高字节 /LBA 16:23
//OutPortB(baseAddress + 6, (disk[5]+IDEDIR));//0:3 磁头 /LBA 24:27
}
//写功能
OutPortB(baseAddress + 1, disk[0]);//功能
//写命令
OutPortB(baseAddress + 7, disk[6]);
//等待 BYS 0
waitLoop = 100000;
while (--waitLoop > 0)
{
if(waitLoop<4) {printf("命令执行失败0\n");return done;}
InPortB(IDE); //读交一下交互状态寄存器 使主机在读它时它的值是有效的
portValue=InPortB(baseAddress + 7);
if ((portValue & 0x80) == 0x00) //BYS 如果设备不忙
{
//如果设备出错就读交互状态寄存器,开中断,并退出返回失败
if ((portValue & 0x01) == 0x01){printf("命令执行失败1\n");OutPortB(IDE, 0x00);return done;}
//如果设备准备好数据传送
if ((portValue & 0x58) == 0x58){ break; }
}
}
//----------------- 写参数写命令过程结束-------------------------------------------------
//----------------- 数据传输开始 -------------------------------------------------------
//-----传数据-----
if(RW==0)//如果是读
{
for (index = 0; index < 256; index++)
diskdata [index]=InPortW(baseAddress);
}
if(RW==1) //如果是写
{
for (index = 0; index < 256; index++)
OutPortW(baseAddress,diskdata [index]);
}
//----等待 BYS 0-----
waitLoop = 100000;
while (--waitLoop > 0)
{
if(waitLoop<4) {printf("传数据失败0\n");return done;}
InPortB(IDE); //读交一下交互状态寄存器 使主机在读它时它的值是有效的
portValue=InPortB(baseAddress + 7);
if ((portValue & 0x80) == 0x00) //BYS 如果设备不忙
{
//如果设备出错就读交互状态寄存器,开中断,并退出返回失败
if ((portValue & 0x01) == 0x01){printf("传数据失败1\n");OutPortB(IDE, 0x00);return done;}
//如果设备准备好数据传送
if ((portValue & 0x40) == 0x40){ break; }
}
}
//----------------- 数据传输结束 -------------------------------------------------------
//---- 关中断 ----
OutPortB(IDE, 0x00); //可择 这里不要那后面的 开中断也不能要
//---- 关中断 ----
//---------------- 后期处理开始 -------------------------------------------------------
if(RW==0) //如果是读
{
for (index = 0; index < 256; index++)
buf[index] = diskdata [index];
}
//---------------- 后期处理结束 -------------------------------------------------------
//----------------- 显示开始 -------------------------------------------------------
//PrintIdeInfo1(diskdata);
//----------------- 显示结束 -------------------------------------------------------
done = true;
return done;
}
//参数不用指针是为了工作于多线程
BOOL SW_NoDriveCmd (int drive1,BOOL lab ,BYTE Cmd[7])
//设备号,读写模式,命令与参数,
{
BOOL done = FALSE;
long waitLoop = 0;
int index = 0;
int drive = drive1 ; //设备号
WORD baseAddress = 0; //设备寄存器的基地址
WORD IDE = 0; //交换状态/IDE控制器寄存器地址
WORD portValue = 0; //辅助的变量用于读端口反回值
WORD IDEDIR = 0; //设备选择参数
BOOL LAB = lab ; //设备工作模式
BYTE disk[7]; //要执行的命令与命令参数
//------------------------参数检查开始 ---------------------------------------------
if( drive > 3 ) { printf("设备号超出范围\n");return done; }//检查设备号是否超出范围
if( Cmd[5]>0x0F ){ printf("Cmd[5]只能填写底4位\n");return done; }
//------------------------参数检查结束 ---------------------------------------------
//------------------- 初始化变量开始 -------------------------------------
//初始化设备所有寄存器的其始地址 与 交换状态/IDE控制器 端口地址
switch (drive / 2)
{
case 0: {baseAddress = 0x1f0; break; IDE=0x3f6;}
case 1: {baseAddress = 0x170; break; IDE=0x376;}
//case 2: baseAddress = 0x1e8; break;
//case 3: baseAddress = 0x168; break;
}
//初始化要执行的命令与命令参数
disk[0] = Cmd[0]; //错误寄存器/功能
disk[1] = Cmd[1]; //扇区数寄存器
disk[2] = Cmd[2]; //扇区号寄存器
disk[3] = Cmd[3]; //柱面号寄存器底字节
disk[4] = Cmd[4]; //柱面号寄存器高字节
disk[5] = Cmd[5]; //设备选择/磁头寄存器 磁头参数只用低4位请只设低4位的值
disk[6] = Cmd[6]; //命令/状态寄存器(这里设定的是查看硬盘信息命令F8)
//初始化设备选择参数
if ((drive % 2) == 0) //如果选择是主设备
{
if(LAB)
IDEDIR=0xE0;//驱动器是LBA模式
else
IDEDIR=0xA0;//驱动器是CHS模式
}
else //如果选择是从设备
{
if(LAB)
IDEDIR=0xF0;//驱动器是LBA模式
else
IDEDIR=0xB0;//驱动器是CHS模式
}
//------------------- 初始化变量结束 -------------------------------------
//------------------- 选设备过程开始 -------------------------------------
//等待 BYS DRQ EER为0
waitLoop = 100000;
while (--waitLoop > 1)
{
if(waitLoop<4) {printf("选择设备失败0\n");return done;}
portValue=InPortB(IDE);
if ((portValue & 0x89) == 0x00) break; //BYS DRQ EER 设备不忙,不准备传数据,没有出错
}
//写选设备寄存器
OutPortB(baseAddress + 6, IDEDIR+disk[5]);
//等待 BYS DRQ EER为0
waitLoop = 100000000;
while (--waitLoop > 1)
{
if(waitLoop<4) {printf("选择设备失败1\n");return done;}
portValue=InPortB(IDE);
if ((portValue & 0x88) == 0x00) break; //BYS DRQ 设备不忙,不准备传数据.
if ((portValue & 0x01) == 0x01){ return done; }//出错退出
}
//---------------------- 选设备过程结束 ----------------------------
//---- 关中断 ----
OutPortB(IDE, 0x02); //可择 这里不要那后面的 开中断也不能要
//---- 关中断 ----
//---------------------- 写参数写命令过程开始 ------------------------
//写参数
OutPortB(baseAddress + 1, disk[0]);//功能
OutPortB(baseAddress + 2, disk[1]);//扇区数
OutPortB(baseAddress + 3, disk[2]);//扇区号/LBA 0:7
OutPortB(baseAddress + 4, disk[3]);//柱面号寄存器底字节 /lBA 8:15
OutPortB(baseAddress + 5, disk[4]);//柱面号寄存器高字节 /LBA 16:23
//OutPortB(baseAddress + 6, (disk[5]+IDEDIR));//0:3 磁头 /LBA 24:27
//写命令
OutPortB(baseAddress + 7, disk[6]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -