@@ -155,28 +155,28 @@ class MemoryManager
u8* m_logical_page_mappings_base = nullptr;

// The actual memory used for backing the memory map.
u8* m_ram;
u8* m_exram;
u8* m_l1_cache;
u8* m_fake_vmem;
u8* m_ram = nullptr;
u8* m_exram = nullptr;
u8* m_l1_cache = nullptr;
u8* m_fake_vmem = nullptr;

// m_ram_size is the amount allocated by the emulator, whereas m_ram_size_real
// is what will be reported in lowmem, and thus used by emulated software.
// Note: Writing to lowmem is done by IPL. If using retail IPL, it will
// always be set to 24MB.
u32 m_ram_size_real;
u32 m_ram_size;
u32 m_ram_mask;
u32 m_fakevmem_size;
u32 m_fakevmem_mask;
u32 m_l1_cache_size;
u32 m_l1_cache_mask;
u32 m_ram_size_real = 0;
u32 m_ram_size = 0;
u32 m_ram_mask = 0;
u32 m_fakevmem_size = 0;
u32 m_fakevmem_mask = 0;
u32 m_l1_cache_size = 0;
u32 m_l1_cache_mask = 0;
// m_exram_size is the amount allocated by the emulator, whereas m_exram_size_real
// is what gets used by emulated software. If using retail IOS, it will
// always be set to 64MB.
u32 m_exram_size_real;
u32 m_exram_size;
u32 m_exram_mask;
u32 m_exram_size_real = 0;
u32 m_exram_size = 0;
u32 m_exram_mask = 0;

bool m_is_fastmem_arena_initialized = false;

@@ -231,12 +231,12 @@ class MemoryManager
//
// TODO: The actual size of RAM is 24MB; the other 8MB shouldn't be backed by actual memory.
// TODO: Do we want to handle the mirrors of the GC RAM?
std::array<PhysicalMemoryRegion, 4> m_physical_regions;
std::array<PhysicalMemoryRegion, 4> m_physical_regions{};

std::vector<LogicalMemoryView> m_logical_mapped_entries;

std::array<void*, PowerPC::BAT_PAGE_COUNT> m_physical_page_mappings;
std::array<void*, PowerPC::BAT_PAGE_COUNT> m_logical_page_mappings;
std::array<void*, PowerPC::BAT_PAGE_COUNT> m_physical_page_mappings{};
std::array<void*, PowerPC::BAT_PAGE_COUNT> m_logical_page_mappings{};

void InitMMIO(bool is_wii);
};
@@ -85,12 +85,12 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
MMIO::DirectWrite<u32>(&m_fifo_cpu_write_pointer, 0xFFFFFFE0));

mmio->Register(base | PI_FIFO_RESET, MMIO::InvalidRead<u32>(),
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
// Used by GXAbortFrame
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_FIFO_RESET: {:08x}", val);
if ((val & 1) != 0)
{
GPFifo::ResetGatherPipe();
system.GetGPFifo().ResetGatherPipe();

// Call Fifo::ResetVideoBuffer() from the video thread. Since that function
// resets various pointers used by the video thread, we can't call it directly
@@ -12,6 +12,7 @@
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"

/*
@@ -244,7 +245,7 @@ void Interpreter::mfspr(UGeckoInstruction inst)
// GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)).
// Currently, we always treat the buffer as not empty, as the exact behavior is unclear
// (and games that use display lists will hang if the bit doesn't eventually become zero).
if (GPFifo::IsBNE())
if (Core::System::GetInstance().GetGPFifo().IsBNE())
rSPR(index) |= 1;
else
rSPR(index) &= ~1;
@@ -370,7 +371,7 @@ void Interpreter::mtspr(UGeckoInstruction inst)
case SPR_WPAR:
ASSERT_MSG(POWERPC, rSPR(SPR_WPAR) == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS,
"Gather pipe changed to unexpected address {:08x} @ PC {:08x}", rSPR(SPR_WPAR), PC);
GPFifo::ResetGatherPipe();
Core::System::GetInstance().GetGPFifo().ResetGatherPipe();
break;

// Graphics Quantization Registers
@@ -527,7 +527,7 @@ bool Jit64::Cleanup()
CMP(64, R(RSCRATCH), Imm32(GPFifo::GATHER_PIPE_SIZE));
FixupBranch exit = J_CC(CC_L);
ABI_PushRegistersAndAdjustStack({}, 0);
ABI_CallFunction(GPFifo::UpdateGatherPipe);
ABI_CallFunctionP(GPFifo::UpdateGatherPipe, &Core::System::GetInstance().GetGPFifo());
ABI_PopRegistersAndAdjustStack({}, 0);
SetJumpTarget(exit);
did_something = true;
@@ -1027,7 +1027,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
js.mustCheckFifo = false;
BitSet32 registersInUse = CallerSavedRegistersInUse();
ABI_PushRegistersAndAdjustStack(registersInUse, 0);
ABI_CallFunction(GPFifo::FastCheckGatherPipe);
ABI_CallFunctionP(GPFifo::FastCheckGatherPipe, &Core::System::GetInstance().GetGPFifo());
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
gatherPipeIntCheck = true;
}
@@ -281,8 +281,9 @@ void JitArm64::Cleanup()
SUB(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X1);
CMP(ARM64Reg::X0, GPFifo::GATHER_PIPE_SIZE);
FixupBranch exit = B(CC_LT);
MOVP2R(ARM64Reg::X0, &GPFifo::UpdateGatherPipe);
BLR(ARM64Reg::X0);
MOVP2R(ARM64Reg::X1, &GPFifo::UpdateGatherPipe);
MOVP2R(ARM64Reg::X0, &Core::System::GetInstance().GetGPFifo());
BLR(ARM64Reg::X1);
SetJumpTarget(exit);
}

@@ -965,6 +966,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
ABI_PushRegisters(regs_in_use);
m_float_emit.ABI_PushRegisters(fprs_in_use, ARM64Reg::X30);
MOVP2R(ARM64Reg::X8, &GPFifo::FastCheckGatherPipe);
MOVP2R(ARM64Reg::X0, &Core::System::GetInstance().GetGPFifo());
BLR(ARM64Reg::X8);
m_float_emit.ABI_PopRegisters(fprs_in_use, ARM64Reg::X30);
ABI_PopRegisters(regs_in_use);
@@ -332,20 +332,21 @@ static void WriteToHardware(Core::System& system, Memory::MemoryManager& memory,
switch (size)
{
case 1:
GPFifo::Write8(static_cast<u8>(data));
system.GetGPFifo().Write8(static_cast<u8>(data));
return;
case 2:
GPFifo::Write16(static_cast<u16>(data));
system.GetGPFifo().Write16(static_cast<u16>(data));
return;
case 4:
GPFifo::Write32(data);
system.GetGPFifo().Write32(data);
return;
default:
// Some kind of misaligned write. TODO: Does this match how the actual hardware handles it?
auto& gpfifo = system.GetGPFifo();
for (size_t i = size * 8; i > 0;)
{
i -= 8;
GPFifo::Write8(static_cast<u8>(data >> i));
gpfifo.Write8(static_cast<u8>(data >> i));
}
return;
}
@@ -13,6 +13,7 @@
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/DVD/DVDThread.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/GPFifo.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/MemoryInterface.h"
#include "Core/HW/ProcessorInterface.h"
@@ -30,6 +31,8 @@ namespace Core
{
struct System::Impl
{
explicit Impl(System& system) : m_gp_fifo(system) {}

std::unique_ptr<SoundStream> m_sound_stream;
bool m_sound_stream_running = false;
bool m_audio_dump_started = false;
@@ -43,6 +46,7 @@ struct System::Impl
ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state;
Fifo::FifoManager m_fifo;
GeometryShaderManager m_geometry_shader_manager;
GPFifo::GPFifoManager m_gp_fifo;
Memory::MemoryManager m_memory;
MemoryInterface::MemoryInterfaceState m_memory_interface_state;
PixelEngine::PixelEngineManager m_pixel_engine;
@@ -54,7 +58,7 @@ struct System::Impl
VideoInterface::VideoInterfaceState m_video_interface_state;
};

System::System() : m_impl{std::make_unique<Impl>()}
System::System() : m_impl{std::make_unique<Impl>(*this)}
{
}

@@ -142,6 +146,11 @@ GeometryShaderManager& System::GetGeometryShaderManager() const
return m_impl->m_geometry_shader_manager;
}

GPFifo::GPFifoManager& System::GetGPFifo() const
{
return m_impl->m_gp_fifo;
}

Memory::MemoryManager& System::GetMemory() const
{
return m_impl->m_memory;
@@ -43,6 +43,10 @@ namespace Fifo
{
class FifoManager;
}
namespace GPFifo
{
class GPFifoManager;
}
namespace Memory
{
class MemoryManager;
@@ -111,6 +115,7 @@ class System
ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const;
Fifo::FifoManager& GetFifo() const;
GeometryShaderManager& GetGeometryShaderManager() const;
GPFifo::GPFifoManager& GetGPFifo() const;
Memory::MemoryManager& GetMemory() const;
MemoryInterface::MemoryInterfaceState& GetMemoryInterfaceState() const;
PixelEngine::PixelEngineManager& GetPixelEngine() const;