diff --git a/Source/Core/Core/FifoPlayer/FifoDataFile.cpp b/Source/Core/Core/FifoPlayer/FifoDataFile.cpp index f795d5f08a..0e1e44aef9 100644 --- a/Source/Core/Core/FifoPlayer/FifoDataFile.cpp +++ b/Source/Core/Core/FifoPlayer/FifoDataFile.cpp @@ -140,7 +140,8 @@ bool FifoDataFile::Save(const std::string& filename) header.fileId = FILE_ID; header.file_version = VERSION_NUMBER; // Maintain backwards compatibility so long as the RAM sizes aren't overridden. - if (Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE)) + if (Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE) || + SConfig::GetInstance().GetSimulatedMemorySize() > Memory::MEM1_SIZE_RETAIL) header.min_loader_version = MIN_LOADER_VERSION_FOR_RAM_OVERRIDE; else header.min_loader_version = MIN_LOADER_VERSION; diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index e6d8fd56a5..054596e3d8 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -25,6 +25,7 @@ #include "Common/MsgHandler.h" #include "Common/Swap.h" #include "Core/Config/MainSettings.h" +#include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/AudioInterface.h" #include "Core/HW/DSP.h" @@ -87,10 +88,18 @@ void MemoryManager::InitMMIO(Core::System& system) void MemoryManager::Init() { - const auto get_mem1_size = [] { + const auto get_mem1_size = [this] { if (Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE)) return Config::Get(Config::MAIN_MEM1_SIZE); - return Memory::MEM1_SIZE_RETAIL; + // The simulated memory size in the game's header was originally used to ask the Apploader to + // simulate a smaller memory size than that in development systems. That is, it could make the + // 48 MiB devkit act like a 24 MiB retail console during testing, or any other config. + // + // Dolphin is reusing this as a signal to automatically adjust the emulated memory size. The + // upper bound is clamped to 64 MiB (maximum supported by Flipper's memory controller), + // reflecting Apploader behaviour of clamping the simulated size to physical memory size. It is + // never desired to emulate less than a retail console, so the lower bound is clapped to 24 MiB. + return std::clamp(m_system.GetSimulatedMemorySize(), MEM1_SIZE_RETAIL, MEM1_SIZE_MAX); }; const auto get_mem2_size = [] { if (Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE)) diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index baa910cc70..e9253272f6 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -34,8 +34,10 @@ constexpr u32 MEM1_BASE_ADDR = 0x80000000U; constexpr u32 MEM2_BASE_ADDR = 0x90000000U; constexpr u32 MEM1_SIZE_RETAIL = 0x01800000U; constexpr u32 MEM1_SIZE_GDEV = 0x04000000U; +constexpr u32 MEM1_SIZE_MAX = 0x04000000U; constexpr u32 MEM2_SIZE_RETAIL = 0x04000000U; constexpr u32 MEM2_SIZE_NDEV = 0x08000000U; +constexpr u32 MEM2_SIZE_MAX = 0x08000000U; struct PhysicalMemoryRegion { diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp index d3986775b6..49c0b2bbd3 100644 --- a/Source/Core/Core/IOS/IOS.cpp +++ b/Source/Core/Core/IOS/IOS.cpp @@ -221,8 +221,11 @@ static void ReleasePPCAncast(Core::System& system) void RAMOverrideForIOSMemoryValues(Memory::MemoryManager& memory, MemorySetupType setup_type) { // Don't touch anything if the feature isn't enabled. - if (!Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE)) + if (!Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE) || + SConfig::GetInstance().GetSimulatedMemorySize() <= Memory::MEM1_SIZE_RETAIL) + { return; + } // Some unstated constants that can be inferred. const u32 ipc_buffer_size = diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index 686d1a3264..12da7dcaea 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -119,6 +119,7 @@ void System::Initialize() m_separate_cpu_and_gpu_threads = Config::Get(Config::MAIN_CPU_THREAD); m_mmu_enabled = Config::Get(Config::MAIN_MMU); m_pause_on_panic_enabled = Config::Get(Config::MAIN_PAUSE_ON_PANIC); + m_simulated_memory_size = SConfig::GetInstance().GetSimulatedMemorySize(); } SoundStream* System::GetSoundStream() const diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index a170c608ee..8524003400 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -5,6 +5,8 @@ #include +#include "Common/CommonTypes.h" + class GeometryShaderManager; class Interpreter; class JitInterface; @@ -147,6 +149,7 @@ public: bool IsTriforce() const { return m_is_triforce; } bool IsWii() const { return m_is_wii; } bool IsBranchWatchIgnoreApploader() { return m_branch_watch_ignore_apploader; } + u32 GetSimulatedMemorySize() const { return m_simulated_memory_size; } void SetIsMIOS(bool is_mios) { m_is_mios = is_mios; } void SetIsTriforce(bool is_triforce) { m_is_triforce = is_triforce; } @@ -216,5 +219,6 @@ private: bool m_is_triforce = false; bool m_is_wii = false; bool m_branch_watch_ignore_apploader = false; + u32 m_simulated_memory_size{0}; }; } // namespace Core diff --git a/Source/UnitTests/Core/PowerPC/PageTableHostMappingTest.cpp b/Source/UnitTests/Core/PowerPC/PageTableHostMappingTest.cpp index 2cfb4b8c8f..c2622cee37 100644 --- a/Source/UnitTests/Core/PowerPC/PageTableHostMappingTest.cpp +++ b/Source/UnitTests/Core/PowerPC/PageTableHostMappingTest.cpp @@ -10,6 +10,7 @@ #include "Common/Align.h" #include "Common/CommonTypes.h" #include "Common/Swap.h" +#include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/MemTools.h" #include "Core/PowerPC/BreakPoints.h" @@ -131,6 +132,8 @@ public: if (!EMM::IsExceptionHandlerSupported()) GTEST_SKIP() << "Skipping PageTableHostMappingTest because exception handler is unsupported."; + SConfig::Init(); + auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); const u32 host_page_size = memory.GetHostPageSize(); @@ -177,6 +180,8 @@ public: EMM::UninstallExceptionHandler(); Core::UndeclareAsCPUThread(); system.GetMemory().Shutdown(); + + SConfig::Shutdown(); } static void SetSR(size_t index, u32 vsid)