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