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 + -
显示快捷键?