9ee04e264d710c61e5465a1983352018df5e073f
[reactos.git] / subsystems / mvdm / ntvdm / bios / bios.c
1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/bios/bios.c
5 * PURPOSE: VDM BIOS Support Library
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "ntvdm.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 #include "emulator.h"
17 #include "cpu/callback.h"
18 #include "cpu/bop.h"
19
20 #include "bios.h"
21 #include "bios32/bios32.h"
22 #include "rom.h"
23 #include "umamgr.h"
24
25 #include "io.h"
26 #include "hardware/cmos.h"
27
28 #include <stdlib.h>
29
30 /* DEFINES ********************************************************************/
31
32 /* BOP Identifiers */
33 #define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
34 // to let the virtual machine perform the POST.
35 #define BOP_EQUIPLIST 0x11
36 #define BOP_GETMEMSIZE 0x12
37
38 /* PRIVATE VARIABLES **********************************************************/
39
40 static BOOLEAN Bios32Loaded = FALSE;
41
42 PBIOS_DATA_AREA Bda;
43 PBIOS_CONFIG_TABLE Bct;
44
45 /* PRIVATE FUNCTIONS **********************************************************/
46
47 /* PUBLIC FUNCTIONS ***********************************************************/
48
49 VOID WINAPI
50 WinNtVdmBiosReset(LPWORD Stack)
51 {
52 DisplayMessage(L"You are loading Windows NTVDM BIOS!\n");
53 // Bios32Post(Stack);
54
55 DisplayMessage(L"ReactOS NTVDM doesn't support Windows NTVDM BIOS at the moment. The VDM will shut down.");
56 EmulatorTerminate();
57 }
58
59 BOOLEAN
60 BiosInitialize(IN LPCSTR BiosFileName,
61 IN LPCSTR RomFiles OPTIONAL)
62 {
63 BOOLEAN Success = FALSE;
64 BOOLEAN Success2 = FALSE;
65 LPCSTR RomFile;
66 LPSTR ptr;
67 ULONG RomAddress;
68 CHAR RomFileName[MAX_PATH + 10 + 1];
69
70 /* Disable interrupts */
71 setIF(0);
72
73 /* Initialize the BDA and the BCT pointers */
74 Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT , 0x0000);
75 // The BCT is found at F000:E6F5 for 100% compatible BIOSes.
76 Bct = (PBIOS_CONFIG_TABLE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5);
77
78 /* Register the BIOS support BOPs */
79 RegisterBop(BOP_RESET, WinNtVdmBiosReset); // Needed for Windows NTVDM (SoftPC) BIOS.
80 RegisterBop(BOP_EQUIPLIST , BiosEquipmentService); // Needed by Windows NTVDM (SoftPC) BIOS
81 RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize); // and also NTDOS!!
82
83 if (BiosFileName == NULL)
84 {
85 Success = Bios32Loaded = Bios32Initialize();
86 }
87 else if (BiosFileName[0] != '\0')
88 {
89 PVOID BiosLocation = NULL;
90
91 Success = LoadBios(BiosFileName, &BiosLocation, NULL);
92 DPRINT1("BIOS file '%s' loading %s at address 0x%08x; GetLastError() = %u\n",
93 BiosFileName, Success ? "succeeded" : "failed", BiosLocation, GetLastError());
94 }
95 else // if (BiosFileName[0] == '\0')
96 {
97 /* Do nothing */
98 Success = TRUE;
99 }
100
101 /* Bail out now if we failed to load any BIOS file */
102 if (!Success) return FALSE;
103
104 /* Load optional ROMs */
105 if (RomFiles)
106 {
107 RomFile = RomFiles;
108 while (*RomFile)
109 {
110 strncpy(RomFileName, RomFile, ARRAYSIZE(RomFileName));
111 RomFileName[ARRAYSIZE(RomFileName)-1] = '\0';
112
113 ptr = strchr(RomFileName, '|'); // Since '|' is forbidden as a valid file name, we use it as a separator for the ROM address.
114 if (!ptr) goto Skip;
115 *ptr++ = '\0';
116
117 RomAddress = strtoul(ptr, NULL, 0); // ROM segment
118 RomAddress <<= 4; // Convert to real address
119 if (RomAddress == 0) goto Skip;
120
121 Success2 = LoadRom(RomFileName, (PVOID)RomAddress, NULL);
122 DPRINT1("ROM file '%s' loading %s at address 0x%08x; GetLastError() = %u\n",
123 RomFileName, Success2 ? "succeeded" : "failed", RomAddress, GetLastError());
124
125 Skip:
126 RomFile += strlen(RomFile) + 1;
127 }
128 }
129
130 /*
131 * Boot it up.
132 * The CPU is already in reset-mode so that
133 * CS:IP points to F000:FFF0 as required.
134 */
135 // DisplayMessage(L"CS:IP=%04X:%04X", getCS(), getIP());
136 // setCS(0xF000);
137 // setIP(0xFFF0);
138
139 // /* Enable interrupts */
140 // setIF(1);
141
142 /* Initialize the Upper Memory Area Manager */
143 if (!UmaMgrInitialize())
144 {
145 wprintf(L"FATAL: Failed to initialize the UMA manager.\n");
146 return FALSE;
147 }
148
149 return Success;
150 }
151
152 VOID
153 BiosCleanup(VOID)
154 {
155 UmaMgrCleanup();
156
157 if (Bios32Loaded) Bios32Cleanup();
158 }
159
160 /* EOF */