Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #8722 from Minty-Meeo/master
Configurable MEM1 and MEM2 sizes at runtime via Dolphin.ini
  • Loading branch information
leoetlino committed Apr 28, 2020
2 parents 54b85f6 + cc858c6 commit 4b00ddf
Show file tree
Hide file tree
Showing 27 changed files with 487 additions and 133 deletions.
35 changes: 19 additions & 16 deletions Source/Core/Core/Boot/Boot_BS2Emu.cpp
Expand Up @@ -172,7 +172,7 @@ void CBoot::SetupGCMemory()
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020);

// Physical Memory Size (24MB on retail)
PowerPC::HostWrite_U32(Memory::REALRAM_SIZE, 0x80000028);
PowerPC::HostWrite_U32(Memory::GetRamSizeReal(), 0x80000028);

// Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
// TODO: determine why some games fail when using a retail ID.
Expand Down Expand Up @@ -369,26 +369,26 @@ bool CBoot::SetupWiiMemory(IOS::HLE::IOSC::ConsoleType console_type)
0x80000060 Copyright code
*/

Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
Memory::Write_U32(Memory::REALRAM_SIZE, 0x00000028); // MEM1 size 24MB
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
Memory::Write_U32(Memory::GetRamSizeReal(), 0x00000028); // MEM1 size 24MB
u32 board_model = console_type == IOS::HLE::IOSC::ConsoleType::RVT ? 0x10000021 : 0x00000023;
Memory::Write_U32(board_model, 0x0000002c); // Board Model
Memory::Write_U32(0x00000000, 0x00000030); // Init
Memory::Write_U32(0x817FEC60, 0x00000034); // Init
// 38, 3C should get start, size of FST through apploader
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(Memory::REALRAM_SIZE, 0x000000f0); // "Simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
Memory::Write_U16(0x0000, 0x000030e6); // Console type
Memory::Write_U32(0x00000000, 0x000030c0); // EXI
Memory::Write_U32(0x00000000, 0x000030c4); // EXI
Memory::Write_U32(0x00000000, 0x000030dc); // Time
Memory::Write_U32(0xffffffff, 0x000030d8); // Unknown, set by any official NAND title
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
Memory::Write_U32(0x00000000, 0x000030f0); // Apploader
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(Memory::GetRamSizeReal(), 0x000000f0); // "Simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
Memory::Write_U16(0x0000, 0x000030e6); // Console type
Memory::Write_U32(0x00000000, 0x000030c0); // EXI
Memory::Write_U32(0x00000000, 0x000030c4); // EXI
Memory::Write_U32(0x00000000, 0x000030dc); // Time
Memory::Write_U32(0xffffffff, 0x000030d8); // Unknown, set by any official NAND title
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
Memory::Write_U32(0x00000000, 0x000030f0); // Apploader

// During the boot process, 0x315c is first set to 0xdeadbeef by IOS
// in the boot_ppc syscall. The value is then partly overwritten by SDK titles.
Expand Down Expand Up @@ -493,6 +493,9 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume)
if (!RunApploader(/*is_wii*/ true, volume))
return false;

// The Apploader probably just overwrote values needed for RAM Override. Run this again!
IOS::HLE::RAMOverrideForIOSMemoryValues(IOS::HLE::MemorySetupType::IOSReload);

// Warning: This call will set incorrect running game metadata if our volume parameter
// doesn't point to the same disc as the one that's inserted in the emulated disc drive!
IOS::HLE::GetIOS()->GetES()->DIVerify(tmd, volume.GetTicket(partition));
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/Boot/DolReader.cpp
Expand Up @@ -102,7 +102,7 @@ bool DolReader::LoadIntoMemory(bool only_in_mem1) const
for (size_t i = 0; i < m_text_sections.size(); ++i)
if (!m_text_sections[i].empty() &&
!(only_in_mem1 &&
m_dolheader.textAddress[i] + m_text_sections[i].size() >= Memory::REALRAM_SIZE))
m_dolheader.textAddress[i] + m_text_sections[i].size() >= Memory::GetRamSizeReal()))
{
Memory::CopyToEmu(m_dolheader.textAddress[i], m_text_sections[i].data(),
m_text_sections[i].size());
Expand All @@ -112,7 +112,7 @@ bool DolReader::LoadIntoMemory(bool only_in_mem1) const
for (size_t i = 0; i < m_data_sections.size(); ++i)
if (!m_data_sections[i].empty() &&
!(only_in_mem1 &&
m_dolheader.dataAddress[i] + m_data_sections[i].size() >= Memory::REALRAM_SIZE))
m_dolheader.dataAddress[i] + m_data_sections[i].size() >= Memory::GetRamSizeReal()))
{
Memory::CopyToEmu(m_dolheader.dataAddress[i], m_data_sections[i].data(),
m_data_sections[i].size());
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Boot/ElfReader.cpp
Expand Up @@ -151,7 +151,7 @@ bool ElfReader::LoadIntoMemory(bool only_in_mem1) const
u32 srcSize = p->p_filesz;
u32 dstSize = p->p_memsz;

if (only_in_mem1 && p->p_vaddr >= Memory::REALRAM_SIZE)
if (only_in_mem1 && p->p_vaddr >= Memory::GetRamSizeReal())
continue;

Memory::CopyToEmu(writeAddr, src, srcSize);
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Core/Config/MainSettings.cpp
Expand Up @@ -9,6 +9,7 @@
#include "AudioCommon/AudioCommon.h"
#include "Common/Config/Config.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/PowerPC/PowerPC.h"

Expand Down Expand Up @@ -98,6 +99,9 @@ const ConfigInfo<bool> MAIN_ACCURATE_NANS{{System::Main, "Core", "AccurateNaNs"}
const ConfigInfo<float> MAIN_EMULATION_SPEED{{System::Main, "Core", "EmulationSpeed"}, 1.0f};
const ConfigInfo<float> MAIN_OVERCLOCK{{System::Main, "Core", "Overclock"}, 1.0f};
const ConfigInfo<bool> MAIN_OVERCLOCK_ENABLE{{System::Main, "Core", "OverclockEnable"}, false};
const ConfigInfo<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEnable"}, false};
const ConfigInfo<u32> MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_SIZE_RETAIL};
const ConfigInfo<u32> MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL};
const ConfigInfo<std::string> MAIN_GFX_BACKEND{{System::Main, "Core", "GFXBackend"}, ""};
const ConfigInfo<std::string> MAIN_GPU_DETERMINISM_MODE{
{System::Main, "Core", "GPUDeterminismMode"}, "auto"};
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/Config/MainSettings.h
Expand Up @@ -76,6 +76,9 @@ extern const ConfigInfo<bool> MAIN_ACCURATE_NANS;
extern const ConfigInfo<float> MAIN_EMULATION_SPEED;
extern const ConfigInfo<float> MAIN_OVERCLOCK;
extern const ConfigInfo<bool> MAIN_OVERCLOCK_ENABLE;
extern const ConfigInfo<bool> MAIN_RAM_OVERRIDE_ENABLE;
extern const ConfigInfo<u32> MAIN_MEM1_SIZE;
extern const ConfigInfo<u32> MAIN_MEM2_SIZE;
// Should really be part of System::GFX, but again, we're stuck with past mistakes.
extern const ConfigInfo<std::string> MAIN_GFX_BACKEND;
extern const ConfigInfo<std::string> MAIN_GPU_DETERMINISM_MODE;
Expand Down
6 changes: 5 additions & 1 deletion Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
Expand Up @@ -28,7 +28,7 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
return true;
}

static constexpr std::array<const Config::ConfigLocation*, 93> s_setting_saveable = {
static constexpr std::array<const Config::ConfigLocation*, 96> s_setting_saveable = {
// Main.Core

&Config::MAIN_DEFAULT_ISO.location,
Expand All @@ -37,8 +37,12 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
&Config::MAIN_AUTO_DISC_CHANGE.location,
&Config::MAIN_DPL2_DECODER.location,
&Config::MAIN_DPL2_QUALITY.location,
&Config::MAIN_RAM_OVERRIDE_ENABLE.location,
&Config::MAIN_MEM1_SIZE.location,
&Config::MAIN_MEM2_SIZE.location,

// Main.Display

&Config::MAIN_FULLSCREEN_DISPLAY_RES.location,
&Config::MAIN_FULLSCREEN.location,
&Config::MAIN_RENDER_TO_MAIN.location,
Expand Down
65 changes: 62 additions & 3 deletions Source/Core/Core/FifoPlayer/FifoDataFile.cpp
Expand Up @@ -11,12 +11,18 @@
#include <vector>

#include "Common/File.h"
#include "Common/MsgHandler.h"
#include "Core/Config/MainSettings.h"
#include "Core/HW/Memmap.h"

enum
{
FILE_ID = 0x0d01f1f0,
VERSION_NUMBER = 4,
VERSION_NUMBER = 5,
MIN_LOADER_VERSION = 1,
// This value is only used if the DFF file was created with overridden RAM sizes.
// If the MIN_LOADER_VERSION ever exceeds this, it's alright to remove it.
MIN_LOADER_VERSION_FOR_RAM_OVERRIDE = 5,
};

#pragma pack(push, 1)
Expand All @@ -39,7 +45,11 @@ struct FileHeader
u32 flags;
u64 texMemOffset;
u32 texMemSize;
u8 reserved[40];
// These are for overriden RAM sizes. Otherwise the FIFO Player
// will crash and burn with mismatched settings. See PR #8722.
u32 mem1_size;
u32 mem2_size;
u8 reserved[32];
};
static_assert(sizeof(FileHeader) == 128, "FileHeader should be 128 bytes");

Expand Down Expand Up @@ -129,7 +139,11 @@ bool FifoDataFile::Save(const std::string& filename)
FileHeader header;
header.fileId = FILE_ID;
header.file_version = VERSION_NUMBER;
header.min_loader_version = MIN_LOADER_VERSION;
// Maintain backwards compatability so long as the RAM sizes aren't overridden.
if (Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE))
header.min_loader_version = MIN_LOADER_VERSION_FOR_RAM_OVERRIDE;
else
header.min_loader_version = MIN_LOADER_VERSION;

header.bpMemOffset = bpMemOffset;
header.bpMemSize = BP_MEM_SIZE;
Expand All @@ -151,6 +165,9 @@ bool FifoDataFile::Save(const std::string& filename)

header.flags = m_Flags;

header.mem1_size = Memory::GetRamSizeReal();
header.mem2_size = Memory::GetExRamSizeReal();

file.Seek(0, SEEK_SET);
file.WriteBytes(&header, sizeof(FileHeader));

Expand Down Expand Up @@ -198,21 +215,59 @@ std::unique_ptr<FifoDataFile> FifoDataFile::Load(const std::string& filename, bo

if (header.fileId != FILE_ID || header.min_loader_version > VERSION_NUMBER)
{
CriticalAlertT(
"The DFF's minimum loader version (%d) exceeds the version of this FIFO Player (%d)",
header.min_loader_version, VERSION_NUMBER);
file.Close();
return nullptr;
}

// Official support for overridden RAM sizes was added in version 5.
if (header.file_version < 5)
{
// It's safe to assume FIFO Logs before PR #8722 weren't using this
// obscure feature, so load up these header values with the old defaults.
header.mem1_size = Memory::MEM1_SIZE_RETAIL;
header.mem2_size = Memory::MEM2_SIZE_RETAIL;
}

auto dataFile = std::make_unique<FifoDataFile>();

dataFile->m_Flags = header.flags;
dataFile->m_Version = header.file_version;

if (flagsOnly)
{
// Force settings to match those used when the DFF was created. This is sort of a hack.
// It only works because this function gets called twice, and the first time (flagsOnly mode)
// happens to be before HW::Init(). But the convenience is hard to deny!
Config::SetCurrent(Config::MAIN_RAM_OVERRIDE_ENABLE, true);
Config::SetCurrent(Config::MAIN_MEM1_SIZE, header.mem1_size);
Config::SetCurrent(Config::MAIN_MEM2_SIZE, header.mem2_size);

file.Close();
return dataFile;
}

// To make up for such a hacky thing, here is a catch-all failsafe in case if the above code
// stops working or is otherwise removed. As it is, this should never end up running.
// It should be noted, however, that Dolphin *will still crash* from the nullptr being returned
// in a non-flagsOnly context, so if this code becomes necessary, it should be moved above the
// prior conditional.
if (header.mem1_size != Memory::GetRamSizeReal() ||
header.mem2_size != Memory::GetExRamSizeReal())
{
CriticalAlertT("Emulated memory size mismatch!\n"
"Current | MEM1 %08X (%3dMB) MEM2 %08X (%3dMB)\n"
"DFF | MEM1 %08X (%3dMB) MEM2 %08X (%3dMB)",
Memory::GetRamSizeReal(), Memory::GetRamSizeReal() / 0x100000,
Memory::GetExRamSizeReal(), Memory::GetExRamSizeReal() / 0x100000,
header.mem1_size, header.mem1_size / 0x100000, header.mem2_size,
header.mem2_size / 0x100000);
file.Close();
return nullptr;
}

u32 size = std::min<u32>(BP_MEM_SIZE, header.bpMemSize);
file.Seek(header.bpMemOffset, SEEK_SET);
file.ReadArray(dataFile->m_BPMem, size);
Expand All @@ -238,6 +293,10 @@ std::unique_ptr<FifoDataFile> FifoDataFile::Load(const std::string& filename, bo
file.ReadArray(dataFile->m_TexMem, size);
}

// idk what else these could be used for, but it'd be a shame to not make them available.
dataFile->m_ram_size_real = header.mem1_size;
dataFile->m_exram_size_real = header.mem2_size;

// Read frames
for (u32 i = 0; i < header.frameCount; ++i)
{
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/FifoPlayer/FifoDataFile.h
Expand Up @@ -69,6 +69,9 @@ class FifoDataFile
u32* GetXFMem() { return m_XFMem; }
u32* GetXFRegs() { return m_XFRegs; }
u8* GetTexMem() { return m_TexMem; }
u32 GetRamSizeReal() { return m_ram_size_real; }
u32 GetExRamSizeReal() { return m_exram_size_real; }

void AddFrame(const FifoFrameInfo& frameInfo);
const FifoFrameInfo& GetFrame(u32 frame) const { return m_Frames[frame]; }
u32 GetFrameCount() const { return static_cast<u32>(m_Frames.size()); }
Expand Down Expand Up @@ -96,6 +99,8 @@ class FifoDataFile
u32 m_XFMem[XF_MEM_SIZE];
u32 m_XFRegs[XF_REGS_SIZE];
u8 m_TexMem[TEX_MEM_SIZE];
u32 m_ram_size_real;
u32 m_exram_size_real;

u32 m_Flags = 0;
u32 m_Version = 0;
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/FifoPlayer/FifoPlayer.cpp
Expand Up @@ -356,9 +356,9 @@ void FifoPlayer::WriteMemory(const MemoryUpdate& memUpdate)
u8* mem = nullptr;

if (memUpdate.address & 0x10000000)
mem = &Memory::m_pEXRAM[memUpdate.address & Memory::EXRAM_MASK];
mem = &Memory::m_pEXRAM[memUpdate.address & Memory::GetExRamMask()];
else
mem = &Memory::m_pRAM[memUpdate.address & Memory::RAM_MASK];
mem = &Memory::m_pRAM[memUpdate.address & Memory::GetRamMask()];

std::copy(memUpdate.data.begin(), memUpdate.data.end(), mem);
}
Expand Down
12 changes: 6 additions & 6 deletions Source/Core/Core/FifoPlayer/FifoRecorder.cpp
Expand Up @@ -36,8 +36,8 @@ void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb)
// - Global variables suck
// - Multithreading with the above two sucks
//
m_Ram.resize(Memory::RAM_SIZE);
m_ExRam.resize(Memory::EXRAM_SIZE);
m_Ram.resize(Memory::GetRamSize());
m_ExRam.resize(Memory::GetExRamSize());

std::fill(m_Ram.begin(), m_Ram.end(), 0);
std::fill(m_ExRam.begin(), m_ExRam.end(), 0);
Expand Down Expand Up @@ -121,13 +121,13 @@ void FifoRecorder::UseMemory(u32 address, u32 size, MemoryUpdate::Type type, boo
u8* newData;
if (address & 0x10000000)
{
curData = &m_ExRam[address & Memory::EXRAM_MASK];
newData = &Memory::m_pEXRAM[address & Memory::EXRAM_MASK];
curData = &m_ExRam[address & Memory::GetExRamMask()];
newData = &Memory::m_pEXRAM[address & Memory::GetExRamMask()];
}
else
{
curData = &m_Ram[address & Memory::RAM_MASK];
newData = &Memory::m_pRAM[address & Memory::RAM_MASK];
curData = &m_Ram[address & Memory::GetRamMask()];
newData = &Memory::m_pRAM[address & Memory::GetRamMask()];
}

if (!dynamicUpdate && memcmp(curData, newData, size) != 0)
Expand Down
25 changes: 17 additions & 8 deletions Source/Core/Core/HW/AddressSpace.cpp
Expand Up @@ -234,6 +234,7 @@ struct AccessorMapping

struct CompositeAddressSpaceAccessors : Accessors
{
CompositeAddressSpaceAccessors() = default;
CompositeAddressSpaceAccessors(std::initializer_list<AccessorMapping> accessors)
: m_accessor_mappings(accessors.begin(), accessors.end())
{
Expand Down Expand Up @@ -303,6 +304,7 @@ struct CompositeAddressSpaceAccessors : Accessors

struct SmallBlockAccessors : Accessors
{
SmallBlockAccessors() = default;
SmallBlockAccessors(u8** alloc_base_, u32 size_) : alloc_base{alloc_base_}, size{size_} {}

bool IsValidAddress(u32 address) const override
Expand Down Expand Up @@ -366,14 +368,11 @@ struct NullAccessors : Accessors

static EffectiveAddressSpaceAccessors s_effective_address_space_accessors;
static AuxiliaryAddressSpaceAccessors s_auxiliary_address_space_accessors;
static SmallBlockAccessors s_mem1_address_space_accessors{&Memory::m_pRAM, Memory::REALRAM_SIZE};
static SmallBlockAccessors s_mem2_address_space_accessors{&Memory::m_pEXRAM, Memory::EXRAM_SIZE};
static SmallBlockAccessors s_fake_address_space_accessors{&Memory::m_pFakeVMEM,
Memory::FAKEVMEM_SIZE};
static CompositeAddressSpaceAccessors s_physical_address_space_accessors_gcn{
{0x00000000, &s_mem1_address_space_accessors}};
static CompositeAddressSpaceAccessors s_physical_address_space_accessors_wii{
{0x00000000, &s_mem1_address_space_accessors}, {0x10000000, &s_mem2_address_space_accessors}};
static SmallBlockAccessors s_mem1_address_space_accessors;
static SmallBlockAccessors s_mem2_address_space_accessors;
static SmallBlockAccessors s_fake_address_space_accessors;
static CompositeAddressSpaceAccessors s_physical_address_space_accessors_gcn;
static CompositeAddressSpaceAccessors s_physical_address_space_accessors_wii;
static NullAccessors s_null_accessors;

Accessors* GetAccessors(Type address_space)
Expand Down Expand Up @@ -413,4 +412,14 @@ Accessors* GetAccessors(Type address_space)
return &s_null_accessors;
}

void Init()
{
s_mem1_address_space_accessors = {&Memory::m_pRAM, Memory::GetRamSizeReal()};
s_mem2_address_space_accessors = {&Memory::m_pEXRAM, Memory::GetExRamSizeReal()};
s_fake_address_space_accessors = {&Memory::m_pFakeVMEM, Memory::GetFakeVMemSize()};
s_physical_address_space_accessors_gcn = {{0x00000000, &s_mem1_address_space_accessors}};
s_physical_address_space_accessors_wii = {{0x00000000, &s_mem1_address_space_accessors},
{0x10000000, &s_mem2_address_space_accessors}};
}

} // namespace AddressSpace
2 changes: 2 additions & 0 deletions Source/Core/Core/HW/AddressSpace.h
Expand Up @@ -47,4 +47,6 @@ struct Accessors

Accessors* GetAccessors(Type address_space);

void Init();

} // namespace AddressSpace

0 comments on commit 4b00ddf

Please sign in to comment.