注册 登录
编程论坛 C图形专区

XMS还是不好使呀!

beyondabcd 发布于 2007-09-20 09:56, 3312 次点击

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


#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();
}


只有本站会员才能查看附件,请 登录

25 回复
#2
beyondabcd2007-09-21 13:31
大家帮帮忙吧,我实在是能不出来呀
#3
RockCarry2007-09-21 19:19
用 VC 吧,在内存使用上不再有烦恼。
#4
beyondabcd2007-09-22 09:15
我是用PC104编程,相当于486的机器,windows 启动不起来呀
#5
kk48682007-09-24 08:27

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

#6
ba_wang_mao2007-09-24 10:34

我给你点源代码吧!,已经成功运用于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;
}
}

#7
beyondabcd2007-09-25 17:17
回复:(kk4868)传递给XMS句柄的必须为偶数
你能不能指点一下,那一句必须为偶数,应该怎么改
#8
beyondabcd2007-09-25 17:18
回复:(ba_wang_mao)我给你点源代码吧!,已经成功运...
太感谢你了,我回去运行试试
#9
beyondabcd2007-09-26 18:23
回复:(ba_wang_mao)我给你点源代码吧!,已经成功运...
你那个程序有几个变量没有定义呀,不能运行,你能不能贴个完整的,也包括程序,上来就能运行的,谢谢啦
#10
beyondabcd2007-09-26 18:23
我贴的那个程序在move_xms()
通过_BL返回来的错误号是A2,和A7这是怎么回事呀?
上面的程序只能读,保存屏幕的最后一行,来覆盖出现的图片,这是怎么回事呀?
#11
kk48682007-09-26 23:28
a2:无效的句柄
a7:无效的数据长度
#12
beyondabcd2007-09-29 13:51
谁有XMS保存,恢复图片的例子,给一个
谁有XMS保存,恢复图片的例子,给一个.谢谢拉
#13
beyondabcd2007-10-03 17:19
自己在顶一下,希望有好心人能给一个用XMS保存屏幕的源码
#14
kk48682007-10-03 20:26

我写的EC中有有关XMS和图片操作的,这个网站上应该有下载,你自己看看去吧
EC 1.9

[此贴子已经被作者于2007-10-3 20:27:11编辑过]

#15
beyondabcd2007-10-05 09:35
应该怎么搜索呀,我找不到
#16
kk48682007-10-05 11:08
#17
beyondabcd2007-10-06 14:36
我有Easy C ,在Easy C 里的xms我也没能明白怎么用呀!
#18
kk48682007-10-06 16:01
#include "ECPIC.H"
void main()
{
IMAGE m;
m.mode = FROM_XMS;
user_screen(320,200,8);
init_base();
show_bmp(0,0,"test.bmp",TO_MEM, &m); /* 将图像装入内存 */
getch();
direct(0, 0, m, ALL_AUTO); /* 从XMS输出到屏幕 */
getch();
quit_base();
}
#19
kk48682007-10-06 16:01

注意 test.bmp的尺寸要小于320*200
否则会报告申请内存失败

#20
beyondabcd2007-10-07 12:36
谢谢你,大侠!!!
啊!我想用640X480的呀,
#21
beyondabcd2007-10-07 12:37
回复:(beyondabcd)谢谢你,大侠!!![em17][em17][em...

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

#include "showbmp.c"
#include "rsvga256.h"

char sssbuf[300];
unsigned int Handle;

void Save_Image_XMS(int POPUP_x1,int POPUP_x2,int POPUP_y1,int POPUP_y2)
{
int i,j;
char *pp;
long size,text1,text2;
unsigned long offset = 0;
unsigned int size1;
unsigned long testsize;
unsigned long nMax, nTotal;

int x1= POPUP_x1,x2= POPUP_x2,y1=POPUP_y1,y2=POPUP_y2;


size = ((long)POPUP_x2-(long)POPUP_x1+1)*((long)POPUP_y2-(long)POPUP_y1+1); printf("%ld_1",size);
size=size/1024+1; printf(" %ld_2",size);

XMS_GetFree(&nMax, &nTotal);
printf(" %ld_2",size);
if (nTotal<size)
puts("not enough XMS");
printf("nTotal=%ld,size=%ld",nTotal,size);

printf(" %ld_2",size);
if (( XMS_Allocate(size, &Handle)) == 0)
puts("XMS handle Error...\n");

for (i= y1; i<=y2;i++)
{
testsize= x2-x1;
pp = sssbuf;

for (j= x1; j<x2;j++)
{ *pp++ = getpixel(j,i);}

XMS_CopyToXMS(Handle, offset, sssbuf, testsize); /*是xms_save_restore_handle还是Handle呀?*/

offset += testsize;
}

}

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

size = POPUP_x2-POPUP_x1;
for (i= POPUP_y1; i<=POPUP_y2;i++)
{ XMS_CopyFromXMS(sssbuf, Handle, offset, size);

offset += size;
pp = sssbuf;
for (j= POPUP_x1; j<POPUP_x2;j++)
putpixel(j,i,*pp++);/* sssbuf[j-POPUP_x1]); */
}
XMS_Free(Handle);
}


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

void main()
{ int iii=DETECT, jjj=0;

installuserdriver("Svga256", rReturn_SVGA256); /* 对于svga256必需执行该函数以安装BGI驱动 */
initgraph(&iii, &jjj, "");

if(XMS_Init() == 0)
{
printf("Unable to find XMS driver.\n");

}


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

为什么我这个程序当X(横坐标)长度大于150时,程序就出现错误(出现一大堆乱码
后,然后自动退出)。Y(纵坐标)很大时,程序就没有问题,这是为什么,应怎么解决

下面是程序包,把XMS.H,bb1.c,rSvga256.h放在INCLUDE目录中,XMS.LIB放在LIB目录中.


#22
kk48682007-10-07 18:51

修改user_screen(640,480,8);
如果黑屏,证明你的机器对它的支持不好

#23
beyondabcd2007-10-08 11:37

我的XMS终于好使了,贴出来让大家看看,哈哈。谢谢给过我帮助的朋友们!!!

/* A sequential table of variable length records in XMS */
#include "graphics.h"
#include<dos.h>


#include "showbmp.c"
#include "rsvga256.h"
#define TRUE 1
#define FALSE 0

/* BLOCKSIZE will be the size of our real-memory buffer that we'll swap XMS through (must be a multiple of 1024, since
XMS is allocated in 1K chunks.) */

char sssbuf[640];

/* XMSParms is a structure for copying information to and from real-mode memory to XMS memory */

struct parmstruct
{
/* blocklength is the size in bytes of block to copy */

unsigned long blockLength;

/* sourceHandle is the XMS handle of source; 0 means that sourcePtr will be a 16:16 real-mode pointer, otherwise
sourcePtr is a 32-bit offset from the beginning of the XMS area that sourceHandle points to */

unsigned int sourceHandle;
void far *sourcePtr;

/* destHandle is the XMS handle of destination; 0 means that destPtr will be a 16:16 real-mode pointer, otherwise
destPtr is a 32-bit offset from the beginning of the XMS area that destHandle points to */

unsigned int destHandle;
void far *destPtr;
}
XMSParms;

void far (*XMSFunc) (void); /* Used to call XMS manager (himem.sys) */
char GetBuf(void);
void GetXMSEntry(void);
/* Conventional memory buffer for transfers */
unsigned int XMSHandle; /* handle to allocated XMS block */
char XMS_init()
{
/* returns 0 if XMS present,
1 if XMS absent
2 if unable to allocate transfer buffer
*/
unsigned char status;
_AX=0x4300;
geninterrupt(0x2F);
status = _AL;
if(status==0x80)
{
GetXMSEntry();


return 0;
}
return 1;
}

void GetXMSEntry(void)
{
/* GetXMSEntry sets XMSFunc to the XMS Manager entry point so we can call it later */
_AX=0x4310;
geninterrupt(0x2F);
XMSFunc= (void (far *)(void)) MK_FP(_ES,_BX);
}

void XMSSize(unsigned long *kbAvail, unsigned long *largestAvail)
{
/* XMSSize returns the total kilobytes available, and the size in kilobytes of the largest available block */

_AH=8;
(*XMSFunc)();
*largestAvail=_DX;
*kbAvail=_AX;
}

char AllocXMS(unsigned long numberBytes)
{
/* Allocate a block of XMS memory numberBytes long */
_DX = (int)(numberBytes/1024+1);
_AH = 9;
(*XMSFunc)();
if (_AX==0)
{
return FALSE;
}
XMSHandle=_DX;
return TRUE;
}

void XMS_free(void)
{
/* Free used XMS */
_DX=XMSHandle;
_AH=0x0A;
(*XMSFunc)();
}

char XMS_write(unsigned long loc, char far *val, unsigned long length)
{ /* Round length up to next even value */
length += length % 2;
XMSParms.sourceHandle=0;
XMSParms.sourcePtr=val;
XMSParms.destHandle=XMSHandle;
XMSParms.destPtr=(void far *) (loc);
XMSParms.blockLength=length; /* Must be an even number! */
_SI = FP_OFF(&XMSParms);
_AH=0x0B;
(*XMSFunc)();
if (_AX==0)
{
return FALSE;
}
return TRUE;
}

void *XMS_read(unsigned long loc,unsigned long length)
{
/*
Returns pointer to data or NULL on error */
/* Round length up to next even value */
length += length % 2;
XMSParms.sourceHandle=XMSHandle;
XMSParms.sourcePtr=(void far *) (loc);
XMSParms.destHandle=0;
XMSParms.destPtr=sssbuf;
XMSParms.blockLength=length; /* Must be an even number */
_SI=FP_OFF(&XMSParms);
_AH=0x0B;
(*XMSFunc)();
if (_AX==0)
{
return NULL;
}
return sssbuf;
}


void Save_Image_XMS(int POPUP_x1,int POPUP_x2,int POPUP_y1,int POPUP_y2)
{
int i,j;
unsigned long kbAvail,largestAvail;
char *pp;
unsigned long size;
unsigned long offset = 0;
unsigned int size1;
unsigned long testsize;

int x1= POPUP_x1,x2= POPUP_x2,y1=POPUP_y1,y2=POPUP_y2;
size = ((long)POPUP_x2-(long)POPUP_x1+1)*((long)POPUP_y2-(long)POPUP_y1+1);
size1=(int)(size/1024)+1;

XMSSize(&kbAvail,&largestAvail);

if (kbAvail<size1)
puts("not enough XMS");

if (!AllocXMS(size))
puts("XMS handle Error...\n");

for (i= y1; i<=y2;i++)
{
testsize= x2-x1;
pp = sssbuf;

for (j= x1; j<x2;j++)
{ *pp++ = getpixel(j,i);}

XMS_write( offset, sssbuf, testsize);
offset += testsize;
}

}

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

size = POPUP_x2-POPUP_x1;
for (i= POPUP_y1; i<=POPUP_y2;i++)
{ pp =XMS_read(offset, size);

offset += size;

for (j= POPUP_x1; j<POPUP_x2;j++)
putpixel(j,i,*pp++);/* sssbuf[j-POPUP_x1]); */
}
XMS_free();
}


/* Demonstration code Read various length strings into a single XMS block (EMB) and write them out again */

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

void main()
{ int iii=DETECT, jjj=0;

installuserdriver("Svga256", rReturn_SVGA256); /* 对于svga256必需执行该函数以安装BGI驱动 */
initgraph(&iii, &jjj, "");


if (XMS_init() != 0)

printf("XMS Not Available\n");


show_bmp("main.bmp",0,0);
Save_Image_XMS(0,637,0,476 );
getch();
show_bmp("filemain.bmp",0,0);
getch();
Restore_Image_XMS(0,637,0,476 );
getch();
closegraph();
}


#24
ba_wang_mao2007-10-08 12:04
原来程序哪里出现错误呢?
#25
beyondabcd2007-10-08 14:32
你给我的那个缺少定义的变量
#26
ba_wang_mao2007-10-08 15:54

呵呵,是否原先没有如下定义过变量
void far (*XMS_Function)(void) = 0L;// XMS服务程序入口地址
XMS_HANDLE xms_handle; // 伪指针
struct XMS xms;
1