diff options
| author | cristian64 <cristian64@gmail.com> | 2026-04-03 10:58:54 +0100 |
|---|---|---|
| committer | cristian64 <cristian64@gmail.com> | 2026-07-11 23:02:54 +0100 |
| commit | 0cab1731d61ecb87c7bc388dbd176a4150afbbe3 (patch) | |
| tree | f30c08837851d9fe32073003cbaff5a4bc418b06 | |
| parent | 03b1f2148b080adc9ed15ecc40e3948404388b61 (diff) | |
Core: Adjust emulated memory size automatically.
Dolphin now uses the simulated memory size defined in `bi2.bin` to
adjust the memory size in the emulated console automatically.
If **Enable Emulated Memory Size Override** has been enabled by the
user, the fixed memory size specified for **MEM1** and **MEM2** are
still used as they were before.
Most retail games do not define the simulated memory size (Wii or
Triforce games), or define it to a value that matches the default 24 MiB
(GameCube games), so, in the general case, there is no behavior change.
One game that sets the simulated memory to a non-default value is the
debug build of _Mario Kart: Double Dash!!_, where the value is set to
48 MiB.
This enhancement is focused mainly to the modding community. Prior to
these changes, modded games with extended memory requirements would
fail to launch in Dolphin [with no indication of what the problem is] if
the user failed to set the emulated memory override to the correct
value. Now, modding tools can specify the simulated memory size in the
`bi2.bin` file to produce extended games that _just work_ in Dolphin,
without cumbersome instructions that can be overlooked by the user.
| -rw-r--r-- | Source/Core/Core/FifoPlayer/FifoDataFile.cpp | 3 | ||||
| -rw-r--r-- | Source/Core/Core/HW/Memmap.cpp | 13 | ||||
| -rw-r--r-- | Source/Core/Core/HW/Memmap.h | 2 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/IOS.cpp | 5 | ||||
| -rw-r--r-- | Source/Core/Core/System.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/Core/System.h | 4 | ||||
| -rw-r--r-- | Source/UnitTests/Core/PowerPC/PageTableHostMappingTest.cpp | 5 |
7 files changed, 29 insertions, 4 deletions
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 <memory> +#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) |
