mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 09:50:02 +00:00
[NTVDM]
- Increase the maximum number of EMS handles to the maximum permitted by the specification (ie. 255 handles) - Zero out EMS handles names. - EMS status are always returned in the AH register! - Implement functions 4Bh "Get Number of Opened Handles" and 4Ch "Get Handle Number of Pages" - Remove an hardcoded value. - Cosmetic change: rename EMS_STATUS_OK to EMS_STATUS_SUCCESS to comply with the name convention used also in XMS, etc... svn path=/trunk/; revision=68600
This commit is contained in:
parent
7f132c17b0
commit
f4853ceb55
2 changed files with 72 additions and 38 deletions
|
@ -4,6 +4,9 @@
|
||||||
* FILE: emsdrv.c
|
* FILE: emsdrv.c
|
||||||
* PURPOSE: DOS EMS Driver
|
* PURPOSE: DOS EMS Driver
|
||||||
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
||||||
|
*
|
||||||
|
* DOCUMENTATION: Official specification:
|
||||||
|
* LIM EMS v4.0: http://www.phatcode.net/res/218/files/limems40.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -48,6 +51,7 @@ static VOID InitHandlesTable(VOID)
|
||||||
{
|
{
|
||||||
HandleTable[i].Allocated = FALSE;
|
HandleTable[i].Allocated = FALSE;
|
||||||
HandleTable[i].PageCount = 0;
|
HandleTable[i].PageCount = 0;
|
||||||
|
RtlZeroMemory(HandleTable[i].Name, sizeof(HandleTable[i].Name));
|
||||||
InitializeListHead(&HandleTable[i].PageList);
|
InitializeListHead(&HandleTable[i].PageList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +81,8 @@ static VOID FreeHandle(PEMS_HANDLE HandleEntry)
|
||||||
{
|
{
|
||||||
HandleEntry->Allocated = FALSE;
|
HandleEntry->Allocated = FALSE;
|
||||||
HandleEntry->PageCount = 0;
|
HandleEntry->PageCount = 0;
|
||||||
|
RtlZeroMemory(HandleEntry->Name, sizeof(HandleEntry->Name));
|
||||||
|
// InitializeListHead(HandleEntry->PageList);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline PEMS_HANDLE GetHandleRecord(USHORT Handle)
|
static inline PEMS_HANDLE GetHandleRecord(USHORT Handle)
|
||||||
|
@ -110,10 +116,9 @@ static UCHAR EmsFree(USHORT Handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeListHead(&HandleEntry->PageList);
|
InitializeListHead(&HandleEntry->PageList);
|
||||||
|
|
||||||
FreeHandle(HandleEntry);
|
FreeHandle(HandleEntry);
|
||||||
|
|
||||||
return EMS_STATUS_OK;
|
return EMS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
|
static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
|
||||||
|
@ -154,7 +159,7 @@ static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EMS_STATUS_OK;
|
return EMS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PEMS_PAGE GetLogicalPage(PEMS_HANDLE HandleEntry, USHORT LogicalPage)
|
static PEMS_PAGE GetLogicalPage(PEMS_HANDLE HandleEntry, USHORT LogicalPage)
|
||||||
|
@ -186,7 +191,7 @@ static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
|
||||||
{
|
{
|
||||||
/* Unmap */
|
/* Unmap */
|
||||||
Mapping[PhysicalPage] = NULL;
|
Mapping[PhysicalPage] = NULL;
|
||||||
return EMS_STATUS_OK;
|
return EMS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
|
PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
|
||||||
|
@ -194,7 +199,7 @@ static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
|
||||||
|
|
||||||
Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
|
Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
|
||||||
+ ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE);
|
+ ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE);
|
||||||
return EMS_STATUS_OK;
|
return EMS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
|
@ -204,22 +209,22 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
/* Get Manager Status */
|
/* Get Manager Status */
|
||||||
case 0x40:
|
case 0x40:
|
||||||
{
|
{
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Page Frame Segment */
|
/* Get Page Frame Segment */
|
||||||
case 0x41:
|
case 0x41:
|
||||||
{
|
{
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setBX(EmsSegment);
|
setBX(EmsSegment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Number of Pages */
|
/* Get Number of Unallocated Pages */
|
||||||
case 0x42:
|
case 0x42:
|
||||||
{
|
{
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setBX(RtlNumberOfClearBits(&AllocBitmap));
|
setBX(RtlNumberOfClearBits(&AllocBitmap));
|
||||||
setDX(EmsTotalPages);
|
setDX(EmsTotalPages);
|
||||||
break;
|
break;
|
||||||
|
@ -232,7 +237,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
UCHAR Status = EmsAlloc(getBX(), &Handle);
|
UCHAR Status = EmsAlloc(getBX(), &Handle);
|
||||||
|
|
||||||
setAH(Status);
|
setAH(Status);
|
||||||
if (Status == EMS_STATUS_OK) setDX(Handle);
|
if (Status == EMS_STATUS_SUCCESS) setDX(Handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +258,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
/* Get EMM Version */
|
/* Get EMM Version */
|
||||||
case 0x46:
|
case 0x46:
|
||||||
{
|
{
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setAL(EMS_VERSION_NUM);
|
setAL(EMS_VERSION_NUM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -272,6 +277,39 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get Number of Opened Handles */
|
||||||
|
case 0x4B:
|
||||||
|
{
|
||||||
|
USHORT NumOpenHandles = 0;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < EMS_MAX_HANDLES; i++)
|
||||||
|
{
|
||||||
|
if (HandleTable[i].Allocated)
|
||||||
|
++NumOpenHandles;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
|
setBX(NumOpenHandles);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Handle Number of Pages */
|
||||||
|
case 0x4C:
|
||||||
|
{
|
||||||
|
PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());
|
||||||
|
|
||||||
|
if (!ValidateHandle(HandleEntry))
|
||||||
|
{
|
||||||
|
setAH(EMS_STATUS_INVALID_HANDLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
|
setBX(HandleEntry->PageCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get/Set Handle Name */
|
/* Get/Set Handle Name */
|
||||||
case 0x53:
|
case 0x53:
|
||||||
{
|
{
|
||||||
|
@ -279,7 +317,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
|
|
||||||
if (!ValidateHandle(HandleEntry))
|
if (!ValidateHandle(HandleEntry))
|
||||||
{
|
{
|
||||||
setAL(EMS_STATUS_INVALID_HANDLE);
|
setAH(EMS_STATUS_INVALID_HANDLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +327,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
|
RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
|
||||||
HandleEntry->Name,
|
HandleEntry->Name,
|
||||||
sizeof(HandleEntry->Name));
|
sizeof(HandleEntry->Name));
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x01)
|
else if (getAL() == 0x01)
|
||||||
{
|
{
|
||||||
|
@ -297,7 +335,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
RtlCopyMemory(HandleEntry->Name,
|
RtlCopyMemory(HandleEntry->Name,
|
||||||
SEG_OFF_TO_PTR(getDS(), getSI()),
|
SEG_OFF_TO_PTR(getDS(), getSI()),
|
||||||
sizeof(HandleEntry->Name));
|
sizeof(HandleEntry->Name));
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -321,18 +359,16 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
{
|
{
|
||||||
/* Expanded memory */
|
/* Expanded memory */
|
||||||
HandleEntry = GetHandleRecord(Data->SourceHandle);
|
HandleEntry = GetHandleRecord(Data->SourceHandle);
|
||||||
|
|
||||||
if (!ValidateHandle(HandleEntry))
|
if (!ValidateHandle(HandleEntry))
|
||||||
{
|
{
|
||||||
setAL(EMS_STATUS_INVALID_HANDLE);
|
setAH(EMS_STATUS_INVALID_HANDLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
|
PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
|
||||||
|
|
||||||
if (!PageEntry)
|
if (!PageEntry)
|
||||||
{
|
{
|
||||||
setAL(EMS_STATUS_INV_LOGICAL_PAGE);
|
setAH(EMS_STATUS_INV_LOGICAL_PAGE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,18 +386,16 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
{
|
{
|
||||||
/* Expanded memory */
|
/* Expanded memory */
|
||||||
HandleEntry = GetHandleRecord(Data->DestHandle);
|
HandleEntry = GetHandleRecord(Data->DestHandle);
|
||||||
|
|
||||||
if (!ValidateHandle(HandleEntry))
|
if (!ValidateHandle(HandleEntry))
|
||||||
{
|
{
|
||||||
setAL(EMS_STATUS_INVALID_HANDLE);
|
setAH(EMS_STATUS_INVALID_HANDLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
|
PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
|
||||||
|
|
||||||
if (!PageEntry)
|
if (!PageEntry)
|
||||||
{
|
{
|
||||||
setAL(EMS_STATUS_INV_LOGICAL_PAGE);
|
setAH(EMS_STATUS_INV_LOGICAL_PAGE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +427,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
|
RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAL(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,12 +447,12 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
*(PWORD)SEG_OFF_TO_PTR(getES(), Offset++) = i;
|
*(PWORD)SEG_OFF_TO_PTR(getES(), Offset++) = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setCX(EMS_PHYSICAL_PAGES);
|
setCX(EMS_PHYSICAL_PAGES);
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x01)
|
else if (getAL() == 0x01)
|
||||||
{
|
{
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setCX(EMS_PHYSICAL_PAGES);
|
setCX(EMS_PHYSICAL_PAGES);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -444,12 +478,12 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
||||||
HardwareInfo->DmaRegisterSets = 0;
|
HardwareInfo->DmaRegisterSets = 0;
|
||||||
HardwareInfo->DmaChannelOperation = 0;
|
HardwareInfo->DmaChannelOperation = 0;
|
||||||
|
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x01)
|
else if (getAL() == 0x01)
|
||||||
{
|
{
|
||||||
/* Same as function AH = 42h */
|
/* Same as function AH = 42h */
|
||||||
setAH(EMS_STATUS_OK);
|
setAH(EMS_STATUS_SUCCESS);
|
||||||
setBX(RtlNumberOfClearBits(&AllocBitmap));
|
setBX(RtlNumberOfClearBits(&AllocBitmap));
|
||||||
setDX(EmsTotalPages);
|
setDX(EmsTotalPages);
|
||||||
}
|
}
|
||||||
|
@ -517,7 +551,6 @@ static WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer,
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
// TODO: NOT IMPLEMENTED
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
return DOS_DEVSTAT_DONE;
|
return DOS_DEVSTAT_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,8 +565,6 @@ BOOLEAN EmsDrvInitialize(USHORT Segment, ULONG TotalPages)
|
||||||
Size = EMS_SEGMENT_SIZE; // Size in paragraphs
|
Size = EMS_SEGMENT_SIZE; // Size in paragraphs
|
||||||
if (!UmaDescReserve(&EmsSegment, &Size)) return FALSE;
|
if (!UmaDescReserve(&EmsSegment, &Size)) return FALSE;
|
||||||
|
|
||||||
InitHandlesTable();
|
|
||||||
|
|
||||||
EmsTotalPages = TotalPages;
|
EmsTotalPages = TotalPages;
|
||||||
BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
|
@ -575,16 +606,18 @@ BOOLEAN EmsDrvInitialize(USHORT Segment, ULONG TotalPages)
|
||||||
EmsReadMemory,
|
EmsReadMemory,
|
||||||
EmsWriteMemory);
|
EmsWriteMemory);
|
||||||
|
|
||||||
|
// FIXME: The EMS driver MUST automatically initialize handle 0x0000
|
||||||
|
// (operating system handle) as per the specification says!
|
||||||
|
InitHandlesTable();
|
||||||
|
|
||||||
/* Create the device */
|
/* Create the device */
|
||||||
Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
|
Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
|
||||||
EMS_DEVICE_NAME,
|
EMS_DEVICE_NAME,
|
||||||
32);
|
Int16To32StubSize);
|
||||||
Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
|
Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
|
||||||
|
|
||||||
RegisterInt32(MAKELONG(sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE, HIWORD(Node->Driver)),
|
RegisterInt32(DEVICE_PRIVATE_AREA(Node->Driver),
|
||||||
EMS_INTERRUPT_NUM,
|
EMS_INTERRUPT_NUM, EmsIntHandler, NULL);
|
||||||
EmsIntHandler,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
#define EMS_VERSION_NUM 0x40
|
#define EMS_VERSION_NUM 0x40
|
||||||
#define EMS_INTERRUPT_NUM 0x67
|
#define EMS_INTERRUPT_NUM 0x67
|
||||||
#define EMS_SEGMENT 0xD000 // Default segment
|
#define EMS_SEGMENT 0xD000 // Default segment
|
||||||
#define EMS_MAX_HANDLES 16
|
// Specification: Operating system handle 0x0000; user handles from 0x0001 to 0x00FE
|
||||||
|
#define EMS_MAX_HANDLES 255
|
||||||
#define EMS_PAGE_BITS 14
|
#define EMS_PAGE_BITS 14
|
||||||
#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
|
#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS)
|
||||||
#define EMS_PHYSICAL_PAGES 4
|
#define EMS_PHYSICAL_PAGES 4
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
/* 16 MB of EMS memory */
|
/* 16 MB of EMS memory */
|
||||||
#define EMS_TOTAL_PAGES 1024
|
#define EMS_TOTAL_PAGES 1024
|
||||||
|
|
||||||
#define EMS_STATUS_OK 0x00
|
#define EMS_STATUS_SUCCESS 0x00
|
||||||
#define EMS_STATUS_INTERNAL_ERROR 0x80
|
#define EMS_STATUS_INTERNAL_ERROR 0x80
|
||||||
#define EMS_STATUS_INVALID_HANDLE 0x83
|
#define EMS_STATUS_INVALID_HANDLE 0x83
|
||||||
#define EMS_STATUS_NO_MORE_HANDLES 0x85
|
#define EMS_STATUS_NO_MORE_HANDLES 0x85
|
||||||
|
|
Loading…
Reference in a new issue