#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目录中.
我的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();
}