Get maximum reserve memory ranges from host.

Plus more fixup to manage reliable memory design on loader launch and emulator.
This commit is contained in:
RadWolfie 2020-03-18 00:16:39 -05:00
parent 37b230fbfe
commit fb7398d7c9
14 changed files with 308 additions and 63 deletions

View File

@ -27,7 +27,7 @@
#include "AddressRanges.h"
bool AddressRangeMatchesFlags(const int index, const int flags)
bool AddressRangeMatchesFlags(const int index, const unsigned int flags)
{
return XboxAddressRanges[index].RangeFlags & flags;
}
@ -37,6 +37,11 @@ bool IsOptionalAddressRange(const int index)
return AddressRangeMatchesFlags(index, MAY_FAIL);
}
int AddressRangeGetSystemFlags(const int index)
{
return XboxAddressRanges[index].RangeFlags & SYSTEM_ALL;
}
bool VerifyWow64()
{
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

View File

@ -56,7 +56,7 @@ const struct {
#ifdef DEBUG
uint32_t End; // TODO : Add validation that this End corresponds to specified Size
#endif
int Size;
uint32_t Size;
DWORD InitialMemoryProtection; // Memory page protection, for use by VirtualAlloc
// Shortend symbol aliasses for memory page protection
#define PROT_UNH 0 // UNHANDLED
@ -64,7 +64,7 @@ const struct {
#define PROT_XRW PAGE_EXECUTE_READWRITE
#define PROT_NAC PAGE_NOACCESS
int RangeFlags;
unsigned int RangeFlags;
// Range flags (used for system selection and optional marker)
#define MAY_FAIL (1 << 0) // Optional (may fail address range reservation)
#define SYSTEM_XBOX (1 << 1)
@ -85,10 +85,10 @@ const struct {
// See http://xboxdevwiki.net/Memory
// and http://xboxdevwiki.net/Boot_Process#Paging
// Entry : Start , End , Size , Protect , RangeFlags , Comment
RANGE_ENTRY(0x00010000, 0x03FFFFFF, MB( 64) - KB(64), PROT_XRW, SYSTEM_XBOX | MAY_FAIL, "MemLowVirtual (Retail Xbox) Optional (already reserved via virtual_memory_placeholder)"),
RANGE_ENTRY(0x00010000, 0x07FFFFFF, MB(128) - KB(64), PROT_XRW, SYSTEM_128MB | MAY_FAIL, "MemLowVirtual (Chihiro / DevKit)"),
RANGE_ENTRY(0x80000000, 0x83FFFFFF, MB( 64) , PROT_UNH, SYSTEM_XBOX , "MemPhysical (Retail)"),
RANGE_ENTRY(0x80000000, 0x87FFFFFF, MB(128) , PROT_UNH, SYSTEM_128MB , "MemPhysical (Chihiro / DevKit)"),
RANGE_ENTRY(0x00010000, 0x03FFFFFF, MB( 64) - KB(64), PROT_XRW, SYSTEM_ALL | MAY_FAIL, "MemLowVirtual (General Xbox type) lower 64 MB Optional (already reserved via virtual_memory_placeholder)"),
RANGE_ENTRY(0x04000000, 0x07FFFFFF, MB( 64) , PROT_XRW, SYSTEM_128MB | MAY_FAIL, "MemLowVirtual (Chihiro / DevKit) ^ + upper 64 MB"),
RANGE_ENTRY(0x80000000, 0x83FFFFFF, MB( 64) , PROT_UNH, SYSTEM_ALL , "MemPhysical (General Xbox type) lower 64 MB"),
RANGE_ENTRY(0x84000000, 0x87FFFFFF, MB( 64) , PROT_UNH, SYSTEM_128MB , "MemPhysical (Chihiro / DevKit) ^ + upper 64 MB"),
RANGE_ENTRY(0xB0000000, 0xBFFFFFFF, MB(256) , PROT_NAC, SYSTEM_DEVKIT , "DevKitMemory"), // TODO : Check reserved range (might behave like MemTiled)
RANGE_ENTRY(0xC0000000, 0xC03FFFFF, MB( 4) , PROT_RW, SYSTEM_ALL , "MemPageTable"), // See PAGE_TABLES_SIZE, which contains one 4 byte entry per PAGE_SIZE
RANGE_ENTRY(0xD0000000, 0xEFFFFFFF, MB(512) , PROT_RW, SYSTEM_ALL | MAY_FAIL, "SystemMemory Optional"), // TODO : Check reserved range (might behave like MemTiled)
@ -107,8 +107,14 @@ const struct {
#undef RANGE_ENTRY
};
extern bool AddressRangeMatchesFlags(const int index, const int flags);
#define BLOCK_REGION_DEVKIT_INDEX_BEGIN 0
#define BLOCK_REGION_DEVKIT_INDEX_END 4096
#define BLOCK_REGION_SYSTEM_INDEX_BEGIN 4096
#define BLOCK_REGION_SYSTEM_INDEX_END 12288
extern bool AddressRangeMatchesFlags(const int index, const unsigned int flags);
extern bool IsOptionalAddressRange(const int index);
extern int AddressRangeGetSystemFlags(const int index);
extern bool VerifyWow64();

View File

@ -42,8 +42,10 @@ bool ReserveMemoryRange(int index, uint32_t blocks_reserved[384])
const DWORD Protect = XboxAddressRanges[index].InitialMemoryProtection;
bool NeedsReservationTracking = false;
unsigned int arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
switch (Start) {
case 0x80000000:
case 0x84000000:
case 0xF0000000: {
static bool NeedsInitialization = true;
static HANDLE hFileMapping;
@ -63,7 +65,7 @@ bool ReserveMemoryRange(int index, uint32_t blocks_reserved[384])
}
LPVOID Result = MapViewOfFileEx(
hFileMapping,
Start == 0x80000000 ?
(Start == 0x80000000 || Start == 0x84000000) ?
(FILE_MAP_READ | FILE_MAP_WRITE | FILE_MAP_EXECUTE) : (FILE_MAP_READ | FILE_MAP_WRITE),
0,
0,
@ -75,15 +77,21 @@ bool ReserveMemoryRange(int index, uint32_t blocks_reserved[384])
}
break;
case 0xB0000000:
case 0xD0000000: {
case 0xD0000000:
// If additional addresses need to be assign in region's block.
// Then check for nonzero value.
arr_index = BLOCK_REGION_SYSTEM_INDEX_BEGIN;
[[fallthrough]];
case 0xB0000000: {
// arr_index's default is BLOCK_REGION_DEVKIT_INDEX_BEGIN which is zero.
// Any block region above zero should be place above this case to override zero value.
//arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
NeedsReservationTracking = true;
}
[[fallthrough]];
default: {
while (Size > 0) {
static int arr_index = 0;
SIZE_T BlockSize = (SIZE_T)(Size > BLOCK_SIZE) ? BLOCK_SIZE : Size;
LPVOID Result = VirtualAlloc((LPVOID)Start, BlockSize, MEM_RESERVE, Protect);
if (Result == nullptr) {
@ -107,7 +115,53 @@ bool ReserveMemoryRange(int index, uint32_t blocks_reserved[384])
return !HadAnyFailure;
}
bool ReserveAddressRanges(const int system, uint32_t blocks_reserved[384]) {
// Free address range from the host.
void FreeMemoryRange(int index, uint32_t blocks_reserved[384])
{
uint32_t Start = XboxAddressRanges[index].Start, _Start;
int Size = XboxAddressRanges[index].Size;
bool NeedsReservationTracking = false;
unsigned int arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
switch (Start) {
case 0x80000000:
case 0x84000000:
case 0xF0000000: {
(void)UnmapViewOfFile((LPVOID)Start);
}
break;
case 0xD0000000:
// If additional addresses need to be assign in region's block.
// Then check for nonzero value.
arr_index = BLOCK_REGION_SYSTEM_INDEX_BEGIN;
[[fallthrough]];
case 0xB0000000: {
// arr_index's default is BLOCK_REGION_DEVKIT_INDEX_BEGIN which is zero.
// Any block region above zero should be place above this case to override zero value.
//arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
NeedsReservationTracking = true;
}
[[fallthrough]];
default: {
while (Size > 0) {
_Start = Start; // Require to silence C6001's warning complaint
BOOL Result = VirtualFree((LPVOID)_Start, 0, MEM_RELEASE);
// Handle the next block
Start += BLOCK_SIZE;
Size -= BLOCK_SIZE;
if (NeedsReservationTracking) {
if (Result != 0) {
blocks_reserved[arr_index / 32] &= ~(1 << (arr_index % 32));
}
arr_index++;
}
}
}
}
}
bool ReserveAddressRanges(const unsigned int system, uint32_t blocks_reserved[384]) {
// Loop over all Xbox address ranges
for (int i = 0; i < ARRAY_SIZE(XboxAddressRanges); i++) {
// Skip address ranges that don't match the given flags
@ -126,3 +180,74 @@ bool ReserveAddressRanges(const int system, uint32_t blocks_reserved[384]) {
return true;
}
void FreeAddressRanges(const unsigned int system, unsigned int release_systems, uint32_t blocks_reserved[384]) {
// If reserved_systems is empty, then there's nothing to be freed up.
if (release_systems == 0) {
return;
}
// Loop over all Xbox address ranges
for (int i = 0; i < ARRAY_SIZE(XboxAddressRanges); i++) {
// Skip address ranges that do match specific flag
if (AddressRangeMatchesFlags(i, system))
continue;
// Skip address ranges that doesn't match the reserved flags
if (!AddressRangeMatchesFlags(i, release_systems))
continue;
FreeMemoryRange(i, blocks_reserved);
}
}
bool AttemptReserveAddressRanges(unsigned int* p_reserved_systems, uint32_t blocks_reserved[384]) {
int iLast = 0;
unsigned int reserved_systems = *p_reserved_systems, clear_systems = 0;
// Loop over all Xbox address ranges
for (int i = 0; i < ARRAY_SIZE(XboxAddressRanges); i++) {
// Once back to original spot, let's resume.
if (i == iLast && clear_systems) {
reserved_systems &= ~clear_systems;
if (reserved_systems == 0) {
*p_reserved_systems = 0;
return false;
}
// Resume virtual allocated range.
clear_systems = 0;
continue;
}
if (clear_systems) {
// Skip address ranges that doesn't match the given flags
if (!AddressRangeMatchesFlags(i, clear_systems))
continue;
// Release incompatible system's memory range
FreeMemoryRange(i, blocks_reserved);
}
else {
// Skip address ranges that don't match the given flags
if (!AddressRangeMatchesFlags(i, reserved_systems))
continue;
// Try to reserve each address range
if (ReserveMemoryRange(i, blocks_reserved))
continue;
// Some ranges are allowed to fail reserving
if (!IsOptionalAddressRange(i)) {
// If not, then let's free them and downgrade host's limitation.
iLast = i;
i = -1; // Reset index back to zero after for statement's increment.
clear_systems = AddressRangeGetSystemFlags(i);
continue;
}
}
}
*p_reserved_systems = reserved_systems;
return true;
}

View File

@ -26,4 +26,8 @@
// ******************************************************************
#pragma once
extern bool ReserveAddressRanges(const int system, uint32_t blocks_reserved[384]);
extern bool ReserveAddressRanges(const unsigned int system, uint32_t blocks_reserved[384]);
extern void FreeAddressRanges(const unsigned int system, unsigned int release_systems, uint32_t blocks_reserved[384]);
extern bool AttemptReserveAddressRanges(unsigned int* p_reserved_systems, uint32_t blocks_reserved[384]);

View File

@ -163,4 +163,20 @@ long long GetSessionID()
return sessionID;
}
void SetSystemType(const std::string value)
{
// If system types key exist, then do not replace old one.
if (hasKey(cli_config::system_retail)
|| hasKey(cli_config::system_devkit)
|| hasKey(cli_config::system_chihiro)) {
return;
}
// If one of system types match, then set it.
if (value.compare(cli_config::system_retail) == 0
|| value.compare(cli_config::system_devkit) == 0
|| value.compare(cli_config::system_chihiro) == 0) {
SetValue(value, "");
}
}
}

View File

@ -38,6 +38,9 @@ static constexpr char hwnd[] = "hwnd";
static constexpr char debug_mode[] = "dm";
static constexpr char debug_file[] = "df";
static constexpr char sid[] = "sid";
static constexpr char system_retail[] = "retail";
static constexpr char system_devkit[] = "devkit";
static constexpr char system_chihiro[] = "chihiro";
bool GenConfig(char** argv, int argc);
size_t ConfigSize();
@ -53,4 +56,6 @@ long long GetSessionID();
// Change xbe path to launch.
void SetLoad(const std::string value);
void SetSystemType(const std::string value);
}

View File

@ -195,8 +195,8 @@ class EmuShared : public Mutex
// ******************************************************************
// * Previous Memory Layout value Accessors
// ******************************************************************
void GetMmLayout(int* value) { Lock(); *value = m_PreviousMmLayout; Unlock(); }
void SetMmLayout(int* value) { Lock(); m_PreviousMmLayout = *value; Unlock(); }
void GetMmLayout(unsigned int* value) { Lock(); *value = m_PreviousMmLayout; Unlock(); }
void SetMmLayout(unsigned int* value) { Lock(); m_PreviousMmLayout = *value; Unlock(); }
#endif
// ******************************************************************
// * Log Level value Accessors
@ -272,7 +272,7 @@ class EmuShared : public Mutex
bool m_bReady_status;
bool m_bEmulating_status;
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
int m_PreviousMmLayout;
unsigned int m_PreviousMmLayout;
int m_Reserved7[3];
#else
int m_Reserved7[4];

View File

@ -54,6 +54,7 @@ namespace xboxkrnl
#include "CxbxDebugger.h"
#include "common/util/cliConfig.hpp"
#include "common/util/xxhash.h"
#include "common/ReserveAddressRanges.h"
#include <clocale>
#include <process.h>
@ -134,6 +135,36 @@ XbeType GetXbeType(Xbe::Header *pXbeHeader)
return xtRetail;
}
const char* GetSystemTypeToStr(unsigned int system)
{
if (system == SYSTEM_CHIHIRO) {
return cli_config::system_chihiro;
}
if (system == SYSTEM_DEVKIT) {
return cli_config::system_devkit;
}
if (system == SYSTEM_XBOX) {
return cli_config::system_retail;
}
return nullptr;
}
const char* GetXbeTypeToStr(XbeType xbe_type)
{
if (xbe_type == xtChihiro) {
return "chihiro";
}
if (xbe_type == xtDebug) {
return "debug";
}
return "retail";
}
void ApplyMediaPatches()
{
// Patch the XBE Header to allow running from all media types
@ -724,7 +755,23 @@ bool HandleFirstLaunch()
return true;
}
void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
// TODO: Need to move isSystemFlagSupport function somewhere other than CxbxKrnl.cpp file.
bool isSystemFlagSupport(int reserved_systems, int assign_system)
{
if (reserved_systems & assign_system) {
return true;
}
// TODO: Once host's standalone emulation is remove from GUI, remove below as well.
#ifndef CXBXR_EMU
if (reserved_systems == 0) {
return true;
}
#endif
return false;
}
void CxbxKrnlEmulate(unsigned int reserved_systems, uint32_t blocks_reserved[384])
{
std::string tempStr;
@ -1075,8 +1122,51 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
}
}
// Detect XBE type :
g_XbeType = GetXbeType(&CxbxKrnl_Xbe->m_Header);
// If CLI has given console type, then enforce it.
if (cli_config::hasKey(cli_config::system_chihiro)) {
EmuLogInit(LOG_LEVEL::INFO, "Auto detect is disabled, running as chihiro.");
g_XbeType = xtChihiro;
}
else if (cli_config::hasKey(cli_config::system_devkit)) {
EmuLogInit(LOG_LEVEL::INFO, "Auto detect is disabled, running as devkit.");
g_XbeType = xtDebug;
}
else if (cli_config::hasKey(cli_config::system_retail)) {
EmuLogInit(LOG_LEVEL::INFO, "Auto detect is disabled, running as retail.");
g_XbeType = xtRetail;
}
// Otherwise, use auto detect method.
else {
// Detect XBE type :
g_XbeType = GetXbeType(&CxbxKrnl_Xbe->m_Header);
EmuLogInit(LOG_LEVEL::INFO, "Auto detect: XbeType = %s", GetXbeTypeToStr(g_XbeType));
}
EmuLogInit(LOG_LEVEL::INFO, "Host's compatible system types: %2X", reserved_systems);
unsigned int emulate_system = 0;
// Set reserved_systems which system we will about to emulate.
if (isSystemFlagSupport(reserved_systems, SYSTEM_CHIHIRO) && g_XbeType == xtChihiro) {
emulate_system = SYSTEM_CHIHIRO;
}
else if (isSystemFlagSupport(reserved_systems, SYSTEM_DEVKIT) && g_XbeType == xtDebug) {
emulate_system = SYSTEM_DEVKIT;
}
else if (isSystemFlagSupport(reserved_systems, SYSTEM_XBOX) && g_XbeType == xtRetail) {
emulate_system = SYSTEM_XBOX;
}
// If none of system type requested to emulate isn't supported on host's end. Then enforce failure.
else {
CxbxKrnlCleanup("Unable to emulate system type due to host is not able to reserve required memory ranges.");
return;
}
// Clear emulation system from reserved systems to be free.
reserved_systems &= ~emulate_system;
// Once we have determine which system type to run as, enforce it in future reboots.
if ((BootFlags & BOOT_QUICK_REBOOT) == 0) {
const char* system_str = GetSystemTypeToStr(emulate_system);
cli_config::SetSystemType(system_str);
}
// Register if we're running an Chihiro executable or a debug xbe, otherwise it's an Xbox retail executable
g_bIsChihiro = (g_XbeType == xtChihiro);
@ -1106,9 +1196,9 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
uint32_t SystemDevBlocksReserved[384] = { 0 };
g_VMManager.Initialize(0, BootFlags, SystemDevBlocksReserved);
#else
// TODO: Retrieve the system type from the loader and be sure that it doesn't change between quick reboots
FreeAddressRanges(emulate_system, reserved_systems, blocks_reserved);
// Initialize the memory manager
g_VMManager.Initialize(SYSTEM_XBOX, BootFlags, blocks_reserved);
g_VMManager.Initialize(emulate_system, BootFlags, blocks_reserved);
#endif
// Commit the memory used by the xbe header

View File

@ -237,7 +237,7 @@ bool CreateSettings();
bool HandleFirstLaunch();
/*! Cxbx Kernel Entry Point */
void CxbxKrnlEmulate(uint32_t blocks_reserved[384]);
void CxbxKrnlEmulate(unsigned int system, uint32_t blocks_reserved[384]);
/*! initialize emulation */
__declspec(noreturn) void CxbxKrnlInit(void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32_t XbeHeaderSize, void (*Entry)(), int BootFlags);

View File

@ -73,17 +73,19 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const
return false;
}
void VMManager::Initialize(int SystemType, int BootFlags, uint32_t blocks_reserved[384])
void VMManager::Initialize(unsigned int SystemType, int BootFlags, uint32_t blocks_reserved[384])
{
#ifndef CXBXR_EMU
if ((BootFlags & BOOT_QUICK_REBOOT) == 0) {
#ifndef CXBXR_EMU
SystemType = g_bIsRetail ? SYSTEM_XBOX : g_bIsChihiro ? SYSTEM_CHIHIRO : SYSTEM_DEVKIT; // TODO: Temporary placeholder until loader is functional.
#endif
g_EmuShared->SetMmLayout(&SystemType);
}
else {
g_EmuShared->GetMmLayout(&SystemType);
}
#ifndef CXBXR_EMU
if (!ReserveAddressRanges(SystemType, blocks_reserved)) {
CxbxKrnlCleanup("Failed to reserve required memory ranges!", GetLastError());
}
@ -113,26 +115,19 @@ void VMManager::Initialize(int SystemType, int BootFlags, uint32_t blocks_reserv
}
}
// Construct VMAs base on reserved bit indexes for devkit and system region blocks.
if (SystemType == SYSTEM_DEVKIT) {
for (int i = 0; i < 4096; i++) {
for (unsigned int i = BLOCK_REGION_DEVKIT_INDEX_BEGIN; i < BLOCK_REGION_DEVKIT_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(DEVKIT_MEMORY_BASE + i * (64 * ONE_KB), (64 * ONE_KB), DevkitRegion, ReservedVma, false);
}
}
for (int i = 4096; i < 12288; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(SYSTEM_MEMORY_BASE + i * (64 * ONE_KB), (64 * ONE_KB), SystemRegion, ReservedVma, false);
}
}
}
else {
for (int i = 0; i < 8192; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(SYSTEM_MEMORY_BASE + i * (64 * ONE_KB), (64 * ONE_KB), SystemRegion, ReservedVma, false);
}
}
for (unsigned int i = BLOCK_REGION_SYSTEM_INDEX_BEGIN; i < BLOCK_REGION_SYSTEM_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(SYSTEM_MEMORY_BASE + i * (64 * ONE_KB), (64 * ONE_KB), SystemRegion, ReservedVma, false);
}
}

View File

@ -28,10 +28,16 @@
#ifndef VMMANAGER_H
#define VMMANAGER_H
// TODO: Need to move defines below into one header files.
#define SYSTEM_XBOX (1 << 1)
#define SYSTEM_DEVKIT (1 << 2)
#define SYSTEM_CHIHIRO (1 << 3)
#define BLOCK_REGION_DEVKIT_INDEX_BEGIN 0
#define BLOCK_REGION_DEVKIT_INDEX_END 4096
#define BLOCK_REGION_SYSTEM_INDEX_BEGIN 4096
#define BLOCK_REGION_SYSTEM_INDEX_END 12288
#include "PhysicalMemory.h"
@ -103,7 +109,7 @@ class VMManager : public PhysicalMemory
// shutdown routine
void Shutdown();
// initializes the memory manager to the default configuration
void Initialize(int SystemType, int BootFlags, uint32_t blocks_reserved[384]);
void Initialize(unsigned int SystemType, int BootFlags, uint32_t blocks_reserved[384]);
// retrieves memory statistics
void MemoryStatistics(xboxkrnl::PMM_STATISTICS memory_statistics);
// allocates memory in the user region

View File

@ -122,7 +122,7 @@ CommandLineToArgvA(
return argv;
}
DWORD WINAPI Emulate(int system, uint32_t blocks_reserved[384])
DWORD WINAPI Emulate(unsigned int reserved_systems, uint32_t blocks_reserved[384])
{
FUNC_EXPORTS
@ -170,7 +170,13 @@ DWORD WINAPI Emulate(int system, uint32_t blocks_reserved[384])
return EXIT_FAILURE;
}
CxbxKrnlEmulate(blocks_reserved);
if (!reserved_systems) {
CxbxShowError("Unable to preserve any system's memory ranges!");
EmuShared::Cleanup();
return EXIT_FAILURE;
}
CxbxKrnlEmulate(reserved_systems, blocks_reserved);
/*! cleanup shared memory */
EmuShared::Cleanup();

View File

@ -82,7 +82,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
if (cli_config::hasKey("load")) {
#ifndef CXBXR_EMU
CxbxKrnlEmulate(nullptr);
CxbxKrnlEmulate(0, nullptr);
EmuShared::Cleanup();
return EXIT_SUCCESS;
#else

View File

@ -137,29 +137,16 @@ DWORD CALLBACK rawMain()
return ERROR_BAD_ENVIRONMENT;
}
// TODO: NOTE - Must reserve all memory by default. This is a requirement for standalone emulation support.
// It is still possible to release upper 64 MB space after determine the first xbe file.
// However, it is not recommended since modded xbox hardware can have 128MB yet still only able to use lower 64MB if xbe is not patched.
int system = SYSTEM_XBOX; // By default, we'll emulate a retail Xbox
// Note : Since we only have kernel32 API's available (not even the standard libary),
// we use the (exclusively wide-char) FindStringOrdinal() here instead of strstr():
LPWSTR CommandLine = GetCommandLineW();
// TODO: Below options must go, see "NOTE -" comment above for the reasons.
if (FindStringOrdinal(FIND_FROMSTART, CommandLine, -1, L" /chihiro", -1, true) >= 0) {
system = SYSTEM_CHIHIRO;
} else {
if (FindStringOrdinal(FIND_FROMSTART, CommandLine, -1, L" /devkit", -1, true) >= 0) {
system = SYSTEM_DEVKIT;
}
}
// Reserve all memory by default. This is a requirement for standalone emulation support.
// Emulator's initial process will decide which memory ranges will be free.
unsigned int system = SYSTEM_ALL; // Reserve all systems.
// Marking this as static to avoid an implicit call to memset, which is not available in the loader
static uint32_t SystemDevBlocksReserved[384];
if (!ReserveAddressRanges(system, SystemDevBlocksReserved)) {
if (!AttemptReserveAddressRanges(&system, SystemDevBlocksReserved)) {
// If we get here, emulation lacks important address ranges; Don't launch
OutputMessage("Required address range couldn't be reserved!\n");
OutputMessage("None of system types' required address range(s) could be reserved!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
@ -177,7 +164,7 @@ DWORD CALLBACK rawMain()
}
// Find the main emulation function in our DLL
typedef void (WINAPI *Emulate_t)(int, uint32_t[384]);
typedef void (WINAPI *Emulate_t)(unsigned int, uint32_t[384]);
Emulate_t pfnEmulate = (Emulate_t)GetProcAddress(hEmulationDLL, "Emulate");
if (!pfnEmulate) {
OutputMessage("Entrypoint not found!\n");