|   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『楼 主』:
 请教:DJGPP中没有FP_OFF和FP_SEG宏,怎么可以给sregs.ds赋值呢?
 
使用 LLM 解释/回答一下
  
大家好!! 
     我在用int86x(0x13,&in,&out,&sregs)执行扩展13中断调用的时候,要实现以下的赋值: 
                in.x.si = FP_OFF(&DAP_package); 
	sregs.ds =  FP_SEG(&DAP_package); 
     但是,在DJGPP编译器下没有这两个宏,而且地址又是32位的,请问各位高手有什么办法解决呢?? 
 
谢谢!! 
Hello everyone!! 
     When I use int86x(0x13, &in, &out, &sregs) to perform an extended 13 interrupt call, I need to implement the following assignments: 
                in.x.si = FP_OFF(&DAP_package); 
	sregs.ds =  FP_SEG(&DAP_package); 
     However, these two macros are not available under the DJGPP compiler, and the address is 32-bit. May I ask all the experts if there is any way to solve this problem?? 
 
Thank you!! 
    
 
  
 |   
 |  
  2006-8-6 18:39 | 
  
 |  
 |   
GOTOmsdos 
铂金会员
 
        C++启程者
  
 
积分 5154 
发帖 1827 
注册 2003-7-18 
状态 离线
 | 
『第 2 楼』:
 
 
使用 LLM 解释/回答一下
  
共你参考: 
 
#include <dos.h> 
#include <stdio.h> 
void main(){ 
unsigned char buf[51200]; 
 
FILE *f; 
unsigned int i=0; 
union REGS in,out; 
struct DiskAddressPacket 
{ 
unsigned char PacketSize; // 数据包尺寸(16字节) 
unsigned char Reserved; // ==0 
unsigned int BlockCount; // 要传输的数据块个数(以扇区为单位) 
unsigned long BufferAddr;// 传输缓冲地址(segment:offset) 
unsigned long BlockNum;// 磁盘起始绝对块地址 
//unsigned long ab; 
}dap={16,0,100,0,16434490}; 
dap.BufferAddr=(unsigned long)buf; 
 
 
in.h.ah = 0x42; 
in.h.dl = 0x81; 
in.x.si = &dap; 
//磁盘地址数据包(Disk Address Packet) 
 
f=fopen("int13ext.dat","wb+"); 
fclose(f); 
 
 
for(;i<1000;i++) 
{ 
int86(0x13,&in,&out); 
 
f=fopen("int13ext.dat","ab+"); 
fwrite(buf,512,100,f); 
fclose(f); 
 
dap.BlockNum+=100; 
printf("100 * %u\n",i); 
} 
 
} 
 
我试过可以的,但不知道是不是永远可以, 
只能说一般可以。。 
For your reference: 
 
#include <dos.h> 
#include <stdio.h> 
void main(){ 
unsigned char buf; 
 
FILE *f; 
unsigned int i=0; 
union REGS in,out; 
struct DiskAddressPacket 
{ 
unsigned char PacketSize; // Packet size (16 bytes) 
unsigned char Reserved; // ==0 
unsigned int BlockCount; // Number of data blocks to transfer (in sectors) 
unsigned long BufferAddr;// Transfer buffer address (segment:offset) 
unsigned long BlockNum;// Starting absolute block address on disk 
//unsigned long ab; 
}dap={16,0,100,0,16434490}; 
dap.BufferAddr=(unsigned long)buf; 
 
 
in.h.ah = 0x42; 
in.h.dl = 0x81; 
in.x.si = &dap; 
// Disk Address Packet (Disk Address Packet) 
 
f=fopen("int13ext.dat","wb+"); 
fclose(f); 
 
 
for(;i<1000;i++) 
{ 
int86(0x13,&in,&out); 
 
f=fopen("int13ext.dat","ab+"); 
fwrite(buf,512,100,f); 
fclose(f); 
 
dap.BlockNum+=100; 
printf("100 * %u\n",i); 
} 
 
} 
I tried it and it works, but I don't know if it will always work, 
Just to say it generally works. 
    
 
  
 |   
 |  
  2006-8-6 20:49 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 3 楼』:
 
 
使用 LLM 解释/回答一下
  
感谢GOTOmsdos的回复 
   我试过了,读写失败,可能是由于加载了dpmi的原因吧 
 
 Last edited by troylees on 2006-8-7 at 00:56 ] 
Thanks for GOTOmsdos's reply. 
I have tried it, and the read - write failed. Maybe it is because DPMI is loaded. 
 
 Last edited by troylees on 2006 - 8 - 7 at 00:56 ] 
    
 
  
 |   
 |  
  2006-8-7 00:53 | 
  
 |  
 |   
GOTOmsdos 
铂金会员
 
        C++启程者
  
 
积分 5154 
发帖 1827 
注册 2003-7-18 
状态 离线
 | 
『第 4 楼』:
 
 
使用 LLM 解释/回答一下
  
我没有 加载 DPMI ,是可以的 
I didn't load DPMI, and it's okay 
    
 
  
 |   
 |  
  2006-8-7 02:23 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 5 楼』:
 
 
使用 LLM 解释/回答一下
  
To:GOTOmsdos 
   因为DJGPP编译的程序是使用32位地址的,所以一定要加载DPMI 才能运行的 
To:GOTOmsdos 
Because the programs compiled by DJGPP use 32-bit addresses, so you must load DPMI to run them. 
    
 
  
 |   
 |  
  2006-8-7 08:03 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 6 楼』:
 
 
使用 LLM 解释/回答一下
  
To: dear all 
    问题终于解决了,是因为传统的中断调用只能访问低地址1M的内存,而DPMI下保护模式的DOS程序的缓冲区地址可能会超过1M,所以解决办法是,使用DJGPP预定义的低地址缓冲区,他的地址定义在“__tb”,然后用dosmemput和dosmemget函数实现低地址和高地址缓存区的数据交换操作。  详细看看这里 http://www.delorie.com/djgpp/v2faq/faq18_2.html 
To: dear all 
    The problem is finally solved. Because traditional interrupt calls can only access memory with a low address of 1M, and the buffer address of a DOS program in protected mode under DPMI may exceed 1M. So the solution is to use the low-address buffer predefined by DJGPP. Its address is defined as "__tb", and then use the dosmemput and dosmemget functions to implement the data exchange operation between the low-address and high-address buffers. For details, please see here  http://www.delorie.com/djgpp/v2faq/faq18_2.html 
    
 
  
 |   
 |  
  2006-8-8 12:24 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 7 楼』:
 
 
使用 LLM 解释/回答一下
  
大家可以试试以下代码: 
 
#define HANDLE_PRAGMA_PACK_PUSH_POP 1 
#pragma pack(push,1) 
typedef struct  
{ 
unsigned char  PacketSize;           
unsigned char  Reserved1;             
unsigned char  BlockCount;           		  
unsigned char  Reserved2;             
unsigned short BufferAddrOFF;        
unsigned short BufferAddrSEG;      
 unsigned long long  LBA;           
} 
DiskAddressPacket; 
#pragma pack(pop) 
 
 
int ExInt13(char cmd, char driveNum, unsigned long startSector, int sectorNum, char buf[]) 
{ 
	  __dpmi_regs  reg; 
    DiskAddressPacket DAP_package; 
 
    memset(&DAP_package, 0, sizeof(DiskAddressPacket)); 
     
    DAP_package.PacketSize = sizeof(DiskAddressPacket); 
	  DAP_package.BlockCount = sectorNum; 
	  DAP_package.BufferAddrOFF = __tb & 0x0F; 
	  DAP_package.BufferAddrSEG = __tb >> 4; 
    DAP_package.LBA = startSector; 
 
    dosmemput(&DAP_package, sizeof(DiskAddressPacket), __tb + 512 * sectorNum); 
 
    reg.h.ah = cmd; 
    reg.h.dl = driveNum; 
    reg.h.al = 0;                            
    reg.x.ds = (__tb + 512 * sectorNum) >> 4; 
    reg.x.si = (__tb + 512 * sectorNum) & 0x0F; 
     
    __dpmi_int(0x13, ®); 
 
    if((reg.x.flags & 0x0001) == 0) 
    { 
       dosmemget(__tb, 512 * sectorNum, buf); 
       return 0; 
    } 
    else 
       return(reg.h.ah); 
} 
You can try the following code: 
 
#define HANDLE_PRAGMA_PACK_PUSH_POP 1 
#pragma pack(push,1) 
typedef struct  
{ 
unsigned char  PacketSize;           
unsigned char  Reserved1;             
unsigned char  BlockCount;           		  
unsigned char  Reserved2;             
unsigned short BufferAddrOFF;        
unsigned short BufferAddrSEG;      
 unsigned long long  LBA;           
} 
DiskAddressPacket; 
#pragma pack(pop) 
 
 
int ExInt13(char cmd, char driveNum, unsigned long startSector, int sectorNum, char buf) 
{ 
	  __dpmi_regs  reg; 
    DiskAddressPacket DAP_package; 
 
    memset(&DAP_package, 0, sizeof(DiskAddressPacket)); 
     
    DAP_package.PacketSize = sizeof(DiskAddressPacket); 
	  DAP_package.BlockCount = sectorNum; 
	  DAP_package.BufferAddrOFF = __tb & 0x0F; 
	  DAP_package.BufferAddrSEG = __tb >> 4; 
    DAP_package.LBA = startSector; 
 
    dosmemput(&DAP_package, sizeof(DiskAddressPacket), __tb + 512 * sectorNum); 
 
    reg.h.ah = cmd; 
    reg.h.dl = driveNum; 
    reg.h.al = 0;                            
    reg.x.ds = (__tb + 512 * sectorNum) >> 4; 
    reg.x.si = (__tb + 512 * sectorNum) & 0x0F; 
     
    __dpmi_int(0x13, ®); 
 
    if((reg.x.flags & 0x0001) == 0) 
    { 
       dosmemget(__tb, 512 * sectorNum, buf); 
       return 0; 
    } 
    else 
       return(reg.h.ah); 
} 
    
 
  
 |   
 |  
  2006-8-8 12:27 | 
  
 |  
 |   
BSLTT 
初级用户
 
  
 
  
  
积分 59 
发帖 18 
注册 2005-12-25 
状态 离线
 | 
『第 8 楼』:
 
 
使用 LLM 解释/回答一下
  
楼主你好!请问你所写的这个扩展int13是否可以获取磁盘参数 
呢?? 
 
我在调用工能号48H时出错! 
 
INT 13  AH=48H 
 
谢谢~! 
 
 Last edited by BSLTT on 2006-8-12 at 04:30 ] 
Hello, LZ! May I ask if the extended int13 you wrote can obtain disk parameters?? 
 
I got an error when calling function number 48H! 
 
INT 13  AH=48H 
 
Thanks~! 
 
 Last edited by BSLTT on 2006-8-12 at 04:30 ] 
    
 
  
 |   
 |  
  2006-8-12 02:39 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
 |  
  2006-8-12 23:31 | 
  
 |  
 |   
BSLTT 
初级用户
 
  
 
  
  
积分 59 
发帖 18 
注册 2005-12-25 
状态 离线
 | 
『第 10 楼』:
 
 
使用 LLM 解释/回答一下
  
谢谢!问题已解决~! thank you~! 
Thanks! The problem has been solved~! thank you~! 
    
 
  
 |   
 |  
  2006-8-13 02:05 | 
  
 |  
 |   
GOTOmsdos 
铂金会员
 
        C++启程者
  
 
积分 5154 
发帖 1827 
注册 2003-7-18 
状态 离线
 | 
『第 11 楼』:
 
 
使用 LLM 解释/回答一下
  
谁能解释一下: 
地址为什么是 __tb + 512 * sectorNum ? 
跟要读写的硬盘扇区的个数有什么关系?? 
Who can explain: 
Why is the address __tb + 512 * sectorNum? 
What is the relationship with the number of hard disk sectors to be read and written?? 
    
 
  
 |   
 |  
  2007-2-24 10:09 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 12 楼』:
 
 
使用 LLM 解释/回答一下
  
__dpmi_int(0x13, ®)执行以后就会把硬盘扇区信息读出到__tb开始的内存,长度为512 * sectorNum,所以,你必须把DAP_package复制到__tb + 512 * sectorNum地址后面以留出空间。 
不好意思,因为寒假回家了,所以现在才回复,多谢大家的关注!! 
After executing __dpmi_int(0x13, ®), the hard disk sector information will be read into the memory starting from __tb, with a length of 512 * sectorNum. Therefore, you must copy the DAP_package to the address behind __tb + 512 * sectorNum to leave space. 
I'm sorry, because I went home for winter vacation, so I'm replying now. Thanks for everyone's attention! 
    
 
  
 |   
 |  
  2007-3-1 09:44 | 
  
 |  
 |   
GOTOmsdos 
铂金会员
 
        C++启程者
  
 
积分 5154 
发帖 1827 
注册 2003-7-18 
状态 离线
 | 
『第 13 楼』:
 
 
使用 LLM 解释/回答一下
  
可是,你的这个代码,我编译,运行都没问题,可是,写的是0字节...尽管文件大小是有的  
另外,下了两个源码,一个国人的,一个老外的,实验结果是: 
国人的仍然是读写成0字节 
老外的成功了... 
不知道什么原因... 
However, with your code, I have no problem compiling and running it, but it writes 0 bytes... Although the file size is there.  
 
In addition, I downloaded two source codes, one from a Chinese person and one from a foreigner. The experimental results are:  
 
The Chinese one still reads and writes 0 bytes.  
 
The foreign one succeeded...  
 
I don't know the reason... 
    
 
  
 |   
 |  
  2007-3-1 10:56 | 
  
 |  
 |   
troylees 
初级用户
 
  
 
  
  
积分 54 
发帖 19 
注册 2006-7-31 
状态 离线
 | 
『第 14 楼』:
 
 
使用 LLM 解释/回答一下
  
这是我的代码,你试试吧,我运行过没问题的: 
 
#include <stdio.h>  
#include <conio.h>  
#include <process.h>  
#include <bios.h>  
#include <dos.h> 
#include <math.h>  
#include <dir.h>  
#include <stdlib.h>  
#include <string.h>                       
#include <unistd.h>                       
#include <sys/stat.h> 
#include <sys/movedata.h> 
#include <go32.h> 
#include <dpmi.h> 
 
 
#define HANDLE_PRAGMA_PACK_PUSH_POP 1 
#pragma pack(push,1) 
typedef struct  
{ 
		 unsigned char  PacketSize;           /* 数据包尺寸(16字节) */ 
		 unsigned char  Reserved1;            /* 置0 */ 
		 unsigned char  BlockCount;           /* 要传输的数据块个数(以扇区为单位) */ 
		 unsigned char  Reserved2;            /* 置0 */ 
		 unsigned short BufferAddrOFF;        /* 缓冲区偏移地址 */ 
		 unsigned short BufferAddrSEG;        /* 缓冲区段地址 */ 
		 unsigned long long  LBA;             /* 磁盘起始绝对块地址*/ 
} 
DiskAddressPacket; 
#pragma pack(pop) 
 
 
/* 用扩展13中断,读写大硬盘 */                
int ExInt13(char cmd, char driveNum, unsigned long startSector, int sectorNum, char buf[]) 
{ 
	  __dpmi_regs  reg; 
    DiskAddressPacket DAP_package; 
 
    memset(&DAP_package, 0, sizeof(DiskAddressPacket)); 
     
    DAP_package.PacketSize = sizeof(DiskAddressPacket); 
	  DAP_package.BlockCount = sectorNum; 
	  DAP_package.BufferAddrOFF = __tb & 0x0F; 
	  DAP_package.BufferAddrSEG = __tb >> 4; 
    DAP_package.LBA = startSector; 
 
    dosmemput(&DAP_package, sizeof(DiskAddressPacket), __tb + 512 * sectorNum); 
 
    reg.h.ah = cmd; 
    reg.h.dl = driveNum; 
    reg.h.al = 0;                            /* 0 为无写校验,1为有 */ 
    reg.x.ds = (__tb + 512 * sectorNum) >> 4; 
    reg.x.si = (__tb + 512 * sectorNum) & 0x0F; 
     
    __dpmi_int(0x13, ®); 
 
    if((reg.x.flags & 0x0001) == 0) 
    { 
       dosmemget(__tb, 512 * sectorNum, buf); 
       return 0; 
    } 
    else 
       return(reg.h.ah); 
} 
 
 
 
int main(void)  
{  
   int  i, result, temp;  
   unsigned long log_sector; 
   char buf[512];  
   char s[5]; 
 
   scanf("%lu", &log_sector);                   /*输入扇区号*/ 
 
   result = ExInt13(0x42, 0x80, log_sector, 1, buf);    /*读磁盘扇区*/ 
 
   if (result!= 0)                              /*判断是否操作成功*/ 
   {  
      perror("Read Disk Error");                /*不成功显示出错*/ 
      exit(1);  
   }  
 
   printf("Read OK\n");                          /*成功显示"ok"*/ 
 
   for (i=446; i<512; i++)                       /*循环读出分区表*/ 
   {   
   	  if(buf[i] < 0)                             /*将ascii为负值的变为正值*/ 
   	     temp = buf[i] + 256; 
   	  else 
   	     temp = buf[i]; 
      sprintf(s, "%x", temp);                     /*将分区表内容格式转换为16进制*/ 
       
      if(temp < 16)         
         printf("0%s", s);                        /*输出显示*/ 
      else 
         printf("%s", s);    
      printf(" "); 
       
      if((i==461)||(i==477)||(i==493)||(i==509)) 
         printf("\n");  
   }  
    
   getch();  
   return(0);  
} 
This is my code, you can try it, I have run it without problems: 
 
#include <stdio.h>  
#include <conio.h>  
#include <process.h>  
#include <bios.h>  
#include <dos.h> 
#include <math.h>  
#include <dir.h>  
#include <stdlib.h>  
#include <string.h>                       
#include <unistd.h>                       
#include <sys/stat.h> 
#include <sys/movedata.h> 
#include <go32.h> 
#include <dpmi.h> 
 
 
#define HANDLE_PRAGMA_PACK_PUSH_POP 1 
#pragma pack(push,1) 
typedef struct  
{ 
		 unsigned char  PacketSize;           /* Packet size (16 bytes) */ 
		 unsigned char  Reserved1;            /* Set to 0 */ 
		 unsigned char  BlockCount;           /* Number of data blocks to transfer (in sectors) */ 
		 unsigned char  Reserved2;            /* Set to 0 */ 
		 unsigned short BufferAddrOFF;        /* Buffer offset address */ 
		 unsigned short BufferAddrSEG;        /* Buffer segment address */ 
		 unsigned long long  LBA;             /* Absolute block address on disk start */ 
} 
DiskAddressPacket; 
#pragma pack(pop) 
 
 
/* Use extended 13 interrupt to read and write large hard drives */                
int ExInt13(char cmd, char driveNum, unsigned long startSector, int sectorNum, char buf) 
{ 
	  __dpmi_regs  reg; 
    DiskAddressPacket DAP_package; 
 
    memset(&DAP_package, 0, sizeof(DiskAddressPacket)); 
     
    DAP_package.PacketSize = sizeof(DiskAddressPacket); 
	  DAP_package.BlockCount = sectorNum; 
	  DAP_package.BufferAddrOFF = __tb & 0x0F; 
	  DAP_package.BufferAddrSEG = __tb >> 4; 
    DAP_package.LBA = startSector; 
 
    dosmemput(&DAP_package, sizeof(DiskAddressPacket), __tb + 512 * sectorNum); 
 
    reg.h.ah = cmd; 
    reg.h.dl = driveNum; 
    reg.h.al = 0;                            /* 0 for no write check, 1 for with */ 
    reg.x.ds = (__tb + 512 * sectorNum) >> 4; 
    reg.x.si = (__tb + 512 * sectorNum) & 0x0F; 
     
    __dpmi_int(0x13, ®); 
 
    if((reg.x.flags & 0x0001) == 0) 
    { 
       dosmemget(__tb, 512 * sectorNum, buf); 
       return 0; 
    } 
    else 
       return(reg.h.ah); 
} 
 
 
 
int main(void)  
{  
   int  i, result, temp;  
   unsigned long log_sector; 
   char buf;  
   char s; 
 
   scanf("%lu", &log_sector);                   /* Enter sector number */ 
 
   result = ExInt13(0x42, 0x80, log_sector, 1, buf);    /* Read disk sector */ 
 
   if (result!= 0)                              /* Determine if operation is successful */ 
   {  
      perror("Read Disk Error");                /* If not successful, display error */ 
      exit(1);  
   }  
 
   printf("Read OK\n");                          /* If successful, display "ok" */ 
 
   for (i=446; i<512; i++)                       /* Loop to read partition table */ 
   {   
   	  if(buf < 0)                             /* Convert negative ASCII values to positive */ 
   	     temp = buf + 256; 
   	  else 
   	     temp = buf; 
      sprintf(s, "%x", temp);                     /* Convert partition table content to hexadecimal format */ 
       
      if(temp < 16)         
         printf("0%s", s);                        /* Output display */ 
      else 
         printf("%s", s);    
      printf(" "); 
       
      if((i==461)||(i==477)||(i==493)||(i==509)) 
         printf("\n");  
   }  
    
   getch();  
   return(0);  
} 
    
 
  
 |   
 |  
  2007-3-1 12:07 | 
  
 |  
  |