Author: hbelusca
Date: Wed Feb 26 01:07:09 2014
New Revision: 62332
URL:
http://svn.reactos.org/svn/reactos?rev=62332&view=rev
Log:
[NTVDM]
- Add utility functions for loading ROM images from files, and running them.
- Add a missing PVOID in the MEM_ALIGN_DOWN macro.
Added:
branches/ntvdm/subsystems/ntvdm/bios/rom.c (with props)
branches/ntvdm/subsystems/ntvdm/bios/rom.h (with props)
Modified:
branches/ntvdm/subsystems/ntvdm/CMakeLists.txt
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/subsystems/ntvdm/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/CMakeLis…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] Wed Feb 26 01:07:09 2014
@@ -10,6 +10,7 @@
bios/bios32/kbdbios32.c
bios/bios32/vidbios32.c
bios/bios.c
+ bios/rom.c
hardware/cmos.c
hardware/pic.c
hardware/ps2.c
Added: branches/ntvdm/subsystems/ntvdm/bios/rom.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/rom…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios/rom.c (added)
+++ branches/ntvdm/subsystems/ntvdm/bios/rom.c [iso-8859-1] Wed Feb 26 01:07:09 2014
@@ -0,0 +1,237 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: rom.c
+ * PURPOSE: ROM Support Functions
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "emulator.h"
+#include "callback.h"
+
+#include "rom.h"
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static HANDLE
+OpenRomFile(IN LPCWSTR RomFileName,
+ OUT PDWORD RomSize OPTIONAL)
+{
+ HANDLE hRomFile;
+ DWORD dwRomSize;
+
+ /* Open the ROM image file */
+ SetLastError(0); // For debugging purposes
+ hRomFile = CreateFileW(RomFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ DPRINT1("ROM opening %s ; GetLastError() = %u\n", hRomFile !=
INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
+
+ /* We failed, bail out */
+ if (hRomFile == INVALID_HANDLE_VALUE) return NULL;
+
+ /* OK, we have a handle to the ROM image file */
+
+ /*
+ * Retrieve the size of the file.
+ *
+ * The size of the ROM image file is at most 256kB. For instance,
+ * the SeaBIOS image, which includes also expansion ROMs inside it,
+ * covers the range C000:0000 to F000:FFFF .
+ *
+ * We therefore can use GetFileSize.
+ */
+ dwRomSize = GetFileSize(hRomFile, NULL);
+ if ( (dwRomSize == INVALID_FILE_SIZE && GetLastError() != ERROR_SUCCESS) ||
+ (dwRomSize > 0x40000) )
+ {
+ /* We failed, bail out */
+ DPRINT1("Error when retrieving ROM size, or size too large (%d)\n",
dwRomSize);
+
+ /* Close the ROM image file */
+ CloseHandle(hRomFile);
+
+ return NULL;
+ }
+
+ /* Success, return file handle and size if needed */
+ if (RomSize) *RomSize = dwRomSize;
+ return hRomFile;
+}
+
+static BOOL
+LoadRomFileByHandle(IN HANDLE RomFileHandle,
+ IN PVOID RomLocation,
+ IN ULONG RomSize)
+{
+ /*
+ * The size of the ROM image file is at most 256kB. For instance,
+ * the SeaBIOS image, which includes also expansion ROMs inside it,
+ * covers the range C000:0000 to F000:FFFF .
+ */
+ if (RomSize > 0x40000)
+ {
+ DPRINT1("Wrong ROM image size 0x%lx, expected at most 0x40000 (256kB)",
RomSize);
+ return FALSE;
+ }
+
+ /* Attempt to load the ROM image file into memory */
+ SetLastError(0); // For debugging purposes
+ return ReadFile(RomFileHandle,
+ REAL_TO_PHYS(RomLocation),
+ RomSize,
+ &RomSize,
+ NULL);
+}
+
+static UCHAR
+ComputeChecksum(IN ULONG RomLocation,
+ IN ULONG RomSize)
+{
+ ULONG RomLastAddress = RomLocation + RomSize;
+ UCHAR Sum = 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum
modulo 0x100.
+
+ while (RomLocation < RomLastAddress)
+ {
+ Sum += *(PUCHAR)REAL_TO_PHYS(RomLocation);
+ ++RomLocation;
+ }
+
+ return Sum;
+}
+
+static VOID
+InitRomRange(IN PCALLBACK16 Context,
+ IN ULONG Start,
+ IN ULONG End,
+ IN ULONG Increment)
+{
+ ULONG Address, AddressBoot;
+ ULONG RomSize;
+ UCHAR Checksum;
+
+ for (Address = Start; Address < End; Address += Increment)
+ {
+ /* Does the ROM have a valid signature? */
+ if (*(PUSHORT)REAL_TO_PHYS(Address) == OPTION_ROM_SIGNATURE)
+ {
+ /* Check the control sum of the ROM */
+
+ /*
+ * If this is an adapter ROM (Start: C8000, End: E0000), its
+ * reported size is stored in byte 2 of the ROM.
+ *
+ * If this is an expansion ROM (Start: E0000, End: F0000),
+ * its real length is 64kB.
+ */
+ RomSize = *(PUCHAR)REAL_TO_PHYS(Address + 2) * 512;
+ if (Address >= 0xE0000) RomSize = 0x10000;
+
+ Checksum = ComputeChecksum(Address, RomSize);
+ if (Checksum == 0x00)
+ {
+ AddressBoot = Address + 3;
+ DPRINT1("Going to run @ address 0x%p\n", AddressBoot);
+
+ AddressBoot = MAKELONG((AddressBoot & 0xFFFF), (AddressBoot &
0xF0000) >> 4);
+ // setDS((Address & 0xF0000) >> 4);
+ setDS((Address & 0xFF000) >> 4);
+ RunCallback16(Context, AddressBoot);
+ // Call16((AddressBoot & 0xF0000) >> 4, (AddressBoot &
0xFFFF));
+
+ DPRINT1("Rom @ address 0x%p initialized\n", Address);
+ }
+ else
+ {
+ DPRINT1("Rom @ address 0x%p has invalid checksum of 0x%02x\n",
Address, Checksum);
+ }
+ }
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN LoadBios(IN LPCWSTR BiosFileName,
+ OUT PVOID* BiosLocation OPTIONAL,
+ OUT PDWORD BiosSize OPTIONAL)
+{
+ BOOL Success;
+ HANDLE hBiosFile;
+ DWORD dwBiosSize = 0;
+ PVOID pBiosLocation;
+
+ /* Open the BIOS image file */
+ hBiosFile = OpenRomFile(BiosFileName, &dwBiosSize);
+
+ /* If we failed, bail out */
+ if (hBiosFile == NULL) return FALSE;
+
+ /* BIOS location needs to be aligned on 32-bit boundary */
+ // (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - dwBiosSize)
+ pBiosLocation = MEM_ALIGN_DOWN(TO_LINEAR(0xF000, 0xFFFF) + 1 - dwBiosSize,
sizeof(ULONG));
+
+ /* Attempt to load the BIOS image file into memory */
+ Success = LoadRomFileByHandle(hBiosFile, pBiosLocation, dwBiosSize);
+ DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
+
+ /* Close the BIOS image file */
+ CloseHandle(hBiosFile);
+
+ /* In case of success, return BIOS location and size if needed */
+ if (Success)
+ {
+ if (BiosLocation) *BiosLocation = pBiosLocation;
+ if (BiosSize) *BiosSize = dwBiosSize;
+ }
+
+ return (BOOLEAN)Success;
+}
+
+BOOLEAN LoadRom(IN LPCWSTR RomFileName,
+ IN PVOID RomLocation,
+ OUT PDWORD RomSize OPTIONAL)
+{
+ BOOL Success;
+ HANDLE hRomFile;
+ DWORD dwRomSize = 0;
+
+ /* Open the ROM image file */
+ hRomFile = OpenRomFile(RomFileName, &dwRomSize);
+
+ /* If we failed, bail out */
+ if (hRomFile == NULL) return FALSE;
+
+ /* Attempt to load the ROM image file into memory */
+ Success = LoadRomFileByHandle(hRomFile, RomLocation, dwRomSize);
+ DPRINT1("ROM loading %s ; GetLastError() = %u\n", Success ?
"succeeded" : "failed", GetLastError());
+
+ /* Close the ROM image file and return */
+ CloseHandle(hRomFile);
+
+ /* In case of success, return ROM size if needed */
+ if (Success)
+ {
+ if (RomSize) *RomSize = dwRomSize;
+ }
+
+ return (BOOLEAN)Success;
+}
+
+VOID SearchAndInitRoms(IN PCALLBACK16 Context)
+{
+ /* Adapters ROMs -- Start: C8000, End: E0000, 2kB blocks */
+ InitRomRange(Context, 0xC8000, 0xE0000, 0x0800);
+
+ /* Expansion ROM -- Start: E0000, End: F0000, 64kB block */
+ InitRomRange(Context, 0xE0000, 0xEFFFF, 0x10000);
+}
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/bios/rom.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/ntvdm/subsystems/ntvdm/bios/rom.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/rom…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios/rom.h (added)
+++ branches/ntvdm/subsystems/ntvdm/bios/rom.h [iso-8859-1] Wed Feb 26 01:07:09 2014
@@ -0,0 +1,37 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: rom.h
+ * PURPOSE: ROM Support Functions
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+#ifndef _ROM_H_
+#define _ROM_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+
+/* DEFINES ********************************************************************/
+
+#define ROM_AREA_START 0xE0000
+#define ROM_AREA_END 0xFFFFF
+
+#define OPTION_ROM_SIGNATURE 0xAA55
+
+/* FUNCTIONS ******************************************************************/
+
+BOOLEAN LoadBios(IN LPCWSTR BiosFileName,
+ OUT PVOID* BiosLocation OPTIONAL,
+ OUT PDWORD BiosSize OPTIONAL);
+
+BOOLEAN LoadRom(IN LPCWSTR RomFileName,
+ IN PVOID RomLocation,
+ OUT PDWORD RomSize OPTIONAL);
+
+VOID SearchAndInitRoms(IN PCALLBACK16 Context);
+
+#endif // _ROM_H_
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/bios/rom.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Wed Feb 26 01:07:09 2014
@@ -11,9 +11,10 @@
#define NDEBUG
#include "emulator.h"
+#include "callback.h"
#include "clock.h"
-#include "bios/bios.h"
+#include "bios/rom.h"
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/ps2.h"
Modified: branches/ntvdm/subsystems/ntvdm/emulator.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] Wed Feb 26 01:07:09 2014
@@ -45,7 +45,7 @@
/* 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 MEM_ALIGN_DOWN(ptr, align) (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
#define TO_LINEAR(seg, off) (((seg) << 4) + (off))
#define MAX_SEGMENT 0xFFFF