mirror of
https://github.com/reactos/reactos.git
synced 2024-08-05 02:50:55 +00:00
[NTVDM]
Implement Upper Memory Blocks (UMB) support. svn path=/branches/ntvdm/; revision=59501
This commit is contained in:
parent
09e7fede48
commit
495320af6e
|
@ -16,7 +16,7 @@
|
|||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define CONSOLE_VIDEO_MEM_END 0xBFFFF
|
||||
#define ROM_AREA_START 0xC0000
|
||||
#define ROM_AREA_START 0xE0000
|
||||
#define ROM_AREA_END 0xFFFFF
|
||||
#define BDA_SEGMENT 0x40
|
||||
#define BIOS_PIC_MASTER_INT 0x08
|
||||
|
|
|
@ -18,6 +18,7 @@ static WORD CurrentPsp = SYSTEM_PSP;
|
|||
static DWORD DiskTransferArea;
|
||||
static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
|
||||
static WORD DosSftRefCount[DOS_SFT_SIZE];
|
||||
static BOOLEAN DosUmbLinked = FALSE;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
|
@ -397,6 +398,60 @@ BOOLEAN DosFreeMemory(WORD BlockData)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN DosLinkUmb()
|
||||
{
|
||||
DWORD Segment = FIRST_MCB_SEGMENT;
|
||||
PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
|
||||
|
||||
/* Check if UMBs are already linked */
|
||||
if (DosUmbLinked) return FALSE;
|
||||
|
||||
/* Find the last block */
|
||||
while ((Mcb->BlockType == 'M') && (Segment <= 0xFFFF))
|
||||
{
|
||||
Segment += Mcb->Size + 1;
|
||||
Mcb = SEGMENT_TO_MCB(Segment);
|
||||
}
|
||||
|
||||
/* Make sure it's valid */
|
||||
if (Mcb->BlockType != 'Z') return FALSE;
|
||||
|
||||
/* Connect the MCB with the UMB chain */
|
||||
Mcb->BlockType = 'M';
|
||||
|
||||
DosUmbLinked = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN DosUnlinkUmb()
|
||||
{
|
||||
DWORD Segment = FIRST_MCB_SEGMENT;
|
||||
PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
|
||||
|
||||
/* Check if UMBs are already unlinked */
|
||||
if (!DosUmbLinked) return FALSE;
|
||||
|
||||
/* Find the block preceding the MCB that links it with the UMB chain */
|
||||
while (Segment <= 0xFFFF)
|
||||
{
|
||||
if ((Segment + Mcb->Size) == (FIRST_MCB_SEGMENT + USER_MEMORY_SIZE))
|
||||
{
|
||||
/* This is the last non-UMB segment */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Advance to the next MCB */
|
||||
Segment += Mcb->Size + 1;
|
||||
Mcb = SEGMENT_TO_MCB(Segment);
|
||||
}
|
||||
|
||||
/* Mark the MCB as the last MCB */
|
||||
Mcb->BlockType = 'Z';
|
||||
|
||||
DosUmbLinked = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
|
@ -1412,7 +1467,11 @@ VOID DosInt21h(WORD CodeSegment)
|
|||
{
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
}
|
||||
else EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
else
|
||||
{
|
||||
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_ARENA_TRASHED);
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1442,6 +1501,35 @@ VOID DosInt21h(WORD CodeSegment)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Get/Set Memory Management Options */
|
||||
case 0x58:
|
||||
{
|
||||
if (LOBYTE(Eax) == 0x02)
|
||||
{
|
||||
/* Get UMB link state */
|
||||
|
||||
Eax &= 0xFFFFFF00;
|
||||
if (DosUmbLinked) Eax |= 1;
|
||||
EmulatorSetRegister(EMULATOR_REG_AX, Eax);
|
||||
}
|
||||
else if (LOBYTE(Eax) == 0x03)
|
||||
{
|
||||
/* Set UMB link state */
|
||||
|
||||
if (Ebx) DosLinkUmb();
|
||||
else DosUnlinkUmb();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid or unsupported function */
|
||||
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unsupported */
|
||||
default:
|
||||
{
|
||||
|
@ -1472,6 +1560,18 @@ BOOLEAN DosInitialize()
|
|||
Mcb->Size = USER_MEMORY_SIZE;
|
||||
Mcb->OwnerPsp = 0;
|
||||
|
||||
/* Initialize the link MCB to the UMB area */
|
||||
Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
|
||||
Mcb->BlockType = 'M';
|
||||
Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
|
||||
Mcb->OwnerPsp = SYSTEM_PSP;
|
||||
|
||||
/* Initialize the UMB area */
|
||||
Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
|
||||
Mcb->BlockType = 'Z';
|
||||
Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
|
||||
Mcb->OwnerPsp = 0;
|
||||
|
||||
/* Get the environment strings */
|
||||
SourcePtr = Environment = GetEnvironmentStringsW();
|
||||
if (Environment == NULL) return FALSE;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#define DOS_SFT_SIZE 255
|
||||
#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
|
||||
#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
|
||||
#define UMB_START_SEGMENT 0xC000
|
||||
#define UMB_END_SEGMENT 0xDFFF
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
|
Loading…
Reference in a new issue