Add 6502 disassembler.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
883cbdd404
commit
dd6455ceb9
9 changed files with 268 additions and 2 deletions
|
@ -1,6 +1,14 @@
|
|||
include(FindPkgConfig)
|
||||
|
||||
set(SOURCE_FILES
|
||||
Debugger/Debugger_Disassembler.cpp
|
||||
Debugger/Debugger_Symbols.cpp
|
||||
Debugger/Debugger_DisassemblerData.cpp
|
||||
Debugger/Debugger_Console.cpp
|
||||
Debugger/Debugger_Assembler.cpp
|
||||
Debugger/Debugger_Parser.cpp
|
||||
Debugger/Debugger_Range.cpp
|
||||
|
||||
Speaker.cpp
|
||||
SoundCore.cpp
|
||||
AY8910.cpp
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef UINT64 uint64_t;
|
|||
#include <stdexcept>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
#include "linux/win.h"
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Riff.h"
|
||||
#include "Utilities.h"
|
||||
#include "Interface.h"
|
||||
#include "Debugger/Debug.h"
|
||||
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
|
@ -87,6 +88,8 @@ namespace common2
|
|||
GetCardMgr().GetDisk2CardMgr().Reset();
|
||||
HD_Reset();
|
||||
Snapshot_Startup();
|
||||
|
||||
DebugInitialize();
|
||||
}
|
||||
|
||||
Initialisation::~Initialisation()
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "Registry.h"
|
||||
#include "Memory.h"
|
||||
|
||||
#include "Debugger/Debug.h"
|
||||
#include "Debugger/DebugDefs.h"
|
||||
|
||||
namespace
|
||||
|
@ -51,6 +52,12 @@ namespace sa2
|
|||
ImGui::Checkbox("Memory", &myShowMemory);
|
||||
ImGui::SameLine(); HelpMarker("Show Apple memory.");
|
||||
|
||||
if (ImGui::Checkbox("CPU", &myShowCPU) && myShowCPU)
|
||||
{
|
||||
DebugBegin();
|
||||
}
|
||||
ImGui::SameLine(); HelpMarker("Show Apple CPU.");
|
||||
|
||||
ImGui::Checkbox("Show Demo", &myShowDemo);
|
||||
ImGui::SameLine(); HelpMarker("Show Dear ImGui DemoWindow.");
|
||||
|
||||
|
@ -146,6 +153,11 @@ namespace sa2
|
|||
showMemory();
|
||||
}
|
||||
|
||||
if (myShowCPU)
|
||||
{
|
||||
showCPU();
|
||||
}
|
||||
|
||||
if (myShowDemo)
|
||||
{
|
||||
ImGui::ShowDemoWindow(&myShowDemo);
|
||||
|
@ -163,6 +175,10 @@ namespace sa2
|
|||
{
|
||||
ImGui::MenuItem("Settings", nullptr, &myShowSettings);
|
||||
ImGui::MenuItem("Memory", nullptr, &myShowMemory);
|
||||
if (ImGui::MenuItem("CPU", nullptr, &myShowCPU) && myShowCPU)
|
||||
{
|
||||
DebugBegin();
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("Demo", nullptr, &myShowDemo);
|
||||
ImGui::EndMenu();
|
||||
|
@ -201,4 +217,90 @@ namespace sa2
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImGuiSettings::showCPU()
|
||||
{
|
||||
if (ImGui::Begin("CPU", &myShowCPU))
|
||||
{
|
||||
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::SliderInt("PC position", &g_nDisasmCurLine, 1, 100) || recalc)
|
||||
{
|
||||
g_nDisasmCurAddress = regs.pc;
|
||||
DisasmCalcTopBotAddress();
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("CPU"))
|
||||
{
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuter;
|
||||
if (ImGui::BeginTable("CPU", 7, flags))
|
||||
{
|
||||
// weigths proportional to column width (including header)
|
||||
ImGui::TableSetupColumn("Disassembly", 0, 30);
|
||||
ImGui::TableSetupColumn("Target", 0, 6);
|
||||
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)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
DisasmLine_t line;
|
||||
const char* pSymbol = FindSymbolFromAddress(nAddress);
|
||||
const int bDisasmFormatFlags = GetDisassemblyLine(nAddress, line);
|
||||
nAddress += line.nOpbyte;
|
||||
|
||||
static size_t m = 0;
|
||||
char buffer[CONSOLE_WIDTH];
|
||||
FormatDisassemblyLine(line, buffer, sizeof(buffer));
|
||||
m = std::max(m, strlen(buffer));
|
||||
|
||||
if (nAddress == regs.pc)
|
||||
{
|
||||
const ImU32 currentBgColor = ImGui::GetColorU32(ImVec4(0, 0, 1, 1));
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, currentBgColor);
|
||||
}
|
||||
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Selectable(buffer, false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::TextUnformatted(line.sTarget);
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextUnformatted(line.sTargetOffset);
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
ImGui::TextUnformatted(line.sTargetPointer);
|
||||
ImGui::TableSetColumnIndex(4);
|
||||
ImGui::TextUnformatted(line.sTargetValue);
|
||||
ImGui::TableSetColumnIndex(5);
|
||||
ImGui::TextUnformatted(line.sImmediate);
|
||||
ImGui::TableSetColumnIndex(6);
|
||||
ImGui::TextUnformatted(line.sBranch);
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace sa2
|
|||
bool myShowDemo = false;
|
||||
bool myShowSettings = false;
|
||||
bool myShowMemory = false;
|
||||
bool myShowCPU = false;
|
||||
bool mySyncCPU = false;
|
||||
|
||||
int mySpeakerVolume = 50;
|
||||
int myMockingboardVolume = 50;
|
||||
|
@ -26,6 +28,7 @@ namespace sa2
|
|||
|
||||
void showSettings();
|
||||
void showMemory();
|
||||
void showCPU();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -336,6 +336,7 @@ namespace sa2
|
|||
SoundCore_SetFade(FADE_OUT);
|
||||
break;
|
||||
case MODE_PAUSED:
|
||||
case MODE_DEBUG:
|
||||
g_nAppMode = MODE_RUNNING;
|
||||
SoundCore_SetFade(FADE_IN);
|
||||
mySpeed.reset();
|
||||
|
|
|
@ -2,13 +2,139 @@
|
|||
#include "Common.h"
|
||||
|
||||
#include "Debug.h"
|
||||
#include "DebugDefs.h"
|
||||
#include "CPU.h"
|
||||
#include "Core.h"
|
||||
#include "Interface.h"
|
||||
|
||||
void InitDisasm()
|
||||
{
|
||||
g_nDisasmCurAddress = regs.pc;
|
||||
DisasmCalcTopBotAddress();
|
||||
}
|
||||
|
||||
void WindowUpdateDisasmSize()
|
||||
{
|
||||
g_nDisasmWinHeight = (MAX_DISPLAY_LINES - g_nConsoleDisplayLines) / 2;
|
||||
g_nDisasmCurLine = MAX(0, (g_nDisasmWinHeight - 1) / 2);
|
||||
}
|
||||
|
||||
void DebugInitialize()
|
||||
{
|
||||
WindowUpdateDisasmSize();
|
||||
|
||||
extern bool g_bSymbolsDisplayMissingFile;
|
||||
g_bSymbolsDisplayMissingFile = false;
|
||||
|
||||
g_iCommand = CMD_SYMBOLS_ROM;
|
||||
CmdSymbolsLoad(0);
|
||||
|
||||
g_iCommand = CMD_SYMBOLS_APPLESOFT;
|
||||
CmdSymbolsLoad(0);
|
||||
|
||||
g_iCommand = CMD_SYMBOLS_USER_1;
|
||||
CmdSymbolsLoad(0);
|
||||
|
||||
g_bSymbolsDisplayMissingFile = true;
|
||||
}
|
||||
|
||||
void DebugReset(void)
|
||||
{
|
||||
}
|
||||
|
||||
void DebugBegin()
|
||||
{
|
||||
// This is called every time the debugger is entered.
|
||||
g_nAppMode = MODE_DEBUG;
|
||||
GetFrame().FrameRefreshStatus(DRAW_TITLE | DRAW_DISK_STATUS);
|
||||
|
||||
if (GetMainCpu() == CPU_6502)
|
||||
{
|
||||
g_aOpcodes = & g_aOpcodes6502[ 0 ]; // Apple ][, ][+, //e
|
||||
g_aOpmodes[ AM_2 ].m_nBytes = 1;
|
||||
g_aOpmodes[ AM_3 ].m_nBytes = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_aOpcodes = & g_aOpcodes65C02[ 0 ]; // Enhanced Apple //e
|
||||
g_aOpmodes[ AM_2 ].m_nBytes = 2;
|
||||
g_aOpmodes[ AM_3 ].m_nBytes = 3;
|
||||
}
|
||||
|
||||
InitDisasm();
|
||||
}
|
||||
|
||||
|
||||
DWORD extbench = 0;
|
||||
|
||||
void DebugReset(void)
|
||||
// NOTE: BreakpointSource_t and g_aBreakpointSource must match!
|
||||
const char *g_aBreakpointSource[ NUM_BREAKPOINT_SOURCES ] =
|
||||
{ // Used to be one char, since ArgsCook also uses // TODO/FIXME: Parser use Param[] ?
|
||||
// Used for both Input & Output!
|
||||
// Regs
|
||||
"A", // Reg A
|
||||
"X", // Reg X
|
||||
"Y", // Reg Y
|
||||
// Special
|
||||
"PC", // Program Counter -- could use "$"
|
||||
"S" , // Stack Pointer
|
||||
// Flags -- .8 Moved: Flag names from g_aFlagNames[] to "inlined" g_aBreakpointSource[]
|
||||
"P", // Processor Status
|
||||
"C", // ---- ---1 Carry
|
||||
"Z", // ---- --1- Zero
|
||||
"I", // ---- -1-- Interrupt
|
||||
"D", // ---- 1--- Decimal
|
||||
"B", // ---1 ---- Break
|
||||
"R", // --1- ---- Reserved
|
||||
"V", // -1-- ---- Overflow
|
||||
"N", // 1--- ---- Sign
|
||||
// Misc
|
||||
"OP", // Opcode/Instruction/Mnemonic
|
||||
"M", // Mem RW
|
||||
"M", // Mem READ_ONLY
|
||||
"M", // Mem WRITE_ONLY
|
||||
// TODO: M0 ram bank 0, M1 aux ram ?
|
||||
};
|
||||
|
||||
WORD g_nDisasmTopAddress = 0;
|
||||
WORD g_nDisasmBotAddress = 0;
|
||||
WORD g_nDisasmCurAddress = 0;
|
||||
|
||||
bool g_bDisasmCurBad = false;
|
||||
int g_nDisasmCurLine = 0; // Aligned to Top or Center
|
||||
int g_iDisasmCurState = CURSOR_NORMAL;
|
||||
|
||||
int g_nDisasmWinHeight = 0;
|
||||
|
||||
MemorySearchResults_t g_vMemorySearchResults;
|
||||
|
||||
int g_iCommand; // last command (enum) // used for consecutive commands
|
||||
|
||||
bool g_bConfigDisasmAddressView = true;
|
||||
int g_bConfigDisasmClick = 4; // GH#462 alt=1, ctrl=2, shift=4 bitmask (default to Shift-Click)
|
||||
bool g_bConfigDisasmAddressColon = true;
|
||||
bool g_bConfigDisasmOpcodesView = true;
|
||||
bool g_bConfigDisasmOpcodeSpaces = true;
|
||||
int g_iConfigDisasmTargets = DISASM_TARGET_BOTH;
|
||||
int g_iConfigDisasmBranchType = DISASM_BRANCH_FANCY;
|
||||
int g_bConfigDisasmImmediateChar = DISASM_IMMED_BOTH;
|
||||
int g_iConfigDisasmScroll = 3; // favor 3 byte opcodes
|
||||
// Config - Info
|
||||
bool g_bConfigInfoTargetPointer = false;
|
||||
|
||||
MemoryTextFile_t g_ConfigState;
|
||||
|
||||
int FindParam(LPCTSTR pLookupName, Match_e eMatch, int & iParam_, int iParamBegin, int iParamEnd )
|
||||
{
|
||||
throw std::runtime_error("FindParam: not implemented");
|
||||
}
|
||||
|
||||
void DebugDisplay ( BOOL bInitDisasm )
|
||||
void DebugDisplay ( BOOL bInitDisasm )
|
||||
{
|
||||
throw std::runtime_error("DebugDisplay: not implemented");
|
||||
}
|
||||
|
||||
Update_t Help_Arg_1( int iCommandHelp )
|
||||
{
|
||||
throw std::runtime_error("Help_Arg_1: not implemented");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "linux/windows/strings.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
// make all chars in buffer lowercase
|
||||
DWORD CharLowerBuff(LPTSTR lpsz, DWORD cchLength)
|
||||
|
@ -16,3 +17,11 @@ void strcpy_s(char * dest, size_t size, const char * source)
|
|||
{
|
||||
strncpy(dest, source, size);
|
||||
}
|
||||
|
||||
int vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list argptr)
|
||||
{
|
||||
// is this even right?
|
||||
const int res = vsnprintf(buffer, sizeOfBuffer, format, argptr);
|
||||
buffer[sizeOfBuffer - 1] = 0;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,20 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <ctype.h>
|
||||
#include <cstdarg>
|
||||
|
||||
void strcpy_s(char * dest, size_t size, const char * source);
|
||||
|
||||
int vsnprintf_s(
|
||||
char *buffer,
|
||||
size_t sizeOfBuffer,
|
||||
size_t count,
|
||||
const char *format,
|
||||
va_list argptr
|
||||
);
|
||||
|
||||
#define _TRUNCATE ((size_t)-1)
|
||||
|
||||
#define sprintf_s snprintf
|
||||
|
||||
#define _strdup strdup
|
||||
|
@ -21,6 +32,8 @@ void strcpy_s(char * dest, size_t size, const char * source);
|
|||
#define _tcschr strchr
|
||||
#define _tcsstr strstr
|
||||
#define _tcscpy strcpy
|
||||
#define _tcstol strtol
|
||||
#define _tcstoul strtoul
|
||||
#define _snprintf snprintf
|
||||
#define wsprintf sprintf
|
||||
#define sscanf_s sscanf
|
||||
|
|
Loading…
Add table
Reference in a new issue