mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 11:32:56 +00:00
[NTVDM]
Implement XMS function 0Fh (Reallocate Extended Memory Block). svn path=/trunk/; revision=68592
This commit is contained in:
parent
96c972db0b
commit
6828502269
1 changed files with 90 additions and 37 deletions
|
@ -272,6 +272,89 @@ static UCHAR XmsAlloc(WORD Size, PWORD Handle)
|
||||||
return XMS_STATUS_OUT_OF_MEMORY;
|
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)
|
static UCHAR XmsFree(WORD Handle)
|
||||||
{
|
{
|
||||||
DWORD BlockNumber;
|
DWORD BlockNumber;
|
||||||
|
@ -478,7 +561,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
||||||
WORD Handle;
|
WORD Handle;
|
||||||
UCHAR Result = XmsAlloc(getDX(), &Handle);
|
UCHAR Result = XmsAlloc(getDX(), &Handle);
|
||||||
|
|
||||||
if (Result >= 0)
|
if (Result == XMS_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
setAX(1);
|
setAX(1);
|
||||||
setDX(Handle);
|
setDX(Handle);
|
||||||
|
@ -497,7 +580,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
||||||
{
|
{
|
||||||
UCHAR Result = XmsFree(getDX());
|
UCHAR Result = XmsFree(getDX());
|
||||||
|
|
||||||
setAX(Result >= 0);
|
setAX(Result == XMS_STATUS_SUCCESS);
|
||||||
setBL(Result);
|
setBL(Result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -571,7 +654,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
||||||
DWORD Address;
|
DWORD Address;
|
||||||
UCHAR Result = XmsLock(getDX(), &Address);
|
UCHAR Result = XmsLock(getDX(), &Address);
|
||||||
|
|
||||||
if (Result >= 0)
|
if (Result == XMS_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
setAX(1);
|
setAX(1);
|
||||||
|
|
||||||
|
@ -593,7 +676,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
||||||
{
|
{
|
||||||
UCHAR Result = XmsUnlock(getDX());
|
UCHAR Result = XmsUnlock(getDX());
|
||||||
|
|
||||||
setAX(Result >= 0);
|
setAX(Result == XMS_STATUS_SUCCESS);
|
||||||
setBL(Result);
|
setBL(Result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -627,40 +710,10 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
||||||
/* Reallocate Extended Memory Block */
|
/* Reallocate Extended Memory Block */
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
{
|
{
|
||||||
PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
|
UCHAR Result = XmsRealloc(getDX(), getBX());
|
||||||
WORD NewSize = getBX();
|
|
||||||
|
|
||||||
if (!ValidateHandle(HandleEntry))
|
setAX(Result == XMS_STATUS_SUCCESS);
|
||||||
{
|
setBL(Result);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue