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