[NTVDM]
[reactos.git] / reactos / subsystems / mvdm / ntvdm / dos / dos32krnl / emsdrv.c
index 0c1bcb4..77fb7b1 100644 (file)
@@ -35,7 +35,7 @@ static PVOID EmsMemory = NULL;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
-static PEMS_HANDLE GetHandleRecord(USHORT Handle)
+static inline PEMS_HANDLE GetHandleRecord(USHORT Handle)
 {
     if (Handle >= EMS_MAX_HANDLES) return NULL;
     return &HandleTable[Handle];
@@ -162,6 +162,8 @@ static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
 
 static VOID WINAPI EmsIntHandler(LPWORD Stack)
 {
+    static PVOID MappingBackup[EMS_PHYSICAL_PAGES] = { NULL };
+
     switch (getAH())
     {
         /* Get Manager Status */
@@ -221,6 +223,55 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
             break;
         }
 
+        /* Save Page Map */
+        case 0x47:
+        {
+            RtlCopyMemory(MappingBackup, Mapping, sizeof(PVOID) * EMS_PHYSICAL_PAGES);
+            break;
+        }
+
+        /* Restore Page Map */
+        case 0x48:
+        {
+            RtlCopyMemory(Mapping, MappingBackup, sizeof(PVOID) * EMS_PHYSICAL_PAGES);
+            break;
+        }
+
+        /* Get/Set Handle Name */
+        case 0x53:
+        {
+            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());
+            if (HandleEntry == NULL || !HandleEntry->Allocated)
+            {
+                setAL(EMS_STATUS_INVALID_HANDLE);
+                break;
+            }
+
+            if (getAL() == 0x00)
+            {
+                /* Retrieve the name */
+                RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
+                              HandleEntry->Name,
+                              sizeof(HandleEntry->Name));
+                setAH(EMS_STATUS_OK);
+            }
+            else if (getAL() == 0x01)
+            {
+                /* Store the name */
+                RtlCopyMemory(HandleEntry->Name,
+                              SEG_OFF_TO_PTR(getDS(), getSI()),
+                              sizeof(HandleEntry->Name));
+                setAH(EMS_STATUS_OK);
+            }
+            else
+            {
+                DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
+                setAH(EMS_STATUS_UNKNOWN_FUNCTION);
+            }
+
+            break;
+        }
+
         /* Move/Exchange Memory */
         case 0x57:
         {
@@ -310,6 +361,38 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
             break;
         }
 
+        /* Get Expanded Memory Hardware Information */
+        case 0x59:
+        {
+            if (getAL() == 0x00)
+            {
+                PEMS_HARDWARE_INFO HardwareInfo = (PEMS_HARDWARE_INFO)SEG_OFF_TO_PTR(getES(), getDI());
+
+                /* Return the hardware information */
+                HardwareInfo->RawPageSize         = EMS_PAGE_SIZE >> 4;
+                HardwareInfo->AlternateRegSets    = 0;
+                HardwareInfo->ContextAreaSize     = sizeof(Mapping);
+                HardwareInfo->DmaRegisterSets     = 0;
+                HardwareInfo->DmaChannelOperation = 0;
+
+                setAH(EMS_STATUS_OK);
+            }
+            else if (getAL() == 0x01)
+            {
+                /* Same as function AH = 42h */
+                setAH(EMS_STATUS_OK);
+                setBX(RtlNumberOfClearBits(&AllocBitmap));
+                setDX(EmsTotalPages);
+            }
+            else
+            {
+                DPRINT1("Invalid subfunction %02X for EMS function AH = 59h\n", getAL());
+                setAH(EMS_STATUS_UNKNOWN_FUNCTION);
+            }
+
+            break;
+        }
+
         default:
         {
             DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH());
@@ -319,7 +402,7 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
     }
 }
 
-static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
+static VOID FASTCALL EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
 {
     ULONG i;
     ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
@@ -339,7 +422,7 @@ static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
     }
 }
 
-static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
+static BOOLEAN FASTCALL EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
 {
     ULONG i;
     ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0);
@@ -418,13 +501,18 @@ BOOLEAN EmsDrvInitialize(ULONG TotalPages)
                              EmsReadMemory,
                              EmsWriteMemory);
 
-    RegisterDosInt32(EMS_INTERRUPT_NUM, EmsIntHandler);
 
     /* Create the device */
-    Node = DosCreateDevice(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
-                           EMS_DEVICE_NAME);
+    Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
+                             EMS_DEVICE_NAME,
+                             32);
     Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
 
+    RegisterInt32(MAKELONG(sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE, HIWORD(Node->Driver)),
+                  EMS_INTERRUPT_NUM,
+                  EmsIntHandler,
+                  NULL);
+
     return TRUE;
 }