2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: Virtual DOS Machine
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
11 BOOLEAN VdmRunning
= TRUE
;
12 LPVOID BaseAddress
= NULL
;
13 LPCWSTR ExceptionName
[] =
20 L
"Bound Range Exceeded",
25 VOID
DisplayMessage(LPCWSTR Format
, ...)
30 va_start(Parameters
, Format
);
31 _vsnwprintf(Buffer
, 256, Format
, Parameters
);
32 MessageBox(NULL
, Buffer
, L
"NTVDM Subsystem", MB_OK
);
36 BOOL WINAPI
ConsoleCtrlHandler(DWORD ControlType
)
41 case CTRL_BREAK_EVENT
:
43 /* Perform interrupt 0x23 */
44 EmulatorInterrupt(0x23);
48 /* Stop the VDM if the user logs out or closes the console */
55 INT
wmain(INT argc
, WCHAR
*argv
[])
58 CHAR CommandLine
[128];
59 DWORD CurrentTickCount
, LastTickCount
= 0, Cycles
= 0, LastCyclePrintout
= 0;
60 LARGE_INTEGER Frequency
, LastTimerTick
, Counter
;
63 /* Set the handler routine */
64 SetConsoleCtrlHandler(ConsoleCtrlHandler
, TRUE
);
66 /* The DOS command line must be ASCII */
67 WideCharToMultiByte(CP_ACP
, 0, GetCommandLine(), -1, CommandLine
, 128, NULL
, NULL
);
69 if (!EmulatorInitialize()) return 1;
71 /* Initialize the performance counter (needed for hardware timers) */
72 if (!QueryPerformanceFrequency(&Frequency
))
74 wprintf(L
"FATAL: Performance counter not available\n");
78 /* Initialize the system BIOS */
79 if (!BiosInitialize())
81 wprintf(L
"FATAL: Failed to initialize the VDM BIOS.\n");
85 /* Initialize the VDM DOS kernel */
88 wprintf(L
"FATAL: Failed to initialize the VDM DOS kernel.\n");
92 /* Start the process from the command line */
93 if (!DosCreateProcess(CommandLine
, 0))
95 DisplayMessage(L
"Could not start program: %S", CommandLine
);
99 /* Set the last timer tick to the current time */
100 QueryPerformanceCounter(&LastTimerTick
);
105 /* Get the current number of ticks */
106 CurrentTickCount
= GetTickCount();
108 /* Get the current performance counter value */
109 QueryPerformanceCounter(&Counter
);
111 /* Get the number of PIT ticks that have passed */
112 TimerTicks
= ((Counter
.QuadPart
- LastTimerTick
.QuadPart
)
113 * PIT_BASE_FREQUENCY
) / Frequency
.QuadPart
;
116 for (i
= 0; i
< TimerTicks
; i
++) PitDecrementCount();
117 LastTimerTick
= Counter
;
119 /* Check for console input events every millisecond */
120 if (CurrentTickCount
!= LastTickCount
)
122 CheckForInputEvents();
123 LastTickCount
= CurrentTickCount
;
126 /* Continue CPU emulation */
127 for (i
= 0; i
< STEPS_PER_CYCLE
; i
++) EmulatorStep();
129 Cycles
+= STEPS_PER_CYCLE
;
130 if ((CurrentTickCount
- LastCyclePrintout
) >= 1000)
132 DPRINT1("NTVDM: %d Instructions Per Second\n", Cycles
);
133 LastCyclePrintout
= CurrentTickCount
;