Implement XMS function 0Fh (Reallocate Extended Memory Block).


svn path=/trunk/; revision=68592
This commit is contained in:
Aleksandar Andrejevic 2015-08-01 21:48:06 +00:00
parent 96c972db0b
commit 6828502269

View file

@ -272,6 +272,89 @@ static UCHAR XmsAlloc(WORD Size, PWORD Handle)
return XMS_STATUS_OUT_OF_MEMORY;
}
static UCHAR XmsRealloc(WORD Handle, WORD NewSize)
{
DWORD BlockNumber;
PXMS_HANDLE HandleEntry = GetHandleRecord(Handle);
DWORD CurrentIndex = 0;
ULONG RunStart;
ULONG RunSize;
if (!ValidateHandle(HandleEntry))
return XMS_STATUS_INVALID_HANDLE;
if (HandleEntry->LockCount)
return XMS_STATUS_LOCKED;
/* Get the block number */
BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
if (NewSize < HandleEntry->Size)
{
/* Just reduce the size of this block */
RtlClearBits(&AllocBitmap, BlockNumber + NewSize, HandleEntry->Size - NewSize);
FreeBlocks += HandleEntry->Size - NewSize;
HandleEntry->Size = NewSize;
}
else if (NewSize > HandleEntry->Size)
{
/* Check if we can expand in-place */
if (RtlAreBitsClear(&AllocBitmap,
BlockNumber + HandleEntry->Size,
NewSize - HandleEntry->Size))
{
/* Just increase the size of this block */
RtlSetBits(&AllocBitmap,
BlockNumber + HandleEntry->Size,
NewSize - HandleEntry->Size);
FreeBlocks -= NewSize - HandleEntry->Size;
HandleEntry->Size = NewSize;
/* We're done */
return XMS_STATUS_SUCCESS;
}
/* Deallocate the current block range */
RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
/* Find a new place for this block */
while (CurrentIndex < XMS_BLOCKS)
{
RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
if (RunSize == 0) break;
if (RunSize >= NewSize)
{
/* Allocate the new range */
RtlSetBits(&AllocBitmap, RunStart, NewSize);
/* Move the data to the new location */
RtlMoveMemory((PVOID)REAL_TO_PHYS(XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE),
(PVOID)REAL_TO_PHYS(HandleEntry->Address),
HandleEntry->Size * XMS_BLOCK_SIZE);
/* Update the handle entry */
HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE;
HandleEntry->Size = NewSize;
/* Update the free block counter */
FreeBlocks -= NewSize - HandleEntry->Size;
return XMS_STATUS_SUCCESS;
}
/* Keep searching */
CurrentIndex = RunStart + RunSize;
}
/* Restore the old block range */
RtlSetBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
return XMS_STATUS_OUT_OF_MEMORY;
}
return XMS_STATUS_SUCCESS;
}
static UCHAR XmsFree(WORD Handle)
{
DWORD BlockNumber;
@ -478,7 +561,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
WORD Handle;
UCHAR Result = XmsAlloc(getDX(), &Handle);
if (Result >= 0)
if (Result == XMS_STATUS_SUCCESS)
{
setAX(1);
setDX(Handle);
@ -497,7 +580,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
{
UCHAR Result = XmsFree(getDX());
setAX(Result >= 0);
setAX(Result == XMS_STATUS_SUCCESS);
setBL(Result);
break;
}
@ -571,7 +654,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
DWORD Address;
UCHAR Result = XmsLock(getDX(), &Address);
if (Result >= 0)
if (Result == XMS_STATUS_SUCCESS)
{
setAX(1);
@ -593,7 +676,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
{
UCHAR Result = XmsUnlock(getDX());
setAX(Result >= 0);
setAX(Result == XMS_STATUS_SUCCESS);
setBL(Result);
break;
}
@ -627,40 +710,10 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
/* Reallocate Extended Memory Block */
case 0x0F:
{
PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
WORD NewSize = getBX();
UCHAR Result = XmsRealloc(getDX(), getBX());
if (!ValidateHandle(HandleEntry))
{
setAX(0);
setBL(XMS_STATUS_INVALID_HANDLE);
break;
}
if (HandleEntry->LockCount)
{
setAX(0);
setBL(XMS_STATUS_LOCKED);
break;
}
/* Check for reduction or enlargement */
if (NewSize < HandleEntry->Size)
{
/* Reduction, the easy case: just update the size */
HandleEntry->Size = NewSize;
}
else
{
/* Enlargement: we need to reallocate elsewhere */
UNIMPLEMENTED;
setAX(0);
setBL(XMS_STATUS_NOT_IMPLEMENTED);
break;
}
setAX(1);
setBL(XMS_STATUS_SUCCESS);
setAX(Result == XMS_STATUS_SUCCESS);
setBL(Result);
break;
}