Author: aandrejevic
Date: Tue Apr 21 22:48:28 2015
New Revision: 67339
URL:
http://svn.reactos.org/svn/reactos?rev=67339&view=rev
Log:
[NTVDM]
- Move the EMS code from the BIOS to the DOS driver where it belongs.
- Expand the DOS device API with a new function, DosCreateDeviceEx, which
will allow 32-bit DOS driver to reserve private memory.
- For each DOS device, create an entry in guest memory so that 16-bit code
can call 32-bit DOS drivers directly.
- Implement an XMS driver stub that uses the above.
- Arch, that's not how the DOS driver strategy routine works, you need to
give it the request in ES:BX which it will store somewhere, and then call
the interrupt routine.
Added:
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h (with props)
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c (with props)
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h (with props)
Removed:
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.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] Tue Apr 21 22:48:28
2015
@@ -10,7 +10,6 @@
bios/bios32/kbdbios32.c
bios/bios32/vidbios32.c
bios/bios32/moubios32.c
- bios/bios32/ems.c
bios/bios.c
bios/kbdbios.c
bios/rom.c
@@ -34,6 +33,7 @@
dos/dos32krnl/dos.c
dos/dos32krnl/dosfiles.c
dos/dos32krnl/emsdrv.c
+ dos/dos32krnl/himem.c
dos/dos32krnl/memory.c
dos/mouse32.c
dos/dem.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -26,8 +26,6 @@
#include "kbdbios32.h"
#include "vidbios32.h"
#include "moubios32.h"
-
-#include "ems.h"
#include "io.h"
#include "hardware/cmos.h"
@@ -665,13 +663,6 @@
SearchAndInitRoms(&BiosContext);
- /* Initialize EMS */
- if (!EmsInitialize(EMS_TOTAL_PAGES))
- {
- DPRINT1("Could not initialize EMS. EMS will not be available.\n"
- "Try reducing the number of EMS pages.\n");
- }
-
/*
* End of the 32-bit POST portion. We then fall back into 16-bit where
* the rest of the POST code is executed, typically calling INT 19h
@@ -733,7 +724,6 @@
VOID Bios32Cleanup(VOID)
{
- EmsCleanup();
MouseBios32Cleanup();
VidBios32Cleanup();
KbdBios32Cleanup();
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -21,9 +21,6 @@
// #define BIOS_TIME_INTERRUPT 0x1A
// #define BIOS_SYS_TIMER_INTERRUPT 0x1C
-/* 16 MB of EMS memory */
-#define EMS_TOTAL_PAGES 1024
-
/* FUNCTIONS ******************************************************************/
BOOLEAN Bios32Initialize(VOID);
Removed: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c (removed)
@@ -1,422 +0,0 @@
-/*
- * 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 "ntvdm.h"
-#include "emulator.h"
-#include "bios/bios32/bios32p.h"
-#include "ems.h"
-#include "memory.h"
-
-/* PRIVATE VARIABLES **********************************************************/
-
-static RTL_BITMAP AllocBitmap;
-static PULONG BitmapBuffer = NULL;
-static PEMS_PAGE PageTable = NULL;
-static EMS_HANDLE HandleTable[EMS_MAX_HANDLES];
-static PVOID Mapping[EMS_PHYSICAL_PAGES] = { NULL };
-static ULONG EmsTotalPages = 0;
-static PVOID EmsMemory = 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 = ARRAY_INDEX(PageEntry, PageTable);
-
- /* 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 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)
-{
- PEMS_PAGE PageEntry;
- PEMS_HANDLE HandleEntry = &HandleTable[Handle];
-
- 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;
-
- PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
- if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
-
- Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
- + ARRAY_INDEX(PageEntry, PageTable) * 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(EmsTotalPages);
- 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;
- }
-
- /* Get EMM Version */
- case 0x46:
- {
- setAH(EMS_STATUS_OK);
- setAL(EMS_VERSION_NUM);
- 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)((ULONG_PTR)EmsMemory
- + 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)((ULONG_PTR)EmsMemory
- + 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());
- setAH(EMS_STATUS_UNKNOWN_FUNCTION);
- break;
- }
- }
-}
-
-static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
-{
- ULONG i;
- ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
- ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
- ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
- ULONG Offset, Length;
-
- for (i = FirstPage; i <= LastPage; i++)
- {
- Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
- Length = ((i == LastPage)
- ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
- : EMS_PAGE_SIZE) - Offset;
-
- if (Mapping[i]) RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Mapping[i] + Offset),
Length);
- Buffer = (PVOID)((ULONG_PTR)Buffer + Length);
- }
-}
-
-static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
-{
- ULONG i;
- ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
- ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
- ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
- ULONG Offset, Length;
-
- for (i = FirstPage; i <= LastPage; i++)
- {
- Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
- Length = ((i == LastPage)
- ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
- : EMS_PAGE_SIZE) - Offset;
-
- if (Mapping[i]) RtlCopyMemory((PVOID)((ULONG_PTR)Mapping[i] + Offset), Buffer,
Length);
- Buffer = (PVOID)((ULONG_PTR)Buffer + Length);
- }
-
- return TRUE;
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-BOOLEAN EmsInitialize(ULONG TotalPages)
-{
- ULONG i;
-
- for (i = 0; i < EMS_MAX_HANDLES; i++)
- {
- HandleTable[i].Allocated = FALSE;
- HandleTable[i].PageCount = 0;
- InitializeListHead(&HandleTable[i].PageList);
- }
-
- EmsTotalPages = TotalPages;
- BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- ((TotalPages + 31) / 32) * sizeof(ULONG));
- if (BitmapBuffer == NULL) return FALSE;
-
- RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, TotalPages);
-
- PageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- TotalPages * sizeof(EMS_PAGE));
- if (PageTable == NULL)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
- BitmapBuffer = NULL;
-
- return FALSE;
- }
-
- EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages *
EMS_PAGE_SIZE);
- if (EmsMemory == NULL)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable);
- PageTable = NULL;
- RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
- BitmapBuffer = NULL;
-
- return FALSE;
- }
-
- MemInstallFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0),
- EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE,
- EmsReadMemory,
- EmsWriteMemory);
-
- RegisterBiosInt32(EMS_INTERRUPT_NUM, EmsIntHandler);
- return TRUE;
-}
-
-VOID EmsCleanup(VOID)
-{
- MemRemoveFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0),
- EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE);
-
- if (EmsMemory)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
- EmsMemory = NULL;
- }
-
- if (PageTable)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable);
- PageTable = NULL;
- }
-
- if (BitmapBuffer)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
- BitmapBuffer = NULL;
- }
-}
Removed: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h (removed)
@@ -1,69 +0,0 @@
-/*
- * 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_VERSION_NUM 0x04
-#define EMS_INTERRUPT_NUM 0x67
-#define EMS_SEGMENT 0xD000
-#define EMS_MAX_HANDLES 16
-#define EMS_PAGE_BITS 14
-#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
-#define EMS_PHYSICAL_PAGES 4
-
-#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;
-
-#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 ******************************************************************/
-
-BOOLEAN EmsInitialize(ULONG TotalPages);
-VOID EmsCleanup(VOID);
-
-#endif // _EMS_H_
-
-/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c [iso-8859-1] Tue Apr 21 22:48:28 2015
@@ -19,6 +19,7 @@
#include "utils.h"
#include "dem.h"
+#include "dos/dos32krnl/device.h"
#include "cpu/bop.h"
#include "bios/bios.h"
@@ -27,14 +28,6 @@
/* PRIVATE VARIABLES **********************************************************/
/**/extern BYTE CurrentDrive;/**/
-
-/* DEFINES ********************************************************************/
-
-/* BOP Identifiers */
-#define BOP_LOAD_DOS 0x2B // DOS Loading and Initializing BOP. In parameter
(following bytes) we take a NULL-terminated string indicating the name of the DOS kernel
file.
-#define BOP_START_DOS 0x2C // DOS Starting BOP. In parameter (following bytes) we
take a NULL-terminated string indicating the name of the DOS kernel file.
-#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
-#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM)
/* PRIVATE FUNCTIONS **********************************************************/
@@ -86,6 +79,20 @@
EmulatorTerminate();
}
+ break;
+ }
+
+ /* Call 32-bit Driver Strategy Routine */
+ case BOP_DRV_STRATEGY:
+ {
+ DeviceStrategyBop();
+ break;
+ }
+
+ /* Call 32-bit Driver Interrupt Routine */
+ case BOP_DRV_INTERRUPT:
+ {
+ DeviceInterruptBop();
break;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h [iso-8859-1] Tue Apr 21 22:48:28 2015
@@ -16,6 +16,14 @@
/* INCLUDES *******************************************************************/
#include "dos32krnl/dos.h"
+
+/* DEFINES ********************************************************************/
+
+/* BOP Identifiers */
+#define BOP_LOAD_DOS 0x2B // DOS Loading and Initializing BOP. In parameter
(following bytes) we take a NULL-terminated string indicating the name of the DOS kernel
file.
+#define BOP_START_DOS 0x2C // DOS Starting BOP. In parameter (following bytes) we
take a NULL-terminated string indicating the name of the DOS kernel file.
+#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
+#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM)
/* FUNCTIONS ******************************************************************/
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -12,6 +12,7 @@
#include "ntvdm.h"
#include "emulator.h"
+#include "cpu/bop.h"
#include "device.h"
#include "dos.h"
@@ -20,27 +21,54 @@
/* PRIVATE VARIABLES **********************************************************/
+static const BYTE StrategyRoutine[] = {
+ LOBYTE(EMULATOR_BOP),
+ HIBYTE(EMULATOR_BOP),
+ BOP_DOS,
+ BOP_DRV_STRATEGY,
+ 0xCB // retf
+};
+
+static const BYTE InterruptRoutine[] = {
+ LOBYTE(EMULATOR_BOP),
+ HIBYTE(EMULATOR_BOP),
+ BOP_DOS,
+ BOP_DRV_INTERRUPT,
+ 0xCB // retf
+};
+
+C_ASSERT((sizeof(StrategyRoutine) + sizeof(InterruptRoutine)) == DEVICE_CODE_SIZE);
+
static LIST_ENTRY DeviceList = { &DeviceList, &DeviceList };
+static DWORD FirstDriver = 0xFFFFFFFF;
+static PDOS_REQUEST_HEADER DeviceRequest;
/* PRIVATE FUNCTIONS **********************************************************/
static VOID DosCallDriver(DWORD Driver, PDOS_REQUEST_HEADER Request)
{
PDOS_DRIVER DriverBlock = (PDOS_DRIVER)FAR_POINTER(Driver);
- PDOS_REQUEST_HEADER RemoteRequest;
-
- /* Call the strategy routine first */
- Call16(HIWORD(Driver), DriverBlock->StrategyRoutine);
- RemoteRequest = (PDOS_REQUEST_HEADER)SEG_OFF_TO_PTR(getES(), getBX());
+ PDOS_REQUEST_HEADER RemoteRequest = FAR_POINTER(REQUEST_LOCATION);
+ WORD ES = getES();
+ WORD BX = getBX();
+
+ /* Set ES:BX to the location of the request */
+ setES(HIWORD(REQUEST_LOCATION));
+ setBX(LOWORD(REQUEST_LOCATION));
/* Copy the request structure to ES:BX */
RtlMoveMemory(RemoteRequest, Request, Request->RequestLength);
- /* Call the interrupt routine */
+ /* Call the strategy routine, and then the interrupt routine */
+ Call16(HIWORD(Driver), DriverBlock->StrategyRoutine);
Call16(HIWORD(Driver), DriverBlock->InterruptRoutine);
/* Get the request structure from ES:BX */
- RtlMoveMemory(Request, RemoteRequest, RemoteRequest->RequestLength);
+ RtlMoveMemory(Request, RemoteRequest, Request->RequestLength);
+
+ /* Restore ES:BX */
+ setES(ES);
+ setBX(BX);
}
static inline WORD NTAPI DosDriverReadInternal(PDOS_DEVICE_NODE DeviceNode,
@@ -183,41 +211,65 @@
return Request.Header.Status;
}
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName)
-{
- PLIST_ENTRY i;
- PDOS_DEVICE_NODE Node;
- ANSI_STRING DeviceNameString;
-
- RtlInitAnsiString(&DeviceNameString, DeviceName);
-
- for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink)
- {
- Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry);
- if (RtlEqualString(&Node->Name, &DeviceNameString, TRUE)) return
Node;
- }
-
- return NULL;
-}
-
-PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName)
+static VOID DosAddDriver(DWORD Driver)
+{
+ PDOS_DRIVER LastDriver;
+
+ if (LOWORD(FirstDriver) == 0xFFFF)
+ {
+ /* This is the first driver */
+ FirstDriver = Driver;
+ return;
+ }
+
+ /* The list isn't empty, so find the last driver in it */
+ LastDriver = (PDOS_DRIVER)FAR_POINTER(FirstDriver);
+ while (LOWORD(LastDriver->Link) != 0xFFFF)
+ {
+ LastDriver = (PDOS_DRIVER)FAR_POINTER(LastDriver->Link);
+ }
+
+ /* Add the new driver to the list */
+ LastDriver->Link = Driver;
+}
+
+static VOID DosRemoveDriver(DWORD Driver)
+{
+ DWORD CurrentDriver = FirstDriver;
+
+ if (FirstDriver == Driver)
+ {
+ /* Update the first driver */
+ FirstDriver = ((PDOS_DRIVER)FAR_POINTER(FirstDriver))->Link;
+ return;
+ }
+
+ while (LOWORD(CurrentDriver) != 0xFFFF)
+ {
+ PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver);
+
+ if (DriverHeader->Link == Driver)
+ {
+ /* Remove it from the list */
+ DriverHeader->Link =
((PDOS_DRIVER)FAR_POINTER(DriverHeader->Link))->Link;
+ return;
+ }
+
+ CurrentDriver = DriverHeader->Link;
+ }
+}
+
+static PDOS_DEVICE_NODE DosCreateDeviceNode(DWORD Driver)
{
BYTE i;
- PDOS_DEVICE_NODE Node;
-
- /* Make sure this is a character device */
- if (!(Attributes & DOS_DEVATTR_CHARACTER))
- {
- DPRINT1("ERROR: Block devices are not supported.\n");
- return FALSE;
- }
-
- Node = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*Node));
+ PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(Driver);
+ PDOS_DEVICE_NODE Node = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(*Node));
if (Node == NULL) return NULL;
- Node->DeviceAttributes = Attributes;
+ Node->Driver = Driver;
+ Node->DeviceAttributes = DriverHeader->DeviceAttributes;
/* Initialize the name string */
Node->Name.Buffer = Node->NameBuffer;
@@ -225,8 +277,8 @@
for (i = 0; i < MAX_DEVICE_NAME; i++)
{
- if (DeviceName[i] == '\0' || DeviceName[i] == ' ') break;
- Node->Name.Buffer[i] = DeviceName[i];
+ if (DriverHeader->DeviceName[i] == ' ') break;
+ Node->Name.Buffer[i] = DriverHeader->DeviceName[i];
}
Node->Name.Length = i;
@@ -235,10 +287,266 @@
return Node;
}
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName)
+{
+ PLIST_ENTRY i;
+ DWORD CurrentDriver = FirstDriver;
+ ANSI_STRING DeviceNameString;
+
+ RtlInitAnsiString(&DeviceNameString, DeviceName);
+
+ while (LOWORD(CurrentDriver) != 0xFFFF)
+ {
+ PDOS_DEVICE_NODE Node;
+ PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver);
+
+ /* Get the device node for this driver */
+ for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink)
+ {
+ Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry);
+ if (Node->Driver == CurrentDriver) break;
+ }
+
+ if (i == &DeviceList)
+ {
+ DPRINT1("The driver at %04X:%04X has no associated device node. "
+ "Installing automagically.\n",
+ HIWORD(CurrentDriver),
+ LOWORD(CurrentDriver));
+
+ /* Create the device node */
+ Node = DosCreateDeviceNode(CurrentDriver);
+ Node->IoctlReadRoutine = DosDriverDispatchIoctlRead;
+ Node->ReadRoutine = DosDriverDispatchRead;
+ Node->PeekRoutine = DosDriverDispatchPeek;
+ Node->InputStatusRoutine = DosDriverDispatchInputStatus;
+ Node->FlushInputRoutine = DosDriverDispatchFlushInput;
+ Node->IoctlWriteRoutine = DosDriverDispatchIoctlWrite;
+ Node->WriteRoutine = DosDriverDispatchWrite;
+ Node->OutputStatusRoutine = DosDriverDispatchOutputStatus;
+ Node->FlushOutputRoutine = DosDriverDispatchFlushOutput;
+ Node->OpenRoutine = DosDriverDispatchOpen;
+ Node->CloseRoutine = DosDriverDispatchClose;
+ Node->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy;
+ }
+
+ if (RtlEqualString(&Node->Name, &DeviceNameString, TRUE)) return
Node;
+ CurrentDriver = DriverHeader->Link;
+ }
+
+ return NULL;
+}
+
+PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD
PrivateDataSize)
+{
+ BYTE i;
+ WORD Segment;
+ PDOS_DRIVER DriverHeader;
+ PDOS_DEVICE_NODE Node;
+
+ /* Make sure this is a character device */
+ if (!(Attributes & DOS_DEVATTR_CHARACTER))
+ {
+ DPRINT1("ERROR: Block devices are not supported.\n");
+ return NULL;
+ }
+
+ /* Create a driver header for this device */
+ Segment = DosAllocateMemory(sizeof(DOS_DRIVER) + 10 + PrivateDataSize, NULL);
+ if (Segment == 0) return NULL;
+
+ /* Fill the header with data */
+ DriverHeader = SEG_OFF_TO_PTR(Segment, 0);
+ DriverHeader->Link = 0xFFFFFFFF;
+ DriverHeader->DeviceAttributes = Attributes;
+ DriverHeader->StrategyRoutine = sizeof(DOS_DRIVER);
+ DriverHeader->InterruptRoutine = sizeof(DOS_DRIVER) + sizeof(StrategyRoutine);
+
+ RtlFillMemory(DriverHeader->DeviceName, MAX_DEVICE_NAME, ' ');
+ for (i = 0; i < MAX_DEVICE_NAME; i++)
+ {
+ if (DeviceName[i] == '\0' || DeviceName[i] == ' ') break;
+ DriverHeader->DeviceName[i] = DeviceName[i];
+ }
+
+ /* Write the routines */
+ RtlMoveMemory(SEG_OFF_TO_PTR(Segment, DriverHeader->StrategyRoutine),
+ StrategyRoutine,
+ sizeof(StrategyRoutine));
+ RtlMoveMemory(SEG_OFF_TO_PTR(Segment, DriverHeader->StrategyRoutine),
+ InterruptRoutine,
+ sizeof(InterruptRoutine));
+
+ /* Create the node */
+ Node = DosCreateDeviceNode(MAKELONG(0, Segment));
+ if (Node == NULL)
+ {
+ DosFreeMemory(Segment);
+ return NULL;
+ }
+
+ DosAddDriver(Node->Driver);
+ return Node;
+}
+
+PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName)
+{
+ /* Call the extended API */
+ return DosCreateDeviceEx(Attributes, DeviceName, 0);
+}
+
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
{
+ DosRemoveDriver(DeviceNode->Driver);
+
+ ASSERT(LOWORD(DeviceNode->Driver) == 0);
+ DosFreeMemory(HIWORD(DeviceNode->Driver));
+
RemoveEntryList(&DeviceNode->Entry);
RtlFreeHeap(RtlGetProcessHeap(), 0, DeviceNode);
+}
+
+VOID DeviceStrategyBop(VOID)
+{
+ /* Save ES:BX */
+ DeviceRequest = (PDOS_REQUEST_HEADER)SEG_OFF_TO_PTR(getES(), getBX());
+}
+
+VOID DeviceInterruptBop(VOID)
+{
+ PLIST_ENTRY i;
+ PDOS_DEVICE_NODE Node;
+ DWORD DriverAddress = (getCS() << 4) + getIP() - sizeof(DOS_DRIVER) - 9;
+
+ /* Get the device node for this driver */
+ for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink)
+ {
+ Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry);
+ if (TO_LINEAR(HIWORD(Node->Driver), LOWORD(Node->Driver)) == DriverAddress)
break;
+ }
+
+ if (i == &DeviceList)
+ {
+ DPRINT1("Device interrupt BOP from an unknown location.\n");
+ return;
+ }
+
+ switch (DeviceRequest->CommandCode)
+ {
+ case DOS_DEVCMD_IOCTL_READ:
+ {
+ PDOS_IOCTL_RW_REQUEST Request = (PDOS_IOCTL_RW_REQUEST)DeviceRequest;
+
+ DeviceRequest->Status = Node->IoctlReadRoutine(
+ Node,
+ Request->BufferPointer,
+ &Request->Length
+ );
+
+ break;
+ }
+
+ case DOS_DEVCMD_READ:
+ {
+ PDOS_RW_REQUEST Request = (PDOS_RW_REQUEST)DeviceRequest;
+
+ DeviceRequest->Status = Node->ReadRoutine(
+ Node,
+ Request->BufferPointer,
+ &Request->Length
+ );
+
+ break;
+ }
+
+ case DOS_DEVCMD_PEEK:
+ {
+ PDOS_PEEK_REQUEST Request = (PDOS_PEEK_REQUEST)DeviceRequest;
+ DeviceRequest->Status = Node->PeekRoutine(Node,
&Request->Character);
+ break;
+ }
+
+ case DOS_DEVCMD_INSTAT:
+ {
+ DeviceRequest->Status = Node->InputStatusRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_FLUSH_INPUT:
+ {
+ DeviceRequest->Status = Node->FlushInputRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_IOCTL_WRITE:
+ {
+ PDOS_IOCTL_RW_REQUEST Request = (PDOS_IOCTL_RW_REQUEST)DeviceRequest;
+
+ DeviceRequest->Status = Node->IoctlWriteRoutine(
+ Node,
+ Request->BufferPointer,
+ &Request->Length
+ );
+
+ break;
+ }
+
+ case DOS_DEVCMD_WRITE:
+ {
+ PDOS_RW_REQUEST Request = (PDOS_RW_REQUEST)DeviceRequest;
+
+ DeviceRequest->Status = Node->WriteRoutine(Node,
+ Request->BufferPointer,
+ &Request->Length
+ );
+
+ break;
+ }
+
+ case DOS_DEVCMD_OUTSTAT:
+ {
+ DeviceRequest->Status = Node->OutputStatusRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_FLUSH_OUTPUT:
+ {
+ DeviceRequest->Status = Node->FlushOutputRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_OPEN:
+ {
+ DeviceRequest->Status = Node->OpenRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_CLOSE:
+ {
+ DeviceRequest->Status = Node->CloseRoutine(Node);
+ break;
+ }
+
+ case DOS_DEVCMD_OUTPUT_BUSY:
+ {
+ PDOS_OUTPUT_BUSY_REQUEST Request = (PDOS_OUTPUT_BUSY_REQUEST)DeviceRequest;
+
+ DeviceRequest->Status = Node->OutputUntilBusyRoutine(
+ Node,
+ Request->BufferPointer,
+ &Request->Length
+ );
+
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("Unknown device command code: %u\n",
DeviceRequest->CommandCode);
+ }
+ }
}
DWORD DosLoadDriver(LPCSTR DriverFile)
@@ -334,10 +642,8 @@
goto Next;
}
- /* Create the device */
- DeviceNode = DosCreateDevice(DriverHeader->DeviceAttributes,
- DriverHeader->DeviceName);
- DeviceNode->Driver = Driver;
+ /* Create the device node */
+ DeviceNode = DosCreateDeviceNode(Driver);
DeviceNode->IoctlReadRoutine = DosDriverDispatchIoctlRead;
DeviceNode->ReadRoutine = DosDriverDispatchRead;
DeviceNode->PeekRoutine = DosDriverDispatchPeek;
@@ -351,6 +657,7 @@
DeviceNode->CloseRoutine = DosDriverDispatchClose;
DeviceNode->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy;
+ DosAddDriver(Driver);
DriversLoaded++;
Next:
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -12,6 +12,12 @@
/* DEFINITIONS ****************************************************************/
#define MAX_DEVICE_NAME 8
+#define REQUEST_LOCATION 0x00700100 // 0070:0100
+#define DEVICE_CODE_SIZE 10
+#define DEVICE_PRIVATE_AREA(Driver) (Driver + sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE)
+
+#define BOP_DRV_STRATEGY 0x42
+#define BOP_DRV_INTERRUPT 0x43
#define DOS_DEVATTR_STDIN (1 << 0)
#define DOS_DEVATTR_STDOUT (1 << 1)
@@ -80,6 +86,7 @@
struct _DOS_DEVICE_NODE
{
LIST_ENTRY Entry;
+ DWORD Driver;
WORD DeviceAttributes;
ANSI_STRING Name;
CHAR NameBuffer[MAX_DEVICE_NAME];
@@ -95,7 +102,6 @@
PDOS_DEVICE_GENERIC_ROUTINE OpenRoutine;
PDOS_DEVICE_GENERIC_ROUTINE CloseRoutine;
PDOS_DEVICE_IO_ROUTINE OutputUntilBusyRoutine;
- DWORD Driver;
};
#pragma pack(push, 1)
@@ -190,7 +196,16 @@
PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName);
PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName);
+PDOS_DEVICE_NODE DosCreateDeviceEx
+(
+ WORD Attributes,
+ PCHAR DeviceName,
+ WORD PrivateDataSize
+);
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode);
+VOID DeviceStrategyBop(VOID);
+VOID DeviceInterruptBop(VOID);
+DWORD DosLoadDriver(LPCSTR DriverFile);
#endif // _DEVICE_H_
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -20,11 +20,14 @@
#include "dos/dem.h"
#include "device.h"
#include "memory.h"
+#include "himem.h"
#include "bios/bios.h"
#include "io.h"
#include "hardware/ps2.h"
+
+#include "emsdrv.h"
/* PRIVATE VARIABLES **********************************************************/
@@ -2934,9 +2937,39 @@
VOID WINAPI DosInt2Fh(LPWORD Stack)
{
- DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
- getAH(), getAL());
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ switch (getAH())
+ {
+ /* Extended Memory Specification */
+ case 0x43:
+ {
+ DWORD DriverEntry;
+ if (!XmsGetDriverEntry(&DriverEntry)) break;
+
+ if (getAL() == 0x00)
+ {
+ /* The driver is loaded */
+ setAL(0x80);
+ }
+ else if (getAL() == 0x10)
+ {
+ setES(HIWORD(DriverEntry));
+ setBX(LOWORD(DriverEntry));
+ }
+ else
+ {
+ DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL =
%xh\n", getAL());
+ }
+
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
+ getAH(), getAL());
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ }
+ }
}
BOOLEAN DosKRNLInitialize(VOID)
@@ -3003,12 +3036,6 @@
DosSystemFileTable[i].Type = DOS_SFT_ENTRY_NONE;
DosSystemFileTable[i].RefCount = 0;
}
-
- /* Load the EMS driver */
- EmsDrvInitialize();
-
- /* Load the CON driver */
- ConDrvInitialize();
#endif
@@ -3024,6 +3051,19 @@
RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
RegisterDosInt32(0x2F, DosInt2Fh );
+ /* Load the EMS driver */
+ if (!EmsDrvInitialize(EMS_TOTAL_PAGES))
+ {
+ DPRINT1("Could not initialize EMS. EMS will not be available.\n"
+ "Try reducing the number of EMS pages.\n");
+ }
+
+ /* Load the XMS driver (HIMEM) */
+ XmsInitialize();
+
+ /* Load the CON driver */
+ ConDrvInitialize();
+
return TRUE;
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -49,6 +49,9 @@
#define DOS_CHAR_ATTRIBUTE 0x07
#define DOS_PROGRAM_NAME_TAG 0x0001
#define DEFAULT_JFT_SIZE 20
+
+/* 16 MB of EMS memory */
+#define EMS_TOTAL_PAGES 1024
typedef enum
{
@@ -198,8 +201,6 @@
VOID DosPrintCharacter(WORD FileHandle, CHAR Character);
BOOLEAN DosBIOSInitialize(VOID);
-VOID EmsDrvInitialize(VOID);
-VOID EmsDrvCleanup(VOID);
VOID ConDrvInitialize(VOID);
VOID ConDrvCleanup(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -11,18 +11,347 @@
#define NDEBUG
#include "ntvdm.h"
+#include "emulator.h"
#include "dos.h"
#include "dos/dem.h"
#include "device.h"
+#include "../../memory.h"
+#include "emsdrv.h"
+
#define EMS_DEVICE_NAME "EMMXXXX0"
/* PRIVATE VARIABLES **********************************************************/
static PDOS_DEVICE_NODE Node;
+static RTL_BITMAP AllocBitmap;
+static PULONG BitmapBuffer = NULL;
+static PEMS_PAGE PageTable = NULL;
+static EMS_HANDLE HandleTable[EMS_MAX_HANDLES];
+static PVOID Mapping[EMS_PHYSICAL_PAGES] = { NULL };
+static ULONG EmsTotalPages = 0;
+static PVOID EmsMemory = 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 = ARRAY_INDEX(PageEntry, PageTable);
+
+ /* 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 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)
+{
+ PEMS_PAGE PageEntry;
+ PEMS_HANDLE HandleEntry = &HandleTable[Handle];
+
+ 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;
+
+ PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
+ if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
+
+ Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
+ + ARRAY_INDEX(PageEntry, PageTable) * 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(EmsTotalPages);
+ 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;
+ }
+
+ /* Get EMM Version */
+ case 0x46:
+ {
+ setAH(EMS_STATUS_OK);
+ setAL(EMS_VERSION_NUM);
+ 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)((ULONG_PTR)EmsMemory
+ + 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)((ULONG_PTR)EmsMemory
+ + 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());
+ setAH(EMS_STATUS_UNKNOWN_FUNCTION);
+ break;
+ }
+ }
+}
+
+static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
+{
+ ULONG i;
+ ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
+ ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
+ ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
+ ULONG Offset, Length;
+
+ for (i = FirstPage; i <= LastPage; i++)
+ {
+ Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
+ Length = ((i == LastPage)
+ ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
+ : EMS_PAGE_SIZE) - Offset;
+
+ if (Mapping[i]) RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Mapping[i] + Offset),
Length);
+ Buffer = (PVOID)((ULONG_PTR)Buffer + Length);
+ }
+}
+
+static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
+{
+ ULONG i;
+ ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
+ ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
+ ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
+ ULONG Offset, Length;
+
+ for (i = FirstPage; i <= LastPage; i++)
+ {
+ Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
+ Length = ((i == LastPage)
+ ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
+ : EMS_PAGE_SIZE) - Offset;
+
+ if (Mapping[i]) RtlCopyMemory((PVOID)((ULONG_PTR)Mapping[i] + Offset), Buffer,
Length);
+ Buffer = (PVOID)((ULONG_PTR)Buffer + Length);
+ }
+
+ return TRUE;
+}
+
WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
{
@@ -34,17 +363,85 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-VOID EmsDrvInitialize(VOID)
-{
+BOOLEAN EmsDrvInitialize(ULONG TotalPages)
+{
+ ULONG i;
+
+ for (i = 0; i < EMS_MAX_HANDLES; i++)
+ {
+ HandleTable[i].Allocated = FALSE;
+ HandleTable[i].PageCount = 0;
+ InitializeListHead(&HandleTable[i].PageList);
+ }
+
+ EmsTotalPages = TotalPages;
+ BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ ((TotalPages + 31) / 32) * sizeof(ULONG));
+ if (BitmapBuffer == NULL) return FALSE;
+
+ RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, TotalPages);
+
+ PageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ TotalPages * sizeof(EMS_PAGE));
+ if (PageTable == NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
+ BitmapBuffer = NULL;
+
+ return FALSE;
+ }
+
+ EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages *
EMS_PAGE_SIZE);
+ if (EmsMemory == NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable);
+ PageTable = NULL;
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
+ BitmapBuffer = NULL;
+
+ return FALSE;
+ }
+
+ MemInstallFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0),
+ EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE,
+ EmsReadMemory,
+ EmsWriteMemory);
+
+ RegisterDosInt32(EMS_INTERRUPT_NUM, EmsIntHandler);
+
/* Create the device */
- Node = DosCreateDevice(DOS_DEVATTR_IOCTL
- | DOS_DEVATTR_CHARACTER,
+ Node = DosCreateDevice(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
EMS_DEVICE_NAME);
Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
+
+ return TRUE;
}
VOID EmsDrvCleanup(VOID)
{
/* Delete the device */
DosDeleteDevice(Node);
-}
+
+ MemRemoveFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0),
+ EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE);
+
+ if (EmsMemory)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
+ EmsMemory = NULL;
+ }
+
+ if (PageTable)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable);
+ PageTable = NULL;
+ }
+
+ if (BitmapBuffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer);
+ BitmapBuffer = NULL;
+ }
+}
Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h (added)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -0,0 +1,67 @@
+/*
+ * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: emsdrv.h
+ * PURPOSE: DOS EMS Driver
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _EMSDRV_H_
+#define _EMSDRV_H_
+
+/* DEFINITIONS ****************************************************************/
+
+#define EMS_VERSION_NUM 0x04
+#define EMS_INTERRUPT_NUM 0x67
+#define EMS_SEGMENT 0xD000
+#define EMS_MAX_HANDLES 16
+#define EMS_PAGE_BITS 14
+#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
+#define EMS_PHYSICAL_PAGES 4
+
+#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;
+
+#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)
+
+#endif
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN EmsDrvInitialize(ULONG TotalPages);
+VOID EmsDrvCleanup(VOID);
Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c (added)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -0,0 +1,89 @@
+/*
+ * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: himem.c
+ * PURPOSE: DOS XMS Driver
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "ntvdm.h"
+#include "emulator.h"
+#include "cpu/bop.h"
+
+#include "dos.h"
+#include "dos/dem.h"
+#include "device.h"
+
+#define XMS_DEVICE_NAME "XMSXXXX0"
+#define XMS_BOP 0x52
+
+/* PRIVATE VARIABLES **********************************************************/
+
+static const BYTE EntryProcedure[] = {
+ 0xEB, // jmp short +0x03
+ 0x03,
+ 0x90, // nop
+ 0x90, // nop
+ 0x90, // nop
+ LOBYTE(EMULATOR_BOP),
+ HIBYTE(EMULATOR_BOP),
+ XMS_BOP,
+ 0xCB // retf
+};
+
+static PDOS_DEVICE_NODE Node = NULL;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID WINAPI XmsBopProcedure(LPWORD Stack)
+{
+ switch (getAH())
+ {
+ /* Get XMS Version */
+ case 0x00:
+ {
+ setAX(0x0300); /* XMS version 3.0 */
+ setDX(0x0001); /* HMA present */
+
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH());
+ }
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN XmsGetDriverEntry(PDWORD Pointer)
+{
+ if (Node == NULL) return FALSE;
+ *Pointer = DEVICE_PRIVATE_AREA(Node->Driver);
+ return TRUE;
+}
+
+VOID XmsInitialize(VOID)
+{
+ Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
+ XMS_DEVICE_NAME,
+ sizeof(EntryProcedure));
+
+ RegisterBop(XMS_BOP, XmsBopProcedure);
+
+ /* Copy the entry routine to the device private area */
+ RtlMoveMemory(FAR_POINTER(DEVICE_PRIVATE_AREA(Node->Driver)),
+ EntryProcedure,
+ sizeof(EntryProcedure));
+}
+
+VOID XmsCleanup(VOID)
+{
+ RegisterBop(XMS_BOP, NULL);
+ DosDeleteDevice(Node);
+}
Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h (added)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h [iso-8859-1] Tue Apr 21
22:48:28 2015
@@ -0,0 +1,13 @@
+/*
+ * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: himem.h
+ * PURPOSE: DOS XMS Driver
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN XmsGetDriverEntry(PDWORD Pointer);
+VOID XmsInitialize(VOID);
+VOID XmsCleanup(VOID);
Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h
------------------------------------------------------------------------------
svn:eol-style = native