diff --git a/.vscode/settings.json b/.vscode/settings.json index 18b5f5e..f8c4440 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -139,5 +139,22 @@ ], "editor.insertSpaces": false, - "workbench.list.openMode": "doubleClick" + "workbench.list.openMode": "doubleClick", + "files.autoSave": "afterDelay", + "files.autoSaveDelay": 200, + "workbench.activityBar.location": "hidden", + "workbench.editor.openPositioning": "last", + "workbench.editor.tabActionCloseVisibility": false, + "window.density.editorTabHeight": "compact", + "window.zoomLevel": 1, + "explorer.autoReveal": false, + "editor.stickyScroll.enabled": false, + "workbench.statusBar.visible": false, + "breadcrumbs.enabled": false, + "workbench.tree.enableStickyScroll": false, + + "cmake.configureOnOpen": false, + "cmake.options.statusBarVisibility": "hidden", + + "git.openRepositoryInParentFolders": "never" } diff --git a/CMakeLists.txt b/CMakeLists.txt index ed6b729..7f92fd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND RUNTIME_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp ${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp ) list(APPEND DEBUGGER_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/debugger/debugger_main.cpp @@ -66,6 +67,7 @@ list(APPEND DEBUGGER_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/assembler/Assembler.cpp ${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp ) list(APPEND ASSEMBLER_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/assembler/assembler_main.cpp @@ -105,7 +107,10 @@ set(TOOLS_TARGET dtools) add_executable(${TOOLS_TARGET} ${TOOLS_SOURCE_FILES}) target_include_directories(${TOOLS_TARGET} PUBLIC ${INCLUDE_DIRS}) -target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER} - Alpha") +target_compile_definitions(${RUNTIME_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +target_compile_definitions(${DEBUGGER_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +target_compile_definitions(${ASSEMBLER_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +target_compile_definitions(${TOOLS_TARGET} PUBLIC BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") #TODO: Different flags for Release/Debug add_compile_options(-O3 -m32 -MMD -MP -Wall -ggdb) diff --git a/build.nr b/build.nr index b1e142d..aa6f5d2 100644 --- a/build.nr +++ b/build.nr @@ -1 +1 @@ -1584 +1587 diff --git a/create_win_release.sh b/create_win_release.sh index df3d63b..cd3aeae 100644 --- a/create_win_release.sh +++ b/create_win_release.sh @@ -7,7 +7,7 @@ rm -r ./win-release cd bin printf "${green}Compiling vBIOS...\n${clear}" -./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose +./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose --save-exports printf "\n${green}Creating Virtual Disk...\n${clear}" rm dragon/disk1.dr @@ -44,7 +44,7 @@ cp -r ./bin/dragon ./win-release rm ./bin/disassembly/test1.dds rm ./bin/disassembly/test2.dds -mkdir ./win-release/dss +mkdir ./win-release/dss4 mkdir ./win-release/dss/bios cp ./bin/dss/bios/* ./win-release/dss/bios cp ./bin/dss/mbr.dss ./win-release/dss diff --git a/extra/dss/bios/data.dss b/extra/dss/bios/data.dss index cf8d684..9e052e7 100644 --- a/extra/dss/bios/data.dss +++ b/extra/dss/bios/data.dss @@ -1,5 +1,7 @@ @guard _DATA_DSS_ +@export BIOS_API bios_api.dss + ## ============================= Memory Mapped Devices and Registers ============================= @group MemoryAddresses MBR 0x1380 @@ -14,19 +16,41 @@ BOOT_DISK { MemoryAddresses.CMOS + 0x0010 } @end -@group VGA_Registers + + +@export_comment /BIOS_API "These are the Hardware Interrupt codes of this machine." +@group /BIOS_API HW_Int + DISK_INTERFACE_FINISHED 0x80 + KEY_PRESSED 0xA0 + KEY_RELEASED 0xA1 + TEXT_ENTERED 0xA2 +@end +@export_comment /BIOS_API "\n" + + + +@export_comment /BIOS_API "These are the memory-mapped registers used to interact with the video card's interface." +@group /BIOS_API VGA_Registers VIDEO_MODE { MemoryAddresses.VGA + 0x0000 } SIGNAL { MemoryAddresses.VGA + 0x0003 } TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 } BUFF_START { MemoryAddresses.VGA + 0x00E0 } @end +@export_comment /BIOS_API "\n" -@group VGA_VideoModes + + +@export_comment /BIOS_API "These are the different Video Modes that the video card supports." +@group /BIOS_API VGA_VideoModes TEXT_SINGLE_COLOR 0x00 @end +@export_comment /BIOS_API "\n" -@group Sig_VGA_Text_Single_Color + + +@export_comment /BIOS_API "These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode." +@group /BIOS_API Sig_VGA_Text_Single_Color CONTINUE 0x00 PRINT_CHAR 0x02 STORE_CHAR 0x03 @@ -37,6 +61,9 @@ REFRESH_SCREEN 0xE0 CLEAR_SCREEN 0xE1 @end +@export_comment /BIOS_API "\n" + + @define S_REG_1 0x07 @define S_REG_2 0x08 diff --git a/extra/scripts/bios_flash b/extra/scripts/bios_flash index e673e16..ceb6cc2 100644 --- a/extra/scripts/bios_flash +++ b/extra/scripts/bios_flash @@ -6,5 +6,5 @@ clear='\033[0m' printf "${green}Reloading BIOS...\n${clear}" cd .. cp ../extra/dss/bios/* ./dss/bios/ -./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose +./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose --save-exports cp dragon/bios.bin ../extra/dragon/bios.bin diff --git a/src/assembler/Assembler.cpp b/src/assembler/Assembler.cpp index 2799aa9..5211f1f 100644 --- a/src/assembler/Assembler.cpp +++ b/src/assembler/Assembler.cpp @@ -149,6 +149,8 @@ namespace dragon } else if (edit == "--verbose") args.verbose = true; + else if (edit == "--save-exports") + args.save_exports = true; } } return RETURN_VAL_EXIT_SUCCESS; @@ -168,6 +170,9 @@ namespace dragon tmpCommand = "-o "; tmpCommand.addRightPadding(commandLength); out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to specify the output binary file.").reset().nl(); + tmpCommand = "--save-exports"; + tmpCommand.addRightPadding(commandLength); + out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Used to save any specified exports in the code.").reset().nl(); tmpCommand = "--help"; tmpCommand.addRightPadding(commandLength); out.fg(ostd::ConsoleColors::Blue).p(tmpCommand).fg(ostd::ConsoleColors::Green).p("Displays this help message.").reset().nl(); @@ -199,6 +204,7 @@ namespace dragon if (m_lines.size() == 0) return { }; //TODO: Error removeComments(); + parseExportSpecs(); replaceGroupDefines(); replaceDefines(); parseStructures(); @@ -209,6 +215,7 @@ namespace dragon parseCodeSection(); replaceLabelRefs(); combineDataAndCode(); + processExports(); m_programSize = m_code.size(); if (m_fixedSize > 0 && m_code.size() > m_fixedSize) std::cout << "Warning: Fixed size specified but exceeded: (" << (int)m_code.size() << "/" << (int)m_fixedSize << " bytes)\n"; @@ -285,12 +292,101 @@ namespace dragon m_lines = newLines; } + void Assembler::parseExportSpecs(void) + { + auto exportAlreadyExists = [](const std::unordered_map& exports, const ostd::String& name) -> bool { + return exports.count(name) > 0; + }; + std::vector newLines; + ostd::String lineEdit = ""; + ostd::String tmpLineEdit = ""; + for (auto& line : m_lines) + { + lineEdit = line; + lineEdit.trim(); + tmpLineEdit = lineEdit; + if (tmpLineEdit.toLower().startsWith("@export ")) + { + lineEdit = lineEdit.substr(8); + lineEdit.trim(); + if (!lineEdit.contains(" ")) + { + std::cout << "Invalid @export directive: " << line << "\n"; + return; + } + ostd::String export_name = lineEdit.new_substr(0, lineEdit.indexOf(" ")).trim(); + ostd::String export_file = lineEdit.new_substr(lineEdit.indexOf(" ") + 1).trim(); + if (export_name == "" || export_file == "") + { + std::cout << "Invalid @export directive (null value(s)): " << line << "\n"; + return; + } + if (exportAlreadyExists(m_exportSpecifications, export_name)) + { + std::cout << "An export specification with this name already exists: " << line << "\n"; + return; + } + m_exportSpecifications[export_name] = { export_file, {} }; + continue; + } + newLines.push_back(lineEdit); + } + m_lines.clear(); + m_lines = newLines; + } + + void Assembler::processExports(void) + { + for (auto& exp : m_exportSpecifications) + { + for (auto& def : exp.second.content) + { + if (def.name.startsWith("##")) + { + def.value.replaceAll("\\n", "\n"); + continue; + } + if (def.value.startsWith("{") && def.value.endsWith("}")) + { + def.value.substr(1, def.value.len() - 1).trim(); + int16_t val = (int16_t)ostd::Utils::solveIntegerExpression(def.value); + def.value = ostd::Utils::getHexStr(val, true, 2); + } + } + } + if (!saveExports) return; + for (auto& exp : m_exportSpecifications) + { + ostd::String fileContent = "## -- \n## -- This file is automatically generated by the DragonAssembler (version "; + fileContent.add(VERSION_STR).add(")\n"); + fileContent.add("## -- Please do not modify this file in any way."); + fileContent.add("\n## -- \n\n"); + fileContent.add("@guard __AUTO_GEN_GUARD_").add(exp.first.new_toUpper()).add("_DSS__\n\n"); + std::filesystem::path filePath(exp.second.fileName.cpp_str()); + uint32_t define_fixed_length = 96; + for (auto& def : exp.second.content) + { + if (def.name.startsWith("##")) + { + fileContent.add(def.name).add(def.value).add("\n"); + continue; + } + fileContent.add("@define "); + fileContent.add(def.name.new_addRightPadding(define_fixed_length)).add(" ").add(def.value).add("\n"); + } + std::ofstream outFile(filePath, std::ofstream::out | std::ofstream::trunc); + if (!std::filesystem::exists(filePath)) + { + std::cout << "Invalid export specification file: " << filePath << "\n"; + continue; + } + outFile << fileContent.cpp_str(); + outFile.close(); + } + } + void Assembler::replaceDefines(void) { - struct tDefine { - ostd::String name; - ostd::String value; - }; auto listContainsDefine = [](const std::vector& list, const ostd::String& name) -> bool { for (auto& def : list) { @@ -299,6 +395,9 @@ namespace dragon } return false; }; + auto exportExists = [](const std::unordered_map& exports, const ostd::String& name) -> bool { + return exports.count(name) > 0; + }; std::vector defines; std::vector newLines; ostd::String lineEdit; @@ -308,24 +407,66 @@ namespace dragon lineEdit = line; lineEdit.trim(); tmpLineEdit = lineEdit; - if (tmpLineEdit.toLower().startsWith("@define ")) + ostd::String export_name = ""; + if (tmpLineEdit.toLower().startsWith("@export_comment ")) { - lineEdit = lineEdit.substr(8); - lineEdit.trim(); + lineEdit.substr(16).trim(); + if (!lineEdit.startsWith("/") || !lineEdit.contains(" ")) + { + std::cout << "Invalid @export_comment directive: export specification not found: " << line << "\n"; + return; + } + export_name = lineEdit.new_substr(1, lineEdit.indexOf(" ")).trim(); + lineEdit.substr(lineEdit.indexOf(" ") + 1).trim(); + if (!lineEdit.startsWith("\"") || !lineEdit.endsWith("\"")) + { + std::cout << "Invalid @export_comment directive: comment not found: " << line << "\n"; + return; + } + lineEdit.substr(1, lineEdit.len() - 1); + if (!exportExists(m_exportSpecifications, export_name)) + { + std::cout << "Invalid export specification: " << line << "\n"; + return; + } + m_exportSpecifications[export_name].content.push_back({ "## -- ", lineEdit }); + continue; + } + else if (tmpLineEdit.toLower().startsWith("@define ")) + { + lineEdit.substr(8).trim(); + if (lineEdit.startsWith("/")) + { + if (!lineEdit.contains(" ")) + { + std::cout << "Invalid export definition for group: " << line << "\n"; + return; + } + export_name = lineEdit.new_substr(1, lineEdit.indexOf(" ")).trim(); + lineEdit.substr(lineEdit.indexOf(" ") + 1).trim(); + } if (!lineEdit.contains(" ")) { std::cout << "Invalid @define directive: " << line << "\n"; return; } - ostd::String define_name = lineEdit.new_substr(0, lineEdit.indexOf(" ")); - define_name = ostd::String(define_name).trim(); - ostd::String define_value = lineEdit.new_substr(lineEdit.indexOf(" ") + 1); + ostd::String define_name = lineEdit.new_substr(0, lineEdit.indexOf(" ")).trim(); + ostd::String define_value = lineEdit.new_substr(lineEdit.indexOf(" ") + 1).trim(); if (listContainsDefine(defines, define_name)) { std::cout << "Redefinition of @define value: " << line << "\n"; return; } defines.push_back({ define_name, define_value }); + if (export_name != "") + { + if (!exportExists(m_exportSpecifications, export_name)) + { + std::cout << "Invalid export specification: " << line << "\n"; + return; + } + m_exportSpecifications[export_name].content.push_back({ define_name, define_value }); + } continue; } newLines.push_back(lineEdit); @@ -337,6 +478,14 @@ namespace dragon lineEdit.replaceAll(defines[i].name, defines[i].value.new_trim()); line = lineEdit; } + for (auto& exp : m_exportSpecifications) + { + for (auto& def : exp.second.content) + { + for (int32_t i = defines.size() - 1; i >= 0; i--) + def.value.replaceAll(defines[i].name, defines[i].value.new_trim()); + } + } m_lines.clear(); m_lines = newLines; } @@ -347,6 +496,7 @@ namespace dragon ostd::String lineEdit; bool in_group = false; ostd::String group_name = ""; + ostd::String export_name = ""; for (auto& line : m_lines) { lineEdit = line; @@ -359,6 +509,16 @@ namespace dragon return; } lineEdit.substr(6).trim(); + if (lineEdit.startsWith("/")) + { + if (!lineEdit.contains(" ")) + { + std::cout << "Invalid export definition for group: " << line << "\n"; + return; + } + export_name = lineEdit.new_substr(0, lineEdit.indexOf(" ")).trim(); + lineEdit.substr(lineEdit.indexOf(" ") + 1).trim(); + } if (lineEdit == "") { std::cout << "Group name cannot be empty: " << line << "\n"; @@ -375,6 +535,7 @@ namespace dragon std::cout << "Missing group declaration for @end directive: " << line << "\n"; return; } + export_name = ""; in_group = false; continue; } @@ -388,7 +549,7 @@ namespace dragon std::cout << "Invalid definition inside group: " << line << "\n"; return; } - ostd::String newLine = "@define "; + ostd::String newLine = "@define " + export_name + " "; newLine.add(group_name).add(".").add(lineEdit); newLines.push_back(newLine); } diff --git a/src/assembler/Assembler.hpp b/src/assembler/Assembler.hpp index d9ac44a..fd086b1 100644 --- a/src/assembler/Assembler.hpp +++ b/src/assembler/Assembler.hpp @@ -30,6 +30,11 @@ namespace dragon class Assembler { + public: struct tDefine + { + ostd::String name; + ostd::String value; + }; public: struct tDisassemblyLine { uint32_t addr = 0; @@ -62,6 +67,11 @@ namespace dragon std::vector members; int32_t size; }; + public: struct tExportSpec + { + ostd::String fileName; + std::vector content; + }; public: enum class eOperandType { Register = 0, @@ -79,10 +89,11 @@ namespace dragon { inline tCommandLineArgs(void) { } ostd::String source_file_path { "" }; - ostd::String dest_file_path = { "" }; - bool save_disassembly = { false }; - bool verbose = { false }; - ostd::String disassembly_file_path = { "" }; + ostd::String dest_file_path { "" }; + bool save_disassembly { false }; + bool verbose { false }; + bool save_exports { false }; + ostd::String disassembly_file_path { "" }; }; public: @@ -107,6 +118,8 @@ namespace dragon private: static void removeComments(void); + static void parseExportSpecs(void); + static void processExports(void); static void replaceDefines(void); static void replaceGroupDefines(void); static void parseSections(void); @@ -134,6 +147,7 @@ namespace dragon inline static std::vector m_rawCodeSection; inline static std::unordered_map m_symbolTable; inline static std::unordered_map m_labelTable; + inline static std::unordered_map m_exportSpecifications; inline static uint16_t m_fixedSize { 0 }; inline static uint8_t m_fixedFillValue { 0x00 }; inline static uint16_t m_loadAddress { 0x0000 }; @@ -141,10 +155,12 @@ namespace dragon inline static uint16_t m_dataSize { 0x0000 }; inline static uint16_t m_programSize { 0x0000 }; inline static std::vector m_structDefs; - inline static std::vector m_disassembly; - inline static ostd::ConsoleOutputHandler out; + inline static uint32_t m_exportCommentCount { 0 }; + + public: + inline static bool saveExports { false }; }; } } \ No newline at end of file diff --git a/src/assembler/assembler_main.cpp b/src/assembler/assembler_main.cpp index 358f107..9f5722a 100644 --- a/src/assembler/assembler_main.cpp +++ b/src/assembler/assembler_main.cpp @@ -8,6 +8,7 @@ int main(int argc, char** argv) if (rValue != dragon::code::Assembler::Application::RETURN_VAL_EXIT_SUCCESS) return rValue; auto& args = dragon::code::Assembler::Application::args; + dragon::code::Assembler::saveExports = args.save_exports; dragon::code::Assembler::assembleToFile(args.source_file_path, args.dest_file_path); if (args.verbose) dragon::code::Assembler::printProgramInfo(); diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index 65f9bbf..820676f 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -234,7 +234,6 @@ namespace dragon void Debugger::Display::printDiff(void) { out.clear(); - ostd::String str; str.add("|===============|================PREV================|================CURR================|=====|===PREV====|===CURR====|"); str.add("\n"); @@ -242,7 +241,7 @@ namespace dragon str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| Code: | ---- |*%CURR_CODE%************************| R2 |*%PREV_R2%*|*%CURR_R2%*|"); + str.add("| Code: | ----- |*%CURR_CODE%************************| R2 |*%PREV_R2%*|*%CURR_R2%*|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); @@ -328,7 +327,7 @@ namespace dragon prevCode.add(ostd::Utils::getHexStr(minfo.previousInstructionFootprint[i], false, 1)).add(" "); tmp.add(prevCode); tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); - tmpStyle = "[@@style foreground:Black,background:BrightGray]"; + tmpStyle = "[@@style foreground:Blue]"; tmpStyle.add(tmp).add("[@@/]"); str.replaceAll("%CURR_CODE%", tmpStyle); @@ -339,10 +338,10 @@ namespace dragon // currCode.add(ostd::Utils::getHexStr(minfo.currentInstructionFootprint[i], false, 1)).add(" "); // tmp.add(currCode); // tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); - // if (currCode != prevCode) - // tmpStyle = "[@@style foreground:Black,background:Yellow]"; - // else - // tmpStyle = "[@@style foreground:Blue]"; + // // if (currCode != prevCode) + // // tmpStyle = "[@@style foreground:Black,background:BrightRed]"; + // // else + // tmpStyle = "[@@style foreground:Blue]"; // tmpStyle.add(tmp).add("[@@/]"); // str.replaceAll("%CURR_CODE%", tmpStyle); } diff --git a/src/hardware/CPUExtensions.cpp b/src/hardware/CPUExtensions.cpp index 3667e94..27bcff2 100644 --- a/src/hardware/CPUExtensions.cpp +++ b/src/hardware/CPUExtensions.cpp @@ -1,5 +1,6 @@ #include "CPUExtensions.hpp" #include "VirtualCPU.hpp" +#include "../runtime/DragonRuntime.hpp" namespace dragon { diff --git a/src/hardware/VirtualCPU.cpp b/src/hardware/VirtualCPU.cpp index a7f4aee..2764b31 100644 --- a/src/hardware/VirtualCPU.cpp +++ b/src/hardware/VirtualCPU.cpp @@ -182,6 +182,7 @@ namespace dragon if (m_extensions[i]->m_code == m_currentInst) { m_currentExtension = m_extensions[i]; + m_currentExtInst = m_memory.read8(readRegister(data::Registers::IP)); return true; } } @@ -192,6 +193,7 @@ namespace dragon { if (m_halt) return false; m_currentExtension = nullptr; + m_currentExtInst = 0x00; m_isDebugBreakPoint = false; uint8_t inst = fetch8(); m_currentInst = inst; diff --git a/src/hardware/VirtualCPU.hpp b/src/hardware/VirtualCPU.hpp index 6b6793a..18b0268 100644 --- a/src/hardware/VirtualCPU.hpp +++ b/src/hardware/VirtualCPU.hpp @@ -43,6 +43,8 @@ namespace dragon inline bool isInBIOSMOde(void) const { return m_biosMode; } inline bool isInSubRoutine(void) const { return m_subroutineCounter > 0; } inline int32_t getSubRoutineCounter(void) const { return m_subroutineCounter; } + inline data::CPUExtension* getCurrentCPUExtension(void) const { return m_currentExtension; } + inline uint8_t getCurrentCPUExtensionInstruction(void) const { return m_currentExtInst; } private: void __debug_store_stack_frame_string_on_push(void); @@ -63,6 +65,7 @@ namespace dragon data::CPUExtension* m_extensions[16]; data::CPUExtension* m_currentExtension { nullptr }; + uint8_t m_currentExtInst { 0x00 }; std::vector m_debug_stackFrameStrings; diff --git a/src/runtime/DragonRuntime.cpp b/src/runtime/DragonRuntime.cpp index 79c4e6e..7e1a621 100644 --- a/src/runtime/DragonRuntime.cpp +++ b/src/runtime/DragonRuntime.cpp @@ -448,12 +448,12 @@ namespace dragon } uint16_t instAddr = cpu.readRegister(data::Registers::IP); - uint8_t instSize = data::OpCodes::getInstructionSIze(memMap.read8(instAddr)); - ostd::String opCode = data::OpCodes::getOpCodeString(memMap.read8(instAddr)); + uint8_t int_op_code = memMap.read8(instAddr); + uint8_t instSize = data::OpCodes::getInstructionSIze(int_op_code); + ostd::String opCode = data::OpCodes::getOpCodeString(int_op_code); uint16_t stackFrameSize = cpu.m_stackFrameSize; int32_t subRoutineCounter = cpu.m_subroutineCounter; - bool debugBreak = cpu.m_isDebugBreakPoint; int32_t intHandlerCount = cpu.m_interruptHandlerCount; bool biosMode = cpu.m_biosMode; @@ -483,14 +483,17 @@ namespace dragon } else { - minfo.currentInstructionAddress = instAddr; + //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 (int8_t i = 0; i < instSize; i++) - minfo.currentInstructionFootprint[i] = memMap.read8(instAddr + i); + minfo.currentInstructionFootprint[i] = memMap.read8(minfo.currentInstructionAddress + i); for (int8_t i = 0; i < 20; i++) minfo.currentInstructionRegisters[i] = cpu.readRegister(i); @@ -568,4 +571,4 @@ namespace dragon out.nl().fg(ostd::ConsoleColors::Magenta).p("Usage: ./dvm [...options...]").reset().nl(); out.nl(); } -} \ No newline at end of file +} diff --git a/src/tools/GlobalData.cpp b/src/tools/GlobalData.cpp new file mode 100644 index 0000000..58341ec --- /dev/null +++ b/src/tools/GlobalData.cpp @@ -0,0 +1,204 @@ +#include "GlobalData.hpp" +#include "../runtime/DragonRuntime.hpp" + +namespace dragon +{ + namespace data + { + ostd::String OpCodes::getOpCodeString(uint8_t opCode) + { + CPUExtension* ext = DragonRuntime::cpu.getCurrentCPUExtension(); + if (ext != nullptr) + return ext->getOpCodeString(DragonRuntime::cpu.getCurrentCPUExtensionInstruction()); + switch (opCode) + { + case data::OpCodes::NoOp: return "NoOp"; + case data::OpCodes::DEBUG_Break: return "debug_break"; + case data::OpCodes::BIOSModeImm: return "BIOSModeImm"; + case data::OpCodes::MovImmReg: return "MovImmReg"; + case data::OpCodes::MovImmMem: return "MovImmMem"; + case data::OpCodes::MovRegReg: return "MovRegReg"; + case data::OpCodes::MovRegMem: return "MovRegMem"; + case data::OpCodes::MovMemReg: return "MovMemReg"; + case data::OpCodes::MovDerefRegReg: return "MovDerefRegReg"; + case data::OpCodes::MovDerefRegMem: return "MovDerefRegMem"; + case data::OpCodes::MovImmRegOffReg: return "MovImmRegOffReg"; + case data::OpCodes::MovRegDerefReg: return "MovRegDerefReg"; + case data::OpCodes::MovMemDerefReg: return "MovMemDerefReg"; + case data::OpCodes::MovImmDerefReg: return "MovImmDerefReg"; + case data::OpCodes::MovDerefRegDerefReg: return "MovDerefRegDerefReg"; + case data::OpCodes::MovByteImmMem: return "MovByteImmMem"; + case data::OpCodes::MovByteRegMem: return "MovByteRegMem"; + case data::OpCodes::MovByteDerefRegMem: return "MovByteDerefRegMem"; + case data::OpCodes::MovByteImmDerefReg: return "MovByteImmDerefReg"; + case data::OpCodes::MovByteRegDerefReg: return "MovByteRegDerefReg"; + case data::OpCodes::MovByteMemDerefReg: return "MovByteMemDerefReg"; + case data::OpCodes::MovByteDerefRegDerefReg: return "MovByteDerefRegDerefReg"; + case data::OpCodes::MovByteMemReg: return "MovByteMemReg"; + case data::OpCodes::MovByteImmReg: return "MovByteImmReg"; + case data::OpCodes::MovByteDerefRegReg: return "MovByteDerefRegReg"; + case data::OpCodes::AddImmReg: return "AddImmReg"; + case data::OpCodes::AddRegReg: return "AddRegReg"; + case data::OpCodes::SubImmReg: return "SubImmReg"; + case data::OpCodes::SubRegReg: return "SubRegReg"; + case data::OpCodes::MulImmReg: return "MulImmReg"; + case data::OpCodes::MulRegReg: return "MulRegReg"; + case data::OpCodes::DivImmReg: return "DivImmReg"; + case data::OpCodes::DivRegReg: return "DivRegReg"; + case data::OpCodes::IncReg: return "IncReg"; + case data::OpCodes::DecReg: return "DecReg"; + case data::OpCodes::RShiftRegImm: return "RShiftRegImm"; + case data::OpCodes::RShiftRegReg: return "RShiftRegReg"; + case data::OpCodes::LShiftRegImm: return "LShiftRegImm"; + case data::OpCodes::LShiftRegReg: return "LShiftRegReg"; + case data::OpCodes::AndRegImm: return "AndRegImm"; + case data::OpCodes::AndRegReg: return "AndRegReg"; + case data::OpCodes::OrRegImm: return "OrRegImm"; + case data::OpCodes::OrRegReg: return "OrRegReg"; + case data::OpCodes::XorRegImm: return "XorRegImm"; + case data::OpCodes::XorRegReg: return "XorRegReg"; + case data::OpCodes::NotReg: return "NotReg"; + case data::OpCodes::NegReg: return "NegReg"; + case data::OpCodes::NegByteReg: return "NegByteReg"; + case data::OpCodes::JmpNotEqImm: return "JmpNotEqImm"; + case data::OpCodes::JmpNotEqReg: return "JmpNotEqReg"; + case data::OpCodes::JmpEqImm: return "JmpEqImm"; + case data::OpCodes::JmpEqReg: return "JmpEqReg"; + case data::OpCodes::JmpGrImm: return "JmpGrImm"; + case data::OpCodes::JmpGrReg: return "JmpGrReg"; + case data::OpCodes::JmpLessImm: return "JmpLessImm"; + case data::OpCodes::JmpLessReg: return "JmpLessReg"; + case data::OpCodes::JmpGeImm: return "JmpGeImm"; + case data::OpCodes::JmpGeReg: return "JmpGeReg"; + case data::OpCodes::JmpLeImm: return "JmpLeImm"; + case data::OpCodes::JmpLeReg: return "JmpLeReg"; + case data::OpCodes::Jmp: return "Jmp"; + case data::OpCodes::Halt: return "Halt"; + case data::OpCodes::PushImm: return "PushImm"; + case data::OpCodes::PushReg: return "PushReg"; + case data::OpCodes::PopReg: return "PopReg"; + case data::OpCodes::CallImm: return "CallImm"; + case data::OpCodes::CallReg: return "CallReg"; + case data::OpCodes::Ret: return "Ret"; + case data::OpCodes::ArgReg: return "ArgReg"; + case data::OpCodes::RetInt: return "RetInt"; + case data::OpCodes::Int: return "Int"; + case data::OpCodes::Ext01: return "Ext01"; + case data::OpCodes::Ext02: return "Ext02"; + case data::OpCodes::Ext03: return "Ext03"; + case data::OpCodes::Ext04: return "Ext04"; + case data::OpCodes::Ext05: return "Ext05"; + case data::OpCodes::Ext06: return "Ext06"; + case data::OpCodes::Ext07: return "Ext07"; + case data::OpCodes::Ext08: return "Ext08"; + case data::OpCodes::Ext09: return "Ext09"; + case data::OpCodes::Ext10: return "Ext10"; + case data::OpCodes::Ext11: return "Ext11"; + case data::OpCodes::Ext12: return "Ext12"; + case data::OpCodes::Ext13: return "Ext13"; + case data::OpCodes::Ext14: return "Ext14"; + case data::OpCodes::Ext15: return "Ext15"; + case data::OpCodes::Ext16: return "Ext16"; + default: return "UNKNOWN_INST"; + } + } + + uint8_t OpCodes::getInstructionSIze(uint8_t opCode) + { + CPUExtension* ext = DragonRuntime::cpu.getCurrentCPUExtension(); + if (ext != nullptr) + return ext->getInstructionSIze(DragonRuntime::cpu.getCurrentCPUExtensionInstruction()); + switch (opCode) + { + case data::OpCodes::NoOp: return 1; + case data::OpCodes::DEBUG_Break: return 1; + case data::OpCodes::BIOSModeImm: return 2; + case data::OpCodes::MovImmReg: return 4; + case data::OpCodes::MovImmMem: return 5; + case data::OpCodes::MovRegReg: return 3; + case data::OpCodes::MovRegMem: return 4; + case data::OpCodes::MovMemReg: return 4; + case data::OpCodes::MovDerefRegReg: return 3; + case data::OpCodes::MovDerefRegMem: return 4; + case data::OpCodes::MovImmRegOffReg: return 5; + case data::OpCodes::MovRegDerefReg: return 3; + case data::OpCodes::MovMemDerefReg: return 4; + case data::OpCodes::MovImmDerefReg: return 4; + case data::OpCodes::MovDerefRegDerefReg: return 3; + case data::OpCodes::MovByteImmMem: return 4; + case data::OpCodes::MovByteRegMem: return 4; + case data::OpCodes::MovByteDerefRegMem: return 4; + case data::OpCodes::MovByteImmDerefReg: return 3; + case data::OpCodes::MovByteRegDerefReg: return 3; + case data::OpCodes::MovByteMemDerefReg: return 4; + case data::OpCodes::MovByteDerefRegDerefReg: return 3; + case data::OpCodes::MovByteMemReg: return 4; + case data::OpCodes::MovByteImmReg: return 3; + case data::OpCodes::MovByteDerefRegReg: return 3; + case data::OpCodes::AddImmReg: return 4; + case data::OpCodes::AddRegReg: return 3; + case data::OpCodes::SubImmReg: return 4; + case data::OpCodes::SubRegReg: return 3; + case data::OpCodes::MulImmReg: return 4; + case data::OpCodes::MulRegReg: return 3; + case data::OpCodes::DivImmReg: return 4; + case data::OpCodes::DivRegReg: return 3; + case data::OpCodes::IncReg: return 2; + case data::OpCodes::DecReg: return 2; + case data::OpCodes::RShiftRegImm: return 4; + case data::OpCodes::RShiftRegReg: return 3; + case data::OpCodes::LShiftRegImm: return 4; + case data::OpCodes::LShiftRegReg: return 3; + case data::OpCodes::AndRegImm: return 4; + case data::OpCodes::AndRegReg: return 3; + case data::OpCodes::OrRegImm: return 4; + case data::OpCodes::OrRegReg: return 3; + case data::OpCodes::XorRegImm: return 4; + case data::OpCodes::XorRegReg: return 3; + case data::OpCodes::NotReg: return 2; + case data::OpCodes::NegReg: return 2; + case data::OpCodes::NegByteReg: return 2; + case data::OpCodes::JmpNotEqImm: return 5; + case data::OpCodes::JmpNotEqReg: return 4; + case data::OpCodes::JmpEqImm: return 5; + case data::OpCodes::JmpEqReg: return 4; + case data::OpCodes::JmpGrImm: return 5; + case data::OpCodes::JmpGrReg: return 4; + case data::OpCodes::JmpLessImm: return 5; + case data::OpCodes::JmpLessReg: return 4; + case data::OpCodes::JmpGeImm: return 5; + case data::OpCodes::JmpGeReg: return 4; + case data::OpCodes::JmpLeImm: return 5; + case data::OpCodes::JmpLeReg: return 4; + case data::OpCodes::Jmp: return 3; + case data::OpCodes::Halt: return 1; + case data::OpCodes::PushImm: return 3; + case data::OpCodes::PushReg: return 2; + case data::OpCodes::PopReg: return 2; + case data::OpCodes::CallImm: return 3; + case data::OpCodes::CallReg: return 2; + case data::OpCodes::Ret: return 1; + case data::OpCodes::ArgReg: return 2; + case data::OpCodes::RetInt: return 1; + case data::OpCodes::Int: return 2; + case data::OpCodes::Ext01: return 0; + case data::OpCodes::Ext02: return 0; + case data::OpCodes::Ext03: return 0; + case data::OpCodes::Ext04: return 0; + case data::OpCodes::Ext05: return 0; + case data::OpCodes::Ext06: return 0; + case data::OpCodes::Ext07: return 0; + case data::OpCodes::Ext08: return 0; + case data::OpCodes::Ext09: return 0; + case data::OpCodes::Ext10: return 0; + case data::OpCodes::Ext11: return 0; + case data::OpCodes::Ext12: return 0; + case data::OpCodes::Ext13: return 0; + case data::OpCodes::Ext14: return 0; + case data::OpCodes::Ext15: return 0; + case data::OpCodes::Ext16: return 0; + default: return 0; + } + } + } +} \ No newline at end of file diff --git a/src/tools/GlobalData.hpp b/src/tools/GlobalData.hpp index 4eaae3a..ba12674 100644 --- a/src/tools/GlobalData.hpp +++ b/src/tools/GlobalData.hpp @@ -310,200 +310,8 @@ namespace dragon inline static constexpr uint8_t Int = 0xFE; inline static constexpr uint8_t Halt = 0xFF; - inline static ostd::String getOpCodeString(uint8_t opCode, CPUExtension* ext = nullptr) - { - if (ext != nullptr) - return ext->getOpCodeString(opCode); - switch (opCode) - { - case data::OpCodes::NoOp: return "NoOp"; - case data::OpCodes::DEBUG_Break: return "debug_break"; - case data::OpCodes::BIOSModeImm: return "BIOSModeImm"; - case data::OpCodes::MovImmReg: return "MovImmReg"; - case data::OpCodes::MovImmMem: return "MovImmMem"; - case data::OpCodes::MovRegReg: return "MovRegReg"; - case data::OpCodes::MovRegMem: return "MovRegMem"; - case data::OpCodes::MovMemReg: return "MovMemReg"; - case data::OpCodes::MovDerefRegReg: return "MovDerefRegReg"; - case data::OpCodes::MovDerefRegMem: return "MovDerefRegMem"; - case data::OpCodes::MovImmRegOffReg: return "MovImmRegOffReg"; - case data::OpCodes::MovRegDerefReg: return "MovRegDerefReg"; - case data::OpCodes::MovMemDerefReg: return "MovMemDerefReg"; - case data::OpCodes::MovImmDerefReg: return "MovImmDerefReg"; - case data::OpCodes::MovDerefRegDerefReg: return "MovDerefRegDerefReg"; - case data::OpCodes::MovByteImmMem: return "MovByteImmMem"; - case data::OpCodes::MovByteRegMem: return "MovByteRegMem"; - case data::OpCodes::MovByteDerefRegMem: return "MovByteDerefRegMem"; - case data::OpCodes::MovByteImmDerefReg: return "MovByteImmDerefReg"; - case data::OpCodes::MovByteRegDerefReg: return "MovByteRegDerefReg"; - case data::OpCodes::MovByteMemDerefReg: return "MovByteMemDerefReg"; - case data::OpCodes::MovByteDerefRegDerefReg: return "MovByteDerefRegDerefReg"; - case data::OpCodes::MovByteMemReg: return "MovByteMemReg"; - case data::OpCodes::MovByteImmReg: return "MovByteImmReg"; - case data::OpCodes::MovByteDerefRegReg: return "MovByteDerefRegReg"; - case data::OpCodes::AddImmReg: return "AddImmReg"; - case data::OpCodes::AddRegReg: return "AddRegReg"; - case data::OpCodes::SubImmReg: return "SubImmReg"; - case data::OpCodes::SubRegReg: return "SubRegReg"; - case data::OpCodes::MulImmReg: return "MulImmReg"; - case data::OpCodes::MulRegReg: return "MulRegReg"; - case data::OpCodes::DivImmReg: return "DivImmReg"; - case data::OpCodes::DivRegReg: return "DivRegReg"; - case data::OpCodes::IncReg: return "IncReg"; - case data::OpCodes::DecReg: return "DecReg"; - case data::OpCodes::RShiftRegImm: return "RShiftRegImm"; - case data::OpCodes::RShiftRegReg: return "RShiftRegReg"; - case data::OpCodes::LShiftRegImm: return "LShiftRegImm"; - case data::OpCodes::LShiftRegReg: return "LShiftRegReg"; - case data::OpCodes::AndRegImm: return "AndRegImm"; - case data::OpCodes::AndRegReg: return "AndRegReg"; - case data::OpCodes::OrRegImm: return "OrRegImm"; - case data::OpCodes::OrRegReg: return "OrRegReg"; - case data::OpCodes::XorRegImm: return "XorRegImm"; - case data::OpCodes::XorRegReg: return "XorRegReg"; - case data::OpCodes::NotReg: return "NotReg"; - case data::OpCodes::NegReg: return "NegReg"; - case data::OpCodes::NegByteReg: return "NegByteReg"; - case data::OpCodes::JmpNotEqImm: return "JmpNotEqImm"; - case data::OpCodes::JmpNotEqReg: return "JmpNotEqReg"; - case data::OpCodes::JmpEqImm: return "JmpEqImm"; - case data::OpCodes::JmpEqReg: return "JmpEqReg"; - case data::OpCodes::JmpGrImm: return "JmpGrImm"; - case data::OpCodes::JmpGrReg: return "JmpGrReg"; - case data::OpCodes::JmpLessImm: return "JmpLessImm"; - case data::OpCodes::JmpLessReg: return "JmpLessReg"; - case data::OpCodes::JmpGeImm: return "JmpGeImm"; - case data::OpCodes::JmpGeReg: return "JmpGeReg"; - case data::OpCodes::JmpLeImm: return "JmpLeImm"; - case data::OpCodes::JmpLeReg: return "JmpLeReg"; - case data::OpCodes::Jmp: return "Jmp"; - case data::OpCodes::Halt: return "Halt"; - case data::OpCodes::PushImm: return "PushImm"; - case data::OpCodes::PushReg: return "PushReg"; - case data::OpCodes::PopReg: return "PopReg"; - case data::OpCodes::CallImm: return "CallImm"; - case data::OpCodes::CallReg: return "CallReg"; - case data::OpCodes::Ret: return "Ret"; - case data::OpCodes::ArgReg: return "ArgReg"; - case data::OpCodes::RetInt: return "RetInt"; - case data::OpCodes::Int: return "Int"; - case data::OpCodes::Ext01: return "Ext01"; - case data::OpCodes::Ext02: return "Ext02"; - case data::OpCodes::Ext03: return "Ext03"; - case data::OpCodes::Ext04: return "Ext04"; - case data::OpCodes::Ext05: return "Ext05"; - case data::OpCodes::Ext06: return "Ext06"; - case data::OpCodes::Ext07: return "Ext07"; - case data::OpCodes::Ext08: return "Ext08"; - case data::OpCodes::Ext09: return "Ext09"; - case data::OpCodes::Ext10: return "Ext10"; - case data::OpCodes::Ext11: return "Ext11"; - case data::OpCodes::Ext12: return "Ext12"; - case data::OpCodes::Ext13: return "Ext13"; - case data::OpCodes::Ext14: return "Ext14"; - case data::OpCodes::Ext15: return "Ext15"; - case data::OpCodes::Ext16: return "Ext16"; - default: return "UNKNOWN_INST"; - } - } - - inline static uint8_t getInstructionSIze(uint8_t opCode, CPUExtension* ext = nullptr) - { - if (ext != nullptr) - return ext->getInstructionSIze(opCode); - switch (opCode) - { - case data::OpCodes::NoOp: return 1; - case data::OpCodes::DEBUG_Break: return 1; - case data::OpCodes::BIOSModeImm: return 2; - case data::OpCodes::MovImmReg: return 4; - case data::OpCodes::MovImmMem: return 5; - case data::OpCodes::MovRegReg: return 3; - case data::OpCodes::MovRegMem: return 4; - case data::OpCodes::MovMemReg: return 4; - case data::OpCodes::MovDerefRegReg: return 3; - case data::OpCodes::MovDerefRegMem: return 4; - case data::OpCodes::MovImmRegOffReg: return 5; - case data::OpCodes::MovRegDerefReg: return 3; - case data::OpCodes::MovMemDerefReg: return 4; - case data::OpCodes::MovImmDerefReg: return 4; - case data::OpCodes::MovDerefRegDerefReg: return 3; - case data::OpCodes::MovByteImmMem: return 4; - case data::OpCodes::MovByteRegMem: return 4; - case data::OpCodes::MovByteDerefRegMem: return 4; - case data::OpCodes::MovByteImmDerefReg: return 3; - case data::OpCodes::MovByteRegDerefReg: return 3; - case data::OpCodes::MovByteMemDerefReg: return 4; - case data::OpCodes::MovByteDerefRegDerefReg: return 3; - case data::OpCodes::MovByteMemReg: return 4; - case data::OpCodes::MovByteImmReg: return 3; - case data::OpCodes::MovByteDerefRegReg: return 3; - case data::OpCodes::AddImmReg: return 4; - case data::OpCodes::AddRegReg: return 3; - case data::OpCodes::SubImmReg: return 4; - case data::OpCodes::SubRegReg: return 3; - case data::OpCodes::MulImmReg: return 4; - case data::OpCodes::MulRegReg: return 3; - case data::OpCodes::DivImmReg: return 4; - case data::OpCodes::DivRegReg: return 3; - case data::OpCodes::IncReg: return 2; - case data::OpCodes::DecReg: return 2; - case data::OpCodes::RShiftRegImm: return 4; - case data::OpCodes::RShiftRegReg: return 3; - case data::OpCodes::LShiftRegImm: return 4; - case data::OpCodes::LShiftRegReg: return 3; - case data::OpCodes::AndRegImm: return 4; - case data::OpCodes::AndRegReg: return 3; - case data::OpCodes::OrRegImm: return 4; - case data::OpCodes::OrRegReg: return 3; - case data::OpCodes::XorRegImm: return 4; - case data::OpCodes::XorRegReg: return 3; - case data::OpCodes::NotReg: return 2; - case data::OpCodes::NegReg: return 2; - case data::OpCodes::NegByteReg: return 2; - case data::OpCodes::JmpNotEqImm: return 5; - case data::OpCodes::JmpNotEqReg: return 4; - case data::OpCodes::JmpEqImm: return 5; - case data::OpCodes::JmpEqReg: return 4; - case data::OpCodes::JmpGrImm: return 5; - case data::OpCodes::JmpGrReg: return 4; - case data::OpCodes::JmpLessImm: return 5; - case data::OpCodes::JmpLessReg: return 4; - case data::OpCodes::JmpGeImm: return 5; - case data::OpCodes::JmpGeReg: return 4; - case data::OpCodes::JmpLeImm: return 5; - case data::OpCodes::JmpLeReg: return 4; - case data::OpCodes::Jmp: return 3; - case data::OpCodes::Halt: return 1; - case data::OpCodes::PushImm: return 3; - case data::OpCodes::PushReg: return 2; - case data::OpCodes::PopReg: return 2; - case data::OpCodes::CallImm: return 3; - case data::OpCodes::CallReg: return 2; - case data::OpCodes::Ret: return 1; - case data::OpCodes::ArgReg: return 2; - case data::OpCodes::RetInt: return 1; - case data::OpCodes::Int: return 2; - case data::OpCodes::Ext01: return 0; - case data::OpCodes::Ext02: return 0; - case data::OpCodes::Ext03: return 0; - case data::OpCodes::Ext04: return 0; - case data::OpCodes::Ext05: return 0; - case data::OpCodes::Ext06: return 0; - case data::OpCodes::Ext07: return 0; - case data::OpCodes::Ext08: return 0; - case data::OpCodes::Ext09: return 0; - case data::OpCodes::Ext10: return 0; - case data::OpCodes::Ext11: return 0; - case data::OpCodes::Ext12: return 0; - case data::OpCodes::Ext13: return 0; - case data::OpCodes::Ext14: return 0; - case data::OpCodes::Ext15: return 0; - case data::OpCodes::Ext16: return 0; - default: return 0; - } - } - + static ostd::String getOpCodeString(uint8_t opCode); + static uint8_t getInstructionSIze(uint8_t opCode); }; } } \ No newline at end of file