Author: hbelusca
Date: Sat Oct 4 13:36:17 2014
New Revision: 64521
URL:
http://svn.reactos.org/svn/reactos?rev=64521&view=rev
Log:
[NTVDM]
- Move almost all the DOS command launch thread into dem.c,
- Rework the code so that now, when we want to either load our BIOS32 or a custom one, we
start their execution at F000:FFF0 as it should be,
- For modularity purposes (ie. to be able one day to load real OSes in our ntvdm),
implement INT 19h (bootstrap loader) so that it calls a (temporary) dos bootsector loader
that writes some bootstrap code at 0000:7c00, then the INT 19h runs this code, that has as
an effect to load our DOS32 (for a real OS, the MBR code goes to 0000:7c00 and is then
run).
Modified:
trunk/reactos/subsystems/ntvdm/bios/bios.c
trunk/reactos/subsystems/ntvdm/bios/bios.h
trunk/reactos/subsystems/ntvdm/bios/bios32/bios32.c
trunk/reactos/subsystems/ntvdm/dos/dem.c
trunk/reactos/subsystems/ntvdm/dos/dem.h
trunk/reactos/subsystems/ntvdm/ntvdm.c
trunk/reactos/subsystems/ntvdm/ntvdm.h
Modified: trunk/reactos/subsystems/ntvdm/bios/bios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/bios/bios…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/bios/bios.c [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -25,7 +25,7 @@
/* DEFINES ********************************************************************/
/* BOP Identifiers */
-#define BOP_BIOSINIT 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
+#define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
// to let the virtual machine initialize itself
// the IVT and its hardware.
#define BOP_EQUIPLIST 0x11
@@ -35,83 +35,10 @@
static BOOLEAN Bios32Loaded = FALSE;
-static CALLBACK16 __BiosContext;
PBIOS_DATA_AREA Bda;
PBIOS_CONFIG_TABLE Bct;
/* PRIVATE FUNCTIONS **********************************************************/
-
-static VOID WINAPI BiosInitBop(LPWORD Stack)
-{
- BOOLEAN Success;
-
- /* Load the second part of the Windows NTVDM BIOS image */
- LPCSTR BiosFileName = "bios1.rom";
- PVOID BiosLocation = (PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000);
- DWORD BiosSize = 0;
-
- /* Disable interrupts */
- setIF(0);
-
- DisplayMessage(L"You are loading Windows NTVDM BIOS!\n");
-
- /* Initialize a private callback context */
- InitializeContext(&__BiosContext, BIOS_SEGMENT, 0x0000);
-
- Success = LoadRom(BiosFileName, BiosLocation, &BiosSize);
- DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
-
- if (Success == FALSE)
- {
- /* Stop the VDM */
- EmulatorTerminate();
- return;
- }
-
- // DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
- // L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
- // BiosLocation,
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
-
- // (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
- // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
-
- /* Initialize IVT and hardware */
-
- /* Initialize the Keyboard and Video BIOS */
- if (!KbdBiosInitialize() || !VidBiosInitialize())
- {
- /* Stop the VDM */
- EmulatorTerminate();
- return;
- }
-
- /* Load VGA BIOS */
- // Success = LoadRom("v7vga.rom", (PVOID)0xC0000, &BiosSize);
- // DPRINT1("VGA BIOS loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
-
- /* Enable interrupts */
- setIF(1);
-
- ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
-
- /* Load some ROMs */
- // Success = LoadRom("boot.bin", (PVOID)0xE0000, &BiosSize);
- // DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
-
- SearchAndInitRoms(&__BiosContext);
-}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -140,12 +67,14 @@
// The BCT is found at F000:E6F5 for 100% compatible BIOSes.
Bct = (PBIOS_CONFIG_TABLE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5);
- /* Register the BIOS support BOPs */
- RegisterBop(BOP_BIOSINIT , BiosInitBop);
- RegisterBop(BOP_EQUIPLIST , BiosEquipmentService);
- RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize);
+ /**** HACK! HACK! for Windows NTVDM BIOS ****/
+ // WinNtVdmBiosSupportInitialize();
- if (BiosFileName)
+ // /* Register the BIOS support BOPs */
+ // RegisterBop(BOP_EQUIPLIST , BiosEquipmentService);
+ // RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize);
+
+ if (BiosFileName && BiosFileName[0] != '\0')
{
PVOID BiosLocation = NULL;
DWORD BiosSize = 0;
@@ -199,8 +128,8 @@
Success = Bios32Loaded = Bios32Initialize();
}
- /* Enable interrupts */
- setIF(1);
+ // /* Enable interrupts */
+ // setIF(1);
return Success;
}
Modified: trunk/reactos/subsystems/ntvdm/bios/bios.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/bios/bios…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/bios/bios.h [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -16,6 +16,16 @@
#include "vidbios.h"
/* DEFINES ********************************************************************/
+
+/* BOP Identifiers */
+#define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
+ // to let the virtual machine initialize itself
+ // the IVT and its hardware.
+#define BOP_EQUIPLIST 0x11
+#define BOP_GETMEMSIZE 0x12
+
+
+
#define BDA_SEGMENT 0x40
#define BIOS_SEGMENT 0xF000
Modified: trunk/reactos/subsystems/ntvdm/bios/bios32/bios32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/bios/bios…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/bios/bios32/bios32.c [iso-8859-1] Sat Oct 4 13:36:17
2014
@@ -15,8 +15,8 @@
#include "emulator.h"
#include "cpu/cpu.h" // for EMULATOR_FLAG_CF
+#include "cpu/bop.h"
#include "int32.h"
-// #include "bop.h"
#include "../bios.h"
#include "../rom.h"
@@ -129,7 +129,8 @@
*/
static BYTE PostCode[] =
{
- 0xCD, 0x19, // int 0x19, the bootstrap loader interrupt
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_RESET, // Call BIOS POST
+ 0xCD, 0x19, // INT 0x19, the bootstrap
loader interrupt
// LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
};
@@ -278,16 +279,25 @@
return;
}
+
+VOID DosBootsectorInitialize(VOID);
+
static VOID WINAPI BiosBootstrapLoader(LPWORD Stack)
{
/*
- * In real bioses one loads the bootsector read from a diskette
- * or from a disk, to 0000:7C00 and then one runs it.
+ * In real BIOSes one loads the bootsector read from a diskette
+ * or from a disk, copy it to 0000:7C00 and then boot it.
* Since we are 32-bit VM and we hardcode our DOS at the moment,
* just call the DOS 32-bit initialization code.
*/
DPRINT1("BiosBootstrapLoader -->\n");
+
+ /* Load DOS */
+ DosBootsectorInitialize();
+ /* Position CPU to 0000:7C00 to boot the OS */
+ setCS(0x0000);
+ setIP(0x7C00);
DPRINT1("<-- BiosBootstrapLoader\n");
}
@@ -510,6 +520,25 @@
((PULONG)BaseAddress)[0x49] = (ULONG)NULL;
}
+static VOID InitializeBiosData(VOID)
+{
+ UCHAR Low, High;
+
+ /* Initialize the BDA contents */
+ RtlZeroMemory(Bda, sizeof(*Bda));
+ Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
+
+ /*
+ * Retrieve the conventional memory size
+ * in kB from CMOS, typically 640 kB.
+ */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
+ Low = IOReadB(CMOS_DATA_PORT);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
+ High = IOReadB(CMOS_DATA_PORT);
+ Bda->MemorySize = MAKEWORD(Low, High);
+}
+
static VOID InitializeBiosInfo(VOID)
{
RtlZeroMemory(Bct, sizeof(*Bct));
@@ -525,45 +554,17 @@
Bct->Feature[4] = 0x00;
}
-static VOID InitializeBiosData(VOID)
-{
- UCHAR Low, High;
-
- /* System BIOS Copyright */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE000), BiosCopyright,
sizeof(BiosCopyright)-1);
-
- /* System BIOS Version */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE080), BiosVersion, sizeof(BiosVersion)-1); //
FIXME: or E061, or E100 ??
-
- /* System BIOS Date */
- RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xFFF5), BiosDate, sizeof(BiosDate)-1);
-
- /* System BIOS Model (same as Bct->Model) */
- *(PBYTE)(SEG_OFF_TO_PTR(0xF000, 0xFFFE)) = BIOS_MODEL;
-
- /* Initialize the BDA contents */
- RtlZeroMemory(Bda, sizeof(*Bda));
- Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
-
- /*
- * Retrieve the conventional memory size
- * in kB from CMOS, typically 640 kB.
- */
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
- Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
- High = IOReadB(CMOS_DATA_PORT);
- Bda->MemorySize = MAKEWORD(Low, High);
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
+
/*
* The BIOS POST (Power On-Self Test)
*/
-BOOLEAN Bios32Initialize(VOID)
+VOID
+Bios32Post(VOID)
{
BOOLEAN Success;
+
+ DPRINT1("Bios32Post\n");
/* Initialize the stack */
// That's what says IBM... (stack at 30:00FF going downwards)
@@ -587,7 +588,13 @@
/* Initialize the Keyboard, Video and Mouse BIOS */
if (!KbdBios32Initialize() || !VidBios32Initialize() || !MouseBios32Initialize())
- return FALSE;
+ {
+ // return FALSE;
+
+ /* Stop the VDM */
+ EmulatorTerminate();
+ return;
+ }
///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
@@ -597,10 +604,70 @@
SearchAndInitRoms(&BiosContext);
+ /*
+ * End of the 32-bit POST portion. We then fall back into 16-bit where
+ * the rest of the POST code is executed, typically calling INT 19h
+ * to boot up the OS.
+ */
+}
+
+static VOID WINAPI Bios32ResetBop(LPWORD Stack)
+{
+ DPRINT1("Bios32ResetBop\n");
+
+ /* Disable interrupts */
+ setIF(0);
+
+ // FIXME: Check the word at 0040h:0072h and do one of the following actions:
+ // - if the word is 1234h, perform a warm reboot (aka. Ctrl-Alt-Del);
+ // - if the word is 0000h, perform a cold reboot (aka. Reset).
+
+ /* Initialize IVT and hardware */
+
+ /* Initialize the Keyboard and Video BIOS */
+ if (!KbdBiosInitialize() || !VidBiosInitialize())
+ {
+ /* Stop the VDM */
+ EmulatorTerminate();
+ return;
+ }
+
+ /* Do the POST */
+ Bios32Post();
+
+ /* Enable interrupts */
+ setIF(1);
+}
+
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN Bios32Initialize(VOID)
+{
+ /*
+ * Initialize BIOS32 static data
+ */
+
/* Bootstrap code */
RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE05B), PostCode , sizeof(PostCode ));
RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xFFF0), Bootstrap, sizeof(Bootstrap));
+ /* System BIOS Copyright */
+ RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE000), BiosCopyright,
sizeof(BiosCopyright)-1);
+
+ /* System BIOS Version */
+ RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xE080), BiosVersion, sizeof(BiosVersion)-1);
+ // FIXME: or E061, or E100 ??
+
+ /* System BIOS Date */
+ RtlCopyMemory(SEG_OFF_TO_PTR(0xF000, 0xFFF5), BiosDate, sizeof(BiosDate)-1);
+
+ /* System BIOS Model (same as Bct->Model) */
+ *(PBYTE)(SEG_OFF_TO_PTR(0xF000, 0xFFFE)) = BIOS_MODEL;
+
+ /* Redefine our POST function */
+ RegisterBop(BOP_RESET, Bios32ResetBop);
+
/* We are done */
return TRUE;
}
Modified: trunk/reactos/subsystems/ntvdm/dos/dem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dem.c…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dem.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dem.c [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -33,8 +33,10 @@
/* DEFINES ********************************************************************/
/* BOP Identifiers */
-#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
-#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM)
+#define BOP_LOAD_DOS 0x2B // DOS Loading and Initializing BOP. In parameter
(following bytes) we take a NULL-terminated string indicating the name of the DOS kernel
file.
+#define BOP_START_DOS 0x2C // DOS Starting BOP. In parameter (following bytes) we
take a NULL-terminated string indicating the name of the DOS kernel file.
+#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
+#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM)
/* PRIVATE FUNCTIONS **********************************************************/
@@ -185,17 +187,157 @@
}
}
+#ifndef STANDALONE
+static DWORD
+WINAPI
+CommandThreadProc(LPVOID Parameter)
+{
+ BOOLEAN First = TRUE;
+ DWORD Result;
+ VDM_COMMAND_INFO CommandInfo;
+ CHAR CmdLine[MAX_PATH];
+ CHAR AppName[MAX_PATH];
+ CHAR PifFile[MAX_PATH];
+ CHAR Desktop[MAX_PATH];
+ CHAR Title[MAX_PATH];
+ ULONG EnvSize = 256;
+ PVOID Env = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
+
+ UNREFERENCED_PARAMETER(Parameter);
+ ASSERT(Env != NULL);
+
+ do
+ {
+ /* Clear the structure */
+ ZeroMemory(&CommandInfo, sizeof(CommandInfo));
+
+ /* Initialize the structure members */
+ CommandInfo.TaskId = SessionId;
+ CommandInfo.VDMState = VDM_FLAG_DOS;
+ CommandInfo.CmdLine = CmdLine;
+ CommandInfo.CmdLen = sizeof(CmdLine);
+ CommandInfo.AppName = AppName;
+ CommandInfo.AppLen = sizeof(AppName);
+ CommandInfo.PifFile = PifFile;
+ CommandInfo.PifLen = sizeof(PifFile);
+ CommandInfo.Desktop = Desktop;
+ CommandInfo.DesktopLen = sizeof(Desktop);
+ CommandInfo.Title = Title;
+ CommandInfo.TitleLen = sizeof(Title);
+ CommandInfo.Env = Env;
+ CommandInfo.EnvLen = EnvSize;
+
+ if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
+
+Command:
+ if (!GetNextVDMCommand(&CommandInfo))
+ {
+ if (CommandInfo.EnvLen > EnvSize)
+ {
+ /* Expand the environment size */
+ EnvSize = CommandInfo.EnvLen;
+ Env = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);
+
+ /* Repeat the request */
+ goto Command;
+ }
+
+ break;
+ }
+
+ /* Start the process from the command line */
+ DPRINT1("Starting '%s' ('%s')...\n", AppName,
CmdLine);
+ Result = DosStartProcess(AppName, CmdLine, Env);
+ if (Result != ERROR_SUCCESS)
+ {
+ DisplayMessage(L"Could not start '%S'. Error: %u", AppName,
Result);
+ // break;
+ continue;
+ }
+
+ First = FALSE;
+ }
+ while (AcceptCommands);
+
+ HeapFree(GetProcessHeap(), 0, Env);
+ return 0;
+}
+#endif
+
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN DosInitialize(IN LPCSTR DosKernelFileName)
-{
+//
+// This function (equivalent of the DOS bootsector) is called by the bootstrap
+// loader *BEFORE* jumping at 0000:7C00. What we should do is to write at 0000:7C00
+// a BOP call that calls DosInitialize back. Then the bootstrap loader jumps at
+// 0000:7C00, our BOP gets called and then we can initialize the 32-bit part of the DOS.
+//
+
+/* 16-bit bootstrap code at 0000:7C00 */
+/* Of course, this is not in real bootsector format, because we don't care */
+static BYTE Bootsector1[] =
+{
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_LOAD_DOS, // Call DOS Loading
+};
+/* This portion of code is run if we failed to load the DOS */
+static BYTE Bootsector2[] =
+{
+ 0xEA, // jmp far ptr
+ 0x5B, 0xE0, 0x00, 0xF0, // F000:E05B /** HACK! What to do instead?? **/
+};
+
+static VOID WINAPI DosInitialize(LPWORD Stack);
+
+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
+
+ DPRINT1("DosBootsectorInitialize\n");
+
+ /* Write the "bootsector" */
+ RtlCopyMemory((PVOID)Address, Bootsector1, sizeof(Bootsector1));
+ Address += sizeof(Bootsector1);
+ RtlCopyMemory((PVOID)Address, DosKernelFileName, sizeof(DosKernelFileName));
+ Address += sizeof(DosKernelFileName);
+ RtlCopyMemory((PVOID)Address, Bootsector2, sizeof(Bootsector2));
+
+ /* Register the DOS Loading BOP */
+ RegisterBop(BOP_LOAD_DOS, DosInitialize);
+}
+
+
+//
+// This function is called by the DOS bootsector. We finish to load
+// the DOS, then we jump to 0070:0000.
+//
+
+/* 16-bit startup code at 0070:0000 */
+static BYTE Startup[] =
+{
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_START_DOS, // Call DOS Start
+};
+
+static VOID WINAPI DosStart(LPWORD Stack);
+
+static VOID WINAPI DosInitialize(LPWORD Stack)
+{
+ BOOLEAN Success = FALSE;
+
+ /* Get the DOS kernel 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
+
+ DPRINT1("DosInitialize('%s')\n", DosKernelFileName);
+
/* Register the DOS BOPs */
RegisterBop(BOP_DOS, DosSystemBop );
RegisterBop(BOP_CMD, DosCmdInterpreterBop);
- if (DosKernelFileName)
- {
- BOOLEAN Success;
+ if (DosKernelFileName && DosKernelFileName[0] != '\0')
+ {
HANDLE hDosBios;
ULONG ulDosBiosSize = 0;
@@ -203,7 +345,7 @@
hDosBios = FileOpen(DosKernelFileName, &ulDosBiosSize);
/* If we failed, bail out */
- if (hDosBios == NULL) return FALSE;
+ if (hDosBios == NULL) goto QuitCustom;
/* Attempt to load the DOS BIOS into memory */
Success = FileLoadByHandle(hDosBios,
@@ -220,26 +362,121 @@
/* Close the DOS BIOS file */
FileClose(hDosBios);
- if (Success)
- {
- /* Position execution pointers and return */
- setCS(0x0070);
- setIP(0x0000);
- }
-
- return Success;
+ if (!Success) goto QuitCustom;
+
+ /* Position execution pointers and return */
+ setCS(0x0070);
+ setIP(0x0000);
+
+ /* Return control */
+QuitCustom:
+ if (!Success)
+ DisplayMessage(L"Custom DOS '%S' loading failed, what to
do??", DosKernelFileName);
}
else
{
- BOOLEAN Result;
-
- Result = DosBIOSInitialize();
- DosMouseInitialize(); // FIXME: Should be done by the DOS BIOS
- // Result &= DosKRNLInitialize();
-
- return Result;
- }
-}
+ Success = DosBIOSInitialize();
+ // Success &= DosKRNLInitialize();
+
+ if (!Success) goto Quit32;
+
+ /* Write the "bootsector" */
+ RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));
+
+ /* Register the DOS Starting BOP */
+ 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);
+ }
+}
+
+static VOID WINAPI DosStart(LPWORD Stack)
+{
+#ifdef STANDALONE
+ DWORD Result;
+ CHAR ApplicationName[MAX_PATH];
+ CHAR CommandLine[DOS_CMDLINE_LENGTH];
+#endif
+
+ DPRINT1("DosStart\n");
+
+ /*
+ * We succeeded, deregister the DOS Starting BOP
+ * so that no app will be able to call us back.
+ */
+ RegisterBop(BOP_START_DOS, NULL);
+
+ /* Load the mouse driver */
+ DosMouseInitialize();
+
+#ifndef STANDALONE
+
+ /* Create the GetNextVDMCommand thread */
+ CommandThread = CreateThread(NULL, 0, &CommandThreadProc, NULL, 0, NULL);
+ if (CommandThread == NULL)
+ {
+ wprintf(L"FATAL: Failed to create the command processing thread: %d\n",
GetLastError());
+ goto Quit;
+ }
+
+ /* Wait for the command thread to exit */
+ WaitForSingleObject(CommandThread, INFINITE);
+
+ /* Close the thread handle */
+ CloseHandle(CommandThread);
+
+#else
+
+ if (NtVdmArgc >= 2)
+ {
+ WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[1], -1, ApplicationName,
sizeof(ApplicationName), NULL, NULL);
+
+ if (NtVdmArgc >= 3)
+ WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[2], -1, CommandLine,
sizeof(CommandLine), NULL, NULL);
+ else
+ strcpy(CommandLine, "");
+ }
+ else
+ {
+ DisplayMessage(L"Invalid DOS command line\n");
+ goto Quit;
+ }
+
+ /* Start the process from the command line */
+ DPRINT1("Starting '%s' ('%s')...\n", ApplicationName,
CommandLine);
+ Result = DosStartProcess(ApplicationName,
+ CommandLine,
+ GetEnvironmentStrings());
+ if (Result != ERROR_SUCCESS)
+ {
+ DisplayMessage(L"Could not start '%S'. Error: %u",
ApplicationName, Result);
+ goto Quit;
+ }
+
+#endif
+
+Quit:
+ /* Stop the VDM */
+ EmulatorTerminate();
+}
+
+
/* PUBLIC EXPORTED APIS *******************************************************/
Modified: trunk/reactos/subsystems/ntvdm/dos/dem.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dem.h…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dem.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dem.h [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -19,8 +19,6 @@
#include "dos32krnl/dos.h"
/* FUNCTIONS ******************************************************************/
-
-BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames);
DWORD
WINAPI
Modified: trunk/reactos/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/ntvdm.c?r…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/ntvdm.c [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -12,6 +12,7 @@
#include "ntvdm.h"
#include "emulator.h"
+#include "cpu/cpu.h"
#include "clock.h"
#include "hardware/ps2.h"
@@ -26,18 +27,24 @@
static HANDLE ConsoleInput = INVALID_HANDLE_VALUE;
static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
static DWORD OrgConsoleInputMode, OrgConsoleOutputMode;
-static BOOLEAN AcceptCommands = TRUE;
-static HANDLE CommandThread = NULL;
+
+// For DOS
+#ifndef STANDALONE
+BOOLEAN AcceptCommands = TRUE;
+HANDLE CommandThread = NULL;
+ULONG SessionId = 0;
+#endif
+
+HANDLE VdmTaskEvent = NULL;
+
+// Command line of NTVDM
+INT NtVdmArgc;
+WCHAR** NtVdmArgv;
+
static HMENU hConsoleMenu = NULL;
static INT VdmMenuPos = -1;
static BOOLEAN ShowPointer = FALSE;
-
-#ifndef STANDALONE
-ULONG SessionId = 0;
-#endif
-
-HANDLE VdmTaskEvent = NULL;
/*
* Those menu helpers were taken from the GUI frontend in winsrv.dll
@@ -198,6 +205,7 @@
case CTRL_BREAK_EVENT:
{
/* Call INT 23h */
+ DPRINT1("Ctrl-C/Break: Call INT 23h\n");
EmulatorInterrupt(0x23);
break;
}
@@ -206,14 +214,18 @@
if (WaitForSingleObject(VdmTaskEvent, 0) == WAIT_TIMEOUT)
{
/* Exit immediately */
+#ifndef STANDALONE
if (CommandThread) TerminateThread(CommandThread, 0);
+#endif
EmulatorTerminate();
}
+#ifndef STANDALONE
else
{
/* Stop accepting new commands */
AcceptCommands = FALSE;
}
+#endif
break;
}
@@ -361,100 +373,12 @@
DPRINT1("Focus events not handled\n");
}
-#ifndef STANDALONE
-static DWORD
-WINAPI
-CommandThreadProc(LPVOID Parameter)
-{
- BOOLEAN First = TRUE;
- DWORD Result;
- VDM_COMMAND_INFO CommandInfo;
- CHAR CmdLine[MAX_PATH];
- CHAR AppName[MAX_PATH];
- CHAR PifFile[MAX_PATH];
- CHAR Desktop[MAX_PATH];
- CHAR Title[MAX_PATH];
- ULONG EnvSize = 256;
- PVOID Env = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
-
- UNREFERENCED_PARAMETER(Parameter);
- ASSERT(Env != NULL);
-
- do
- {
- /* Clear the structure */
- ZeroMemory(&CommandInfo, sizeof(CommandInfo));
-
- /* Initialize the structure members */
- CommandInfo.TaskId = SessionId;
- CommandInfo.VDMState = VDM_FLAG_DOS;
- CommandInfo.CmdLine = CmdLine;
- CommandInfo.CmdLen = sizeof(CmdLine);
- CommandInfo.AppName = AppName;
- CommandInfo.AppLen = sizeof(AppName);
- CommandInfo.PifFile = PifFile;
- CommandInfo.PifLen = sizeof(PifFile);
- CommandInfo.Desktop = Desktop;
- CommandInfo.DesktopLen = sizeof(Desktop);
- CommandInfo.Title = Title;
- CommandInfo.TitleLen = sizeof(Title);
- CommandInfo.Env = Env;
- CommandInfo.EnvLen = EnvSize;
-
- if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
-
-Command:
- if (!GetNextVDMCommand(&CommandInfo))
- {
- if (CommandInfo.EnvLen > EnvSize)
- {
- /* Expand the environment size */
- EnvSize = CommandInfo.EnvLen;
- Env = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);
-
- /* Repeat the request */
- goto Command;
- }
-
- break;
- }
-
- /* Start the process from the command line */
- DPRINT1("Starting '%s' ('%s')...\n", AppName,
CmdLine);
- Result = DosStartProcess(AppName, CmdLine, Env);
- if (Result != ERROR_SUCCESS)
- {
- DisplayMessage(L"Could not start '%S'. Error: %u", AppName,
Result);
- // break;
- continue;
- }
-
- First = FALSE;
- }
- while (AcceptCommands);
-
- HeapFree(GetProcessHeap(), 0, Env);
- return 0;
-}
-#endif
-
INT
wmain(INT argc, WCHAR *argv[])
{
#ifdef STANDALONE
- DWORD Result;
- CHAR ApplicationName[MAX_PATH];
- CHAR CommandLine[DOS_CMDLINE_LENGTH];
-
- if (argc >= 2)
- {
- WideCharToMultiByte(CP_ACP, 0, argv[1], -1, ApplicationName,
sizeof(ApplicationName), NULL, NULL);
-
- if (argc >= 3) WideCharToMultiByte(CP_ACP, 0, argv[2], -1, CommandLine,
sizeof(CommandLine), NULL, NULL);
- else strcpy(CommandLine, "");
- }
- else
+ if (argc < 2)
{
wprintf(L"\nReactOS Virtual DOS Machine\n\n"
L"Usage: NTVDM <executable> [<parameters>]\n");
@@ -481,6 +405,9 @@
#endif
+ NtVdmArgc = argc;
+ NtVdmArgv = argv;
+
DPRINT1("\n\n\nNTVDM - Starting...\n\n\n");
/* Create the task event */
@@ -508,43 +435,8 @@
goto Cleanup;
}
- /* Initialize the VDM DOS kernel */
- if (!DosInitialize(NULL))
- {
- wprintf(L"FATAL: Failed to initialize the VDM DOS kernel.\n");
- goto Cleanup;
- }
-
-#ifndef STANDALONE
-
- /* Create the GetNextVDMCommand thread */
- CommandThread = CreateThread(NULL, 0, &CommandThreadProc, NULL, 0, NULL);
- if (CommandThread == NULL)
- {
- wprintf(L"FATAL: Failed to create the command processing thread: %d\n",
GetLastError());
- goto Cleanup;
- }
-
- /* Wait for the command thread to exit */
- WaitForSingleObject(CommandThread, INFINITE);
-
- /* Close the thread handle */
- CloseHandle(CommandThread);
-
-#else
-
- /* Start the process from the command line */
- DPRINT1("Starting '%s' ('%s')...\n", ApplicationName,
CommandLine);
- Result = DosStartProcess(ApplicationName,
- CommandLine,
- GetEnvironmentStrings());
- if (Result != ERROR_SUCCESS)
- {
- DisplayMessage(L"Could not start '%S'. Error: %u",
ApplicationName, Result);
- goto Cleanup;
- }
-
-#endif
+ /* Let's go! Start simulation */
+ CpuSimulate();
Cleanup:
BiosCleanup();
Modified: trunk/reactos/subsystems/ntvdm/ntvdm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/ntvdm.h?r…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/ntvdm.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/ntvdm.h [iso-8859-1] Sat Oct 4 13:36:17 2014
@@ -41,10 +41,17 @@
/* FUNCTIONS ******************************************************************/
#ifndef STANDALONE
+extern BOOLEAN AcceptCommands;
+extern HANDLE CommandThread;
extern ULONG SessionId;
#endif
extern HANDLE VdmTaskEvent;
+
+// Command line of NTVDM
+extern INT NtVdmArgc;
+extern WCHAR** NtVdmArgv;
+
/*
* Interface functions