#ifndef XRH_XMS_LIBRARY #define XRH_XMS_LIBRARY #include
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 (); / * After setting the structure XMD, actively call this function to realize the mobile * / myXMs (); ~ myXMs ();}; int myXms: mYxms_num = 0; // XMS (INT 2F / 43) multiplex // int 2F - XMS driver installation detection // input parameters: AX = 4300H // Return value: Al = 80H XMS driver installed // al <> 80h did not find XMS driver
// Note: XMS allows you to access the expansion memory and other non-EMS memory // other programs above 640K may not use the same installation detection method as
INT xms_test (void) {asm {mov AX, 0x4300 INT 0x2f} IF (_al == 0x80) XMS = 1; ELSE XMS = 0; Return XMS;}
// INT 2F - XMS - Get Driver Inlet Address // Input Parameters: AX = 4310H // Return Value: ES: BX -> Driver Inlet Address // See: AX = 4300HINT 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 Module Function No. // 8FH deadly driver error // 90H high-end memory (HMA) does not exist // 91H high-end memory (HMA) has been used // 92h DX is less THE THE // 92H DX IS LESS THE THE / HMAMIN = parameter // 93H high-end memory (HMA) Assigned // 94H A20 address line has been activated // A0H All expansion memory has been assigned // A1H All available handles have been assigned // A2h invalid handle // A3H invalid source handle // A4H invalid source Ship // A5H invalid target handle // A6H invalid purposes // A7H invalid length // A8H mobile has illegal overlapping // A9h occurs in parity error // AAH block unlocked // Abh block Locked // ACH block lock count Overflow // ADH lock failed // B0H Only smaller UMB Space // B1H No UMB Space Void MyXM S :: 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;} // query idle expand memory space, excluding hma // input parameters: AH = 08H // Return value: AX = maximum expansion memory block size ( Unit: k) // DX = Size of the total expansion memory block (unit: k) // BL = Error code 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)));}
// Assign expanded memory // input parameters: AH = 09h // DX = Requires allocated memory block size (unit: k) // Return value: AX = 0001H Success // DX = Handle of memory // ax = 0000H Failure // BL = Error Code 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 (! (} // Reassign the memory // input parameters for the handle: AH = 0FH // DX = handle // bx = new block capacity (unit: k) // Return value: AX = 0001H Success // = 0000H failed // BL = Error code 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;} // Release the expansion memory // input parameter assigned by the specified handle: AH = 0ah // DX = Handle // Return value of the memory block: AX = 0001H Success // = 0000H failed // BL = Wrong Code INT MyXMS :: xms_free (unsigned Handle) {Unsigned AX = 0; if (xms) {asm {MOV AH, 0x0A MOV DX, HANDLE} (); AX = _ax; xms_err = _bl; if (! Ax) Return 0; return 1;} return 0; // Return (! (ISerr (xms_err)));} // Move expansion memory block // input parameters: AH = 0bh // DS: Si -> XMS_MOV Structure // Return Value : AX = 0001H Success // = 0000H failed // BL = Error code // Note: If any handle is 0000h, then its corresponding 32-bit offset will be considered a conventional memory // absolute address / * Struct XMS_MOVE_DATA {Unsigned long move_bytes; // Moved bytes Unsigned source_handle; // Source Handle Unsigned long source_offset;
// Source offset Unsigned target_handle; // Director handle unsigned long target_offset; // destination 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