/* 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];
static VOID WINAPI EmsIntHandler(LPWORD Stack)
{
+ static PVOID MappingBackup[EMS_PHYSICAL_PAGES] = { NULL };
+
switch (getAH())
{
/* Get Manager Status */
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:
{
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());
}
}
-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);
}
}
-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);
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;
}