Unverified Commit 1a96229b authored by Ignacio Sanchez Gines's avatar Ignacio Sanchez Gines
Browse files

Debugger improvements

parent a45a4cfb
......@@ -475,6 +475,9 @@ static void sdl_shortcuts_gui(const SDL_Event* event)
case SDL_SCANCODE_F10:
gui_shortcut(gui_ShortcutDebugStep);
break;
case SDL_SCANCODE_BACKSPACE:
gui_shortcut(gui_ShortcutDebugGoBack);
break;
}
}
}
......
......@@ -174,6 +174,10 @@ void gui_shortcut(gui_ShortCutEvent event)
if (config_debug.debug)
gui_debug_runtocursor();
break;
case gui_ShortcutDebugGoBack:
if (config_debug.debug)
gui_debug_go_back();
break;
case gui_ShortcutShowMainMenu:
show_main_menu = !show_main_menu;
break;
......@@ -729,6 +733,13 @@ static void main_menu(void)
ImGui::Separator();
if (ImGui::MenuItem("Go Back", "CTRL + BACKSPACE", (void*)0, config_debug.debug))
{
gui_debug_go_back();
}
ImGui::Separator();
if (ImGui::MenuItem("Toggle Breakpoint", "CTRL + F9", (void*)0, config_debug.debug))
{
gui_debug_toggle_breakpoint();
......
......@@ -53,6 +53,7 @@ enum gui_ShortCutEvent
gui_ShortcutDebugNextFrame,
gui_ShortcutDebugBreakpoint,
gui_ShortcutDebugRuntocursor,
gui_ShortcutDebugGoBack,
gui_ShortcutShowMainMenu
};
......
......@@ -17,6 +17,7 @@
*
*/
#include <math.h>
#include "imgui/imgui.h"
#include "imgui/imgui_memory_editor.h"
#include "FileBrowser/ImGuiFileBrowser.h"
......@@ -57,6 +58,11 @@ static ImVec4 dark_gray = ImVec4(0.1f,0.1f,0.1f,1.0f);
static std::vector<DebugSymbol> symbols;
static Memory::stDisassembleRecord* selected_record = NULL;
static char brk_address[8] = "";
static char goto_address[5] = "";
static bool goto_address_requested = false;
static u16 goto_address_target = 0;
static bool goto_back_requested = false;
static int goto_back = 0;
static void debug_window_processor(void);
static void debug_window_memory(void);
......@@ -69,6 +75,7 @@ static void debug_window_vram_palettes(void);
static void debug_window_vram_regs(void);
static void add_symbol(const char* line);
static void add_breakpoint(void);
static void request_goto_address(u16 addr);
static ImVec4 color_444_to_float(u16 color);
static ImVec4 color_222_to_float(u8 color);
......@@ -160,6 +167,11 @@ void gui_debug_reset_breakpoints(void)
brk_address[0] = 0;
}
void gui_debug_go_back(void)
{
goto_back_requested = true;
}
static void debug_window_memory(void)
{
ImGui::SetNextWindowPos(ImVec2(160, 380), ImGuiCond_FirstUseEver);
......@@ -302,14 +314,6 @@ static void debug_window_disassembler(void)
int pc = proc_state->PC->GetValue();
static bool follow_pc = true;
static bool show_mem = true;
static bool show_symbols = true;
ImGui::Checkbox("Follow PC", &follow_pc); ImGui::SameLine();
ImGui::Checkbox("Show Memory", &show_mem); ImGui::SameLine();
ImGui::Checkbox("Show Symbols", &show_symbols);
if (ImGui::Button("Step Over"))
emu_debug_step();
ImGui::SameLine();
......@@ -322,6 +326,55 @@ static void debug_window_disassembler(void)
if (ImGui::Button("Run To Cursor"))
gui_debug_runtocursor();
static bool follow_pc = true;
static bool show_mem = true;
static bool show_symbols = true;
ImGui::Checkbox("Follow PC", &follow_pc); ImGui::SameLine();
ImGui::Checkbox("Show Memory", &show_mem); ImGui::SameLine();
ImGui::Checkbox("Show Symbols", &show_symbols);
ImGui::Separator();
ImGui::Text("Go To Address: ");
ImGui::SameLine();
ImGui::PushItemWidth(45);
if (ImGui::InputTextWithHint("##goto_address", "XXXX", goto_address, IM_ARRAYSIZE(goto_address), ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
try
{
request_goto_address(std::stoul(goto_address, 0, 16));
follow_pc = false;
}
catch(const std::invalid_argument& ia)
{
}
goto_address[0] = 0;
}
ImGui::PopItemWidth();
ImGui::SameLine();
if (ImGui::Button("Go", ImVec2(30, 0)))
{
try
{
request_goto_address(std::stoul(goto_address, 0, 16));
follow_pc = false;
}
catch(const std::invalid_argument& ia)
{
}
goto_address[0] = 0;
}
ImGui::SameLine();
if (ImGui::Button("Back", ImVec2(50, 0)))
{
goto_back_requested = true;
follow_pc = false;
}
ImGui::Separator();
if (ImGui::CollapsingHeader("Breakpoints"))
{
ImGui::Checkbox("Disable All", &emu_debug_disable_breakpoints);
......@@ -391,6 +444,7 @@ static void debug_window_disassembler(void)
{
int dis_size = 0;
int pc_pos = 0;
int goto_address_pos = 0;
std::vector<DisassmeblerLine> vec(0x10000);
......@@ -438,6 +492,9 @@ static void debug_window_disassembler(void)
if (vec[dis_size].record->address == pc)
pc_pos = dis_size;
if (goto_address_requested && (vec[dis_size].record->address <= goto_address_target))
goto_address_pos = dis_size;
vec[dis_size].is_breakpoint = false;
for (long unsigned int b = 0; b < breakpoints->size(); b++)
......@@ -460,6 +517,19 @@ static void debug_window_disassembler(void)
ImGui::SetScrollY((pc_pos * ImGui::GetTextLineHeightWithSpacing()) - offset);
}
if (goto_address_requested)
{
goto_address_requested = false;
goto_back = ImGui::GetScrollY();
ImGui::SetScrollY((goto_address_pos * ImGui::GetTextLineHeightWithSpacing()) + 2);
}
if (goto_back_requested)
{
goto_back_requested = false;
ImGui::SetScrollY(goto_back);
}
ImGuiListClipper clipper(dis_size, ImGui::GetTextLineHeightWithSpacing());
while (clipper.Step())
......@@ -476,9 +546,14 @@ static void debug_window_disassembler(void)
bool is_selected = (selected_record == vec[item].record);
if (ImGui::Selectable("", is_selected))
if (ImGui::Selectable("", is_selected, ImGuiSelectableFlags_AllowDoubleClick))
{
if (is_selected)
if (ImGui::IsMouseDoubleClicked(0) && vec[item].record->jump)
{
follow_pc = false;
request_goto_address(vec[item].record->jump_address);
}
else if (is_selected)
{
InitPointer(selected_record);
brk_address[0] = 0;
......@@ -1335,19 +1410,25 @@ static void add_symbol(const char* line)
std::size_t separator = str.find(":");
if (separator != std::string::npos)
try
{
s.address = (u16)std::stoul(str.substr(separator + 1 , std::string::npos), 0, 16);
if (separator != std::string::npos)
{
s.address = (u16)std::stoul(str.substr(separator + 1 , std::string::npos), 0, 16);
s.bank = std::stoul(str.substr(0, separator), 0 , 16);
s.bank = std::stoul(str.substr(0, separator), 0 , 16);
}
else
{
s.address = (u16)std::stoul(str, 0, 16);
s.bank = 0;
}
symbols.push_back(s);
}
else
catch(const std::invalid_argument& ia)
{
s.address = (u16)std::stoul(str, 0, 16);
s.bank = 0;
}
symbols.push_back(s);
}
}
......@@ -1358,25 +1439,32 @@ static void add_breakpoint(void)
int target_bank = 0;
int target_offset = 0;
if ((input_len == 7) && (brk_address[2] == ':'))
try
{
std::string str(brk_address);
std::size_t separator = str.find(":");
if (separator != std::string::npos)
if ((input_len == 7) && (brk_address[2] == ':'))
{
target_address = (u16)std::stoul(str.substr(separator + 1 , std::string::npos), 0, 16);
std::string str(brk_address);
std::size_t separator = str.find(":");
target_bank = std::stoul(str.substr(0, separator), 0 , 16);
target_bank &= 0xFF;
if (separator != std::string::npos)
{
target_address = (u16)std::stoul(str.substr(separator + 1 , std::string::npos), 0, 16);
target_bank = std::stoul(str.substr(0, separator), 0 , 16);
target_bank &= 0xFF;
}
}
else if (input_len == 4)
{
target_bank = 0;
target_address = (u16)std::stoul(brk_address, 0, 16);
}
else
{
return;
}
}
else if (input_len == 4)
{
target_bank = 0;
target_address = (u16)std::stoul(brk_address, 0, 16);
}
else
catch(const std::invalid_argument& ia)
{
return;
}
......@@ -1439,3 +1527,9 @@ static ImVec4 color_222_to_float(u8 color)
ret.z = (1.0f / 3.0f) * ((color >> 4) & 0x3);
return ret;
}
static void request_goto_address(u16 address)
{
goto_address_requested = true;
goto_address_target = address;
}
......@@ -46,6 +46,7 @@ EXTERN void gui_debug_load_symbols_file(const char* path);
EXTERN void gui_debug_toggle_breakpoint(void);
EXTERN void gui_debug_reset_breakpoints(void);
EXTERN void gui_debug_runtocursor(void);
EXTERN void gui_debug_go_back(void);
#undef GUI_DEBUG_IMPORT
#undef EXTERN
......
......@@ -34,6 +34,9 @@ public:
char bytes[16];
int size;
int bank;
u8 opcodes[4];
bool jump;
u16 jump_address;
};
enum MediaSlots
......
......@@ -364,9 +364,25 @@ bool Processor::Disassemble(u16 address)
map[offset]->name[0] = 0;
map[offset]->bytes[0] = 0;
map[offset]->size = 0;
for (int i = 0; i < 6; i++)
map[offset]->opcodes[i] = 0;
map[offset]->jump = false;
map[offset]->jump_address = 0;
}
if (map[offset]->size == 0)
u8 opcodes[6];
bool changed = false;
int maxSize = std::min(map[offset]->size, 4);
for (int i = 0; i < maxSize; i++)
{
opcodes[i] = m_pMemory->Read(address + i);
if (opcodes[i] != map[offset]->opcodes[i])
changed = true;
}
if ((map[offset]->size == 0) || changed)
{
map[offset]->bank = bank;
map[offset]->address = address;
......@@ -445,6 +461,9 @@ bool Processor::Disassemble(u16 address)
{
strcat(map[offset]->bytes, " ");
}
if (i < maxSize)
map[offset]->opcodes[i] = bytes[i];
}
first += prefixed ? 1 : 0;
......@@ -461,13 +480,17 @@ bool Processor::Disassemble(u16 address)
sprintf(map[offset]->name, info.name, bytes[first + 1]);
break;
case 3:
sprintf(map[offset]->name, info.name, (bytes[first + 2] << 8) | bytes[first + 1]);
map[offset]->jump = true;
map[offset]->jump_address = (bytes[first + 2] << 8) | bytes[first + 1];
sprintf(map[offset]->name, info.name, map[offset]->jump_address);
break;
case 4:
sprintf(map[offset]->name, info.name, (s8)bytes[first + 1]);
break;
case 5:
sprintf(map[offset]->name, info.name, address + info.size + (s8)bytes[first + 1], (s8)bytes[first + 1]);
map[offset]->jump = true;
map[offset]->jump_address = address + info.size + (s8)bytes[first + 1];
sprintf(map[offset]->name, info.name, map[offset]->jump_address, (s8)bytes[first + 1]);
break;
case 6:
sprintf(map[offset]->name, info.name, (s8)bytes[first + 1], bytes[first + 2]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment