Tc2中如何具体的使用1M以上XMS内存?非常感谢您的回答!

rdr 2000-02-18 08:43:00
我找来如下函数,但不会具体使用,万分感谢!

#include <dos.h>
#include <stdio.h>
static void far (*XMS_Faction)();

static void get_xmsentry(void)
{ _AX=0x4310; geninterrupt(0x2f);
XMS_Faction=(void far *)MK_FP(_ES,_BX);
}

int xmsinstalled(void)
{ int a; _AX=0x4300; geninterrupt(0x2f); a=_AL;
if(a!=0x80){ cputs("NO MXS Installed !");return 0;}
get_xmsentry(); return a;
}

int xmssize(unsigned int b) /* b:kb */
{ _AH=8;XMS_Faction();
if(_AX<b)return 0;/* NO Enough XMS for block ! */
else return _AX;/* return MaxSize of XMS */
}

unsigned int xmsalloc(unsigned int b) /* b: kb */
{ unsigned int a;
_DX=b;_AH=9;XMS_Faction(); a=_DX;
if(_AX!=1) return 0;
return a;
}

void xmsfree(unsigned int describ_word)
{ _DX=describ_word; _AH=0x0a; XMS_Faction(); }

/*
int xmsmove(struct para_table *q)
{ unsigned seg,off;
seg=FP_SEG((void far *)q); off=FP_OFF((void far *)q);
_DS=seg; _SI=off; _AH=0x0b; XMS_Faction();
if(_AX!=1) return 0;
return 1;
}

unsigned moveblocktoxms(char far *source,unsigned len,unsigned block,long blockoff)
{ struct para_table p;
p.block_length=len; p.source_handle=0;
p.source_addr.i[0]=FP_OFF(source); p.source_addr.i[1]=FP_SEG(source);
p.targ_handle=block; p.targ_addr.t=blockoff;
return xmsmove(&p);
}

unsigned moveblocktomem(char far *targ,unsigned xms_handle,
unsigned block_len,long blockoff )
{ struct para_table p;
p.block_length=block_len; p.source_handle=xms_handle;
p.source_addr.t=blockoff; p.targ_handle=0;
p.targ_addr.i[0]=FP_OFF(targ); p.targ_addr.i[1]=FP_SEG(targ);
return xmsmove(&p);
}
*/

main()
{
unsigned int bs,ai=0,ax=0,dx=0;
bs=100;
ai=xmsinstalled();
ax=xmssize(bs); /* b:kb */
dx=xmsalloc(bs); /* b: kb */
xmsfree(bs);
}
...全文
393 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
netmare 2000-02-26
  • 打赏
  • 举报
回复
修改程序后,已调试通过,具体原因请看所附x222.c中第114行的注释.
程序中还有一些其它错误,如因flen为unsigned int型,所以明明t2.txt的大小为
112k,但由于flen的极限为65535,所以发生溢出,应改为unsigned long.另外,由于
xmsalloc时没有保存返回的句柄,所以以后将无法释放分配的emb,导致xms内存耗
尽,我在调试时就发生了这样的事,只好reboot机器.这两个错误,我都没给改.

/*在MS-DOS下用C语言编程来实现对XMS内存的使用*/

#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
static void far (*XMS_Faction)();
struct s_addr
{ unsigned i[2];
};
struct t_addr
{ long t;
};
struct para_table
{ unsigned long block_length;
unsigned source_handle;
struct s_addr source_addr;
unsigned targ_handle;
struct t_addr targ_addr;

}p,q;

static void get_xmsentry(void)
{ _AX=0x4310; geninterrupt(0x2f);
XMS_Faction=(void far *)MK_FP(_ES,_BX);
}

int xmsinstalled(void)
{ int a; _AX=0x4300; geninterrupt(0x2f); a=_AL;
if(a!=0x80){ printf("No XMS Installed !\n");return 0;}
get_xmsentry(); return a;
}

int xmssize(unsigned int b) /* b:kb */
{ _AH=8;
XMS_Faction();
if(_AX<b)
{printf(" NO Enough XMS for block ! \n");
exit(1);}
else return _AX;/* return MaxSize of XMS */
}

unsigned int xmsalloc(unsigned int b) /* b: kb */
{ unsigned int a;
_DX=b;_AH=9;XMS_Faction(); a=_DX;
if(_AX!=1) return 0;
return a;
}

void xmsfree(unsigned int describ_word)
{ _DX=describ_word; _AH=0x0a; XMS_Faction(); }


int xmsmove(struct para_table *q)
{ unsigned long seg=0;
unsigned off=0;
seg=FP_SEG((void far *)q); off=FP_OFF((void far *)q);
_DS=seg; _SI=off; _AH=0x0b; XMS_Faction();
if(_AX==0) { printf("No move to XMS !\n");return 0;}
return 1;
}

unsigned moveblocktoxms(unsigned char far *source,unsigned len,unsigned block,long blockoff)
{
if(len%2) len--;
p.block_length=len; p.source_handle=0;
p.source_addr.i[0]=FP_OFF(source); p.source_addr.i[1]=FP_SEG(source);
p.targ_handle=block; p.targ_addr.t=blockoff;
return xmsmove(&p);
}
/*
unsigned moveblocktomem(unsigned char far *targ,unsigned xms_handle,
unsigned block_len,long blockoff )
{ struct para_table p;
p.block_length=block_len; p.source_handle=xms_handle;
p.source_addr.t=blockoff; p.targ_handle=0;
p.targ_addr.i[0]=FP_OFF(targ); p.targ_addr.i[1]=FP_SEG(targ);
return xmsmove(&p);
}
*/
main()
{
FILE *f1;
char *name="d:\\tc\\t2.txt";
unsigned bufsize=0xF000,pagenum=0,lastpage=0;
unsigned char far *buf="";
unsigned int i,k;
unsigned int bs,xsetup,flen=0;
long bo=0;
clrscr();
if((f1=fopen(name,"rb"))==NULL)
{printf("open %s error\n",name);
exit(1);}
fseek(f1,0L,SEEK_END);
flen=ftell(f1);
rewind(f1);

xsetup=xmsinstalled();
get_xmsentry();
pagenum=flen/bufsize;
lastpage=flen%bufsize;
/* for(i=1;i<=pagenum;i++)
{
k=bufsize;
if(i==pagenum)*/
k=lastpage;
if((buf=(unsigned char *)calloc(1,k))==NULL)
{ printf("Memroy Allocate error1\n");
exit(1); }
if(fread(buf,k,1,f1)!=1)
{ printf("read %s to buf then error!\n",name);
exit(1);}
xmssize(k/1024+1);
/*少分了一块emb,所以move时返回0xa7错误,表示长度无效,因为长度>emb的大小
moveblocktoxms(buf,k,xmsalloc(k/1024),bo);
*/
/*另外,如果像这样只分配,而不释放的话,没多久xms就用完了,只有重起dos才行了*/
moveblocktoxms(buf,k,xmsalloc(k/1024+1),bo);
bo+=0xF000;

/* }*/

/* moveblocktoxms(); fread();
moveblocktomem();*/
fclose(f1);
free(buf);
}
netmare 2000-02-23
  • 打赏
  • 举报
回复
我的e-mail:netmare@cmmail.com
netmare 2000-02-23
  • 打赏
  • 举报
回复
_DS与seg的值一样是正常的,因为_DS代表数据段寄存器ds,而seg是q所指向的para_table的段值,全局数据para_table就位于数据段中,所以二者是一样的.另外,seg应为16位的unsigned int型而不应是32位的long型
我也不知道为什么还不对,不如将你的程序和t2.txt发给我来试试
upstream 2000-02-23
  • 打赏
  • 举报
回复
请你再检查一下,cxl.zip约480k.我插在了附件中。
rdr 2000-02-23
  • 打赏
  • 举报
回复
netmare友:请告诉我你的Email.我好发信给你。
upstream友:今天收到了cxl.zip,很感谢!!!我得慢慢琢磨琢磨。
upstream 2000-02-22
  • 打赏
  • 举报
回复
I have mailed to you. The filename is cxl.zip.
rdr 2000-02-22
  • 打赏
  • 举报
回复
netmare友:
照你所说,改完后,结果同前一样:编译可以通过,但xmsmove()函数中的_AX返回值是0,移动无效。
另:在还没有运行到"_DS=seg;...."程序行时,_DS与seg的值就是一样的,将seg改成unsigned long类型,仍是一样。
读文件到buf中正常.
是否"seg=FP_SEG((void far *)q);"程序行有问题?
感谢你!!!

upstream友;
你发的E-mail中没有cxl.zip附件,不知何故。
netmare 2000-02-22
  • 打赏
  • 举报
回复
补充一下:打开文件时用if((f1=fopen(name,"rb"))==NULL),则读文件if(fread(buf,k,1,f1)!=1)
时就不会错了,另外,在tc2的huge模式下也通过了
netmare 2000-02-22
  • 打赏
  • 举报
回复
改为
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
static void far (*XMS_Faction)();
struct s_addr
{ unsigned i[2];
};
struct t_addr
{ long t;
};
struct para_table
{
unsigned long block_length; /*此处应为long型*/
unsigned source_handle;
struct s_addr source_addr;
unsigned targ_handle;
struct t_addr targ_addr;

}p,q;

static void get_xmsentry(void)
{ _AX=0x4310; geninterrupt(0x2f);
XMS_Faction=(void far *)MK_FP(_ES,_BX);
}

int xmsinstalled(void)
{ int a; _AX=0x4300; geninterrupt(0x2f); a=_AL;
if(a!=0x80){ printf("No XMS Installed !\n");return 0;}
get_xmsentry(); return a;
}

int xmssize(unsigned int b) /* b:kb */
{
_AH=8;
XMS_Faction();
if(_AX<b)
{printf(" NO Enough XMS for block ! \n");
exit(1);}
else return _AX;/* return MaxSize of XMS */
}

unsigned int xmsalloc(unsigned int b) /* b: kb */
{ unsigned int a;
_DX=b;_AH=9;XMS_Faction(); a=_DX;
if(_AX!=1) return 0;
return a;
}

void xmsfree(unsigned int describ_word)
{ _DX=describ_word; _AH=0x0a; XMS_Faction(); }


int xmsmove(struct para_table *q)
{ unsigned seg,off;
seg=FP_SEG((void far *)q); off=FP_OFF((void far *)q);
_DS=seg; _SI=off; _AH=0x0b; XMS_Faction();
if(_AX!=1) { printf("No move to XMS !\n");return 0;}
return 1;
}

unsigned moveblocktoxms(char far *source,unsigned len,unsigned block,long blockoff)
{
/*注意len应为偶数*/
if(len%2)
len--;
p.block_length=len; p.source_handle=0;
p.source_addr.i[0]=FP_OFF(source); p.source_addr.i[1]=FP_SEG(source);
p.targ_handle=block; p.targ_addr.t=blockoff;
return xmsmove(&p);
}
/*
unsigned moveblocktomem(char far *targ,unsigned xms_handle,
unsigned block_len,long blockoff )
{ struct para_table p;
p.block_length=block_len; p.source_handle=xms_handle;
p.source_addr.t=blockoff; p.targ_handle=0;
p.targ_addr.i[0]=FP_OFF(targ); p.targ_addr.i[1]=FP_SEG(targ);
return xmsmove(&p);
}
*/
main()
{
FILE *f1;
char *name="d:\\tc\\t2.txt";
unsigned bufsize=0xF000,pagenum=0,lastpage=0;
unsigned char *buf=NULL:
unsigned int i,k,handle;
unsigned int bs,xsetup,flen=0;
long bo=0;
clrscr();
if((f1=fopen(name,"r"))==NULL)
{printf("open %s error\n",name);
exit(1);}
fseek(f1,0L,SEEK_END);
flen=ftell(f1);
rewind(f1);

xsetup=xmsinstalled();
get_xmsentry();
pagenum=flen/bufsize;
lastpage=flen%bufsize;
/* for(i=1;i<=pagenum;i++)
{
k=bufsize;
if(i==pagenum)*/
k=lastpage;
if((buf=(unsigned char *)calloc(1,k))==NULL)
{ printf("Memroy Allocate error1\n");
exit(1); }
/*此处可能有误
if(fread(buf,k,1,f1)!=1)
{ printf("read %s to buf then error!\n",name);
exit(1);}
*/
xmssize(k/1024+1);
handle=xmsalloc(k/1024+1);
moveblocktoxms(buf,k,handle,bo);
xmsfree(handle);
bo+=0xF000;
fclose(f1);
free(buf);
}
本程序已在bc3.1的small模式通过,你在tc2下试一下,应该也没问题
rdr 2000-02-21
  • 打赏
  • 举报
回复
rdr E-mail: strawhat@mail.east.net.cn
rdr 2000-02-21
  • 打赏
  • 举报
回复
因上周机时用完,所以今天才回复,请各位原谅!
请yusuco朋友发E-mail传给我。
另本人琢磨一翻,编写了如下程序,但不能使用xmsmove()进行移动,其中t2.txt文件长度为48KB.
有劳各位,非常感谢!
/*在MS-DOS下用C语言编程来实现对XMS内存的使用*/

#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
static void far (*XMS_Faction)();
struct s_addr
{ unsigned i[2];
};
struct t_addr
{ long t;
};
struct para_table
{ unsigned block_length;
unsigned source_handle;
struct s_addr source_addr;
unsigned targ_handle;
struct t_addr targ_addr;

}p,q;

static void get_xmsentry(void)
{ _AX=0x4310; geninterrupt(0x2f);
XMS_Faction=(void far *)MK_FP(_ES,_BX);
}

int xmsinstalled(void)
{ int a; _AX=0x4300; geninterrupt(0x2f); a=_AL;
if(a!=0x80){ printf("No XMS Installed !\n");return 0;}
get_xmsentry(); return a;
}

int xmssize(unsigned int b) /* b:kb */
{ _AH=8;
XMS_Faction();
if(_AX<b)
{printf(" NO Enough XMS for block ! \n");
exit(1);}
else return _AX;/* return MaxSize of XMS */
}

unsigned int xmsalloc(unsigned int b) /* b: kb */
{ unsigned int a;
_DX=b;_AH=9;XMS_Faction(); a=_DX;
if(_AX!=1) return 0;
return a;
}

void xmsfree(unsigned int describ_word)
{ _DX=describ_word; _AH=0x0a; XMS_Faction(); }


int xmsmove(struct para_table *q)
{ unsigned seg,off;
seg=FP_SEG((void far *)q); off=FP_OFF((void far *)q);
_DS=seg; _SI=off; _AH=0x0b; XMS_Faction();
if(_AX!=1) { printf("No move to XMS !\n");return 0;}
return 1;
}

unsigned moveblocktoxms(char far *source,unsigned len,unsigned block,long blockoff)
{

p.block_length=len; p.source_handle=0;
p.source_addr.i[0]=FP_OFF(source); p.source_addr.i[1]=FP_SEG(source);
p.targ_handle=block; p.targ_addr.t=blockoff;
return xmsmove(&p);
}
/*
unsigned moveblocktomem(char far *targ,unsigned xms_handle,
unsigned block_len,long blockoff )
{ struct para_table p;
p.block_length=block_len; p.source_handle=xms_handle;
p.source_addr.t=blockoff; p.targ_handle=0;
p.targ_addr.i[0]=FP_OFF(targ); p.targ_addr.i[1]=FP_SEG(targ);
return xmsmove(&p);
}
*/
main()
{
FILE *f1;
char *name="d:\\tc\\t2.txt";
unsigned bufsize=0xF000,pagenum=0,lastpage=0;
unsigned char *buf="";
unsigned int i,k;
unsigned int bs,xsetup,flen=0;
long bo=0;
clrscr();
if((f1=fopen(name,"r"))==NULL)
{printf("open %s error\n",name);
exit(1);}
fseek(f1,0L,SEEK_END);
flen=ftell(f1);
rewind(f1);

xsetup=xmsinstalled();
get_xmsentry();
pagenum=flen/bufsize;
lastpage=flen%bufsize;
/* for(i=1;i<=pagenum;i++)
{
k=bufsize;
if(i==pagenum)*/
k=lastpage;
if((buf=(unsigned char *)calloc(1,k))==NULL)
{ printf("Memroy Allocate error1\n");
exit(1); }
if(fread(buf,k,1,f1)!=1)
{ printf("read %s to buf then error!\n",name);
exit(1);}
xmssize(k/1024);
moveblocktoxms(buf,k,xmsalloc(k/1024),bo);
bo+=0xF000;
fclose(f1);
free(buf);
}
upstream 2000-02-21
  • 打赏
  • 举报
回复
我有一个软件包,Dos编程的,支持各种C的dos实现,包含有xms使用的函数,很简单,可以
提供给你.
netmare 2000-02-21
  • 打赏
  • 举报
回复
不知道你是用什么模式编译的,请注意unsigned char *buf和unsigned moveblocktoxms(char far *source是不同的,一个是近指针,一个是远指针,二者的位数是不同的
rdr 2000-02-21
  • 打赏
  • 举报
回复
非常感谢大家的支持!
感谢yusuco朋友!
netmare:我用的是tc2.0 huge模式编译。
请upstream朋友E-mail给我,strawhat@mail.east.net.cn
yusuco 2000-02-19
  • 打赏
  • 举报
回复
我这里有一个游戏程序申请内存的代码,要就说一声!使用方便!tc3.0
netmare 2000-02-18
  • 打赏
  • 举报
回复
xmsinstalled测试是否有xms驱动程序,就是himem.sys,返回0为失败
get_xmsentry返回xms驱动程序入口地址XMS_Faction,返回0为失败
xmssize(unsigned int b)查询可用xms大小,如小于bKB返回0否则返回最大可用值
xmsalloc(unsigned int b) 分配bKB EMB,返回非0值为EMB(扩充内存块)句柄
xmsfree(unsigned int describ_word)释放EMB,describ_word就是上述的句柄
moveblocktoxms和moveblocktomem用于在常规内存和EMB之间传递数据
unsigned moveblocktoxms(char far *source,unsigned len,unsigned block,long blockoff)表示将source所指向的常规内存,复制到block代表的EMB的偏移blockoff处,长度为len.
moveblocktomem与之类似
使用方法:
1.使用xmsinstalled测试是否有xms驱动程序
2.通过get_xmsentry得到xms驱动程序入口地址XMS_Faction
3.分配所需的EMB
4.必要时在常规内存和xms之间传递数据
5.释放EMB
Firing_Sky 2000-02-18
  • 打赏
  • 举报
回复
好像要用到远指针
jiangtao 2000-02-18
  • 打赏
  • 举报
回复
xms内存不能直接使用,但可以保存你的数据,
moveblocktoxms将基本内存的数据move到XMS
movexmstoblock则反之
如你有一个1M的字库,你可以把字库全部Move到XMS上,
需要使用时再分段映射move到基本内存,才能使用

rdr 2000-02-18
  • 打赏
  • 举报
回复
感谢您的回答。
能具体些指点迷津。
不好意思,能否给个例子参考。
feng 2000-02-18
  • 打赏
  • 举报
回复
你想具体怎么用?
main()
{
unsigned int bs,ai=0,ax=0,dx=0;
bs=100;
ai=xmsinstalled();
ax=xmssize(bs); /* b:kb */
dx=xmsalloc(bs); /* b: kb */

..... /*具体的buffer快操作*/

xmsfree(bs);
}
加载更多回复(2)

69,337

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧