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毫秒