ReactOS 0.4.16-dev-289-g096a551
himem.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "cpu/bop.h"
#include "../../memory.h"
#include "bios/umamgr.h"
#include "device.h"
#include "himem.h"
Include dependency graph for himem.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define XMS_DEVICE_NAME   "XMSXXXX0"
 
#define BOP_XMS   0x52
 

Functions

static VOID XmsLocalEnableA20 (VOID)
 
static VOID XmsLocalDisableA20 (VOID)
 
static PXMS_HANDLE GetXmsHandleRecord (WORD Handle)
 
static BOOLEAN ValidateXmsHandle (PXMS_HANDLE HandleEntry)
 
static WORD XmsGetLargestFreeBlock (VOID)
 
static UCHAR XmsAlloc (WORD Size, PWORD Handle)
 
static UCHAR XmsRealloc (WORD Handle, WORD NewSize)
 
static UCHAR XmsFree (WORD Handle)
 
static UCHAR XmsLock (WORD Handle, PDWORD Address)
 
static UCHAR XmsUnlock (WORD Handle)
 
static VOID WINAPI XmsBopProcedure (LPWORD Stack)
 
BOOLEAN XmsGetDriverEntry (PDWORD Pointer)
 
VOID XmsInitialize (VOID)
 
VOID XmsCleanup (VOID)
 

Variables

static const BYTE EntryProcedure []
 
static PDOS_DEVICE_NODE Node = NULL
 
static XMS_HANDLE HandleTable [XMS_MAX_HANDLES]
 
static WORD FreeBlocks = XMS_BLOCKS
 
static RTL_BITMAP AllocBitmap
 
static ULONG BitmapBuffer [(XMS_BLOCKS+31)/32]
 
static WORD HmaMinSize = 0
 
static BOOLEAN IsHmaReserved = FALSE
 
static BOOLEAN IsA20Enabled = FALSE
 
static BOOLEAN CanChangeA20 = TRUE
 
static LONG A20EnableCount = 0
 

Macro Definition Documentation

◆ BOP_XMS

#define BOP_XMS   0x52

Definition at line 65 of file himem.c.

◆ NDEBUG

#define NDEBUG

Definition at line 51 of file himem.c.

◆ XMS_DEVICE_NAME

#define XMS_DEVICE_NAME   "XMSXXXX0"

Definition at line 62 of file himem.c.

Function Documentation

◆ GetXmsHandleRecord()

static PXMS_HANDLE GetXmsHandleRecord ( WORD  Handle)
inlinestatic

Definition at line 172 of file himem.c.

173{
175 if (Handle == 0 || Handle >= XMS_MAX_HANDLES) return NULL;
176
177 Entry = &HandleTable[Handle - 1];
178 return Entry->Size ? Entry : NULL;
179}
#define NULL
Definition: types.h:112
ULONG Handle
Definition: gdb_input.c:15
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define XMS_MAX_HANDLES
Definition: himem.h:18
base of all file and directory entries
Definition: entries.h:83

Referenced by XmsBopProcedure(), XmsFree(), XmsLock(), XmsRealloc(), and XmsUnlock().

◆ ValidateXmsHandle()

static BOOLEAN ValidateXmsHandle ( PXMS_HANDLE  HandleEntry)
inlinestatic

Definition at line 181 of file himem.c.

182{
183 return (HandleEntry != NULL && HandleEntry->Handle != 0);
184}
BYTE Handle
Definition: himem.h:45

Referenced by XmsBopProcedure(), XmsFree(), XmsLock(), XmsRealloc(), and XmsUnlock().

◆ XmsAlloc()

static UCHAR XmsAlloc ( WORD  Size,
PWORD  Handle 
)
static

Definition at line 208 of file himem.c.

209{
210 BYTE i;
211 PXMS_HANDLE HandleEntry;
212 DWORD CurrentIndex = 0;
213 ULONG RunStart;
214 ULONG RunSize;
215
217
218 for (i = 0; i < XMS_MAX_HANDLES; i++)
219 {
220 HandleEntry = &HandleTable[i];
221 if (HandleEntry->Handle == 0)
222 {
223 *Handle = i + 1;
224 break;
225 }
226 }
227
229
230 /* Optimize blocks */
231 for (i = 0; i < XMS_MAX_HANDLES; i++)
232 {
233 /* Skip free and locked blocks */
234 if (HandleEntry->Handle == 0 || HandleEntry->LockCount > 0) continue;
235
236 CurrentIndex = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
237
238 /* Check if there is any free space before this block */
239 RunSize = RtlFindLastBackwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
240 if (RunSize == 0) break;
241
242 /* Move this block back */
243 RtlMoveMemory((PVOID)REAL_TO_PHYS(HandleEntry->Address - RunSize * XMS_BLOCK_SIZE),
244 (PVOID)REAL_TO_PHYS(HandleEntry->Address),
245 RunSize * XMS_BLOCK_SIZE);
246
247 /* Update the address */
248 HandleEntry->Address -= RunSize * XMS_BLOCK_SIZE;
249 }
250
251 while (CurrentIndex < XMS_BLOCKS)
252 {
253 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
254 if (RunSize == 0) break;
255
256 if (RunSize >= HandleEntry->Size)
257 {
258 /* Allocate it here */
259 HandleEntry->Handle = i + 1;
260 HandleEntry->LockCount = 0;
261 HandleEntry->Size = Size;
262 HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE;
263
264 FreeBlocks -= Size;
265 RtlSetBits(&AllocBitmap, RunStart, HandleEntry->Size);
266
267 return XMS_STATUS_SUCCESS;
268 }
269
270 /* Keep searching */
271 CurrentIndex = RunStart + RunSize;
272 }
273
275}
#define RtlFindNextForwardRunClear
Definition: dbgbitmap.h:338
#define RtlFindLastBackwardRunClear
Definition: dbgbitmap.h:336
#define RtlSetBits
Definition: dbgbitmap.h:345
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:37
unsigned long DWORD
Definition: ntddk_ex.h:95
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
static WORD FreeBlocks
Definition: himem.c:84
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
#define XMS_ADDRESS
Definition: himem.h:15
#define XMS_BLOCKS
Definition: himem.h:17
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_BLOCK_SIZE
Definition: himem.h:16
#define XMS_STATUS_OUT_OF_HANDLES
Definition: himem.h:29
WORD Size
Definition: himem.h:47
DWORD Address
Definition: himem.h:48
BYTE LockCount
Definition: himem.h:46
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
unsigned char BYTE
Definition: xxhash.c:193

Referenced by XmsBopProcedure().

◆ XmsBopProcedure()

static VOID WINAPI XmsBopProcedure ( LPWORD  Stack)
static

Definition at line 413 of file himem.c.

414{
415 switch (getAH())
416 {
417 /* Get XMS Version */
418 case 0x00:
419 {
420 setAX(0x0300); /* XMS version 3.00 */
421 setBX(0x0301); /* Driver version 3.01 */
422 setDX(0x0001); /* HMA present */
423 break;
424 }
425
426 /* Request HMA */
427 case 0x01:
428 {
429 /* Check whether HMA is already reserved */
430 if (IsHmaReserved)
431 {
432 /* It is, bail out */
433 setAX(0x0000);
435 break;
436 }
437
438 // NOTE: We implicitly suppose that we always have HMA.
439 // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST
440 // error code.
441
442 /* Check whether the requested size is above the minimal allowed one */
443 if (getDX() < HmaMinSize)
444 {
445 /* It is not, bail out */
446 setAX(0x0000);
448 break;
449 }
450
451 /* Reserve it */
453 setAX(0x0001);
455 break;
456 }
457
458 /* Release HMA */
459 case 0x02:
460 {
461 /* Check whether HMA was reserved */
462 if (!IsHmaReserved)
463 {
464 /* It was not, bail out */
465 setAX(0x0000);
467 break;
468 }
469
470 /* Release it */
472 setAX(0x0001);
474 break;
475 }
476
477 /* Global Enable A20 */
478 case 0x03:
479 {
480 /* Enable A20 if needed */
481 if (!IsA20Enabled)
482 {
484 if (getAX() != 0x0001)
485 {
486 /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */
487 break;
488 }
489
491 }
492
493 setAX(0x0001); /* Line successfully enabled */
495 break;
496 }
497
498 /* Global Disable A20 */
499 case 0x04:
500 {
502
503 /* Disable A20 if needed */
504 if (IsA20Enabled)
505 {
507 if (getAX() != 0x0001)
508 {
509 /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */
510 break;
511 }
512
514 Result = getBL();
515 }
516
517 setAX(0x0001); /* Line successfully disabled */
518 setBL(Result);
519 break;
520 }
521
522 /* Local Enable A20 */
523 case 0x05:
524 {
525 /* This call sets AX and BL to their correct values */
527 break;
528 }
529
530 /* Local Disable A20 */
531 case 0x06:
532 {
533 /* This call sets AX and BL to their correct values */
535 break;
536 }
537
538 /* Query A20 State */
539 case 0x07:
540 {
543 break;
544 }
545
546 /* Query Free Extended Memory */
547 case 0x08:
548 {
551
552 if (FreeBlocks > 0)
554 else
556
557 break;
558 }
559
560 /* Allocate Extended Memory Block */
561 case 0x09:
562 {
563 WORD Handle;
565
567 {
568 setAX(1);
569 setDX(Handle);
570 }
571 else
572 {
573 setAX(0);
574 setBL(Result);
575 }
576
577 break;
578 }
579
580 /* Free Extended Memory Block */
581 case 0x0A:
582 {
584
586 setBL(Result);
587 break;
588 }
589
590 /* Move Extended Memory Block */
591 case 0x0B:
592 {
593 PVOID SourceAddress, DestAddress;
595 PXMS_HANDLE HandleEntry;
596
597 if (CopyData->SourceHandle)
598 {
599 HandleEntry = GetXmsHandleRecord(CopyData->SourceHandle);
600 if (!ValidateXmsHandle(HandleEntry))
601 {
602 setAX(0);
604 break;
605 }
606
607 if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
608 {
609 setAX(0);
611 }
612
613 SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset);
614 }
615 else
616 {
617 /* The offset is actually a 16-bit segment:offset pointer */
619 }
620
621 if (CopyData->DestHandle)
622 {
623 HandleEntry = GetXmsHandleRecord(CopyData->DestHandle);
624 if (!ValidateXmsHandle(HandleEntry))
625 {
626 setAX(0);
628 break;
629 }
630
631 if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
632 {
633 setAX(0);
635 }
636
637 DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset);
638 }
639 else
640 {
641 /* The offset is actually a 16-bit segment:offset pointer */
642 DestAddress = FAR_POINTER(CopyData->DestOffset);
643 }
644
645 /* Perform the move */
646 RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count);
647
648 setAX(1);
650 break;
651 }
652
653 /* Lock Extended Memory Block */
654 case 0x0C:
655 {
658
660 {
661 setAX(1);
662
663 /* Store the LINEAR address in DX:BX */
666 }
667 else
668 {
669 setAX(0);
670 setBL(Result);
671 }
672
673 break;
674 }
675
676 /* Unlock Extended Memory Block */
677 case 0x0D:
678 {
680
682 setBL(Result);
683 break;
684 }
685
686 /* Get Handle Information */
687 case 0x0E:
688 {
689 PXMS_HANDLE HandleEntry = GetXmsHandleRecord(getDX());
690 UINT i;
691 UCHAR Handles = 0;
692
693 if (!ValidateXmsHandle(HandleEntry))
694 {
695 setAX(0);
697 break;
698 }
699
700 for (i = 0; i < XMS_MAX_HANDLES; i++)
701 {
702 if (HandleTable[i].Handle == 0) Handles++;
703 }
704
705 setAX(1);
706 setBH(HandleEntry->LockCount);
707 setBL(Handles);
708 setDX(HandleEntry->Size);
709 break;
710 }
711
712 /* Reallocate Extended Memory Block */
713 case 0x0F:
714 {
716
718 setBL(Result);
719 break;
720 }
721
722 /* Request UMB */
723 case 0x10:
724 {
726 USHORT Segment = 0x0000; /* No preferred segment */
727 USHORT Size = getDX(); /* Size is in paragraphs */
728
730 if (Result)
731 setBX(Segment);
732 else
734
735 setDX(Size);
736 setAX(Result);
737 break;
738 }
739
740 /* Release UMB */
741 case 0x11:
742 {
744 USHORT Segment = getDX();
745
747 if (!Result)
749
750 setAX(Result);
751 break;
752 }
753
754 /* Reallocate UMB */
755 case 0x12:
756 {
758 USHORT Segment = getDX();
759 USHORT Size = getBX(); /* Size is in paragraphs */
760
762 if (!Result)
763 {
764 if (Size > 0)
765 {
767 setDX(Size);
768 }
769 else
770 {
772 }
773 }
774
775 setAX(Result);
776 break;
777 }
778
779 default:
780 {
781 DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH());
783 }
784 }
785}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FAR_POINTER(x)
Definition: emulator.h:35
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
unsigned short WORD
Definition: ntddk_ex.h:93
static WORD XmsGetLargestFreeBlock(VOID)
Definition: himem.c:186
static UCHAR XmsLock(WORD Handle, PDWORD Address)
Definition: himem.c:380
static UCHAR XmsFree(WORD Handle)
Definition: himem.c:360
static UCHAR XmsRealloc(WORD Handle, WORD NewSize)
Definition: himem.c:277
static UCHAR XmsAlloc(WORD Size, PWORD Handle)
Definition: himem.c:208
static BOOLEAN IsHmaReserved
Definition: himem.c:103
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
static BOOLEAN IsA20Enabled
Definition: himem.c:109
static VOID XmsLocalEnableA20(VOID)
Definition: himem.c:125
static UCHAR XmsUnlock(WORD Handle)
Definition: himem.c:397
static WORD HmaMinSize
Definition: himem.c:98
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
static VOID XmsLocalDisableA20(VOID)
Definition: himem.c:141
#define XMS_STATUS_BAD_SRC_HANDLE
Definition: himem.h:31
#define XMS_STATUS_BAD_SRC_OFFSET
Definition: himem.h:33
struct _XMS_COPY_DATA * PXMS_COPY_DATA
#define XMS_STATUS_SMALLER_UMB
Definition: himem.h:39
#define XMS_STATUS_BAD_DEST_HANDLE
Definition: himem.h:32
#define XMS_STATUS_HMA_IN_USE
Definition: himem.h:24
#define XMS_STATUS_INVALID_UMB
Definition: himem.h:41
#define XMS_STATUS_HMA_MIN_SIZE
Definition: himem.h:25
#define XMS_STATUS_OUT_OF_UMBS
Definition: himem.h:40
#define XMS_STATUS_HMA_NOT_ALLOCATED
Definition: himem.h:26
#define XMS_STATUS_BAD_DEST_OFFSET
Definition: himem.h:34
#define XMS_STATUS_NOT_IMPLEMENTED
Definition: himem.h:21
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
unsigned int UINT
Definition: ndis.h:50
#define LOWORD(l)
Definition: pedump.c:82
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
DWORD SourceOffset
Definition: himem.h:56
DWORD DestOffset
Definition: himem.h:58
WORD SourceHandle
Definition: himem.h:55
WORD DestHandle
Definition: himem.h:57
DWORD Count
Definition: himem.h:54
BOOLEAN EmulatorGetA20(VOID)
Definition: memory.c:280
void * PVOID
Definition: typedefs.h:50
#define HIWORD(l)
Definition: typedefs.h:247
BOOLEAN UmaDescReallocate(IN USHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:260
BOOLEAN UmaDescRelease(IN USHORT Segment)
Definition: umamgr.c:207
BOOLEAN UmaDescReserve(IN OUT PUSHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:84
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1127
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by XmsInitialize().

◆ XmsCleanup()

VOID XmsCleanup ( VOID  )

Definition at line 814 of file himem.c.

815{
818}
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define BOP_XMS
Definition: himem.c:65
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
Definition: dlist.c:348

◆ XmsFree()

static UCHAR XmsFree ( WORD  Handle)
static

Definition at line 360 of file himem.c.

361{
362 DWORD BlockNumber;
364
365 if (!ValidateXmsHandle(HandleEntry))
367
368 if (HandleEntry->LockCount)
369 return XMS_STATUS_LOCKED;
370
371 BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
372 RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
373
374 HandleEntry->Handle = 0;
375 FreeBlocks += HandleEntry->Size;
376
377 return XMS_STATUS_SUCCESS;
378}
#define RtlClearBits
Definition: dbgbitmap.h:331
#define XMS_STATUS_LOCKED
Definition: himem.h:36

Referenced by XmsBopProcedure().

◆ XmsGetDriverEntry()

BOOLEAN XmsGetDriverEntry ( PDWORD  Pointer)

Definition at line 789 of file himem.c.

790{
791 if (Node == NULL) return FALSE;
792 *Pointer = DEVICE_PRIVATE_AREA(Node->Driver);
793 return TRUE;
794}
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16

Referenced by DosInt2Fh().

◆ XmsGetLargestFreeBlock()

static WORD XmsGetLargestFreeBlock ( VOID  )
static

Definition at line 186 of file himem.c.

187{
188 WORD Result = 0;
189 DWORD CurrentIndex = 0;
190 ULONG RunStart;
191 ULONG RunSize;
192
193 while (CurrentIndex < XMS_BLOCKS)
194 {
195 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
196 if (RunSize == 0) break;
197
198 /* Update the maximum */
199 if (RunSize > Result) Result = RunSize;
200
201 /* Go to the next run */
202 CurrentIndex = RunStart + RunSize;
203 }
204
205 return Result;
206}

Referenced by XmsBopProcedure().

◆ XmsInitialize()

VOID XmsInitialize ( VOID  )

Definition at line 796 of file himem.c.

797{
801
804 sizeof(EntryProcedure));
805
807
808 /* Copy the entry routine to the device private area */
811 sizeof(EntryProcedure));
812}
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
Definition: himem.c:413
#define XMS_DEVICE_NAME
Definition: himem.c:62
static const BYTE EntryProcedure[]
Definition: himem.c:69
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by DosKRNLInitialize().

◆ XmsLocalDisableA20()

static VOID XmsLocalDisableA20 ( VOID  )
static

Definition at line 141 of file himem.c.

142{
144
145 /* Disable A20 only if we can do so, otherwise make the caller believe we disabled it */
146 if (!CanChangeA20) goto Quit;
147
148 /* If the count is already zero, fail */
149 if (A20EnableCount == 0) goto Fail;
150
152
153 /* The count is zero so disable A20 */
154 if (A20EnableCount == 0)
155 EmulatorSetA20(FALSE); // Result = XMS_STATUS_SUCCESS;
156 else
158
159Quit:
160 setAX(0x0001); /* Line successfully disabled */
161 setBL(Result);
162 return;
163
164Fail:
165 setAX(0x0000); /* Line failed to be disabled */
167 return;
168}
int Fail
Definition: ehthrow.cxx:24
static LONG A20EnableCount
Definition: himem.c:121
static BOOLEAN CanChangeA20
Definition: himem.c:116
#define XMS_STATUS_A20_STILL_ENABLED
Definition: himem.h:27
#define XMS_STATUS_A20_ERROR
Definition: himem.h:22
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:275

Referenced by XmsBopProcedure().

◆ XmsLocalEnableA20()

static VOID XmsLocalEnableA20 ( VOID  )
static

Definition at line 125 of file himem.c.

126{
127 /* Enable A20 only if we can do so, otherwise make the caller believe we enabled it */
128 if (!CanChangeA20) goto Quit;
129
130 /* The count is zero so enable A20 */
132
134
135Quit:
136 setAX(0x0001); /* Line successfully enabled */
138 return;
139}

Referenced by XmsBopProcedure().

◆ XmsLock()

static UCHAR XmsLock ( WORD  Handle,
PDWORD  Address 
)
static

Definition at line 380 of file himem.c.

381{
383
384 if (!ValidateXmsHandle(HandleEntry))
386
387 if (HandleEntry->LockCount == 0xFF)
389
390 /* Increment the lock count */
391 HandleEntry->LockCount++;
392 *Address = HandleEntry->Address;
393
394 return XMS_STATUS_SUCCESS;
395}
#define XMS_STATUS_LOCK_OVERFLOW
Definition: himem.h:37

Referenced by XmsBopProcedure().

◆ XmsRealloc()

static UCHAR XmsRealloc ( WORD  Handle,
WORD  NewSize 
)
static

Definition at line 277 of file himem.c.

278{
279 DWORD BlockNumber;
281 DWORD CurrentIndex = 0;
282 ULONG RunStart;
283 ULONG RunSize;
284
285 if (!ValidateXmsHandle(HandleEntry))
287
288 if (HandleEntry->LockCount)
289 return XMS_STATUS_LOCKED;
290
291 /* Get the block number */
292 BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
293
294 if (NewSize < HandleEntry->Size)
295 {
296 /* Just reduce the size of this block */
297 RtlClearBits(&AllocBitmap, BlockNumber + NewSize, HandleEntry->Size - NewSize);
298 FreeBlocks += HandleEntry->Size - NewSize;
299 HandleEntry->Size = NewSize;
300 }
301 else if (NewSize > HandleEntry->Size)
302 {
303 /* Check if we can expand in-place */
305 BlockNumber + HandleEntry->Size,
306 NewSize - HandleEntry->Size))
307 {
308 /* Just increase the size of this block */
310 BlockNumber + HandleEntry->Size,
311 NewSize - HandleEntry->Size);
312 FreeBlocks -= NewSize - HandleEntry->Size;
313 HandleEntry->Size = NewSize;
314
315 /* We're done */
316 return XMS_STATUS_SUCCESS;
317 }
318
319 /* Deallocate the current block range */
320 RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
321
322 /* Find a new place for this block */
323 while (CurrentIndex < XMS_BLOCKS)
324 {
325 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
326 if (RunSize == 0) break;
327
328 if (RunSize >= NewSize)
329 {
330 /* Allocate the new range */
331 RtlSetBits(&AllocBitmap, RunStart, NewSize);
332
333 /* Move the data to the new location */
335 (PVOID)REAL_TO_PHYS(HandleEntry->Address),
336 HandleEntry->Size * XMS_BLOCK_SIZE);
337
338 /* Update the handle entry */
339 HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE;
340 HandleEntry->Size = NewSize;
341
342 /* Update the free block counter */
343 FreeBlocks -= NewSize - HandleEntry->Size;
344
345 return XMS_STATUS_SUCCESS;
346 }
347
348 /* Keep searching */
349 CurrentIndex = RunStart + RunSize;
350 }
351
352 /* Restore the old block range */
353 RtlSetBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
355 }
356
357 return XMS_STATUS_SUCCESS;
358}
#define RtlAreBitsClear
Definition: dbgbitmap.h:327
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975

Referenced by XmsBopProcedure().

◆ XmsUnlock()

static UCHAR XmsUnlock ( WORD  Handle)
static

Definition at line 397 of file himem.c.

398{
400
401 if (!ValidateXmsHandle(HandleEntry))
403
404 if (!HandleEntry->LockCount)
406
407 /* Decrement the lock count */
408 HandleEntry->LockCount--;
409
410 return XMS_STATUS_SUCCESS;
411}
#define XMS_STATUS_NOT_LOCKED
Definition: himem.h:35

Referenced by XmsBopProcedure().

Variable Documentation

◆ A20EnableCount

LONG A20EnableCount = 0
static

Definition at line 121 of file himem.c.

Referenced by XmsLocalDisableA20(), and XmsLocalEnableA20().

◆ AllocBitmap

RTL_BITMAP AllocBitmap
static

Definition at line 85 of file himem.c.

Referenced by XmsAlloc(), XmsFree(), XmsGetLargestFreeBlock(), XmsInitialize(), and XmsRealloc().

◆ BitmapBuffer

◆ CanChangeA20

BOOLEAN CanChangeA20 = TRUE
static

Definition at line 116 of file himem.c.

Referenced by XmsLocalDisableA20(), and XmsLocalEnableA20().

◆ EntryProcedure

const BYTE EntryProcedure[]
static
Initial value:
=
{
0xEB,
0x03,
0x90,
0x90,
0x90,
0xCB
}
#define EMULATOR_BOP
Definition: bop.h:16
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486

Definition at line 69 of file himem.c.

Referenced by XmsInitialize().

◆ FreeBlocks

WORD FreeBlocks = XMS_BLOCKS
static

Definition at line 84 of file himem.c.

Referenced by XmsAlloc(), XmsBopProcedure(), XmsFree(), and XmsRealloc().

◆ HandleTable

◆ HmaMinSize

WORD HmaMinSize = 0
static

Definition at line 98 of file himem.c.

Referenced by XmsBopProcedure().

◆ IsA20Enabled

BOOLEAN IsA20Enabled = FALSE
static

Definition at line 109 of file himem.c.

Referenced by XmsBopProcedure().

◆ IsHmaReserved

BOOLEAN IsHmaReserved = FALSE
static

Definition at line 103 of file himem.c.

Referenced by XmsBopProcedure().

◆ Node

Definition at line 82 of file himem.c.