40a5cddfd83c6cff3ef66e472d34474b5e3f51a9
[reactos.git] / subsystems / ntvdm / ntvdm.c
1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: ntvdm.c
5 * PURPOSE: Virtual DOS Machine
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 #include "ntvdm.h"
10
11 BOOLEAN VdmRunning = TRUE;
12 LPVOID BaseAddress = NULL;
13 LPCWSTR ExceptionName[] =
14 {
15 L"Division By Zero",
16 L"Debug",
17 L"Unexpected Error",
18 L"Breakpoint",
19 L"Integer Overflow",
20 L"Bound Range Exceeded",
21 L"Invalid Opcode",
22 L"FPU Not Available"
23 };
24
25 VOID DisplayMessage(LPCWSTR Format, ...)
26 {
27 WCHAR Buffer[256];
28 va_list Parameters;
29
30 va_start(Parameters, Format);
31 _vsnwprintf(Buffer, 256, Format, Parameters);
32 MessageBox(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
33 va_end(Parameters);
34 }
35
36 BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
37 {
38 switch (ControlType)
39 {
40 case CTRL_C_EVENT:
41 case CTRL_BREAK_EVENT:
42 {
43 /* Perform interrupt 0x23 */
44 EmulatorInterrupt(0x23);
45 }
46 default:
47 {
48 /* Stop the VDM if the user logs out or closes the console */
49 VdmRunning = FALSE;
50 }
51 }
52 return TRUE;
53 }
54
55 INT wmain(INT argc, WCHAR *argv[])
56 {
57 INT i;
58 BOOLEAN PrintUsage = TRUE;
59 CHAR CommandLine[128];
60
61 /* Set the handler routine */
62 SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
63
64 /* Parse the command line arguments */
65 for (i = 1; i < argc; i++)
66 {
67 if (argv[i][0] != L'-' && argv[i][0] != L'/') continue;
68
69 switch (argv[i][1])
70 {
71 case L'f':
72 case L'F':
73 {
74 if (argv[i+1] != NULL)
75 {
76 /* The DOS command line must be ASCII */
77 WideCharToMultiByte(CP_ACP, 0, argv[i+1], -1, CommandLine, 128, NULL, NULL);
78
79 /* This is the only mandatory parameter */
80 PrintUsage = FALSE;
81 }
82 break;
83 }
84 default:
85 {
86 wprintf(L"Unknown option: %s", argv[i]);
87 }
88 }
89 }
90
91 if (PrintUsage)
92 {
93 wprintf(L"ReactOS Virtual DOS Machine\n\n");
94 wprintf(L"Usage: NTVDM /F <PROGRAM>\n");
95 return 0;
96 }
97
98 if (!EmulatorInitialize()) return 1;
99
100 /* Initialize the system BIOS */
101 if (!BiosInitialize())
102 {
103 wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
104 goto Cleanup;
105 }
106
107 /* Initialize the VDM DOS kernel */
108 if (!DosInitialize())
109 {
110 wprintf(L"FATAL: Failed to initialize the VDM DOS kernel.\n");
111 goto Cleanup;
112 }
113
114 /* Start the process from the command line */
115 if (!DosCreateProcess(CommandLine, 0))
116 {
117 DisplayMessage(L"Could not start program: %S", CommandLine);
118 return -1;
119 }
120
121 /* Main loop */
122 while (VdmRunning) EmulatorStep();
123
124 Cleanup:
125 EmulatorCleanup();
126
127 return 0;
128 }
129
130 /* EOF */