Author: aandrejevic
Date: Sat Mar 7 00:43:17 2015
New Revision: 66596
URL:
http://svn.reactos.org/svn/reactos?rev=66596&view=rev
Log:
[NTVDM]
Begin implementing Expanded Memory Space (EMS) support.
Added:
trunk/reactos/subsystems/mvdm/ntvdm/ems.c (with props)
trunk/reactos/subsystems/mvdm/ntvdm/ems.h (with props)
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt
trunk/reactos/subsystems/mvdm/ntvdm/emulator.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/CMak…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt [iso-8859-1] Sat Mar 7 00:43:17
2015
@@ -33,6 +33,7 @@
dos/mouse32.c
dos/dem.c
clock.c
+ ems.c
emulator.c
int32.c
io.c
Added: 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 (added)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ems.c [iso-8859-1] Sat Mar 7 00:43:17 2015
@@ -0,0 +1,231 @@
+/*
+ * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: ems.c
+ * PURPOSE: Expanded Memory Support
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "bios/bios32/bios32p.h"
+#include <ndk/rtltypes.h>
+#include <ndk/rtlfuncs.h>
+#include "ems.h"
+
+/* PRIVATE VARIABLES **********************************************************/
+
+static RTL_BITMAP AllocBitmap;
+static ULONG BitmapBuffer[(EMS_TOTAL_PAGES + sizeof(ULONG) - 1) / sizeof(ULONG)];
+static EMS_PAGE PageTable[EMS_TOTAL_PAGES];
+static EMS_HANDLE HandleTable[EMS_MAX_HANDLES];
+static PVOID Mapping[EMS_PHYSICAL_PAGES] = { NULL };
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static USHORT EmsFree(USHORT Handle)
+{
+ PLIST_ENTRY Entry;
+ PEMS_HANDLE HandleEntry = &HandleTable[Handle];
+
+ if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated)
+ {
+ return EMS_STATUS_INVALID_HANDLE;
+ }
+
+ for (Entry = HandleEntry->PageList.Flink;
+ Entry != &HandleEntry->PageList;
+ Entry = Entry->Flink)
+ {
+ PEMS_PAGE PageEntry = (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry);
+ ULONG PageNumber = (ULONG)(((ULONG_PTR)PageEntry - (ULONG_PTR)PageTable) /
sizeof(EMS_PAGE));
+
+ /* Free the page */
+ RtlClearBits(&AllocBitmap, PageNumber, 1);
+ }
+
+ HandleEntry->Allocated = FALSE;
+ HandleEntry->PageCount = 0;
+ InitializeListHead(&HandleEntry->PageList);
+
+ return EMS_STATUS_OK;
+}
+
+static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
+{
+ ULONG i, CurrentIndex = 0;
+ PEMS_HANDLE HandleEntry;
+
+ if (NumPages == 0) return EMS_STATUS_ZERO_PAGES;
+
+ for (i = 0; i < EMS_MAX_HANDLES; i++)
+ {
+ HandleEntry = &HandleTable[i];
+ if (!HandleEntry->Allocated)
+ {
+ *Handle = i;
+ break;
+ }
+ }
+
+ if (i == EMS_MAX_HANDLES) return EMS_STATUS_NO_MORE_HANDLES;
+ HandleEntry->Allocated = TRUE;
+
+ while (HandleEntry->PageCount < NumPages)
+ {
+ ULONG RunStart;
+ ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex,
&RunStart);
+
+ if (RunSize == 0)
+ {
+ /* Free what's been allocated already and report failure */
+ EmsFree(*Handle);
+ return EMS_STATUS_INSUFFICIENT_PAGES;
+ }
+ else if ((HandleEntry->PageCount + RunSize) > NumPages)
+ {
+ /* We don't need the entire run */
+ RunSize = NumPages - HandleEntry->PageCount;
+ }
+
+ CurrentIndex = RunStart + RunSize;
+ HandleEntry->PageCount += RunSize;
+ RtlSetBits(&AllocBitmap, RunStart, RunSize);
+
+ for (i = 0; i < RunSize; i++)
+ {
+ PageTable[RunStart + i].Handle = *Handle;
+ InsertTailList(&HandleEntry->PageList, &PageTable[RunStart +
i].Entry);
+ }
+ }
+
+ return EMS_STATUS_OK;
+}
+
+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)
+ {
+ /* Unmap */
+ Mapping[PhysicalPage] = NULL;
+ return EMS_STATUS_OK;
+ }
+
+ 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);
+
+ return EMS_STATUS_OK;
+}
+
+static VOID WINAPI EmsIntHandler(LPWORD Stack)
+{
+ switch (getAH())
+ {
+ /* Get Manager Status */
+ case 0x40:
+ {
+ setAH(EMS_STATUS_OK);
+ break;
+ }
+
+ /* Get Page Frame Segment */
+ case 0x41:
+ {
+ setAH(EMS_STATUS_OK);
+ setBX(EMS_SEGMENT);
+ break;
+ }
+
+ /* Get Number Of Pages */
+ case 0x42:
+ {
+ setAH(EMS_STATUS_OK);
+ setBX(RtlNumberOfClearBits(&AllocBitmap));
+ setDX(EMS_TOTAL_PAGES);
+ break;
+ }
+
+ /* Get Handle And Allocate Memory */
+ case 0x43:
+ {
+ USHORT Handle;
+ UCHAR Status = EmsAlloc(getBX(), &Handle);
+
+ setAH(Status);
+ if (Status == EMS_STATUS_OK) setDX(Handle);
+ break;
+ }
+
+ /* Map Memory */
+ case 0x44:
+ {
+ setAH(EmsMap(getDX(), getAL(), getBX()));
+ break;
+ }
+
+ /* Release Handle And Memory */
+ case 0x45:
+ {
+ setAH(EmsFree(getDX()));
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH());
+ setAH(EMS_STATUS_UNKNOWN_FUNCTION);
+ break;
+ }
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
+{
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+}
+
+VOID EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
+{
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+}
+
+VOID EmsInitialize(VOID)
+{
+ ULONG i;
+ RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, EMS_TOTAL_PAGES);
+
+ for (i = 0; i < EMS_MAX_HANDLES; i++)
+ {
+ HandleTable[i].Allocated = FALSE;
+ HandleTable[i].PageCount = 0;
+ InitializeListHead(&HandleTable[i].PageList);
+ }
+
+ RegisterBiosInt32(EMS_INTERRUPT_NUM, EmsIntHandler);
+}
Propchange: trunk/reactos/subsystems/mvdm/ntvdm/ems.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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 (added)
+++ trunk/reactos/subsystems/mvdm/ntvdm/ems.h [iso-8859-1] Sat Mar 7 00:43:17 2015
@@ -0,0 +1,56 @@
+/*
+ * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: ems.h
+ * PURPOSE: Expanded Memory Support
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _EMS_H_
+#define _EMS_H_
+
+/* DEFINITIONS ****************************************************************/
+
+#define EMS_INTERRUPT_NUM 0x67
+#define EMS_SEGMENT 0xE000
+#define EMS_MAX_HANDLES 16
+#define EMS_TOTAL_PAGES 256
+#define EMS_PAGE_BITS 14
+#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
+#define EMS_ADDRESS 0xA00000
+#define EMS_PHYSICAL_PAGES 4
+#define EMS_START_ADDRESS (EMS_SEGMENT << 4)
+#define EMS_END_ADDRESS (EMS_START_ADDRESS + EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE)
+
+#define EMS_STATUS_OK 0x00
+#define EMS_STATUS_INTERNAL_ERROR 0x80
+#define EMS_STATUS_INVALID_HANDLE 0x83
+#define EMS_STATUS_NO_MORE_HANDLES 0x85
+#define EMS_STATUS_INSUFFICIENT_PAGES 0x88
+#define EMS_STATUS_ZERO_PAGES 0x89
+#define EMS_STATUS_INV_LOGICAL_PAGE 0x8A
+#define EMS_STATUS_INV_PHYSICAL_PAGE 0x8B
+#define EMS_STATUS_UNKNOWN_FUNCTION 0x8F
+
+typedef struct _EMS_HANDLE
+{
+ BOOLEAN Allocated;
+ USHORT PageCount;
+ LIST_ENTRY PageList;
+} EMS_HANDLE, *PEMS_HANDLE;
+
+typedef struct _EMS_PAGE
+{
+ LIST_ENTRY Entry;
+ USHORT Handle;
+} EMS_PAGE, *PEMS_PAGE;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size);
+VOID EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size);
+VOID EmsInitialize(VOID);
+
+#endif // _EMS_H_
+
+/* EOF */
Propchange: trunk/reactos/subsystems/mvdm/ntvdm/ems.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/subsystems/mvdm/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/emul…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/emulator.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/emulator.c [iso-8859-1] Sat Mar 7 00:43:17 2015
@@ -30,6 +30,7 @@
#include "hardware/sound/speaker.h"
#include "hardware/pit.h"
#include "hardware/video/vga.h"
+#include "ems.h"
#include "vddsup.h"
#include "io.h"
@@ -619,6 +620,9 @@
/* Initialize I/O ports */
/* Initialize RAM */
+ /* Initialize EMS */
+ EmsInitialize();
+
/* Initialize the CPU */
/* Initialize the internal clock */