『第 2 楼』:
 
 
使用 LLM 解释/回答一下
  
以下是我写的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); 
 
    
 
  
 |