精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>○ DOS>>工具箱>>有关DOS下扩充内存的使用

主题:有关DOS下扩充内存的使用
发信人: riffle()
整理人: yangcs(2000-01-25 11:46:50), 站内信件
emsmem.cpp

/* author : *** */  // ***
/*--------------------------------------------------------------*/

#include <STDIO.H>
#include <DOS.H>

/*--------------------------------------------------------------*/

#define EMSINT 0x67

/*--------------------------------------------------------------*/

static int IsInstalled = 0;
static int IsHaveEMS = 0;

/*--------------------------------------------------------------*/

static unsigned int uiEMSSeg = 0;

/*--------------------------------------------------------------*/

static unsigned int uiaUsedMap[ 4 ] = { 0, 0 ,0, 0 };

/*--------------------------------------------------------------*/
/****************************************************************/
/*-- 系统是否有EMS管理程序   程序开始 --------------------------*/
int IsSystemHaveEMS( void )
{
  union REGS inregs;
  union REGS outregs;

  if ( !IsInstalled )
    {
      IsInstalled = 1;
      // 安装了INT 67?
      if ( getvect( EMSINT ) != NULL )
{
  inregs.h.ah = 0x46;
  int86( EMSINT, &inregs, &outregs );
  // 取EMS版本号
  if ( ( outregs.h.ah == 0 ) &&
       ( outregs.h.al == 0x40 ) )
    // 4.0?
    {
      inregs.h.ah = 0x41;
      int86( EMSINT, &inregs, &outregs );
      // 取EMS页帧段地址,如0XD000
      if ( outregs.h.ah == 0 )
{
  uiEMSSeg = outregs.x.bx;
  IsHaveEMS = 1;
}
    }
}
    }
  return IsHaveEMS;
}
/*-- 系统是否有EMS管理程序   程序结束 --------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 分配若干字节的EMS内存   程序开始 --------------------------*/
int AllocateEMS( unsigned int uiBytes, unsigned int &uiEMSHandle )
{
  union REGS inregs;
  union REGS outregs;

  inregs.h.ah = 0x43;
  // 计算以16K为单位的页数
  inregs.x.bx = uiBytes / 16384;

  if ( uiBytes % 16384 )
    inregs.x.bx++;

  if ( IsSystemHaveEMS() )
    {
      // 分配EMS内存页
      int86( EMSINT, &inregs, &outregs );
      // 得到EMS内存页句柄
      uiEMSHandle = outregs.x.dx;
      return outregs.h.ah;
    }
  // 若系统没有安装EMS管理程序,返回0X80表示内部错误
  return 0x80;
}
/*-- 分配若干字节的EMS内存   程序结束 --------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 分配若干页的EMS内存   程序开始 ----------------------------*/
int AllocateEMSPages( unsigned int uiPages, unsigned int &uiEMSHandle 
)
{
  union REGS inregs;
  union REGS outregs;

  inregs.h.ah = 0x43;
  // EMS 内存页数
  inregs.x.bx = uiPages;

  if ( IsSystemHaveEMS() )
    {
      int86( EMSINT, &inregs, &outregs );
      // 得到EMS内存页句柄
      uiEMSHandle = outregs.x.dx;
      return outregs.h.ah;
    }
  // 若系统没有安装EMS管理程序,返回0X80表示内部错误
  return 0x80;
}
/*-- 分配若干页的EMS内存   程序结束 ----------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 释放某页EMS内存   程序开始 --------------------------------*/
int FreeEMS( unsigned int uiEMSHandle )
{
  union REGS inregs;
  union REGS outregs;

  inregs.h.ah = 0x45;
  // EMS内存页句柄
  inregs.x.dx = uiEMSHandle;
  if ( IsSystemHaveEMS() )
    {
      int86( EMSINT, &inregs, &outregs );
      return outregs.h.ah;
    }
  // 若系统没有安装EMS管理程序,返回0X80表示内部错误
  return 0x80;
}
/*-- 释放某页EMS内存   程序结束 --------------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 取系统共有多少EMS内存页   程序开始 ------------------------*/
int GetEMSPage( unsigned int &uiEMSTotalPages,
unsigned int &uiEMSFreePages )
{
  union REGS inregs;
  union REGS outregs;

  if ( IsSystemHaveEMS() )
    {
      inregs.h.ah = 0x42;
      int86( EMSINT, &inregs, &outregs );
      // 总页数
      uiEMSTotalPages = outregs.x.dx;
      // 未分配的页数
      uiEMSFreePages = outregs.x.bx;
      return outregs.h.ah;
    }
  // 若系统没有安装EMS管理程序,返回0X80表示内部错误
  return 0x80;
}
/*-- 取系统共有多少EMS内存页   程序结束 ------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 将物理页映射到逻辑页   程序开始 ---------------------------*/
int MapMemory( unsigned char ucPhisycalPage,
       unsigned int uiLogicPage,
       unsigned int uiEMSHandle )
{
  union REGS inregs;
  union REGS outregs;

  inregs.h.ah = 0x44;
  // 物理页
  inregs.h.al = ucPhisycalPage;
  // 逻辑页
  inregs.x.bx = uiLogicPage;
  // EMS句柄
  inregs.x.dx = uiEMSHandle;
  if ( IsSystemHaveEMS() )
    {
      int86( EMSINT, &inregs, &outregs );
      return outregs.h.ah;
    }
  // 若系统没有安装EMS管理程序,返回0X80表示内部错误
  return 0x80;
}
/*-- 将物理页映射到逻辑页   程序结束 ---------------------------*/
/****************************************************************/

/****************************************************************/
/*-- 取逻辑页地址   程序开始 -----------------------------------*/
char far *GetLogicPageAddress( unsigned int uiLogicPageNum,
       unsigned int uiEMSHandle )
{
  // 无效逻辑页号或无效EMS句柄号,则返回NULL。
  if ( ( uiLogicPageNum >= 4 ) || ( uiEMSHandle <= 0 ) )
return NULL;
// 若该页尚未映射过
else if ( uiaUsedMap[ uiLogicPageNum ] != uiEMSHandle )
{
// 将该对应句柄的逻辑页映射到物理页(0~3)
// 于是其地址可以对应为 0XD000:0000 ~ 0XD000 : FFFF
if ( !MapMemory( uiLogicPageNum, uiLogicPageNum, uiEMSHandle ) )

// 记载该页已经映射
uiaUsedMap[ uiLogicPageNum ] = uiEMSHandle;
else
return NULL;
}
// 因为每页为16K,所以返回的远地址为段地址加上页号 * 16K。
return ( char far * )MK_FP( uiEMSSeg, uiLogicPageNum << 14 );
}
/*-- 取逻辑页地址 程序结束 -----------------------------------*/
/****************************************************************/
/****************************************************************/
/****************************************************************/

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.185.27]

[关闭][返回]