Programming 版 (精华区)
发信人: Tomgin (GTomgin), 信区: Programming
标 题: BC端口读硬盘代码
发信站: 哈工大紫丁香 (Mon Feb 23 21:56:22 2004), 站内信件
很久以前在bc31下写的代码,不要见笑。
【 在 iamxiaohan 的大作中提到: 】
: thank you very much!
: 【 在 Tomgin (GTomgin) 的大作中提到: 】
: : 给你 award bios 源码中磁盘操作部分的源码
: : 晚上在给你 c语言的源码。
: :
: :
/*
* 1999.9.28
*
* 硬盘设置为 LBA 模式
*/
//-------------------------------------
#define DEBUG 0
#include <dos.h>
#include <alloc.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define IDE_PRI_ADD 0X1F0 //主 IDE 硬盘的端口地址
#define IDE_SEC_ADD 0X170 //从 IDE 硬盘的端口地址
#define SECT_NUM 128 //一次读取 128 个扇区
#define MAX_NUM 32
#define CMD_ONE 0XE0 //命令 忘了。
typedef struct {
unsigned int aa[60];
unsigned long secnum;
unsigned int bb[194];
}DISKINFO; //读磁盘信息时需要的结构。
unsigned long get_ide_sec(int add); //取磁盘总扇区数
void showmsg(int s,char * msg ,int x,int y,long num,int flag);
unsigned int far * buffer;
void main()
{
int m=0,n=0,s=0;
char msgbuf[100];
unsigned long i,sec_num_mas,sec_num_sec;
unsigned short b,bff;
unsigned short byte;
//--------- get all sector of master disk
clrscr();
sec_num_mas=get_ide_sec(IDE_PRI_ADD);
sec_num_sec=get_ide_sec(IDE_SEC_ADD);
gotoxy(10,11);
//printf("mas: %ld sec: %ld ",sec_num_mas,sec_num_sec);
//getch();
if(sec_num_mas>sec_num_sec) {
printf("\nmas: %ld sec: %ld ",sec_num_mas,sec_num_sec);
printf("\nsecend disk big to master disk !");
exit(0);
}
buffer=(unsigned int *)farmalloc(SECT_NUM*256L*sizeof(unsigned int));
if(buffer==NULL) {
printf("can not alloc memory !");
exit(0);
}
for(i=0L;i<sec_num_mas;i=i+SECT_NUM) {
//--------- read master disk 主硬盘状态就绪
while(1) {
byte=inportb(IDE_PRI_ADD+7); // 取硬盘状态
if(byte==0x50) break; // 就绪可以发命令
if(kbhit()){//{
if(getch()=='}') { // 按 } 退出程序
farfree(buffer);
exit(0);
}
}
s++;//{
sprintf(msgbuf," } -- exit cmd mas ");
showmsg(s,msgbuf,10,12,sec_num_mas-i,1);
if(s>=4) s=0;
}
// 向主硬盘发读128个扇区数据命令
b=SECT_NUM;
outportb(IDE_PRI_ADD+2,b);
b=(unsigned short)i&0x000000ff;
outportb(IDE_PRI_ADD+3,b);
b=(unsigned short)(i>>8)&0x000000ff;
outportb(IDE_PRI_ADD+4,b);
b=(unsigned short)(i>>16)&0x000000ff;
outportb(IDE_PRI_ADD+5,b);
b=(unsigned short)((i>>24)&0x0000000f)+0xe0;
outportb(IDE_PRI_ADD+6,b);
b=0x20; //命令字
outportb(IDE_PRI_ADD+7,b);
//--------- 从硬盘状态就绪
while(1) {
byte=inportb(IDE_SEC_ADD+7);
if(byte==0x50 ) break; // 从硬盘可以发命令
if(kbhit()){//{
if(getch()=='}') {
farfree(buffer);
exit(0);
}
}
s++;//{
sprintf(msgbuf," } -- exit cmd sec ");
showmsg(s,msgbuf,10,12,sec_num_mas-i,1);
if(s>=4) s=0;
}
// 向从硬盘发写128个扇区数据命令
b=SECT_NUM;
outportb(IDE_SEC_ADD+2,b);
b=(unsigned short)i&0x000000ff;
outportb(IDE_SEC_ADD+3,b);
b=(unsigned short)(i>>8)&0x000000ff;
outportb(IDE_SEC_ADD+4,b);
b=(unsigned short)(i>>16)&0x000000ff;
outportb(IDE_SEC_ADD+5,b);
b=(unsigned short)((i>>24)&0x0000000f)+0xe0;
outportb(IDE_SEC_ADD+6,b);
b=0x30;//命令字
outportb(IDE_SEC_ADD+7,b);
for(m=0;m<SECT_NUM;m++) {
// 主硬盘可以写数据了
while(1) {
byte=inportb(IDE_PRI_ADD+7);
if(byte==0x58) break; //主硬盘可以读数据了
if(kbhit()){//{
if(getch()=='}') {
farfree(buffer);
exit(0);
}
}
}
// 从硬盘可以写数据了
while(1) {
byte=inportb(IDE_SEC_ADD+7);
if((byte&0x58)==0x58) break; //从硬盘可以写数据了
if(kbhit()){//{
if(getch()=='}') {
farfree(buffer);
exit(0);
}
}
}
// 从主盘读数据,再写到从盘
for(n=0;n<256;n++){
bff=inpw(IDE_PRI_ADD); // 读一个字
outpw(IDE_SEC_ADD,bff); // 写一个字
}
if(kbhit()){//{
if(getch()=='}') {
farfree(buffer);
exit(0);
}
}
}
s++;
sprintf(msgbuf,"UNMOVE ");
showmsg(s,msgbuf,10,12,sec_num_mas-i,1); //显示未写盘的数据
if(s>=4) s=0;
if(kbhit()){//{
if(getch()=='}') {
farfree(buffer);
exit(0);
}
}
}
farfree(buffer);
printf("\n OK !");
}
unsigned long get_ide_sec(int add)
{
int s=0,i,ss;
char msgbuf1[100];
unsigned int buf[256];
DISKINFO * di;
ss=sizeof(DISKINFO);
if(ss!=512) {
printf("struct error !");
exit(0);
}
//发读硬盘总扇区数的命令
outportb(add+6,0Xa0);
outportb(add+7,0xec);
delay(50);
while(inportb(add+7)!=0X58) { //数据准备就绪
if(kbhit()){//{
if(getch()=='}') exit(0);
}
s++;//{{
if(add==IDE_PRI_ADD) sprintf(msgbuf1," } -- exit get mas ");
else sprintf(msgbuf1," } -- exit get sec ");
showmsg(s,msgbuf1,10,12,0L,1);
if(s>=4) s=0;
}
for(i=0;i<256;i++) buf[i]=inpw(add); //读信息
(unsigned int *) di=buf;
return (di->secnum); //返回扇区数
}
void showmsg(int s,char * msg ,int x,int y,long num,int flag)
{
if(flag==1) {
gotoxy(x,y);
printf("%s%10ld ",msg,num);
}
else gotoxy(x+36,y);
switch(s) {
case 1:
putch('|');
break;
case 2:
putch('/');
break;
case 3:
putch('-');
break;
default:
putch('\\');
break;
}
}
//---------------- File End --------
--
※ 来源:.哈工大紫丁香 bbs.hit.edu.cn [FROM: 61.158.70.136]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.635毫秒