mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #1856 from magumagu/correct-translation-disable-2
Make address translation respect the CPU translation mode
This commit is contained in:
@@ -127,12 +127,12 @@ void MemArena::ReleaseView(void* view, size_t size)
|
||||
}
|
||||
|
||||
|
||||
u8* MemArena::Find4GBBase()
|
||||
u8* MemArena::FindMemoryBase()
|
||||
{
|
||||
#if _ARCH_64
|
||||
#ifdef _WIN32
|
||||
// 64 bit
|
||||
u8* base = (u8*)VirtualAlloc(0, 0xE1000000, MEM_RESERVE, PAGE_READWRITE);
|
||||
u8* base = (u8*)VirtualAlloc(0, 0x400000000, MEM_RESERVE, PAGE_READWRITE);
|
||||
VirtualFree(base, 0, MEM_RELEASE);
|
||||
return base;
|
||||
#else
|
||||
@@ -250,7 +250,7 @@ u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena
|
||||
arena->GrabSHMSegment(total_mem);
|
||||
|
||||
// Now, create views in high memory where there's plenty of space.
|
||||
u8 *base = MemArena::Find4GBBase();
|
||||
u8 *base = MemArena::FindMemoryBase();
|
||||
// This really shouldn't fail - in 64-bit, there will always be enough
|
||||
// address space.
|
||||
if (!Memory_TryBase(base, views, num_views, flags, arena))
|
||||
|
||||
@@ -24,8 +24,8 @@ public:
|
||||
void *CreateView(s64 offset, size_t size, void *base = nullptr);
|
||||
void ReleaseView(void *view, size_t size);
|
||||
|
||||
// This only finds 1 GB in 32-bit
|
||||
static u8 *Find4GBBase();
|
||||
// This finds 1 GB in 32-bit, 16 GB in 64-bit.
|
||||
static u8 *FindMemoryBase();
|
||||
private:
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -44,7 +44,7 @@ enum {
|
||||
struct MemoryView
|
||||
{
|
||||
u8** out_ptr;
|
||||
u32 virtual_address;
|
||||
u64 virtual_address;
|
||||
u32 size;
|
||||
u32 flags;
|
||||
void* mapped_ptr;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "Core/ARDecrypt.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
namespace ActionReplay
|
||||
{
|
||||
@@ -320,7 +320,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data)
|
||||
u32 repeat = data >> 8;
|
||||
for (u32 i = 0; i <= repeat; ++i)
|
||||
{
|
||||
Memory::Write_U8(data & 0xFF, new_addr + i);
|
||||
PowerPC::HostWrite_U8(data & 0xFF, new_addr + i);
|
||||
LogInfo("Wrote %08x to address %08x", data & 0xFF, new_addr + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
@@ -334,7 +334,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data)
|
||||
u32 repeat = data >> 16;
|
||||
for (u32 i = 0; i <= repeat; ++i)
|
||||
{
|
||||
Memory::Write_U16(data & 0xFFFF, new_addr + i * 2);
|
||||
PowerPC::HostWrite_U16(data & 0xFFFF, new_addr + i * 2);
|
||||
LogInfo("Wrote %08x to address %08x", data & 0xFFFF, new_addr + i * 2);
|
||||
}
|
||||
LogInfo("--------");
|
||||
@@ -345,7 +345,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data)
|
||||
case DATATYPE_32BIT: // Dword write
|
||||
LogInfo("32-bit Write");
|
||||
LogInfo("--------");
|
||||
Memory::Write_U32(data, new_addr);
|
||||
PowerPC::HostWrite_U32(data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", data, new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
@@ -364,7 +364,7 @@ static bool Subtype_RamWriteAndFill(const ARAddr& addr, const u32 data)
|
||||
static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data)
|
||||
{
|
||||
const u32 new_addr = addr.GCAddress();
|
||||
const u32 ptr = Memory::Read_U32(new_addr);
|
||||
const u32 ptr = PowerPC::HostRead_U32(new_addr);
|
||||
|
||||
LogInfo("Hardware Address: %08x", new_addr);
|
||||
LogInfo("Size: %08x", addr.size);
|
||||
@@ -380,7 +380,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data)
|
||||
LogInfo("Pointer: %08x", ptr);
|
||||
LogInfo("Byte: %08x", thebyte);
|
||||
LogInfo("Offset: %08x", offset);
|
||||
Memory::Write_U8(thebyte, ptr + offset);
|
||||
PowerPC::HostWrite_U8(thebyte, ptr + offset);
|
||||
LogInfo("Wrote %08x to address %08x", thebyte, ptr + offset);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
@@ -395,7 +395,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data)
|
||||
LogInfo("Pointer: %08x", ptr);
|
||||
LogInfo("Byte: %08x", theshort);
|
||||
LogInfo("Offset: %08x", offset);
|
||||
Memory::Write_U16(theshort, ptr + offset);
|
||||
PowerPC::HostWrite_U16(theshort, ptr + offset);
|
||||
LogInfo("Wrote %08x to address %08x", theshort, ptr + offset);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
@@ -405,7 +405,7 @@ static bool Subtype_WriteToPointer(const ARAddr& addr, const u32 data)
|
||||
case DATATYPE_32BIT:
|
||||
LogInfo("Write 32-bit to pointer");
|
||||
LogInfo("--------");
|
||||
Memory::Write_U32(data, ptr);
|
||||
PowerPC::HostWrite_U32(data, ptr);
|
||||
LogInfo("Wrote %08x to address %08x", data, ptr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
@@ -433,24 +433,24 @@ static bool Subtype_AddCode(const ARAddr& addr, const u32 data)
|
||||
case DATATYPE_8BIT:
|
||||
LogInfo("8-bit Add");
|
||||
LogInfo("--------");
|
||||
Memory::Write_U8(Memory::Read_U8(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", Memory::Read_U8(new_addr) + (data & 0xFF), new_addr);
|
||||
PowerPC::HostWrite_U8(PowerPC::HostRead_U8(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(new_addr) + (data & 0xFF), new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
||||
case DATATYPE_16BIT:
|
||||
LogInfo("16-bit Add");
|
||||
LogInfo("--------");
|
||||
Memory::Write_U16(Memory::Read_U16(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", Memory::Read_U16(new_addr) + (data & 0xFFFF), new_addr);
|
||||
PowerPC::HostWrite_U16(PowerPC::HostRead_U16(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U16(new_addr) + (data & 0xFFFF), new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
||||
case DATATYPE_32BIT:
|
||||
LogInfo("32-bit Add");
|
||||
LogInfo("--------");
|
||||
Memory::Write_U32(Memory::Read_U32(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", Memory::Read_U32(new_addr) + data, new_addr);
|
||||
PowerPC::HostWrite_U32(PowerPC::HostRead_U32(new_addr) + data, new_addr);
|
||||
LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U32(new_addr) + data, new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
||||
@@ -459,10 +459,10 @@ static bool Subtype_AddCode(const ARAddr& addr, const u32 data)
|
||||
LogInfo("32-bit floating Add");
|
||||
LogInfo("--------");
|
||||
|
||||
const u32 read = Memory::Read_U32(new_addr);
|
||||
const u32 read = PowerPC::HostRead_U32(new_addr);
|
||||
const float fread = *((float*)&read) + (float)data; // data contains an integer value
|
||||
const u32 newval = *((u32*)&fread);
|
||||
Memory::Write_U32(newval, new_addr);
|
||||
PowerPC::HostWrite_U32(newval, new_addr);
|
||||
LogInfo("Old Value %08x", read);
|
||||
LogInfo("Increment %08x", data);
|
||||
LogInfo("New value %08x", newval);
|
||||
@@ -517,7 +517,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const
|
||||
LogInfo("--------");
|
||||
for (int i = 0; i < write_num; ++i)
|
||||
{
|
||||
Memory::Write_U8(val & 0xFF, curr_addr);
|
||||
PowerPC::HostWrite_U8(val & 0xFF, curr_addr);
|
||||
curr_addr += addr_incr;
|
||||
val += val_incr;
|
||||
LogInfo("Write %08x to address %08x", val & 0xFF, curr_addr);
|
||||
@@ -533,7 +533,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const
|
||||
LogInfo("--------");
|
||||
for (int i=0; i < write_num; ++i)
|
||||
{
|
||||
Memory::Write_U16(val & 0xFFFF, curr_addr);
|
||||
PowerPC::HostWrite_U16(val & 0xFFFF, curr_addr);
|
||||
LogInfo("Write %08x to address %08x", val & 0xFFFF, curr_addr);
|
||||
curr_addr += addr_incr * 2;
|
||||
val += val_incr;
|
||||
@@ -548,7 +548,7 @@ static bool ZeroCode_FillAndSlide(const u32 val_last, const ARAddr& addr, const
|
||||
LogInfo("--------");
|
||||
for (int i = 0; i < write_num; ++i)
|
||||
{
|
||||
Memory::Write_U32(val, curr_addr);
|
||||
PowerPC::HostWrite_U32(val, curr_addr);
|
||||
LogInfo("Write %08x to address %08x", val, curr_addr);
|
||||
curr_addr += addr_incr * 4;
|
||||
val += val_incr;
|
||||
@@ -586,8 +586,8 @@ static bool ZeroCode_MemoryCopy(const u32 val_last, const ARAddr& addr, const u3
|
||||
LogInfo("--------");
|
||||
for (int i = 0; i < 138; ++i)
|
||||
{
|
||||
Memory::Write_U8(Memory::Read_U8(addr_src + i), addr_dest + i);
|
||||
LogInfo("Wrote %08x to address %08x", Memory::Read_U8(addr_src + i), addr_dest + i);
|
||||
PowerPC::HostWrite_U8(PowerPC::HostRead_U8(addr_src + i), addr_dest + i);
|
||||
LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(addr_src + i), addr_dest + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
}
|
||||
@@ -597,8 +597,8 @@ static bool ZeroCode_MemoryCopy(const u32 val_last, const ARAddr& addr, const u3
|
||||
LogInfo("--------");
|
||||
for (int i=0; i < num_bytes; ++i)
|
||||
{
|
||||
Memory::Write_U8(Memory::Read_U8(addr_src + i), addr_dest + i);
|
||||
LogInfo("Wrote %08x to address %08x", Memory::ReadUnchecked_U8(addr_src + i), addr_dest + i);
|
||||
PowerPC::HostWrite_U8(PowerPC::HostRead_U8(addr_src + i), addr_dest + i);
|
||||
LogInfo("Wrote %08x to address %08x", PowerPC::HostRead_U8(addr_src + i), addr_dest + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
return true;
|
||||
@@ -709,16 +709,16 @@ static bool ConditionalCode(const ARAddr& addr, const u32 data, int* const pSkip
|
||||
switch (addr.size)
|
||||
{
|
||||
case DATATYPE_8BIT:
|
||||
result = CompareValues((u32)Memory::Read_U8(new_addr), (data & 0xFF), addr.type);
|
||||
result = CompareValues((u32)PowerPC::HostRead_U8(new_addr), (data & 0xFF), addr.type);
|
||||
break;
|
||||
|
||||
case DATATYPE_16BIT:
|
||||
result = CompareValues((u32)Memory::Read_U16(new_addr), (data & 0xFFFF), addr.type);
|
||||
result = CompareValues((u32)PowerPC::HostRead_U16(new_addr), (data & 0xFFFF), addr.type);
|
||||
break;
|
||||
|
||||
case DATATYPE_32BIT_FLOAT:
|
||||
case DATATYPE_32BIT:
|
||||
result = CompareValues(Memory::Read_U32(new_addr), data, addr.type);
|
||||
result = CompareValues(PowerPC::HostRead_U32(new_addr), data, addr.type);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -39,10 +39,10 @@ void CBoot::Load_FST(bool _bIsWii)
|
||||
return;
|
||||
|
||||
// copy first 20 bytes of disc to start of Mem 1
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x80000000), 0, 0x20, false);
|
||||
DVDInterface::DVDRead(/*offset*/0, /*address*/0, /*length*/0x20, false);
|
||||
|
||||
// copy of game id
|
||||
Memory::Write_U32(Memory::Read_U32(0x80000000), 0x80003180);
|
||||
Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
|
||||
|
||||
u32 shift = 0;
|
||||
if (_bIsWii)
|
||||
@@ -56,7 +56,7 @@ void CBoot::Load_FST(bool _bIsWii)
|
||||
Memory::Write_U32(arenaHigh, 0x00000034);
|
||||
|
||||
// load FST
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(arenaHigh), fstOffset, fstSize, _bIsWii);
|
||||
DVDInterface::DVDRead(fstOffset, arenaHigh, fstSize, _bIsWii);
|
||||
Memory::Write_U32(arenaHigh, 0x00000038);
|
||||
Memory::Write_U32(maxFstSize, 0x0000003c);
|
||||
}
|
||||
@@ -188,9 +188,9 @@ bool CBoot::Load_BS2(const std::string& _rBootROMFilename)
|
||||
// Run the descrambler over the encrypted section containing BS1/BS2
|
||||
CEXIIPL::Descrambler((u8*)data.data()+0x100, 0x1AFE00);
|
||||
|
||||
Memory::CopyToEmu(0x81200000, data.data() + 0x100, 0x700);
|
||||
Memory::CopyToEmu(0x81300000, data.data() + 0x820, 0x1AFE00);
|
||||
PC = 0x81200000;
|
||||
Memory::CopyToEmu(0x01200000, data.data() + 0x100, 0x700);
|
||||
Memory::CopyToEmu(0x01300000, data.data() + 0x820, 0x1AFE00);
|
||||
PC = 0x01200000;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ bool CBoot::BootUp()
|
||||
}
|
||||
|
||||
// Scan for common HLE functions
|
||||
if (_StartupPara.bSkipIdle && !_StartupPara.bEnableDebugging)
|
||||
if (_StartupPara.bSkipIdle && _StartupPara.bHLE_BS2 && !_StartupPara.bEnableDebugging)
|
||||
{
|
||||
PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
|
||||
SignatureDB db;
|
||||
@@ -309,6 +309,25 @@ bool CBoot::BootUp()
|
||||
|
||||
if (!BS2Success)
|
||||
{
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
|
||||
dolLoader.Load();
|
||||
PC = dolLoader.GetEntryPoint();
|
||||
}
|
||||
@@ -403,7 +422,7 @@ bool CBoot::BootUp()
|
||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||
{
|
||||
HLE::Patch(0x80001800, "HBReload");
|
||||
Memory::CopyToEmu(0x80001804, "STUBHAXX", 8);
|
||||
Memory::CopyToEmu(0x00001804, "STUBHAXX", 8);
|
||||
}
|
||||
|
||||
// Not part of the binary itself, but either we or Gecko OS might insert
|
||||
|
||||
@@ -41,6 +41,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
@@ -54,28 +57,28 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
// Write necessary values
|
||||
// Here we write values to memory that the apploader does not take care of. Game info goes
|
||||
// to 0x80000000 according to YAGCD 4.2.
|
||||
DVDInterface::DVDRead(0x00000000, 0x80000000, 0x20, false); // write disc info
|
||||
DVDInterface::DVDRead(/*offset*/0x00000000, /*address*/0x00000000, 0x20, false); // write disc info
|
||||
|
||||
Memory::Write_U32(0x0D15EA5E, 0x80000020); // Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||
Memory::Write_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
|
||||
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020); // Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||
PowerPC::HostWrite_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
|
||||
// TODO determine why some games fail when using a retail ID. (Seem to take different EXI paths, see Ikaruga for example)
|
||||
Memory::Write_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
|
||||
PowerPC::HostWrite_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
|
||||
|
||||
Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC
|
||||
PowerPC::HostWrite_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC
|
||||
? 0 : 1, 0x800000CC); // Fake the VI Init of the IPL (YAGCD 4.2.1.4)
|
||||
|
||||
Memory::Write_U32(0x01000000, 0x800000d0); // ARAM Size. 16MB main + 4/16/32MB external (retail consoles have no external ARAM)
|
||||
PowerPC::HostWrite_U32(0x01000000, 0x800000d0); // ARAM Size. 16MB main + 4/16/32MB external (retail consoles have no external ARAM)
|
||||
|
||||
Memory::Write_U32(0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
Memory::Write_U32(0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
PowerPC::HostWrite_U32(0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
PowerPC::HostWrite_U32(0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
|
||||
Memory::Write_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
PowerPC::HostWrite_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
|
||||
Memory::Write_U64((u64)CEXIIPL::GetGCTime() * (u64)40500000, 0x800030D8); // Preset time base ticks
|
||||
PowerPC::HostWrite_U64((u64)CEXIIPL::GetGCTime() * (u64)40500000, 0x800030D8); // Preset time base ticks
|
||||
// HIO checks this
|
||||
//Memory::Write_U16(0x8200, 0x000030e6); // Console type
|
||||
//PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type
|
||||
|
||||
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
|
||||
|
||||
@@ -89,7 +92,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
INFO_LOG(BOOT, "GC BS2: Not running apploader!");
|
||||
return false;
|
||||
}
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize, false);
|
||||
DVDInterface::DVDRead(iAppLoaderOffset + 0x20, 0x01200000, iAppLoaderSize, false);
|
||||
|
||||
// Setup pointers like real BS2 does
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC)
|
||||
@@ -114,9 +117,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(iAppLoaderEntry);
|
||||
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr + 8);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderInit");
|
||||
@@ -135,9 +138,9 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
|
||||
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
|
||||
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c);
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c);
|
||||
|
||||
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength, false);
|
||||
@@ -239,7 +242,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
0x80000060 Copyright code
|
||||
*/
|
||||
|
||||
DVDInterface::DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code
|
||||
DVDInterface::DVDRead(0x00000000, 0x00000000, 0x20, false); // Game 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
|
||||
@@ -253,12 +256,12 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
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_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(0x00000000, 0x000030d8); // Time
|
||||
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
|
||||
Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable
|
||||
Memory::Write_U32(0x00000000, 0x000030f0); // Apploader
|
||||
Memory::Write_U32(0x01800000, 0x00003100); // BAT
|
||||
Memory::Write_U32(0x01800000, 0x00003104); // BAT
|
||||
@@ -275,7 +278,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
// 40 is copied from 88 after running apploader
|
||||
Memory::Write_U32(0x00090204, 0x00003140); // IOS revision (IOS9, v2.4)
|
||||
Memory::Write_U32(0x00062507, 0x00003144); // IOS date in USA format (June 25, 2007)
|
||||
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
|
||||
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
|
||||
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
|
||||
Memory::Write_U32(0x00000000, 0x00003160); // Init semaphore (sysmenu waits for this to clear)
|
||||
Memory::Write_U32(0x00090204, 0x00003188); // Expected IOS revision
|
||||
@@ -290,7 +293,7 @@ bool CBoot::SetupWiiMemory(IVolume::ECountry country)
|
||||
// Clear exception handler. Why? Don't we begin with only zeros?
|
||||
for (int i = 0x3000; i <= 0x3038; i += 4)
|
||||
{
|
||||
Memory::Write_U32(0x00000000, 0x80000000 + i);
|
||||
Memory::Write_U32(0x00000000, i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -314,7 +317,7 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// values as the game boots. This location keep the 4 byte ID for as long
|
||||
// as the game is running. The 6 byte ID at 0x00 is overwritten sometime
|
||||
// after this check during booting.
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4, true);
|
||||
DVDInterface::DVDRead(0, 0x3180, 4, true);
|
||||
|
||||
// Execute the apploader
|
||||
bool apploaderRan = false;
|
||||
@@ -323,9 +326,12 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
@@ -336,9 +342,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
|
||||
Memory::Write_U32(0x4c000064, 0x80000300); // Write default DFI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x00000300); // Write default DSI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x00000800); // Write default FPU Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x00000C00); // Write default Syscall Handler: rfi
|
||||
|
||||
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
|
||||
|
||||
@@ -354,7 +360,7 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
|
||||
return false;
|
||||
}
|
||||
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize, true);
|
||||
DVDInterface::DVDRead(iAppLoaderOffset + 0x20, 0x01200000, iAppLoaderSize, true);
|
||||
|
||||
//call iAppLoaderEntry
|
||||
DEBUG_LOG(BOOT, "Call iAppLoaderEntry");
|
||||
@@ -364,9 +370,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(iAppLoaderEntry);
|
||||
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
|
||||
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
|
||||
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(BOOT, "Run iAppLoaderInit");
|
||||
@@ -387,9 +393,9 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
|
||||
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
|
||||
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c) << 2;
|
||||
|
||||
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength, true);
|
||||
@@ -404,8 +410,8 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
// Pass the "#002 check"
|
||||
// Apploader writes the IOS version and revision here, we copy it
|
||||
// Fake IOSv9 r2.4 if no version is found (elf loading)
|
||||
u32 firmwareVer = Memory::Read_U32(0x80003188);
|
||||
Memory::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x00003140);
|
||||
u32 firmwareVer = PowerPC::Read_U32(0x80003188);
|
||||
PowerPC::Write_U32(firmwareVer ? firmwareVer : 0x00090204, 0x80003140);
|
||||
|
||||
// Load patches and run startup patches
|
||||
PatchEngine::LoadPatches();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "Core/Boot/Boot_DOL.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size)
|
||||
: m_isWii(false)
|
||||
|
||||
@@ -107,7 +107,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
||||
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
||||
}
|
||||
pDolLoader->Load();
|
||||
PC = pDolLoader->GetEntryPoint() | 0x80000000;
|
||||
PC = pDolLoader->GetEntryPoint();
|
||||
|
||||
// Pass the "#002 check"
|
||||
// Apploader should write the IOS version and revision to 0x3140, and compare it
|
||||
|
||||
@@ -109,7 +109,6 @@ set(SRCS ActionReplay.cpp
|
||||
HW/GPFifo.cpp
|
||||
HW/HW.cpp
|
||||
HW/Memmap.cpp
|
||||
HW/MemmapFunctions.cpp
|
||||
HW/MemoryInterface.cpp
|
||||
HW/MMIO.cpp
|
||||
HW/ProcessorInterface.cpp
|
||||
@@ -153,6 +152,7 @@ set(SRCS ActionReplay.cpp
|
||||
IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp
|
||||
IPC_HLE/WII_IPC_HLE_WiiMote.cpp
|
||||
IPC_HLE/WiiMote_HID_Attr.cpp
|
||||
PowerPC/MMU.cpp
|
||||
PowerPC/PowerPC.cpp
|
||||
PowerPC/PPCAnalyst.cpp
|
||||
PowerPC/PPCCache.cpp
|
||||
|
||||
@@ -140,7 +140,6 @@
|
||||
<ClCompile Include="HW\GPFifo.cpp" />
|
||||
<ClCompile Include="HW\HW.cpp" />
|
||||
<ClCompile Include="HW\Memmap.cpp" />
|
||||
<ClCompile Include="HW\MemmapFunctions.cpp" />
|
||||
<ClCompile Include="HW\MemoryInterface.cpp" />
|
||||
<ClCompile Include="HW\MMIO.cpp" />
|
||||
<ClCompile Include="HW\ProcessorInterface.cpp" />
|
||||
@@ -245,6 +244,7 @@
|
||||
<ClCompile Include="PowerPC\JitCommon\Jit_Util.cpp" />
|
||||
<ClCompile Include="PowerPC\JitCommon\TrampolineCache.cpp" />
|
||||
<ClCompile Include="PowerPC\JitInterface.cpp" />
|
||||
<ClCompile Include="PowerPC\MMU.cpp" />
|
||||
<ClCompile Include="PowerPC\PowerPC.cpp" />
|
||||
<ClCompile Include="PowerPC\PPCAnalyst.cpp" />
|
||||
<ClCompile Include="PowerPC\PPCCache.cpp" />
|
||||
|
||||
@@ -512,9 +512,6 @@
|
||||
<ClCompile Include="HW\Memmap.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\MemmapFunctions.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\MMIO.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29</Filter>
|
||||
</ClCompile>
|
||||
@@ -726,6 +723,8 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\GCKeyboard.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
|
||||
<ClCompile Include="PowerPC\MMU.cpp">
|
||||
<Filter>PowerPC</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -39,27 +39,27 @@ void AddAutoBreakpoints()
|
||||
// Returns true if the address is not a valid RAM address or NULL.
|
||||
static bool IsStackBottom(u32 addr)
|
||||
{
|
||||
return !addr || !Memory::IsRAMAddress(addr);
|
||||
return !addr || !PowerPC::HostIsRAMAddress(addr);
|
||||
}
|
||||
|
||||
static void WalkTheStack(const std::function<void(u32)>& stack_step)
|
||||
{
|
||||
if (!IsStackBottom(PowerPC::ppcState.gpr[1]))
|
||||
{
|
||||
u32 addr = Memory::ReadUnchecked_U32(PowerPC::ppcState.gpr[1]); // SP
|
||||
u32 addr = PowerPC::HostRead_U32(PowerPC::ppcState.gpr[1]); // SP
|
||||
|
||||
// Walk the stack chain
|
||||
for (int count = 0;
|
||||
!IsStackBottom(addr + 4) && (count++ < 20);
|
||||
++count)
|
||||
{
|
||||
u32 func_addr = Memory::ReadUnchecked_U32(addr + 4);
|
||||
u32 func_addr = PowerPC::HostRead_U32(addr + 4);
|
||||
stack_step(func_addr);
|
||||
|
||||
if (IsStackBottom(addr))
|
||||
break;
|
||||
|
||||
addr = Memory::ReadUnchecked_U32(addr);
|
||||
addr = PowerPC::HostRead_U32(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ static void WalkTheStack(const std::function<void(u32)>& stack_step)
|
||||
// instead of "pointing ahead"
|
||||
bool GetCallstack(std::vector<CallstackEntry> &output)
|
||||
{
|
||||
if (!Core::IsRunning() || !Memory::IsRAMAddress(PowerPC::ppcState.gpr[1]))
|
||||
if (!Core::IsRunning() || !PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[1]))
|
||||
return false;
|
||||
|
||||
if (LR == 0)
|
||||
|
||||
@@ -19,26 +19,22 @@
|
||||
|
||||
std::string PPCDebugInterface::Disassemble(unsigned int address)
|
||||
{
|
||||
// Memory::ReadUnchecked_U32 seemed to crash on shutdown
|
||||
// PowerPC::HostRead_U32 seemed to crash on shutdown
|
||||
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
|
||||
return "";
|
||||
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
if (Core::GetState() == Core::CORE_PAUSE)
|
||||
{
|
||||
if (!Memory::IsRAMAddress(address, true, true))
|
||||
if (!PowerPC::HostIsRAMAddress(address))
|
||||
{
|
||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || !((address & JIT_ICACHE_VMEM_BIT) &&
|
||||
Memory::TranslateAddress<Memory::FLAG_NO_EXCEPTION>(address)))
|
||||
{
|
||||
return "(No RAM here)";
|
||||
}
|
||||
return "(No RAM here)";
|
||||
}
|
||||
|
||||
u32 op = Memory::Read_Instruction(address);
|
||||
u32 op = PowerPC::HostRead_Instruction(address);
|
||||
std::string disasm = GekkoDisassembler::Disassemble(op, address);
|
||||
|
||||
UGeckoInstruction inst;
|
||||
inst.hex = Memory::ReadUnchecked_U32(address);
|
||||
inst.hex = PowerPC::HostRead_U32(address);
|
||||
|
||||
if (inst.OPCD == 1)
|
||||
{
|
||||
@@ -57,7 +53,7 @@ void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha
|
||||
{
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
{
|
||||
if (memory || Memory::IsRAMAddress(address, true, true))
|
||||
if (memory || PowerPC::HostIsRAMAddress(address))
|
||||
{
|
||||
snprintf(dest, max_size, "%08X%s", ReadExtraMemory(memory, address), memory ? " (ARAM)" : "");
|
||||
}
|
||||
@@ -74,7 +70,7 @@ void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha
|
||||
|
||||
unsigned int PPCDebugInterface::ReadMemory(unsigned int address)
|
||||
{
|
||||
return Memory::ReadUnchecked_U32(address);
|
||||
return PowerPC::HostRead_U32(address);
|
||||
}
|
||||
|
||||
unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address)
|
||||
@@ -82,7 +78,7 @@ unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address
|
||||
switch (memory)
|
||||
{
|
||||
case 0:
|
||||
return Memory::ReadUnchecked_U32(address);
|
||||
return PowerPC::HostRead_U32(address);
|
||||
case 1:
|
||||
return (DSP::ReadARAM(address) << 24) |
|
||||
(DSP::ReadARAM(address + 1) << 16) |
|
||||
@@ -95,7 +91,7 @@ unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address
|
||||
|
||||
unsigned int PPCDebugInterface::ReadInstruction(unsigned int address)
|
||||
{
|
||||
return Memory::Read_Instruction(address);
|
||||
return PowerPC::HostRead_Instruction(address);
|
||||
}
|
||||
|
||||
bool PPCDebugInterface::IsAlive()
|
||||
@@ -170,7 +166,7 @@ void PPCDebugInterface::ToggleMemCheck(unsigned int address)
|
||||
|
||||
void PPCDebugInterface::InsertBLR(unsigned int address, unsigned int value)
|
||||
{
|
||||
Memory::Write_U32(value, address);
|
||||
PowerPC::HostWrite_U32(value, address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::BreakNow()
|
||||
@@ -184,7 +180,9 @@ void PPCDebugInterface::BreakNow()
|
||||
// -------------
|
||||
int PPCDebugInterface::GetColor(unsigned int address)
|
||||
{
|
||||
if (!Memory::IsRAMAddress(address, true, true))
|
||||
if (!IsAlive())
|
||||
return 0xFFFFFF;
|
||||
if (!PowerPC::HostIsRAMAddress(address))
|
||||
return 0xeeeeee;
|
||||
static const int colors[6] =
|
||||
{
|
||||
|
||||
@@ -348,6 +348,17 @@ void FifoPlayer::SetupFifo()
|
||||
|
||||
void FifoPlayer::LoadMemory()
|
||||
{
|
||||
UReg_MSR newMSR;
|
||||
newMSR.DR = 1;
|
||||
newMSR.IR = 1;
|
||||
MSR = newMSR.Hex;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
|
||||
Memory::Clear();
|
||||
|
||||
SetupFifo();
|
||||
@@ -391,12 +402,12 @@ void FifoPlayer::LoadMemory()
|
||||
|
||||
void FifoPlayer::WriteCP(u32 address, u16 value)
|
||||
{
|
||||
Memory::Write_U16(value, 0xCC000000 | address);
|
||||
PowerPC::Write_U16(value, 0xCC000000 | address);
|
||||
}
|
||||
|
||||
void FifoPlayer::WritePI(u32 address, u32 value)
|
||||
{
|
||||
Memory::Write_U32(value, 0xCC003000 | address);
|
||||
PowerPC::Write_U32(value, 0xCC003000 | address);
|
||||
}
|
||||
|
||||
void FifoPlayer::FlushWGP()
|
||||
|
||||
@@ -90,16 +90,17 @@ static bool InstallCodeHandler()
|
||||
}
|
||||
|
||||
// Install code handler
|
||||
Memory::CopyToEmu(INSTALLER_BASE_ADDRESS, data.data(), data.length());
|
||||
for (size_t i = 0, e = data.length(); i < e; ++i)
|
||||
PowerPC::HostWrite_U8(data[i], (u32)(INSTALLER_BASE_ADDRESS + i));
|
||||
|
||||
// Patch the code handler to the system starting up
|
||||
for (unsigned int h = 0; h < data.length(); h += 4)
|
||||
{
|
||||
// Patch MMIO address
|
||||
if (Memory::ReadUnchecked_U32(INSTALLER_BASE_ADDRESS + h) == (0x3f000000u | ((mmioAddr ^ 1) << 8)))
|
||||
if (PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS + h) == (0x3f000000u | ((mmioAddr ^ 1) << 8)))
|
||||
{
|
||||
NOTICE_LOG(ACTIONREPLAY, "Patching MMIO access at %08x", INSTALLER_BASE_ADDRESS + h);
|
||||
Memory::Write_U32(0x3f000000u | mmioAddr << 8, INSTALLER_BASE_ADDRESS + h);
|
||||
PowerPC::HostWrite_U32(0x3f000000u | mmioAddr << 8, INSTALLER_BASE_ADDRESS + h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,11 +108,11 @@ static bool InstallCodeHandler()
|
||||
u32 codelist_end_address = INSTALLER_END_ADDRESS;
|
||||
|
||||
// Write a magic value to 'gameid' (codehandleronly does not actually read this).
|
||||
Memory::Write_U32(0xd01f1bad, INSTALLER_BASE_ADDRESS);
|
||||
PowerPC::HostWrite_U32(0xd01f1bad, INSTALLER_BASE_ADDRESS);
|
||||
|
||||
// Create GCT in memory
|
||||
Memory::Write_U32(0x00d0c0de, codelist_base_address);
|
||||
Memory::Write_U32(0x00d0c0de, codelist_base_address + 4);
|
||||
PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address);
|
||||
PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address + 4);
|
||||
|
||||
std::lock_guard<std::mutex> lk(active_codes_lock);
|
||||
|
||||
@@ -126,19 +127,19 @@ static bool InstallCodeHandler()
|
||||
// Make sure we have enough memory to hold the code list
|
||||
if ((codelist_base_address + 24 + i) < codelist_end_address)
|
||||
{
|
||||
Memory::Write_U32(code.address, codelist_base_address + 8 + i);
|
||||
Memory::Write_U32(code.data, codelist_base_address + 12 + i);
|
||||
PowerPC::HostWrite_U32(code.address, codelist_base_address + 8 + i);
|
||||
PowerPC::HostWrite_U32(code.data, codelist_base_address + 12 + i);
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory::Write_U32(0xff000000, codelist_base_address + 8 + i);
|
||||
Memory::Write_U32(0x00000000, codelist_base_address + 12 + i);
|
||||
PowerPC::HostWrite_U32(0xff000000, codelist_base_address + 8 + i);
|
||||
PowerPC::HostWrite_U32(0x00000000, codelist_base_address + 12 + i);
|
||||
|
||||
// Turn on codes
|
||||
Memory::Write_U8(1, INSTALLER_BASE_ADDRESS + 7);
|
||||
PowerPC::HostWrite_U8(1, INSTALLER_BASE_ADDRESS + 7);
|
||||
|
||||
// Invalidate the icache and any asm codes
|
||||
for (unsigned int j = 0; j < (INSTALLER_END_ADDRESS - INSTALLER_BASE_ADDRESS); j += 32)
|
||||
@@ -156,7 +157,7 @@ void RunCodeHandler()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats && active_codes.size() > 0)
|
||||
{
|
||||
if (!code_handler_installed || Memory::Read_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5)
|
||||
if (!code_handler_installed || PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5)
|
||||
code_handler_installed = InstallCodeHandler();
|
||||
|
||||
if (!code_handler_installed)
|
||||
|
||||
@@ -63,7 +63,7 @@ void HLEGeckoCodehandler()
|
||||
// robust alternative would be to actually detect memory writes, but that
|
||||
// would be even uglier.)
|
||||
u32 magic = 0xd01f1bad;
|
||||
u32 existing = Memory::Read_U32(0x80001800);
|
||||
u32 existing = PowerPC::HostRead_U32(0x80001800);
|
||||
if (existing - magic == 5)
|
||||
{
|
||||
return;
|
||||
@@ -72,7 +72,7 @@ void HLEGeckoCodehandler()
|
||||
{
|
||||
existing = magic;
|
||||
}
|
||||
Memory::Write_U32(existing + 1, 0x80001800);
|
||||
PowerPC::HostWrite_U32(existing + 1, 0x80001800);
|
||||
PowerPC::ppcState.iCache.Reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ void HLE_OSPanic()
|
||||
void HLE_GeneralDebugPrint()
|
||||
{
|
||||
std::string ReportMessage;
|
||||
if (Memory::Read_U32(GPR(3)) > 0x80000000)
|
||||
if (PowerPC::HostRead_U32(GPR(3)) > 0x80000000)
|
||||
{
|
||||
GetStringVA(ReportMessage, 4);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg)
|
||||
std::string ArgumentBuffer = "";
|
||||
u32 ParameterCounter = strReg+1;
|
||||
u32 FloatingParameterCounter = 1;
|
||||
std::string string = Memory::GetString(GPR(strReg));
|
||||
std::string string = PowerPC::HostGetString(GPR(strReg));
|
||||
|
||||
for(u32 i = 0; i < string.size(); i++)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg)
|
||||
u64 Parameter;
|
||||
if (ParameterCounter > 10)
|
||||
{
|
||||
Parameter = Memory::Read_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
|
||||
Parameter = PowerPC::HostRead_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,7 +101,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg)
|
||||
switch (string[i])
|
||||
{
|
||||
case 's':
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), Memory::GetString((u32)Parameter).c_str());
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), PowerPC::HostGetString((u32)Parameter).c_str());
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
@@ -135,7 +135,7 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg)
|
||||
_rOutBuffer += string[i];
|
||||
}
|
||||
}
|
||||
if (_rOutBuffer[_rOutBuffer.length() - 1] == '\n')
|
||||
if (!_rOutBuffer.empty() && _rOutBuffer[_rOutBuffer.length() - 1] == '\n')
|
||||
_rOutBuffer.resize(_rOutBuffer.length() - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,12 @@ void DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address, cha
|
||||
|
||||
unsigned int DSPDebugInterface::ReadMemory(unsigned int address)
|
||||
{
|
||||
return 0; //Memory::ReadUnchecked_U32(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int DSPDebugInterface::ReadInstruction(unsigned int address)
|
||||
{
|
||||
return 0; //Memory::Read_Instruction(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::IsAlive()
|
||||
|
||||
@@ -185,7 +185,9 @@ bool DSPLLE::Initialize(bool bWii, bool bDSPThread)
|
||||
return false;
|
||||
|
||||
// DSPLLE directly accesses the fastmem arena.
|
||||
g_dsp.cpu_ram = Memory::base;
|
||||
// TODO: The fastmem arena is only supposed to be used by the JIT:
|
||||
// among other issues, its size is only 1GB on 32-bit targets.
|
||||
g_dsp.cpu_ram = Memory::physical_base;
|
||||
DSPCore_Reset();
|
||||
|
||||
InitInstructionTable();
|
||||
|
||||
@@ -470,7 +470,7 @@ void SetLidOpen(bool _bOpen)
|
||||
|
||||
bool DVDRead(u64 _iDVDOffset, u32 _iRamAddress, u32 _iLength, bool decrypt)
|
||||
{
|
||||
return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength, decrypt);
|
||||
return VolumeHandler::ReadToPtr(Memory::GetPointer(_iRamAddress), _iDVDOffset, _iLength, decrypt);
|
||||
}
|
||||
|
||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
|
||||
+116
-107
@@ -53,7 +53,8 @@ static bool bMMU = false;
|
||||
// Init() declarations
|
||||
// ----------------
|
||||
// Store the MemArena here
|
||||
u8* base = nullptr;
|
||||
u8* physical_base = nullptr;
|
||||
u8* logical_base = nullptr;
|
||||
|
||||
// The MemArena class
|
||||
static MemArena g_arena;
|
||||
@@ -102,17 +103,60 @@ bool IsInitialized()
|
||||
}
|
||||
|
||||
|
||||
// We don't declare the IO region in here since its handled by other means.
|
||||
// Dolphin allocates memory to represent four regions:
|
||||
// - 24MB RAM, available on Gamecube and Wii
|
||||
// - 64MB "EXRAM", RAM only available on Wii
|
||||
// - 64MB FakeVMem, allocated when MMU support is turned off. This is used
|
||||
// to approximate the behavior of a common library which pages memory to
|
||||
// and from the DSP's dedicated RAM, which isn't directly addressable on
|
||||
// GameCube.
|
||||
// - 256KB Locked L1, to represent cache lines allocated out of the L1 data cache
|
||||
// cache in Locked L1 mode. Dolphin does not emulate this hardware feature
|
||||
// accurately; it just pretends there is extra memory at 0xE0000000.
|
||||
//
|
||||
// The 4GB starting at physical_base represents access from the CPU
|
||||
// with address translation turned off. (This is only used by the CPU;
|
||||
// other devices, like the GPU, use other rules, approximated by
|
||||
// Memory::GetPointer.) This memory is laid out as follows:
|
||||
// [0x00000000, 0x01800000) - 24MB RAM
|
||||
// [0x08000000, 0x0C000000) - EFB "mapping" (not handled here)
|
||||
// [0x0C000000, 0x0E000000) - MMIO etc. (not handled here)
|
||||
// [0x10000000, 0x14000000) - 64MB RAM (Wii-only; slightly slower)
|
||||
//
|
||||
// The 4GB starting at logical_base represents access from the CPU
|
||||
// with address translation turned on. Instead of changing the mapping
|
||||
// based on the BAT registers, we approximate the common BAT configuration
|
||||
// used by games:
|
||||
// [0x00000000, 0x01800000) - 24MB RAM, cached access, normally only mapped
|
||||
// during startup by Wii WADs
|
||||
// [0x40000000, 0x50000000) - FakeVMEM
|
||||
// [0x70000000, 0x80000000) - FakeVMEM
|
||||
// [0x80000000, 0x81800000) - 24MB RAM, cached access
|
||||
// [0x90000000, 0x94000000) - 64MB RAM, Wii-only, cached access
|
||||
// [0xC0000000, 0xC1800000) - 24MB RAM, uncached access
|
||||
// [0xC8000000, 0xCC000000) - EFB "mapping" (not handled here)
|
||||
// [0xCC000000, 0xCE000000) - MMIO etc. (not handled here)
|
||||
// [0xD0000000, 0xD4000000) - 64MB RAM, Wii-only, uncached access
|
||||
// [0xE0000000, 0xE0040000) - 256KB locked L1
|
||||
//
|
||||
// TODO: We shouldn't hardcode this mapping; we can generate it dynamically
|
||||
// based on the BAT registers.
|
||||
//
|
||||
// Each of these 4GB regions is followed by 4GB of empty space so overflows
|
||||
// in address computation in the JIT don't access the wrong memory.
|
||||
//
|
||||
// Dolphin doesn't emulate the difference between cached and uncached access.
|
||||
static MemoryView views[] =
|
||||
{
|
||||
{&m_pRAM, 0x00000000, RAM_SIZE, 0},
|
||||
{nullptr, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
|
||||
{&m_pL1Cache, 0xE0000000, L1_CACHE_SIZE, 0},
|
||||
{&m_pFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM},
|
||||
{nullptr, 0x200000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0x280000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0x2C0000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
|
||||
{&m_pL1Cache, 0x2E0000000, L1_CACHE_SIZE, 0},
|
||||
{&m_pFakeVMEM, 0x27E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM},
|
||||
{&m_pEXRAM, 0x10000000, EXRAM_SIZE, MV_WII_ONLY},
|
||||
{nullptr, 0x90000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0xD0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0x290000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS},
|
||||
{nullptr, 0x2D0000000, EXRAM_SIZE, MV_WII_ONLY | MV_MIRROR_PREVIOUS},
|
||||
};
|
||||
static const int num_views = sizeof(views) / sizeof(MemoryView);
|
||||
|
||||
@@ -129,7 +173,10 @@ void Init()
|
||||
u32 flags = 0;
|
||||
if (wii) flags |= MV_WII_ONLY;
|
||||
if (bFakeVMEM) flags |= MV_FAKE_VMEM;
|
||||
base = MemoryMap_Setup(views, num_views, flags, &g_arena);
|
||||
physical_base = MemoryMap_Setup(views, num_views, flags, &g_arena);
|
||||
#ifndef _ARCH_32
|
||||
logical_base = physical_base + 0x200000000;
|
||||
#endif
|
||||
|
||||
mmio_mapping = new MMIO::Mapping();
|
||||
|
||||
@@ -164,7 +211,8 @@ void Shutdown()
|
||||
if (bFakeVMEM) flags |= MV_FAKE_VMEM;
|
||||
MemoryMap_Shutdown(views, num_views, flags, &g_arena);
|
||||
g_arena.ReleaseSHMSegment();
|
||||
base = nullptr;
|
||||
physical_base = nullptr;
|
||||
logical_base = nullptr;
|
||||
delete mmio_mapping;
|
||||
INFO_LOG(MEMMAP, "Memory system shut down.");
|
||||
}
|
||||
@@ -188,12 +236,6 @@ bool AreMemoryBreakpointsActivated()
|
||||
#endif
|
||||
}
|
||||
|
||||
u32 Read_Instruction(const u32 address)
|
||||
{
|
||||
UGeckoInstruction inst = ReadUnchecked_U32(address);
|
||||
return inst.hex;
|
||||
}
|
||||
|
||||
static inline bool ValidCopyRange(u32 address, size_t size)
|
||||
{
|
||||
return (GetPointer(address) != nullptr &&
|
||||
@@ -228,19 +270,6 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength)
|
||||
{
|
||||
memset(ptr,_iValue,_iLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < _iLength; i++)
|
||||
Write_U8(_iValue, _Address + i);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearCacheLine(const u32 address)
|
||||
{
|
||||
// FIXME: does this do the right thing if dcbz is run on hardware memory, e.g.
|
||||
// the FIFO? Do games even do that? Probably not, but we should try to be correct...
|
||||
for (u32 i = 0; i < 32; i += 8)
|
||||
Write_U64(0, address + i);
|
||||
}
|
||||
|
||||
std::string GetString(u32 em_address, size_t size)
|
||||
@@ -260,93 +289,73 @@ std::string GetString(u32 em_address, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPointer must always return an address in the bottom 32 bits of address space, so that 64-bit
|
||||
// programs don't have problems directly addressing any part of memory.
|
||||
// TODO re-think with respect to other BAT setups...
|
||||
u8* GetPointer(const u32 address)
|
||||
u8* GetPointer(u32 address)
|
||||
{
|
||||
switch (address >> 28)
|
||||
// TODO: Should we be masking off more bits here? Can all devices access
|
||||
// EXRAM?
|
||||
address &= 0x3FFFFFFF;
|
||||
if (address < REALRAM_SIZE)
|
||||
return m_pRAM + address;
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x8:
|
||||
if ((address & 0xfffffff) < REALRAM_SIZE)
|
||||
return m_pRAM + (address & RAM_MASK);
|
||||
break;
|
||||
case 0xc:
|
||||
switch (address >> 24)
|
||||
{
|
||||
case 0xcc:
|
||||
case 0xcd:
|
||||
_dbg_assert_msg_(MEMMAP, 0, "GetPointer from IO Bridge doesnt work");
|
||||
break;
|
||||
case 0xc8:
|
||||
// EFB. We don't want to return a pointer here since we have no memory mapped for it.
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((address & 0xfffffff) < REALRAM_SIZE)
|
||||
return m_pRAM + (address & RAM_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
case 0x9:
|
||||
case 0xd:
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||
{
|
||||
if ((address & 0xfffffff) < EXRAM_SIZE)
|
||||
return m_pEXRAM + (address & EXRAM_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
if (address < (0xE0000000 + L1_CACHE_SIZE))
|
||||
return m_pL1Cache + (address & L1_CACHE_MASK);
|
||||
else
|
||||
break;
|
||||
|
||||
default:
|
||||
if (bFakeVMEM)
|
||||
return m_pFakeVMEM + (address & FAKEVMEM_MASK);
|
||||
break;
|
||||
if ((address >> 28) == 0x1 && (address & 0x0fffffff) < EXRAM_SIZE)
|
||||
return m_pEXRAM + (address & EXRAM_MASK);
|
||||
}
|
||||
|
||||
ERROR_LOG(MEMMAP, "Unknown Pointer %#8x PC %#8x LR %#8x", address, PC, LR);
|
||||
PanicAlert("Unknown Pointer 0x%08x PC 0x%08x LR 0x%08x", address, PC, LR);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IsRAMAddress(const u32 address, bool allow_locked_cache, bool allow_fake_vmem)
|
||||
u8 Read_U8(u32 address)
|
||||
{
|
||||
switch ((address >> 24) & 0xFC)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x80:
|
||||
case 0xC0:
|
||||
if ((address & 0x1FFFFFFF) < RAM_SIZE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 0x10:
|
||||
case 0x90:
|
||||
case 0xD0:
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && (address & 0x0FFFFFFF) < EXRAM_SIZE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 0xE0:
|
||||
if (allow_locked_cache && address - 0xE0000000 < L1_CACHE_SIZE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
case 0x7C:
|
||||
if (allow_fake_vmem && bFakeVMEM && address >= 0x7E000000)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return *GetPointer(address);
|
||||
}
|
||||
|
||||
u16 Read_U16(u32 address)
|
||||
{
|
||||
return Common::swap16(GetPointer(address));
|
||||
}
|
||||
|
||||
u32 Read_U32(u32 address)
|
||||
{
|
||||
return Common::swap32(GetPointer(address));
|
||||
}
|
||||
|
||||
u64 Read_U64(u32 address)
|
||||
{
|
||||
return Common::swap64(GetPointer(address));
|
||||
}
|
||||
|
||||
void Write_U8(u8 value, u32 address)
|
||||
{
|
||||
*GetPointer(address) = value;
|
||||
}
|
||||
|
||||
void Write_U16(u16 value, u32 address)
|
||||
{
|
||||
*(u16*)GetPointer(address) = Common::swap16(value);
|
||||
}
|
||||
|
||||
void Write_U32(u32 value, u32 address)
|
||||
{
|
||||
*(u32*)GetPointer(address) = Common::swap32(value);
|
||||
}
|
||||
|
||||
void Write_U64(u64 value, u32 address)
|
||||
{
|
||||
*(u64*)GetPointer(address) = Common::swap64(value);
|
||||
}
|
||||
|
||||
void Write_U32_Swap(u32 value, u32 address)
|
||||
{
|
||||
*(u32*)GetPointer(address) = value;
|
||||
}
|
||||
|
||||
void Write_U64_Swap(u64 value, u32 address)
|
||||
{
|
||||
*(u64*)GetPointer(address) = value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user