Author: aandrejevic
Date: Thu Jul 18 11:44:06 2013
New Revision: 59501
URL:
http://svn.reactos.org/svn/reactos?rev=59501&view=rev
Log:
[NTVDM]
Implement Upper Memory Blocks (UMB) support.
Modified:
branches/ntvdm/subsystems/ntvdm/bios.h
branches/ntvdm/subsystems/ntvdm/dos.c
branches/ntvdm/subsystems/ntvdm/dos.h
Modified: branches/ntvdm/subsystems/ntvdm/bios.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Thu Jul 18 11:44:06 2013
@@ -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
Modified: branches/ntvdm/subsystems/ntvdm/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Thu Jul 18 11:44:06 2013
@@ -18,6 +18,7 @@
static DWORD DiskTransferArea;
static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
static WORD DosSftRefCount[DOS_SFT_SIZE];
+static BOOLEAN DosUmbLinked = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -394,6 +395,60 @@
/* Mark the block as free */
Mcb->OwnerPsp = 0;
+ 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;
}
@@ -1412,7 +1467,11 @@
{
EmulatorClearFlag(EMULATOR_FLAG_CF);
}
- else EmulatorSetFlag(EMULATOR_FLAG_CF);
+ else
+ {
+ EmulatorSetRegister(EMULATOR_REG_AX, ERROR_ARENA_TRASHED);
+ EmulatorSetFlag(EMULATOR_FLAG_CF);
+ }
break;
}
@@ -1439,6 +1498,35 @@
case 0x4C:
{
DosTerminateProcess(CurrentPsp, LOBYTE(Eax));
+ 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;
}
@@ -1470,6 +1558,18 @@
/* Initialize the MCB */
Mcb->BlockType = 'Z';
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 */
Modified: branches/ntvdm/subsystems/ntvdm/dos.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.h?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.h [iso-8859-1] Thu Jul 18 11:44:06 2013
@@ -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)