『第
2 楼』:
以下是我写的TOdisk/miniTO中使用的扩展中断13的函数组,请参考
/* 检测是否支持扩展13中断 */
#include <dos.h>
/* return 1 if supports, return 0 if not */
int checkExtInt13(int driveNum)
{
union REGS in,out;
in.h.ah=0x41;
in.h.dl=driveNum;
in.x.bx=0x55AA;
int86(0x13,&in,&out);
if(out.x.bx==0xAA55) return 1;
else return 0;
}
/* 用扩展13中断获取硬盘参数 */
/* #include "zlib.h" */
#include <dos.h>
#include <stdio.h>
/* #include "zlib.h" */
/*
#define BYTE unsigned char /*定义字节数据类型名
#define unsigned short unsigned short /*定义字数据类型名
#define Dunsigned short unsigned long /*定义双字数据类型名
*/
/* return 0 if succeeds, return non-0 if fails */
int extInt13DriveParameter(int driveNum,
unsigned long *maxCylinder,
unsigned long *maxHead,
unsigned long *maxSector,
unsigned long *totalSector)
{
/*
unsigned long cylinder=0;
unsigned long head=0;
unsigned long sector=0;
unsigned long totalSectorVar=0; */
union REGS regs;
struct SREGS sregs;
struct {
unsigned short size; /*地址包大小*/
unsigned short inforflags; /*信息标志*/
unsigned long cylns; /*物理柱面数*/
unsigned long heads; /*物理磁头数*/
unsigned long sects; /*物理每柱扇区数*/
unsigned long tslow; /*扇区总数低位*/
unsigned long tshi; /*扇区总数高位*/
unsigned short bps; /*每扇区字节数*/
} package; /*LBA地址包定义*/
regs.h.ah=0x48;
regs.h.dl=(unsigned char)driveNum;
sregs.ds=FP_SEG(&package); /*获得package的段地址*/
regs.x.si=FP_OFF(&package); /*获得package的偏移量*/
int86x(0x13,®s,®s,&sregs); /*调用中断*/
if(regs.h.ah!=0) return regs.h.ah;
*maxCylinder=package.cylns;
*maxHead=package.heads;
*maxSector=package.sects;
*totalSector=package.tslow;
/*
printf("Cylinders=%lu Heads=%lu Sectors=%lu\nTotal sectors=%lu (%lu.3f GB)\n",cylinder,head,sector,totalSectorVar,totalSectorVar*512);
*/
/*
printf("Cylinders=%lu Heads=%lu Sectors=%lu\nTotal sectors=%lu (%lu MB)\n\n",
package.cylns,package.heads,package.sects,package.tslow,package.tslow/2/1024);
/*
printf("Cylinders=%lu Heads=%lu Sectors=%lu\nTotal sectors=%lu (%lu.3f GB)\n",*maxCylinder,*maxHead,*maxSector,*totalSector,(*totalSector)*512);
*/
/*
*maxCylinder=cylinder;
*maxHead=head;
*maxSector=sector;
*totalSector=totalSectorVar;
*/
return 0;
}
/* 扩展13中断,可读写大硬盘 */
#include <dos.h>
/* return 0 if succeeds, return non-0 if fails */
int extInt13(unsigned int cmd,
int driveNum,
unsigned long startSector,
unsigned int sectorToDo,
char *buf)
{
union REGS in,out;
struct SREGS sregs;
struct DiskAddressPacket
{
unsigned char PacketSize; /* 数据包尺寸(16字节) */
unsigned char Reserved; /* ==0 */
unsigned int BlockCount; /* 要传输的数据块个数(以扇区为单位) */
unsigned int BufferAddrOFF; /* 缓冲地址偏移 */
unsigned int BufferAddrSEG; /* 缓冲地址段地址 */
unsigned long BlockNumLow; /* 磁盘起始绝对块地址低位,支持4G的扇区数,就是2048G字节 */
unsigned long BlockNumHigh; /* 磁盘起始绝对块地址高位,可支持天文数字的GB,本程序未用,置0 */
}dap;
dap.PacketSize=16;
dap.Reserved=0;
dap.BlockCount=sectorToDo;
dap.BufferAddrOFF=FP_OFF(buf);
dap.BufferAddrSEG=FP_SEG(buf);
dap.BlockNumLow=startSector;
dap.BlockNumHigh=0;
in.h.ah = cmd;
in.h.dl = driveNum;
in.h.al = 0; /* 0 为无写校验,1为有 */
in.x.si = FP_OFF(&dap);
sregs.ds = FP_SEG(&dap);
int86x(0x13,&in,&out,&sregs);
return out.h.ah;
}
/* 13中断的出错提示 */
void int13Error(int cmd, int drive, unsigned long start, int returnValue)
{
/* if(cmd==0x42)*/
printf("\n%s drive:%d sector:%lu error\n",(cmd==0x42 ? "Read" : "Write"),drive,start);
/*else
{
if(cmd==0x43) printf("\nWrite drive error : \n");
} */
/* 基本13中断 */
switch(returnValue)
{
case 0x01 : printf("Bad command.\n"); break;
case 0x02 : printf("Address mark not found.\n"); break;
case 0x03 : printf("Attempt to write to write-protected disk.\n"); break;
case 0x04 : printf("Sector not found.\n"); break;
case 0x05 : printf("Reset failed (hard disk).\n"); break;
case 0x06 : printf("Disk changed since last operation.\n"); break;
case 0x07 : printf("Drive parameter activity failed.\n"); break;
case 0x08 : printf("Direct memory access (DMA) overrun.\n"); break;
case 0x09 : printf("Attempt to perform DMA across 64K boundary.\n"); break;
case 0x0A : printf("Bad sector detected.\n"); break;
case 0x0B : printf("Bad track detected.\n"); break;
case 0x0C : printf("Unsupported track.\n"); break;
case 0x10 : printf("Bad CRC/ECC on disk read.\n"); break;
case 0x11 : printf("CRC/ECC corrected data error.\n"); break;
case 0x20 : printf("Controller has failed.\n"); break;
case 0x40 : printf("Seek operation failed.\n"); break;
case 0x80 : printf("Attachment failed to respond.\n"); break;
case 0xAA : printf("Drive not ready (hard disk only).\n"); break;
case 0xBB : printf("Undefined error occurred (hard disk only).\n"); break;
case 0xCC : printf("Write fault occurred.\n"); break;
case 0xE0 : printf("Status error.\n"); break;
case 0xFF : printf("Sense operation failed.\n"); break;
/* 扩展的13中断 */
case 0xB0 : printf("Media in drive not locked.\n"); break;
case 0xB1 : printf("Media in drive locked.\n"); break;
case 0xB2 : printf("Media portable.\n"); break;
case 0xB3 : printf("Media being in use.\n"); break;
case 0xB4 : printf("Count of lock overflow.\n"); break;
case 0xB5 : printf("legal request of ejection failed.\n"); break;
}
}
使用:
操作: 0x42 读 0x43 写
if(extInt13(操作,drive+127,0,1,pBuffer))
int13Error(操作,int13Return);
|