2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: ROM Support Functions
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 /* INCLUDES *******************************************************************/
15 #include "cpu/callback.h"
20 /* PRIVATE FUNCTIONS **********************************************************/
23 OpenRomFile(IN PCSTR RomFileName
,
24 OUT PULONG RomSize OPTIONAL
)
29 /* Open the ROM image file */
30 hRomFile
= FileOpen(RomFileName
, &ulRomSize
);
32 /* If we failed, bail out */
33 if (hRomFile
== NULL
) return NULL
;
36 * The size of the ROM image file is at most 256kB. For instance,
37 * the SeaBIOS image, which includes also expansion ROMs inside it,
38 * covers the range C000:0000 to F000:FFFF .
40 if (ulRomSize
> 0x40000)
42 /* We failed, bail out */
43 DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)", ulRomSize
);
48 /* Success, return file handle and size if needed */
49 if (RomSize
) *RomSize
= ulRomSize
;
54 LoadRomFileByHandle(IN HANDLE RomFileHandle
,
60 * The size of the ROM image file is at most 256kB. For instance,
61 * the SeaBIOS image, which includes also expansion ROMs inside it,
62 * covers the range C000:0000 to F000:FFFF .
64 if (RomSize
> 0x40000)
66 DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)", RomSize
);
70 /* Attempt to load the ROM image file into memory */
71 return FileLoadByHandle(RomFileHandle
,
72 REAL_TO_PHYS(RomLocation
),
78 ComputeChecksum(IN ULONG RomLocation
,
81 ULONG RomLastAddress
= RomLocation
+ RomSize
;
82 UCHAR Sum
= 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum modulo 0x100.
84 while (RomLocation
< RomLastAddress
)
86 Sum
+= *(PUCHAR
)REAL_TO_PHYS(RomLocation
);
94 InitRomRange(IN PCALLBACK16 Context
,
99 ULONG Address
, AddressBoot
;
103 for (Address
= Start
; Address
< End
; Address
+= Increment
)
105 /* Does the ROM have a valid signature? */
106 if (*(PUSHORT
)REAL_TO_PHYS(Address
) == OPTION_ROM_SIGNATURE
)
108 /* Check the control sum of the ROM */
111 * If this is an adapter ROM (Start: C8000, End: E0000), its
112 * reported size is stored in byte 2 of the ROM.
114 * If this is an expansion ROM (Start: E0000, End: F0000),
115 * its real length is 64kB.
117 RomSize
= *(PUCHAR
)REAL_TO_PHYS(Address
+ 2) * 512;
118 if (Address
>= 0xE0000) RomSize
= 0x10000;
120 Checksum
= ComputeChecksum(Address
, RomSize
);
121 if (Checksum
== 0x00)
123 AddressBoot
= Address
+ 3;
124 DPRINT1("Going to run @ address 0x%p\n", AddressBoot
);
126 AddressBoot
= MAKELONG((AddressBoot
& 0xFFFF), (AddressBoot
& 0xF0000) >> 4);
127 // setDS((Address & 0xF0000) >> 4);
128 setDS((Address
& 0xFF000) >> 4);
129 RunCallback16(Context
, AddressBoot
);
130 // Call16((AddressBoot & 0xF0000) >> 4, (AddressBoot & 0xFFFF));
132 DPRINT1("Rom @ address 0x%p initialized\n", Address
);
136 DPRINT1("Rom @ address 0x%p has invalid checksum of 0x%02x\n", Address
, Checksum
);
142 /* PUBLIC FUNCTIONS ***********************************************************/
145 LoadBios(IN PCSTR BiosFileName
,
146 OUT PVOID
* BiosLocation OPTIONAL
,
147 OUT PULONG BiosSize OPTIONAL
)
151 ULONG ulBiosSize
= 0;
154 /* Open the BIOS image file */
155 hBiosFile
= OpenRomFile(BiosFileName
, &ulBiosSize
);
157 /* If we failed, bail out */
158 if (hBiosFile
== NULL
) return FALSE
;
160 /* BIOS location needs to be aligned on 32-bit boundary */
161 // (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - ulBiosSize)
162 pBiosLocation
= MEM_ALIGN_DOWN(TO_LINEAR(0xF000, 0xFFFF) + 1 - ulBiosSize
, sizeof(ULONG
));
164 /* Attempt to load the BIOS image file into memory */
165 Success
= LoadRomFileByHandle(hBiosFile
,
169 DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success
? "succeeded" : "failed", GetLastError());
171 /* Close the BIOS image file */
172 FileClose(hBiosFile
);
174 /* In case of success, return BIOS location and size if needed */
177 if (BiosLocation
) *BiosLocation
= pBiosLocation
;
178 if (BiosSize
) *BiosSize
= ulBiosSize
;
185 LoadRom(IN PCSTR RomFileName
,
186 IN PVOID RomLocation
,
187 OUT PULONG RomSize OPTIONAL
)
193 /* Open the ROM image file */
194 hRomFile
= OpenRomFile(RomFileName
, &ulRomSize
);
196 /* If we failed, bail out */
197 if (hRomFile
== NULL
) return FALSE
;
199 /* Attempt to load the ROM image file into memory */
200 Success
= LoadRomFileByHandle(hRomFile
,
204 DPRINT1("ROM loading %s ; GetLastError() = %u\n", Success
? "succeeded" : "failed", GetLastError());
206 /* Close the ROM image file and return */
209 /* In case of success, return ROM size if needed */
212 if (RomSize
) *RomSize
= ulRomSize
;
219 SearchAndInitRoms(IN PCALLBACK16 Context
)
221 /* Adapters ROMs -- Start: C8000, End: E0000, 2kB blocks */
222 InitRomRange(Context
, 0xC8000, 0xE0000, 0x0800);
224 /* Expansion ROM -- Start: E0000, End: F0000, 64kB block */
225 InitRomRange(Context
, 0xE0000, 0xEFFFF, 0x10000);