Add 6502 disassembler.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-03-07 20:32:24 +00:00
parent 883cbdd404
commit dd6455ceb9
9 changed files with 268 additions and 2 deletions

View file

@ -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

View file

@ -53,6 +53,7 @@ typedef UINT64 uint64_t;
#include <stdexcept>
#include <cstdarg>
#include <cstring>
#include <algorithm>
#include "linux/win.h"

View file

@ -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()

View file

@ -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();
}
}

View file

@ -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();
};
}

View file

@ -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();

View file

@ -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");
}

View file

@ -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;
}

View file

@ -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