ReactOS 0.4.15-dev-7897-g78dc504
emsdrv.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "../../memory.h"
#include "bios/umamgr.h"
#include "dos.h"
#include "dos/dem.h"
#include "device.h"
#include "emsdrv.h"
Include dependency graph for emsdrv.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define EMS_DEVICE_NAME   "EMMXXXX0"
 
#define EMS_SEGMENT_SIZE   ((EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE) >> 4)
 
#define EMS_SYSTEM_HANDLE   0
 

Functions

static VOID InitHandlesTable (VOID)
 
static PEMS_HANDLE CreateHandle (PUSHORT Handle)
 
static VOID FreeHandle (PEMS_HANDLE HandleEntry)
 
static PEMS_HANDLE GetEmsHandleRecord (USHORT Handle)
 
static BOOLEAN ValidateHandle (PEMS_HANDLE HandleEntry)
 
static UCHAR EmsFree (USHORT Handle)
 
static UCHAR EmsAlloc (USHORT NumPages, PUSHORT Handle)
 
static UCHAR InitSystemHandle (USHORT NumPages)
 
static PEMS_PAGE GetLogicalPage (PEMS_HANDLE HandleEntry, USHORT LogicalPage)
 
static UCHAR EmsMap (USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
 
static VOID WINAPI EmsIntHandler (LPWORD Stack)
 
static VOID FASTCALL EmsReadMemory (ULONG Address, PVOID Buffer, ULONG Size)
 
static BOOLEAN FASTCALL EmsWriteMemory (ULONG Address, PVOID Buffer, ULONG Size)
 
static WORD NTAPI EmsDrvDispatchIoctlRead (PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
 
BOOLEAN EmsDrvInitialize (USHORT Segment, ULONG TotalPages)
 
VOID EmsDrvCleanup (VOID)
 

Variables

static PDOS_DEVICE_NODE Node
 
static RTL_BITMAP AllocBitmap
 
static PULONG EmsBitmapBuffer = NULL
 
static PEMS_PAGE EmsPageTable = NULL
 
static EMS_HANDLE EmsHandleTable [EMS_MAX_HANDLES]
 
static PVOID Mapping [EMS_PHYSICAL_PAGES] = { NULL }
 
static PVOID MappingBackup [EMS_PHYSICAL_PAGES] = { NULL }
 
static ULONG EmsTotalPages = 0
 
static PVOID EmsMemory = NULL
 
static USHORT EmsSegment = EMS_SEGMENT
 

Macro Definition Documentation

◆ EMS_DEVICE_NAME

#define EMS_DEVICE_NAME   "EMMXXXX0"

Definition at line 29 of file emsdrv.c.

◆ EMS_SEGMENT_SIZE

#define EMS_SEGMENT_SIZE   ((EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE) >> 4)

Definition at line 31 of file emsdrv.c.

◆ EMS_SYSTEM_HANDLE

#define EMS_SYSTEM_HANDLE   0

Definition at line 32 of file emsdrv.c.

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file emsdrv.c.

Function Documentation

◆ CreateHandle()

static PEMS_HANDLE CreateHandle ( PUSHORT  Handle)
static

Definition at line 62 of file emsdrv.c.

63{
64 PEMS_HANDLE HandleEntry;
65 USHORT i;
66
67 /* Handle 0 is reserved (system handle) */
68 for (i = 1; i < ARRAYSIZE(EmsHandleTable); i++)
69 {
70 HandleEntry = &EmsHandleTable[i];
71 if (!HandleEntry->Allocated)
72 {
73 *Handle = i;
74 HandleEntry->Allocated = TRUE;
75 return HandleEntry;
76 }
77 }
78
79 return NULL;
80}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static EMS_HANDLE EmsHandleTable[EMS_MAX_HANDLES]
Definition: emsdrv.c:40
ULONG Handle
Definition: gdb_input.c:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN Allocated
Definition: emsdrv.h:42

Referenced by EmsAlloc().

◆ EmsAlloc()

static UCHAR EmsAlloc ( USHORT  NumPages,
PUSHORT  Handle 
)
static

Definition at line 128 of file emsdrv.c.

129{
130 ULONG i, CurrentIndex = 0;
131 PEMS_HANDLE HandleEntry;
132
133 if (NumPages == 0) return EMS_STATUS_ZERO_PAGES;
134
135 HandleEntry = CreateHandle(Handle);
136 if (!HandleEntry) return EMS_STATUS_NO_MORE_HANDLES;
137
138 while (HandleEntry->PageCount < NumPages)
139 {
140 ULONG RunStart;
141 ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
142
143 if (RunSize == 0)
144 {
145 /* Free what's been allocated already and report failure */
146 EmsFree(*Handle);
148 }
149 else if ((HandleEntry->PageCount + RunSize) > NumPages)
150 {
151 /* We don't need the entire run */
152 RunSize = NumPages - HandleEntry->PageCount;
153 }
154
155 CurrentIndex = RunStart + RunSize;
156 HandleEntry->PageCount += RunSize;
157 RtlSetBits(&AllocBitmap, RunStart, RunSize);
158
159 for (i = 0; i < RunSize; i++)
160 {
161 EmsPageTable[RunStart + i].Handle = *Handle;
162 InsertTailList(&HandleEntry->PageList, &EmsPageTable[RunStart + i].Entry);
163 }
164 }
165
166 return EMS_STATUS_SUCCESS;
167}
static PEMS_HANDLE CreateHandle(PUSHORT Handle)
Definition: emsdrv.c:62
static PEMS_PAGE EmsPageTable
Definition: emsdrv.c:39
static RTL_BITMAP AllocBitmap
Definition: emsdrv.c:37
static UCHAR EmsFree(USHORT Handle)
Definition: emsdrv.c:101
#define EMS_STATUS_NO_MORE_HANDLES
Definition: emsdrv.h:30
#define EMS_STATUS_ZERO_PAGES
Definition: emsdrv.h:32
#define EMS_STATUS_SUCCESS
Definition: emsdrv.h:26
#define EMS_STATUS_INSUFFICIENT_PAGES
Definition: emsdrv.h:31
#define InsertTailList(ListHead, Entry)
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
USHORT PageCount
Definition: emsdrv.h:43
LIST_ENTRY PageList
Definition: emsdrv.h:44
USHORT Handle
Definition: emsdrv.h:51
LIST_ENTRY Entry
Definition: emsdrv.h:50
uint32_t ULONG
Definition: typedefs.h:59

Referenced by EmsIntHandler().

◆ EmsDrvCleanup()

VOID EmsDrvCleanup ( VOID  )

Definition at line 850 of file emsdrv.c.

851{
852 /* Delete the device */
854
857
858 if (EmsMemory)
859 {
860 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
861 EmsMemory = NULL;
862 }
863
864 if (EmsPageTable)
865 {
866 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
868 }
869
870 if (EmsBitmapBuffer)
871 {
872 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
874 }
875
877}
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define UlongToPtr(u)
Definition: config.h:106
static PULONG EmsBitmapBuffer
Definition: emsdrv.c:38
static USHORT EmsSegment
Definition: emsdrv.c:45
static PVOID EmsMemory
Definition: emsdrv.c:44
#define EMS_PAGE_SIZE
Definition: emsdrv.h:20
#define EMS_PHYSICAL_PAGES
Definition: emsdrv.h:21
#define TO_LINEAR(seg, off)
Definition: emulator.h:26
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
BOOL MemRemoveFastMemoryHook(PVOID Address, ULONG Size)
Definition: memory.c:353
BOOLEAN UmaDescRelease(IN USHORT Segment)
Definition: umamgr.c:207
Definition: dlist.c:348

◆ EmsDrvDispatchIoctlRead()

static WORD NTAPI EmsDrvDispatchIoctlRead ( PDOS_DEVICE_NODE  Device,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 758 of file emsdrv.c.

759{
760 // TODO: NOT IMPLEMENTED
762 return DOS_DEVSTAT_DONE;
763}
#define UNIMPLEMENTED
Definition: debug.h:115
#define DOS_DEVSTAT_DONE
Definition: device.h:49

Referenced by EmsDrvInitialize().

◆ EmsDrvInitialize()

BOOLEAN EmsDrvInitialize ( USHORT  Segment,
ULONG  TotalPages 
)

Definition at line 767 of file emsdrv.c.

768{
769 USHORT Size;
770
771 /* Try to allocate our page table in UMA at the given segment */
773 Size = EMS_SEGMENT_SIZE; // Size in paragraphs
774 if (!UmaDescReserve(&EmsSegment, &Size)) return FALSE;
775
776 EmsTotalPages = TotalPages;
777 EmsBitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
779 ((TotalPages + 31) / 32) * sizeof(ULONG));
780 if (EmsBitmapBuffer == NULL)
781 {
783 return FALSE;
784 }
785
787
788 EmsPageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(),
790 TotalPages * sizeof(EMS_PAGE));
791 if (EmsPageTable == NULL)
792 {
793 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
795
797 return FALSE;
798 }
799
800 EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages * EMS_PAGE_SIZE);
801 if (EmsMemory == NULL)
802 {
803 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
805 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
807
809 return FALSE;
810 }
811
813 /*
814 * FIXME: We should ensure that the system handle is associated
815 * with mapped pages from conventional memory. DosEmu seems to do
816 * it correctly. 384kB of memory mapped.
817 */
819 {
820 DPRINT1("Impossible to allocate pages for the system handle!\n");
821
822 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
823 EmsMemory = NULL;
824 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
826 RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
828
830 return FALSE;
831 }
832
837
838 /* Create the device */
842 Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
843
846
847 return TRUE;
848}
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define FALSE
Definition: types.h:117
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
Definition: emsdrv.c:758
static VOID WINAPI EmsIntHandler(LPWORD Stack)
Definition: emsdrv.c:260
static ULONG EmsTotalPages
Definition: emsdrv.c:43
static BOOLEAN FASTCALL EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: emsdrv.c:736
static VOID InitHandlesTable(VOID)
Definition: emsdrv.c:49
#define EMS_SEGMENT_SIZE
Definition: emsdrv.c:31
static UCHAR InitSystemHandle(USHORT NumPages)
Definition: emsdrv.c:169
static VOID FASTCALL EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: emsdrv.c:716
#define EMS_DEVICE_NAME
Definition: emsdrv.c:29
struct _EMS_PAGE * PEMS_PAGE
#define EMS_INTERRUPT_NUM
Definition: emsdrv.h:15
struct _EMS_PAGE EMS_PAGE
#define EMS_SEGMENT
Definition: emsdrv.h:16
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
ULONG RegisterInt32(IN ULONG FarPtr, IN BYTE IntNumber, IN EMULATOR_INT32_PROC IntHandler, OUT PSIZE_T CodeSize OPTIONAL)
Definition: int32.c:118
#define Int16To32StubSize
Definition: int32.h:38
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
BOOL MemInstallFastMemoryHook(PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
Definition: memory.c:299
void * PVOID
Definition: typedefs.h:50
BOOLEAN UmaDescReserve(IN OUT PUSHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:84
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

Referenced by DosKRNLInitialize().

◆ EmsFree()

static UCHAR EmsFree ( USHORT  Handle)
static

Definition at line 101 of file emsdrv.c.

102{
105
106 if (!ValidateHandle(HandleEntry))
108
109 for (Entry = HandleEntry->PageList.Flink;
110 Entry != &HandleEntry->PageList;
111 Entry = Entry->Flink)
112 {
114 ULONG PageNumber = ARRAY_INDEX(PageEntry, EmsPageTable);
115
116 /* Free the page */
117 RtlClearBits(&AllocBitmap, PageNumber, 1);
118 }
119
120 InitializeListHead(&HandleEntry->PageList);
121
123 FreeHandle(HandleEntry);
124
125 return EMS_STATUS_SUCCESS;
126}
static VOID FreeHandle(PEMS_HANDLE HandleEntry)
Definition: emsdrv.c:82
static BOOLEAN ValidateHandle(PEMS_HANDLE HandleEntry)
Definition: emsdrv.c:96
static PEMS_HANDLE GetEmsHandleRecord(USHORT Handle)
Definition: emsdrv.c:90
#define EMS_SYSTEM_HANDLE
Definition: emsdrv.c:32
#define EMS_STATUS_INVALID_HANDLE
Definition: emsdrv.h:28
#define ARRAY_INDEX(ptr, array)
Definition: emulator.h:40
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by EmsAlloc(), EmsIntHandler(), and InitSystemHandle().

◆ EmsIntHandler()

static VOID WINAPI EmsIntHandler ( LPWORD  Stack)
static

Definition at line 260 of file emsdrv.c.

261{
262 switch (getAH())
263 {
264 /* Get Manager Status */
265 case 0x40:
266 {
268 break;
269 }
270
271 /* Get Page Frame Segment */
272 case 0x41:
273 {
276 break;
277 }
278
279 /* Get Number of Unallocated Pages */
280 case 0x42:
281 {
285 break;
286 }
287
288 /* Get Handle and Allocate Memory */
289 case 0x43:
290 {
293
295 setDX(Handle);
296
297 setAH(Status);
298 break;
299 }
300
301 /* Map Memory */
302 case 0x44:
303 {
304 setAH(EmsMap(getDX(), getAL(), getBX()));
305 break;
306 }
307
308 /* Release Handle and Memory */
309 case 0x45:
310 {
311 setAH(EmsFree(getDX()));
312 break;
313 }
314
315 /* Get EMM Version */
316 case 0x46:
317 {
320 break;
321 }
322
323 /* Save Page Map */
324 case 0x47:
325 {
326 // FIXME: This depends on an EMS handle given in DX
329 break;
330 }
331
332 /* Restore Page Map */
333 case 0x48:
334 {
335 // FIXME: This depends on an EMS handle given in DX
338 break;
339 }
340
341 /* Get Number of Opened Handles */
342 case 0x4B:
343 {
344 USHORT NumOpenHandles = 0;
345 USHORT i;
346
347 for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
348 {
350 ++NumOpenHandles;
351 }
352
354 setBX(NumOpenHandles);
355 break;
356 }
357
358 /* Get Handle Number of Pages */
359 case 0x4C:
360 {
361 PEMS_HANDLE HandleEntry = GetEmsHandleRecord(getDX());
362
363 if (!ValidateHandle(HandleEntry))
364 {
366 break;
367 }
368
370 setBX(HandleEntry->PageCount);
371 break;
372 }
373
374 /* Get All Handles Number of Pages */
375 case 0x4D:
376 {
378 USHORT NumOpenHandles = 0;
379 USHORT i;
380
381 for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
382 {
384 {
385 HandlePageInfo->Handle = i;
386 HandlePageInfo->PageCount = EmsHandleTable[i].PageCount;
387 ++HandlePageInfo;
388 ++NumOpenHandles;
389 }
390 }
391
393 setBX(NumOpenHandles);
394 break;
395 }
396
397 /* Get or Set Page Map */
398 case 0x4E:
399 {
400 switch (getAL())
401 {
402 /* Get Mapping Registers */
403 // case 0x00: // TODO: NOT IMPLEMENTED
404
405 /* Set Mapping Registers */
406 // case 0x01: // TODO: NOT IMPLEMENTED
407
408 /* Get and Set Mapping Registers At Once */
409 // case 0x02: // TODO: NOT IMPLEMENTED
410
411 /* Get Size of Page-Mapping Array */
412 case 0x03:
413 {
415 setAL(sizeof(Mapping));
416 break;
417 }
418
419 default:
420 {
421 DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL());
423 break;
424 }
425 }
426
427 break;
428 }
429
430 /* Get/Set Handle Name */
431 case 0x53:
432 {
433 PEMS_HANDLE HandleEntry = GetEmsHandleRecord(getDX());
434
435 if (!ValidateHandle(HandleEntry))
436 {
438 break;
439 }
440
441 if (getAL() == 0x00)
442 {
443 /* Retrieve the name */
445 HandleEntry->Name,
446 sizeof(HandleEntry->Name));
448 }
449 else if (getAL() == 0x01)
450 {
451 /* Store the name */
452 RtlCopyMemory(HandleEntry->Name,
454 sizeof(HandleEntry->Name));
456 }
457 else
458 {
459 DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
461 }
462
463 break;
464 }
465
466 /* Handle Directory functions */
467 case 0x54:
468 {
469 if (getAL() == 0x00)
470 {
471 /* Get Handle Directory */
472
474 USHORT NumOpenHandles = 0;
475 USHORT i;
476
477 for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
478 {
480 {
481 HandleDir->Handle = i;
482 RtlCopyMemory(HandleDir->Name,
484 sizeof(HandleDir->Name));
485 ++HandleDir;
486 ++NumOpenHandles;
487 }
488 }
489
491 setAL((UCHAR)NumOpenHandles);
492 }
493 else if (getAL() == 0x01)
494 {
495 /* Search for Named Handle */
496
497 PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
498 PEMS_HANDLE HandleFound = NULL;
499 USHORT i;
500
501 for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
502 {
504 RtlCompareMemory(HandleName,
506 sizeof(EmsHandleTable[i].Name)) == sizeof(EmsHandleTable[i].Name))
507 {
508 HandleFound = &EmsHandleTable[i];
509 break;
510 }
511 }
512
513 /* Bail out if no handle was found */
514 if (i >= ARRAYSIZE(EmsHandleTable)) // HandleFound == NULL
515 {
517 break;
518 }
519
520 /* Return the handle number */
521 setDX(i);
522
523 /* Sanity check: Check whether the handle was unnamed */
524 i = 0;
525 while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0'))
526 ++i;
527
528 if (i >= sizeof(HandleFound->Name))
529 {
531 }
532 else
533 {
535 }
536 }
537 else if (getAL() == 0x02)
538 {
539 /*
540 * Get Total Number of Handles
541 *
542 * This function retrieves the maximum number of handles
543 * (allocated or not) the memory manager supports, which
544 * a program may request.
545 */
548 }
549 else
550 {
551 DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL());
553 }
554
555 break;
556 }
557
558 /* Move/Exchange Memory */
559 case 0x57:
560 {
561 PUCHAR SourcePtr, DestPtr;
562 PEMS_HANDLE HandleEntry;
563 PEMS_PAGE PageEntry;
564 BOOLEAN Exchange = getAL();
566
567 if (Data->SourceType)
568 {
569 /* Expanded memory */
570 HandleEntry = GetEmsHandleRecord(Data->SourceHandle);
571 if (!ValidateHandle(HandleEntry))
572 {
574 break;
575 }
576
577 PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
578 if (!PageEntry)
579 {
581 break;
582 }
583
584 SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory
586 + Data->SourceOffset);
587 }
588 else
589 {
590 /* Conventional memory */
591 SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
592 }
593
594 if (Data->DestType)
595 {
596 /* Expanded memory */
597 HandleEntry = GetEmsHandleRecord(Data->DestHandle);
598 if (!ValidateHandle(HandleEntry))
599 {
601 break;
602 }
603
604 PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
605 if (!PageEntry)
606 {
608 break;
609 }
610
611 DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory
613 + Data->DestOffset);
614 }
615 else
616 {
617 /* Conventional memory */
618 DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
619 }
620
621 if (Exchange)
622 {
623 ULONG i;
624
625 /* Exchange */
626 for (i = 0; i < Data->RegionLength; i++)
627 {
628 UCHAR Temp = DestPtr[i];
629 DestPtr[i] = SourcePtr[i];
630 SourcePtr[i] = Temp;
631 }
632 }
633 else
634 {
635 /* Move */
636 RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
637 }
638
640 break;
641 }
642
643 /* Get Mappable Physical Address Array */
644 case 0x58:
645 {
646 if (getAL() == 0x00)
647 {
649 ULONG i;
650
651 for (i = 0; i < EMS_PHYSICAL_PAGES; i++)
652 {
653 PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4);
654 PageArray->PageNumber = i;
655 ++PageArray;
656 }
657
660 }
661 else if (getAL() == 0x01)
662 {
665 }
666 else
667 {
668 DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL());
670 }
671
672 break;
673 }
674
675 /* Get Expanded Memory Hardware Information */
676 case 0x59:
677 {
678 if (getAL() == 0x00)
679 {
681
682 /* Return the hardware information */
683 HardwareInfo->RawPageSize = EMS_PAGE_SIZE >> 4;
684 HardwareInfo->AlternateRegSets = 0;
685 HardwareInfo->ContextAreaSize = sizeof(Mapping);
686 HardwareInfo->DmaRegisterSets = 0;
687 HardwareInfo->DmaChannelOperation = 0;
688
690 }
691 else if (getAL() == 0x01)
692 {
693 /* Same as function AH = 42h */
697 }
698 else
699 {
700 DPRINT1("Invalid subfunction %02X for EMS function AH = 59h\n", getAL());
702 }
703
704 break;
705 }
706
707 default:
708 {
709 DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH());
711 break;
712 }
713 }
714}
unsigned char BOOLEAN
static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
Definition: emsdrv.c:234
static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
Definition: emsdrv.c:128
static PVOID MappingBackup[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:42
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
static PEMS_PAGE GetLogicalPage(PEMS_HANDLE HandleEntry, USHORT LogicalPage)
Definition: emsdrv.c:220
struct _EMS_COPY_DATA * PEMS_COPY_DATA
#define EMS_STATUS_HANDLE_NOT_FOUND
Definition: emsdrv.h:36
#define EMS_STATUS_INV_LOGICAL_PAGE
Definition: emsdrv.h:33
struct _EMS_HANDLE_PAGE_INFO * PEMS_HANDLE_PAGE_INFO
#define EMS_STATUS_UNKNOWN_FUNCTION
Definition: emsdrv.h:29
struct _EMS_HANDLE_DIR_ENTRY * PEMS_HANDLE_DIR_ENTRY
#define EMS_STATUS_UNNAMED_HANDLE
Definition: emsdrv.h:37
struct _EMS_MAPPABLE_PHYS_PAGE * PEMS_MAPPABLE_PHYS_PAGE
struct _EMS_HARDWARE_INFO * PEMS_HARDWARE_INFO
#define EMS_STATUS_INVALID_SUBFUNCTION
Definition: emsdrv.h:35
#define EMS_VERSION_NUM
Definition: emsdrv.h:14
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:310
Status
Definition: gdiplustypes.h:25
NTSYSAPI ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP)
Definition: emsdrv.h:63
USHORT Handle
Definition: emsdrv.h:64
UCHAR Name[8]
Definition: emsdrv.h:65
UCHAR Name[8]
Definition: emsdrv.h:45
WORD RawPageSize
Definition: emsdrv.h:89
WORD DmaChannelOperation
Definition: emsdrv.h:93
WORD AlternateRegSets
Definition: emsdrv.h:90
WORD DmaRegisterSets
Definition: emsdrv.h:92
WORD ContextAreaSize
Definition: emsdrv.h:91
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
USHORT WINAPI getES(VOID)
Definition: registers.c:522
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by EmsDrvInitialize().

◆ EmsMap()

static UCHAR EmsMap ( USHORT  Handle,
UCHAR  PhysicalPage,
USHORT  LogicalPage 
)
static

Definition at line 234 of file emsdrv.c.

235{
236 PEMS_PAGE PageEntry;
238
239 if (!ValidateHandle(HandleEntry))
241
242 if (PhysicalPage >= EMS_PHYSICAL_PAGES)
244
245 if (LogicalPage == 0xFFFF)
246 {
247 /* Unmap */
248 Mapping[PhysicalPage] = NULL;
249 return EMS_STATUS_SUCCESS;
250 }
251
252 PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
253 if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
254
255 Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
256 + ARRAY_INDEX(PageEntry, EmsPageTable) * EMS_PAGE_SIZE);
257 return EMS_STATUS_SUCCESS;
258}
#define EMS_STATUS_INV_PHYSICAL_PAGE
Definition: emsdrv.h:34

Referenced by EmsIntHandler().

◆ EmsReadMemory()

static VOID FASTCALL EmsReadMemory ( ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)
static

Definition at line 716 of file emsdrv.c.

717{
718 ULONG i;
719 ULONG RelativeAddress = Address - TO_LINEAR(EmsSegment, 0);
720 ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
721 ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
723
724 for (i = FirstPage; i <= LastPage; i++)
725 {
726 Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
727 Length = ((i == LastPage)
728 ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
730
733 }
734}
Definition: bufpool.h:45
#define EMS_PAGE_BITS
Definition: emsdrv.h:19
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static WCHAR Address[46]
Definition: ping.c:68

Referenced by EmsDrvInitialize().

◆ EmsWriteMemory()

static BOOLEAN FASTCALL EmsWriteMemory ( ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)
static

Definition at line 736 of file emsdrv.c.

737{
738 ULONG i;
739 ULONG RelativeAddress = Address - TO_LINEAR(EmsSegment, 0);
740 ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
741 ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
743
744 for (i = FirstPage; i <= LastPage; i++)
745 {
746 Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
747 Length = ((i == LastPage)
748 ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
750
753 }
754
755 return TRUE;
756}

Referenced by EmsDrvInitialize().

◆ FreeHandle()

static VOID FreeHandle ( PEMS_HANDLE  HandleEntry)
static

Definition at line 82 of file emsdrv.c.

83{
84 HandleEntry->Allocated = FALSE;
85 HandleEntry->PageCount = 0;
86 RtlZeroMemory(HandleEntry->Name, sizeof(HandleEntry->Name));
87 // InitializeListHead(&HandleEntry->PageList);
88}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by EmsFree().

◆ GetEmsHandleRecord()

static PEMS_HANDLE GetEmsHandleRecord ( USHORT  Handle)
inlinestatic

Definition at line 90 of file emsdrv.c.

91{
92 if (Handle >= ARRAYSIZE(EmsHandleTable)) return NULL;
93 return &EmsHandleTable[Handle];
94}

Referenced by EmsFree(), EmsIntHandler(), and EmsMap().

◆ GetLogicalPage()

static PEMS_PAGE GetLogicalPage ( PEMS_HANDLE  HandleEntry,
USHORT  LogicalPage 
)
static

Definition at line 220 of file emsdrv.c.

221{
222 PLIST_ENTRY Entry = HandleEntry->PageList.Flink;
223
224 while (LogicalPage)
225 {
226 if (Entry == &HandleEntry->PageList) return NULL;
227 LogicalPage--;
228 Entry = Entry->Flink;
229 }
230
232}

Referenced by EmsIntHandler(), and EmsMap().

◆ InitHandlesTable()

static VOID InitHandlesTable ( VOID  )
static

Definition at line 49 of file emsdrv.c.

50{
51 USHORT i;
52
53 for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
54 {
59 }
60}

Referenced by EmsDrvInitialize().

◆ InitSystemHandle()

static UCHAR InitSystemHandle ( USHORT  NumPages)
static

Definition at line 169 of file emsdrv.c.

170{
171 //
172 // FIXME: This is an adapted copy of EmsAlloc!!
173 //
174
175 ULONG i, CurrentIndex = 0;
177
178 /* The system handle must never have been initialized before */
179 ASSERT(!HandleEntry->Allocated);
180
181 /* Now allocate it */
182 HandleEntry->Allocated = TRUE;
183
184 while (HandleEntry->PageCount < NumPages)
185 {
186 ULONG RunStart;
187 ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
188
189 if (RunSize == 0)
190 {
191 /* Free what's been allocated already and report failure */
193 // FIXME: For this function (and EmsAlloc as well),
194 // use instead an internal function that just uses
195 // PEMS_HANDLE pointers instead. It's only in the
196 // EMS interrupt handler that we should do the
197 // unfolding.
199 }
200 else if ((HandleEntry->PageCount + RunSize) > NumPages)
201 {
202 /* We don't need the entire run */
203 RunSize = NumPages - HandleEntry->PageCount;
204 }
205
206 CurrentIndex = RunStart + RunSize;
207 HandleEntry->PageCount += RunSize;
208 RtlSetBits(&AllocBitmap, RunStart, RunSize);
209
210 for (i = 0; i < RunSize; i++)
211 {
213 InsertTailList(&HandleEntry->PageList, &EmsPageTable[RunStart + i].Entry);
214 }
215 }
216
217 return EMS_STATUS_SUCCESS;
218}
#define ASSERT(a)
Definition: mode.c:44

Referenced by EmsDrvInitialize().

◆ ValidateHandle()

static BOOLEAN ValidateHandle ( PEMS_HANDLE  HandleEntry)
inlinestatic

Definition at line 96 of file emsdrv.c.

97{
98 return (HandleEntry != NULL && HandleEntry->Allocated);
99}

Referenced by EmsFree(), EmsIntHandler(), and EmsMap().

Variable Documentation

◆ AllocBitmap

RTL_BITMAP AllocBitmap
static

Definition at line 37 of file emsdrv.c.

Referenced by EmsAlloc(), EmsDrvInitialize(), EmsFree(), EmsIntHandler(), and InitSystemHandle().

◆ EmsBitmapBuffer

PULONG EmsBitmapBuffer = NULL
static

Definition at line 38 of file emsdrv.c.

Referenced by EmsDrvCleanup(), and EmsDrvInitialize().

◆ EmsHandleTable

EMS_HANDLE EmsHandleTable[EMS_MAX_HANDLES]
static

◆ EmsMemory

PVOID EmsMemory = NULL
static

Definition at line 44 of file emsdrv.c.

Referenced by EmsDrvCleanup(), EmsDrvInitialize(), EmsIntHandler(), and EmsMap().

◆ EmsPageTable

PEMS_PAGE EmsPageTable = NULL
static

◆ EmsSegment

USHORT EmsSegment = EMS_SEGMENT
static

◆ EmsTotalPages

ULONG EmsTotalPages = 0
static

Definition at line 43 of file emsdrv.c.

Referenced by EmsDrvInitialize(), and EmsIntHandler().

◆ Mapping

◆ MappingBackup

PVOID MappingBackup[EMS_PHYSICAL_PAGES] = { NULL }
static

Definition at line 42 of file emsdrv.c.

Referenced by EmsIntHandler().

◆ Node

Definition at line 36 of file emsdrv.c.