[NTVDM]
[reactos.git] / subsystems / ntvdm / bios / bios.c
1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: bios.c
5 * PURPOSE: VDM BIOS Support Library
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #define NDEBUG
12
13 #include "emulator.h"
14 #include "callback.h"
15
16 #include "bios.h"
17
18 #include "bop.h"
19 #include "rom.h"
20
21 /* PRIVATE VARIABLES **********************************************************/
22
23 static BOOLEAN Bios32Loaded = FALSE;
24
25 static CALLBACK16 __BiosContext;
26
27 /* BOP Identifiers */
28 #define BOP_BIOSINIT 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
29 // to let the virtual machine initialize itself
30 // the IVT and its hardware.
31
32 /* PRIVATE FUNCTIONS **********************************************************/
33
34 static VOID WINAPI BiosInitBop(LPWORD Stack)
35 {
36 /* Load the second part of the Windows NTVDM BIOS image */
37 LPCWSTR BiosFileName = L"bios1.rom";
38 PVOID BiosLocation = (PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000);
39 DWORD BiosSize = 0;
40 BOOLEAN Success;
41
42 DPRINT1("You are loading Windows NTVDM BIOS!");
43
44 /* Initialize a private callback context */
45 InitializeContext(&__BiosContext, BIOS_SEGMENT, 0x0000);
46
47 Success = LoadRom(BiosFileName, BiosLocation, &BiosSize);
48 DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
49
50 if (Success == FALSE) return;
51
52 // DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
53 // L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
54 // BiosLocation,
55 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
56 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
57 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
58 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
59 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
60 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
61 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
62 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
63 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
64 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
65
66 // (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
67 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
68 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
69 // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
70
71 /* Initialize IVT and hardware */
72
73 /* Load VGA BIOS */
74 // Success = LoadRom(L"v7vga.rom", (PVOID)0xC0000, &BiosSize);
75 // DPRINT1("VGA BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
76
77 ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! /////////////////////
78
79 /* Load some ROMs */
80 Success = LoadRom(L"boot.bin", (PVOID)0xE0000, &BiosSize);
81 DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
82
83 SearchAndInitRoms(&__BiosContext);
84 }
85
86 /* PUBLIC FUNCTIONS ***********************************************************/
87
88 BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName,
89 IN HANDLE ConsoleInput,
90 IN HANDLE ConsoleOutput)
91 {
92 /* Register the BIOS support BOPs */
93 RegisterBop(BOP_BIOSINIT, BiosInitBop);
94
95 if (BiosFileName)
96 {
97 PVOID BiosLocation = NULL;
98 DWORD BiosSize = 0;
99 BOOLEAN Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize);
100
101 DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
102
103 if (Success == FALSE) return FALSE;
104
105 DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
106 L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
107 BiosLocation,
108 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
109 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
110 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
111 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
112 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
113 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
114 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
115 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
116 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
117 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
118
119 (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
120 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
121 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
122 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
123
124 DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
125 TO_LINEAR(getCS(), getIP()),
126 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 0),
127 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 1),
128 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 2),
129 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 3),
130 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 4));
131
132 /* Boot it up */
133
134 /*
135 * The CPU is already in reset-mode so that
136 * CS:IP points to F000:FFF0 as required.
137 */
138 DisplayMessage(L"CS=0x%p ; IP=0x%p", getCS(), getIP());
139 // setCS(0xF000);
140 // setIP(0xFFF0);
141
142 return TRUE;
143 }
144 else
145 {
146 Bios32Loaded = Bios32Initialize(ConsoleInput, ConsoleOutput);
147 return Bios32Loaded;
148 }
149 }
150
151 VOID BiosCleanup(VOID)
152 {
153 if (Bios32Loaded) Bios32Cleanup();
154 }
155
156 /* EOF */