Stripped old debugger code

This commit is contained in:
OmniaX-Dev 2026-06-15 08:18:44 +02:00
parent 59d9d8f910
commit de279f4721
11 changed files with 40 additions and 2269 deletions

View file

@ -40,7 +40,6 @@ list(APPEND RUNTIME_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.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/Utils.cpp
${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp ${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp
@ -49,7 +48,6 @@ list(APPEND RUNTIME_SOURCE_FILES
list(APPEND DEBUGGER_SOURCE_FILES list(APPEND DEBUGGER_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/debugger/debugger_main.cpp ${CMAKE_CURRENT_LIST_DIR}/src/debugger/debugger_main.cpp
${CMAKE_CURRENT_LIST_DIR}/src/debugger/DisassemblyLoader.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/VirtualCPU.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.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/VirtualHardDrive.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.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/DragonRuntime.cpp
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp ${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp

View file

@ -775,7 +775,7 @@ namespace dragon
void Assembler::saveCurrentStageToFile(void) 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); ostd::FileSystem::writeTextFile(Application::args.final_stage_path, m_lines);
} }

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,54 +1,29 @@
#include <ostd/utils/Defines.hpp> #include <ostd/utils/Defines.hpp>
#include "Debugger.hpp" // #include "../runtime/DragonRuntime.hpp"
#include "../runtime/DragonRuntime.hpp"
// #include "DebuggerNew.hpp"
#include <ostd/utils/Signals.hpp> #include <ostd/utils/Signals.hpp>
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
//Loading commandline arguments //Loading commandline arguments
i32 rValue = dragon::Debugger::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 = 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);
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER) // if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
// return 0; // return 0;
// if (rValue != 0) return rValue; // if (rValue != 0) return rValue;
// //Initializing the runtime // //Initializing the runtime
// rValue = debuggerInstance.initRuntime(); // rValue = dragon::Debugger::initRuntime();
// if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER) // if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
// return 0; // return 0;
// if (rValue != 0) return rValue; // if (rValue != 0) return rValue;
// while (debuggerInstance.isRunning()) // //Running top-level prompt
// { // rValue = dragon::Debugger::topLevelPrompt();
// debuggerInstance.update(); // if (rValue == dragon::DragonRuntime::RETURN_VAL_CLOSE_DEBUGGER)
// } // return 0;
// if (rValue != 0) return rValue;
// //Executing the runtime
// return dragon::Debugger::executeRuntime();
return 0; return 0;
} }

View file

@ -82,11 +82,6 @@ namespace dragon
void VirtualCPU::pushStackFrame(void) void VirtualCPU::pushStackFrame(void)
{ {
if (m_debugModeEnabled)
{
__debug_store_stack_frame_string_on_push();
return;
}
u16 argStartAddr = readRegister(data::Registers::SP) + 2; u16 argStartAddr = readRegister(data::Registers::SP) + 2;
u16 argCount = m_memory.read16(argStartAddr); u16 argCount = m_memory.read16(argStartAddr);
if (argCount == 0) if (argCount == 0)
@ -120,7 +115,6 @@ namespace dragon
u16 framePointerAddr = readRegister(data::Registers::FP); u16 framePointerAddr = readRegister(data::Registers::FP);
writeRegister16(data::Registers::SP, framePointerAddr); writeRegister16(data::Registers::SP, framePointerAddr);
m_stackFrameSize = popFromStack(); m_stackFrameSize = popFromStack();
// u16 tmpStackFrameSize = m_stackFrameSize;
writeRegister16(data::Registers::FP, popFromStack()); writeRegister16(data::Registers::FP, popFromStack());
writeRegister16(data::Registers::IP, popFromStack()); writeRegister16(data::Registers::IP, popFromStack());
@ -139,12 +133,7 @@ namespace dragon
u16 nArgs = popFromStack(); u16 nArgs = popFromStack();
for (i32 i = 0; i < nArgs; i++) for (i32 i = 0; i < nArgs; i++)
{
popFromStack(); popFromStack();
// writeRegister(data::Registers::FP, readRegister(data::Registers::FP) - 2);
}
// writeRegister(data::Registers::FP, framePointerAddr + tmpStackFrameSize);
} }
bool VirtualCPU::readFlag(u8 flg) bool VirtualCPU::readFlag(u8 flg)
@ -173,15 +162,15 @@ namespace dragon
m_subroutineCounter++; m_subroutineCounter++;
m_interruptHandlerCount++; m_interruptHandlerCount++;
writeRegister16(data::Registers::IP, handlerAddress); writeRegister16(data::Registers::IP, handlerAddress);
if (m_debugModeEnabled && hardware) // if (m_debugModeEnabled && hardware)
{ // {
DragonRuntime::tCallInfo interruptData; // DragonRuntime::tCallInfo interruptData;
interruptData.info = "HW INT"; // interruptData.info = "HW INT";
interruptData.addr = intValue; // interruptData.addr = intValue;
interruptData.inst_addr = 0x0000; // interruptData.inst_addr = 0x0000;
interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled); // interruptData.interrupts_disabled = !readFlag(data::Flags::InterruptsEnabled);
ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::Signal::Priority::RealTime, interruptData); // ostd::SignalHandler::emitSignal(DragonRuntime::SignalListener::Signal_HardwareInterruptOccurred, ostd::Signal::Priority::RealTime, interruptData);
} // }
} }
bool VirtualCPU::loadExtension(void) bool VirtualCPU::loadExtension(void)
@ -222,33 +211,26 @@ namespace dragon
{ {
case data::OpCodes::NoOp: case data::OpCodes::NoOp:
{ {
//
} }
break; break;
case data::OpCodes::DEBUG_Break: case data::OpCodes::DEBUG_Break:
{ {
if (!m_debugModeEnabled) break;
m_isDebugBreakPoint = true; m_isDebugBreakPoint = true;
} }
break; break;
case data::OpCodes::DEBUG_DumpRAM: case data::OpCodes::DEBUG_DumpRAM:
{ {
if (!m_debugModeEnabled) break;
ostd::Memory::saveByteStreamToFile(*DragonRuntime::ram.getByteStream(), "ram_dump.bin"); ostd::Memory::saveByteStreamToFile(*DragonRuntime::ram.getByteStream(), "ram_dump.bin");
m_isDebugBreakPoint = true; m_isDebugBreakPoint = true;
m_ramDumped = true; m_ramDumped = true;
} }
break; 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: case data::OpCodes::DEBUG_StartProfile:
{ {
if (!m_debugModeEnabled) break;
i8 id = fetch8(); i8 id = fetch8();
i8 timeUnit = fetch8(); i8 timeUnit = fetch8();
ostd::eTimeUnits tu = ostd::eTimeUnits::Milliseconds; ostd::eTimeUnits tu = ostd::eTimeUnits::Milliseconds;
@ -264,11 +246,22 @@ namespace dragon
break; break;
case data::OpCodes::DEBUG_StopProfile: case data::OpCodes::DEBUG_StopProfile:
{ {
if (!m_debugModeEnabled) break;
if (m_debugProfilerStarted) if (m_debugProfilerStarted)
m_profilerTimer.end(true); m_profilerTimer.end(true);
m_debugProfilerStarted = false; m_debugProfilerStarted = false;
} }
break; 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: case data::OpCodes::MovImmReg:
{ {
u8 regAddr = fetch8(); u8 regAddr = fetch8();
@ -325,16 +318,6 @@ namespace dragon
m_memory.write16(destAddr, value); m_memory.write16(destAddr, value);
} }
break; 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: case data::OpCodes::MovRegDerefReg:
{ {
u8 destRegAddr = fetch8(); u8 destRegAddr = fetch8();
@ -821,7 +804,6 @@ namespace dragon
case data::OpCodes::Ret: case data::OpCodes::Ret:
{ {
popStackFrame(); popStackFrame();
// m_subroutineCounter = ZERO(m_subroutineCounter - 1);
m_subroutineCounter--; m_subroutineCounter--;
} }
break; break;
@ -839,7 +821,6 @@ namespace dragon
{ {
m_interruptHandlerCount--; m_interruptHandlerCount--;
popStackFrame(); popStackFrame();
// m_subroutineCounter = ZERO(m_subroutineCounter - 1);
m_subroutineCounter--; m_subroutineCounter--;
} }
break; break;
@ -903,60 +884,5 @@ namespace dragon
return true; 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);
}
} }
} }

View file

@ -5,7 +5,6 @@
#include <ostd/utils/Time.hpp> #include <ostd/utils/Time.hpp>
#include "IMemoryDevice.hpp" #include "IMemoryDevice.hpp"
#include "../debugger/Debugger.hpp"
#include "../tools/GlobalData.hpp" #include "../tools/GlobalData.hpp"
namespace dragon namespace dragon
@ -52,9 +51,6 @@ namespace dragon
inline bool isOffsetAddressingModeEnabled(void) const { return m_isOffsetAddressingEnabled; } inline bool isOffsetAddressingModeEnabled(void) const { return m_isOffsetAddressingEnabled; }
inline u16 getCurrentOffset(void) const { return m_currentOffset; } inline u16 getCurrentOffset(void) const { return m_currentOffset; }
private:
void __debug_store_stack_frame_string_on_push(void);
private: private:
i16 m_registers[20]; i16 m_registers[20];
ostd::BitField_16 m_tempFlags; ostd::BitField_16 m_tempFlags;
@ -78,13 +74,9 @@ namespace dragon
data::CPUExtension* m_currentExtension { nullptr }; data::CPUExtension* m_currentExtension { nullptr };
u8 m_currentExtInst { 0x00 }; u8 m_currentExtInst { 0x00 };
std::vector<String> m_debug_stackFrameStrings;
ostd::Counter m_profilerTimer; ostd::Counter m_profilerTimer;
friend class dragon::DragonRuntime; friend class dragon::DragonRuntime;
friend class dragon::Debugger::Display;
friend class dragon::Debugger;
}; };
} }
} }

View file

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

View file

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

View file

@ -17,51 +17,12 @@ namespace dragon
{ {
if (signal.ID == Signal_HardwareInterruptOccurred) 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) void DragonRuntime::processErrors(void)
{ {
while (dragon::data::ErrorHandler::hasError()) while (dragon::data::ErrorHandler::hasError())
@ -330,12 +291,7 @@ namespace dragon
if (info.verboseLoad) if (info.verboseLoad)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl(); out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl();
out.nl().nl(); out.nl().nl();
s_trackMachineInfo = info.trackMachineInfoDiff;
s_trackCallStack = info.trackCallStack;
return RETURN_VAL_EXIT_SUCCESS; return RETURN_VAL_EXIT_SUCCESS;
} }
@ -363,9 +319,7 @@ namespace dragon
u16 addr = cpu.readRegister(dragon::data::Registers::IP); u16 addr = cpu.readRegister(dragon::data::Registers::IP);
u16 spAddr = cpu.readRegister(dragon::data::Registers::SP); u16 spAddr = cpu.readRegister(dragon::data::Registers::SP);
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate); u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
// _timer.start(true, "Profiling", ostd::eTimeUnits::Microseconds, &out);
running = cpu.execute() && vDisplay.isRunning(); running = cpu.execute() && vDisplay.isRunning();
// _timer.end(true);
vDisplay.mainLoop(); vDisplay.mainLoop();
vDiskInterface.cycleStep(); vDiskInterface.cycleStep();
if (dragon::data::ErrorHandler::hasError()) if (dragon::data::ErrorHandler::hasError())
@ -378,7 +332,6 @@ namespace dragon
avg_count++; avg_count++;
avg_tot += _time; avg_tot += _time;
s_avgInstTime = (u64)std::round(avg_tot / avg_count); s_avgInstTime = (u64)std::round(avg_tot / avg_count);
// out.fg(ostd::ConsoleColors::Red).p(getAvgClockSpeed()).nl().reset();
acc = 0; acc = 0;
} }
if (acc2 == (1000.0 / screenRedrawRate)) 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(); bool running = cpu.execute() && vDisplay.isRunning();
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate); u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
vDisplay.mainLoop(); vDisplay.mainLoop();
@ -414,7 +364,6 @@ namespace dragon
s_stepAcc2++; s_stepAcc2++;
// vDisplay.redrawScreen(); // This is slow...maybe it should be on a 100ms rate, like in normal runtime mode // vDisplay.redrawScreen(); // This is slow...maybe it should be on a 100ms rate, like in normal runtime mode
vDiskInterface.cycleStep(); vDiskInterface.cycleStep();
__get_machine_footprint(&s_machineInfo, trackedAddresses, false);
return running || vDiskInterface.isBusy(); 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) void DragonRuntime::__print_application_help(void)
{ {
i32 commandLength = 46; i32 commandLength = 46;

View file

@ -25,15 +25,6 @@ namespace dragon
public: public:
inline static const i32 Signal_HardwareInterruptOccurred = ostd::SignalHandler::newCustomSignal(8129); 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 public: struct tCommandLineArgs
{ {
String machine_config_path = ""; String machine_config_path = "";
@ -46,69 +37,24 @@ namespace dragon
{ {
String configFilePath; String configFilePath;
bool verboseLoad { false }; bool verboseLoad { false };
bool trackMachineInfoDiff { false };
bool hideVirtualDisplay { false }; bool hideVirtualDisplay { false };
bool trackCallStack { false };
bool debugModeEnabled { 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: public:
static void printRegisters(hw::VirtualCPU& cpu);
static void processErrors(void); static void processErrors(void);
static std::vector<data::ErrorHandler::tError> getErrorList(void); static std::vector<data::ErrorHandler::tError> getErrorList(void);
static i32 loadArguments(int argc, char** argv, tCommandLineArgs& args); static i32 loadArguments(int argc, char** argv, tCommandLineArgs& args);
static i32 initMachine(const tRuntimeInitInfo& info); static i32 initMachine(const tRuntimeInitInfo& info);
static void shutdownMachine(void); static void shutdownMachine(void);
static void runMachine(void); static void runMachine(void);
static bool runStep(std::vector<u16> trackedAddresses = { }); static bool runStep(void);
static void forceLoad(const String& filePath, u16 loadAddress); 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 bool hasError(void) { return data::ErrorHandler::hasError(); }
inline static ostd::ConsoleOutputHandler& output(void) { return out; } inline static ostd::ConsoleOutputHandler& output(void) { return out; }
inline static u64 getAvgClockSpeed(void) { return (u64)std::round(1000000.0 / s_avgInstTime); } inline static u64 getAvgClockSpeed(void) { return (u64)std::round(1000000.0 / s_avgInstTime); }
private: 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); static void __print_application_help(void);
public: public:
@ -138,12 +84,8 @@ namespace dragon
inline static bool s_enableScreenRedrawDelay { true }; inline static bool s_enableScreenRedrawDelay { true };
private: private:
inline static tMachineDebugInfo s_machineInfo;
inline static bool s_trackMachineInfo { false };
inline static bool s_trackCallStack { false };
inline static SignalListener s_signalListener; inline static SignalListener s_signalListener;
public: public:
inline static const i32 RETURN_VAL_CLOSE_DEBUGGER = 128; inline static const i32 RETURN_VAL_CLOSE_DEBUGGER = 128;
inline static const i32 RETURN_VAL_CLOSE_RUNTIME = 256; inline static const i32 RETURN_VAL_CLOSE_RUNTIME = 256;