diff --git a/subsystems/ntvdm/bios/bios.c b/subsystems/ntvdm/bios/bios.c index 2c698d5dd7b..46d7c6055a1 100644 --- a/subsystems/ntvdm/bios/bios.c +++ b/subsystems/ntvdm/bios/bios.c @@ -11,92 +11,96 @@ #define NDEBUG #include "emulator.h" +#include "callback.h" + #include "bios.h" +#include "bop.h" +#include "rom.h" + /* PRIVATE VARIABLES **********************************************************/ static BOOLEAN Bios32Loaded = FALSE; +static CALLBACK16 __BiosContext; + +/* BOP Identifiers */ +#define BOP_BIOSINIT 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00 + // to let the virtual machine initialize itself + // the IVT and its hardware. + /* PRIVATE FUNCTIONS **********************************************************/ +static VOID WINAPI BiosInitBop(LPWORD Stack) +{ + /* Load the second part of the Windows NTVDM BIOS image */ + LPCWSTR BiosFileName = L"bios1.rom"; + PVOID BiosLocation = (PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000); + DWORD BiosSize = 0; + BOOLEAN Success; + + DPRINT1("You are loading Windows NTVDM BIOS!"); + + /* Initialize a private callback context */ + InitializeContext(&__BiosContext, BIOS_SEGMENT, 0x0000); + + Success = LoadRom(BiosFileName, BiosLocation, &BiosSize); + DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + if (Success == FALSE) return; + + // 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", + // 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)BiosLocation + BiosSize - 2), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0)); + + /* Initialize IVT and hardware */ + + /* Load VGA BIOS */ + // Success = LoadRom(L"v7vga.rom", (PVOID)0xC0000, &BiosSize); + // DPRINT1("VGA BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! ///////////////////// + + /* Load some ROMs */ + Success = LoadRom(L"boot.bin", (PVOID)0xE0000, &BiosSize); + DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + SearchAndInitRoms(&__BiosContext); +} + /* PUBLIC FUNCTIONS ***********************************************************/ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, IN HANDLE ConsoleInput, IN HANDLE ConsoleOutput) { + /* Register the BIOS support BOPs */ + RegisterBop(BOP_BIOSINIT, BiosInitBop); + if (BiosFileName) { - BOOL Success; - HANDLE hBiosFile; - DWORD BiosSize; - PVOID BiosLocation; + PVOID BiosLocation = NULL; + DWORD BiosSize = 0; + BOOLEAN Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize); - /* 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; - } - - /* 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)); - - 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", - 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)); - - /* Attempt to load the BIOS file into memory */ - SetLastError(0); // For debugging purposes - Success = ReadFile(hBiosFile, - REAL_TO_PHYS(BiosLocation), - BiosSize, - &BiosSize, - NULL); DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); - /* Close the BIOS file */ - CloseHandle(hBiosFile); + if (Success == FALSE) return FALSE; 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", @@ -112,10 +116,10 @@ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, *(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)); + (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0)); DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", TO_LINEAR(getCS(), getIP()), diff --git a/subsystems/ntvdm/bios/bios.h b/subsystems/ntvdm/bios/bios.h index 93e8660c7fb..e71d899ecff 100644 --- a/subsystems/ntvdm/bios/bios.h +++ b/subsystems/ntvdm/bios/bios.h @@ -16,14 +16,11 @@ /* DEFINES ********************************************************************/ -#define ROM_AREA_START 0xE0000 -#define ROM_AREA_END 0xFFFFF +// #define BDA_SEGMENT 0x40 +#define BIOS_SEGMENT 0xF000 #if 0 -#define BDA_SEGMENT 0x40 -#define BIOS_SEGMENT 0xF000 - /* * BIOS Data Area at 0040:XXXX * diff --git a/subsystems/ntvdm/bios/bios32/bios32.c b/subsystems/ntvdm/bios/bios32/bios32.c index a71ec25427a..d5a84c89d3c 100644 --- a/subsystems/ntvdm/bios/bios32/bios32.c +++ b/subsystems/ntvdm/bios/bios32/bios32.c @@ -13,6 +13,8 @@ #include "emulator.h" #include "callback.h" +#include "../rom.h" +#include "../bios.h" #include "bios32.h" #include "io.h" @@ -355,8 +357,22 @@ static VOID InitializeBiosInt32(VOID) BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput, IN HANDLE ConsoleOutput) { + BOOLEAN Success; UCHAR Low, High; + /* Disable interrupts */ + setIF(0); + + /* Initialize the stack */ + // That's what says IBM... (stack at 30:00FF going downwards) + // setSS(0x0000); + // setSP(0x0400); + setSS(0x0050); // Stack at 50:0400, going downwards + setSP(0x0400); + + /* Set data segment */ + setDS(BDA_SEGMENT); + /* Initialize the BDA */ Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0); Bda->EquipmentList = BIOS_EQUIPMENT_LIST; @@ -389,6 +405,14 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput, /* Enable interrupts */ setIF(1); + ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! ///////////////////// + + /* Load some ROMs */ + Success = LoadRom(L"boot.bin", (PVOID)0xE0000, NULL); + DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + SearchAndInitRoms(&BiosContext); + /* We are done */ return TRUE; } diff --git a/subsystems/ntvdm/bios/bios32/bios32.h b/subsystems/ntvdm/bios/bios32/bios32.h index 8f153818203..4f9f120485c 100644 --- a/subsystems/ntvdm/bios/bios32/bios32.h +++ b/subsystems/ntvdm/bios/bios32/bios32.h @@ -31,11 +31,8 @@ #define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now -#define ROM_AREA_START 0xE0000 -#define ROM_AREA_END 0xFFFFF - #define BDA_SEGMENT 0x40 -#define BIOS_SEGMENT 0xF000 +// #define BIOS_SEGMENT 0xF000 /* * BIOS Data Area at 0040:XXXX