Author: aandrejevic
Date: Sun Mar 8 00:36:46 2015
New Revision: 66602
URL:
http://svn.reactos.org/svn/reactos?rev=66602&view=rev
Log:
[NTVDM]
Implement EMS function AH = 57h.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/ems.c
trunk/reactos/subsystems/mvdm/ntvdm/ems.h
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ems.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/ems.…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/ems.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ems.c [iso-8859-1] Sun Mar 8 00:36:46 2015
@@ -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 @@
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 @@
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 @@
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());
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ems.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/ems.…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/ems.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ems.h [iso-8859-1] Sun Mar 8 00:36:46 2015
@@ -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 @@
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);