VOID InitializeInt32(VOID) { /* Register the Control BOP */ RegisterBop(BOP_CONTROL, ControlBop); }
VOID XmsCleanup(VOID) { RegisterBop(BOP_XMS, NULL); DosDeleteDevice(Node); }
static VOID WINAPI DosStart(LPWORD Stack) { #ifdef STANDALONE DWORD Result; CHAR ApplicationName[MAX_PATH]; CHAR CommandLine[DOS_CMDLINE_LENGTH]; #endif DPRINT("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, SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0)); if (Result != ERROR_SUCCESS) { DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result); goto Quit; } #endif Quit: /* Stop the VDM */ EmulatorTerminate(); }
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 DPRINT("DosInitialize('%s')\n", DosKernelFileName); /* Register the DOS BOPs */ RegisterBop(BOP_DOS, DosSystemBop ); RegisterBop(BOP_CMD, DosCmdInterpreterBop); if (DosKernelFileName && DosKernelFileName[0] != '\0') { HANDLE hDosBios; ULONG ulDosBiosSize = 0; /* Open the DOS BIOS file */ hDosBios = FileOpen(DosKernelFileName, &ulDosBiosSize); /* If we failed, bail out */ if (hDosBios == NULL) goto QuitCustom; /* Attempt to load the DOS BIOS into memory */ Success = FileLoadByHandle(hDosBios, REAL_TO_PHYS(TO_LINEAR(0x0070, 0x0000)), ulDosBiosSize, &ulDosBiosSize); DPRINT1("DOS BIOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n", (Success ? "succeeded" : "failed"), 0x0070, 0x0000, ulDosBiosSize, GetLastError()); /* Close the DOS BIOS file */ FileClose(hDosBios); 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 { 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); } }
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput) { /* Allocate memory for the 16-bit address space */ BaseAddress = HeapAlloc(GetProcessHeap(), /*HEAP_ZERO_MEMORY*/ 0, MAX_ADDRESS); if (BaseAddress == NULL) { wprintf(L"FATAL: Failed to allocate VDM memory.\n"); return FALSE; } /* * For diagnostics purposes, we fill the memory with INT 0x03 codes * so that if a program wants to execute random code in memory, we can * retrieve the exact CS:IP where the problem happens. */ RtlFillMemory(BaseAddress, MAX_ADDRESS, 0xCC); /* Initialize I/O ports */ /* Initialize RAM */ /* Initialize the CPU */ /* Initialize the internal clock */ if (!ClockInitialize()) { wprintf(L"FATAL: Failed to initialize the clock\n"); return FALSE; } /* Initialize the CPU */ CpuInitialize(); // Fast486Initialize(&EmulatorContext, // EmulatorReadMemory, // EmulatorWriteMemory, // EmulatorReadIo, // EmulatorWriteIo, // NULL, // EmulatorBiosOperation, // EmulatorIntAcknowledge, // NULL /* TODO: Use a TLB */); /* Initialize DMA */ /* Initialize the PIC, the PIT, the CMOS and the PC Speaker */ PicInitialize(); PitInitialize(); CmosInitialize(); SpeakerInitialize(); /* Set output functions */ PitSetOutFunction(0, NULL, PitChan0Out); PitSetOutFunction(1, NULL, PitChan1Out); PitSetOutFunction(2, NULL, PitChan2Out); /* Register the I/O Ports */ RegisterIoPort(CONTROL_SYSTEM_PORT61H, Port61hRead, Port61hWrite); /* Set the console input mode */ // FIXME: Activate ENABLE_WINDOW_INPUT when we will want to perform actions // upon console window events (screen buffer resize, ...). SetConsoleMode(ConsoleInput, ENABLE_PROCESSED_INPUT /* | ENABLE_WINDOW_INPUT */); // SetConsoleMode(ConsoleOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); /**/EnableExtraHardware(ConsoleInput);/**/ /* Initialize the PS/2 port */ PS2Initialize(); /* Initialize the keyboard and mouse and connect them to their PS/2 ports */ KeyboardInit(0); MouseInit(1); /**************** ATTACH INPUT WITH CONSOLE *****************/ /* Start the input thread */ InputThread = CreateThread(NULL, 0, &PumpConsoleInput, ConsoleInput, 0, NULL); if (InputThread == NULL) { DisplayMessage(L"Failed to create the console input thread."); return FALSE; } /************************************************************/ /* Initialize the VGA */ if (!VgaInitialize(ConsoleOutput)) { DisplayMessage(L"Failed to initialize VGA support."); return FALSE; } /* Initialize the software callback system and register the emulator BOPs */ InitializeInt32(); RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop); // RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop); /* Initialize VDD support */ VDDSupInitialize(); return TRUE; }
BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput) { USHORT i; /* Initialize memory */ if (!MemInitialize()) { wprintf(L"Memory initialization failed.\n"); return FALSE; } /* Initialize I/O ports */ /* Initialize RAM */ /* Initialize the CPU */ /* Initialize the internal clock */ if (!ClockInitialize()) { wprintf(L"FATAL: Failed to initialize the clock\n"); EmulatorCleanup(); return FALSE; } /* Initialize the CPU */ CpuInitialize(); /* Initialize DMA */ DmaInitialize(); /* Initialize PIC, PIT, CMOS, PC Speaker and PS/2 */ PicInitialize(); PitInitialize(); PitSetOutFunction(0, NULL, PitChan0Out); PitSetOutFunction(1, NULL, PitChan1Out); PitSetOutFunction(2, NULL, PitChan2Out); CmosInitialize(); SpeakerInitialize(); PpiInitialize(); PS2Initialize(); /* Initialize the keyboard and mouse and connect them to their PS/2 ports */ KeyboardInit(0); MouseInit(1); /**************** ATTACH INPUT WITH CONSOLE *****************/ /* Create the task event */ VdmTaskEvent = CreateEventW(NULL, TRUE, FALSE, NULL); ASSERT(VdmTaskEvent != NULL); /* Start the input thread */ InputThread = CreateThread(NULL, 0, &ConsoleEventThread, ConsoleInput, 0, NULL); if (InputThread == NULL) { wprintf(L"FATAL: Failed to create the console input thread.\n"); EmulatorCleanup(); return FALSE; } ResumeEventThread(); /************************************************************/ /* Initialize the VGA */ if (!VgaInitialize(ConsoleOutput)) { wprintf(L"FATAL: Failed to initialize VGA support.\n"); EmulatorCleanup(); return FALSE; } /* Initialize the disk controller */ if (!DiskCtrlInitialize()) { wprintf(L"FATAL: Failed to completely initialize the disk controller.\n"); EmulatorCleanup(); return FALSE; } /* Mount the available floppy disks */ for (i = 0; i < ARRAYSIZE(GlobalSettings.FloppyDisks); ++i) { if (GlobalSettings.FloppyDisks[i].Length != 0 && GlobalSettings.FloppyDisks[i].Buffer && GlobalSettings.FloppyDisks[i].Buffer != '\0') { if (!MountDisk(FLOPPY_DISK, i, GlobalSettings.FloppyDisks[i].Buffer, FALSE)) { DPRINT1("Failed to mount floppy disk file '%wZ'.\n", &GlobalSettings.FloppyDisks[i]); RtlFreeUnicodeString(&GlobalSettings.FloppyDisks[i]); RtlInitEmptyUnicodeString(&GlobalSettings.FloppyDisks[i], NULL, 0); } } } /* * Mount the available hard disks. Contrary to floppies, failing * mounting a hard disk is considered as an unrecoverable error. */ for (i = 0; i < ARRAYSIZE(GlobalSettings.HardDisks); ++i) { if (GlobalSettings.HardDisks[i].Length != 0 && GlobalSettings.HardDisks[i].Buffer && GlobalSettings.HardDisks[i].Buffer != L'\0') { if (!MountDisk(HARD_DISK, i, GlobalSettings.HardDisks[i].Buffer, FALSE)) { wprintf(L"FATAL: Failed to mount hard disk file '%wZ'.\n", &GlobalSettings.HardDisks[i]); EmulatorCleanup(); return FALSE; } } } /* Refresh the menu state */ UpdateVdmMenuDisks(); /* Initialize the software callback system and register the emulator BOPs */ InitializeInt32(); RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop); // RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop); /* Initialize VDD support */ VDDSupInitialize(); return TRUE; }