emsarray.h

来自「提供使用扩充内存EMS完成大数组的类」· C头文件 代码 · 共 180 行

H
180
字号
//////////////////////////////////////////////////
//提供使用扩充内存完成大数组的类,
//用法:CEmsArray<类型> 变量名(数组大小);
//注意:数组类型的大小必须是偶数
//编制人:张洪波   云南师范大学数学学院
//时间2004年09月27日
//#include "EmsArray.h"
/////////////////////////////////////////////////


#if  (!__LARGE__)
#error You must choose  Large Memory Model at compile time(选择大模式编译)
#endif

#include <dos.h>
#include <string.h>
#include <stdio.h>
/******************************************************
对扩充内存进行分配使用:
//物理内存0页面地址由GetPageFrameAddr()得出;
//物理内存1页面地址由GetPageFrameAddr()+0x4000得出;
//物理内存2页面地址由GetPageFrameAddr()+0x8000得出;
//物理内存3页面地址由GetPageFrameAddr()+0xC000得出;
//p=(int far *)MK_FP(SegmentAddr,0x4000);
******************************************************/
#ifndef _CLASS_CEMSMemoryAlloc__
#define _CLASS_CEMSMemoryAlloc__
class CEMSMemoryAlloc
{
protected:
	char CheckEMMXXX(); //检测是否安装EMM386管理器
	unsigned short int GetFreePage(); //获得剩余页面数,每一页为16K,0为有错误
	unsigned short int MallocPage(unsigned short int AllocPageCount); //分配逻辑页面数,返回句柄,为0是有错.01H-FFH成功
	char ClosePage(unsigned short int PageHandle); //释放页面句柄,为0是有错,非0成功
	unsigned short int GetPageFrameAddr();
	char EchoPageToMemory(unsigned short int Pagehandle,unsigned short int PageNo,char Phypage);// 映射PageNo页到物理内存Phypage页面(一般为0,1,2,3),为0是有错,非0成功
	union REGS r;
};
inline char CEMSMemoryAlloc::CheckEMMXXX () //检测是否安装EMM386管理器,0错误,非0成功
{
	//检测是否安装EMM386管理器
	struct SREGS ss;
	r.h.ah=0x35;
	r.h.al=0x67;
	int86x(0x21,&r,&r,&ss);
	return !memcmp((char *)MK_FP(ss.es,0xB),"MMXXXX0",7);
}
inline unsigned short int CEMSMemoryAlloc::GetFreePage() //获得剩余页面数,每一页为16K,0为有错误
{
	r.h.ah=0x42;
	int86(0x67,&r,&r);
	if(r.h.ah) return 0;
	return r.x.bx;
}
inline unsigned short int CEMSMemoryAlloc::MallocPage(unsigned short int AllocPageCount) //分配逻辑页面数,返回句柄,为0是有错.01H-FFH成功
{
	r.h.ah=0x43;
	r.x.bx=AllocPageCount;
	int86(0x67,&r,&r);
	if(r.h.ah) return 0;
	return r.x.dx;
}
inline char CEMSMemoryAlloc::ClosePage(unsigned short int PageHandle) //释放页面句柄,为0是有错,非0成功
{
	r.h.ah=0x45;
	r.x.dx=PageHandle;
	int86(0x67,&r,&r);
	return !(r.h.ah);
}
inline unsigned short int CEMSMemoryAlloc::GetPageFrameAddr()	//得到页面的基地址,为0是有错,非0成功
{
	r.h.ah=0x41;
	int86(0x67,&r,&r);	
	return r.x.bx;
}
//映射PageNo页从0开始到物理内存Phypage(0,1,2,3)页面,为0是有错,非0成功
inline char CEMSMemoryAlloc::EchoPageToMemory(unsigned short int Pagehandle,unsigned short int PageNo,char Phypage)
{
	if((Phypage!=0)&&(Phypage!=1))
	{
		printf("\nEchoPageToMemory Error");
		return 0;
	}
	r.h.al=Phypage;
	r.x.dx=Pagehandle;
	r.x.bx=PageNo;
	r.h.ah=0x44;
	int86(0x67,&r,&r);
	return r.h.ah;
}
#endif

/******************************************************
在扩充内存中分配大数组
用法:
CEmsArray<基类型> 数组名(数组大小)
******************************************************/

#ifndef _CLASS_CEmsArray_H_
#define _CLASS_CEmsArray_H_
template<class TYPE> class CEmsArray: public CEMSMemoryAlloc
{
public:
	CEmsArray();
	~CEmsArray();
	unsigned short int SetSize(unsigned short uSize);
	unsigned short int GetSize();
	TYPE & operator[](long int nIndex);
protected:
	int AllocExternMemory();
	unsigned short int m_StructSize;	//结构大小
	unsigned short int m_PageSegAddr;	//页面地址
	unsigned short int m_NumUnitPage;	//每页元素个数
	unsigned short int m_PageHandle;	//页句柄
	unsigned short int m_AllocPageCount;//分配的页数
	unsigned short int m_nMaxSize;  //数组元素的个数
};
template<class TYPE> CEmsArray<TYPE>::CEmsArray()
{
	memset(this,0,sizeof(*this));
}

template<class TYPE>  CEmsArray<TYPE>::~CEmsArray()
{
	if(m_PageHandle) ClosePage(m_PageHandle);
	m_PageHandle=0;
}
template<class TYPE>  unsigned short int CEmsArray<TYPE>::SetSize(unsigned short int uSize)
{
	if(m_PageHandle) ClosePage(m_PageHandle);
	m_PageHandle=0;

	m_nMaxSize=uSize;			//数组大小,比最大下标小1
	m_StructSize=sizeof(TYPE);	//结构大小
	m_NumUnitPage=0x4000/m_StructSize;	//每页元素个数
	m_AllocPageCount=(m_nMaxSize+m_NumUnitPage-1)/m_NumUnitPage;//应该分配页数
	if(!AllocExternMemory()) m_nMaxSize=0;
	return m_nMaxSize;
}

template<class TYPE> int CEmsArray<TYPE>::AllocExternMemory()
{
	if(CheckEMMXXX()) //检测是否安装EMM386管理器
	{
		unsigned short int FreePageCount=GetFreePage(); //获得剩余页面数,每一页为16K,0为有错误
		printf("\nFree Memory=%u,AllocPageCount=%u",FreePageCount,m_AllocPageCount);
		if(FreePageCount<m_AllocPageCount) return 0;

		m_PageHandle=MallocPage(m_AllocPageCount); //分配逻辑页面数,返回句柄,为0是有错.01H-FFH成功
		m_PageSegAddr=GetPageFrameAddr();//页面的基地址
		if(!m_PageHandle||!m_PageSegAddr) return 0;

		unsigned short int k;
		char *p=(char far*)MK_FP(m_PageSegAddr,0);
		for(k=0;k<m_AllocPageCount;k++)
		{
			EchoPageToMemory(m_PageHandle,k,0);
			memset(p,0,0x4000);
		}
		return 1;
	}
	printf("\nEmm386 Not Found!!!!!");
	return 0;
}
template<class TYPE> TYPE& CEmsArray<TYPE>::operator[](long int nIndex)
{
	if(nIndex>=m_nMaxSize)
	{
		printf("nIndex=%u,m_nMaxSize=%u,Error!!!\n",nIndex,m_nMaxSize);
	}
	EchoPageToMemory(m_PageHandle,(unsigned short int)(nIndex/m_NumUnitPage),0);//规定用 0
	return *(TYPE *)MK_FP(m_PageSegAddr,(nIndex%m_NumUnitPage)*m_StructSize);

}
template<class TYPE>  unsigned short int CEmsArray<TYPE>::GetSize()
{
	return m_nMaxSize;
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?