| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3307 人关注过本帖
标题:XMS还是不好使呀!
只看楼主 加入收藏
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
 问题点数:0 回复次数:25 
XMS还是不好使呀!

现存程序可以正常运行了,可是当图片复原后和图片的背景不完全一样呀!大家帮忙给看一看
最下面是整个程序包


#include "graphics.h"
#include<dos.h>

#include<conio.h>

#include "stdio.h"
#include "fcntl.h"
#include "malloc.h"
#include "io.h"
#include "showbmp.c"
#include "rsvga256.h"

typedef unsigned int XMS_HANDLE;
XMS_HANDLE xms_handle; /* 伪指针 */
XMS_HANDLE xms_save_restore_handle; /* 伪指针 */

typedef struct emm {
unsigned int length;
unsigned source_handle;
unsigned long source_offset;
unsigned dest_handle;
unsigned long dest_offset;
} xmm;
xmm xms;

int far(* XMS_Function)( );
int xms_installed( )
{
_AX=0x4300;
geninterrupt(0x2f);
if(_AL==0x80)
{
_AX=0x4310;
geninterrupt(0x2f);
XMS_Function=MK_FP(_ES,_BX);
return(1);
}
else
{
printf("XMS is not installed\n!");
return(0);
}
}

int test_xms(unsigned int size)
{
_AH=8;
XMS_Function( );
if(_AX<size)
{
printf("No enough XMS to be used!\n");
return(0);
}
else
return(1);
}

unsigned int alloc_xms(unsigned int size)
{
_DX=size;
_AH=9;
XMS_Function( );
if(_AX!=1)
{
printf("XMS allocation is error\n");
return(0);
}
else
return(_DX);
}


int move_xms()
{
if(XMS_Function( ))
{
_DS=FP_SEG(&xms);
_SI=FP_OFF(&xms);
_AH=0x0b;
XMS_Function( );

if(_AX!=1)
{
printf("XMS move error! %d\n",_BL);
return(0);
}

return(1);
}
else
return(0);
}

void free_xms(unsigned int handle)
{
_DX=handle;
_AH=0x0a;
XMS_Function( );
}


/*----------------------------------------------------------- */
/* 从常规内存缓冲区buf装载到扩充内存 */
/*-----------------------------------------------------------*/


void Write_To_XMS(char *buf, unsigned int size,unsigned handle,unsigned long offset)
{
xms.length=size;
xms.source_handle = 0;
xms.source_offset = FP_SEG((void far *)buf);
xms.source_offset <<= 16;
xms.source_offset += FP_OFF((void far *)buf);
xms.dest_handle = handle;
xms.dest_offset = offset;
move_xms(&xms);
}


/*----------------------------------------------------------- */
/* 从扩充内存中读取信息到常规内存缓冲区buf */
/*-----------------------------------------------------------*/
void Read_From_XMS(char *buf,unsigned int size,unsigned handle,unsigned long offset)
{
xms.length = size;
xms.source_handle = handle;
xms.source_offset = offset;
xms.dest_handle = 0;
xms.dest_offset = FP_SEG((void far *)buf);
xms.dest_offset <<= 16;
xms.dest_offset += FP_OFF((void far *)buf);
move_xms(&xms);
}


char sssbuf[300];
void Save_Image_XMS(int POPUP_x1,int POPUP_x2,int POPUP_y1,int POPUP_y2 )
{
int i,j;
unsigned int size;
unsigned long offset = 0;
char *pp;

size = (POPUP_x2-POPUP_x1+1)*(POPUP_y2-POPUP_y1+1)/1024+1;

if (test_xms(size)==0)
puts("not enough XMS");
if ((xms_save_restore_handle = alloc_xms(size)) == 0)
puts("XMS handle Error...\n");
for (i= POPUP_y1; i<=POPUP_y2;i++)
{
size = POPUP_x2-POPUP_x1;
pp = sssbuf;
for (j= POPUP_x1; j<=POPUP_x2;j++)
*pp++ = getpixel(j,i);
Write_To_XMS(sssbuf,size,xms_save_restore_handle,offset);
offset += size;
}
}


void Restore_Image_XMS(int POPUP_x1,int POPUP_x2,int POPUP_y1,int POPUP_y2)
{
int i,j;
unsigned short size;
unsigned long offset = 0;
char *pp;

size = POPUP_x2-POPUP_x1;
for (i= POPUP_y1; i<=POPUP_y2;i++)
{
Read_From_XMS(sssbuf,size,xms_save_restore_handle,offset);
offset += size;
pp = sssbuf;
for (j= POPUP_x1; j<=POPUP_x2;j++)
putpixel(j,i,*pp++);/* sssbuf[j-POPUP_x1]); */
}
free_xms(xms_save_restore_handle);
}


int huge rReturn_SVGA256(void)
{
return(SVGA640x480x256);
}

void main()
{ int iii=DETECT, jjj=0;
int aa=30;
installuserdriver("Svga256", rReturn_SVGA256); /* 对于svga256必需执行该函数以安装BGI驱动 */
initgraph(&iii, &jjj, "");
xms_installed( ); /*初始化一定要写上*/

show_bmp("main.bmp",0,0);
Save_Image_XMS(50,139,50,176 );
getch();
show_bmp("bell.bmp",50,50);
getch();
Restore_Image_XMS(50,139,50,176);
getch();
closegraph();
}


HQNbOLSc.rar (15.62 KB) XMS还是不好使呀!


搜索更多相关主题的帖子: XMS 
2007-09-20 09:56
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
大家帮帮忙吧,我实在是能不出来呀
2007-09-21 13:31
RockCarry
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
收藏
得分:0 
用 VC 吧,在内存使用上不再有烦恼。
2007-09-21 19:19
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
我是用PC104编程,相当于486的机器,windows 启动不起来呀
2007-09-22 09:15
kk4868
Rank: 1
等 级:新手上路
帖 子:77
专家分:0
注 册:2007-6-3
收藏
得分:0 

传递给XMS句柄的必须为偶数


2007-09-24 08:27
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
得分:0 

我给你点源代码吧!,已经成功运用于MSDOS6.22操作系统。

struct GUI_STACK
{
unsigned int x1;
unsigned int y1;
unsigned int x2;
unsigned int y2;
XMS_HANDLE handle; // XMS句柄
};

/////////////////////////////////////////////////////////////////////////////////////////////////
////测试堆栈是否为空
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl Stack_Empty(void)
{
if (GUI_SP == 0)
return (TRUE);
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////测试堆栈是否溢出
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl Stack_Full(void)
{
if (GUI_SP == 3)
return (TRUE);
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////窗口区域及窗口句柄入栈
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl PUSH_Stack(int x1,int y1,int x2,int y2,XMS_HANDLE handle)
{
if (!Stack_Full())
{
GUI_SP++;
GUI_Stack[GUI_SP].x1 = x1;
GUI_Stack[GUI_SP].y1 = y1;
GUI_Stack[GUI_SP].x2 = x2;
GUI_Stack[GUI_SP].y2 = y2;
GUI_Stack[GUI_SP].handle = handle;
return (TRUE);
}
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////窗口区域及窗口句柄出栈
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl POP_Stack(void)
{
if (!Stack_Empty())
{
GUI_SP--;
return (TRUE);
}
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////获取栈顶.x1
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl TOP_X1(void)
{
return (GUI_Stack[GUI_SP].x1);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////获取栈顶.x2
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl TOP_X2(void)
{
return (GUI_Stack[GUI_SP].x2);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////获取栈顶.y1
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl TOP_Y1(void)
{
return (GUI_Stack[GUI_SP].y1);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////获取栈顶.y2
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl TOP_Y2(void)
{
return (GUI_Stack[GUI_SP].y2);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
////获取栈顶.handle
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl TOP_Handle(void)
{
return (GUI_Stack[GUI_SP].handle);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//检测XMS是否安装
// INT 2F - XMS 驱动程序安装检测
// 输入参数:AX = 4300h
// 返回值: AL = 80h XMS 驱动程序已安装
// AL <> 80h 未发现XMS 驱动程序
// 注: XMS 使你可以访问扩充内存以及其它的高于640K的非EMS内存,
// 其它程序不得使用与之相同的安装检测方式
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl XMS_Test(void)
{
_AX = 0x4300;
__int__(0x2F);
if (_AL == 0x80) // 检查XMS驱动程序是否已经安装
{
_AX = 0x4310;
__int__(0x2F); // 取得XMS功能调用的地址
XMS_Function=(void far *)MK_FP(_ES,_BX); // 返回值:ES:BX -> 驱动程序入口地址
return (TRUE);
}
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
// 说明: 获取XMS驱动器版本号
// 参数: 返回参数: XMS驱动器版本号
/////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int _Cdecl XMS_Version(void)
{
_AH = 0x00;
(XMS_Function)();
return (_AX);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//查询空闲的扩充内存空间(不包括HMA)
//输入参数:AH = 08h
//返回值:AX = 最大的扩充内存块的大小(单位:K)
//DX = 总的扩充内存块的大小(单位:K)
//AX = 最大的扩充内存块的大小(单位:K)
//BL = 错误代码
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl XMS_Size(void)
{
_AH = 0x08;
XMS_Function();
return (_DX);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//分配扩充内存
//输入参数:AH = 09h
// DX = 要求分配的内存块大小(单位:K)
//返回值:
// AX = 0001h 成功
// DX = 内存块的句柄
// AX = 0000h 失败
// BL = 错误代码
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl XMS_Alloc(int size)
{
_DX = size; // 扩充内存块大小,单位为K字节
_AH = 0x09;
XMS_Function();
if(_AX == 1)
return (_DX);
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
// 为句柄重新分配内存
// 输入参数:AH = 0Fh
// DX = 句柄
// BX = 新的块的容量(单位:K)
// 返回值:
// AX = 0001h 成功
// = 0000h 失败
// BL = 错误代码
/////////////////////////////////////////////////////////////////////////////////////////////////
int _Cdecl XMS_ReAlloc(XMS_HANDLE handle,int resize)
{
_AH = 0x0F;
_DX = handle;
_BX = resize;
(XMS_Function)();
if (_AX)
{
XMS_Size();
return (handle);
}
return (-1);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
// 释放指定句柄所分配的扩充内存
// 输入参数:AH = 0Ah
// DX = 内存块的句柄
// 返回值:
// AX = 0001h 成功
// = 0000h 失败
// BL = 错误代码
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl XMS_Free(XMS_HANDLE handle)
{
_DX = handle;
_AH = 0x0A;
XMS_Function();
if(_AX)
return (TRUE);
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//扩充内存和常规内存中的数据交换(移动扩充内存块)
// 移动扩充内存块
// 输入参数:
// AH = 0Bh
// DS:SI -> XMS 结构
// 返回值:
// AX = 0001h 成功
// = 0000h 失败
// BL = 错误代码
// 注: 如果结构中任一句柄为0000h, 那么其对应32位偏移量将被视为常规内存的绝对地址
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl XMS_Move(struct XMS *xms)
{
_DS = FP_SEG(xms);
_SI = FP_OFF(xms);
_AH = 0x0B;
XMS_Function();
if (_AX)
return (TRUE);
return (FALSE);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//将汉字库点阵字模从常规内存缓冲区buf装载到扩充内存
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Write_To_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)
{
xms.length = size;
xms.source_handle = 0;
xms.source_offset = FP_SEG((void far *)buf);
xms.source_offset <<= 16;
xms.source_offset += FP_OFF((void far *)buf);
xms.dest_handle = handle;
xms.dest_offset = offset;
XMS_Move(&xms);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//从扩充内存中读取汉字点阵字模到常规内存缓冲区buf
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Read_From_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)
{
xms.length = size;
xms.source_handle = handle;
xms.source_offset = offset;
xms.dest_handle = 0;
xms.dest_offset = FP_SEG((void far *)buf);
xms.dest_offset <<= 16;
xms.dest_offset += FP_OFF((void far *)buf);
XMS_Move(&xms);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//汉字库点阵装载到扩充内存
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl ReadHzkXMS(char *Hzk16)
{
unsigned long hzksize;
unsigned int size;
unsigned long offset = 0;
char buf[32];
FILE *fp;

if (!XMS_Test())
{
puts("not found XMS");
exit(1);
}
if ((fp = fopen(Hzk16,"rb")) == NULL)
{
puts("Cannot Open HZK16 ...\n");
exit(1);
}
fseek(fp,0L,SEEK_END);
hzksize = ftell(fp);
fseek(fp,0L,SEEK_SET);
size = (int)(hzksize>>10) +1;
if (XMS_Size() < size)
{
puts("not enough XMS");
fclose(fp);
exit(-1);
}
if ((xms_handle = XMS_Alloc(size)) == 0)
{
puts("XMS handle Error...");
fclose(fp);
exit(-1);
}
while (!feof(fp))
{
size = fread(buf,sizeof(char),32,fp);
Write_To_XMS(buf,size,xms_handle,offset);
offset += size;
}
fclose(fp);
ROM_ASCII = Current_ASCII_ROM(S16X8);//从ROM中获取ASCII码点阵基地址
}


/////////////////////////////////////////////////////////////////////////////////////////////////
// 释放XMS内存
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl HzkFree(void)
{
XMS_Free(xms_handle);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
// 汉字点阵字模从XMS读到缓冲区buf中
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl ReadHzkBit(unsigned char *qw,unsigned char *buf)
{
unsigned short QM,WM;
long offset;

QM = *qw - 160;
WM = *(qw+1) - 160;
offset = ((QM-1)*94+WM-1)*32L;
Read_From_XMS(buf,32,xms_handle,offset);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//获得 ASCII ROM字符集首址
/////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char far *Get_ASCII_ROM(unsigned int BX)
{
_AX = 0x1130;
_BX = BX;
__int__(0x10);
return (unsigned char far *)MK_FP(_ES,_BP);

}


/////////////////////////////////////////////////////////////////////////////////////////////////
//获得 8X8或14X8或16X8英文字模基地址
/////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char far *Current_ASCII_ROM(int ch)
{
switch(ch)
{
case S8X8:
return (Get_ASCII_ROM(0x0300));
case S14X8:
return (Get_ASCII_ROM(0x0200));
case S16X8:
return (Get_ASCII_ROM(0x0600));
default:
return (Get_ASCII_ROM(0x0600));
}
}


/////////////////////////////////////////////////////////////////////////////////////////////////
//显存换页函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl set_vbe_page(int page)
{
if (g_cur_vbe_page != page)
{
_BX = 0;
_DX = g_cur_vbe_page = page;
_AX = 0x4F05;
__int__(0x10);
}
}

//////////////////////////////////////////////////////////////////////////////
////保存窗口映像
//////////////////////////////////////////////////////////////////////////////
BOOL _Cdecl Save_Image_XMS(int x1,int y1,int x2,int y2)
{
int i,j,size;
long long_size,offset = 0;
XMS_HANDLE handle;
char *ptr,buffer[800];

long_size = ((long)800L-(long)x1+1)*((long)y2-(long)y1+1);
long_size >>= 10;
size = long_size;
size++;
if (XMS_Size() > size)
{
if ((handle = XMS_Alloc(size)) != 0)
{
if (PUSH_Stack(x1,y1,x2,y2,handle))
{
size = 800 - TOP_X1();
for (i = TOP_Y1() ; i <= TOP_Y2() ; i++)
{
ptr = buffer;
for (j = TOP_X1() ; j < 800 ; j++)
*ptr++ = GetPixel(j,i);
Write_To_XMS(buffer,size,TOP_Handle(),offset);
offset += size;
}
return (TRUE);
}
}
}
return (FALSE);
}


//////////////////////////////////////////////////////////////////////////////
////恢复窗口映像
//////////////////////////////////////////////////////////////////////////////
void _Cdecl Restore_Image_XMS(void)
{
int i,j,size;
long offset = 0;
char *ptr,buffer[800];

for (i = TOP_Y1() ; i <= TOP_Y2() ; i++)
{
size = 800 - TOP_X1();
Read_From_XMS(buffer,size,TOP_Handle(),offset);
ptr = buffer;
for (j = TOP_X1() ; j < 800 ; j++)
POPUP_PutPixel(j,i,*ptr++);//画点
offset += size;
}
}


多年以来还在MSDOS、单片机下搞嵌入式编程,对WINDOWS编程一窍不通,很想了解WINDOWS下病毒编程技术。
2007-09-24 10:34
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
回复:(kk4868)传递给XMS句柄的必须为偶数
你能不能指点一下,那一句必须为偶数,应该怎么改
2007-09-25 17:17
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
回复:(ba_wang_mao)我给你点源代码吧!,已经成功运...
太感谢你了,我回去运行试试
2007-09-25 17:18
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
回复:(ba_wang_mao)我给你点源代码吧!,已经成功运...
你那个程序有几个变量没有定义呀,不能运行,你能不能贴个完整的,也包括程序,上来就能运行的,谢谢啦
2007-09-26 18:23
beyondabcd
Rank: 1
等 级:新手上路
帖 子:112
专家分:0
注 册:2007-5-19
收藏
得分:0 
我贴的那个程序在move_xms()
通过_BL返回来的错误号是A2,和A7这是怎么回事呀?
上面的程序只能读,保存屏幕的最后一行,来覆盖出现的图片,这是怎么回事呀?
2007-09-26 18:23
快速回复:XMS还是不好使呀!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.056721 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved