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/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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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 <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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue