Dos下的XMS完全控制类 --- 使用它,让你的DOS程序使用XMS不再是梦想!

类别:VC语言 点击:0 评论:0 推荐:

 #ifndef XRH_XMS_LIBRARY
 #define XRH_XMS_LIBRARY
 #include <DOS.H>
 #include <STDIO.H>
 #include <STDLIB.H>
  struct XMS_Move_Data{
     unsigned long far Move_Bytes;             // 移动的字节数
     unsigned far Source_Handle;                 // 源句柄
     unsigned long far Source_Offset;          // 源偏移量
     unsigned far Target_Handle;                  // 目的句柄
     unsigned long far Target_Offset;          // 目的偏移量
      };
   int  far XMS=0;
//  void (far *Xms)();
//   int  far Xms_Err=0;

  class MyXMS{

       private:
       int XMS;
       int   Xms_Err;
       int   IsErr(int Xms_Err_Num);
      void (far *Xms)(void);
      void  XMS_Get_Drive_Addr(void);
       static int  MyXMS_Num;

      public:
      XMS_Move_Data  Xmd; // very important, the detail at above
      int  XMS_Check(unsigned &Max_Block_Size,unsigned &Total_Size);
      int  XMS_Get(unsigned &Handle,unsigned Size);
      int  XMS_ReGet(unsigned Handle,unsigned ReSize);
      int  XMS_Free(unsigned Handle);
      int  XMS_Move();  /* 设置好了结构体 Xmd 之后,主动调用本函数,可实现数据块的移动 */
    MyXMS();
   ~MyXMS();
       };
  int  MyXMS::MyXMS_Num=0;
// XMS (Int 2F/43) 多路中断
//  INT 2F - XMS 驱动程序安装检测
//   输入参数:AX = 4300h
//     返回值:AL = 80h XMS 驱动程序已安装
//       AL <> 80h 未发现XMS 驱动程序

//  注: XMS 使你可以访问扩充内存以及其它的高于640K的非EMS内存
//      其它程序不得使用与之相同的安装检测方式

 int  XMS_Test(void)
     {
       asm{
       mov ax ,0x4300
       int 0x2F
    }
       if(_AL==0x80)
    XMS=1;
 else
    XMS=0;
     return XMS;
     }

// INT 2F - XMS - 获取驱动程序入口地址
//  输入参数:AX = 4310h
//     返回值:ES:BX -> 驱动程序入口地址
//  请参见: AX=4300h
int  MyXMS::IsErr(int Xms_Err_Num)
     {
     switch(Xms_Err_Num)
       {
 case 0x80:
 case 0x81:
 case 0x82:
 case 0x8E:
 case 0x8F:
 case 0x90:
 case 0x91:
 case 0x92:
 case 0x93:
 case 0x94:
 case 0xA0:
 case 0xA1:
 case 0xA2:
 case 0xA3:
 case 0xA4:
 case 0xA5:
 case 0xA6:
 case 0xA7:
 case 0xA8:
 case 0xA9:
 case 0xAA:
 case 0xAB:
 case 0xAC:
 case 0xAD:
 case 0xB0:
 case 0xB1: return 1;
 default  : return 0;
       }
     }
// AH中放功能号, 用远调用的方式调用驱动程序
//  BL中返回的错误代码
//  80h 没有提供的功能
//  81h 检测到虚拟盘(Vdisk)
//  82h 发生A20地址线错误
//  8Eh 一般驱动程序错误
//  8Fh 致命的驱动程序错误
//  90h 高端内存(HMA)不存在
//  91h 高端内存(HMA)已被使用
//  92h DX is less than the /HMAMIN= parameter
//  93h 高端内存(HMA)未被分配
//  94h A20地址线已被激活
//  A0h 所有扩充内存已被分配
//  A1h 所有可用的句柄已被分配
//  A2h 无效的句柄
//  A3h 无效的源句柄
//  A4h 无效的源偏移
//  A5h 无效的目的句柄
//  A6h 无效的目的偏移
//  A7h 无效的长度
//  A8h 移动有非法的重叠
//  A9h 发生奇偶校验错误
//  AAh 块未加锁
//  ABh 块已被锁定
//  ACh 块锁定计数溢出
//  ADh 锁定失败
//  B0h 只有更小一些的UMB空间
//  B1h 没有可用的UMB空间

    void  MyXMS::XMS_Get_Drive_Addr()
       {
  if (XMS)
    {
     asm {
  mov ax,0x4310
  int 0x2F
   }

   this->Xms=(void (far *)())(((unsigned long)(_ES)<<16)+_BX);
  // Xms=(void (far *)())(((unsigned long)(_ES)<<16)+_BX);
    }
       return;
       }
// 查询空闲的扩充内存空间, 不包括HMA
//  输入参数:AH = 08h
//    返回值:AX = 最大的扩充内存块的大小(单位:K)
//      DX = 总的扩充内存块的大小(单位:K)
//      BL = 错误代码
int  MyXMS::XMS_Check(unsigned &Max_Block_Size,unsigned &Total_Size)
    {
 if (XMS)
     {
       asm mov ah,0x08
       Xms();
       Max_Block_Size=_AX;
       Total_Size=_DX;
       Xms_Err=_BL;
     }
      return (!(IsErr(Xms_Err)));
     }

// 分配扩充内存
//   输入参数:AH = 09h
//       DX = 要求分配的内存块大小(单位:K)
//     返回值:AX = 0001h 成功
//         DX = 内存块的句柄
//       AX = 0000h 失败
//       BL = 错误代码
    int  MyXMS::XMS_Get(unsigned &Handle,unsigned Size)
     {        unsigned Ax=0;
  if (XMS)
     {
       asm {
      mov ah,0x09
      mov dx,Size
     }
       Xms();
       Ax=_AX;
       Handle=_DX;
       Xms_Err=_BL;
       if(!Ax) return 0;
        return 1;
      }
       return 0;
       // return(!(IsErr(Xms_Err)));
      }
// 为句柄重新分配内存
//  输入参数:AH = 0Fh
//      DX = 句柄
//      BX = 新的块的容量(单位:K)
//    返回值:AX = 0001h 成功
//              = 0000h 失败
//           BL = 错误代码
   int  MyXMS::XMS_ReGet(unsigned Handle,unsigned ReSize)
       {
   unsigned Ax=0;
        if (XMS)
   {
    asm {
       mov ah,0x0F
       mov dx,Handle
       mov bx,ReSize
         }
     Xms();
       Ax=_AX;
       Xms_Err=_BL;
  if(!Ax) return 0;
     return 1;
   }
 return 0;
 }
// 释放指定句柄所分配的扩充内存
//  输入参数:AH = 0Ah
//      DX = 内存块的句柄
//    返回值:AX = 0001h 成功
//              = 0000h 失败
//           BL = 错误代码
     int  MyXMS::XMS_Free(unsigned Handle)
     {  unsigned Ax=0;
        if (XMS)
     {
     asm {
    mov ah,0x0A
    mov dx,Handle
   }
      Xms();
      Ax=_AX;
      Xms_Err=_BL;
      if(!Ax) return 0;
       return 1;
       }
       return 0;
       //  return(!(IsErr(Xms_Err)));
       }
// 移动扩充内存块
//  输入参数:AH = 0Bh
//      DS:SI -> xms_mov 结构
//    返回值:AX = 0001h 成功
//              = 0000h 失败
//           BL = 错误代码
//   注: 如果结构中任一句柄为0000h, 那么其对应32位偏移量将被视为常规内存
//       的绝对地址
/*
  struct XMS_Move_Data{
     unsigned long Move_Bytes;             // 移动的字节数
     unsigned Source_Handle;        // 源句柄
     unsigned long Source_Offset;          // 源偏移量
     unsigned Target_Handle;               // 目的句柄
     unsigned long Target_Offset;          // 目的偏移量
      }Xmd;
*/
    int  MyXMS::XMS_Move()// XMS_Move_Data& Xmd)
 {          unsigned Ax=0;
    if (XMS)
        {
    unsigned Xseg=FP_SEG(&(this->Xmd)),Xoff=FP_OFF(&(this->Xmd));
        asm  {
      mov ah,0x0B
      mov si,Xoff
      mov ds,Xseg
      }
        Xms();
        Ax=_AX;
        Xms_Err=_BL;
        if(!Ax) return 0;
    return 1;
        }
       return 0;
       }

    MyXMS::MyXMS()
      {
       Xms_Err=0;
       if (!MyXMS_Num)
  ::XMS_Test();

       XMS=::XMS;
       if(!XMS){printf("\n  XMS Not Found,Please Setup In 'Config.sys' File.");exit(1);}
       MyXMS_Num++;
       XMS_Get_Drive_Addr();
       }
     MyXMS::~MyXMS()
      {
       MyXMS_Num--;

      }


#endif

本文地址:http://com.8s8s.com/it/it3594.htm