mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[NTVDM]
Implement EMS function AH = 57h. svn path=/trunk/; revision=66602
This commit is contained in:
parent
e0a175fa25
commit
b0c6956a17
2 changed files with 128 additions and 16 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#define NDEBUG
|
||||
|
||||
#include "emulator.h"
|
||||
#include "bios/bios32/bios32p.h"
|
||||
#include <ndk/rtltypes.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
@ -104,12 +105,24 @@ static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
|
|||
return EMS_STATUS_OK;
|
||||
}
|
||||
|
||||
static PEMS_PAGE GetLogicalPage(PEMS_HANDLE Handle, USHORT LogicalPage)
|
||||
{
|
||||
PLIST_ENTRY Entry = Handle->PageList.Flink;
|
||||
|
||||
while (LogicalPage)
|
||||
{
|
||||
if (Entry == &Handle->PageList) return NULL;
|
||||
LogicalPage--;
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
return (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry);
|
||||
}
|
||||
|
||||
static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PEMS_PAGE PageEntry;
|
||||
PEMS_HANDLE HandleEntry = &HandleTable[Handle];
|
||||
ULONG PageNumber;
|
||||
|
||||
if (PhysicalPage >= EMS_PHYSICAL_PAGES) return EMS_STATUS_INV_PHYSICAL_PAGE;
|
||||
if (LogicalPage == 0xFFFF)
|
||||
|
@ -121,21 +134,10 @@ static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
|
|||
|
||||
if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) return EMS_STATUS_INVALID_HANDLE;
|
||||
|
||||
Entry = HandleEntry->PageList.Flink;
|
||||
while (LogicalPage)
|
||||
{
|
||||
if (Entry == &HandleEntry->PageList) break;
|
||||
|
||||
LogicalPage--;
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
if (Entry == &HandleEntry->PageList) return EMS_STATUS_INV_LOGICAL_PAGE;
|
||||
|
||||
PageEntry = (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry);
|
||||
PageNumber = (ULONG)(((ULONG_PTR)PageEntry - (ULONG_PTR)PageTable) / sizeof(EMS_PAGE));
|
||||
Mapping[PhysicalPage] = (PVOID)(EMS_ADDRESS + PageNumber * EMS_PAGE_SIZE);
|
||||
PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
|
||||
if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
|
||||
|
||||
Mapping[PhysicalPage] = (PVOID)(EMS_ADDRESS + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE);
|
||||
return EMS_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -192,6 +194,97 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Move/Exchange Memory */
|
||||
case 0x57:
|
||||
{
|
||||
PUCHAR SourcePtr, DestPtr;
|
||||
PEMS_HANDLE HandleEntry;
|
||||
PEMS_PAGE PageEntry;
|
||||
BOOLEAN Exchange = getAL();
|
||||
PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());
|
||||
|
||||
if (Data->SourceType)
|
||||
{
|
||||
/* Expanded memory */
|
||||
HandleEntry = &HandleTable[Data->SourceHandle];
|
||||
|
||||
if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated)
|
||||
{
|
||||
setAL(EMS_STATUS_INVALID_HANDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
|
||||
|
||||
if (!PageEntry)
|
||||
{
|
||||
setAL(EMS_STATUS_INV_LOGICAL_PAGE);
|
||||
break;
|
||||
}
|
||||
|
||||
SourcePtr = (PUCHAR)(EMS_ADDRESS
|
||||
+ ARRAY_INDEX(PageEntry, PageTable)
|
||||
* EMS_PAGE_SIZE
|
||||
+ Data->SourceOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional memory */
|
||||
SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
|
||||
}
|
||||
|
||||
if (Data->DestType)
|
||||
{
|
||||
/* Expanded memory */
|
||||
HandleEntry = &HandleTable[Data->DestHandle];
|
||||
|
||||
if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated)
|
||||
{
|
||||
setAL(EMS_STATUS_INVALID_HANDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
|
||||
|
||||
if (!PageEntry)
|
||||
{
|
||||
setAL(EMS_STATUS_INV_LOGICAL_PAGE);
|
||||
break;
|
||||
}
|
||||
|
||||
DestPtr = (PUCHAR)(EMS_ADDRESS
|
||||
+ ARRAY_INDEX(PageEntry, PageTable)
|
||||
* EMS_PAGE_SIZE
|
||||
+ Data->DestOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional memory */
|
||||
DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
|
||||
}
|
||||
|
||||
if (Exchange)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Exchange */
|
||||
for (i = 0; i < Data->RegionLength; i++)
|
||||
{
|
||||
UCHAR Temp = DestPtr[i];
|
||||
DestPtr[i] = SourcePtr[i];
|
||||
SourcePtr[i] = Temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move */
|
||||
RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
|
||||
}
|
||||
|
||||
setAL(EMS_STATUS_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH());
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#define EMS_STATUS_INV_PHYSICAL_PAGE 0x8B
|
||||
#define EMS_STATUS_UNKNOWN_FUNCTION 0x8F
|
||||
|
||||
#define ARRAY_INDEX(ptr, array) ((ULONG)(((ULONG_PTR)(ptr) - (ULONG_PTR)(array)) / sizeof(*array)))
|
||||
|
||||
typedef struct _EMS_HANDLE
|
||||
{
|
||||
BOOLEAN Allocated;
|
||||
|
@ -45,6 +47,23 @@ typedef struct _EMS_PAGE
|
|||
USHORT Handle;
|
||||
} EMS_PAGE, *PEMS_PAGE;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct _EMS_COPY_DATA
|
||||
{
|
||||
ULONG RegionLength;
|
||||
UCHAR SourceType;
|
||||
USHORT SourceHandle;
|
||||
USHORT SourceOffset;
|
||||
USHORT SourceSegment;
|
||||
UCHAR DestType;
|
||||
USHORT DestHandle;
|
||||
USHORT DestOffset;
|
||||
USHORT DestSegment;
|
||||
} EMS_COPY_DATA, *PEMS_COPY_DATA;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size);
|
||||
|
|
Loading…
Reference in a new issue