dolphin/Source/Core/Core/Debugger/PPCDebugInterface.cpp
magumagu ac54c6a4e2 Make address translation respect the CPU translation mode.
The PowerPC CPU has bits in MSR (DR and IR) which control whether
addresses are translated. We should respect these instead of mixing
physical addresses and translated addresses into the same address space.

This is mostly mass-renaming calls to memory accesses APIs from places
which expect address translation to use a different version from those
which do not expect address translation.

This does very little on its own, but it's the first step to a correct BAT
implementation.
2015-02-11 13:56:22 -08:00

225 lines
4.8 KiB
C++

// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <string>
#include "Common/GekkoDisassembler.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/Debugger/Debugger_SymbolMap.h"
#include "Core/Debugger/PPCDebugInterface.h"
#include "Core/HW/CPU.h"
#include "Core/HW/DSP.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
std::string PPCDebugInterface::Disassemble(unsigned int address)
{
// PowerPC::HostRead_U32 seemed to crash on shutdown
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
return "";
if (Core::GetState() == Core::CORE_PAUSE)
{
if (!PowerPC::HostIsRAMAddress(address))
{
return "(No RAM here)";
}
u32 op = PowerPC::HostRead_Instruction(address);
std::string disasm = GekkoDisassembler::Disassemble(op, address);
UGeckoInstruction inst;
inst.hex = PowerPC::HostRead_U32(address);
if (inst.OPCD == 1)
{
disasm += " (hle)";
}
return disasm;
}
else
{
return "<unknown>";
}
}
void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size)
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
if (memory || PowerPC::HostIsRAMAddress(address))
{
snprintf(dest, max_size, "%08X%s", ReadExtraMemory(memory, address), memory ? " (ARAM)" : "");
}
else
{
strcpy(dest, memory ? "--ARAM--" : "--------");
}
}
else
{
strcpy(dest, "<unknwn>"); // bad spelling - 8 chars
}
}
unsigned int PPCDebugInterface::ReadMemory(unsigned int address)
{
return PowerPC::HostRead_U32(address);
}
unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address)
{
switch (memory)
{
case 0:
return PowerPC::HostRead_U32(address);
case 1:
return (DSP::ReadARAM(address) << 24) |
(DSP::ReadARAM(address + 1) << 16) |
(DSP::ReadARAM(address + 2) << 8) |
(DSP::ReadARAM(address + 3));
default:
return 0;
}
}
unsigned int PPCDebugInterface::ReadInstruction(unsigned int address)
{
return PowerPC::HostRead_Instruction(address);
}
bool PPCDebugInterface::IsAlive()
{
return Core::GetState() != Core::CORE_UNINITIALIZED;
}
bool PPCDebugInterface::IsBreakpoint(unsigned int address)
{
return PowerPC::breakpoints.IsAddressBreakPoint(address);
}
void PPCDebugInterface::SetBreakpoint(unsigned int address)
{
PowerPC::breakpoints.Add(address);
}
void PPCDebugInterface::ClearBreakpoint(unsigned int address)
{
PowerPC::breakpoints.Remove(address);
}
void PPCDebugInterface::ClearAllBreakpoints()
{
PowerPC::breakpoints.Clear();
}
void PPCDebugInterface::ToggleBreakpoint(unsigned int address)
{
if (PowerPC::breakpoints.IsAddressBreakPoint(address))
PowerPC::breakpoints.Remove(address);
else
PowerPC::breakpoints.Add(address);
}
void PPCDebugInterface::AddWatch(unsigned int address)
{
PowerPC::watches.Add(address);
}
void PPCDebugInterface::ClearAllMemChecks()
{
PowerPC::memchecks.Clear();
}
bool PPCDebugInterface::IsMemCheck(unsigned int address)
{
return (Memory::AreMemoryBreakpointsActivated() &&
PowerPC::memchecks.GetMemCheck(address));
}
void PPCDebugInterface::ToggleMemCheck(unsigned int address)
{
if (Memory::AreMemoryBreakpointsActivated() &&
!PowerPC::memchecks.GetMemCheck(address))
{
// Add Memory Check
TMemCheck MemCheck;
MemCheck.StartAddress = address;
MemCheck.EndAddress = address;
MemCheck.OnRead = true;
MemCheck.OnWrite = true;
MemCheck.Log = true;
MemCheck.Break = true;
PowerPC::memchecks.Add(MemCheck);
}
else
PowerPC::memchecks.Remove(address);
}
void PPCDebugInterface::InsertBLR(unsigned int address, unsigned int value)
{
PowerPC::HostWrite_U32(value, address);
}
void PPCDebugInterface::BreakNow()
{
CCPU::Break();
}
// =======================================================
// Separate the blocks with colors.
// -------------
int PPCDebugInterface::GetColor(unsigned int address)
{
if (!IsAlive())
return 0xFFFFFF;
if (!PowerPC::HostIsRAMAddress(address))
return 0xeeeeee;
static const int colors[6] =
{
0xd0FFFF, // light cyan
0xFFd0d0, // light red
0xd8d8FF, // light blue
0xFFd0FF, // light purple
0xd0FFd0, // light green
0xFFFFd0, // light yellow
};
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(address);
if (!symbol)
return 0xFFFFFF;
if (symbol->type != Symbol::SYMBOL_FUNCTION)
return 0xEEEEFF;
return colors[symbol->index % 6];
}
// =============
std::string PPCDebugInterface::GetDescription(unsigned int address)
{
return g_symbolDB.GetDescription(address);
}
unsigned int PPCDebugInterface::GetPC()
{
return PowerPC::ppcState.pc;
}
void PPCDebugInterface::SetPC(unsigned int address)
{
PowerPC::ppcState.pc = address;
}
void PPCDebugInterface::RunToBreakpoint()
{
}