Skip to content

Commit fd55f4f

Browse files
committed
[debugger] Improve symbol substitution
1 parent 149d680 commit fd55f4f

File tree

7 files changed

+226
-71
lines changed

7 files changed

+226
-71
lines changed

platforms/shared/desktop/gui_debug_disassembler.cpp

Lines changed: 182 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct DisassemblerLine
3737
bool is_breakpoint;
3838
GG_Disassembler_Record* record;
3939
char name_enhanced[64];
40+
char tooltip[128];
4041
int name_real_length;
4142
DebugSymbol* symbol;
4243
bool is_auto_symbol;
@@ -93,7 +94,7 @@ static void add_auto_symbol(GG_Disassembler_Record* record, u16 address);
9394
static void add_breakpoint(int type);
9495
static void request_goto_address(u16 addr);
9596
static bool is_return_instruction(u8 opcode);
96-
static void replace_symbols(DisassemblerLine* line, const char* color, const char* auto_color);
97+
static void replace_symbols(DisassemblerLine* line, const char* jump_color, const char* operand_color, const char* auto_color, const char* original_color);
9798
static void replace_labels(DisassemblerLine* line, const char* color, const char* original_color);
9899
static void draw_instruction_name(DisassemblerLine* line, bool is_pc);
99100
static void disassembler_menu(void);
@@ -636,6 +637,7 @@ static void prepare_drawable_lines(void)
636637
line.is_breakpoint = false;
637638
line.record = record;
638639
snprintf(line.name_enhanced, 64, "%s", line.record->name);
640+
line.tooltip[0] = 0;
639641

640642
std::vector<HuC6280::GG_Breakpoint>* breakpoints = emu_get_core()->GetHuC6280()->GetBreakpoints();
641643

@@ -805,6 +807,13 @@ static void draw_disassembly(void)
805807
ImGui::SameLine();
806808
draw_instruction_name(&line, line.address == pc);
807809

810+
if (line.tooltip[0] != 0 && ImGui::IsItemHovered())
811+
{
812+
ImGui::BeginTooltip();
813+
TextColoredEx("%s", line.tooltip);
814+
ImGui::EndTooltip();
815+
}
816+
808817
if (config_debug.dis_show_mem)
809818
{
810819
int len = line.name_real_length;
@@ -971,6 +980,20 @@ static void add_symbol(const char* line)
971980
snprintf(s.text, 64, "%s", symbol.c_str());
972981

973982
// Store the symbol
983+
DebugSymbol* existing = fixed_symbols[s.bank][s.address];
984+
if (IsValidPointer(existing))
985+
{
986+
for (size_t i = 0; i < fixed_symbol_list.size(); i++)
987+
{
988+
if (fixed_symbol_list[i].symbol == existing)
989+
{
990+
fixed_symbol_list.erase(fixed_symbol_list.begin() + i);
991+
break;
992+
}
993+
}
994+
SafeDelete(fixed_symbols[s.bank][s.address]);
995+
}
996+
974997
DebugSymbol* new_symbol = new DebugSymbol;
975998
new_symbol->address = s.address;
976999
new_symbol->bank = s.bank;
@@ -1088,81 +1111,169 @@ static bool is_return_instruction(u8 opcode)
10881111
}
10891112
}
10901113

1091-
static void replace_symbols(DisassemblerLine* line, const char* color, const char* auto_color)
1114+
static bool replace_address_in_string(std::string& instr, u16 address, bool is_zp, const char* replacement_text)
10921115
{
1093-
bool symbol_found = false;
1116+
const char* format = is_zp ? "$%02X" : "$%04X";
1117+
const char* indirect_format = is_zp ? "$(%02X" : "$(%04X";
1118+
int replace_len = is_zp ? 3 : 5;
1119+
int indirect_replace_len = is_zp ? 4 : 6;
1120+
1121+
char address_str[8];
1122+
snprintf(address_str, 8, format, address);
1123+
size_t pos = instr.find(address_str);
1124+
if (pos != std::string::npos)
1125+
{
1126+
instr.replace(pos, replace_len, replacement_text);
1127+
return true;
1128+
}
10941129

1095-
DebugSymbol* fixed_symbol = fixed_symbols[line->record->jump_bank][line->record->jump_address];
1130+
snprintf(address_str, 8, indirect_format, address);
1131+
pos = instr.find(address_str);
1132+
if (pos != std::string::npos)
1133+
{
1134+
std::string indirect_replacement = std::string("(") + replacement_text;
1135+
instr.replace(pos, indirect_replace_len, indirect_replacement);
1136+
return true;
1137+
}
1138+
1139+
return false;
1140+
}
10961141

1097-
if (IsValidPointer(fixed_symbol))
1142+
static bool get_record_operand(GG_Disassembler_Record* record, u16* out_address, bool* out_is_zp)
1143+
{
1144+
if (record->jump)
10981145
{
1099-
std::string instr = line->record->name;
1100-
std::string symbol = fixed_symbol->text;
1101-
char jump_address[6];
1102-
snprintf(jump_address, 6, "$%04X", line->record->jump_address);
1103-
size_t pos = instr.find(jump_address);
1104-
if (pos != std::string::npos)
1146+
*out_address = record->jump_address;
1147+
*out_is_zp = false;
1148+
return true;
1149+
}
1150+
else if (record->has_operand_address)
1151+
{
1152+
*out_address = record->operand_address;
1153+
*out_is_zp = record->operand_is_zp;
1154+
return true;
1155+
}
1156+
return false;
1157+
}
1158+
1159+
bool gui_debug_resolve_symbol(GG_Disassembler_Record* record, std::string& instr, const char* color, const char* original_color, const char** out_name, u16* out_address)
1160+
{
1161+
u16 lookup_address = 0;
1162+
bool is_zp = false;
1163+
1164+
if (!get_record_operand(record, &lookup_address, &is_zp))
1165+
return false;
1166+
1167+
u16 bank_address = is_zp ? (0x2000 | lookup_address) : lookup_address;
1168+
u8 bank = record->jump ? record->jump_bank : emu_get_core()->GetMemory()->GetBank(bank_address);
1169+
DebugSymbol* symbol = fixed_symbols[bank][bank_address];
1170+
if (IsValidPointer(symbol))
1171+
{
1172+
std::string replacement = std::string(color) + symbol->text + original_color;
1173+
if (replace_address_in_string(instr, lookup_address, is_zp, replacement.c_str()))
11051174
{
1106-
instr.replace(pos, 5, color + symbol);
1107-
snprintf(line->name_enhanced, 64, "%s", instr.c_str());
1108-
symbol_found = true;
1175+
if (out_name) *out_name = symbol->text;
1176+
if (out_address) *out_address = lookup_address;
1177+
return true;
11091178
}
11101179
}
11111180

1112-
if (symbol_found)
1113-
return;
1114-
1115-
if (!config_debug.dis_show_auto_symbols)
1116-
return;
1181+
return false;
1182+
}
11171183

1118-
DebugSymbol* dynamic_symbol = dynamic_symbols[line->record->jump_bank][line->record->jump_address];
1184+
bool gui_debug_resolve_label(GG_Disassembler_Record* record, std::string& instr, const char* color, const char* original_color, const char** out_name, u16* out_address)
1185+
{
1186+
u16 lookup_address = 0;
1187+
bool is_zp = false;
11191188

1120-
if (IsValidPointer(dynamic_symbol))
1189+
if (get_record_operand(record, &lookup_address, &is_zp))
11211190
{
1122-
std::string instr = line->record->name;
1123-
std::string symbol = dynamic_symbol->text;
1124-
char jump_address[6];
1125-
snprintf(jump_address, 6, "$%04X", line->record->jump_address);
1126-
size_t pos = instr.find(jump_address);
1127-
if (pos != std::string::npos)
1191+
u16 hardware_offset = 0x0000;
1192+
1193+
for (int i = 0; i < 8; i++)
11281194
{
1129-
instr.replace(pos, 5, auto_color + symbol);
1130-
snprintf(line->name_enhanced, 64, "%s", instr.c_str());
1195+
if (emu_get_core()->GetMemory()->GetMpr(i) == 0xFF)
1196+
{
1197+
hardware_offset = i * 0x2000;
1198+
break;
1199+
}
11311200
}
11321201

1202+
u16 label_lookup = is_zp ? (0x2000 | lookup_address) : lookup_address;
1203+
1204+
for (int i = 0; i < k_debug_label_count; i++)
1205+
{
1206+
if (k_debug_labels[i].address + hardware_offset == label_lookup)
1207+
{
1208+
char label_address[6];
1209+
snprintf(label_address, 6, "$%04X", lookup_address);
1210+
std::string replacement = std::string(color) + k_debug_labels[i].label + label_address + original_color;
1211+
if (replace_address_in_string(instr, lookup_address, is_zp, replacement.c_str()))
1212+
{
1213+
if (out_name) *out_name = k_debug_labels[i].label;
1214+
if (out_address) *out_address = lookup_address;
1215+
return true;
1216+
}
1217+
}
1218+
}
11331219
}
1220+
1221+
return false;
11341222
}
11351223

1136-
static void replace_labels(DisassemblerLine* line, const char* color, const char* original_color)
1224+
static void replace_symbols(DisassemblerLine* line, const char* jump_color, const char* operand_color, const char* auto_color, const char* original_color)
11371225
{
1138-
u16 hardware_offset = 0x0000;
1226+
std::string instr = line->record->name;
1227+
const char* color = line->record->jump ? jump_color : operand_color;
1228+
const char* resolved_name = NULL;
1229+
u16 resolved_address = 0;
11391230

1140-
for (int i = 0; i < 8; i++)
1231+
if (gui_debug_resolve_symbol(line->record, instr, color, original_color, &resolved_name, &resolved_address))
11411232
{
1142-
if (emu_get_core()->GetMemory()->GetMpr(i) == 0xFF)
1143-
{
1144-
hardware_offset = i * 0x2000;
1145-
break;
1146-
}
1233+
snprintf(line->name_enhanced, 64, "%s", instr.c_str());
1234+
snprintf(line->tooltip, 128, "%s%s%s = %s$%04X", color, resolved_name, c_white, c_cyan, resolved_address);
1235+
return;
11471236
}
11481237

1149-
for (int i = 0; i < k_debug_label_count; i++)
1238+
if (!config_debug.dis_show_auto_symbols)
1239+
return;
1240+
1241+
if (!line->record->jump)
1242+
return;
1243+
1244+
u16 lookup_address = 0;
1245+
bool is_zp = false;
1246+
1247+
if (!get_record_operand(line->record, &lookup_address, &is_zp))
1248+
return;
1249+
1250+
DebugSymbol* dynamic_symbol = dynamic_symbols[line->record->jump_bank][lookup_address];
1251+
1252+
if (IsValidPointer(dynamic_symbol))
11501253
{
1151-
std::string instr = line->record->name;
1152-
std::string label = k_debug_labels[i].label;
1153-
char label_address[7];
1154-
snprintf(label_address, 7, "$%04X", k_debug_labels[i].address + hardware_offset);
1155-
size_t pos = instr.find(label_address);
1156-
if (pos != std::string::npos)
1254+
std::string replacement = std::string(auto_color) + dynamic_symbol->text + original_color;
1255+
if (replace_address_in_string(instr, lookup_address, is_zp, replacement.c_str()))
11571256
{
1158-
if (pos > 0 && instr[pos - 1] == '#')
1159-
continue;
1160-
instr.replace(pos, 5, color + label + label_address + original_color);
11611257
snprintf(line->name_enhanced, 64, "%s", instr.c_str());
1258+
snprintf(line->tooltip, 128, "%s%s%s = %s$%04X", auto_color, dynamic_symbol->text, c_white, c_cyan, lookup_address);
11621259
}
11631260
}
11641261
}
11651262

1263+
static void replace_labels(DisassemblerLine* line, const char* color, const char* original_color)
1264+
{
1265+
std::string instr = line->record->name;
1266+
const char* resolved_name = NULL;
1267+
u16 resolved_address = 0;
1268+
1269+
if (gui_debug_resolve_label(line->record, instr, color, original_color, &resolved_name, &resolved_address))
1270+
{
1271+
snprintf(line->name_enhanced, 64, "%s", instr.c_str());
1272+
if (line->tooltip[0] == 0)
1273+
snprintf(line->tooltip, 128, "%s%s%s = %s$%04X", color, resolved_name, c_white, c_cyan, resolved_address);
1274+
}
1275+
}
1276+
11661277
static void draw_instruction_name(DisassemblerLine* line, bool is_pc)
11671278
{
11681279
const char* name_color;
@@ -1196,10 +1307,10 @@ static void draw_instruction_name(DisassemblerLine* line, bool is_pc)
11961307
extra_color = c_blue;
11971308
}
11981309

1199-
if (config_debug.dis_replace_symbols && line->record->jump)
1310+
if (config_debug.dis_replace_symbols)
12001311
{
12011312
const char* auto_symbol_color = config_debug.dis_dim_auto_symbols ? c_dim_green : symbol_color;
1202-
replace_symbols(line, symbol_color, auto_symbol_color);
1313+
replace_symbols(line, symbol_color, label_color, auto_symbol_color, operands_color);
12031314
}
12041315

12051316
if (config_debug.dis_replace_labels)
@@ -1218,7 +1329,9 @@ static void draw_instruction_name(DisassemblerLine* line, bool is_pc)
12181329
if (pos != std::string::npos)
12191330
instr.replace(pos, 3, operands_color);
12201331

1332+
ImGui::BeginGroup();
12211333
line->name_real_length = TextColoredEx("%s%s", name_color, instr.c_str());
1334+
ImGui::EndGroup();
12221335
}
12231336

12241337
static void disassembler_menu(void)
@@ -1437,13 +1550,13 @@ static void disassembler_menu(void)
14371550
ImGui::MenuItem("Symbols Window", NULL, &config_debug.show_symbols);
14381551

14391552
ImGui::Separator();
1553+
ImGui::MenuItem("Hardware Labels", NULL, &config_debug.dis_replace_labels);
14401554

14411555
ImGui::MenuItem("Automatic Symbols", NULL, &config_debug.dis_show_auto_symbols);
14421556
if (!config_debug.dis_show_auto_symbols) ImGui::BeginDisabled();
14431557
ImGui::MenuItem("Dim Automatic Symbols", NULL, &config_debug.dis_dim_auto_symbols);
14441558
if (!config_debug.dis_show_auto_symbols) ImGui::EndDisabled();
14451559
ImGui::MenuItem("Replace Address With Symbol", NULL, &config_debug.dis_replace_symbols);
1446-
ImGui::MenuItem("Replace Address With Label", NULL, &config_debug.dis_replace_labels);
14471560

14481561
ImGui::Separator();
14491562

@@ -1869,6 +1982,14 @@ void gui_debug_window_symbols(void)
18691982
emu_get_core()->GetHuC6280()->AddBreakpoint(symbol->address);
18701983
}
18711984

1985+
if (is_manual)
1986+
{
1987+
if (ImGui::Selectable("Remove Symbol"))
1988+
{
1989+
gui_debug_remove_symbol(b, symbol->address);
1990+
}
1991+
}
1992+
18721993
ImGui::EndPopup();
18731994
}
18741995
ImGui::PushFont(gui_default_font);
@@ -1906,26 +2027,20 @@ void gui_debug_add_symbol(const char* symbol_str)
19062027

19072028
void gui_debug_remove_symbol(u8 bank, u16 address)
19082029
{
1909-
Memory* memory = emu_get_core()->GetMemory();
1910-
GG_Disassembler_Record* record = memory->GetDisassemblerRecord(address);
1911-
1912-
if (IsValidPointer(record) && record->bank == bank)
2030+
DebugSymbol* symbol = fixed_symbols[bank][address];
2031+
if (IsValidPointer(symbol))
19132032
{
1914-
DebugSymbol* symbol = fixed_symbols[bank][address];
1915-
if (IsValidPointer(symbol))
2033+
for (size_t i = 0; i < fixed_symbol_list.size(); i++)
19162034
{
1917-
for (size_t i = 0; i < fixed_symbol_list.size(); i++)
2035+
if (fixed_symbol_list[i].symbol == symbol)
19182036
{
1919-
if (fixed_symbol_list[i].symbol == symbol)
1920-
{
1921-
fixed_symbol_list.erase(fixed_symbol_list.begin() + i);
1922-
break;
1923-
}
2037+
fixed_symbol_list.erase(fixed_symbol_list.begin() + i);
2038+
break;
19242039
}
1925-
delete symbol;
1926-
fixed_symbols[bank][address] = NULL;
1927-
symbols_dirty = true;
19282040
}
2041+
delete symbol;
2042+
fixed_symbols[bank][address] = NULL;
2043+
symbols_dirty = true;
19292044
}
19302045
}
19312046

@@ -2048,9 +2163,9 @@ static void save_current_disassembler(FILE* file)
20482163

20492164
fprintf(file, " %04X ", line.address);
20502165

2051-
if (config_debug.dis_replace_symbols && line.record->jump)
2166+
if (config_debug.dis_replace_symbols)
20522167
{
2053-
replace_symbols(&line, "", "");
2168+
replace_symbols(&line, "", "", "", "");
20542169
}
20552170

20562171
if (config_debug.dis_replace_labels)

platforms/shared/desktop/gui_debug_disassembler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define GUI_DEBUG_DISASSEMBLER_H
2222

2323
#include "geargrafx.h"
24+
#include <string>
2425

2526
#ifdef GUI_DEBUG_DISASSEMBLER_IMPORT
2627
#define EXTERN
@@ -51,6 +52,8 @@ EXTERN void gui_debug_remove_disassembler_bookmark(u16 address);
5152
EXTERN int gui_debug_get_disassembler_bookmarks(void** bookmarks_ptr);
5253
EXTERN void gui_debug_reset_disassembler_bookmarks(void);
5354
EXTERN int gui_debug_get_symbols(void** symbols_ptr);
55+
EXTERN bool gui_debug_resolve_symbol(GG_Disassembler_Record* record, std::string& instr, const char* color, const char* original_color, const char** out_name = NULL, u16* out_address = NULL);
56+
EXTERN bool gui_debug_resolve_label(GG_Disassembler_Record* record, std::string& instr, const char* color, const char* original_color, const char** out_name = NULL, u16* out_address = NULL);
5457
EXTERN void gui_debug_runtocursor(void);
5558
EXTERN void gui_debug_runto_address(u16 address);
5659
EXTERN void gui_debug_go_back(void);

0 commit comments

Comments
 (0)