Stripped old debugger code
This commit is contained in:
parent
59d9d8f910
commit
de279f4721
11 changed files with 40 additions and 2269 deletions
|
|
@ -40,7 +40,6 @@ list(APPEND RUNTIME_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualMMU.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp
|
||||
|
|
@ -49,7 +48,6 @@ list(APPEND RUNTIME_SOURCE_FILES
|
|||
list(APPEND DEBUGGER_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/debugger_main.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/DisassemblyLoader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/debugger/Debugger.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
|
||||
|
|
@ -58,7 +56,6 @@ list(APPEND DEBUGGER_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualMMU.cpp
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@ namespace dragon
|
|||
|
||||
void Assembler::saveCurrentStageToFile(void)
|
||||
{
|
||||
std::cout << "LINES: " << (int)m_lines.size() << "\n";
|
||||
// std::cout << "LINES: " << (int)m_lines.size() << "\n";
|
||||
ostd::FileSystem::writeTextFile(Application::args.final_stage_path, m_lines);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,105 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostd/io/IOHandlers.hpp>
|
||||
#include "../assembler/Assembler.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
typedef std::vector<dragon::code::Assembler::tDisassemblyLine> DisassemblyList;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
public: struct tCommandLineArgs
|
||||
{
|
||||
inline tCommandLineArgs(void) { }
|
||||
String machine_config_path = "";
|
||||
bool verbose_load = false;
|
||||
bool force_load = false;
|
||||
bool step_exec = false;
|
||||
bool track_step_diff = true;
|
||||
bool auto_start_debug = false;
|
||||
bool hide_virtual_display = true;
|
||||
bool track_call_stack = true;
|
||||
bool auto_track_all_data_symbols = true;
|
||||
String force_load_file = "";
|
||||
u16 force_load_mem_offset = 0x00;
|
||||
};
|
||||
public: struct tDebuggerData
|
||||
{
|
||||
inline tDebuggerData(void) { }
|
||||
tCommandLineArgs args;
|
||||
DisassemblyList code;
|
||||
DisassemblyList labels;
|
||||
DisassemblyList data;
|
||||
std::vector<u16> trackedAddresses;
|
||||
String command;
|
||||
i32 labelLineLength { 40 };
|
||||
u16 currentAddress { 0 };
|
||||
bool userQuit { false };
|
||||
String disassemblyDirectory { "disassembly" };
|
||||
std::vector<u16> manualBreakPoints;
|
||||
};
|
||||
struct tCloseEventListener : public ostd::BaseObject
|
||||
{
|
||||
void init(void);
|
||||
void handleSignal(ostd::Signal& signal);
|
||||
inline bool hasHappened(void) const { return m_mainWindowClosed; }
|
||||
|
||||
private:
|
||||
bool m_mainWindowClosed { false };
|
||||
};
|
||||
public: class Utils
|
||||
{
|
||||
public:
|
||||
static DisassemblyList findCodeRegion(const DisassemblyList& code, u16 address, u16 codeRegionMargin);
|
||||
static String findSymbol(const DisassemblyList& labels, u16 address, u16* outSize = nullptr);
|
||||
static u16 findSymbol(const DisassemblyList& labels, const String& symbol, u16* outSize = nullptr);
|
||||
static bool isValidLabelNameChar(char c);
|
||||
static void clearConsoleLine(void);
|
||||
static bool isEscapeKeyPressed(bool blocking = false);
|
||||
static ostd::ConsoleOutputHandler& printFullLine(char c, const ostd::ConsoleColors::tConsoleColor& foreground);
|
||||
static ostd::ConsoleOutputHandler& printFullLine(char c, const ostd::ConsoleColors::tConsoleColor& foreground, const ostd::ConsoleColors::tConsoleColor& background);
|
||||
static void removeBreakPoint(u16 addr);
|
||||
static bool isBreakPoint(u16 addr);
|
||||
static void addBreakPoint(u16 addr);
|
||||
};
|
||||
public: class Display
|
||||
{
|
||||
public:
|
||||
static void colorizeInstructionBody(const String& instBody, bool currentLine, const DisassemblyList& labelList);
|
||||
static void colorCodeInstructions(const String& inst, bool currentLine, const DisassemblyList& labelList);
|
||||
static void printPrompt(void);
|
||||
static void printStep(void);
|
||||
static void printDiff(void);
|
||||
static void printTrackedAddresses(void);
|
||||
static void printStack(u16 nrows);
|
||||
static void printCallStack(void);
|
||||
static void printHelp(void);
|
||||
static String changeScreen(void);
|
||||
};
|
||||
public:
|
||||
static void processErrors(void);
|
||||
static i32 loadArguments(int argc, char** argv);
|
||||
static i32 initRuntime(void);
|
||||
static String getCommandInput(void);
|
||||
static inline tDebuggerData& data(void) { return debugger; }
|
||||
static inline ostd::ConsoleOutputHandler& output(void) { return out; }
|
||||
static i32 topLevelPrompt(void);
|
||||
static i32 executeRuntime(void);
|
||||
|
||||
private:
|
||||
static i32 step_execution(bool& outUserQuit, bool exec_first_step = true);
|
||||
static i32 normal_runtime(bool& outUserQuit);
|
||||
static void exec_watch_command(void);
|
||||
static void print_top_level_prompt_help(void);
|
||||
static void print_application_help(void);
|
||||
|
||||
private:
|
||||
inline static tDebuggerData debugger;
|
||||
inline static ostd::ConsoleOutputHandler out;
|
||||
static tCloseEventListener closeEventListener;
|
||||
|
||||
public:
|
||||
inline static const String InputCommandQuit = "//quit//";
|
||||
};
|
||||
}
|
||||
|
|
@ -1,54 +1,29 @@
|
|||
#include <ostd/utils/Defines.hpp>
|
||||
#include "Debugger.hpp"
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
// #include "DebuggerNew.hpp"
|
||||
// #include "../runtime/DragonRuntime.hpp"
|
||||
#include <ostd/utils/Signals.hpp>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//Loading commandline arguments
|
||||
i32 rValue = dragon::Debugger::loadArguments(argc, argv);
|
||||
if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
return 0;
|
||||
if (rValue != 0) return rValue;
|
||||
|
||||
//Initializing the runtime
|
||||
rValue = dragon::Debugger::initRuntime();
|
||||
if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
return 0;
|
||||
if (rValue != 0) return rValue;
|
||||
|
||||
//Running top-level prompt
|
||||
rValue = dragon::Debugger::topLevelPrompt();
|
||||
if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
return 0;
|
||||
if (rValue != 0) return rValue;
|
||||
|
||||
//Executing the runtime
|
||||
return dragon::Debugger::executeRuntime();
|
||||
|
||||
|
||||
|
||||
// dragon::DebuggerNew debuggerInstance;
|
||||
// debuggerInstance.initialize(2000, 1090, "DragonVM Live Debugger");
|
||||
// debuggerInstance.setClearColor({ 5, 0, 0 });
|
||||
|
||||
// //Loading commandline arguments
|
||||
// i32 rValue = debuggerInstance.loadArguments(argc, argv);
|
||||
// i32 rValue = dragon::Debugger::loadArguments(argc, argv);
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
// //Initializing the runtime
|
||||
// rValue = debuggerInstance.initRuntime();
|
||||
// rValue = dragon::Debugger::initRuntime();
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
// while (debuggerInstance.isRunning())
|
||||
// {
|
||||
// debuggerInstance.update();
|
||||
// }
|
||||
// //Running top-level prompt
|
||||
// rValue = dragon::Debugger::topLevelPrompt();
|
||||
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
|
||||
// return 0;
|
||||
// if (rValue != 0) return rValue;
|
||||
|
||||
// //Executing the runtime
|
||||
// return dragon::Debugger::executeRuntime();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,11 +82,6 @@ namespace dragon
|
|||
|
||||
void VirtualCPU::pushStackFrame(void)
|
||||
{
|
||||
if (m_debugModeEnabled)
|
||||
{
|
||||
__debug_store_stack_frame_string_on_push();
|
||||
return;
|
||||
}
|
||||
u16 argStartAddr = readRegister(data::Registers::SP) + 2;
|
||||
u16 argCount = m_memory.read16(argStartAddr);
|
||||
if (argCount == 0)
|
||||
|
|
@ -120,7 +115,6 @@ namespace dragon
|
|||
u16 framePointerAddr = readRegister(data::Registers::FP);
|
||||
writeRegister16(data::Registers::SP, framePointerAddr);
|
||||
m_stackFrameSize = popFromStack();
|
||||
// u16 tmpStackFrameSize = m_stackFrameSize;
|
||||
|
||||
writeRegister16(data::Registers::FP, popFromStack());
|
||||
writeRegister16(data::Registers::IP, popFromStack());
|
||||
|
|
@ -139,12 +133,7 @@ namespace dragon
|
|||
|
||||
u16 nArgs = popFromStack();
|
||||
for (i32 i = 0; i < nArgs; i++)
|
||||
{
|
||||
popFromStack();
|
||||
// writeRegister(data::Registers::FP, readRegister(data::Registers::FP) - 2);
|
||||
}
|
||||
|
||||
// writeRegister(data::Registers::FP, framePointerAddr + tmpStackFrameSize);
|
||||
}
|
||||
|
||||
bool VirtualCPU::readFlag(u8 flg)
|
||||
|
|
@ -173,15 +162,15 @@ namespace dragon
|
|||
m_subroutineCounter++;
|
||||
m_interruptHandlerCount++;
|
||||
writeRegister16(data::Registers::IP, handlerAddress);
|
||||
if (m_debugModeEnabled && hardware)
|
||||
{
|
||||
DragonRuntime::tCallInfo interruptData;
|
||||
interruptData.info = "HW INT";
|
||||
interruptData.addr = intValue;
|
||||
interruptData.inst_addr = 0x0000;
|
||||
interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled);
|
||||
ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::Signal::Priority::RealTime, interruptData);
|
||||
}
|
||||
// if (m_debugModeEnabled && hardware)
|
||||
// {
|
||||
// DragonRuntime::tCallInfo interruptData;
|
||||
// interruptData.info = "HW INT";
|
||||
// interruptData.addr = intValue;
|
||||
// interruptData.inst_addr = 0x0000;
|
||||
// interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled);
|
||||
// ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::Signal::Priority::RealTime, interruptData);
|
||||
// }
|
||||
}
|
||||
|
||||
bool VirtualCPU::loadExtension(void)
|
||||
|
|
@ -222,33 +211,26 @@ namespace dragon
|
|||
{
|
||||
case data::OpCodes::NoOp:
|
||||
{
|
||||
|
||||
//
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::DEBUG_Break:
|
||||
{
|
||||
if (!m_debugModeEnabled) break;
|
||||
m_isDebugBreakPoint = true;
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::DEBUG_DumpRAM:
|
||||
{
|
||||
if (!m_debugModeEnabled) break;
|
||||
ostd::Memory::saveByteStreamToFile(*DragonRuntime::ram.getByteStream(), "ram_dump.bin");
|
||||
m_isDebugBreakPoint = true;
|
||||
m_ramDumped = true;
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::BIOSModeImm:
|
||||
{
|
||||
u16 tmpAddr = m_currentAddr;
|
||||
i8 value = fetch8();
|
||||
if (tmpAddr >= data::MemoryMapAddresses::BIOS_End)
|
||||
m_biosMode = false;
|
||||
else
|
||||
m_biosMode = value != 0;
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::DEBUG_StartProfile:
|
||||
{
|
||||
if (!m_debugModeEnabled) break;
|
||||
i8 id = fetch8();
|
||||
i8 timeUnit = fetch8();
|
||||
ostd::eTimeUnits tu = ostd::eTimeUnits::Milliseconds;
|
||||
|
|
@ -264,11 +246,22 @@ namespace dragon
|
|||
break;
|
||||
case data::OpCodes::DEBUG_StopProfile:
|
||||
{
|
||||
if (!m_debugModeEnabled) break;
|
||||
if (m_debugProfilerStarted)
|
||||
m_profilerTimer.end(true);
|
||||
m_debugProfilerStarted = false;
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::BIOSModeImm:
|
||||
{
|
||||
u16 tmpAddr = m_currentAddr;
|
||||
i8 value = fetch8();
|
||||
if (tmpAddr >= data::MemoryMapAddresses::BIOS_End)
|
||||
m_biosMode = false;
|
||||
else
|
||||
m_biosMode = value != 0;
|
||||
}
|
||||
break;
|
||||
case data::OpCodes::MovImmReg:
|
||||
{
|
||||
u8 regAddr = fetch8();
|
||||
|
|
@ -325,16 +318,6 @@ namespace dragon
|
|||
m_memory.write16(destAddr, value);
|
||||
}
|
||||
break;
|
||||
// case data::OpCodes::MovImmRegOffReg:
|
||||
// {
|
||||
// u8 destRegAddr = fetch8();
|
||||
// u16 addr = fetch16();
|
||||
// u8 offRegAddr = fetch8();
|
||||
// i16 offset = readRegister(offRegAddr);
|
||||
// i16 value = m_memory.read16(addr + offset);
|
||||
// writeRegister(destRegAddr, value);
|
||||
// }
|
||||
// break;
|
||||
case data::OpCodes::MovRegDerefReg:
|
||||
{
|
||||
u8 destRegAddr = fetch8();
|
||||
|
|
@ -821,7 +804,6 @@ namespace dragon
|
|||
case data::OpCodes::Ret:
|
||||
{
|
||||
popStackFrame();
|
||||
// m_subroutineCounter = ZERO(m_subroutineCounter - 1);
|
||||
m_subroutineCounter--;
|
||||
}
|
||||
break;
|
||||
|
|
@ -839,7 +821,6 @@ namespace dragon
|
|||
{
|
||||
m_interruptHandlerCount--;
|
||||
popStackFrame();
|
||||
// m_subroutineCounter = ZERO(m_subroutineCounter - 1);
|
||||
m_subroutineCounter--;
|
||||
}
|
||||
break;
|
||||
|
|
@ -903,60 +884,5 @@ namespace dragon
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VirtualCPU::__debug_store_stack_frame_string_on_push(void)
|
||||
{
|
||||
if (!m_debugModeEnabled) return;
|
||||
String stackFrameString = "";
|
||||
|
||||
u16 argStartAddr = readRegister(data::Registers::SP) + 2;
|
||||
u16 argCount = m_memory.read16(argStartAddr);
|
||||
if (argCount == 0)
|
||||
argStartAddr = 0;
|
||||
else
|
||||
argStartAddr += (argCount * 2);
|
||||
|
||||
stackFrameString.add("args: ").add(String::getHexStr(argStartAddr, true, 2)).add(", argc: ").add(argCount).add("\n");
|
||||
|
||||
pushToStack(readRegister(data::Registers::R1));
|
||||
stackFrameString.add("R1: ").add(String::getHexStr(readRegister(data::Registers::R1), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R2));
|
||||
stackFrameString.add(" R2: ").add(String::getHexStr(readRegister(data::Registers::R2), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R3));
|
||||
stackFrameString.add(" R3: ").add(String::getHexStr(readRegister(data::Registers::R3), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R4));
|
||||
stackFrameString.add(" R4: ").add(String::getHexStr(readRegister(data::Registers::R4), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R5));
|
||||
stackFrameString.add(" R5: ").add(String::getHexStr(readRegister(data::Registers::R5), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R6));
|
||||
stackFrameString.add(" R6: ").add(String::getHexStr(readRegister(data::Registers::R6), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R7));
|
||||
stackFrameString.add(" R7: ").add(String::getHexStr(readRegister(data::Registers::R7), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R8));
|
||||
stackFrameString.add(" R8: ").add(String::getHexStr(readRegister(data::Registers::R8), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R9));
|
||||
stackFrameString.add(" R9: ").add(String::getHexStr(readRegister(data::Registers::R9), true, 2));
|
||||
pushToStack(readRegister(data::Registers::R10));
|
||||
stackFrameString.add(" R10: ").add(String::getHexStr(readRegister(data::Registers::R10), true, 2));
|
||||
stackFrameString.add("\n");
|
||||
pushToStack(readRegister(data::Registers::PP));
|
||||
stackFrameString.add("PP: ").add(String::getHexStr(readRegister(data::Registers::PP), true, 2));
|
||||
pushToStack(readRegister(data::Registers::ACC));
|
||||
stackFrameString.add(" ACC: ").add(String::getHexStr(readRegister(data::Registers::ACC), true, 2));
|
||||
pushToStack(readRegister(data::Registers::IP));
|
||||
stackFrameString.add(" IP: ").add(String::getHexStr(readRegister(data::Registers::IP), true, 2));
|
||||
pushToStack(readRegister(data::Registers::FP));
|
||||
stackFrameString.add(" FP: ").add(String::getHexStr(readRegister(data::Registers::FP), true, 2));
|
||||
stackFrameString.add("\n");
|
||||
pushToStack(m_stackFrameSize);
|
||||
stackFrameString.add("StackFrame: ").add(m_stackFrameSize).add(", ");
|
||||
|
||||
writeRegister16(data::Registers::PP, argStartAddr);
|
||||
writeRegister16(data::Registers::FP, readRegister(data::Registers::SP));
|
||||
stackFrameString.add("New FP: ").add(String::getHexStr(readRegister(data::Registers::FP), true, 2));
|
||||
m_stackFrameSize = 0;
|
||||
|
||||
m_debug_stackFrameStrings.push_back(stackFrameString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include <ostd/utils/Time.hpp>
|
||||
#include "IMemoryDevice.hpp"
|
||||
|
||||
#include "../debugger/Debugger.hpp"
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
|
|
@ -52,9 +51,6 @@ namespace dragon
|
|||
inline bool isOffsetAddressingModeEnabled(void) const { return m_isOffsetAddressingEnabled; }
|
||||
inline u16 getCurrentOffset(void) const { return m_currentOffset; }
|
||||
|
||||
private:
|
||||
void __debug_store_stack_frame_string_on_push(void);
|
||||
|
||||
private:
|
||||
i16 m_registers[20];
|
||||
ostd::BitField_16 m_tempFlags;
|
||||
|
|
@ -78,13 +74,9 @@ namespace dragon
|
|||
data::CPUExtension* m_currentExtension { nullptr };
|
||||
u8 m_currentExtInst { 0x00 };
|
||||
|
||||
std::vector<String> m_debug_stackFrameStrings;
|
||||
|
||||
ostd::Counter m_profilerTimer;
|
||||
|
||||
friend class dragon::DragonRuntime;
|
||||
friend class dragon::Debugger::Display;
|
||||
friend class dragon::Debugger;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#include "VirtualMMU.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
VirtualMMU& VirtualMMU::init(void)
|
||||
{
|
||||
m_data.init(VirtualMMU::MMUSize);
|
||||
m_data.enableAutoResize(false);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../tools/LegacyOstdSerial.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace hw
|
||||
{
|
||||
class VirtualMMU //TODO: Implement for later use
|
||||
{
|
||||
public:
|
||||
inline VirtualMMU(void) { init(); }
|
||||
VirtualMMU& init(void);
|
||||
|
||||
private:
|
||||
ostd::serial::SerialIO m_data;
|
||||
|
||||
public:
|
||||
inline static constexpr u16 MMUSize = 6144;
|
||||
inline static constexpr u16 PageSize = 512;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -17,51 +17,12 @@ namespace dragon
|
|||
{
|
||||
if (signal.ID == Signal_HardwareInterruptOccurred)
|
||||
{
|
||||
tCallInfo& interruptData = (tCallInfo&)signal.userData;
|
||||
DragonRuntime::s_machineInfo.callStack.push_back(interruptData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void DragonRuntime::printRegisters(dragon::hw::VirtualCPU& cpu)
|
||||
{
|
||||
out.fg("green").p("IP: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::IP), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R1: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R1), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R2: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R2), true, 2).cpp_str()).nl();
|
||||
|
||||
out.fg("green").p("SP: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::SP), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R3: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R3), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R4: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R4), true, 2).cpp_str()).nl();
|
||||
|
||||
out.fg("green").p("FP: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::FP), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R5: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R5), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R6: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R6), true, 2).cpp_str()).nl();
|
||||
|
||||
out.fg("green").p("RV: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::RV), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R7: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R7), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R8: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R8), true, 2).cpp_str()).nl();
|
||||
|
||||
out.fg("green").p("PP: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::PP), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R9: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R9), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("R10: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::R10), true, 2).cpp_str()).nl();
|
||||
|
||||
out.fg("green").p("ACC: ").fg("white").p(String::getHexStr(cpu.readRegister(dragon::data::Registers::ACC), true, 2).cpp_str());
|
||||
out.p(" ");
|
||||
out.fg("yellow").p("FL: ").fg("white").p(String::getBinStr(cpu.readRegister(dragon::data::Registers::FL), true, 2).cpp_str());
|
||||
}
|
||||
|
||||
void DragonRuntime::processErrors(void)
|
||||
{
|
||||
while (dragon::data::ErrorHandler::hasError())
|
||||
|
|
@ -330,12 +291,7 @@ namespace dragon
|
|||
if (info.verboseLoad)
|
||||
out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl();
|
||||
|
||||
|
||||
|
||||
|
||||
out.nl().nl();
|
||||
s_trackMachineInfo = info.trackMachineInfoDiff;
|
||||
s_trackCallStack = info.trackCallStack;
|
||||
return RETURN_VAL_EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -363,9 +319,7 @@ namespace dragon
|
|||
u16 addr = cpu.readRegister(dragon::data::Registers::IP);
|
||||
u16 spAddr = cpu.readRegister(dragon::data::Registers::SP);
|
||||
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
|
||||
// _timer.start(true, "Profiling", ostd::eTimeUnits::Microseconds, &out);
|
||||
running = cpu.execute() && vDisplay.isRunning();
|
||||
// _timer.end(true);
|
||||
vDisplay.mainLoop();
|
||||
vDiskInterface.cycleStep();
|
||||
if (dragon::data::ErrorHandler::hasError())
|
||||
|
|
@ -378,7 +332,6 @@ namespace dragon
|
|||
avg_count++;
|
||||
avg_tot += _time;
|
||||
s_avgInstTime = (u64)std::round(avg_tot / avg_count);
|
||||
// out.fg(ostd::ConsoleColors::Red).p(getAvgClockSpeed()).nl().reset();
|
||||
acc = 0;
|
||||
}
|
||||
if (acc2 == (1000.0 / screenRedrawRate))
|
||||
|
|
@ -394,11 +347,8 @@ namespace dragon
|
|||
}
|
||||
}
|
||||
|
||||
bool DragonRuntime::runStep(std::vector<u16> trackedAddresses)
|
||||
bool DragonRuntime::runStep(void)
|
||||
{
|
||||
std::sort(trackedAddresses.begin(), trackedAddresses.end());
|
||||
__get_machine_footprint(&s_machineInfo, trackedAddresses, true);
|
||||
__track_call_stack(&s_machineInfo);
|
||||
bool running = cpu.execute() && vDisplay.isRunning();
|
||||
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
|
||||
vDisplay.mainLoop();
|
||||
|
|
@ -414,7 +364,6 @@ namespace dragon
|
|||
s_stepAcc2++;
|
||||
// vDisplay.redrawScreen(); // This is slow...maybe it should be on a 100ms rate, like in normal runtime mode
|
||||
vDiskInterface.cycleStep();
|
||||
__get_machine_footprint(&s_machineInfo, trackedAddresses, false);
|
||||
return running || vDiskInterface.isBusy();
|
||||
}
|
||||
|
||||
|
|
@ -431,131 +380,6 @@ namespace dragon
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DragonRuntime::__get_machine_footprint(DragonRuntime::tMachineDebugInfo* machineInfo, std::vector<u16> trackedAddresses, bool previous)
|
||||
{
|
||||
if (!s_trackMachineInfo || machineInfo == nullptr) return;
|
||||
auto& minfo = *machineInfo;
|
||||
|
||||
if (previous)
|
||||
{
|
||||
minfo.vCPUHalt = cpu.m_halt;
|
||||
minfo.trackedAddresses.clear();
|
||||
minfo.previousInstructionTrackedValues.clear();
|
||||
minfo.currentInstructionTrackedValues.clear();
|
||||
|
||||
for (i32 i = 0; i < 20; i++)
|
||||
{
|
||||
if (i < 5)
|
||||
{
|
||||
minfo.previousInstructionFootprint[i] = 0;
|
||||
minfo.currentInstructionFootprint[i] = 0;
|
||||
}
|
||||
minfo.previousInstructionRegisters[i] = 0;
|
||||
minfo.currentInstructionRegisters[i] = 0;
|
||||
}
|
||||
|
||||
for (auto& addr : trackedAddresses)
|
||||
minfo.trackedAddresses.push_back(addr);
|
||||
}
|
||||
|
||||
u16 instAddr = cpu.readRegister(data::Registers::IP);
|
||||
u8 int_op_code = memMap.read8(instAddr);
|
||||
u8 instSize = data::OpCodes::getInstructionSIze(int_op_code);
|
||||
String opCode = data::OpCodes::getOpCodeString(int_op_code);
|
||||
u16 stackFrameSize = cpu.m_stackFrameSize;
|
||||
i32 subRoutineCounter = cpu.m_subroutineCounter;
|
||||
|
||||
bool debugBreak = cpu.m_isDebugBreakPoint;
|
||||
i32 intHandlerCount = cpu.m_interruptHandlerCount;
|
||||
bool biosMode = cpu.m_biosMode;
|
||||
bool isInSubRoutine = cpu.isInSubRoutine();
|
||||
|
||||
if (previous)
|
||||
{
|
||||
minfo.previousInstructionAddress = instAddr;
|
||||
minfo.previousInstructionFootprintSize = instSize;
|
||||
minfo.previousInstructionStackFrameSize = stackFrameSize;
|
||||
minfo.previousInstructionOpCode = opCode;
|
||||
minfo.previousSubRoutineCounter = subRoutineCounter;
|
||||
|
||||
for (i8 i = 0; i < instSize; i++)
|
||||
minfo.previousInstructionFootprint[i] = memMap.read8(instAddr + i);
|
||||
|
||||
for (i8 i = 0; i < 20; i++)
|
||||
minfo.previousInstructionRegisters[i] = cpu.readRegister(i);
|
||||
|
||||
for (auto& addr : minfo.trackedAddresses)
|
||||
minfo.previousInstructionTrackedValues.push_back(memMap.read8(addr));
|
||||
|
||||
minfo.previousInstructionDebugBreak = debugBreak;
|
||||
minfo.previousInstructionInterruptHandlerCount = intHandlerCount;
|
||||
minfo.previousInstructionBiosMode = biosMode;
|
||||
minfo.previousIsInSubRoutine = isInSubRoutine;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (int_op_code >= data::OpCodes::Ext01 && int_op_code <= data::OpCodes::Ext16)
|
||||
// minfo.currentInstructionAddress = minfo.previousInstructionAddress;
|
||||
//else
|
||||
minfo.currentInstructionAddress = instAddr;
|
||||
minfo.currentInstructionFootprintSize = instSize;
|
||||
minfo.currentInstructionStackFrameSize = stackFrameSize;
|
||||
minfo.currentInstructionOpCode = opCode;
|
||||
minfo.currentSubRoutineCounter = subRoutineCounter;
|
||||
|
||||
for (i8 i = 0; i < instSize; i++)
|
||||
minfo.currentInstructionFootprint[i] = memMap.read8(minfo.currentInstructionAddress + i);
|
||||
|
||||
for (i8 i = 0; i < 20; i++)
|
||||
minfo.currentInstructionRegisters[i] = cpu.readRegister(i);
|
||||
|
||||
for (auto& addr : minfo.trackedAddresses)
|
||||
minfo.currentInstructionTrackedValues.push_back(memMap.read8(addr));
|
||||
|
||||
minfo.currentInstructionDebugBreak = debugBreak;
|
||||
minfo.currentInstructionInterruptHandlerCount = intHandlerCount;
|
||||
minfo.currentInstructionBiosMode = biosMode;
|
||||
minfo.currentIsInSubRoutine = isInSubRoutine;
|
||||
}
|
||||
}
|
||||
|
||||
void DragonRuntime::__track_call_stack(tMachineDebugInfo* machineInfo)
|
||||
{
|
||||
if (!s_trackCallStack || machineInfo == nullptr) return;
|
||||
auto& minfo = *machineInfo;
|
||||
|
||||
bool interrupts_enabled = cpu.readFlag(data::Flags::InterruptsEnabled);
|
||||
|
||||
u16 instAddr = cpu.readRegister(data::Registers::IP);
|
||||
u8 inst = memMap.read8(instAddr);
|
||||
|
||||
if (inst == data::OpCodes::CallImm)
|
||||
{
|
||||
u16 call_addr = memMap.read16(instAddr + 1);
|
||||
minfo.callStack.push_back({ "CALL IMM", call_addr, instAddr, !interrupts_enabled });
|
||||
}
|
||||
else if (inst == data::OpCodes::CallReg)
|
||||
{
|
||||
u8 reg_addr = memMap.read8(instAddr + 1);
|
||||
u16 call_addr = cpu.readRegister(reg_addr);
|
||||
minfo.callStack.push_back({ "CALL REG", call_addr, instAddr, !interrupts_enabled });
|
||||
}
|
||||
else if (interrupts_enabled && inst == data::OpCodes::Int)
|
||||
{
|
||||
u8 int_num = memMap.read8(instAddr + 1);
|
||||
minfo.callStack.push_back({ "INT", int_num, instAddr, !interrupts_enabled });
|
||||
}
|
||||
else if (inst == data::OpCodes::Ret)
|
||||
{
|
||||
minfo.callStack.push_back({ "RET", 0x0000, instAddr, !interrupts_enabled });
|
||||
}
|
||||
else if (interrupts_enabled && inst == data::OpCodes::RetInt)
|
||||
{
|
||||
minfo.callStack.push_back({ "RET INT", 0x0000, instAddr, !interrupts_enabled });
|
||||
}
|
||||
}
|
||||
|
||||
void DragonRuntime::__print_application_help(void)
|
||||
{
|
||||
i32 commandLength = 46;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,6 @@ namespace dragon
|
|||
public:
|
||||
inline static const i32 Signal_HardwareInterruptOccurred = ostd::SignalHandler::newCustomSignal(8129);
|
||||
};
|
||||
public: struct tCallInfo : public ostd::BaseObject
|
||||
{
|
||||
inline tCallInfo(void) { }
|
||||
inline tCallInfo(const String& _info, u16 _addr, u16 _inst_addr, bool ints_disabled) : info(_info), addr(_addr), inst_addr(_inst_addr), interrupts_disabled(ints_disabled) { }
|
||||
String info;
|
||||
u16 addr;
|
||||
u16 inst_addr;
|
||||
bool interrupts_disabled;
|
||||
};
|
||||
public: struct tCommandLineArgs
|
||||
{
|
||||
String machine_config_path = "";
|
||||
|
|
@ -46,69 +37,24 @@ namespace dragon
|
|||
{
|
||||
String configFilePath;
|
||||
bool verboseLoad { false };
|
||||
bool trackMachineInfoDiff { false };
|
||||
bool hideVirtualDisplay { false };
|
||||
bool trackCallStack { false };
|
||||
bool debugModeEnabled { false };
|
||||
};
|
||||
public: struct tMachineDebugInfo
|
||||
{
|
||||
inline tMachineDebugInfo(void) { }
|
||||
|
||||
u16 previousInstructionAddress { 0x0000 };
|
||||
u16 currentInstructionAddress { 0x0000 };
|
||||
i8 previousInstructionFootprintSize { 0x00 };
|
||||
i8 currentInstructionFootprintSize { 0x00 };
|
||||
u16 previousInstructionStackFrameSize { 0x00 };
|
||||
u16 currentInstructionStackFrameSize { 0x00 };
|
||||
i32 previousSubRoutineCounter { 0x00000000 };
|
||||
i32 currentSubRoutineCounter { 0x00000000 };
|
||||
|
||||
String previousInstructionOpCode { "" };
|
||||
String currentInstructionOpCode { "" };
|
||||
|
||||
i8 previousInstructionFootprint[5] { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
i8 currentInstructionFootprint[5] { 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
i16 previousInstructionRegisters[20] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
i16 currentInstructionRegisters[20] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
i32 previousInstructionInterruptHandlerCount { 0 };
|
||||
i32 currentInstructionInterruptHandlerCount { 0 };
|
||||
|
||||
std::vector<u16> trackedAddresses;
|
||||
std::vector<i8> previousInstructionTrackedValues;
|
||||
std::vector<i8> currentInstructionTrackedValues;
|
||||
|
||||
bool previousInstructionDebugBreak { false };
|
||||
bool currentInstructionDebugBreak { false };
|
||||
bool previousInstructionBiosMode { false };
|
||||
bool currentInstructionBiosMode { false };
|
||||
bool previousIsInSubRoutine { false };
|
||||
bool currentIsInSubRoutine { false };
|
||||
|
||||
bool vCPUHalt { false };
|
||||
|
||||
|
||||
std::vector<tCallInfo> callStack;
|
||||
};
|
||||
public:
|
||||
static void printRegisters(hw::VirtualCPU& cpu);
|
||||
static void processErrors(void);
|
||||
static std::vector<data::ErrorHandler::tError> getErrorList(void);
|
||||
static i32 loadArguments(int argc, char** argv, tCommandLineArgs& args);
|
||||
static i32 initMachine(const tRuntimeInitInfo& info);
|
||||
static void shutdownMachine(void);
|
||||
static void runMachine(void);
|
||||
static bool runStep(std::vector<u16> trackedAddresses = { });
|
||||
static bool runStep(void);
|
||||
static void forceLoad(const String& filePath, u16 loadAddress);
|
||||
|
||||
inline static const tMachineDebugInfo& getMachineInfoDiff(void) { return s_machineInfo; }
|
||||
inline static bool hasError(void) { return data::ErrorHandler::hasError(); }
|
||||
inline static ostd::ConsoleOutputHandler& output(void) { return out; }
|
||||
inline static u64 getAvgClockSpeed(void) { return (u64)std::round(1000000.0 / s_avgInstTime); }
|
||||
|
||||
private:
|
||||
static void __get_machine_footprint(tMachineDebugInfo* machineInfo, std::vector<u16> trackedAddresses, bool previous);
|
||||
static void __track_call_stack(tMachineDebugInfo* machineInfo);
|
||||
static void __print_application_help(void);
|
||||
|
||||
public:
|
||||
|
|
@ -138,12 +84,8 @@ namespace dragon
|
|||
inline static bool s_enableScreenRedrawDelay { true };
|
||||
|
||||
private:
|
||||
inline static tMachineDebugInfo s_machineInfo;
|
||||
inline static bool s_trackMachineInfo { false };
|
||||
inline static bool s_trackCallStack { false };
|
||||
inline static SignalListener s_signalListener;
|
||||
|
||||
|
||||
public:
|
||||
inline static const i32 RETURN_VAL_CLOSE_DEBUGGER = 128;
|
||||
inline static const i32 RETURN_VAL_CLOSE_RUNTIME = 256;
|
||||
|
|
|
|||
Loading…
Reference in a new issue