From f4853ceb55425451bf224cf7c53b3b1b42715979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 5 Aug 2015 15:12:46 +0000 Subject: [PATCH] [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 --- .../mvdm/ntvdm/dos/dos32krnl/emsdrv.c | 105 ++++++++++++------ .../mvdm/ntvdm/dos/dos32krnl/emsdrv.h | 5 +- 2 files changed, 72 insertions(+), 38 deletions(-) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c index 3cfdf3b927f..a4861b3e812 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c @@ -4,6 +4,9 @@ * FILE: emsdrv.c * PURPOSE: DOS EMS Driver * PROGRAMMERS: Aleksandar Andrejevic + * + * DOCUMENTATION: Official specification: + * LIM EMS v4.0: http://www.phatcode.net/res/218/files/limems40.txt */ /* INCLUDES *******************************************************************/ @@ -48,6 +51,7 @@ static VOID InitHandlesTable(VOID) { HandleTable[i].Allocated = FALSE; HandleTable[i].PageCount = 0; + RtlZeroMemory(HandleTable[i].Name, sizeof(HandleTable[i].Name)); InitializeListHead(&HandleTable[i].PageList); } } @@ -77,6 +81,8 @@ static VOID FreeHandle(PEMS_HANDLE HandleEntry) { HandleEntry->Allocated = FALSE; HandleEntry->PageCount = 0; + RtlZeroMemory(HandleEntry->Name, sizeof(HandleEntry->Name)); + // InitializeListHead(HandleEntry->PageList); } static inline PEMS_HANDLE GetHandleRecord(USHORT Handle) @@ -110,10 +116,9 @@ static UCHAR EmsFree(USHORT Handle) } InitializeListHead(&HandleEntry->PageList); - FreeHandle(HandleEntry); - return EMS_STATUS_OK; + return EMS_STATUS_SUCCESS; } 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) @@ -186,7 +191,7 @@ static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage) { /* Unmap */ Mapping[PhysicalPage] = NULL; - return EMS_STATUS_OK; + return EMS_STATUS_SUCCESS; } PageEntry = GetLogicalPage(HandleEntry, LogicalPage); @@ -194,7 +199,7 @@ static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage) Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE); - return EMS_STATUS_OK; + return EMS_STATUS_SUCCESS; } static VOID WINAPI EmsIntHandler(LPWORD Stack) @@ -204,22 +209,22 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) /* Get Manager Status */ case 0x40: { - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); break; } /* Get Page Frame Segment */ case 0x41: { - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setBX(EmsSegment); break; } - /* Get Number of Pages */ + /* Get Number of Unallocated Pages */ case 0x42: { - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setBX(RtlNumberOfClearBits(&AllocBitmap)); setDX(EmsTotalPages); break; @@ -232,7 +237,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) UCHAR Status = EmsAlloc(getBX(), &Handle); setAH(Status); - if (Status == EMS_STATUS_OK) setDX(Handle); + if (Status == EMS_STATUS_SUCCESS) setDX(Handle); break; } @@ -253,7 +258,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) /* Get EMM Version */ case 0x46: { - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setAL(EMS_VERSION_NUM); break; } @@ -272,6 +277,39 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) 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 */ case 0x53: { @@ -279,7 +317,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) if (!ValidateHandle(HandleEntry)) { - setAL(EMS_STATUS_INVALID_HANDLE); + setAH(EMS_STATUS_INVALID_HANDLE); break; } @@ -289,7 +327,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()), HandleEntry->Name, sizeof(HandleEntry->Name)); - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); } else if (getAL() == 0x01) { @@ -297,7 +335,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) RtlCopyMemory(HandleEntry->Name, SEG_OFF_TO_PTR(getDS(), getSI()), sizeof(HandleEntry->Name)); - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); } else { @@ -321,18 +359,16 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) { /* Expanded memory */ HandleEntry = GetHandleRecord(Data->SourceHandle); - if (!ValidateHandle(HandleEntry)) { - setAL(EMS_STATUS_INVALID_HANDLE); + setAH(EMS_STATUS_INVALID_HANDLE); break; } PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment); - if (!PageEntry) { - setAL(EMS_STATUS_INV_LOGICAL_PAGE); + setAH(EMS_STATUS_INV_LOGICAL_PAGE); break; } @@ -350,18 +386,16 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) { /* Expanded memory */ HandleEntry = GetHandleRecord(Data->DestHandle); - if (!ValidateHandle(HandleEntry)) { - setAL(EMS_STATUS_INVALID_HANDLE); + setAH(EMS_STATUS_INVALID_HANDLE); break; } PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment); - if (!PageEntry) { - setAL(EMS_STATUS_INV_LOGICAL_PAGE); + setAH(EMS_STATUS_INV_LOGICAL_PAGE); break; } @@ -393,7 +427,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength); } - setAL(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); break; } @@ -408,17 +442,17 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) for (i = 0; i < EMS_PHYSICAL_PAGES; i++) { *(PWORD)SEG_OFF_TO_PTR(getES(), Offset++) = - EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4); + EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4); *(PWORD)SEG_OFF_TO_PTR(getES(), Offset++) = i; } - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setCX(EMS_PHYSICAL_PAGES); } else if (getAL() == 0x01) { - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setCX(EMS_PHYSICAL_PAGES); } else @@ -444,12 +478,12 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack) HardwareInfo->DmaRegisterSets = 0; HardwareInfo->DmaChannelOperation = 0; - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); } else if (getAL() == 0x01) { /* Same as function AH = 42h */ - setAH(EMS_STATUS_OK); + setAH(EMS_STATUS_SUCCESS); setBX(RtlNumberOfClearBits(&AllocBitmap)); setDX(EmsTotalPages); } @@ -517,7 +551,6 @@ static WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer, { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; - return DOS_DEVSTAT_DONE; } @@ -532,8 +565,6 @@ BOOLEAN EmsDrvInitialize(USHORT Segment, ULONG TotalPages) Size = EMS_SEGMENT_SIZE; // Size in paragraphs if (!UmaDescReserve(&EmsSegment, &Size)) return FALSE; - InitHandlesTable(); - EmsTotalPages = TotalPages; BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, @@ -575,16 +606,18 @@ BOOLEAN EmsDrvInitialize(USHORT Segment, ULONG TotalPages) EmsReadMemory, EmsWriteMemory); + // FIXME: The EMS driver MUST automatically initialize handle 0x0000 + // (operating system handle) as per the specification says! + InitHandlesTable(); + /* Create the device */ Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER, EMS_DEVICE_NAME, - 32); + Int16To32StubSize); Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead; - RegisterInt32(MAKELONG(sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE, HIWORD(Node->Driver)), - EMS_INTERRUPT_NUM, - EmsIntHandler, - NULL); + RegisterInt32(DEVICE_PRIVATE_AREA(Node->Driver), + EMS_INTERRUPT_NUM, EmsIntHandler, NULL); return TRUE; } diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h index dfb37125ede..3789fb406e3 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h @@ -14,7 +14,8 @@ #define EMS_VERSION_NUM 0x40 #define EMS_INTERRUPT_NUM 0x67 #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_SIZE (1 << EMS_PAGE_BITS) #define EMS_PHYSICAL_PAGES 4 @@ -22,7 +23,7 @@ /* 16 MB of EMS memory */ #define EMS_TOTAL_PAGES 1024 -#define EMS_STATUS_OK 0x00 +#define EMS_STATUS_SUCCESS 0x00 #define EMS_STATUS_INTERNAL_ERROR 0x80 #define EMS_STATUS_INVALID_HANDLE 0x83 #define EMS_STATUS_NO_MORE_HANDLES 0x85