2013-06-17 00:00:36 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Virtual DOS Machine
|
|
|
|
* FILE: bios.c
|
2014-02-17 22:20:03 +00:00
|
|
|
* PURPOSE: VDM BIOS Support Library
|
|
|
|
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
2013-06-17 00:00:36 +00:00
|
|
|
*/
|
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* INCLUDES *******************************************************************/
|
2013-06-17 00:00:36 +00:00
|
|
|
|
2013-07-22 13:51:26 +00:00
|
|
|
#define NDEBUG
|
|
|
|
|
2014-02-17 22:50:41 +00:00
|
|
|
#include "emulator.h"
|
2013-11-09 22:15:40 +00:00
|
|
|
#include "bios.h"
|
2013-11-09 23:01:11 +00:00
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* PRIVATE VARIABLES **********************************************************/
|
|
|
|
|
2014-02-17 22:20:03 +00:00
|
|
|
static BOOLEAN Bios32Loaded = FALSE;
|
2013-07-15 01:37:38 +00:00
|
|
|
|
2013-08-05 23:20:25 +00:00
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
2013-06-26 22:58:41 +00:00
|
|
|
|
2014-01-25 00:21:51 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
2013-07-05 01:31:50 +00:00
|
|
|
|
2014-02-17 22:20:03 +00:00
|
|
|
BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName,
|
|
|
|
IN HANDLE ConsoleInput,
|
|
|
|
IN HANDLE ConsoleOutput)
|
2013-06-21 00:47:07 +00:00
|
|
|
{
|
2014-02-17 22:50:41 +00:00
|
|
|
if (BiosFileName)
|
|
|
|
{
|
|
|
|
BOOL Success;
|
|
|
|
HANDLE hBiosFile;
|
|
|
|
DWORD BiosSize;
|
2014-02-23 20:40:09 +00:00
|
|
|
PVOID BiosLocation;
|
2014-02-17 22:50:41 +00:00
|
|
|
|
|
|
|
/* Open the BIOS file */
|
|
|
|
SetLastError(0); // For debugging purposes
|
|
|
|
hBiosFile = CreateFileW(BiosFileName,
|
|
|
|
GENERIC_READ,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
NULL);
|
|
|
|
DPRINT1("BIOS opening %s ; GetLastError() = %u\n", hBiosFile != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
|
|
|
|
|
|
|
|
/* If we failed, bail out */
|
|
|
|
if (hBiosFile == INVALID_HANDLE_VALUE) return FALSE;
|
|
|
|
|
|
|
|
/* OK, we have a handle to the BIOS file */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Retrieve the size of the file. Since the size of the BIOS file
|
|
|
|
* should be at most 64kB, we just use GetFileSize.
|
|
|
|
*/
|
|
|
|
BiosSize = GetFileSize(hBiosFile, NULL);
|
|
|
|
if (BiosSize == INVALID_FILE_SIZE && GetLastError() != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
/* We failed, return failure */
|
|
|
|
|
|
|
|
/* Close the BIOS file */
|
|
|
|
CloseHandle(hBiosFile);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-02-23 20:40:09 +00:00
|
|
|
/* BIOS location needs to be aligned on 32-bit boundary */
|
|
|
|
/* (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - BiosSize) */
|
|
|
|
BiosLocation = (PVOID)MEM_ALIGN_DOWN((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) + 1 - BiosSize, sizeof(ULONG));
|
|
|
|
|
2014-02-17 22:50:41 +00:00
|
|
|
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"
|
|
|
|
L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
|
2014-02-23 20:40:09 +00:00
|
|
|
BiosLocation,
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
|
|
|
|
|
|
|
|
(PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) - 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 1),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 0));
|
2014-02-17 22:50:41 +00:00
|
|
|
|
|
|
|
/* Attempt to load the BIOS file into memory */
|
|
|
|
SetLastError(0); // For debugging purposes
|
|
|
|
Success = ReadFile(hBiosFile,
|
2014-02-23 20:40:09 +00:00
|
|
|
REAL_TO_PHYS(BiosLocation),
|
2014-02-17 22:50:41 +00:00
|
|
|
BiosSize,
|
|
|
|
&BiosSize,
|
|
|
|
NULL);
|
|
|
|
DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
|
|
|
|
|
|
|
/* Close the BIOS file */
|
|
|
|
CloseHandle(hBiosFile);
|
|
|
|
|
|
|
|
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"
|
|
|
|
L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x",
|
2014-02-23 20:40:09 +00:00
|
|
|
BiosLocation,
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8),
|
|
|
|
*(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9),
|
|
|
|
|
|
|
|
(PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) - 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 1),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 0));
|
2014-02-17 22:50:41 +00:00
|
|
|
|
|
|
|
DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
|
|
|
|
TO_LINEAR(getCS(), getIP()),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 0),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 1),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 2),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 3),
|
|
|
|
*(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(getCS(), getIP()) + 4));
|
|
|
|
|
|
|
|
/* Boot it up */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The CPU is already in reset-mode so that
|
|
|
|
* CS:IP points to F000:FFF0 as required.
|
|
|
|
*/
|
|
|
|
DisplayMessage(L"CS=0x%p ; IP=0x%p", getCS(), getIP());
|
|
|
|
// setCS(0xF000);
|
|
|
|
// setIP(0xFFF0);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Bios32Loaded = Bios32Initialize(ConsoleInput, ConsoleOutput);
|
|
|
|
return Bios32Loaded;
|
|
|
|
}
|
2014-01-25 00:21:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID BiosCleanup(VOID)
|
|
|
|
{
|
2014-02-17 22:20:03 +00:00
|
|
|
if (Bios32Loaded) Bios32Cleanup();
|
2013-06-21 00:47:07 +00:00
|
|
|
}
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* EOF */
|