Skip to content

Commit

Permalink
Debugger GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasnoble committed Apr 23, 2019
1 parent 68806a2 commit 44baf7d
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 36 deletions.
21 changes: 14 additions & 7 deletions src/core/debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,32 +88,40 @@ void PCSX::Debug::DebugCheckBP(uint32_t address, BreakpointType type) {
if (m_mapping_w16 && type == BW2) MarkMap(address, MAP_W16);
if (m_mapping_w32 && type == BW4) MarkMap(address, MAP_W32);

for (auto& bp : m_breakpoints) {
if ((bp.m_type == type) && (bp.m_address == address)) {
for (auto it = m_breakpoints.begin(); it != m_breakpoints.end(); it++) {
if ((it->m_type == type) && (it->m_address == address)) {
m_lastBP = it;
PCSX::g_system->pause();
return;
}
}

if (m_breakmp_e && type == BE && !IsMapMarked(address, MAP_EXEC)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_r8 && type == BR1 && !IsMapMarked(address, MAP_R8)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_r16 && type == BR2 && !IsMapMarked(address, MAP_R16)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_r32 && type == BR4 && !IsMapMarked(address, MAP_R32)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_w8 && type == BW1 && !IsMapMarked(address, MAP_W8)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_w16 && type == BW2 && !IsMapMarked(address, MAP_W16)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
} else if (m_breakmp_w32 && type == BW4 && !IsMapMarked(address, MAP_W32)) {
m_lastBP = m_breakpoints.end();
PCSX::g_system->pause();
return;
}
Expand All @@ -125,11 +133,11 @@ std::string PCSX::Debug::GenerateFlowIDC() {
ss << "static main(void) {\r\n";
for (uint32_t i = 0; i < 0x00200000; i++) {
if (IsMapMarked(i, MAP_EXEC_JAL)) {
ss << "\tMakeFunction(0X8" << std ::hex << std::setw(7) << std::setfill('0') << i << ", BADADDR);\r\n ";
ss << "\tMakeFunction(0X8" << std::hex << std::setw(7) << std::setfill('0') << i << ", BADADDR);\r\n ";
}
}
ss << "}\r\n";
return ss.str;
return ss.str();
}

std::string PCSX::Debug::GenerateMarkIDC() {
Expand All @@ -138,10 +146,9 @@ std::string PCSX::Debug::GenerateMarkIDC() {
ss << "static main(void) {\r\n";
for (uint32_t i = 0; i < 0x00200000; i++) {
if (IsMapMarked(i, MAP_EXEC)) {
ss << "\tMakeCode(0X8" << std ::hex << std::setw(7) << std::setfill('0') << i << ");\r\n";
ss << "\tMakeCode(0X8" << std::hex << std::setw(7) << std::setfill('0') << i << ");\r\n";
}

}
ss << "}\r\n";
return ss.str;
return ss.str();
}
21 changes: 15 additions & 6 deletions src/core/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#pragma once

#include <functional>
#include <list>
#include <string>

Expand All @@ -39,6 +40,8 @@ class Debug {

class Breakpoint {
public:
BreakpointType Type() const { return m_type; }
uint32_t Address() const { return m_address; }
Breakpoint(uint32_t address, BreakpointType type) : m_address(address), m_type(type) {}

private:
Expand All @@ -48,18 +51,24 @@ class Debug {
};

private:
using BreakpointList = std::list<Breakpoint>;
using bpiterator = BreakpointList::const_iterator;
typedef std::list<Breakpoint> BreakpointList;

public:
bpiterator bpBegin() const { return m_breakpoints.cbegin(); }
bpiterator bpEnd() const { return m_breakpoints.cend(); }
void erase(bpiterator pos) { m_breakpoints.erase(pos); }
typedef BreakpointList::const_iterator bpiterator;
inline void AddBreakpoint(uint32_t address, BreakpointType type) { m_breakpoints.emplace_back(address, type); }
inline void ForEachBP(std::function<bool(bpiterator)> lambda) {
for (auto i = m_breakpoints.begin(); i != m_breakpoints.end(); i++) {
if (!lambda(i)) return;
}
}
inline void EraseBP(bpiterator pos) { m_breakpoints.erase(pos); }
inline bool HasLastBP() { return m_lastBP != m_breakpoints.end(); }
inline bpiterator LastBP() { return m_lastBP; }

private:
BreakpointList m_breakpoints;
bpiterator m_lastBP = m_breakpoints.end();

bool m_mapping_e = false;
bool m_mapping_e = false;
bool m_mapping_r8 = false, m_mapping_r16 = false, m_mapping_r32 = false;
bool m_mapping_w8 = false, m_mapping_w16 = false, m_mapping_w32 = false;
Expand Down
2 changes: 0 additions & 2 deletions src/core/psxcounters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,6 @@ void PCSX::Counters::psxRcntUpdate() {
PCSX::g_emulator.EmuUpdate();
}
}

PCSX::g_emulator.m_debug->DebugVSync();
}

/******************************************************************************/
Expand Down
1 change: 0 additions & 1 deletion src/core/r3000a.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ int PCSX::R3000Acpu::psxInit() {
}

PGXP_Init();
PCSX::g_emulator.m_debug->PauseDebugger();

return g_emulator.m_psxCpu->Init();
}
Expand Down
143 changes: 123 additions & 20 deletions src/gui/widgets/assembly.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/

#include <functional>

#include "imgui.h"

#include "core/debug.h"
#include "core/disr3000a.h"
#include "core/psxmem.h"
#include "core/r3000a.h"
Expand Down Expand Up @@ -156,6 +159,17 @@ class ImGuiAsm : public PCSX::Disasm {
sameLine();
ImGui::Text("0x%2.2x", value);
}
inline uint8_t* ptr(uint32_t addr) {
uint8_t* lut = m_memory->g_psxMemRLUT[addr >> 16];
if (lut) {
return lut + (addr & 0xffff);
} else {
return nullptr;
}
}
inline uint8_t mem8(uint32_t addr) { return *ptr(addr); }
inline uint16_t mem16(uint32_t addr) { return SWAP_LE16(*(int16_t*)ptr(addr)); }
inline uint32_t mem32(uint32_t addr) { return SWAP_LE32(*(int32_t*)ptr(addr)); }
virtual void OfB(int16_t offset, uint8_t reg, int size) {
comma();
sameLine();
Expand All @@ -166,13 +180,13 @@ class ImGuiAsm : public PCSX::Disasm {
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
switch (size) {
case 1:
ImGui::Text("[%8.8x] = %2.2x", addr, psxMu8(addr));
ImGui::Text("[%8.8x] = %2.2x", addr, mem8(addr));
break;
case 2:
ImGui::Text("[%8.8x] = %4.4x", addr, psxMu16(addr));
ImGui::Text("[%8.8x] = %4.4x", addr, mem16(addr));
break;
case 4:
ImGui::Text("[%8.8x] = %8.8x", addr, psxMu32(addr));
ImGui::Text("[%8.8x] = %8.8x", addr, mem32(addr));
break;
}
ImGui::PopTextWrapPos();
Expand Down Expand Up @@ -202,32 +216,121 @@ void PCSX::Widgets::Assembly::draw(psxRegisters* registers, Memory* memory, cons
return;
}

uint32_t pc = registers->pc & 0x1fffff;
DummyAsm dummy;
ImGuiAsm imguiAsm(registers, memory);

uint32_t base = (registers->pc >> 20) & 0xffc;
uint32_t real = registers->pc & 0x1fffff;
uint32_t pc = real;
if ((base == 0x000) || (base == 0x800) || (base == 0xa00)) {
// main memory first
if (real >= 0x00200000) pc = 0;
} else if (base == 0x1f0) {
// parallel port second
if (real >= 0x00010000) {
pc = 0;
} else {
pc += 0x00200000;
}
} else if (base == 0xbfc) {
// bios last
if (real >= 0x00080000) {
pc = 0;
} else {
pc += 0x00210000;
}
}
ImGui::Checkbox("Follow PC", &m_followPC);
ImGui::BeginChild("##ScrollingRegion", ImVec2(0, 0), true, ImGuiWindowFlags_HorizontalScrollbar);
ImGuiListClipper clipper(2 * 1024 * 1024 / 4);
ImGuiListClipper clipper(0x00290000 / 4);

while (clipper.Step()) {
bool skipNext = false;
if (clipper.DisplayStart != 0) {
uint32_t addr = clipper.DisplayStart * 4 - 4;
uint32_t code = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr);
typedef std::function<void(uint32_t, const char*, uint32_t)> prependType;
auto process = [&](uint32_t addr, prependType prepend, PCSX::Disasm* disasm) {
uint32_t code = 0;
uint32_t nextCode = 0;
if (addr <= 0x1ffff8) {
nextCode = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr + 4);
uint32_t base = 0;
const char* section = "UNK";
if (addr <= 0x00200000) {
section = "RAM";
code = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr);
if (addr <= 0x001ffff8) {
nextCode = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr + 4);
}
base = 0x80000000;
} else if (addr <= 0x00210000) {
section = "PAR";
addr -= 0x00200000;
code = *reinterpret_cast<uint32_t*>(memory->g_psxP + addr);
if (addr <= 0x0000fff8) {
nextCode = *reinterpret_cast<uint32_t*>(memory->g_psxP + addr);
}
base = 0x1f000000;
} else if (addr <= 0x00290000) {
section = "ROM";
addr -= 0x00210000;
code = *reinterpret_cast<uint32_t*>(memory->g_psxR + addr);
if (addr <= 0x0007fff8) {
nextCode = *reinterpret_cast<uint32_t*>(memory->g_psxR + addr);
}
base = 0xbfc00000;
}
DummyAsm dummy;
dummy.process(code, nextCode, addr | 0x80000000, &skipNext);
prepend(code, section, addr | base);
disasm->process(code, nextCode, addr | base, &skipNext);
};
if (clipper.DisplayStart != 0) {
uint32_t addr = clipper.DisplayStart * 4 - 4;
process(addr, [](uint32_t, const char*, uint32_t) {}, &dummy);
}
ImGuiAsm imguiAsm(registers, memory);
for (int x = clipper.DisplayStart; x < clipper.DisplayEnd; x++) {
uint32_t addr = x * 4;
uint32_t code = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr);
uint32_t nextCode = 0;
if (addr <= 0x1ffff8) {
nextCode = *reinterpret_cast<uint32_t*>(memory->g_psxM + addr + 4);
}
ImGui::Text("%c %8.8x %8.8x: ", addr == pc ? '>' : ' ', addr | 0x80000000, code);
imguiAsm.process(code, nextCode, addr | 0x80000000, &skipNext);
Debug::bpiterator currentBP;
prependType l = [&](uint32_t code, const char* section, uint32_t dispAddr) {
bool hasBP = false;
PCSX::g_emulator.m_debug->ForEachBP([&](PCSX::Debug::bpiterator it) mutable {
uint32_t addr = dispAddr;
uint32_t bpAddr = it->Address();
uint32_t base = (addr >> 20) & 0xffc;
uint32_t bpBase = (bpAddr >> 20) & 0xffc;
if ((base == 0x000) || (base == 0x800) || (base == 0xa00)) {
addr &= 0x1fffff;
}
if ((bpBase == 0x000) || (bpBase == 0x800) || (bpBase == 0xa00)) {
bpAddr &= 0x1fffff;
}
if ((it->Type() == Debug::BE) && (addr == bpAddr)) {
hasBP = true;
currentBP = it;
return false;
}
return true;
});

char p = ' ';
if (addr == pc) p = '>';
if (hasBP) p = 'o';
if (addr == pc && hasBP) p = 'X';

ImGui::Text("%c %s:%8.8x %8.8x: ", p, section, dispAddr, code);
std::string contextMenuTitle = "assembly address menu ";
contextMenuTitle += dispAddr;
if (ImGui::BeginPopupContextItem(contextMenuTitle.c_str())) {
if (hasBP) {
if (ImGui::Button("Remove breakpoint from here")) {
PCSX::g_emulator.m_debug->EraseBP(currentBP);
hasBP = false;
}
} else {
if (ImGui::Button("Set Breakpoint here")) {
PCSX::g_emulator.m_debug->AddBreakpoint(dispAddr, Debug::BE);
hasBP = true;
}
}
ImGui::EndPopup();
}
};
process(addr, l, &imguiAsm);
}
}
if (m_followPC) {
Expand Down

0 comments on commit 44baf7d

Please sign in to comment.