Add DebuggerConsole and improve disassembler.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-03-14 20:40:37 +00:00
parent 49cae397d6
commit 0f66cd6f85
2 changed files with 161 additions and 97 deletions

View file

@ -53,7 +53,7 @@ namespace sa2
ImGui::Checkbox("Memory", &myShowMemory); ImGui::Checkbox("Memory", &myShowMemory);
ImGui::SameLine(); HelpMarker("Show Apple memory."); ImGui::SameLine(); HelpMarker("Show Apple memory.");
if (ImGui::Checkbox("CPU", &myShowCPU) && myShowCPU) if (ImGui::Checkbox("Debugger", &myShowDebugger) && myShowDebugger)
{ {
DebugBegin(); DebugBegin();
} }
@ -154,9 +154,9 @@ namespace sa2
showMemory(); showMemory();
} }
if (myShowCPU) if (myShowDebugger)
{ {
showCPU(frame); showDebugger(frame);
} }
if (myShowDemo) if (myShowDemo)
@ -176,7 +176,7 @@ namespace sa2
{ {
ImGui::MenuItem("Settings", nullptr, &myShowSettings); ImGui::MenuItem("Settings", nullptr, &myShowSettings);
ImGui::MenuItem("Memory", nullptr, &myShowMemory); ImGui::MenuItem("Memory", nullptr, &myShowMemory);
if (ImGui::MenuItem("CPU", nullptr, &myShowCPU) && myShowCPU) if (ImGui::MenuItem("Debugger", nullptr, &myShowDebugger) && myShowDebugger)
{ {
DebugBegin(); DebugBegin();
} }
@ -218,116 +218,177 @@ namespace sa2
ImGui::End(); ImGui::End();
} }
void ImGuiSettings::showCPU(SDLFrame * frame) void ImGuiSettings::drawDisassemblyTable()
{ {
if (ImGui::Begin("CPU", &myShowCPU)) const ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
if (ImGui::BeginTable("Disassembly", 6, flags))
{ {
ImGui::Checkbox("Auto-sync PC", &mySyncCPU); // weigths proportional to column width (including header)
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("Disassembly", 0, 30);
ImGui::TableSetupColumn("Symbol", 0, 20);
ImGui::TableSetupColumn("Target", 0, 20);
ImGui::TableSetupColumn("Pointer", 0, 9);
ImGui::TableSetupColumn("Immediate", 0, 9);
ImGui::TableSetupColumn("Branch", 0, 6);
ImGui::TableHeadersRow();
// complicated if condition to preserve widget order ImGuiListClipper clipper;
const bool recalc = mySyncCPU || (ImGui::SameLine(), ImGui::Button("Sync PC")); clipper.Begin(1000);
int row = 0;
if (ImGui::Button("Step")) WORD nAddress = g_nDisasmTopAddress;
while (clipper.Step())
{ {
frame->ChangeMode(MODE_STEPPING); for (; row < clipper.DisplayStart; ++row)
frame->Execute(myStepCycles);
}
ImGui::SameLine();
ImGui::PushItemWidth(150);
ImGui::DragInt("cycles", &myStepCycles, 0.2f, 0, 256, "%d");
ImGui::PopItemWidth();
if ((ImGui::SameLine(), ImGui::Button("Run")))
{
frame->ChangeMode(MODE_RUNNING);
}
if ((ImGui::SameLine(), ImGui::Button("Pause")))
{
frame->ChangeMode(MODE_PAUSED);
}
ImGui::SameLine(); ImGui::Text("%016llu - %04X", g_nCumulativeCycles, regs.pc);
if (ImGui::SliderInt("PC position", &g_nDisasmCurLine, 1, 100) || recalc)
{
g_nDisasmCurAddress = regs.pc;
DisasmCalcTopBotAddress();
}
const ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
if (ImGui::BeginTable("Disassembly", 8, flags))
{
// weigths proportional to column width (including header)
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("Disassembly", 0, 30);
ImGui::TableSetupColumn("Symbol", 0, 20);
ImGui::TableSetupColumn("Target", 0, 20);
ImGui::TableSetupColumn("Offset", 0, 6);
ImGui::TableSetupColumn("Pointer", 0, 7);
ImGui::TableSetupColumn("Value", 0, 5);
ImGui::TableSetupColumn("Immediate", 0, 9);
ImGui::TableSetupColumn("Branch", 0, 6);
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(1000);
int row = 0;
WORD nAddress = g_nDisasmTopAddress;
while (clipper.Step())
{ {
for (; row < clipper.DisplayStart; ++row) int iOpcode, iOpmode, nOpbyte;
_6502_GetOpmodeOpbyte(nAddress, iOpmode, nOpbyte, nullptr);
nAddress += nOpbyte;
}
IM_ASSERT(row == clipper.DisplayStart && "Clipper position mismatch");
for (; row < clipper.DisplayEnd; ++row)
{
DisasmLine_t line;
const char* pSymbol = FindSymbolFromAddress(nAddress);
const int bDisasmFormatFlags = GetDisassemblyLine(nAddress, line);
char buffer[CONSOLE_WIDTH];
FormatDisassemblyLine(line, buffer, sizeof(buffer));
ImGui::TableNextRow();
if (nAddress == regs.pc)
{ {
int iOpcode, iOpmode, nOpbyte; const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(0, 0, 1, 1));
_6502_GetOpmodeOpbyte(nAddress, iOpmode, nOpbyte, nullptr); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
nAddress += nOpbyte;
} }
IM_ASSERT(row == clipper.DisplayStart && "Clipper position mismatch");
for (; row < clipper.DisplayEnd; ++row) ImGui::TableNextColumn();
ImGui::Selectable(buffer, false, ImGuiSelectableFlags_SpanAllColumns);
ImGui::TableNextColumn();
if (pSymbol)
{ {
DisasmLine_t line; ImGui::TextUnformatted(pSymbol);
const char* pSymbol = FindSymbolFromAddress(nAddress); }
const int bDisasmFormatFlags = GetDisassemblyLine(nAddress, line);
char buffer[CONSOLE_WIDTH]; ImGui::TableNextColumn();
FormatDisassemblyLine(line, buffer, sizeof(buffer)); if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
{
ImGui::TableNextRow(); ImGui::Text("%s%+d", line.sTarget, line.nTargetOffset);
}
if (nAddress == regs.pc) else
{ {
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(0, 0, 1, 1));
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
}
ImGui::TableNextColumn();
ImGui::Selectable(buffer, false, ImGuiSelectableFlags_SpanAllColumns);
ImGui::TableNextColumn();
if (pSymbol)
{
ImGui::TextUnformatted(pSymbol);
}
ImGui::TableNextColumn();
ImGui::TextUnformatted(line.sTarget); ImGui::TextUnformatted(line.sTarget);
}
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted(line.sTargetOffset); if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_VALUE)
{
ImGui::TableNextColumn(); ImGui::Text("%s:%s", line.sTargetPointer, line.sTargetValue);
}
else if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER)
{
ImGui::TextUnformatted(line.sTargetPointer); ImGui::TextUnformatted(line.sTargetPointer);
}
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted(line.sTargetValue); if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
{
ImGui::TableNextColumn();
ImGui::TextUnformatted(line.sImmediate); ImGui::TextUnformatted(line.sImmediate);
}
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (bDisasmFormatFlags & DISASM_FORMAT_BRANCH)
{
ImGui::TextUnformatted(line.sBranch); ImGui::TextUnformatted(line.sBranch);
}
nAddress += line.nOpbyte; nAddress += line.nOpbyte;
}
}
ImGui::EndTable();
}
}
void ImGuiSettings::drawConsole()
{
const ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
if (ImGui::BeginTable("Console", 1, flags))
{
// ImGuiListClipper clipper;
// clipper.Begin(CONSOLE_HEIGHT);
// while (clipper.Step())
{
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
for (int i = 0; i < CONSOLE_HEIGHT; ++i)
{
char line[CONSOLE_WIDTH + 1];
const conchar_t * src = g_aConsoleDisplay[CONSOLE_HEIGHT - i - 1];
for (size_t j = 0; j < CONSOLE_WIDTH; ++j)
{
line[j] = ConsoleChar_GetChar(src[j]);
}
if (line[0])
{
line[CONSOLE_WIDTH] = 0;
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(line);
} }
} }
ImGui::EndTable(); }
ImGui::EndTable();
}
}
void ImGuiSettings::showDebugger(SDLFrame * frame)
{
if (ImGui::Begin("Debugger", &myShowDebugger))
{
if (ImGui::BeginTabBar("Settings"))
{
if (ImGui::BeginTabItem("CPU"))
{
ImGui::Checkbox("Auto-sync PC", &mySyncCPU);
// complicated if condition to preserve widget order
const bool recalc = mySyncCPU || (ImGui::SameLine(), ImGui::Button("Sync PC"));
if (ImGui::Button("Step"))
{
frame->ChangeMode(MODE_STEPPING);
frame->Execute(myStepCycles);
}
ImGui::SameLine();
ImGui::PushItemWidth(150);
ImGui::DragInt("cycles", &myStepCycles, 0.2f, 0, 256, "%d");
ImGui::PopItemWidth();
if ((ImGui::SameLine(), ImGui::Button("Run")))
{
frame->ChangeMode(MODE_RUNNING);
}
if ((ImGui::SameLine(), ImGui::Button("Pause")))
{
frame->ChangeMode(MODE_PAUSED);
}
ImGui::SameLine(); ImGui::Text("%016llu - %04X", g_nCumulativeCycles, regs.pc);
if (ImGui::SliderInt("PC position", &g_nDisasmCurLine, 1, 100) || recalc)
{
g_nDisasmCurAddress = regs.pc;
DisasmCalcTopBotAddress();
}
drawDisassemblyTable();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Console"))
{
drawConsole();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
} }
} }
ImGui::End(); ImGui::End();

View file

@ -19,7 +19,7 @@ namespace sa2
bool myShowDemo = false; bool myShowDemo = false;
bool myShowSettings = false; bool myShowSettings = false;
bool myShowMemory = false; bool myShowMemory = false;
bool myShowCPU = false; bool myShowDebugger = false;
bool mySyncCPU = true; bool mySyncCPU = true;
int myStepCycles = 0; int myStepCycles = 0;
@ -30,8 +30,11 @@ namespace sa2
MemoryEditor myAuxMemoryEditor; MemoryEditor myAuxMemoryEditor;
void showSettings(); void showSettings();
void showCPU(SDLFrame* frame); void showDebugger(SDLFrame* frame);
void showMemory(); void showMemory();
void drawDisassemblyTable();
void drawConsole();
}; };
} }