From 93c0a8a1a06101213c5499772ba8f28c70b89545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 15 Jun 2015 23:43:16 +0000 Subject: [PATCH] [NTVDM]: Commit what I have in my local wc so far (and which is commitable & works): - 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 --- reactos/subsystems/mvdm/ntvdm/bios/bios.h | 32 +++-- .../mvdm/ntvdm/bios/bios32/bios32.c | 31 ++--- .../mvdm/ntvdm/bios/bios32/bios32p.h | 2 +- .../mvdm/ntvdm/bios/bios32/kbdbios32.c | 4 +- .../mvdm/ntvdm/bios/bios32/moubios32.c | 2 +- reactos/subsystems/mvdm/ntvdm/dos/dem.c | 117 +++++++++--------- .../mvdm/ntvdm/dos/dos32krnl/bios.c | 67 +++++----- .../subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c | 37 +++--- .../mvdm/ntvdm/dos/dos32krnl/dosfiles.c | 4 +- .../mvdm/ntvdm/dos/dos32krnl/emsdrv.c | 3 +- .../mvdm/ntvdm/dos/dos32krnl/himem.c | 4 +- .../mvdm/ntvdm/dos/dos32krnl/memory.c | 27 +++- .../mvdm/ntvdm/dos/dos32krnl/memory.h | 4 +- .../mvdm/ntvdm/dos/dos32krnl/process.h | 14 +-- reactos/subsystems/mvdm/ntvdm/dos/mouse32.c | 2 +- reactos/subsystems/mvdm/ntvdm/emulator.h | 7 +- reactos/subsystems/mvdm/ntvdm/hardware/cmos.c | 2 +- reactos/subsystems/mvdm/ntvdm/hardware/pic.c | 6 +- .../mvdm/ntvdm/hardware/video/vga.c | 6 +- reactos/subsystems/mvdm/ntvdm/memory.c | 8 +- reactos/subsystems/mvdm/ntvdm/memory.h | 2 +- 21 files changed, 216 insertions(+), 165 deletions(-) diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios.h b/reactos/subsystems/mvdm/ntvdm/bios/bios.h index cbbd1518f14..e8f30ba503c 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios.h +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios.h @@ -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. diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c index e64e829fb4f..a4df846e86e 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c @@ -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 */ diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32p.h b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32p.h index 423648551ad..bb78c8ed287 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32p.h +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32p.h @@ -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_ diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c b/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c index bec4fde71bc..1eef4b89e80 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c @@ -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 ***********************************************************/ diff --git a/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c b/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c index 9ab48616f70..a17c410acd1 100644 --- a/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c +++ b/reactos/subsystems/mvdm/ntvdm/bios/bios32/moubios32.c @@ -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) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dem.c b/reactos/subsystems/mvdm/ntvdm/dos/dem.c index dabee5d041f..1f278fec84e 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dem.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dem.c @@ -16,6 +16,8 @@ #include "ntvdm.h" #include "emulator.h" +#include + #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(); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c index ff20adf6031..f384cd1ad85 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c index 1793c39e039..efed9ea55d1 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c @@ -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) + switch (getAL()) { - /* The driver is loaded */ - setAL(0x80); - } - else if (getAL() == 0x10) - { - setES(HIWORD(DriverEntry)); - setBX(LOWORD(DriverEntry)); - } - else - { - 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 diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c index a2740769335..c7252fa7cbf 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.c @@ -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; diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c index 77fb7b12f74..b2e9cc1c2c8 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c @@ -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, diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c index 96bd5c779aa..3952194622f 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c @@ -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) diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c index f0539280d81..1e31b2fb941 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c @@ -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 */ diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h index e9ed2dc70f5..bf3e61ae965 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.h @@ -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 */ diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h index 3d5525b6cb8..4d2d136c8e2 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.h @@ -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); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c b/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c index 61a50e74fe9..99a63fb8ef1 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/mouse32.c @@ -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) diff --git a/reactos/subsystems/mvdm/ntvdm/emulator.h b/reactos/subsystems/mvdm/ntvdm/emulator.h index b904345503e..3f9e08a6f94 100644 --- a/reactos/subsystems/mvdm/ntvdm/emulator.h +++ b/reactos/subsystems/mvdm/ntvdm/emulator.h @@ -16,20 +16,19 @@ /* 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) diff --git a/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c b/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c index b894b7c0370..ed72a507a5e 100644 --- a/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c +++ b/reactos/subsystems/mvdm/ntvdm/hardware/cmos.c @@ -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; diff --git a/reactos/subsystems/mvdm/ntvdm/hardware/pic.c b/reactos/subsystems/mvdm/ntvdm/hardware/pic.c index e7c38ebc064..74172af339b 100644 --- a/reactos/subsystems/mvdm/ntvdm/hardware/pic.c +++ b/reactos/subsystems/mvdm/ntvdm/hardware/pic.c @@ -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 diff --git a/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c b/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c index 7d4a1de396a..2aa0c4aa757 100644 --- a/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c +++ b/reactos/subsystems/mvdm/ntvdm/hardware/video/vga.c @@ -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]; } diff --git a/reactos/subsystems/mvdm/ntvdm/memory.c b/reactos/subsystems/mvdm/ntvdm/memory.c index 49a14eb144a..692cc526ff8 100644 --- a/reactos/subsystems/mvdm/ntvdm/memory.c +++ b/reactos/subsystems/mvdm/ntvdm/memory.c @@ -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; diff --git a/reactos/subsystems/mvdm/ntvdm/memory.h b/reactos/subsystems/mvdm/ntvdm/memory.h index f3bc537f6ef..c5419cfb67c 100644 --- a/reactos/subsystems/mvdm/ntvdm/memory.h +++ b/reactos/subsystems/mvdm/ntvdm/memory.h @@ -27,7 +27,7 @@ typedef BOOLEAN ULONG Address, PVOID Buffer, ULONG Size -); +); /* FUNCTIONS ******************************************************************/