From 679980a06c67bd228f0eadea7716cb6df9845b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 23 Feb 2014 20:40:09 +0000 Subject: [PATCH] [NTVDM] - BIOS location must be aligned on 32bit boundaries (or 16, I have to check). This fixes BIOS images loading when they miss a (null) byte to make them (e.g.) 8192 bytes long (example: the BIOS image of windows ntvdm). - Add useful alignment (and others) macros. svn path=/branches/ntvdm/; revision=62312 --- subsystems/ntvdm/CMakeLists.txt | 2 +- subsystems/ntvdm/bios/bios.c | 68 +++++++++++++++++---------------- subsystems/ntvdm/callback.c | 3 -- subsystems/ntvdm/emulator.h | 6 +++ 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/subsystems/ntvdm/CMakeLists.txt b/subsystems/ntvdm/CMakeLists.txt index 4351ef56005..f2deea5ead8 100644 --- a/subsystems/ntvdm/CMakeLists.txt +++ b/subsystems/ntvdm/CMakeLists.txt @@ -20,9 +20,9 @@ list(APPEND SOURCE dos/dos32krnl/dos.c dos/dem.c bop.c + callback.c clock.c emulator.c - callback.c io.c registers.c vddsup.c diff --git a/subsystems/ntvdm/bios/bios.c b/subsystems/ntvdm/bios/bios.c index 50498152149..2c698d5dd7b 100644 --- a/subsystems/ntvdm/bios/bios.c +++ b/subsystems/ntvdm/bios/bios.c @@ -30,6 +30,7 @@ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, BOOL Success; HANDLE hBiosFile; DWORD BiosSize; + PVOID BiosLocation; /* Open the BIOS file */ SetLastError(0); // For debugging purposes @@ -62,30 +63,33 @@ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, 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", - (PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) + 1 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 1 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 2 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 3 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 4 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 5 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 6 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 7 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 8 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 9 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 0xa - BiosSize), + 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)); + (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, - (PVOID)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 1 - BiosSize), - /* (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - BiosSize) */ + REAL_TO_PHYS(BiosLocation), BiosSize, &BiosSize, NULL); @@ -96,22 +100,22 @@ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, 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", - (PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) + 1 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 1 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 2 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 3 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 4 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 5 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 6 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 7 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 8 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 9 - BiosSize), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) + 0xa - BiosSize), + 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)); + (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)); 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/callback.c b/subsystems/ntvdm/callback.c index 03e7f67c385..36e80071449 100644 --- a/subsystems/ntvdm/callback.c +++ b/subsystems/ntvdm/callback.c @@ -32,9 +32,6 @@ EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL }; #define BOP_CONTROL_INT32 0xFF -// #define ALIGN(ptr) (((ULONG_PTR)(ptr) + 15) & ~15) -#define ALIGN(ptr) (ptr) - #define BOP(num) LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num) #define UnSimulate16 MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE) diff --git a/subsystems/ntvdm/emulator.h b/subsystems/ntvdm/emulator.h index 51e9dceb249..b5ba9a8fc48 100644 --- a/subsystems/ntvdm/emulator.h +++ b/subsystems/ntvdm/emulator.h @@ -44,6 +44,9 @@ /* Basic Memory Management */ +#define MEM_ALIGN_UP(ptr, align) MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align)) +#define MEM_ALIGN_DOWN(ptr, align) ((ULONG_PTR)(ptr) & ~((align) - 1l)) + #define TO_LINEAR(seg, off) (((seg) << 4) + (off)) #define MAX_SEGMENT 0xFFFF #define MAX_OFFSET 0xFFFF @@ -55,6 +58,9 @@ #define SEG_OFF_TO_PTR(seg, off) \ (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off))) +#define REAL_TO_PHYS(ptr) (PVOID)((ULONG_PTR)(ptr) + (ULONG_PTR)BaseAddress) +#define PHYS_TO_REAL(ptr) (PVOID)((ULONG_PTR)(ptr) - (ULONG_PTR)BaseAddress) + /* BCD-Binary conversion */ #define BINARY_TO_BCD(x) ((((x) / 1000) << 12) + (((x) / 100) << 8) + (((x) / 10) << 4) + ((x) % 10))