From 085bdbc75cc34cdd7cee723c42411ae400877f6b Mon Sep 17 00:00:00 2001 From: OmniaX-dev Date: Fri, 12 Jan 2024 22:47:09 +0100 Subject: [PATCH] Added instruction --- build.nr | 2 +- compile | 0 count_lines.sh | 0 extra/dragon/bios.bin | Bin 4096 -> 4096 bytes extra/dss/bios/bios.dss | 29 ++++++++++++-- extra/dss/bios/data.dss | 49 +++++++++++++++++++++++ extra/dss/newTest.dss | 2 +- extra/font.bmp | Bin extra/font_big.bmp | Bin extra/make | 0 extra/make_and_debug | 0 extra/make_and_run | 0 src/assembler/Assembler.cpp | 26 +++++++++++++ src/debugger/Debugger.cpp | 73 +++++++++++++++++++++++++++++++---- src/hardware/VirtualCPU.cpp | 16 ++++++++ src/runtime/ConfigLoader.cpp | 2 +- src/tools/GlobalData.hpp | 10 ++++- 17 files changed, 194 insertions(+), 15 deletions(-) mode change 100644 => 100755 compile mode change 100644 => 100755 count_lines.sh create mode 100644 extra/dss/bios/data.dss mode change 100644 => 100755 extra/font.bmp mode change 100644 => 100755 extra/font_big.bmp mode change 100644 => 100755 extra/make mode change 100644 => 100755 extra/make_and_debug mode change 100644 => 100755 extra/make_and_run diff --git a/build.nr b/build.nr index 7bb9a89..4f66854 100644 --- a/build.nr +++ b/build.nr @@ -1 +1 @@ -1578 +1579 diff --git a/compile b/compile old mode 100644 new mode 100755 diff --git a/count_lines.sh b/count_lines.sh old mode 100644 new mode 100755 diff --git a/extra/dragon/bios.bin b/extra/dragon/bios.bin index 7d25a2b36e0d460917b2d1382829c768c62044bc..e0fb35ad3b43e255b830195a88b4bb3c582b7ba7 100644 GIT binary patch literal 4096 zcmeH_v2GJV5QhKV^{vU+LVIhUp}eF(wh-WeNGJ~k1r3~S*&PKEf&z`089jt zn)$MBPBAexE?AtH80|&MPO(#qHY>p@U8z#d;^KMj`gzT)lw7o*Ef-N7=^W^ZZ_gpT zDQe?otZNP*VH~~#4nH6Y{Mt??HnZEwl;fr3kfYB>n|!>M$T3v zxy#>!)11>;noMwojASaO)v#-2z`C+|n%C(s|zZGwtP?~)nEN^_w@ z{(9mhCN<7SRq z+#3~gIFenDyqysnCx^hk2E`SE9mIopRLWii1t5sSjJa;raWhRvt})uK;(;~4K8 zbF7GU%L)y_LRXjxUE?FAn@Z7(;-Xd-#zl`U)E1UGvIECd5}lS!)U)2OgTRM!0jQ<& zORE3TA2a7*SB))i2{X3+dFmuuSPo&IxRAOeRz0(Aaz|BqnY`0_|1D(QF`_)6#Pd}7 zB}T%lY}x?>9n({>`-xh@sj7>r13LyB=FGN6t!WYtO)gdOQMAi0S*57`&~VQQ+Z_&a cK-qA@qE3LsD%+vXwefrIAJl$+@}v&G0op)R0ssI2 diff --git a/extra/dss/bios/bios.dss b/extra/dss/bios/bios.dss index 0bf18c8..059263c 100644 --- a/extra/dss/bios/bios.dss +++ b/extra/dss/bios/bios.dss @@ -77,12 +77,14 @@ mov R10, 0x02 int 0x30 - ## MBR Loading //TODO: Figure out why and is not working + ## MBR Loading and FL, 0b1111111111111110 ## Disable interrupts + mov FL, ACC push 0 call $_load_mbr_data_block or FL, 0b0000000000000001 ## Enable interrupts - ## ---- //TODO: Figure out why or is not working + mov FL, ACC + ## ---- jmp MemoryAddresses.MBR ## Jump to start of MBR in memory hlt ## Just in case somehow execution reaches this point @@ -194,7 +196,6 @@ _int_30_store_string_text_single: inc R9 movb ACC, *R9 jne $_int_30_store_string_text_single, 0 - debug_break jmp $_int_30_end @@ -252,6 +253,21 @@ _set_interrupt_vector_entry_end: _print_integer: mov R1, 0 arg ACC + mov R3, 0 ## Used as boolean, 0 = positive, 1 = negative + jle $_print_integer_not_negative, 0 + mov R3, 1 + jeq $_print_integer_overflow_case, 0x8000 + neg ACC + jmp $_print_integer_loop +_print_integer_overflow_case: ## Hardcoded for -32768 (0x8000) + push 56 + push 54 + push 55 + push 50 + push 51 + mov R1, 5 + jmp $_print_integer_loop_end +_print_integer_not_negative: jne $_print_integer_loop, 0 push 48 ## '0' ASCII is 48 inc R1 @@ -266,12 +282,17 @@ _print_integer_loop: mov ACC, R2 jmp $_print_integer_loop _print_integer_loop_end: + mov ACC, R3 + jne $_print_integer_no_sign, 1 + push 45 ## '-' ASCII is 45 + inc R1 +_print_integer_no_sign: pop R9 dec R1 movb [VGA_Registers.TEXT_SINGLE_CHAR], R9 movb [VGA_Registers.SIGNAL], reg(S_REG_1) mov ACC, R1 - jne $_print_integer_loop_end, 0 + jne $_print_integer_no_sign, 0 ret diff --git a/extra/dss/bios/data.dss b/extra/dss/bios/data.dss new file mode 100644 index 0000000..72874a7 --- /dev/null +++ b/extra/dss/bios/data.dss @@ -0,0 +1,49 @@ +@guard _DATA_DSS_ + +## ============================= Memory Mapped Devices and Registers ============================= +@group MemoryAddresses + MBR 0x1380 + INT_VEC 0x1080 + DISK_INTERFACE 0x1580 + RAM 0x1740 + CMOS 0x1000 + VGA 0x1600 +@end + +@group CMOS_Settings + BOOT_DISK { MemoryAddresses.CMOS + 0x0010 } +@end + +@group VGA_Registers + VIDEO_MODE { MemoryAddresses.VGA + 0x0000 } + SIGNAL { MemoryAddresses.VGA + 0x0003 } + TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 } + + BUFF_START { MemoryAddresses.VGA + 0x00E0 } +@end + +@group VGA_VideoModes + TEXT_SINGLE_COLOR 0x00 +@end + +@group Sig_VGA_Text_Single_Color + CONTINUE 0x00 + PRINT_CHAR 0x02 + STORE_CHAR 0x03 + PRINT_FLUSH_BUFF 0x04 + FLUSH_BUFF 0x05 + PRINT_BUFF 0x06 + + REFRESH_SCREEN 0xE0 + CLEAR_SCREEN 0xE1 +@end + +@define S_REG_1 0x07 +@define S_REG_2 0x08 +@define S_REG_3 0x09 +## =============================================================================================== + +.data + $_bios_name "DragonBIOS" + $_bios_version_number_maj 0x00, 0x00 + $_bios_version_number_min 0x00, 0x03 \ No newline at end of file diff --git a/extra/dss/newTest.dss b/extra/dss/newTest.dss index ad0b86b..d854d9c 100644 --- a/extra/dss/newTest.dss +++ b/extra/dss/newTest.dss @@ -10,7 +10,7 @@ $string "Hello World!!" .code - mov R1, 99 ## Zero the counter + mov R1, 0x7FF0 ## Zero the counter infinite_loop: inc R1 ## Increment the counter div R1, 10 ## Divide the counter by 10 diff --git a/extra/font.bmp b/extra/font.bmp old mode 100644 new mode 100755 diff --git a/extra/font_big.bmp b/extra/font_big.bmp old mode 100644 new mode 100755 diff --git a/extra/make b/extra/make old mode 100644 new mode 100755 diff --git a/extra/make_and_debug b/extra/make_and_debug old mode 100644 new mode 100755 diff --git a/extra/make_and_run b/extra/make_and_run old mode 100644 new mode 100755 diff --git a/src/assembler/Assembler.cpp b/src/assembler/Assembler.cpp index 2a8df79..2ce2570 100644 --- a/src/assembler/Assembler.cpp +++ b/src/assembler/Assembler.cpp @@ -959,6 +959,32 @@ namespace dragon m_code.push_back((uint8_t)word); return; } + else if (instEdit == "neg") + { + eOperandType opType = parseOperand(opEdit, word); + if (opType != eOperandType::Register) + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; + exit(0); + return; + } + m_code.push_back(data::OpCodes::NegReg); + m_code.push_back((uint8_t)word); + return; + } + else if (instEdit == "negb") + { + eOperandType opType = parseOperand(opEdit, word); + if (opType != eOperandType::Register) + { + std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; + exit(0); + return; + } + m_code.push_back(data::OpCodes::NegByteReg); + m_code.push_back((uint8_t)word); + return; + } else if (instEdit == "jmp") { m_code.push_back(data::OpCodes::Jmp); diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index 55b8255..b3be0e3 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -190,7 +190,7 @@ namespace dragon void Debugger::Display::printPrompt(void) { - out.fg(ostd::ConsoleColors::Magenta).p(" (ddb) #/> ").fg(ostd::ConsoleColors::White); + out.fg(ostd::ConsoleColors::Magenta).p(" (ddb) #/> ").fg(ostd::ConsoleColors::White).flush(); } void Debugger::Display::printStep(void) @@ -275,17 +275,17 @@ namespace dragon str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|=====|===========|===========|"); str.add("\n"); - str.add("| RV: |*%PREV_RV%**************************|**%CURR_RV%*************************|"); + str.add("| RV: |*%PREV_RV%**************************|**%CURR_RV%*************************| S1 |*%PREV_S1%*|*%CURR_S1*%|"); str.add("\n"); - str.add("|---------------|------------------------------------|------------------------------------|"); + str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| PP: |*%PREV_PP%**************************|**%CURR_PP%*************************|"); + str.add("| PP: |*%PREV_PP%**************************|**%CURR_PP%*************************| S2 |*%PREV_S2%*|*%CURR_S2%*|"); str.add("\n"); - str.add("|---------------|------------------------------------|------------------------------------|"); + str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| FL: |*%PREV_FL%**************************|**%CURR_FL%*************************|"); + str.add("| FL: |*%PREV_FL%**************************|**%CURR_FL%*************************| S3 |*%PREV_S3%*|*%CURR_S3%*|"); str.add("\n"); - str.add("|---------------|------------------------------------|------------------------------------|"); + str.add("|---------------|------------------------------------|------------------------------------|=====|===========|===========|"); str.add("\n"); str.add("| ACC: |*%PREV_ACC%*************************|**%CURR_ACC%************************|"); str.add("\n"); @@ -788,12 +788,71 @@ namespace dragon str.replaceAll("%CURR_R10%", tmpStyle); } + //Special Registers + { + tmp = " ", tmpStyle = ""; + tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::S1], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_S1%", tmpStyle); + tmp = " "; + tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::S1], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + if (minfo.currentInstructionRegisters[dragon::data::Registers::S1] != minfo.previousInstructionRegisters[dragon::data::Registers::S1]) + tmpStyle = "[@@style foreground:Black,background:BrightRed]"; + else + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_S1%", tmpStyle); + + + + + tmp = " ", tmpStyle = ""; + tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::S2], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_S2%", tmpStyle); + + tmp = " "; + tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::S2], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + if (minfo.currentInstructionRegisters[dragon::data::Registers::S2] != minfo.previousInstructionRegisters[dragon::data::Registers::S2]) + tmpStyle = "[@@style foreground:Black,background:BrightRed]"; + else + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_S2%", tmpStyle); + + + + + tmp = " ", tmpStyle = ""; + tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::S3], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_S3%", tmpStyle); + + tmp = " "; + tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::S3], true, 2)); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + if (minfo.currentInstructionRegisters[dragon::data::Registers::S3] != minfo.previousInstructionRegisters[dragon::data::Registers::S3]) + tmpStyle = "[@@style foreground:Black,background:BrightRed]"; + else + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_S3%", tmpStyle); + } ostd::RegexRichString rgxstr(str); rgxstr.fg("InstAddr|Code|StackFrame|DBG BRK|INT Handler|BIOS Mode|SubRoutine", "Magenta"); rgxstr.fg("IP|SP|FP|RV|PP|FL|ACC", "Cyan"); rgxstr.fg("R10|R2|R3|R4|R5|R6|R7|R8|R9|R1", "BrightGreen"); + rgxstr.fg("S1|S2|S3", "BrightRed"); rgxstr.fg("PREV", "Red"); rgxstr.fg("CURR", "Green"); out.pStyled(rgxstr); diff --git a/src/hardware/VirtualCPU.cpp b/src/hardware/VirtualCPU.cpp index 7f7a530..4768678 100644 --- a/src/hardware/VirtualCPU.cpp +++ b/src/hardware/VirtualCPU.cpp @@ -546,6 +546,22 @@ namespace dragon writeRegister(data::Registers::ACC, ~value); } break; + case data::OpCodes::NegReg: + { + uint8_t regAddr = fetch8(); + int16_t value = readRegister(regAddr); + value *= -1; + writeRegister(regAddr, value); + } + break; + case data::OpCodes::NegByteReg: + { + uint8_t regAddr = fetch8(); + int8_t value = (int8_t)readRegister(regAddr); + value *= -1; + writeRegister(regAddr, (int16_t)(0x00FF & value)); + } + break; case data::OpCodes::JmpNotEqImm: { uint16_t addr = fetch16(); diff --git a/src/runtime/ConfigLoader.cpp b/src/runtime/ConfigLoader.cpp index 2e21432..fe26747 100644 --- a/src/runtime/ConfigLoader.cpp +++ b/src/runtime/ConfigLoader.cpp @@ -7,7 +7,7 @@ namespace dragon const tMachineConfig MachineConfigLoader::loadConfig(const ostd::String& configFilePath) { tMachineConfig config; - ostd::TextFileBuffer file(configFilePath); + ostd::TextFileBuffer file(configFilePath.cpp_str()); if (!file.exists()) return config; auto lines = file.getLines(); for (auto& line : lines) diff --git a/src/tools/GlobalData.hpp b/src/tools/GlobalData.hpp index bea96f2..01462ec 100644 --- a/src/tools/GlobalData.hpp +++ b/src/tools/GlobalData.hpp @@ -161,7 +161,9 @@ namespace dragon inline static constexpr uint8_t PP = 0x04; inline static constexpr uint8_t FL = 0x05; inline static constexpr uint8_t ACC = 0x06; - //0x07, 0x08, 0x09 Are hidden registers used internally, but can be normally accessed by address + inline static constexpr uint8_t S1 = 0x07; + inline static constexpr uint8_t S2 = 0x08; + inline static constexpr uint8_t S3 = 0x09; inline static constexpr uint8_t R1 = 0x0A; inline static constexpr uint8_t R2 = 0x0B; inline static constexpr uint8_t R3 = 0x0C; @@ -250,6 +252,8 @@ namespace dragon inline static constexpr uint8_t XorRegImm = 0x68; inline static constexpr uint8_t XorRegReg = 0x69; inline static constexpr uint8_t NotReg = 0x6A; + inline static constexpr uint8_t NegReg = 0x6B; + inline static constexpr uint8_t NegByteReg = 0x6C; inline static constexpr uint8_t JmpNotEqImm = 0x70; inline static constexpr uint8_t JmpNotEqReg = 0x71; @@ -318,6 +322,8 @@ namespace dragon 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"; @@ -394,6 +400,8 @@ namespace dragon 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;