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