[NTVDM]: Commit what I have in my local wc so far (and which is commitable & works):
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 15 Jun 2015 23:43:16 +0000 (23:43 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 15 Jun 2015 23:43:16 +0000 (23:43 +0000)
- Simplify PicIRQComplete helper function.
- Set up temporary stack for the BIOS.
- Initialize the "User Data Area" that is found at 0050:xxxx (see http://helppc.netcore2k.net/table/memory-map for more details).
- Some INT --> UINT
- Simplify few macros.
- Simplify DOS initialization; add few functions that will be useful later on.
- Remove trailing whitespace.

svn path=/trunk/; revision=68159

21 files changed:
reactos/subsystems/mvdm/ntvdm/bios/bios.h
reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c
reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32p.h
reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c
reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
reactos/subsystems/mvdm/ntvdm/dos/dem.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h
reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h
reactos/subsystems/mvdm/ntvdm/dos/mouse32.c
reactos/subsystems/mvdm/ntvdm/emulator.h
reactos/subsystems/mvdm/ntvdm/hardware/cmos.c
reactos/subsystems/mvdm/ntvdm/hardware/pic.c
reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c
reactos/subsystems/mvdm/ntvdm/memory.c
reactos/subsystems/mvdm/ntvdm/memory.h

index cbbd151..e8f30ba 100644 (file)
@@ -111,14 +111,32 @@ typedef struct
     DWORD EGAPtr;                               // 0xa8
     BYTE Reserved12[68];                        // 0xac
     BYTE Reserved13[16];                        // 0xf0
-
-    DWORD Reserved14;                           // 0x100
-    BYTE Reserved15[12];                        // 0x104
-    BYTE Reserved16[17];                        // 0x110
-    BYTE Reserved17[15];                        // 0x121
-    BYTE Reserved18[3];                         // 0x130
 } BIOS_DATA_AREA, *PBIOS_DATA_AREA;
-C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
+C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x100);
+
+/*
+ * User Data Area at 0050:XXXX
+ *
+ * See: http://helppc.netcore2k.net/table/memory-map
+ * for more information.
+ */
+typedef struct
+{
+    BYTE PrintScreen;                           // 0x00
+    BYTE Basic0[3];                             // 0x01
+    BYTE SingleDisketteFlag;                    // 0x04
+    BYTE PostArea[10];                          // 0x05
+    BYTE Basic1;                                // 0x0f
+    WORD Basic2;                                // 0x10
+    DWORD Basic3;                               // 0x12
+    DWORD Basic4;                               // 0x16
+    DWORD Basic5;                               // 0x1a
+    WORD Reserved0;                             // 0x1e
+    WORD DynStorage;                            // 0x20
+    BYTE DisketteInitStorage[14];               // 0x22
+    DWORD Reserved1;                            // 0x30
+} USER_DATA_AREA, *PUSER_DATA_AREA;
+C_ASSERT(sizeof(USER_DATA_AREA) == 0x34);
 
 /*
  * BIOS Configuration Table at F000:E6F5 for 100% compatible BIOSes.
index e64e829..a4df846 100644 (file)
@@ -224,7 +224,7 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
                     Return = (Value & getBH()) != 0;
                     break;
                 }
-                
+
                 /* Test and return if zero */
                 case 4:
                 {
@@ -554,15 +554,11 @@ VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
 }
 
 
-VOID PicIRQComplete(LPWORD Stack)
+VOID PicIRQComplete(BYTE IntNum)
 {
-    /* Get the interrupt number */
-    BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
-
     /*
      * If this was a PIC IRQ, send an End-of-Interrupt to the PIC.
      */
-
     if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
     {
         /* It was an IRQ from the master PIC */
@@ -585,7 +581,7 @@ static VOID WINAPI BiosHandleMasterPicIRQ(LPWORD Stack)
 
     DPRINT("Master - IrqNumber = 0x%02X\n", IrqNumber);
 
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
@@ -597,7 +593,7 @@ static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
 
     DPRINT("Slave - IrqNumber = 0x%02X\n", IrqNumber);
 
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 // Timer IRQ 0
@@ -612,7 +608,7 @@ static VOID WINAPI BiosTimerIrq(LPWORD Stack)
      */
     Int32Call(&BiosContext, BIOS_SYS_TIMER_INTERRUPT);
     // BiosSystemTimerInterrupt(Stack);
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 
@@ -795,15 +791,17 @@ Bios32Post(LPWORD Stack)
     /* Disable interrupts */
     setIF(0);
 
+    /* Set the data segment */
+    setDS(BDA_SEGMENT);
+
     /* Initialize the stack */
-    // That's what says IBM... (stack at 30:00FF going downwards)
+    // Temporary stack for POST (to be used only before initializing the INT vectors)
     // setSS(0x0000);
     // setSP(0x0400);
-    setSS(0x0050);  // Stack at 50:0400, going downwards
-    setSP(0x0400);
-
-    /* Set data segment */
-    setDS(BDA_SEGMENT);
+    //
+    // Stack to be used after the initialization of the INT vectors
+    setSS(0x0000);  // Stack at 00:8000, going downwards
+    setSP(0x8000);
 
     /*
      * Perform early CMOS shutdown status checks
@@ -912,6 +910,9 @@ Bios32Post(LPWORD Stack)
     InitializeBiosData();
     InitializeBiosInfo();
 
+    /* Initialize the User Data Area at 0050:XXXX */
+    RtlZeroMemory(SEG_OFF_TO_PTR(0x50, 0x0000), sizeof(USER_DATA_AREA));
+
     /*
      * Initialize IVT and hardware
      */
index 4236485..bb78c8e 100644 (file)
@@ -40,7 +40,7 @@ do { \
 } while(0);
 
 VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
-VOID PicIRQComplete(LPWORD Stack);
+VOID PicIRQComplete(BYTE IntNum);
 
 #endif // _BIOS32P_H_
 
index bec4fde..1eef4b8 100644 (file)
@@ -118,7 +118,7 @@ static VOID WINAPI BiosKeyboardService(LPWORD Stack)
         case 0x11:
         {
             WORD Character;
-            
+
             if (BiosKbdBufferTop(&Character))
             {
                 /* There is a character, clear ZF and return it */
@@ -315,7 +315,7 @@ static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
            Character, ScanCode, Bda->KeybdShiftFlags);
 
 Quit:
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 /* PUBLIC FUNCTIONS ***********************************************************/
index 9ab4861..a17c410 100644 (file)
@@ -26,7 +26,7 @@
 // Mouse IRQ 12
 static VOID WINAPI BiosMouseIrq(LPWORD Stack)
 {
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 VOID BiosMousePs2Interface(LPWORD Stack)
index dabee5d..1f278fe 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "ntvdm.h"
 #include "emulator.h"
+#include <isvbop.h>
+
 #include "utils.h"
 
 #include "dem.h"
@@ -40,18 +42,18 @@ static VOID WINAPI DosSystemBop(LPWORD Stack)
 
     switch (FuncNum)
     {
-        case 0x11:  // Load the DOS kernel
+        /* Load the DOS kernel */
+        case 0x11:
         {
             BOOLEAN Success = FALSE;
+            LPCSTR  DosKernelFileName = "ntdos.sys";
             HANDLE  hDosKernel;
             ULONG   ulDosKernelSize = 0;
 
             DPRINT1("You are loading Windows NT DOS!\n");
 
             /* Open the DOS kernel file */
-            hDosKernel = FileOpen("ntdos.sys", &ulDosKernelSize);
-
-            /* If we failed, bail out */
+            hDosKernel = FileOpen(DosKernelFileName, &ulDosKernelSize);
             if (hDosKernel == NULL) goto Quit;
 
             /*
@@ -64,7 +66,8 @@ static VOID WINAPI DosSystemBop(LPWORD Stack)
                                        ulDosKernelSize,
                                        &ulDosKernelSize);
 
-            DPRINT1("Windows NT DOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+            DPRINT1("Windows NT DOS file '%s' loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+                    DosKernelFileName,
                     (Success ? "succeeded" : "failed"),
                     getDI(), 0x0000,
                     ulDosKernelSize,
@@ -77,6 +80,8 @@ Quit:
             if (!Success)
             {
                 /* We failed everything, stop the VDM */
+                DisplayMessage(L"Windows NT DOS kernel file '%S' loading failed (Error: %u). The VDM will shut down.",
+                               DosKernelFileName, GetLastError());
                 EmulatorTerminate();
                 return;
             }
@@ -301,16 +306,16 @@ ULONG SessionId = 0;
 //
 
 /* 16-bit bootstrap code at 0000:7C00 */
-/* Of course, this is not in real bootsector format, because we don't care */
+/* Of course, this is not in real bootsector format, because we don't care about it for now */
 static BYTE Bootsector1[] =
 {
-    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_LOAD_DOS,  // Call DOS Loading
+    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_LOAD_DOS
 };
 /* This portion of code is run if we failed to load the DOS */
+// NOTE: This may also be done by the BIOS32.
 static BYTE Bootsector2[] =
 {
-    0xEA,                   // jmp far ptr
-    0x5B, 0xE0, 0x00, 0xF0, // F000:E05B /** HACK! What to do instead?? **/
+    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
 };
 
 static VOID WINAPI DosInitialize(LPWORD Stack);
@@ -319,7 +324,7 @@ VOID DosBootsectorInitialize(VOID)
 {
     /* We write the bootsector at 0000:7C00 */
     ULONG_PTR Address = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
-    CHAR DosKernelFileName[] = ""; // No DOS file name, therefore we'll load DOS32
+    CHAR DosKernelFileName[] = ""; // No DOS BIOS file name, therefore we will load DOS32
 
     DPRINT("DosBootsectorInitialize\n");
 
@@ -336,43 +341,47 @@ VOID DosBootsectorInitialize(VOID)
 
 
 //
-// This function is called by the DOS bootsector. We finish to load
-// the DOS, then we jump to 0070:0000.
+// This function is called by the DOS bootsector in case we load DOS32.
+// It sets up the DOS32 start code then jumps to 0070:0000.
 //
 
-/* 16-bit startup code at 0070:0000 */
+/* 16-bit startup code for DOS32 at 0070:0000 */
 static BYTE Startup[] =
 {
-    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_START_DOS,  // Call DOS Start
+    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_START_DOS,
+    LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
 };
 
 static VOID WINAPI DosStart(LPWORD Stack);
 
 static VOID WINAPI DosInitialize(LPWORD Stack)
 {
-    BOOLEAN Success = FALSE;
-
-    /* Get the DOS kernel file name (NULL-terminated) */
+    /* Get the DOS BIOS file name (NULL-terminated) */
     // FIXME: Isn't it possible to use some DS:SI instead??
-    LPCSTR DosKernelFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
-    setIP(getIP() + strlen(DosKernelFileName) + 1); // Skip it
+    LPCSTR DosBiosFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
+    setIP(getIP() + strlen(DosBiosFileName) + 1); // Skip it
 
-    DPRINT("DosInitialize('%s')\n", DosKernelFileName);
+    DPRINT("DosInitialize('%s')\n", DosBiosFileName);
+
+    /*
+     * We succeeded, deregister the DOS Loading BOP
+     * so that no app will be able to call us back.
+     */
+    RegisterBop(BOP_LOAD_DOS, NULL);
 
     /* Register the DOS BOPs */
     RegisterBop(BOP_DOS, DosSystemBop        );
     RegisterBop(BOP_CMD, DosCmdInterpreterBop);
 
-    if (DosKernelFileName && DosKernelFileName[0] != '\0')
+    if (DosBiosFileName && DosBiosFileName[0] != '\0')
     {
+        BOOLEAN Success = FALSE;
         HANDLE  hDosBios;
         ULONG   ulDosBiosSize = 0;
 
         /* Open the DOS BIOS file */
-        hDosBios = FileOpen(DosKernelFileName, &ulDosBiosSize);
-
-        /* If we failed, bail out */
-        if (hDosBios == NULL) goto QuitCustom;
+        hDosBios = FileOpen(DosBiosFileName, &ulDosBiosSize);
+        if (hDosBios == NULL) goto Quit;
 
         /* Attempt to load the DOS BIOS into memory */
         Success = FileLoadByHandle(hDosBios,
@@ -380,7 +389,8 @@ static VOID WINAPI DosInitialize(LPWORD Stack)
                                    ulDosBiosSize,
                                    &ulDosBiosSize);
 
-        DPRINT1("DOS BIOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+        DPRINT1("DOS BIOS file '%s' loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+                DosBiosFileName,
                 (Success ? "succeeded" : "failed"),
                 0x0070, 0x0000,
                 ulDosBiosSize,
@@ -389,52 +399,32 @@ static VOID WINAPI DosInitialize(LPWORD Stack)
         /* Close the DOS BIOS file */
         FileClose(hDosBios);
 
-        if (!Success) goto QuitCustom;
-
-        /* Position execution pointers and return */
-        setCS(0x0070);
-        setIP(0x0000);
-
-        /* Return control */
-QuitCustom:
+Quit:
         if (!Success)
-            DisplayMessage(L"Custom DOS '%S' loading failed, what to do??", DosKernelFileName);
+        {
+            DisplayMessage(L"DOS BIOS file '%S' loading failed (Error: %u). The VDM will shut down.",
+                           DosBiosFileName, GetLastError());
+            return;
+        }
     }
     else
     {
-        Success = DosBIOSInitialize();
-        // Success &= DosKRNLInitialize();
-
-        if (!Success) goto Quit32;
-
-        /* Write the "bootsector" */
+        /* Load the 16-bit startup code for DOS32 and register its Starting BOP */
         RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));
 
-        /* Register the DOS Starting BOP */
+        // This is the equivalent of BOP_LOAD_DOS, function 0x11 "Load the DOS kernel"
+        // for the Windows NT DOS.
         RegisterBop(BOP_START_DOS, DosStart);
-
-        /* Position execution pointers and return */
-        setCS(0x0070);
-        setIP(0x0000);
-
-        /* Return control */
-Quit32:
-        if (!Success)
-            DisplayMessage(L"DOS32 loading failed, what to do??");
     }
 
-    if (Success)
-    {
-        /*
-         * We succeeded, deregister the DOS Loading BOP
-         * so that no app will be able to call us back.
-         */
-        RegisterBop(BOP_LOAD_DOS, NULL);
-    }
+    /* Position execution pointers for DOS startup and return */
+    setCS(0x0070);
+    setIP(0x0000);
 }
 
 static VOID WINAPI DosStart(LPWORD Stack)
 {
+    BOOLEAN Success;
 #ifdef STANDALONE
     DWORD Result;
     CHAR ApplicationName[MAX_PATH];
@@ -451,6 +441,15 @@ static VOID WINAPI DosStart(LPWORD Stack)
      */
     RegisterBop(BOP_START_DOS, NULL);
 
+    Success  = DosBIOSInitialize();
+//  Success &= DosKRNLInitialize();
+    if (!Success)
+    {
+        DisplayMessage(L"DOS32 loading failed (Error: %u). The VDM will shut down.", GetLastError());
+        EmulatorTerminate();
+        return;
+    }
+
     /* Load the mouse driver */
     DosMouseInitialize();
 
index ff20adf..f384cd1 100644 (file)
@@ -30,8 +30,6 @@
 #undef FreeEnvironmentStrings
 #define FreeEnvironmentStrings FreeEnvironmentStringsA
 
-#define CHARACTER_ADDRESS 0x007000FF /* 0070:00FF */
-
 /* PRIVATE VARIABLES **********************************************************/
 
 // static BYTE CurrentDrive;
@@ -102,40 +100,11 @@ VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
                  &BytesWritten);
 }
 
-BOOLEAN DosBIOSInitialize(VOID)
+BOOLEAN DosBuildSysEnvBlock(VOID)
 {
-    PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
-
     LPSTR SourcePtr, Environment;
     LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
 
-#if 0
-    UCHAR i;
-    CHAR CurrentDirectory[MAX_PATH];
-    CHAR DosDirectory[DOS_DIR_LENGTH];
-    LPSTR Path;
-
-    FILE *Stream;
-    WCHAR Buffer[256];
-#endif
-
-    /* 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 */
     SourcePtr = Environment = GetEnvironmentStrings();
     if (Environment == NULL) return FALSE;
@@ -178,6 +147,40 @@ BOOLEAN DosBIOSInitialize(VOID)
     /* Free the memory allocated for environment strings */
     FreeEnvironmentStrings(Environment);
 
+    return TRUE;
+}
+
+BOOLEAN DosBIOSInitialize(VOID)
+{
+#if 0
+    UCHAR i;
+    CHAR CurrentDirectory[MAX_PATH];
+    CHAR DosDirectory[DOS_DIR_LENGTH];
+    LPSTR Path;
+
+    FILE *Stream;
+    WCHAR Buffer[256];
+#endif
+
+    /* Set the data segment */
+    setDS(DOS_DATA_SEGMENT);
+
+    /* Initialize the DOS stack */
+    // Stack just before FIRST_MCB_SEGMENT and after SYSTEM_ENV_BLOCK
+    // FIXME: Add a block of fixed size for the stack in DOS_DATA instead!
+    setSS(0x0F00);
+    setSP(0x0FF0);
+    setBP(0x091E); // DOS base stack pointer relic value
+
+    /* Initialize memory management */
+    DosInitializeMemory();
+
+    /* Build the system master environment block (inherited by the shell) */
+    if (!DosBuildSysEnvBlock())
+    {
+        DPRINT1("An error occurred when setting up the system environment block.\n");
+    }
+
 
 #if 0
 
index 1793c39..efed9ea 100644 (file)
@@ -1502,7 +1502,6 @@ VOID WINAPI DosInt21h(LPWORD Stack)
             /* Return the DOS "list of lists" in ES:BX */
             setES(DOS_DATA_SEGMENT);
             setBX(DOS_DATA_OFFSET(SysVars.FirstDpb));
-
             break;
         }
 
@@ -1877,6 +1876,7 @@ VOID WINAPI DosAbsoluteRead(LPWORD Stack)
     /*
      * This call should leave the flags on the stack for some reason,
      * so move the stack by one word.
+     * See: http://www.techhelpmanual.com/565-int_25h_26h__absolute_disk_read_write.html
      */
     Stack[STACK_INT_NUM] = Stack[STACK_IP];
     Stack[STACK_IP] = Stack[STACK_CS];
@@ -1896,6 +1896,7 @@ VOID WINAPI DosAbsoluteWrite(LPWORD Stack)
     /*
      * This call should leave the flags on the stack for some reason,
      * so move the stack by one word.
+     * See: http://www.techhelpmanual.com/565-int_25h_26h__absolute_disk_read_write.html
      */
     Stack[STACK_INT_NUM] = Stack[STACK_IP];
     Stack[STACK_IP] = Stack[STACK_CS];
@@ -1966,19 +1967,27 @@ VOID WINAPI DosInt2Fh(LPWORD Stack)
             DWORD DriverEntry;
             if (!XmsGetDriverEntry(&DriverEntry)) break;
 
-            if (getAL() == 0x00)
-            {
-                /* The driver is loaded */
-                setAL(0x80);
-            }
-            else if (getAL() == 0x10)
-            {
-                setES(HIWORD(DriverEntry));
-                setBX(LOWORD(DriverEntry));
-            }
-            else
+            switch (getAL())
             {
-                DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL = %xh\n", getAL());
+                /* Installation Check */
+                case 0x00:
+                {
+                    /* The driver is loaded */
+                    setAL(0x80);
+                    break;
+                }
+
+                /* Get Driver Address */
+                case 0x10:
+                {
+                    setES(HIWORD(DriverEntry));
+                    setBX(LOWORD(DriverEntry));
+                    break;
+                }
+
+                default:
+                    DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL = %xh\n", getAL());
+                    break;
             }
 
             break;
@@ -2125,7 +2134,7 @@ BOOLEAN DosKRNLInitialize(VOID)
     RegisterDosInt32(0x27, DosInt27h        ); // Terminate and Stay Resident
     RegisterDosInt32(0x28, DosIdle          ); // DOS Idle Interrupt
     RegisterDosInt32(0x29, DosFastConOut    ); // DOS 2+ Fast Console Output
-    RegisterDosInt32(0x2F, DosInt2Fh        );
+    RegisterDosInt32(0x2F, DosInt2Fh        ); // Multiplex Interrupt
 
     /* Unimplemented DOS interrupts */
     RegisterDosInt32(0x2A, NULL); // Network - Installation Check
index a274076..c7252fa 100644 (file)
@@ -624,7 +624,7 @@ WORD DosOpenFile(LPWORD Handle,
             return (WORD)GetLastError();
         }
     }
+
     DescriptorId = DosFindFreeDescriptor();
     if (DescriptorId == 0xFF)
     {
@@ -1026,7 +1026,7 @@ BOOLEAN DosDeviceIoControl(WORD FileHandle, BYTE ControlCode, DWORD Buffer, PWOR
                 {
                     /* Not ready */
                     *Length = 0;
-                } 
+                }
             }
 
             return TRUE;
index 77fb7b1..b2e9cc1 100644 (file)
@@ -153,7 +153,7 @@ static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
     }
 
     PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
-    if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE; 
+    if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
 
     Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
                             + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE);
@@ -501,7 +501,6 @@ BOOLEAN EmsDrvInitialize(ULONG TotalPages)
                              EmsReadMemory,
                              EmsWriteMemory);
 
-
     /* Create the device */
     Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
                              EMS_DEVICE_NAME,
index 96bd5c7..3952194 100644 (file)
@@ -485,7 +485,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
 
             if (Entry && Entry->Handle != 0)
             {
-                INT i;
+                UINT i;
                 UCHAR Handles = 0;
 
                 for (i = 0; i < XMS_MAX_HANDLES; i++)
@@ -557,7 +557,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
         {
             WORD Segment;
             WORD MaxAvailable;
-            
+
             Segment = DosResizeMemory(getDX(), getBX(), &MaxAvailable);
 
             if (Segment)
index f053928..1e31b2f 100644 (file)
@@ -274,7 +274,7 @@ BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
 
             /* It is, split it into two blocks */
             NextMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
-    
+
             /* Initialize the new MCB structure */
             NextMcb->BlockType = Mcb->BlockType;
             NextMcb->Size = Mcb->Size - NewSize - 1;
@@ -312,7 +312,7 @@ Done:
         /* Return the maximum possible size */
         if (MaxAvailable) *MaxAvailable = ReturnSize;
     }
-    
+
     return Success;
 }
 
@@ -402,3 +402,26 @@ VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
     Mcb->OwnerPsp = NewOwner;
 }
 
+VOID DosInitializeMemory(VOID)
+{
+    PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
+
+    /* 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;
+}
+
+/* EOF */
index e9ed2dc..bf3e61a 100644 (file)
@@ -11,7 +11,7 @@
 
 /* TYPEDEFS *******************************************************************/
 
-#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)SEG_OFF_TO_PTR((seg), 0))
 
 enum DOS_ALLOC_STRATEGY
 {
@@ -45,6 +45,8 @@ BOOLEAN DosLinkUmb(VOID);
 BOOLEAN DosUnlinkUmb(VOID);
 VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner);
 
+VOID DosInitializeMemory(VOID);
+
 #endif // _DOS_MEMORY_H_
 
 /* EOF */
index 3d5525b..4d2d136 100644 (file)
@@ -8,16 +8,16 @@
 
 /* DEFINITIONS ****************************************************************/
 
-#define DOS_CMDLINE_LENGTH 127
+#define DOS_CMDLINE_LENGTH   127
 #define DOS_PROGRAM_NAME_TAG 0x0001
 
-#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)SEG_OFF_TO_PTR((seg), 0))
 
 typedef enum
 {
     DOS_LOAD_AND_EXECUTE = 0x00,
-    DOS_LOAD_ONLY = 0x01,
-    DOS_LOAD_OVERLAY = 0x03
+    DOS_LOAD_ONLY        = 0x01,
+    DOS_LOAD_OVERLAY     = 0x03
 } DOS_EXEC_TYPE;
 
 #pragma pack(push, 1)
@@ -75,14 +75,12 @@ typedef struct _DOS_EXEC_PARAM_BLOCK
 typedef struct _DOS_REGISTER_STATE
 {
     WORD AX, BX, CX, DX, SI, DI, BP, DS, ES;
+//  WORD IP, CS, Flags; // They are supposed to be already
+                        // pushed on stack by the DOS caller.
 } DOS_REGISTER_STATE, *PDOS_REGISTER_STATE;
 
 #pragma pack(pop)
 
-/* VARIABLES ******************************************************************/
-
-extern WORD CurrentPsp;
-
 /* FUNCTIONS ******************************************************************/
 
 VOID DosClonePsp(WORD DestSegment, WORD SourceSegment);
index 61a50e7..99a63fb 100644 (file)
@@ -339,7 +339,7 @@ static VOID WINAPI DosMouseIrq(LPWORD Stack)
     DosUpdateButtons(ButtonState);
 
     /* Complete the IRQ */
-    PicIRQComplete(Stack);
+    PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
 }
 
 static VOID WINAPI DosMouseService(LPWORD Stack)
index b904345..3f9e08a 100644 (file)
 /* DEFINES ********************************************************************/
 
 /* Basic Memory Management */
-#define MEM_ALIGN_UP(ptr, align)    MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
 #define MEM_ALIGN_DOWN(ptr, align)  (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
+#define MEM_ALIGN_UP(ptr, align)    MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
 
 #define TO_LINEAR(seg, off) (((seg) << 4) + (off))
 #define MAX_SEGMENT 0xFFFF
 #define MAX_OFFSET  0xFFFF
 #define MAX_ADDRESS 0x1000000 // 16 MB of RAM; see also: kernel32/client/vdm.c!BaseGetVdmConfigInfo
 
-#define FAR_POINTER(x)  \
-    (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
-
 #define SEG_OFF_TO_PTR(seg, off)    \
     (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
 
+#define FAR_POINTER(x)      SEG_OFF_TO_PTR(HIWORD(x), LOWORD(x))
+
 #define REAL_TO_PHYS(ptr)   (PVOID)((ULONG_PTR)(ptr) + (ULONG_PTR)BaseAddress)
 #define PHYS_TO_REAL(ptr)   (PVOID)((ULONG_PTR)(ptr) - (ULONG_PTR)BaseAddress)
 
index b894b7c..ed72a50 100644 (file)
@@ -105,7 +105,7 @@ static VOID CmosWriteAddress(BYTE Value)
 {
     /* Update the NMI enabled flag */
     NmiEnabled = !(Value & CMOS_DISABLE_NMI);
-    
+
     /* Get the register number */
     Value &= ~CMOS_DISABLE_NMI;
 
index e7c38eb..74172af 100644 (file)
@@ -258,7 +258,7 @@ VOID PicInterruptRequest(BYTE Number)
 
 BYTE PicGetInterrupt(VOID)
 {
-    INT i;
+    UINT i;
 
     /* Search the master PIC interrupts by priority */
     for (i = 0; i < 8; i++)
@@ -299,7 +299,7 @@ BYTE PicGetInterrupt(VOID)
             }
         }
     }
-    
+
     /* Spurious interrupt */
     if (MasterPic.InServiceRegister & (1 << 2)) return SlavePic.IntOffset + 7;
     else return MasterPic.IntOffset + 7;
@@ -330,7 +330,7 @@ call_ica_hw_interrupt(INT  ms,
     /*
      * Adjust the interrupt request number according to the parameters,
      * by adding an offset == 8 to the interrupt number.
-     * 
+     *
      * Indeed VDDs calling this function usually subtracts 8 so that they give:
      *
      *      ms     |  line  | corresponding interrupt number
index 7d4a1de..2aa0c4a 100644 (file)
@@ -777,7 +777,7 @@ static BOOLEAN VgaInitializePalette(VOID)
                                   VGA_MAX_COLORS * sizeof(PALETTEENTRY));
     TextPalette = RtlAllocateHeap(RtlGetProcessHeap(),
                                   HEAP_ZERO_MEMORY,
-                                  sizeof(LOGPALETTE) + 
+                                  sizeof(LOGPALETTE) +
                                       (VGA_AC_PAL_F_REG + 1) * sizeof(PALETTEENTRY));
     if ((Palette == NULL) || (TextPalette == NULL)) goto Cleanup;
 
@@ -1461,7 +1461,7 @@ static BYTE WINAPI VgaReadPort(USHORT Port)
 
         case VGA_SEQ_INDEX:
             return VgaSeqIndex;
-        
+
         case VGA_SEQ_DATA:
             return VgaSeqRegisters[VgaSeqIndex];
 
@@ -1985,7 +1985,7 @@ VOID FASTCALL VgaReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
         for (i = 0; i < Size; i++)
         {
             VideoAddress = VgaTranslateReadAddress(Address + i);
-    
+
             /* Copy the value to the buffer */
             BufPtr[i] = VgaMemory[VideoAddress];
         }
index 49a14eb..692cc52 100644 (file)
@@ -149,7 +149,7 @@ VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buff
     if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
 
     /* If the A20 line is disabled, mask bit 20 */
-    if (!A20Line) Address &= ~(1 << 20); 
+    if (!A20Line) Address &= ~(1 << 20);
 
     if ((Address + Size - 1) >= MAX_ADDRESS)
     {
@@ -171,7 +171,7 @@ VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buff
     }
     else
     {
-        for (i = FirstPage; i <= LastPage; i++) 
+        for (i = FirstPage; i <= LastPage; i++)
         {
             Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
             Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
@@ -190,7 +190,7 @@ VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buf
     UNREFERENCED_PARAMETER(State);
 
     /* If the A20 line is disabled, mask bit 20 */
-    if (!A20Line) Address &= ~(1 << 20); 
+    if (!A20Line) Address &= ~(1 << 20);
 
     if (Address >= MAX_ADDRESS) return;
     Size = min(Size, MAX_ADDRESS - Address);
@@ -204,7 +204,7 @@ VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buf
     }
     else
     {
-        for (i = FirstPage; i <= LastPage; i++) 
+        for (i = FirstPage; i <= LastPage; i++)
         {
             Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
             Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
index f3bc537..c5419cf 100644 (file)
@@ -27,7 +27,7 @@ typedef BOOLEAN
     ULONG Address,
     PVOID Buffer,
     ULONG Size
-); 
+);
 
 /* FUNCTIONS ******************************************************************/