2021-03-06 17:41:32 +00:00
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "frontends/sdl/imgui/sdlsettings.h"
|
|
|
|
#include "frontends/sdl/imgui/settingshelper.h"
|
2021-03-14 11:14:03 +00:00
|
|
|
#include "frontends/sdl/sdlframe.h"
|
2021-04-04 14:31:57 +01:00
|
|
|
#include "linux/registry.h"
|
2021-04-04 19:21:04 +01:00
|
|
|
#include "linux/version.h"
|
2021-05-28 18:10:09 +01:00
|
|
|
#include "linux/tape.h"
|
2021-03-06 17:41:32 +00:00
|
|
|
|
|
|
|
#include "Interface.h"
|
|
|
|
#include "CardManager.h"
|
|
|
|
#include "Core.h"
|
|
|
|
#include "CPU.h"
|
|
|
|
#include "CardManager.h"
|
2021-03-21 16:32:48 +00:00
|
|
|
#include "Disk.h"
|
|
|
|
#include "Harddisk.h"
|
2021-03-06 17:41:32 +00:00
|
|
|
#include "Speaker.h"
|
|
|
|
#include "Mockingboard.h"
|
|
|
|
#include "Registry.h"
|
2021-03-27 20:05:09 +00:00
|
|
|
#include "Utilities.h"
|
2021-03-06 18:00:07 +00:00
|
|
|
#include "Memory.h"
|
|
|
|
|
|
|
|
#include "Debugger/DebugDefs.h"
|
2021-03-06 17:41:32 +00:00
|
|
|
|
2021-04-18 19:01:05 +01:00
|
|
|
#include "Tfe/tfe.h"
|
|
|
|
#include "Tfe/tfesupp.h"
|
2021-04-28 20:32:01 +01:00
|
|
|
#include "linux/network/uthernet2.h"
|
2021-04-18 19:01:05 +01:00
|
|
|
|
2021-03-27 13:39:12 +00:00
|
|
|
#include "imgui_internal.h"
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
void HelpMarker(const char* desc)
|
|
|
|
{
|
|
|
|
ImGui::TextDisabled("(?)");
|
|
|
|
if (ImGui::IsItemHovered())
|
|
|
|
{
|
|
|
|
ImGui::BeginTooltip();
|
|
|
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
|
|
|
ImGui::TextUnformatted(desc);
|
|
|
|
ImGui::PopTextWrapPos();
|
|
|
|
ImGui::EndTooltip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-27 11:33:07 +01:00
|
|
|
char getPrintableChar(const uint8_t x)
|
|
|
|
{
|
|
|
|
if (x >= 0x20 && x <= 0x7e)
|
|
|
|
{
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return '.';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void printReg(const char label, const BYTE value)
|
|
|
|
{
|
|
|
|
ImGui::Text("%c '%c' %02X", label, getPrintableChar(value), value);
|
|
|
|
}
|
|
|
|
|
2021-03-20 17:00:29 +00:00
|
|
|
ImVec4 colorrefToImVec4(const COLORREF cr)
|
2021-03-18 19:40:02 +00:00
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
const float coeff = 1.0 / 255.0;
|
|
|
|
const bgra_t * bgra = reinterpret_cast<const bgra_t *>(&cr);
|
|
|
|
const ImVec4 color(bgra->b * coeff, bgra->g * coeff, bgra->r * coeff, 1);
|
|
|
|
return color;
|
|
|
|
}
|
2021-03-18 19:40:02 +00:00
|
|
|
|
2021-04-03 09:46:56 +01:00
|
|
|
uint8_t roundToRGB(float x)
|
|
|
|
{
|
|
|
|
// c++ cast truncates
|
|
|
|
return uint8_t(x * 255 + 0.5);
|
|
|
|
}
|
|
|
|
|
|
|
|
COLORREF imVec4ToColorref(const ImVec4 & color)
|
|
|
|
{
|
|
|
|
const bgra_t bgra = {roundToRGB(color.x), roundToRGB(color.y), roundToRGB(color.z), roundToRGB(color.w)};
|
|
|
|
const COLORREF * cr = reinterpret_cast<const COLORREF *>(&bgra);
|
|
|
|
return *cr;
|
|
|
|
}
|
|
|
|
|
2021-03-20 17:00:29 +00:00
|
|
|
ImVec4 debuggerGetColor(int iColor)
|
|
|
|
{
|
|
|
|
const COLORREF cr = DebuggerGetColor(iColor);
|
|
|
|
const ImVec4 color = colorrefToImVec4(cr);
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
2021-03-20 10:23:53 +00:00
|
|
|
void debuggerTextColored(int iColor, const char* text)
|
|
|
|
{
|
|
|
|
const ImVec4 color = debuggerGetColor(iColor);
|
|
|
|
ImGui::TextColored(color, "%s", text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void displayDisassemblyLine(const DisasmLine_t& line, const int bDisasmFormatFlags)
|
|
|
|
{
|
2021-03-18 19:40:02 +00:00
|
|
|
const char* pMnemonic = g_aOpcodes[line.iOpcode].sMnemonic;
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::Text("%s ", pMnemonic);
|
2021-03-18 19:40:02 +00:00
|
|
|
|
|
|
|
if (line.bTargetImmediate)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, "#$");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (line.bTargetIndexed || line.bTargetIndirect)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, "(");
|
|
|
|
}
|
|
|
|
|
|
|
|
int targetColor;
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_SYMBOL)
|
|
|
|
{
|
|
|
|
targetColor = FG_DISASM_SYMBOL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (line.iOpmode == AM_M)
|
|
|
|
{
|
|
|
|
targetColor = FG_DISASM_OPCODE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
targetColor = FG_DISASM_TARGET;
|
|
|
|
}
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
|
2021-03-20 10:23:53 +00:00
|
|
|
const char * target = line.sTarget;
|
|
|
|
if (target[0] == '$')
|
|
|
|
{
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, "$");
|
|
|
|
++target;
|
|
|
|
}
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(targetColor, target);
|
2021-03-18 19:40:02 +00:00
|
|
|
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
|
|
|
{
|
|
|
|
if (line.nTargetOffset > 0)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, "+");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
else if (line.nTargetOffset < 0)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, "-");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPCODE, line.sTargetOffset);
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (line.bTargetX)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, ",");
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_INFO_REG, "X");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
else if ((line.bTargetY) && (!line.bTargetIndirect))
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, ",");
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_INFO_REG, "Y");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (line.bTargetIndexed || line.bTargetIndirect)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, ")");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (line.bTargetIndexed && line.bTargetY)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_DISASM_OPERATOR, ",");
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
debuggerTextColored(FG_INFO_REG, "Y");
|
2021-03-18 19:40:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-29 14:14:57 +01:00
|
|
|
void standardLabelText(const char * label, const char * text)
|
|
|
|
{
|
|
|
|
// this is "better/different" that ImGui::LabelText();
|
|
|
|
// because it shows the text in the same style as other options
|
|
|
|
// it will not display the ARROW_DOWN, to indicate the option cannot be changed
|
|
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
|
|
|
if (ImGui::BeginCombo(label, text, ImGuiComboFlags_NoArrowButton))
|
|
|
|
{
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::PopItemFlag();
|
2021-03-29 14:14:57 +01:00
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace sa2
|
|
|
|
{
|
|
|
|
|
2021-03-27 20:05:09 +00:00
|
|
|
void ImGuiSettings::showSettings(SDLFrame* frame)
|
2021-03-06 17:41:32 +00:00
|
|
|
{
|
|
|
|
if (ImGui::Begin("Settings", &myShowSettings))
|
|
|
|
{
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
|
|
if (ImGui::BeginTabBar("Settings"))
|
|
|
|
{
|
|
|
|
if (ImGui::BeginTabItem("General"))
|
|
|
|
{
|
|
|
|
ImGui::Checkbox("Apple Video windowed", &windowed);
|
2021-03-06 18:00:07 +00:00
|
|
|
ImGui::SameLine(); HelpMarker("Show Apple video in a separate window.");
|
|
|
|
|
|
|
|
ImGui::Checkbox("Memory", &myShowMemory);
|
|
|
|
ImGui::SameLine(); HelpMarker("Show Apple memory.");
|
2021-03-06 17:41:32 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
if (ImGui::Checkbox("Debugger", &myShowDebugger) && myShowDebugger)
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
frame->ChangeMode(MODE_DEBUG);
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
|
|
|
ImGui::SameLine(); HelpMarker("Show Apple CPU.");
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::Checkbox("Show Demo", &myShowDemo);
|
|
|
|
ImGui::SameLine(); HelpMarker("Show Dear ImGui DemoWindow.");
|
|
|
|
|
2021-03-27 20:05:09 +00:00
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::Text("FPS: %d", int(io.Framerate));
|
2021-03-27 20:05:09 +00:00
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-04-03 10:03:26 +01:00
|
|
|
if (ImGui::Button("Restart"))
|
2021-03-27 20:05:09 +00:00
|
|
|
{
|
|
|
|
frame->Restart();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("ResetMachineState"))
|
|
|
|
{
|
|
|
|
ResetMachineState();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("CtrlReset"))
|
|
|
|
{
|
|
|
|
CtrlReset();
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
2021-03-21 16:32:48 +00:00
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
if (ImGui::BeginTabItem("Hardware"))
|
|
|
|
{
|
2021-03-28 20:05:30 +01:00
|
|
|
ImGui::LabelText("Option", "Value");
|
|
|
|
const eApple2Type a2e = GetApple2Type();
|
|
|
|
const std::map<eApple2Type, std::string> & apple2Types = getAapple2Types();
|
2021-03-06 17:41:32 +00:00
|
|
|
|
2021-03-28 20:05:30 +01:00
|
|
|
if (ImGui::BeginCombo("Apple 2", getApple2Name(a2e).c_str()))
|
|
|
|
{
|
|
|
|
for (const auto & it : apple2Types)
|
2021-03-06 17:41:32 +00:00
|
|
|
{
|
2021-03-28 20:05:30 +01:00
|
|
|
const bool isSelected = it.first == a2e;
|
|
|
|
if (ImGui::Selectable(getApple2Name(it.first).c_str(), isSelected))
|
|
|
|
{
|
|
|
|
SetApple2Type(it.first);
|
|
|
|
REGSAVE(REGVALUE_APPLE2_TYPE, it.first);
|
|
|
|
}
|
|
|
|
if (isSelected)
|
|
|
|
{
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|
2021-03-28 20:05:30 +01:00
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
2021-03-06 17:41:32 +00:00
|
|
|
|
2021-03-29 14:14:57 +01:00
|
|
|
standardLabelText("CPU", getCPUName(GetMainCpu()).c_str());
|
2021-04-03 09:46:56 +01:00
|
|
|
standardLabelText("Mode", getAppModeName(g_nAppMode).c_str());
|
2021-03-28 20:05:30 +01:00
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
ImGui::LabelText("Slot", "Card");
|
|
|
|
CardManager & manager = GetCardMgr();
|
|
|
|
for (size_t slot = 1; slot < 8; ++slot)
|
|
|
|
{
|
2021-04-01 16:04:50 +01:00
|
|
|
const SS_CARDTYPE current = manager.QuerySlot(slot);
|
2021-03-28 20:05:30 +01:00
|
|
|
if (ImGui::BeginCombo(std::to_string(slot).c_str(), getCardName(current).c_str()))
|
|
|
|
{
|
|
|
|
const std::vector<SS_CARDTYPE> & cards = getCardsForSlot(slot);
|
|
|
|
for (SS_CARDTYPE card : cards)
|
|
|
|
{
|
|
|
|
const bool isSelected = card == current;
|
|
|
|
if (ImGui::Selectable(getCardName(card).c_str(), isSelected))
|
|
|
|
{
|
|
|
|
insertCard(slot, card);
|
|
|
|
}
|
|
|
|
if (isSelected)
|
|
|
|
{
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|
2021-03-28 20:05:30 +01:00
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
{
|
2021-03-28 20:05:30 +01:00
|
|
|
// Expansion
|
|
|
|
const SS_CARDTYPE expansion = GetCurrentExpansionMemType();
|
|
|
|
if (ImGui::BeginCombo("Expansion", getCardName(expansion).c_str()))
|
|
|
|
{
|
|
|
|
const std::vector<SS_CARDTYPE> & cards = getExpansionCards();
|
|
|
|
for (SS_CARDTYPE card : cards)
|
|
|
|
{
|
|
|
|
const bool isSelected = card == expansion;
|
|
|
|
if (ImGui::Selectable(getCardName(card).c_str(), isSelected))
|
|
|
|
{
|
|
|
|
SetExpansionMemType(card);
|
|
|
|
}
|
|
|
|
if (isSelected)
|
|
|
|
{
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-03-21 16:32:48 +00:00
|
|
|
if (ImGui::BeginTabItem("Disks"))
|
|
|
|
{
|
2021-05-28 19:14:28 +01:00
|
|
|
CardManager & cardManager = GetCardMgr();
|
|
|
|
|
|
|
|
bool enhancedSpeed = cardManager.GetDisk2CardMgr().GetEnhanceDisk();
|
|
|
|
if (ImGui::Checkbox("Enhanced speed", &enhancedSpeed))
|
|
|
|
{
|
|
|
|
cardManager.GetDisk2CardMgr().SetEnhanceDisk(enhancedSpeed);
|
|
|
|
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), (DWORD)enhancedSpeed);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-04-01 16:04:50 +01:00
|
|
|
size_t dragAndDropSlot;
|
|
|
|
size_t dragAndDropDrive;
|
|
|
|
frame->getDragDropSlotAndDrive(dragAndDropSlot, dragAndDropDrive);
|
|
|
|
|
|
|
|
if (ImGui::BeginTable("Disk2", 12, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit))
|
2021-03-21 16:32:48 +00:00
|
|
|
{
|
2021-03-21 20:07:27 +00:00
|
|
|
ImGui::TableSetupColumn("Slot", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Drive", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Firmware", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Track", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Track", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Phase", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Eject", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Swap", ImGuiTableColumnFlags_WidthFixed);
|
2021-04-01 16:04:50 +01:00
|
|
|
ImGui::TableSetupColumn("D&D", ImGuiTableColumnFlags_WidthFixed);
|
2021-03-21 20:07:27 +00:00
|
|
|
ImGui::TableSetupColumn("Filename", ImGuiTableColumnFlags_WidthStretch);
|
|
|
|
ImGui::TableHeadersRow();
|
|
|
|
|
|
|
|
for (int slot = SLOT5; slot < SLOT7; ++slot)
|
|
|
|
{
|
|
|
|
ImGui::PushID(slot);
|
|
|
|
if (cardManager.QuerySlot(slot) == CT_Disk2)
|
|
|
|
{
|
2021-03-28 20:05:30 +01:00
|
|
|
Disk2InterfaceCard * card2 = dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(slot));
|
2021-03-21 20:07:27 +00:00
|
|
|
|
|
|
|
const int currentDrive = card2->GetCurrentDrive();
|
|
|
|
Disk_Status_e statuses[NUM_DRIVES] = {};
|
|
|
|
card2->GetLightStatus(statuses + 0, statuses + 1);
|
|
|
|
const UINT firmware = card2->GetCurrentFirmware();
|
|
|
|
|
2021-04-01 16:04:50 +01:00
|
|
|
for (size_t drive = DRIVE_1; drive < NUM_DRIVES; ++drive)
|
2021-03-21 20:07:27 +00:00
|
|
|
{
|
|
|
|
ImGui::PushID(drive);
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", slot);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", drive + 1);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", firmware);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", card2->GetTrack(drive));
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (drive == currentDrive)
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted(card2->GetCurrentTrackString().c_str());
|
|
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (drive == currentDrive)
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted(card2->GetCurrentPhaseString().c_str());
|
|
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
2021-04-03 08:47:29 +01:00
|
|
|
ImGui::TextUnformatted(getDiskStatusName(statuses[drive]).c_str());
|
2021-03-21 20:07:27 +00:00
|
|
|
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::SmallButton("Eject"))
|
|
|
|
{
|
|
|
|
card2->EjectDisk(drive);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::SmallButton("Swap"))
|
|
|
|
{
|
|
|
|
card2->DriveSwap();
|
|
|
|
}
|
|
|
|
|
2021-04-01 16:04:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::RadioButton("", (dragAndDropSlot == slot) && (dragAndDropDrive == drive)))
|
|
|
|
{
|
|
|
|
frame->setDragDropSlotAndDrive(slot, drive);
|
|
|
|
}
|
|
|
|
|
2021-03-21 20:07:27 +00:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted(card2->GetFullDiskFilename(drive).c_str());
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
2021-03-21 16:32:48 +00:00
|
|
|
|
2021-04-01 16:04:50 +01:00
|
|
|
if (HD_CardIsEnabled())
|
|
|
|
{
|
|
|
|
ImGui::PushID(7);
|
|
|
|
Disk_Status_e disk1Status_;
|
|
|
|
HD_GetLightStatus(&disk1Status_);
|
|
|
|
for (size_t drive = HARDDISK_1; drive < NUM_HARDDISKS; ++drive)
|
|
|
|
{
|
|
|
|
ImGui::PushID(drive);
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", SLOT7);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", drive + 1);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted("HD");
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
|
2021-04-03 08:47:29 +01:00
|
|
|
ImGui::TextUnformatted(getDiskStatusName(disk1Status_).c_str());
|
2021-04-01 16:04:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::SmallButton("Eject"))
|
|
|
|
{
|
|
|
|
HD_Unplug(drive);
|
|
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::SmallButton("Swap"))
|
|
|
|
{
|
|
|
|
HD_ImageSwap();
|
|
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::RadioButton("", (dragAndDropSlot == SLOT7) && (dragAndDropDrive == drive)))
|
|
|
|
{
|
|
|
|
frame->setDragDropSlotAndDrive(SLOT7, drive);
|
|
|
|
}
|
2021-03-21 16:32:48 +00:00
|
|
|
|
2021-04-01 16:04:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted(HD_GetFullName(drive).c_str());
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
2021-03-21 16:32:48 +00:00
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
if (ImGui::BeginTabItem("Audio"))
|
|
|
|
{
|
|
|
|
const int volumeMax = GetPropertySheet().GetVolumeMax();
|
2021-03-27 13:39:12 +00:00
|
|
|
mySpeakerVolume = volumeMax - SpkrGetVolume();
|
2021-03-06 17:41:32 +00:00
|
|
|
if (ImGui::SliderInt("Speaker volume", &mySpeakerVolume, 0, volumeMax))
|
|
|
|
{
|
|
|
|
SpkrSetVolume(volumeMax - mySpeakerVolume, volumeMax);
|
|
|
|
REGSAVE(TEXT(REGVALUE_SPKR_VOLUME), SpkrGetVolume());
|
|
|
|
}
|
|
|
|
|
2021-03-27 13:39:12 +00:00
|
|
|
myMockingboardVolume = volumeMax - MB_GetVolume();
|
2021-03-06 17:41:32 +00:00
|
|
|
if (ImGui::SliderInt("Mockingboard volume", &myMockingboardVolume, 0, volumeMax))
|
|
|
|
{
|
|
|
|
MB_SetVolume(volumeMax - myMockingboardVolume, volumeMax);
|
|
|
|
REGSAVE(TEXT(REGVALUE_MB_VOLUME), MB_GetVolume());
|
|
|
|
}
|
|
|
|
|
2021-03-27 13:39:12 +00:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if (ImGui::BeginTable("Devices", 5, ImGuiTableFlags_RowBg))
|
|
|
|
{
|
|
|
|
myAudioInfo = getAudioInfo();
|
|
|
|
ImGui::TableSetupColumn("Running");
|
|
|
|
ImGui::TableSetupColumn("Channels");
|
|
|
|
ImGui::TableSetupColumn("Volume");
|
|
|
|
ImGui::TableSetupColumn("Buffer");
|
|
|
|
ImGui::TableSetupColumn("Queue");
|
|
|
|
ImGui::TableHeadersRow();
|
|
|
|
|
|
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); // this requires imgui_internal.h
|
|
|
|
for (SoundInfo & device : myAudioInfo)
|
|
|
|
{
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Checkbox("", &device.running);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::Text("%d", device.channels);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::SliderFloat("", &device.volume, 0.0f, 1.0f, "%.2f");
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::SliderFloat("", &device.buffer, 0.0f, device.size, "%.3f");
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::SliderFloat("", &device.queue, 0.0f, device.size, "%.3f");
|
|
|
|
}
|
|
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, false);
|
|
|
|
|
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
|
2021-04-03 09:46:56 +01:00
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::BeginTabItem("Video"))
|
|
|
|
{
|
|
|
|
Video & video = GetVideo();
|
|
|
|
const VideoType_e videoType = video.GetVideoType();
|
|
|
|
if (ImGui::BeginCombo("Video mode", getVideoTypeName(videoType).c_str()))
|
|
|
|
{
|
|
|
|
for (size_t value = VT_MONO_CUSTOM; value < NUM_VIDEO_MODES; ++value)
|
|
|
|
{
|
|
|
|
const bool isSelected = value == videoType;
|
|
|
|
if (ImGui::Selectable(getVideoTypeName(VideoType_e(value)).c_str(), isSelected))
|
|
|
|
{
|
|
|
|
video.SetVideoType(VideoType_e(value));
|
|
|
|
frame->ApplyVideoModeChange();
|
|
|
|
}
|
|
|
|
if (isSelected)
|
|
|
|
{
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImVec4 color = colorrefToImVec4(video.GetMonochromeRGB());
|
|
|
|
ImGui::ColorEdit3("Monochrome Color", (float*)&color, 0);
|
|
|
|
const COLORREF cr = imVec4ToColorref(color);
|
|
|
|
video.SetMonochromeRGB(cr);
|
|
|
|
frame->ApplyVideoModeChange();
|
|
|
|
|
|
|
|
bool scanLines = video.IsVideoStyle(VS_HALF_SCANLINES);
|
|
|
|
if (ImGui::Checkbox("50% Scan lines", &scanLines))
|
|
|
|
{
|
|
|
|
setVideoStyle(video, VS_HALF_SCANLINES, scanLines);
|
|
|
|
frame->ApplyVideoModeChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool verticalBlend = video.IsVideoStyle(VS_COLOR_VERTICAL_BLEND);
|
|
|
|
if (ImGui::Checkbox("Vertical blend", &verticalBlend))
|
|
|
|
{
|
|
|
|
setVideoStyle(video, VS_COLOR_VERTICAL_BLEND, verticalBlend);
|
|
|
|
frame->ApplyVideoModeChange();
|
|
|
|
}
|
|
|
|
|
2021-04-03 09:55:05 +01:00
|
|
|
bool hertz50 = video.GetVideoRefreshRate() == VR_50HZ;
|
|
|
|
if (ImGui::Checkbox("50Hz video", &hertz50))
|
|
|
|
{
|
|
|
|
video.SetVideoRefreshRate(hertz50 ? VR_50HZ : VR_60HZ);
|
|
|
|
frame->ApplyVideoModeChange();
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-04-18 19:01:05 +01:00
|
|
|
if (ImGui::BeginTabItem("Uthernet"))
|
|
|
|
{
|
2021-05-05 15:56:10 +01:00
|
|
|
if (ImGui::RadioButton("Disabled", tfe_enabled == 0)) { saveTFEEnabled(0); } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Uthernet I", tfe_enabled == 1)) { saveTFEEnabled(1); } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Uthernet II", tfe_enabled == 2)) { saveTFEEnabled(2); }
|
|
|
|
|
2021-05-20 11:57:44 +01:00
|
|
|
const std::string current_interface = get_tfe_interface().c_str();
|
|
|
|
|
|
|
|
if (ImGui::BeginCombo("Interface", current_interface.c_str()))
|
2021-04-18 19:01:05 +01:00
|
|
|
{
|
2021-04-23 20:09:00 +01:00
|
|
|
std::vector<char *> ifaces;
|
2021-04-18 19:01:05 +01:00
|
|
|
if (tfe_enumadapter_open())
|
|
|
|
{
|
|
|
|
char *pname;
|
|
|
|
char *pdescription;
|
|
|
|
|
|
|
|
while (tfe_enumadapter(&pname, &pdescription))
|
2021-04-23 20:09:00 +01:00
|
|
|
{
|
|
|
|
ifaces.push_back(pname);
|
|
|
|
lib_free(pdescription);
|
|
|
|
}
|
|
|
|
tfe_enumadapter_close();
|
|
|
|
|
|
|
|
for (const auto & iface : ifaces)
|
2021-04-18 19:01:05 +01:00
|
|
|
{
|
2021-05-20 11:57:44 +01:00
|
|
|
const bool isSelected = strcmp(iface, current_interface.c_str()) == 0;
|
2021-04-23 20:09:00 +01:00
|
|
|
if (ImGui::Selectable(iface, isSelected))
|
2021-04-18 19:01:05 +01:00
|
|
|
{
|
2021-04-23 20:09:00 +01:00
|
|
|
// the following line interacts with tfe_enumadapter, so we must run it outside the above loop
|
2021-05-20 11:57:44 +01:00
|
|
|
update_tfe_interface(iface);
|
2021-04-23 20:09:00 +01:00
|
|
|
RegSaveString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, iface);
|
2021-04-18 19:01:05 +01:00
|
|
|
}
|
|
|
|
if (isSelected)
|
|
|
|
{
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
2021-04-23 20:09:00 +01:00
|
|
|
lib_free(iface);
|
2021-04-18 19:01:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-05-28 18:10:09 +01:00
|
|
|
if (ImGui::BeginTabItem("Tape"))
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
size_t pos;
|
|
|
|
int frequency;
|
|
|
|
uint8_t bit;
|
|
|
|
getTapeInfo(size, pos, frequency, bit);
|
|
|
|
|
|
|
|
if (pos < size)
|
|
|
|
{
|
|
|
|
const float remaining = float(size - pos) / float(frequency);
|
|
|
|
const float fraction = float(pos) / float(size);
|
|
|
|
char buf[32];
|
|
|
|
sprintf(buf, "-%.1f s", remaining);
|
|
|
|
const ImU32 color = bit ? IM_COL32(200, 0, 0, 100) : IM_COL32(0, 200, 0, 100);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, color);
|
|
|
|
ImGui::ProgressBar(fraction, ImVec2(-FLT_MIN, 0), buf);
|
|
|
|
ImGui::LabelText("Frequency", "%d Hz", frequency);
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
if (ImGui::Button("Eject tape"))
|
|
|
|
{
|
|
|
|
ejectTape();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("Drop a .wav file.");
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-03-20 19:39:25 +00:00
|
|
|
if (ImGui::BeginTabItem("Debugger"))
|
|
|
|
{
|
|
|
|
if (ImGui::RadioButton("Color", g_iColorScheme == SCHEME_COLOR)) { g_iColorScheme = SCHEME_COLOR; } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Mono", g_iColorScheme == SCHEME_MONO)) { g_iColorScheme = SCHEME_MONO; } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("BW", g_iColorScheme == SCHEME_BW)) { g_iColorScheme = SCHEME_BW; }
|
|
|
|
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-04-04 14:31:57 +01:00
|
|
|
if (ImGui::BeginTabItem("Registry"))
|
|
|
|
{
|
|
|
|
if (ImGui::BeginTable("Registry", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit))
|
|
|
|
{
|
|
|
|
ImGui::TableSetupColumn("Option", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
|
|
|
ImGui::TableHeadersRow();
|
|
|
|
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::TreeNode("Registry"))
|
|
|
|
{
|
|
|
|
const std::map<std::string, std::map<std::string, std::string>> values = Registry::instance->getAllValues();
|
|
|
|
|
|
|
|
for (const auto & it1 : values)
|
|
|
|
{
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (ImGui::TreeNodeEx(it1.first.c_str(), ImGuiTreeNodeFlags_SpanFullWidth))
|
|
|
|
{
|
|
|
|
for (const auto & it2 : it1.second)
|
|
|
|
{
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TreeNodeEx(it2.first.c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted(it2.second.c_str());
|
|
|
|
}
|
|
|
|
ImGui::TreePop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::TreePop();
|
|
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::EndTabBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2021-04-04 19:21:04 +01:00
|
|
|
void ImGuiSettings::showAboutWindow()
|
|
|
|
{
|
|
|
|
if (ImGui::Begin("About", &myShowAbout, ImGuiWindowFlags_AlwaysAutoResize))
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("sa2: Apple ][ emulator for Linux");
|
|
|
|
ImGui::Text("Based on AppleWin %s", getVersion().c_str());
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
SDL_version sdl;
|
|
|
|
SDL_GetVersion(&sdl);
|
|
|
|
ImGui::Text("SDL version %d.%d.%d", sdl.major, sdl.minor, sdl.patch);
|
|
|
|
ImGui::Text("Dear ImGui %s", ImGui::GetVersion());
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2021-03-14 11:14:03 +00:00
|
|
|
void ImGuiSettings::show(SDLFrame * frame)
|
2021-03-06 17:41:32 +00:00
|
|
|
{
|
|
|
|
if (myShowSettings)
|
|
|
|
{
|
2021-03-27 20:05:09 +00:00
|
|
|
showSettings(frame);
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-06 18:00:07 +00:00
|
|
|
if (myShowMemory)
|
|
|
|
{
|
|
|
|
showMemory();
|
|
|
|
}
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
if (myShowDebugger)
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-03-14 20:40:37 +00:00
|
|
|
showDebugger(frame);
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
|
|
|
|
2021-04-04 19:21:04 +01:00
|
|
|
if (myShowAbout)
|
|
|
|
{
|
|
|
|
showAboutWindow();
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
if (myShowDemo)
|
|
|
|
{
|
|
|
|
ImGui::ShowDemoWindow(&myShowDemo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-16 18:48:18 +01:00
|
|
|
float ImGuiSettings::drawMenuBar(SDLFrame* frame)
|
2021-03-06 17:41:32 +00:00
|
|
|
{
|
|
|
|
float menuBarHeight;
|
|
|
|
|
|
|
|
if (ImGui::BeginMainMenuBar())
|
|
|
|
{
|
|
|
|
menuBarHeight = ImGui::GetWindowHeight();
|
|
|
|
if (ImGui::BeginMenu("System"))
|
|
|
|
{
|
|
|
|
ImGui::MenuItem("Settings", nullptr, &myShowSettings);
|
2021-03-06 18:00:07 +00:00
|
|
|
ImGui::MenuItem("Memory", nullptr, &myShowMemory);
|
2021-03-14 20:40:37 +00:00
|
|
|
if (ImGui::MenuItem("Debugger", nullptr, &myShowDebugger) && myShowDebugger)
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
frame->ChangeMode(MODE_DEBUG);
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
2021-04-04 19:21:04 +01:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::BeginMenu("Help"))
|
|
|
|
{
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::MenuItem("Demo", nullptr, &myShowDemo);
|
2021-04-04 19:21:04 +01:00
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::MenuItem("About", nullptr, &myShowAbout);
|
2021-03-06 17:41:32 +00:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
ImGui::EndMainMenuBar();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
menuBarHeight = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return menuBarHeight;
|
|
|
|
}
|
|
|
|
|
2021-03-06 18:00:07 +00:00
|
|
|
void ImGuiSettings::showMemory()
|
|
|
|
{
|
|
|
|
if (ImGui::Begin("Memory Viewer", &myShowMemory))
|
|
|
|
{
|
|
|
|
if (ImGui::BeginTabBar("Memory"))
|
|
|
|
{
|
|
|
|
if (ImGui::BeginTabItem("Main"))
|
|
|
|
{
|
|
|
|
void * mainBase = MemGetMainPtr(0);
|
|
|
|
myMainMemoryEditor.DrawContents(mainBase, _6502_MEM_LEN);
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
if (ImGui::BeginTabItem("AUX"))
|
|
|
|
{
|
|
|
|
void * auxBase = MemGetAuxPtr(0);
|
2021-03-20 17:00:45 +00:00
|
|
|
myAuxMemoryEditor.DrawContents(auxBase, _6502_MEM_LEN);
|
2021-03-06 18:00:07 +00:00
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
ImGui::EndTabBar();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2021-05-18 21:05:14 +01:00
|
|
|
void ImGuiSettings::drawDisassemblyTable(SDLFrame * frame)
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-05-12 15:33:14 +01:00
|
|
|
const ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
|
2021-05-26 17:48:44 +01:00
|
|
|
if (ImGui::BeginTable("Disassembly", 10, flags))
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::PushStyleCompact();
|
2021-03-14 20:40:37 +00:00
|
|
|
// weigths proportional to column width (including header)
|
|
|
|
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::TableSetupColumn("", 0, 1);
|
2021-05-27 11:33:07 +01:00
|
|
|
ImGui::TableSetupColumn("Address", 0, 5);
|
2021-03-18 19:40:02 +00:00
|
|
|
ImGui::TableSetupColumn("Opcode", 0, 8);
|
|
|
|
ImGui::TableSetupColumn("Symbol", 0, 10);
|
|
|
|
ImGui::TableSetupColumn("Disassembly", 0, 20);
|
2021-05-27 11:33:07 +01:00
|
|
|
ImGui::TableSetupColumn("Target", 0, 4);
|
2021-03-18 19:40:02 +00:00
|
|
|
ImGui::TableSetupColumn("Value", 0, 6);
|
2021-05-27 11:33:07 +01:00
|
|
|
ImGui::TableSetupColumn("Immediate", 0, 4);
|
|
|
|
ImGui::TableSetupColumn("Branch", 0, 4);
|
2021-05-26 17:48:44 +01:00
|
|
|
ImGui::TableSetupColumn("Cycles", 0, 6);
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableHeadersRow();
|
|
|
|
|
|
|
|
ImGuiListClipper clipper;
|
|
|
|
clipper.Begin(1000);
|
|
|
|
int row = 0;
|
|
|
|
WORD nAddress = g_nDisasmTopAddress;
|
|
|
|
while (clipper.Step())
|
2021-03-14 11:14:03 +00:00
|
|
|
{
|
2021-03-14 20:40:37 +00:00
|
|
|
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)
|
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::PushID(nAddress);
|
2021-03-14 20:40:37 +00:00
|
|
|
DisasmLine_t line;
|
|
|
|
const char* pSymbol = FindSymbolFromAddress(nAddress);
|
|
|
|
const int bDisasmFormatFlags = GetDisassemblyLine(nAddress, line);
|
2021-03-14 11:14:03 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextRow();
|
|
|
|
|
2021-05-16 18:48:18 +01:00
|
|
|
bool breakpointActive;
|
|
|
|
bool breakpointEnabled;
|
|
|
|
GetBreakpointInfo(nAddress, breakpointActive, breakpointEnabled);
|
|
|
|
|
|
|
|
float red = 0.0;
|
|
|
|
int state = 0;
|
|
|
|
if (breakpointEnabled)
|
|
|
|
{
|
|
|
|
red = 0.5;
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
else if (breakpointActive)
|
|
|
|
{
|
|
|
|
red = 0.25;
|
|
|
|
state = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
|
|
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, g_nAppMode != MODE_DEBUG);
|
|
|
|
if (ImGui::CheckBoxTristate("", &state))
|
|
|
|
{
|
|
|
|
if (!breakpointActive && state == 1)
|
|
|
|
{
|
2021-05-18 21:05:14 +01:00
|
|
|
const std::string command = std::string("bpx ") + line.sAddress;
|
|
|
|
debuggerCommand(frame, command.c_str());
|
2021-05-16 18:48:18 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changeBreakpoint(nAddress, state == 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::PopItemFlag();
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
if (nAddress == regs.pc)
|
2021-03-07 20:32:24 +00:00
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(red, 0, 1, 1));
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
|
2021-03-14 15:22:20 +00:00
|
|
|
}
|
2021-05-12 15:33:14 +01:00
|
|
|
else if (nAddress == g_nDisasmCurAddress)
|
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(red, 0, 0.5, 1));
|
|
|
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
|
|
|
|
}
|
|
|
|
else if (breakpointActive || breakpointEnabled)
|
|
|
|
{
|
|
|
|
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(red, 0, 0, 1));
|
2021-05-12 15:33:14 +01:00
|
|
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
|
|
|
|
}
|
|
|
|
|
2021-03-18 19:40:02 +00:00
|
|
|
ImGui::TableNextColumn();
|
2021-03-20 10:23:53 +00:00
|
|
|
ImGui::Selectable(line.sAddress, false, ImGuiSelectableFlags_SpanAllColumns);
|
2021-03-07 20:32:24 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
2021-03-20 10:23:53 +00:00
|
|
|
debuggerTextColored(FG_DISASM_OPCODE, line.sOpCodes);
|
2021-03-07 20:32:24 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (pSymbol)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
debuggerTextColored(FG_DISASM_SYMBOL, pSymbol);
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-03-14 11:14:03 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
2021-03-20 10:23:53 +00:00
|
|
|
displayDisassemblyLine(line, bDisasmFormatFlags);
|
2021-03-18 19:40:02 +00:00
|
|
|
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER)
|
2021-03-14 20:40:37 +00:00
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
debuggerTextColored(FG_DISASM_ADDRESS, line.sTargetPointer);
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-03-07 20:32:24 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_VALUE)
|
|
|
|
{
|
2021-03-20 10:23:53 +00:00
|
|
|
debuggerTextColored(FG_DISASM_OPCODE, line.sTargetValue);
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted(line.sImmediate);
|
|
|
|
}
|
2021-03-13 20:57:33 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (bDisasmFormatFlags & DISASM_FORMAT_BRANCH)
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted(line.sBranch);
|
|
|
|
}
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-05-26 17:48:44 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (g_nAppMode == MODE_DEBUG)
|
|
|
|
{
|
|
|
|
if (myAddressCycles.find(nAddress) != myAddressCycles.end())
|
|
|
|
{
|
|
|
|
ImGui::Text("%d", myAddressCycles[nAddress]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
nAddress += line.nOpbyte;
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::PopID();
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-16 18:48:18 +01:00
|
|
|
ImGui::PopStyleCompact();
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
}
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-05-27 11:33:07 +01:00
|
|
|
void ImGuiSettings::drawRegisters()
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("Registers");
|
|
|
|
ImGui::Separator();
|
|
|
|
printReg('A', regs.a);
|
|
|
|
printReg('X', regs.x);
|
|
|
|
printReg('Y', regs.y);
|
|
|
|
printReg('P', regs.ps);
|
|
|
|
ImGui::Text("PC %04X", regs.pc);
|
|
|
|
ImGui::Text("SP %04X", regs.sp);
|
|
|
|
if (regs.bJammed)
|
|
|
|
{
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::Selectable("CPU Jammed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
void ImGuiSettings::drawConsole()
|
|
|
|
{
|
|
|
|
const ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY;
|
|
|
|
if (ImGui::BeginTable("Console", 1, flags))
|
|
|
|
{
|
2021-05-15 13:32:34 +01:00
|
|
|
for (int i = g_nConsoleDisplayTotal; i >= CONSOLE_FIRST_LINE; --i)
|
2021-03-14 20:40:37 +00:00
|
|
|
{
|
2021-05-15 13:32:34 +01:00
|
|
|
const conchar_t * src = g_aConsoleDisplay[i];
|
2021-03-20 17:00:29 +00:00
|
|
|
char line[CONSOLE_WIDTH + 1];
|
2021-05-15 13:32:34 +01:00
|
|
|
size_t length = 0;
|
2021-03-20 17:00:29 +00:00
|
|
|
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
2021-05-15 13:32:34 +01:00
|
|
|
COLORREF currentColor = DebuggerGetColor( FG_CONSOLE_OUTPUT );
|
2021-03-20 17:00:29 +00:00
|
|
|
|
|
|
|
const auto textAndReset = [&line, &length, & currentColor] () {
|
|
|
|
line[length] = 0;
|
|
|
|
length = 0;
|
|
|
|
const ImVec4 color = colorrefToImVec4(currentColor);
|
|
|
|
ImGui::TextColored(color, "%s", line);
|
|
|
|
};
|
|
|
|
|
2021-05-15 13:32:34 +01:00
|
|
|
for (size_t j = 0; j < CONSOLE_WIDTH; ++j)
|
2021-03-20 17:00:29 +00:00
|
|
|
{
|
|
|
|
const conchar_t g = src[j];
|
|
|
|
if (ConsoleColor_IsColorOrMouse(g))
|
2021-03-14 20:40:37 +00:00
|
|
|
{
|
2021-03-20 17:00:29 +00:00
|
|
|
// colors propagate till next color information
|
|
|
|
// left in, right out = [ )
|
|
|
|
textAndReset();
|
|
|
|
ImGui::SameLine(0, 0);
|
|
|
|
currentColor = ConsoleColor_GetColor(g);
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-03-20 17:00:29 +00:00
|
|
|
line[length] = ConsoleChar_GetChar(g);
|
2021-05-15 13:32:34 +01:00
|
|
|
if (line[length])
|
|
|
|
{
|
|
|
|
++length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-03-20 17:00:29 +00:00
|
|
|
textAndReset();
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
2021-05-15 13:32:34 +01:00
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted(g_aConsoleInput);
|
|
|
|
|
|
|
|
if (myScrollConsole)
|
|
|
|
{
|
|
|
|
ImGui::SetScrollHereY(1.0f);
|
|
|
|
myScrollConsole = false;
|
|
|
|
}
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
}
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-05-26 17:48:44 +01:00
|
|
|
void ImGuiSettings::resetDebuggerCycles()
|
|
|
|
{
|
|
|
|
myAddressCycles.clear();
|
|
|
|
myBaseDebuggerCycles = g_nCumulativeCycles;
|
|
|
|
}
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
void ImGuiSettings::showDebugger(SDLFrame * frame)
|
|
|
|
{
|
2021-05-26 17:48:44 +01:00
|
|
|
myAddressCycles[regs.pc] = g_nCumulativeCycles - myBaseDebuggerCycles;
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
if (ImGui::Begin("Debugger", &myShowDebugger))
|
|
|
|
{
|
2021-05-15 13:32:34 +01:00
|
|
|
ImGui::BeginChild("Console", ImVec2(0, -ImGui::GetFrameHeightWithSpacing()));
|
|
|
|
if (ImGui::BeginTabBar("Tabs"))
|
2021-03-14 20:40:37 +00:00
|
|
|
{
|
|
|
|
if (ImGui::BeginTabItem("CPU"))
|
|
|
|
{
|
|
|
|
ImGui::Checkbox("Auto-sync PC", &mySyncCPU);
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-05-12 15:57:35 +01:00
|
|
|
bool recalc = false;
|
|
|
|
if (mySyncCPU || (ImGui::SameLine(), ImGui::Button("Sync PC")))
|
|
|
|
{
|
|
|
|
recalc = true;
|
|
|
|
g_nDisasmCurAddress = regs.pc;
|
|
|
|
}
|
2021-03-13 20:56:19 +00:00
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
if (ImGui::Button("Step"))
|
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
frame->ChangeMode(MODE_DEBUG);
|
|
|
|
frame->Execute(0);
|
2021-03-14 20:40:37 +00:00
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2021-03-14 11:14:03 +00:00
|
|
|
|
2021-05-15 13:32:34 +01:00
|
|
|
if ((ImGui::SameLine(), ImGui::Button("Debug")))
|
|
|
|
{
|
|
|
|
frame->ChangeMode(MODE_DEBUG);
|
2021-05-28 19:25:29 +01:00
|
|
|
resetDebuggerCycles();
|
2021-05-15 13:32:34 +01:00
|
|
|
}
|
2021-05-16 18:48:18 +01:00
|
|
|
if ((ImGui::SameLine(), ImGui::Button("Continue")))
|
|
|
|
{
|
|
|
|
frame->ChangeMode(MODE_RUNNING);
|
|
|
|
}
|
2021-05-12 15:57:35 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::Text("%016llu - %04X", g_nCumulativeCycles, regs.pc);
|
2021-03-14 20:40:37 +00:00
|
|
|
|
2021-05-12 15:57:35 +01:00
|
|
|
if (!mySyncCPU)
|
|
|
|
{
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushItemWidth(ImGui::GetFontSize() * 5);
|
|
|
|
if (ImGui::InputScalar("Reference", ImGuiDataType_U16, &g_nDisasmCurAddress, nullptr, nullptr, "%04X", ImGuiInputTextFlags_CharsHexadecimal))
|
|
|
|
{
|
|
|
|
recalc = true;
|
|
|
|
}
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
// do not flip next ||
|
2021-03-18 19:40:02 +00:00
|
|
|
if (ImGui::SliderInt("PC position", &g_nDisasmCurLine, 0, 100) || recalc)
|
2021-03-14 20:40:37 +00:00
|
|
|
{
|
|
|
|
DisasmCalcTopBotAddress();
|
|
|
|
}
|
2021-05-12 15:57:35 +01:00
|
|
|
|
2021-05-27 11:33:07 +01:00
|
|
|
// this is about right to contain the fixed-size register child
|
|
|
|
const ImVec2 registerTextSize = ImGui::CalcTextSize("012345678901");
|
|
|
|
|
|
|
|
ImGui::BeginChild("Disasm", ImVec2(-registerTextSize.x, 0));
|
2021-05-18 21:05:14 +01:00
|
|
|
drawDisassemblyTable(frame);
|
2021-05-27 11:33:07 +01:00
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::BeginChild("Registers");
|
|
|
|
drawRegisters();
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
2021-03-14 20:40:37 +00:00
|
|
|
ImGui::EndTabItem();
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
2021-03-14 20:40:37 +00:00
|
|
|
if (ImGui::BeginTabItem("Console"))
|
|
|
|
{
|
|
|
|
drawConsole();
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
ImGui::EndTabBar();
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
2021-05-15 13:32:34 +01:00
|
|
|
ImGui::EndChild();
|
2021-05-16 18:48:18 +01:00
|
|
|
if (g_nAppMode == MODE_DEBUG)
|
2021-05-15 13:32:34 +01:00
|
|
|
{
|
2021-05-16 18:48:18 +01:00
|
|
|
if (ImGui::InputText("Prompt", myInputBuffer, IM_ARRAYSIZE(myInputBuffer), ImGuiInputTextFlags_EnterReturnsTrue))
|
2021-05-15 13:32:34 +01:00
|
|
|
{
|
2021-05-18 18:56:37 +01:00
|
|
|
debuggerCommand(frame, myInputBuffer);
|
2021-05-16 18:48:18 +01:00
|
|
|
myInputBuffer[0] = 0;
|
|
|
|
ImGui::SetKeyboardFocusHere(-1);
|
2021-05-15 13:32:34 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-07 20:32:24 +00:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2021-05-18 18:56:37 +01:00
|
|
|
void ImGuiSettings::debuggerCommand(SDLFrame * frame, const char * s)
|
2021-05-16 18:48:18 +01:00
|
|
|
{
|
|
|
|
for (; *s; ++s)
|
|
|
|
{
|
|
|
|
DebuggerInputConsoleChar(*s);
|
|
|
|
}
|
2021-05-18 18:56:37 +01:00
|
|
|
// this might trigger a GO
|
|
|
|
frame->ResetSpeed();
|
2021-05-16 18:48:18 +01:00
|
|
|
DebuggerProcessKey(VK_RETURN);
|
|
|
|
myScrollConsole = true;
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:41:32 +00:00
|
|
|
}
|