//-------------------------------------------------------------------------- // // XMS::XMS. // // Constructor for class XMS. Initialises XMSdriver if necessary, // and attempts to allocate a block of the specified number of bytes // (which will be rounded up to the nearest K). // XMS::XMS (long size) { handle = 0; allocation = 0; if ((status = XMSinit()) == SUCCESS) { int result = 0; int realsize; size += K - 1; int request = size / K; _DX = request; _AH = 0x09; XMSdriver (); result = _AX; if (result) { handle = _DX; _AH = 0x0E; XMSdriver (); result = _AX; realsize = _DX; } else status = error (_BL); if (result) allocation = realsize * K; } }
void InitXMSCache(struct LowCacheFunctions* table) { if (XMSinit()) { /* Try allocating all available XMS memory. */ XMSsize = XMScoreleft(); if (XMSsize) { XMSHandle = XMSalloc(XMSsize); if (XMSHandle) { memcpy(table, &XMSCacheTable, sizeof(struct LowCacheFunctions)); if (!Invalidate()) { CloseXMSCache(); table->supported = FALSE; } } else table->supported = FALSE; } else table->supported = FALSE; } else table->supported = FALSE; }
//-------------------------------------------------------------------------- // // XMS::largest. // // Returns the size of the largest unallocated XMS block available. // long XMS::largest () { if (XMSinit () == SUCCESS) { _AH = 0x08; XMSdriver (); return _AX * K; } else return 0; }
//-------------------------------------------------------------------------- // // XMS::available. // // Returns the total size of available XMS. // long XMS::available () { if (XMSinit () == SUCCESS) { _AH = 0x08; XMSdriver (); return _DX * K; } else return 0; }
//-------------------------------------------------------------------------- // // UMB::largest. // // Return size of largest available UMB block. // long UMB::largest () { long size = 0; if (XMSinit () == XMS::SUCCESS) { _AH = 0x10; _DX = 0xFFFF; XMSdriver (); size = unsigned (_DX); } return size * PARA; }
//-------------------------------------------------------------------------- // // XMScopy: copy block to/from XMS. // // This function copies data in accordance with the parameters set // up in the structure "descriptor". Overlapping blocks may not be // handled correctly (as per XMS specification). It does nothing if // XMS initialisation fails. // static XMS::error XMScopy () { XMS::error result = XMSinit (); if (result == XMS::SUCCESS) { _SI = FP_OFF (&descriptor); _AH = 0x0B; XMSdriver (); if (_AX == 0) result = XMS::error (_BL); } return result; }
//-------------------------------------------------------------------------- // // UMB::UMB. // // Attempt to construct a UMB block of the specified size. // UMB::UMB (long size) { address = 0; allocation = 0; if (size > (64 * K - 1) * PARA) status = XMS::BLOCK_TOO_BIG; else if ((status = XMSinit()) == XMS::SUCCESS) { size += PARA - 1; _DX = unsigned (size/PARA); _AH = 0x10; XMSdriver (); if (_AX != 0) { int bx = _BX; address = MK_FP (bx,0); allocation = unsigned (_DX); } else status = XMS::error (_BL); } allocation *= PARA; }
//-------------------------------------------------------------------------- // // HMA::HMA. // // Attempt to allocate HMA for a block of the specified size. // HMA::HMA (unsigned size) { allocation = 0; if (size > (64 * K) - PARA) status = XMS::BLOCK_TOO_BIG; else if ((status = XMSinit()) == XMS::SUCCESS) { _DX = size; _AH = 0x01; XMSdriver (); if (_AX != 0) { allocation = size; _AH = 0x07; XMSdriver (); A20enabled = _AX; if (!A20enabled) { _AH = 0x03; XMSdriver (); if (_AX != 0) return; } } status = XMS::error (_BL); } }
int InitializeFittingMemory (unsigned long size, int HardDiskOk, unsigned long *allocated, /* Needed to check wether a swap file is not created on the source or destination drive: */ char sdrv, char tdrv) { char *tempvar = NULL; struct dfree free; int curdisk, tempdisk, run = 1; unsigned long farfree; struct IniParserStruct *ParsedData; ParsedData = GetParsedData (); Initialised = TRUE; AmofProcessed = 0; CloseFunc = DoNothing; PrepareToReadFunc = ResetAmof; PrepareToWriteFunc = ResetAmof; /* First of all see wether main memory is not large enough */ farfree = farcoreleft (); if (farfree > size) { FarBlock = (char far *) farmalloc (size); LastOffset = FP_OFF (FarBlock); LastSegment = FP_SEG (FarBlock); SavedSegment = LastSegment = LastSegment + LastOffset / 16; SavedOffset = LastOffset = LastOffset % 16; MemType = BUFFERS; CloseFunc = CloseBuffers; ReadFunc = BufferRead; WriteFunc = BufferWrite; PrepareToReadFunc = PrepareForChangingBuffers; PrepareToWriteFunc = PrepareForChangingBuffers; *allocated = size; } /* See wether EMS is installed. */ if ((!MemType) && ParsedData->UseEMS && ((EMSBase = EMSbaseaddress ()) != 0)) { /* See if there is enough memory. */ if ((size / 16384) + 1 < EMSpages ()) { Handle = EMSalloc ((int) (size / 16384) + 1); if (Handle >= 0) { CloseFunc = CloseEMS; WriteFunc = EMSWrite; ReadFunc = EMSRead; MemType = EMS; } *allocated = size; } } /* See wether XMS is installed. */ if (ParsedData->UseXMS && (!MemType) && XMSinit ()) { /* See if there is enough memory. */ if (size < XMScoreleft ()) { Handle = XMSalloc (size); if (Handle != 0) { MemType = XMS; CloseFunc = CloseXMS; WriteFunc = XMSWrite; ReadFunc = XMSRead; } *allocated = size; } } /* See wether the hard disk can be used. */ if (!MemType && HardDiskOk) { tempvar = getenv ("temp"); if (!tempvar) tempvar = getenv ("TEMP"); if (tempvar && tempvar[0]) strcpy (tempfile, tempvar); else strcpy (tempfile, "C:\\"); /* Make sure that the disk where the temporary file is created is not either the source of the target of the disk copy. */ if ((toupper (tempfile[0]) == toupper (sdrv)) || (toupper (tempfile[0]) == toupper (tdrv))) strcpy (tempfile, "C:\\"); curdisk = getdisk (); tempdisk = toupper (tempfile[0]) - 65; /* If the TEMP environment variable doesn't have a path form, use the root of c: instead. */ if ((tempdisk < 0) || (tempdisk > 26) || (tempfile[1] != ':')) { strcpy (tempfile, "C:\\"); tempdisk = 2; } for (;;) { setdisk (tempdisk); if (getdisk () == tempdisk) { unsigned long total; setdisk (curdisk); getdfree (tempdisk + 1, &free); total = (long) free.df_avail * (long) free.df_bsec * (long) free.df_sclus; if (total >= size) { char* pSFNSlot; ConvertToSFN(tempfile, ENVVAR_ID); pSFNSlot = GetSFN(ENVVAR_ID); if (pSFNSlot) { strcpy(tempfile, pSFNSlot); Handle = creattemp (tempfile, 0); if (Handle != -1) { MemType = HARDDISK; CloseFunc = CloseDisk; ReadFunc = DiskRead; WriteFunc = DiskWrite; PrepareToReadFunc = PrepareForReadingDisk; PrepareToWriteFunc = PrepareForWritingDisk; *allocated = size; break; } } } } if (tempdisk != 2 || run == 1) /* if not C drive. */ { run++; strcpy (tempfile, "C:\\"); tempdisk = 2; /* try C drive instead. */ } else break; } } /* See if there is enough memory left on the far heap. */ if (!MemType && farfree > BUFFERSIZE) { size = farfree - (farfree % BUFFERSIZE); FarBlock = (char far *) farmalloc (size); LastOffset = FP_OFF (FarBlock); LastSegment = FP_SEG (FarBlock); SavedSegment = LastSegment = LastSegment + LastOffset / 16; SavedOffset = LastOffset = LastOffset % 16; MemType = BUFFERS; CloseFunc = CloseBuffers; ReadFunc = BufferRead; WriteFunc = BufferWrite; PrepareToReadFunc = PrepareForChangingBuffers; PrepareToWriteFunc = PrepareForChangingBuffers; *allocated = size; } return MemType; }
int main(void) { int i; unsigned int handle1, handle2; /* XMS handles */ char *buf1, *buf2; if ((i = XMSinit()) == 0) { printf("Extended Memory Manager not found, terminating program\n"); return 1; } i = XMSversion(); printf("Extended Memory Manager Version %d.%d is installed\n", i >> 8, (i & 0xff)); printf("There are %ld extended memory bytes available\n", XMScoreleft()); buf1 = malloc(BufSize); buf2 = malloc(BufSize); if (buf1 == NULL || buf2 == NULL) { printf("Error allocating conventional memory\n"); return 1; } for (i = 0; i < BufSize; i++) /* Fill buf1 with some values */ { buf1[i] = i % 255; buf2[i] = 0; } handle1 = XMSalloc(BlockSize); if (handle1 == 0) { printf("Error allocating XMS memory for handle 1\n"); return 1; } printf("Handle 1 is %u and represents %ld bytes\n", handle1, BlockSize); printf("There are %ld extended memory bytes available\n", XMScoreleft()); handle2 = XMSalloc(BlockSize); if (handle2 == 0) { XMSfree(handle1); printf("Error allocating XMS memory for handle 2\n"); return 1; } printf("Handle 2 is %u and represents %ld bytes\n", handle2, BlockSize); printf("There are %ld extended memory bytes available\n", XMScoreleft()); /* Copy data from DOS buf1 to XMS memory of handle1 */ if (DOStoXMSmove(handle1, 0L, buf1, (long) BufSize) != BufSize) printf("DOStoXMS copy failed\n"); /* Copy XMS handle1 data to XMS handle2 */ if (XMSmemcpy(handle2, 0L, handle1, 0L, BlockSize) != BlockSize) printf("XMS copy failed\n"); /* Copy XMS handle2 data to DOS buf2 */ if (XMStoDOSmove(buf2, handle1, 0L, (long) BufSize) != BufSize) printf("XMStoDOS copy failed\n"); /* buf1 data should now == buf2 data */ for (i = 0; i < BufSize; i++) { if (buf1[i] != buf2[i]) { printf("*** ERROR: Mismatch in DOS buffers at " "location %d ***\n", i); break; } } free(buf1); free(buf2); XMSfree(handle2); printf("There are %ld bytes available after freeing handle 2\n", XMScoreleft()); XMSfree(handle1); printf("There are %ld bytes available after freeing handle 1\n", XMScoreleft()); return 0; }