Dos下的XMS完全控制類 --- 使用它,讓你的DOS程式使用XMS不再是夢想! (轉)

worldblog發表於2007-12-27
Dos下的XMS完全控制類 --- 使用它,讓你的DOS程式使用XMS不再是夢想! (轉)[@more@]

 #ifndef XRH_XMS_LIBRARY
 #define XRH_XMS_LIBRARY
 #include
 #include
 #include
  struct XMS_Move_Data{
  unsigned long far Move_Bytes;  // 移動的位元組數
  unsigned far _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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-995890/,如需轉載,請註明出處,否則將追究法律責任。

相關文章