From 56e12f994921627f2ac1c37e1cd5d129bdd1aa9b Mon Sep 17 00:00:00 2001 From: OmniaX-dev Date: Sat, 30 Mar 2024 18:39:14 +0100 Subject: [PATCH] Started work on implementing DASM mnemonics for ExtMov --- extra/dragon info/todo.txt | 48 ++-- extra/dss/extmov_unit_tests.dss | 69 ++++-- extra/make_and_debug | 4 +- extra/make_and_run | 4 +- src/assembler/Assembler.cpp | 384 +++++++++++++++++++++++++++---- src/assembler/Assembler.hpp | 2 + src/assembler/assembler_main.cpp | 1 + src/hardware/CPUExtensions.cpp | 2 +- 8 files changed, 418 insertions(+), 96 deletions(-) diff --git a/extra/dragon info/todo.txt b/extra/dragon info/todo.txt index ad6efda..2938225 100644 --- a/extra/dragon info/todo.txt +++ b/extra/dragon info/todo.txt @@ -9,52 +9,52 @@ Add possibility to specify required instruction sets in dasm Implelemnt Instructions in dasm: ## Offset on first operand - omov *R1, 0xFAAB, 4 ## Move word immediate into (deref reg + immediate offset word) - omov *R1, 0xFAAB, R10 ## Move word immediate into (deref reg + reg offset) - omov *R1, 0xFAAB, 4 ## Move word immediate into (deref reg + immediate offset byte) + ## omov *R1, 0xFAAB, word 4 ## Move word immediate into (deref reg + immediate offset word) + ## omov *R1, 0xFAAB, R10 ## Move word immediate into (deref reg + reg offset) + ## omov *R1, 0xFAAB, 4 ## Move word immediate into (deref reg + immediate offset byte) - omovb *R1, 0xFA, 4 ## Move byte immediate into (deref reg + immediate offset word) - omovb *R1, 0xFA, R10 ## Move byte immediate into (deref reg + reg offset) - omovb *R1, 0xFA, 4 ## Move byte immediate into (deref reg + immediate offset byte) + ## omovb *R1, 0xFA, word 4 ## Move byte immediate into (deref reg + immediate offset word) + ## omovb *R1, 0xFA, R10 ## Move byte immediate into (deref reg + reg offset) + ## omovb *R1, 0xFA, 4 ## Move byte immediate into (deref reg + immediate offset byte) - omov *R1, *R2, 4 ## Move word deref reg into (deref reg + immediate offset word) - omov *R1, *R2, R10 ## Move word deref reg into (deref reg + reg offset) - omov *R1, *R2, 4 ## Move word deref reg into (deref reg + immediate offset byte) + ## omov *R1, *R2, word 4 ## Move word deref reg into (deref reg + immediate offset word) + ## omov *R1, *R2, R10 ## Move word deref reg into (deref reg + reg offset) + ## omov *R1, *R2, 4 ## Move word deref reg into (deref reg + immediate offset byte) - omovb *R1, *R2, 4 ## Move byte deref reg into (deref reg + immediate offset word) - omovb *R1, *R2, R10 ## Move byte deref reg into (deref reg + reg offset) - omovb *R1, *R2, 4 ## Move byte deref reg into (deref reg + immediate offset byte) + ## omovb *R1, *R2, word 4 ## Move byte deref reg into (deref reg + immediate offset word) + ## omovb *R1, *R2, R10 ## Move byte deref reg into (deref reg + reg offset) + ## omovb *R1, *R2, 4 ## Move byte deref reg into (deref reg + immediate offset byte) - omov [0x1800], 0xACAB, 4 ## Move word immediate into (Memory + immediate offset word) - omov [0x1800], 0xACAB, R10 ## Move word immediate into (Memory + reg offset) - omov [0x1800], 0xACAB, 4 ## Move word immediate into (Memory + immediate offset byte) + ## omov [0x1800], 0xACAB, word 4 ## Move word immediate into (Memory + immediate offset word) + ## omov [0x1800], 0xACAB, R10 ## Move word immediate into (Memory + reg offset) + ## omov [0x1800], 0xACAB, 4 ## Move word immediate into (Memory + immediate offset byte) - omovb [0x1800], 0xAC, 4 ## Move byte immediate into (Memory + immediate offset word) - omovb [0x1800], 0xAC, R10 ## Move byte immediate into (Memory + reg offset) - omovb [0x1800], 0xAC, 4 ## Move byte immediate into (Memory + immediate offset byte) + ## omovb [0x1800], 0xAC, word 4 ## Move byte immediate into (Memory + immediate offset word) + ## omovb [0x1800], 0xAC, R10 ## Move byte immediate into (Memory + reg offset) + ## omovb [0x1800], 0xAC, 4 ## Move byte immediate into (Memory + immediate offset byte) ## Offset on second operand - movo *R1, *R2, 4 ## Move word (deref reg + immediate offset word) into deref reg + movo *R1, *R2, word 4 ## Move word (deref reg + immediate offset word) into deref reg movo *R1, *R2, R10 ## Move word (deref reg + reg offset) into deref reg movo *R1, *R2, 4 ## Move word (deref reg + immediate offset byte) into deref reg - movbo *R1, *R2, 4 ## Move byte (deref reg + immediate offset word) into deref reg + movbo *R1, *R2, word 4 ## Move byte (deref reg + immediate offset word) into deref reg movbo *R1, *R2, R10 ## Move byte (deref reg + reg offset) into deref reg movbo *R1, *R2, 4 ## Move byte (deref reg + immediate offset byte) into deref reg - movo R1, [0xFAAB], 4 ## Move word (Memory + immediate offset word) into reg + movo R1, [0xFAAB], word 4 ## Move word (Memory + immediate offset word) into reg movo R1, [0xFAAB], R10 ## Move word (Memory + reg offset) into reg movo R1, [0xFAAB], 4 ## Move word (Memory + immediate offset byte) into reg - movbo R1, [0xFAAB], 4 ## Move byte (Memory + immediate offset word) into reg + movbo R1, [0xFAAB], word 4 ## Move byte (Memory + immediate offset word) into reg movbo R1, [0xFAAB], R10 ## Move byte (Memory + reg offset) into reg movbo R1, [0xFAAB], 4 ## Move byte (Memory + immediate offset byte) into reg - movo R1, *R2, 4 ## Move word (deref reg + immediate offset word) into reg + movo R1, *R2, word 4 ## Move word (deref reg + immediate offset word) into reg movo R1, *R2, R10 ## Move word (deref reg + reg offset) into reg movo R1, *R2, 4 ## Move word (deref reg + immediate offset byte) into reg - movbo R1, *R2, 4 ## Move byte (deref reg + immediate offset word) into reg + movbo R1, *R2, word 4 ## Move byte (deref reg + immediate offset word) into reg movbo R1, *R2, R10 ## Move byte (deref reg + reg offset) into reg movbo R1, *R2, 4 ## Move byte (deref reg + immediate offset byte) into reg \ No newline at end of file diff --git a/extra/dss/extmov_unit_tests.dss b/extra/dss/extmov_unit_tests.dss index 07c4d72..86cc1a3 100644 --- a/extra/dss/extmov_unit_tests.dss +++ b/extra/dss/extmov_unit_tests.dss @@ -2,17 +2,17 @@ @define EXT_MOV 0xE0 -@define wimm_in_dreg_immoffw 0x10 -@define wimm_in_dreg_regoff 0x11 -@define wimm_in_dreg_immoffb 0x12 +## @define wimm_in_dreg_immoffw 0x10 +## @define wimm_in_dreg_regoff 0x11 +## @define wimm_in_dreg_immoffb 0x12 @define bimm_in_dreg_immoffw 0x13 @define bimm_in_dreg_regoff 0x14 @define bimm_in_dreg_immoffb 0x15 -@define wdreg_in_dreg_immoffw 0x16 -@define wdreg_in_dreg_regoff 0x17 -@define wdreg_in_dreg_immoffb 0x18 +## @define wdreg_in_dreg_immoffw 0x16 +## @define wdreg_in_dreg_regoff 0x17 +## @define wdreg_in_dreg_immoffb 0x18 @define bdreg_in_dreg_immoffw 0x19 @define bdreg_in_dreg_regoff 0x1A @@ -83,10 +83,12 @@ ## ------ Test 1 ------ - ## debug_break + debug_break inc R5 mov R1, 0x3000 - %low EXT_MOV wimm_in_dreg_immoffw _R1 0xFA 0xAA 0x00 0x02 + inc R8 + omov *R1, 0xFAAA, word 0x02 + ## %low EXT_MOV wimm_in_dreg_immoffw _R1 0xFA 0xAA 0x00 0x02 add R1, 0x02 mov R1, ACC mov ACC, *R1 @@ -103,7 +105,8 @@ test_1_passed: inc R5 mov R1, 0x3000 mov R2, 0x03 - %low EXT_MOV wimm_in_dreg_regoff _R1 0xFA 0xAA _R2 + omov *R1, 0xFAAA, R2 + ## %low EXT_MOV wimm_in_dreg_regoff _R1 0xFA 0xAA _R2 add R1, 0x03 mov R1, ACC mov ACC, *R1 @@ -119,7 +122,8 @@ test_2_passed: ## debug_break inc R5 mov R1, 0x3000 - %low EXT_MOV wimm_in_dreg_immoffb _R1 0xFA 0xAA 0x04 + omov *R1, 0xFAAA, 0x04 + ## %low EXT_MOV wimm_in_dreg_immoffb _R1 0xFA 0xAA 0x04 add R1, 0x04 mov R1, ACC mov ACC, *R1 @@ -135,7 +139,8 @@ test_3_passed: ## debug_break inc R5 mov R1, 0x3000 - %low EXT_MOV bimm_in_dreg_immoffw _R1 0xEE 0x00 0x06 + omovb *R1, 0xEE, word 0x06 + ## %low EXT_MOV bimm_in_dreg_immoffw _R1 0xEE 0x00 0x06 add R1, 0x06 mov R1, ACC movb ACC, *R1 @@ -152,7 +157,8 @@ test_4_passed: inc R5 mov R1, 0x3000 mov R2, 0x06 - %low EXT_MOV bimm_in_dreg_regoff _R1 0x11 _R2 + omovb *R1, 0x11, R2 + ## %low EXT_MOV bimm_in_dreg_regoff _R1 0x11 _R2 add R1, 0x06 mov R1, ACC movb ACC, *R1 @@ -168,7 +174,8 @@ test_5_passed: ## debug_break inc R5 mov R1, 0x3000 - %low EXT_MOV bimm_in_dreg_immoffb _R1 0x22 0x08 + omovb *R1, 0x22, 0x08 + ## %low EXT_MOV bimm_in_dreg_immoffb _R1 0x22 0x08 add R1, 0x08 mov R1, ACC movb ACC, *R1 @@ -186,7 +193,8 @@ test_6_passed: mov R1, 0x5000 mov R3, 0x4000 mov *R3, 0x33 - %low EXT_MOV wdreg_in_dreg_immoffw _R1 _R3 0x00 0x0A + omov *R1, *R3, word 0x0A + ## %low EXT_MOV wdreg_in_dreg_immoffw _R1 _R3 0x00 0x0A add R1, 0x0A mov R1, ACC mov ACC, *R1 @@ -205,7 +213,8 @@ test_7_passed: mov R3, 0x4000 mov *R3, 0x44 mov R2, 0x0C - %low EXT_MOV wdreg_in_dreg_regoff _R1 _R3 _R2 + omov *R1, *R3, R2 + ## %low EXT_MOV wdreg_in_dreg_regoff _R1 _R3 _R2 add R1, 0x0C mov R1, ACC mov ACC, *R1 @@ -223,7 +232,8 @@ test_8_passed: mov R1, 0x5000 mov R3, 0x4000 mov *R3, 0x55 - %low EXT_MOV wdreg_in_dreg_immoffb _R1 _R3 0x0E + omov *R1, *R3, 0x0E + ## %low EXT_MOV wdreg_in_dreg_immoffb _R1 _R3 0x0E add R1, 0x0E mov R1, ACC mov ACC, *R1 @@ -241,7 +251,8 @@ test_9_passed: mov R1, 0x6000 mov R3, 0x5000 movb *R3, 0x66 - %low EXT_MOV bdreg_in_dreg_immoffw _R1 _R3 0x00 0x10 + omovb *R1, *R3, word 0x10 + ## %low EXT_MOV bdreg_in_dreg_immoffw _R1 _R3 0x00 0x10 add R1, 0x10 mov R1, ACC movb ACC, *R1 @@ -260,7 +271,8 @@ test_10_passed: mov R3, 0x5000 movb *R3, 0x77 mov R2, 0x12 - %low EXT_MOV bdreg_in_dreg_regoff _R1 _R3 _R2 + omovb *R1, *R3, R2 + ## %low EXT_MOV bdreg_in_dreg_regoff _R1 _R3 _R2 add R1, 0x12 mov R1, ACC movb ACC, *R1 @@ -278,7 +290,8 @@ test_11_passed: mov R1, 0x6000 mov R3, 0x5000 movb *R3, 0x88 - %low EXT_MOV bdreg_in_dreg_immoffb _R1 _R3 0x14 + omovb *R1, *R3, 0x14 + ## %low EXT_MOV bdreg_in_dreg_immoffb _R1 _R3 0x14 add R1, 0x14 mov R1, ACC movb ACC, *R1 @@ -293,7 +306,8 @@ test_12_passed: ## ------ Test 13 ------ ## debug_break inc R5 - %low EXT_MOV wimm_in_mem_immoffw 0x70 0x00 0xAA 0x99 0x00 0x16 + omov [0x7000], 0xAA99, word 0x16 + ## %low EXT_MOV wimm_in_mem_immoffw 0x70 0x00 0xAA 0x99 0x00 0x16 mov R1, 0x7000 add R1, 0x16 mov R1, ACC @@ -310,7 +324,8 @@ test_13_passed: ## debug_break inc R5 mov R2, 0x18 - %low EXT_MOV wimm_in_mem_regoff 0x70 0x00 0xAA 0xAA _R2 + omov [0x7000], 0xAAAA, R2 + ## %low EXT_MOV wimm_in_mem_regoff 0x70 0x00 0xAA 0xAA _R2 mov R1, 0x7000 add R1, 0x18 mov R1, ACC @@ -326,7 +341,8 @@ test_14_passed: ## ------ Test 15 ------ ## debug_break inc R5 - %low EXT_MOV wimm_in_mem_immoffb 0x70 0x00 0xAA 0xBB 0x1A + omov [0x7000], 0xAABB, 0x1A + ## %low EXT_MOV wimm_in_mem_immoffb 0x70 0x00 0xAA 0xBB 0x1A mov R1, 0x7000 add R1, 0x1A mov R1, ACC @@ -342,7 +358,8 @@ test_15_passed: ## ------ Test 16 ------ ## debug_break inc R5 - %low EXT_MOV bimm_in_mem_immoffw 0x80 0x00 0xCC 0x00 0x1C + omovb [0x8000], 0xCC, word 0x1C + ## %low EXT_MOV bimm_in_mem_immoffw 0x80 0x00 0xCC 0x00 0x1C mov R1, 0x8000 add R1, 0x1C mov R1, ACC @@ -359,7 +376,8 @@ test_16_passed: ## debug_break inc R5 mov R2, 0x1E - %low EXT_MOV bimm_in_mem_regoff 0x80 0x00 0xDD _R2 + omovb [0x8000], 0xDD, R2 + ## %low EXT_MOV bimm_in_mem_regoff 0x80 0x00 0xDD _R2 mov R1, 0x8000 add R1, 0x1E mov R1, ACC @@ -375,7 +393,8 @@ test_17_passed: ## ------ Test 18 ------ ## debug_break inc R5 - %low EXT_MOV bimm_in_mem_immoffb 0x80 0x00 0xEE 0x20 + omovb [0x8000], 0xEE, 0x20 + ## %low EXT_MOV bimm_in_mem_immoffb 0x80 0x00 0xEE 0x20 mov R1, 0x8000 add R1, 0x20 mov R1, ACC diff --git a/extra/make_and_debug b/extra/make_and_debug index 5f279f6..bcb418f 100755 --- a/extra/make_and_debug +++ b/extra/make_and_debug @@ -17,8 +17,8 @@ if [ $? -eq 0 ]; then /bin/bash ./load_mbr cd .. printf "${green}Compiling Test Program...\n" - ./dasm dss/extmov_unit_tests.dss -o extmov_unit_tests.bin --save-disassembly disassembly/extmov_unit_tests.dds --verbose - # ./dasm dss/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds --verbose + ./dasm dss/extmov_unit_tests.dss -o extmov_unit_tests.bin --extmov --save-disassembly disassembly/extmov_unit_tests.dds --verbose + # ./dasm dss/newTest.dss -o newTest.bin --extmov --save-disassembly disassembly/newTest.dds --verbose printf "\n${green}Running Application...\n\n${clear}" ./ddb config/testMachine.dvm --force-load extmov_unit_tests.bin 0x00 --verbose-load # ./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load diff --git a/extra/make_and_run b/extra/make_and_run index 5462cfa..35ac2bf 100755 --- a/extra/make_and_run +++ b/extra/make_and_run @@ -17,8 +17,8 @@ if [ $? -eq 0 ]; then /bin/bash ./load_mbr cd .. printf "${green}Compiling Test Program...\n" - ./dasm dss/extmov_unit_tests.dss -o extmov_unit_tests.bin --save-disassembly disassembly/extmov_unit_tests.dds --verbose - # ./dasm dss/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds --verbose + ./dasm dss/extmov_unit_tests.dss -o extmov_unit_tests.bin --extmov --save-disassembly disassembly/extmov_unit_tests.dds --verbose + # ./dasm dss/newTest.dss -o newTest.bin --extmov --save-disassembly disassembly/newTest.dds --verbose printf "\n${green}Running Application...\n\n${clear}" ./dvm config/testMachine.dvm --force-load extmov_unit_tests.bin 0x00 # ./dvm config/testMachine.dvm --force-load newTest.bin 0x00 diff --git a/src/assembler/Assembler.cpp b/src/assembler/Assembler.cpp index b5ddab3..23a8d72 100644 --- a/src/assembler/Assembler.cpp +++ b/src/assembler/Assembler.cpp @@ -8,6 +8,7 @@ #include "../tools/GlobalData.hpp" #include "../hardware/VirtualHardDrive.hpp" +#include "../hardware/CPUExtensions.hpp" #include "../tools/Utils.hpp" namespace dragon @@ -147,6 +148,8 @@ namespace dragon print_application_help(); return RETURN_VAL_CLOSE_PROGRAM; } + else if (edit == "--extmov") + args.cpu_extensions.push_back("extmov"); else if (edit == "--verbose") args.verbose = true; else if (edit == "--save-exports") @@ -1619,48 +1622,345 @@ namespace dragon void Assembler::parse3Operand(ostd::String line) { - // ostd::String lineEdit(line); - // ostd::String instEdit(lineEdit.new_substr(0, lineEdit.indexOf(" "))); - // instEdit.trim().toLower(); - // ostd::String opEdit(lineEdit.new_substr(lineEdit.indexOf(" ") + 1)); - // opEdit.trim(); - // int16_t word = 0x0000; - // if (instEdit == "mov") - // { - // auto st = opEdit.tokenize(","); - // eOperandType opType = parseOperand(st.next(), word); - // if (opType != eOperandType::Register) - // { - // std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; - // exit(0); - // return; - // } - // m_code.push_back(data::OpCodes::MovImmRegOffReg); - // m_code.push_back((uint8_t)word); - // opType = parseOperand(st.next(), word); - // if (opType != eOperandType::DerefMemory) - // { - // std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Pointer required\n"; - // exit(0); - // return; - // } - // m_code.push_back((uint8_t)((word & 0xFF00) >> 8)); - // m_code.push_back((uint8_t)(word & 0x00FF)); - // opType = parseOperand(st.next(), word); - // if (opType != eOperandType::Register) - // { - // std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; - // exit(0); - // return; - // } - // m_code.push_back((uint8_t)word); - // return; - // } - // else - // { - // std::cout << "Unknown instruction; " << line << " (" << instEdit << ")\n"; - // exit(0); - // } + ostd::String lineEdit(line); + ostd::String instEdit(lineEdit.new_substr(0, lineEdit.indexOf(" "))); + instEdit.trim().toLower(); + ostd::String opEdit(lineEdit.new_substr(lineEdit.indexOf(" ") + 1)); + opEdit.trim(); + if (STDVEC_CONTAINS(cpuExtensions, "extmov")) + { + uint16_t code_offset = 1; + int16_t word1 = 0x0000; + int16_t word2 = 0x0000; + int16_t word3 = 0x0000; + auto st = opEdit.tokenize(","); + m_code.push_back(data::OpCodes::Ext01); + m_code.push_back(0x00); + if (instEdit == "omov") + { + if (st.count() != 3) + { + std::cout << "Invalid operand number; " << line << "3 -> 3 required\n"; + exit(0); + return; + } + eOperandType opType1 = parseOperand(st.next(), word1); + if (opType1 == eOperandType::DerefRegister) + { + m_code.push_back((uint8_t)word1); + code_offset++; + eOperandType opType2 = parseOperand(st.next(), word2); + ostd::String op3 = st.next(); + bool word_offset = false; + if (op3.startsWith("word")) + { + op3.substr(4).trim(); + word_offset = true; + } + eOperandType opType3 = parseOperand(op3, word3); + switch (opType2) + { + case eOperandType::Immediate: + case eOperandType::Label: + m_code.push_back((uint8_t)((word2 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word2 & 0x00FF)); + code_offset += 2; + break; + case eOperandType::DerefRegister: + m_code.push_back((uint8_t)word2); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + switch (opType3) + { + case eOperandType::Immediate: + case eOperandType::Label: + if (word_offset) + { + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_dreg_immoffw; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wdreg_in_dreg_immoffw; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)((word3 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word3 & 0x00FF)); + code_offset += 2; + } + else + { + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_dreg_immoffb; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wdreg_in_dreg_immoffb; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)word3); + code_offset++; + } + break; + case eOperandType::Register: + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_dreg_regoff; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wdreg_in_dreg_regoff; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)word3); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + } + else if (opType1 == eOperandType::DerefMemory) + { + m_code.push_back((uint8_t)((word1 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word1 & 0x00FF)); + code_offset += 2; + eOperandType opType2 = parseOperand(st.next(), word2); + ostd::String op3 = st.next(); + bool word_offset = false; + if (op3.startsWith("word")) + { + op3.substr(4).trim(); + word_offset = true; + } + eOperandType opType3 = parseOperand(op3, word3); + switch (opType2) + { + case eOperandType::Immediate: + case eOperandType::Label: + m_code.push_back((uint8_t)((word2 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word2 & 0x00FF)); + code_offset += 2; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + switch (opType3) + { + case eOperandType::Immediate: + case eOperandType::Label: + if (word_offset) + { + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_mem_immoffw; + m_code.push_back((uint8_t)((word3 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word3 & 0x00FF)); + code_offset += 2; + } + else + { + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_mem_immoffb; + m_code.push_back((uint8_t)word3); + code_offset++; + } + break; + case eOperandType::Register: + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::wimm_in_mem_regoff; + m_code.push_back((uint8_t)word3); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + } + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> DerefRegister or Pointer required\n"; + exit(0); + return; + } + } + else if (instEdit == "omovb") + { + if (st.count() != 3) + { + std::cout << "Invalid operand number; " << line << "3 -> 3 required\n"; + exit(0); + return; + } + eOperandType opType1 = parseOperand(st.next(), word1); + if (opType1 == eOperandType::DerefRegister) + { + m_code.push_back((uint8_t)word1); + code_offset++; + eOperandType opType2 = parseOperand(st.next(), word2); + ostd::String op3 = st.next(); + bool word_offset = false; + if (op3.startsWith("word")) + { + op3.substr(4).trim(); + word_offset = true; + } + eOperandType opType3 = parseOperand(op3, word3); + switch (opType2) + { + case eOperandType::Immediate: + case eOperandType::Label: + m_code.push_back((uint8_t)word2); + code_offset += 1; + break; + case eOperandType::DerefRegister: + m_code.push_back((uint8_t)word2); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + switch (opType3) + { + case eOperandType::Immediate: + case eOperandType::Label: + if (word_offset) + { + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_dreg_immoffw; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bdreg_in_dreg_immoffw; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)((word3 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word3 & 0x00FF)); + code_offset += 2; + } + else + { + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_dreg_immoffb; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bdreg_in_dreg_immoffb; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)word3); + code_offset++; + } + break; + case eOperandType::Register: + if (opType2 == eOperandType::Immediate || opType2 == eOperandType::Label) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_dreg_regoff; + else if (opType2 == eOperandType::DerefRegister) + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bdreg_in_dreg_regoff; + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + } + m_code.push_back((uint8_t)word3); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + } + else if (opType1 == eOperandType::DerefMemory) + { + m_code.push_back((uint8_t)((word1 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word1 & 0x00FF)); + code_offset += 2; + eOperandType opType2 = parseOperand(st.next(), word2); + ostd::String op3 = st.next(); + bool word_offset = false; + if (op3.startsWith("word")) + { + op3.substr(4).trim(); + word_offset = true; + } + eOperandType opType3 = parseOperand(op3, word3); + switch (opType2) + { + case eOperandType::Immediate: + case eOperandType::Label: + m_code.push_back((uint8_t)word2); + code_offset += 1; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + switch (opType3) + { + case eOperandType::Immediate: + case eOperandType::Label: + if (word_offset) + { + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_mem_immoffw; + m_code.push_back((uint8_t)((word3 & 0xFF00) >> 8)); + m_code.push_back((uint8_t)(word3 & 0x00FF)); + code_offset += 2; + } + else + { + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_mem_immoffb; + m_code.push_back((uint8_t)word3); + code_offset++; + } + break; + case eOperandType::Register: + m_code[m_code.size() - code_offset] = hw::cpuext::ExtMov::OpCodes::bimm_in_mem_regoff; + m_code.push_back((uint8_t)word3); + code_offset++; + break; + default: + std::cout << "Invalid operand type; " << line << " (" << opEdit << ")\n"; + exit(0); + break; + } + } + else + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> DerefRegister or Pointer required\n"; + exit(0); + return; + } + } + else if (instEdit == "movo") + { + } + else if (instEdit == "movbo") + { + } + else + { + std::cout << "Unknown instruction; " << line << " (" << instEdit << ")\n"; + exit(0); + } + } + else if (instEdit == "omov" || instEdit == "omovb" || instEdit == "movo" || instEdit == "movbo") + { + std::cout << "ExtMov instruction detected, please add '--extmov' flag to dasm.\n"; + exit(0); + } } void Assembler::combineDataAndCode(void) diff --git a/src/assembler/Assembler.hpp b/src/assembler/Assembler.hpp index fd086b1..e515852 100644 --- a/src/assembler/Assembler.hpp +++ b/src/assembler/Assembler.hpp @@ -94,6 +94,7 @@ namespace dragon bool verbose { false }; bool save_exports { false }; ostd::String disassembly_file_path { "" }; + std::vector cpu_extensions; }; public: @@ -161,6 +162,7 @@ namespace dragon public: inline static bool saveExports { false }; + inline static std::vector cpuExtensions; }; } } \ No newline at end of file diff --git a/src/assembler/assembler_main.cpp b/src/assembler/assembler_main.cpp index 9f5722a..b1699b0 100644 --- a/src/assembler/assembler_main.cpp +++ b/src/assembler/assembler_main.cpp @@ -9,6 +9,7 @@ int main(int argc, char** argv) return rValue; auto& args = dragon::code::Assembler::Application::args; dragon::code::Assembler::saveExports = args.save_exports; + dragon::code::Assembler::cpuExtensions = args.cpu_extensions; dragon::code::Assembler::assembleToFile(args.source_file_path, args.dest_file_path); if (args.verbose) dragon::code::Assembler::printProgramInfo(); diff --git a/src/hardware/CPUExtensions.cpp b/src/hardware/CPUExtensions.cpp index d3022ac..fb09b03 100644 --- a/src/hardware/CPUExtensions.cpp +++ b/src/hardware/CPUExtensions.cpp @@ -167,7 +167,7 @@ namespace dragon uint8_t dest_dreg = vcpu.fetch8(); int16_t src_mem = vcpu.readRegister(vcpu.fetch8()); uint16_t offset = vcpu.fetch16(); - + uint16_t dest_mem = vcpu.readRegister(dest_dreg); mem.write16(dest_mem + offset, mem.read16(src_mem)); }