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