#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

|