xref: /reactos/subsystems/mvdm/ntvdm/bios/bios.c (revision ebaf247c)
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_PTR 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 */
161