Started work on Extended instruction sets support

This commit is contained in:
OmniaX-dev 2024-03-29 22:37:04 +01:00
parent 9fdd690d0c
commit 522e31ec22
16 changed files with 480 additions and 233 deletions

19
.vscode/settings.json vendored
View file

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

View file

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

View file

@ -1 +1 @@
1584
1587

View file

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

View file

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

View file

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

View file

@ -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 <destination-binary-file>";
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<ostd::String, tExportSpec>& exports, const ostd::String& name) -> bool {
return exports.count(name) > 0;
};
std::vector<ostd::String> 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<tDefine>& list, const ostd::String& name) -> bool {
for (auto& def : list)
{
@ -299,6 +395,9 @@ namespace dragon
}
return false;
};
auto exportExists = [](const std::unordered_map<ostd::String, tExportSpec>& exports, const ostd::String& name) -> bool {
return exports.count(name) > 0;
};
std::vector<tDefine> defines;
std::vector<ostd::String> 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);
}

View file

@ -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<tStructMember> members;
int32_t size;
};
public: struct tExportSpec
{
ostd::String fileName;
std::vector<tDefine> 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<ostd::String> m_rawCodeSection;
inline static std::unordered_map<ostd::String, tSymbol> m_symbolTable;
inline static std::unordered_map<ostd::String, tLabel> m_labelTable;
inline static std::unordered_map<ostd::String, tExportSpec> 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<tStructDefinition> m_structDefs;
inline static std::vector<tDisassemblyLine> m_disassembly;
inline static ostd::ConsoleOutputHandler out;
inline static uint32_t m_exportCommentCount { 0 };
public:
inline static bool saveExports { false };
};
}
}

View file

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

View file

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

View file

@ -1,5 +1,6 @@
#include "CPUExtensions.hpp"
#include "VirtualCPU.hpp"
#include "../runtime/DragonRuntime.hpp"
namespace dragon
{

View file

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

View file

@ -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<ostd::String> m_debug_stackFrameStrings;

View file

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

204
src/tools/GlobalData.cpp Normal file
View file

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

View file

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