[NTVDM]
[reactos.git] / reactos / 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 "cpu/callback.h"
15 #include "cpu/bop.h"
16
17 #include "bios.h"
18 #include "bios32/bios32.h"
19
20 #include "rom.h"
21
22 #include "io.h"
23 #include "hardware/cmos.h"
24
25 /* DEFINES ********************************************************************/
26
27 /* BOP Identifiers */
28 #define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00
29 // to let the virtual machine initialize itself
30 // the IVT and its hardware.
31 #define BOP_EQUIPLIST 0x11
32 #define BOP_GETMEMSIZE 0x12
33
34 /* PRIVATE VARIABLES **********************************************************/
35
36 static BOOLEAN Bios32Loaded = FALSE;
37
38 PBIOS_DATA_AREA Bda;
39 PBIOS_CONFIG_TABLE Bct;
40
41 /* PRIVATE FUNCTIONS **********************************************************/
42
43 /* PUBLIC FUNCTIONS ***********************************************************/
44
45 VOID WINAPI BiosEquipmentService(LPWORD Stack)
46 {
47 /* Return the equipment list */
48 setAX(Bda->EquipmentList);
49 }
50
51 VOID WINAPI BiosGetMemorySize(LPWORD Stack)
52 {
53 /* Return the conventional memory size in kB, typically 640 kB */
54 setAX(Bda->MemorySize);
55 }
56
57 BOOLEAN
58 BiosInitialize(IN LPCSTR BiosFileName)
59 {
60 BOOLEAN Success = FALSE;
61
62 /* Disable interrupts */
63 setIF(0);
64
65 /* Initialize the BDA and the BCT pointers */
66 Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0x0000);
67 // The BCT is found at F000:E6F5 for 100% compatible BIOSes.
68 Bct = (PBIOS_CONFIG_TABLE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5);
69
70 /**** HACK! HACK! for Windows NTVDM BIOS ****/
71 // WinNtVdmBiosSupportInitialize();
72
73 // /* Register the BIOS support BOPs */
74 // RegisterBop(BOP_EQUIPLIST , BiosEquipmentService);
75 // RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize);
76
77 if (BiosFileName && BiosFileName[0] != '\0')
78 {
79 PVOID BiosLocation = NULL;
80 DWORD BiosSize = 0;
81
82 Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize);
83 DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
84
85 if (!Success) return FALSE;
86
87 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"
88 L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
89 BiosLocation,
90 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
91 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
92 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
93 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
94 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
95 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
96 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
97 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
98 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
99 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
100
101 (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2),
102 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2),
103 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1),
104 *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0));
105
106 DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
107 TO_LINEAR(getCS(), getIP()),
108 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 0),
109 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 1),
110 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 2),
111 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 3),
112 *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 4));
113
114 /* Boot it up */
115
116 /*
117 * The CPU is already in reset-mode so that
118 * CS:IP points to F000:FFF0 as required.
119 */
120 DisplayMessage(L"CS=0x%p ; IP=0x%p", getCS(), getIP());
121 // setCS(0xF000);
122 // setIP(0xFFF0);
123
124 Success = TRUE;
125 }
126 else
127 {
128 Success = Bios32Loaded = Bios32Initialize();
129 }
130
131 // /* Enable interrupts */
132 // setIF(1);
133
134 return Success;
135 }
136
137 VOID
138 BiosCleanup(VOID)
139 {
140 if (Bios32Loaded) Bios32Cleanup();
141 }
142
143 /* EOF */