From 758b1e41b8777528576848d6371b03731bdbd905 Mon Sep 17 00:00:00 2001 From: OmniaX Date: Mon, 8 Jan 2024 14:01:17 +0100 Subject: [PATCH] [0.1.1544] - Remove BIOSVideo interface, because it was too messy + Fixed long time bug --- CMakeLists.txt | 6 - build.nr | 2 +- compile | 20 +- extra/dragon info/DragonVM Memory Structure | 128 ++--- extra/dragon info/Interrupts | 59 +- extra/dragon/bios.bin | Bin 1024 -> 4096 bytes extra/dragon/disk1.dr | Bin 4194304 -> 4194304 bytes extra/dss/bios.dss | 28 +- extra/dss/handlerTest.dss | 4 +- extra/dss/mbr.dss | 4 +- extra/dss/newTest.dss | 73 ++- extra/dss/test.dss | 2 +- extra/make_and_run | 8 +- src/assembler/Assembler.cpp | 266 ++++----- src/assembler/Assembler.hpp | 2 + src/assembler/assembler_main.cpp | 14 +- src/debugger/Debugger.cpp | 596 ++++++++++++-------- src/debugger/Debugger.hpp | 24 +- src/debugger/DisassemblyLoader.cpp | 29 +- src/debugger/debugger_main.cpp | 85 ++- src/gui/DebuggerWindow.cpp | 6 - src/gui/DebuggerWindow.hpp | 9 - src/gui/RawTextRenderer.cpp | 6 +- src/gui/VirtualConsole.cpp | 158 ------ src/gui/VirtualConsole.hpp | 64 --- src/gui/VirtualConsoleOutputHandler.cpp | 303 ---------- src/gui/VirtualConsoleOutputHandler.hpp | 99 ---- src/gui/Window.cpp | 122 ++-- src/gui/Window.hpp | 92 ++- src/gui/widgets/VirtualConsoleWidget.cpp | 128 ----- src/gui/widgets/VirtualConsoleWidget.hpp | 67 --- src/gui/widgets/Widget.hpp | 25 - src/hardware/MemoryMapper.cpp | 2 +- src/hardware/MemoryMapper.hpp | 1 + src/hardware/VirtualCPU.cpp | 86 ++- src/hardware/VirtualCPU.hpp | 13 + src/hardware/VirtualHardDrive.cpp | 4 +- src/hardware/VirtualIODevices.cpp | 87 +-- src/hardware/VirtualIODevices.hpp | 28 - src/runtime/ConfigLoader.cpp | 14 +- src/runtime/ConfigLoader.hpp | 2 +- src/runtime/DragonRuntime.cpp | 189 ++++--- src/runtime/DragonRuntime.hpp | 26 +- src/runtime/runtime_main.cpp | 12 +- src/tools/GlobalData.hpp | 41 +- src/tools/SDLInclude.hpp | 3 +- src/tools/tools_main.cpp | 50 +- 47 files changed, 1236 insertions(+), 1751 deletions(-) delete mode 100644 src/gui/DebuggerWindow.cpp delete mode 100644 src/gui/DebuggerWindow.hpp delete mode 100644 src/gui/VirtualConsole.cpp delete mode 100644 src/gui/VirtualConsole.hpp delete mode 100644 src/gui/VirtualConsoleOutputHandler.cpp delete mode 100644 src/gui/VirtualConsoleOutputHandler.hpp delete mode 100644 src/gui/widgets/VirtualConsoleWidget.cpp delete mode 100644 src/gui/widgets/VirtualConsoleWidget.hpp delete mode 100644 src/gui/widgets/Widget.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b4016c..d7d152f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,10 +30,7 @@ list(APPEND RUNTIME_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp ${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/widgets/VirtualConsoleWidget.cpp ${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsoleOutputHandler.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsole.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp @@ -48,11 +45,8 @@ list(APPEND DEBUGGER_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/debugger/DisassemblyLoader.cpp ${CMAKE_CURRENT_LIST_DIR}/src/debugger/Debugger.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/DebuggerWindow.cpp ${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/widgets/VirtualConsoleWidget.cpp ${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/gui/VirtualConsoleOutputHandler.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp diff --git a/build.nr b/build.nr index 57c7c05..df9d396 100644 --- a/build.nr +++ b/build.nr @@ -1 +1 @@ -1542 +1544 diff --git a/compile b/compile index 266a8e8..b6c1597 100644 --- a/compile +++ b/compile @@ -6,10 +6,26 @@ if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then cmake -B bin -S ./ cd bin make - cd .. + if [ $? -eq 0 ]; then + cd .. + typeset -i build_number=$(cat build.nr) + ((build_number++)) + truncate -s 0 build.nr + echo $build_number >> build.nr + else + cd .. + fi elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then cmake -B bin -S ./ -G "MinGW Makefiles" cd bin mingw32-make.exe - cd .. + if [ $? -eq 0 ]; then + cd .. + typeset -i build_number=$(cat build.nr) + ((build_number++)) + truncate -s 0 build.nr + echo $build_number >> build.nr + else + cd .. + fi fi \ No newline at end of file diff --git a/extra/dragon info/DragonVM Memory Structure b/extra/dragon info/DragonVM Memory Structure index 4b39e89..2499593 100644 --- a/extra/dragon info/DragonVM Memory Structure +++ b/extra/dragon info/DragonVM Memory Structure @@ -1,79 +1,69 @@ -0x0000 - BIOS (1024 Bytes) -0x03FF +0x0000 BIOS (4096 Bytes) +0x0FFF ------- -0x0400 - CMOS (128 Bytes) - BootDisk: 0x0010 -0x047F +0x1000 CMOS (128 Bytes) + BootDisk: 0x0010 +0x107F ------- -0x0480 - INTERRUPT VECTOR (512 Bytes) -0x067F +0x1080 INTERRUPT VECTOR (512 Bytes) + Status: 1 Byte + 0xFF: Enabled + 0x00: Disabled + Handler Address: 2 Byte + ...Repeat... +0x127F ------- -0x0680 - KEYBOARD MAPPING (224 Bytes) -0x075F +0x1280 KEYBOARD MAPPING (224 Bytes) +0x135F ------- -0x0760 - MOUSE MAPPING (32 Bytes) -0x077F +0x1360 MOUSE MAPPING (32 Bytes) +0x137F ------- -0x0780 - BIOS VIDEO MEMORY (3840 Bytes) - 0x000: Clear Color (1 Byte) - 0x001: Palette (1 Byte) - 0x002: UseTransparencyOn0x5 (1 Byte) - 0x003: Signal (1 Byte) - 0x00: Continue - 0x01: Clear Screen - 0x03C - 0xEFF: 3780 Bytes - Structure: - 90x21 characters - 1 Byte ascii - 1 byte: 4 Bits background/4 bits foreground -0x167F +0x1380 BOOTLOADER (512 Bytes) +0x157F ------- -0x1680 - BOOTLOADER (512 Bytes) -0x187F +0x1580 DISK INTERFACE (128 Bytes) + Read/Write: + Signal: 1 Byte + 0x00: Start Operation + 0x01: Cancel Current Operation + 0xFF: Ignore + Mode: 1 Byte + 0x00: Read + 0x01: Write + Disk: 1 Byte + Sector: 2 Bytes + Address: 2 Bytes + DataSize: 2 Bytes + DataAddress: 2 Byte + ReadOnly: + Status: 1 Byte + 0x00: Free + 0x01: Writing + 0x02: Reading + CurrentDisk: 1 Byte + CurrentSector: 2 Bytes + CurrentAddress: 2 Bytes + RestDataSize: 2 Bytes + SourceData: 2 Bytes + Free: 107 Byte +0x15FF ------- -0x1880 - DISK INTERFACE (128 Bytes) - Read/Write: - Signal: 1 Byte - 0x00: Start Operation - 0x01: Cancel Current Operation - 0xFF: Ignore - Mode: 1 Byte - 0x00: Read - 0x01: Write - Disk: 1 Byte - Sector: 2 Bytes - Address: 2 Bytes - DataSize: 2 Bytes - DataAddress: 2 Byte - ReadOnly: - Status: 1 Byte - 0x00: Free - 0x01: Writing - 0x02: Reading - CurrentDisk: 1 Byte - CurrentSector: 2 Bytes - CurrentAddress: 2 Bytes - RestDataSize: 2 Bytes - SourceData: 2 Bytes - Free: 107 Byte -0x18FF +0x1600 VIDEO CARD INTERFACE (256 Bytes) + 0x00: Video Mode (1 Byte) + 0x00: Single Color + 0x01: 16-color + 0x02: 256-color + 0x03: True Color Mode + 0x01: Clear Color (1 Byte) + 0x02: Palette (1 Byte) + 0x03: Signal (1 Byte) + 0x00: Continue + 0x01: Clear Screen +0x16FF ------- -0x1900 - VIDEO CARD INTERFACE (256 Bytes) -0x19FF +0x1700 GENERIC SERIAL INTERFACE (64 Bytes) +0x173F ------- -0x1A00 - GENERIC SERIAL INTERFACE (64 Bytes) -0x1A3F -------- -0x1A40 - RAM (58815 Bytes) +0x1740 RAM (59583 Bytes) 0xFFFF diff --git a/extra/dragon info/Interrupts b/extra/dragon info/Interrupts index 0fdc97e..ecf25f3 100644 --- a/extra/dragon info/Interrupts +++ b/extra/dragon info/Interrupts @@ -10,61 +10,4 @@ Software Interrupts: Hardware Interrupts: ==================== -0x80: Disk Interface Finished -0x81: BiosVideo Screen Refreshed - - - - -Default Palette BIOS Colors: -==================== -0x0: Black - 0, 0, 0 - #000000 -0x1: Gray - 157, 157, 157 - #9D9D9D -0x2: White - 255, 255, 255 - #FFFFFF -0x3: Red - 190, 38, 51 - #BE2633 -0x4: Pimk - 224, 111, 139 - #E06F8B -OLD -- 0x5: DarkBrown -OLD -- 73, 60, 43 -OLD -- #493C2B -0x5: Transparent - -- -0x6: Brown - 164, 100, 34 - #A46422 -0x7: Orange - 235, 137, 49 - #EB8931 -0x8: Yellow - 247, 226, 107 - #F7E26B -0x9: Dark Green - 47, 80, 42 - #2F502A -0xA: Green - 68, 137, 26 - #44891A -0xB: Slime Green - 163, 206, 39 - #A3CE27 -0xC: Night Blue - 27, 38, 50 - #1B2632 -0xD: Sea Blue - 0, 87, 132 - #005784 -0xE: Sky Blue - 49, 162, 242 - #31A2F2 -0xF: Cloud Blue - 178, 220, 239 - #B2DCEF \ No newline at end of file +0x80: Disk Interface Finished \ No newline at end of file diff --git a/extra/dragon/bios.bin b/extra/dragon/bios.bin index 4e4dbaafa831459f7d7c33d1a5c020941c251663..6f9e6af6c20c9840f21d601e21bc02040580a143 100644 GIT binary patch literal 4096 zcmeIuu};G<5C-7i#Px8K9s2}h+5ri%z`&lqL87S70m|$lZB>Pe5qKD8o`D@60*R#r z8~PTUhyQ$*?}jg8rj?yRRrY-f_5+vJ1GdDyb-4Pj8lc0oihh`!@jYtT9=AY`2o*8T zd0p1!oHr>?d7CoV-La0xx-Tmp(!|)hwrp_H;Vn1miofpgyZjO9&l3(6uW?S+Uhswj zZ-KzO93w*Dy&v*2Z}{O3FTjdP-w+B%=9=u_3X@-2YM?s2Ix3cWsoCfrpTL5qh_3~q grZX}t$Pob%5CIVo0TB=Z5fA|p5CIVofqxbQEwHYR*6lr$9mq zW*u@1@})oX=W8^@)EpC;u$lVkQ}xM(Nx(QdW4ZjvawvJJ$4zf_QgMT+xP^*)qMC<^ zU%Hu__*KAD-v%6bz2|Pv8<+WpU@vUpa*j&g2N6#G)OHvCMDRRkCvCLN{E{1)2H Q!c4sA1&28_@Q)k#1$XK( i7-NDdW|(7vC01BtgDrO0;d=_Vp)><@7*Y;fJ@qJnHF+3$t zB?kU01Q0|BCc=myiWuTZAc+*xu#iC(IpkrZfFeq8P(}q+)KEtQO|;NP2VL~g#{ff& iFvbK^%rM6SORTWQ23zc~#{oy2aK;5!+}=v=zW)Qm{4~D+ diff --git a/extra/dss/bios.dss b/extra/dss/bios.dss index 1b014d8..d150c9d 100644 --- a/extra/dss/bios.dss +++ b/extra/dss/bios.dss @@ -1,25 +1,21 @@ ## ============================= Memory Mapped Devices and Registers ============================= -@define MBR_START_ADDRESS 0x1680 -@define INT_VEC_START_ADDRESS 0x0480 -@define DISK_INTERFACE_START_ADDRESS 0x1880 -@define MEMORY_START_ADDRESS 0x1A40 -@define CMOS_START_ADDRESS 0x0400 -@define BIOS_VIDEO_START_ADDRESS 0x0780 -@define BIOS_VIDEO_MEMORY_START_ADDRESS 0x07BC -@define BIOS_VIDEO_MEMORY_END_ADDRESS 0x167F - -@define _BIOS_VIDEO_REG_CLEAR_COLOR {BIOS_VIDEO_START_ADDRESS + 0x0000} -@define _BIOS_VIDEO_REG_SIGNAL {BIOS_VIDEO_START_ADDRESS + 0x0003} +@define MBR_START_ADDRESS 0x1380 +@define INT_VEC_START_ADDRESS 0x1080 +@define DISK_INTERFACE_START_ADDRESS 0x1580 +@define MEMORY_START_ADDRESS 0x1740 +@define CMOS_START_ADDRESS 0x1000 ## =============================================================================================== @define _CMOS_REG_BOOT_DISK {CMOS_START_ADDRESS + 0x0010} .load 0x0000 ## BIOS is mapped to address 0x0000 in memory .data - $bios_version_number 0x00, 0x01 ## BIOS Version stored in memory + $bios_version_number 0x04, 0x01 ## BIOS Version stored in memory ## ============================= BIOS Program ============================= .code + ## mov FL, 0 + ## jmp 0x1740 mov FL, 0b0000000000000001 ## Zero the FL Register and enable interrupts movb [{INT_VEC_START_ADDRESS + (0x20 * 3)}], 0xFF ## Setting up int 0x20 handler mov [{INT_VEC_START_ADDRESS + (0x20 * 3) + 1}], $_int_20_handler ## -- @@ -38,6 +34,7 @@ call $_load_mbr_data_block ## ---- + debug_break jmp MBR_START_ADDRESS ## Jump to start of MBR in memory hlt ## Just in case somehow execution reaches this point ## ======================================================================== @@ -89,7 +86,7 @@ _int_30_handler: jeq $_int_30_clear_screen, 0x0000 jmp $_int_30_end _int_30_clear_screen: - movb [_BIOS_VIDEO_REG_SIGNAL], 0x01 ## Signal = ClearScreen + nop _int_30_end: rti ## ================================================================================== @@ -101,8 +98,7 @@ _load_mbr_data_block: movb [{DISK_INTERFACE_START_ADDRESS + 0x2}], R1 ## Disk = Default mov [{DISK_INTERFACE_START_ADDRESS + 0x3}],0x0000 ## Sector = 0x0000 mov [{DISK_INTERFACE_START_ADDRESS + 0x5}],0x0000 ## Address = 0x0000 (Start of Disk) - ##//TODO: currently set to 20 instead of 512, for debugging purposes - mov [{DISK_INTERFACE_START_ADDRESS + 0x7}], 20 ## Size = 512 (Size of MBR is 512 bytes) + mov [{DISK_INTERFACE_START_ADDRESS + 0x7}], 20 ## Size = 512 (Size of MBR is 512 bytes) mov [{DISK_INTERFACE_START_ADDRESS + 0x9}], MBR_START_ADDRESS ## MemoryAddress = MBR Address in memory movb [DISK_INTERFACE_START_ADDRESS], 0x00 ## Signal = Start _load_mbr_data_block_wait_loop: @@ -137,4 +133,4 @@ _set_interrupt_vector_entry_end: mov *R1, ACC ret -.fixed 1024, 0x00 ## BIOS Needs to be 1024 Bytes exactly +.fixed 4096, 0x00 ## BIOS Needs to be 4096 Bytes exactly diff --git a/extra/dss/handlerTest.dss b/extra/dss/handlerTest.dss index 4e8e5e2..b06d314 100644 --- a/extra/dss/handlerTest.dss +++ b/extra/dss/handlerTest.dss @@ -1,4 +1,4 @@ -.load 0x1A40 +.load 0x1740 ##@struct Rectangle { ## width:2, @@ -20,14 +20,12 @@ ## $rect => Rectangle .code - debug_break infinite_loop: push 0 call $clear_screen ## mov $rect.x, 200 - ## debug_break push $string push 1 diff --git a/extra/dss/mbr.dss b/extra/dss/mbr.dss index c8b869f..e01c709 100644 --- a/extra/dss/mbr.dss +++ b/extra/dss/mbr.dss @@ -1,7 +1,7 @@ -.load 0x1680 +.load 0x1380 .code - jmp 0x1A40 + jmp 0x1740 hlt .fixed 512, 0x00 diff --git a/extra/dss/newTest.dss b/extra/dss/newTest.dss index 52c1b39..8790c26 100644 --- a/extra/dss/newTest.dss +++ b/extra/dss/newTest.dss @@ -1,15 +1,74 @@ -.load 0x1A40 +.load 0x1740 .data - $v1 0x00, 0x01 - $v2 0x00, 0x01 - $v3 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 + $cursor_pos 0x00, 0x00 + $color 0x02 + $current_video_addr 0x07, 0xBC + + $string "Hello World!!" .code - mov R1, 0xAA - mov R2, 0xBB - mov R3, 0xCC debug_break +infinite_loop: + push 0 + call $clear_screen + + jmp $infinite_loop hlt + +print_string: + mov R1, *PP + dec PP + dec PP + + push R1 + push 1 + call $strlen + mov R2, RV + + push 65 + push 1 + call $print_char + ret + + +strlen: + mov R1, *PP + dec PP + dec PP + mov R2, 0 +_strlen_loop: + movb ACC, *R1 + jeq $_strlen_end_loop, 0 + inc R2 + inc R1 + jmp $_strlen_loop +_strlen_end_loop: + mov RV, R2 + ret + +print_char: + mov R2, *PP + dec PP + dec PP + mov R1, [$current_video_addr] + mov R3, [$cursor_pos] + mul R3, 2 + mov R3, ACC + add R1, R3 + mov R1, ACC + movb *R1, R2 + inc R1 + movb *R1, [$color] + mov R3, [$cursor_pos] + inc R3 + mov [$cursor_pos], R3 + ret + +clear_screen: + mov R10, 0x00 + int 0x30 + ret + .fixed 512, 0x00 \ No newline at end of file diff --git a/extra/dss/test.dss b/extra/dss/test.dss index 6f8b098..d460bb0 100644 --- a/extra/dss/test.dss +++ b/extra/dss/test.dss @@ -1,4 +1,4 @@ -.load 0x1A40 +.load 0x1740 .code mov R1, 0xABCD diff --git a/extra/make_and_run b/extra/make_and_run index 38e8578..7cacc5a 100644 --- a/extra/make_and_run +++ b/extra/make_and_run @@ -1,13 +1,11 @@ #!/bin/bash - printf "${green}\n============================================[ Building Application ]============================================\n\n${clear}" \cp -r ../extra/* ./ if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then make elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then mingw32-make.exe - cp ../../omnia-framework/bin/libostd.dll ./ fi printf "${green}\n=================================================================================================================\n\n" if [ $? -eq 0 ]; then @@ -16,10 +14,10 @@ if [ $? -eq 0 ]; then /bin/bash ./load_mbr cd .. printf "${green}Compiling Test Program...\n" - ./dasm dss/handlerTest.dss -o handlerTest.bin --save-disassembly disassembly/handlerTest.dds + ./dasm dss/newTest.dss -o newTest.bin --save-disassembly disassembly/newTest.dds printf "\n${green}Running Application...\n\n${clear}" - ./ddb config/testMachine.dvm --force-load handlerTest.bin 0x00 --verbose-load --track-step-diff --hide-vdisplay - #./dvm config/testMachine.dvm --debug --force-load newTest.bin 0x00 --verbose-load + ./ddb config/testMachine.dvm --force-load newTest.bin 0x00 --verbose-load --hide-vdisplay + # ./dvm config/testMachine.dvm --debug --force-load newTest.bin 0x00 --verbose-load cp dragon/disk1.dr ../extra/dragon/disk1.dr cp dragon/cmos.dr ../extra/dragon/cmos.dr fi diff --git a/src/assembler/Assembler.cpp b/src/assembler/Assembler.cpp index da38221..6888a87 100644 --- a/src/assembler/Assembler.cpp +++ b/src/assembler/Assembler.cpp @@ -52,7 +52,7 @@ namespace dragon void Assembler::loadSource(ostd::String source) { m_rawSource = source; - m_lines = ostd::StringEditor(source).tokenize("\n").getRawData(); + m_lines = ostd::String(source).tokenize("\n").getRawData(); } ostd::ByteStream Assembler::assembleToFile(ostd::String sourceFileName, ostd::String binaryFileName) @@ -77,21 +77,21 @@ namespace dragon if (m_code.size() == 0 || m_disassembly.size() == 0) return false; ostd::String header_string = "{ DRAGON_DEBUG_DISASSEMBLY }"; uint64_t da_size = 0; - da_size += (header_string.length() + 1) * ostd::tTypeSize::BYTE; + da_size += (header_string.len() + 1) * ostd::tTypeSize::BYTE; da_size += m_disassembly.size() * ostd::tTypeSize::DWORD; //Addresses da_size += m_disassembly.size() * ostd::tTypeSize::BYTE; //Null Termination for (auto& da : m_disassembly) - da_size += da.code.length() * ostd::tTypeSize::BYTE; //Code Strings + da_size += da.code.len() * ostd::tTypeSize::BYTE; //Code Strings ostd::serial::SerialIO serializer(da_size, ostd::serial::SerialIO::tEndianness::BigEndian); ostd::StreamIndex stream_addr = 0; serializer.w_String(stream_addr, header_string); - stream_addr += (header_string.length() + 1) * ostd::tTypeSize::BYTE; + stream_addr += (header_string.len() + 1) * ostd::tTypeSize::BYTE; for (auto& da : m_disassembly) { serializer.w_DWord(stream_addr, da.addr); stream_addr += ostd::tTypeSize::DWORD; serializer.w_String(stream_addr, da.code); - stream_addr += (da.code.length() + 1) * ostd::tTypeSize::BYTE; + stream_addr += (da.code.len() + 1) * ostd::tTypeSize::BYTE; // ostd::ByteStream code_stream = ostd::Utils::stringToByteStream(da.code); // for (int32_t i = 0; i < code_stream.size(); i++) // { @@ -107,7 +107,7 @@ namespace dragon void Assembler::removeComments(void) { std::vector newLines; - ostd::StringEditor lineEdit; + ostd::String lineEdit; for (auto& line : m_lines) { lineEdit = line; @@ -119,7 +119,7 @@ namespace dragon lineEdit = lineEdit.substr(0, lineEdit.indexOf("##")); lineEdit.trim(); } - newLines.push_back(lineEdit.str()); + newLines.push_back(lineEdit); } m_lines.clear(); m_lines = newLines; @@ -141,8 +141,8 @@ namespace dragon }; std::vector defines; std::vector newLines; - ostd::StringEditor lineEdit; - ostd::StringEditor tmpLineEdit; + ostd::String lineEdit; + ostd::String tmpLineEdit; for (auto& line : m_lines) { lineEdit = line; @@ -157,9 +157,9 @@ namespace dragon std::cout << "Invalid @define directive: " << line << "\n"; return; } - ostd::String define_name = lineEdit.substr(0, lineEdit.indexOf(" ")); - define_name = ostd::StringEditor(define_name).trim().str(); - ostd::String define_value = lineEdit.substr(lineEdit.indexOf(" ") + 1); + 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); if (listContainsDefine(defines, define_name)) { std::cout << "Redefinition of @define value: " << line << "\n"; @@ -169,14 +169,14 @@ namespace dragon // std::cout << define_name << ": " << define_value << "\n"; continue; } - newLines.push_back(lineEdit.str()); + newLines.push_back(lineEdit); } for (auto& line : newLines) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); for (int32_t i = defines.size() - 1; i >= 0; i--) lineEdit.replaceAll(defines[i].name, defines[i].value); - line = lineEdit.str(); + line = lineEdit; } m_lines.clear(); m_lines = newLines; @@ -191,7 +191,7 @@ namespace dragon for (auto& line : m_lines) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); if (lineEdit.startsWith(".data")) currentSection = DATA_SECTION; else if (lineEdit.startsWith(".code")) @@ -212,7 +212,7 @@ namespace dragon std::cout << "Invalid .fixed value: " << lineEdit << "\n"; return; } - ostd::StringEditor fixedSizeEdit = lineEdit.substr(0, lineEdit.indexOf(",")); + ostd::String fixedSizeEdit = lineEdit.new_substr(0, lineEdit.indexOf(",")); fixedSizeEdit.trim(); lineEdit = lineEdit.substr(lineEdit.indexOf(",") + 1); lineEdit.trim(); @@ -278,14 +278,14 @@ namespace dragon { for (auto& line : m_rawDataSection) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); tSymbol symbol; if (!lineEdit.startsWith("$") || lineEdit.indexOf(" ") < 2) { std::cout << "Invalid data entry: " << lineEdit << "\n"; continue; } - ostd::StringEditor symbolName = lineEdit.substr(0, lineEdit.indexOf(" ")); + ostd::String symbolName = lineEdit.new_substr(0, lineEdit.indexOf(" ")); symbolName.trim(); lineEdit = lineEdit.substr(lineEdit.indexOf(" ") + 1); lineEdit.trim(); @@ -304,18 +304,18 @@ namespace dragon symbol.bytes.push_back(value); symbol.address = m_currentDataAddr; m_currentDataAddr += 1; - m_symbolTable[symbolName.str()] = symbol; + m_symbolTable[symbolName] = symbol; continue; } else if (lineEdit.startsWith("\"") && lineEdit.endsWith("\"") && lineEdit.len() > 2) { lineEdit = lineEdit.substr(1, lineEdit.len() - 1); - for (auto c : lineEdit.str()) + for (auto c : lineEdit) symbol.bytes.push_back((uint8_t)c); symbol.bytes.push_back((uint8_t)0); //NULL Termination symbol.address = m_currentDataAddr; m_currentDataAddr += lineEdit.len(); - m_symbolTable[symbolName.str()] = symbol; + m_symbolTable[symbolName] = symbol; continue; } else if (lineEdit.contains(",")) @@ -338,7 +338,7 @@ namespace dragon } symbol.address = m_currentDataAddr; m_currentDataAddr += symbol.bytes.size(); - m_symbolTable[symbolName.str()] = symbol; + m_symbolTable[symbolName] = symbol; continue; } else @@ -358,14 +358,14 @@ namespace dragon { for (auto& line : m_rawCodeSection) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); uint32_t commaCount = lineEdit.count(","); uint32_t spaceCount = lineEdit.count(" "); if (lineEdit.endsWith(":") && commaCount == 0 && spaceCount == 0) //Labels { lineEdit = lineEdit.substr(0, lineEdit.len() - 1); lineEdit.trim(); - m_labelTable["$" + lineEdit.str()] = { { }, 0x0000 }; + m_labelTable["$" + lineEdit] = { { }, 0x0000 }; continue; } } @@ -373,55 +373,55 @@ namespace dragon tDisassemblyLine _disassembly_line; for (auto& line : m_rawCodeSection) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); uint32_t commaCount = lineEdit.count(","); uint32_t spaceCount = lineEdit.count(" "); if (lineEdit.endsWith(":") && commaCount == 0 && spaceCount == 0) //Labels { // _disassembly_line.addr = m_dataSize + m_loadAddress + m_code.size() + 3; - // _disassembly_line.code = lineEdit.str(); + // _disassembly_line.code = lineEdit; // m_disassembly.push_back(_disassembly_line); lineEdit = lineEdit.substr(0, lineEdit.len() - 1); lineEdit.trim(); - m_labelTable["$" + lineEdit.str()].address = m_dataSize + m_loadAddress + m_code.size() + 3; + m_labelTable["$" + lineEdit].address = m_dataSize + m_loadAddress + m_code.size() + 3; continue; } else if (commaCount == 0 && spaceCount <= 0) //0 Operands { _disassembly_line.addr = m_dataSize + m_loadAddress + m_code.size() + 3; - ostd::StringEditor _tmp_edit(lineEdit.str()); + ostd::String _tmp_edit(lineEdit); if (_tmp_edit.toLower().trim().startsWith("debug_")) - parseDebugOperands(lineEdit.str()); + parseDebugOperands(lineEdit); else - parse0Operand(lineEdit.str()); - _disassembly_line.code = lineEdit.str(); + parse0Operand(lineEdit); + _disassembly_line.code = lineEdit; m_disassembly.push_back(_disassembly_line); continue; } else if (commaCount == 0) //1 Operands { _disassembly_line.addr = m_dataSize + m_loadAddress + m_code.size() + 3; - lineEdit = replaceSymbols(lineEdit.str()); - parse1Operand(lineEdit.str()); - _disassembly_line.code = lineEdit.str(); + lineEdit = replaceSymbols(lineEdit); + parse1Operand(lineEdit); + _disassembly_line.code = lineEdit; m_disassembly.push_back(_disassembly_line); continue; } else if (commaCount == 1) //2 Operands { _disassembly_line.addr = m_dataSize + m_loadAddress + m_code.size() + 3; - lineEdit = replaceSymbols(lineEdit.str()); - parse2Operand(lineEdit.str()); - _disassembly_line.code = lineEdit.str(); + lineEdit = replaceSymbols(lineEdit); + parse2Operand(lineEdit); + _disassembly_line.code = lineEdit; m_disassembly.push_back(_disassembly_line); continue; } else if (commaCount == 2) // 3 Operands { _disassembly_line.addr = m_dataSize + m_loadAddress + m_code.size() + 3; - lineEdit = replaceSymbols(lineEdit.str()); - parse3Operand(lineEdit.str()); - _disassembly_line.code = lineEdit.str(); + lineEdit = replaceSymbols(lineEdit); + parse3Operand(lineEdit); + _disassembly_line.code = lineEdit; m_disassembly.push_back(_disassembly_line); continue; } @@ -435,22 +435,22 @@ namespace dragon void Assembler::parse0Operand(ostd::String line) { - if (ostd::StringEditor(line).toLower().startsWith("nop")) + if (ostd::String(line).toLower().startsWith("nop")) { m_code.push_back(data::OpCodes::NoOp); return; } - else if (ostd::StringEditor(line).toLower().startsWith("ret")) + else if (ostd::String(line).toLower().startsWith("ret")) { m_code.push_back(data::OpCodes::Ret); return; } - else if (ostd::StringEditor(line).toLower().startsWith("rti")) + else if (ostd::String(line).toLower().startsWith("rti")) { m_code.push_back(data::OpCodes::RetInt); return; } - else if (ostd::StringEditor(line).toLower().startsWith("hlt")) + else if (ostd::String(line).toLower().startsWith("hlt")) { m_code.push_back(data::OpCodes::Halt); return; @@ -459,7 +459,7 @@ namespace dragon void Assembler::parseDebugOperands(ostd::String line) { - if (ostd::StringEditor(line).toLower().startsWith("debug_break")) + if (ostd::String(line).toLower().startsWith("debug_break")) { m_code.push_back(data::OpCodes::DEBUG_Break); return; @@ -468,15 +468,15 @@ namespace dragon void Assembler::parse1Operand(ostd::String line) { - ostd::StringEditor lineEdit(line); - ostd::StringEditor instEdit(lineEdit.substr(0, lineEdit.indexOf(" "))); + ostd::String lineEdit(line); + ostd::String instEdit(lineEdit.new_substr(0, lineEdit.indexOf(" "))); instEdit.trim().toLower(); - ostd::StringEditor opEdit(lineEdit.substr(lineEdit.indexOf(" ") + 1)); + ostd::String opEdit(lineEdit.new_substr(lineEdit.indexOf(" ") + 1)); opEdit.trim(); int16_t word = 0x0000; - if (instEdit.str() == "inc") + if (instEdit == "inc") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Register) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; @@ -487,9 +487,9 @@ namespace dragon m_code.push_back((uint8_t)word); return; } - else if (instEdit.str() == "dec") + else if (instEdit == "dec") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Register) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; @@ -500,9 +500,9 @@ namespace dragon m_code.push_back((uint8_t)word); return; } - else if (instEdit.str() == "push") + else if (instEdit == "push") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType == eOperandType::Immediate || opType == eOperandType::Label) { m_code.push_back(data::OpCodes::PushImm); @@ -521,9 +521,9 @@ namespace dragon } return; } - else if (instEdit.str() == "pop") + else if (instEdit == "pop") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Register) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; @@ -534,10 +534,10 @@ namespace dragon m_code.push_back((uint8_t)word); return; } - else if (instEdit.str() == "call") + else if (instEdit == "call") { m_code.push_back(0x00); - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType == eOperandType::Immediate || opType == eOperandType::Label) { m_code[m_code.size() - 1] = data::OpCodes::CallImm; @@ -556,9 +556,9 @@ namespace dragon } return; } - else if (instEdit.str() == "not") + else if (instEdit == "not") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Register) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Register required\n"; @@ -569,10 +569,10 @@ namespace dragon m_code.push_back((uint8_t)word); return; } - else if (instEdit.str() == "jmp") + else if (instEdit == "jmp") { m_code.push_back(data::OpCodes::Jmp); - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Label && opType != eOperandType::Immediate) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Immediate (or label) required\n"; @@ -583,9 +583,9 @@ namespace dragon m_code.push_back((uint8_t)(word & 0x00FF)); return; } - else if (instEdit.str() == "int") + else if (instEdit == "int") { - eOperandType opType = parseOperand(opEdit.str(), word); + eOperandType opType = parseOperand(opEdit, word); if (opType != eOperandType::Immediate) { std::cout << "Invalid operand type; " << line << " (" << opEdit << ") -> Immediate required\n"; @@ -605,14 +605,14 @@ namespace dragon void Assembler::parse2Operand(ostd::String line) { - ostd::StringEditor lineEdit(line); - ostd::StringEditor instEdit(lineEdit.substr(0, lineEdit.indexOf(" "))); + ostd::String lineEdit(line); + ostd::String instEdit(lineEdit.new_substr(0, lineEdit.indexOf(" "))); instEdit.trim().toLower(); - ostd::StringEditor opEdit(lineEdit.substr(lineEdit.indexOf(" ") + 1)); + ostd::String opEdit(lineEdit.new_substr(lineEdit.indexOf(" ") + 1)); opEdit.trim(); int16_t word = 0x0000; auto st = opEdit.tokenize(","); - if (instEdit.str() == "mov") + if (instEdit == "mov") { m_code.push_back(0x00); int16_t word1 = 0x0000; @@ -711,7 +711,7 @@ namespace dragon } return; } - else if (instEdit.str() == "movb") + else if (instEdit == "movb") { m_code.push_back(0x00); int16_t word1 = 0x0000; @@ -800,7 +800,7 @@ namespace dragon } return; } - else if (instEdit.str() == "add" || instEdit.str() == "sub" || instEdit.str() == "mul") + else if (instEdit == "add" || instEdit == "sub" || instEdit == "mul") { m_code.push_back(0x00); eOperandType opType = parseOperand(st.next(), word); @@ -815,17 +815,17 @@ namespace dragon if (opType == eOperandType::Immediate) { - if (instEdit.str() == "add") m_code[m_code.size() - 2] = data::OpCodes::AddImmReg; - else if (instEdit.str() == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubImmReg; - else if (instEdit.str() == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulImmReg; + if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddImmReg; + else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubImmReg; + else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulImmReg; m_code.push_back((uint8_t)((word & 0xFF00) >> 8)); m_code.push_back((uint8_t)(word & 0x00FF)); } else if (opType == eOperandType::Register) { - if (instEdit.str() == "add") m_code[m_code.size() - 2] = data::OpCodes::AddRegReg; - else if (instEdit.str() == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubRegReg; - else if (instEdit.str() == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulRegReg; + if (instEdit == "add") m_code[m_code.size() - 2] = data::OpCodes::AddRegReg; + else if (instEdit == "sub") m_code[m_code.size() - 2] = data::OpCodes::SubRegReg; + else if (instEdit == "mul") m_code[m_code.size() - 2] = data::OpCodes::MulRegReg; m_code.push_back((uint8_t)word); } else @@ -836,7 +836,7 @@ namespace dragon } return; } - else if (instEdit.str() == "lsh" || instEdit.str() == "rsh" || instEdit.str() == "and" || instEdit.str() == "or" || instEdit.str() == "xor") + else if (instEdit == "lsh" || instEdit == "rsh" || instEdit == "and" || instEdit == "or" || instEdit == "xor") { eOperandType opType = parseOperand(st.next(), word); if (opType != eOperandType::Register) @@ -849,22 +849,22 @@ namespace dragon opType = parseOperand(st.next(), word); if (opType == eOperandType::Immediate) { - if (instEdit.str() == "lsh") m_code.push_back(data::OpCodes::LShiftRegImm); - else if (instEdit.str() == "rsh") m_code.push_back(data::OpCodes::RShiftRegImm); - else if (instEdit.str() == "and") m_code.push_back(data::OpCodes::AndRegImm); - else if (instEdit.str() == "or") m_code.push_back(data::OpCodes::OrRegImm); - else if (instEdit.str() == "xor") m_code.push_back(data::OpCodes::XorRegImm); + if (instEdit == "lsh") m_code.push_back(data::OpCodes::LShiftRegImm); + else if (instEdit == "rsh") m_code.push_back(data::OpCodes::RShiftRegImm); + else if (instEdit == "and") m_code.push_back(data::OpCodes::AndRegImm); + else if (instEdit == "or") m_code.push_back(data::OpCodes::OrRegImm); + else if (instEdit == "xor") m_code.push_back(data::OpCodes::XorRegImm); m_code.push_back((uint8_t)((word & 0xFF00) >> 8)); m_code.push_back((uint8_t)(word & 0x00FF)); m_code.push_back((uint8_t)regAddr); } else if (opType == eOperandType::Register) { - if (instEdit.str() == "lsh") m_code.push_back(data::OpCodes::LShiftRegReg); - else if (instEdit.str() == "rsh") m_code.push_back(data::OpCodes::RShiftRegReg); - else if (instEdit.str() == "and") m_code.push_back(data::OpCodes::AndRegReg); - else if (instEdit.str() == "or") m_code.push_back(data::OpCodes::OrRegReg); - else if (instEdit.str() == "xor") m_code.push_back(data::OpCodes::XorRegReg); + if (instEdit == "lsh") m_code.push_back(data::OpCodes::LShiftRegReg); + else if (instEdit == "rsh") m_code.push_back(data::OpCodes::RShiftRegReg); + else if (instEdit == "and") m_code.push_back(data::OpCodes::AndRegReg); + else if (instEdit == "or") m_code.push_back(data::OpCodes::OrRegReg); + else if (instEdit == "xor") m_code.push_back(data::OpCodes::XorRegReg); m_code.push_back((uint8_t)word); m_code.push_back((uint8_t)regAddr); } @@ -876,7 +876,7 @@ namespace dragon } return; } - else if (instEdit.str() == "jne" || instEdit.str() == "jeq" || instEdit.str() == "jgr" || instEdit.str() == "jls" || instEdit.str() == "jge" || instEdit.str() == "jle") + else if (instEdit == "jne" || instEdit == "jeq" || instEdit == "jgr" || instEdit == "jls" || instEdit == "jge" || instEdit == "jle") { m_code.push_back(0x00); eOperandType opType = parseOperand(st.next(), word); @@ -893,23 +893,23 @@ namespace dragon if (opType == eOperandType::Immediate) { - if (instEdit.str() == "jeq") m_code[m_code.size() - 3] = data::OpCodes::JmpEqImm; - else if (instEdit.str() == "jne") m_code[m_code.size() - 3] = data::OpCodes::JmpNotEqImm; - else if (instEdit.str() == "jgr") m_code[m_code.size() - 3] = data::OpCodes::JmpGrImm; - else if (instEdit.str() == "jls") m_code[m_code.size() - 3] = data::OpCodes::JmpLessImm; - else if (instEdit.str() == "jge") m_code[m_code.size() - 3] = data::OpCodes::JmpGeImm; - else if (instEdit.str() == "jle") m_code[m_code.size() - 3] = data::OpCodes::JmpLeImm; + if (instEdit == "jeq") m_code[m_code.size() - 3] = data::OpCodes::JmpEqImm; + else if (instEdit == "jne") m_code[m_code.size() - 3] = data::OpCodes::JmpNotEqImm; + else if (instEdit == "jgr") m_code[m_code.size() - 3] = data::OpCodes::JmpGrImm; + else if (instEdit == "jls") m_code[m_code.size() - 3] = data::OpCodes::JmpLessImm; + else if (instEdit == "jge") m_code[m_code.size() - 3] = data::OpCodes::JmpGeImm; + else if (instEdit == "jle") m_code[m_code.size() - 3] = data::OpCodes::JmpLeImm; m_code.push_back((uint8_t)((word & 0xFF00) >> 8)); m_code.push_back((uint8_t)(word & 0x00FF)); } else if (opType == eOperandType::Register) { - if (instEdit.str() == "jeq") m_code[m_code.size() - 3] = data::OpCodes::JmpEqReg; - else if (instEdit.str() == "jne") m_code[m_code.size() - 3] = data::OpCodes::JmpNotEqReg; - else if (instEdit.str() == "jgr") m_code[m_code.size() - 3] = data::OpCodes::JmpGrReg; - else if (instEdit.str() == "jls") m_code[m_code.size() - 3] = data::OpCodes::JmpLessReg; - else if (instEdit.str() == "jge") m_code[m_code.size() - 3] = data::OpCodes::JmpGeReg; - else if (instEdit.str() == "jle") m_code[m_code.size() - 3] = data::OpCodes::JmpLeReg; + if (instEdit == "jeq") m_code[m_code.size() - 3] = data::OpCodes::JmpEqReg; + else if (instEdit == "jne") m_code[m_code.size() - 3] = data::OpCodes::JmpNotEqReg; + else if (instEdit == "jgr") m_code[m_code.size() - 3] = data::OpCodes::JmpGrReg; + else if (instEdit == "jls") m_code[m_code.size() - 3] = data::OpCodes::JmpLessReg; + else if (instEdit == "jge") m_code[m_code.size() - 3] = data::OpCodes::JmpGeReg; + else if (instEdit == "jle") m_code[m_code.size() - 3] = data::OpCodes::JmpLeReg; m_code.push_back((uint8_t)word); } else @@ -929,13 +929,13 @@ namespace dragon void Assembler::parse3Operand(ostd::String line) { - ostd::StringEditor lineEdit(line); - ostd::StringEditor instEdit(lineEdit.substr(0, lineEdit.indexOf(" "))); + ostd::String lineEdit(line); + ostd::String instEdit(lineEdit.new_substr(0, lineEdit.indexOf(" "))); instEdit.trim().toLower(); - ostd::StringEditor opEdit(lineEdit.substr(lineEdit.indexOf(" ") + 1)); + ostd::String opEdit(lineEdit.new_substr(lineEdit.indexOf(" ") + 1)); opEdit.trim(); int16_t word = 0x0000; - if (instEdit.str() == "mov") + if (instEdit == "mov") { auto st = opEdit.tokenize(","); eOperandType opType = parseOperand(st.next(), word); @@ -983,7 +983,7 @@ namespace dragon newCode.push_back((uint8_t)(entryAddr & 0x00FF)); if (m_dataSize > 0) m_disassembly.insert(m_disassembly.begin(), { (uint16_t)(m_loadAddress + 3), "[----------DATA_SECTION----------]" }); - m_disassembly.insert(m_disassembly.begin(), { m_loadAddress, ostd::StringEditor("jmp ").add(ostd::Utils::getHexStr(entryAddr, true, 2)).str() }); + m_disassembly.insert(m_disassembly.begin(), { m_loadAddress, ostd::String("jmp ").add(ostd::Utils::getHexStr(entryAddr, true, 2)) }); for (auto& d : m_symbolTable) symbols.push_back(d.second); for (int32_t i = symbols.size() - 1; i >= 0; i--) @@ -1009,10 +1009,10 @@ namespace dragon ostd::String Assembler::replaceSymbols(ostd::String line) { - ostd::StringEditor lineEdit(line); + ostd::String lineEdit(line); for (auto& symbol : m_symbolTable) lineEdit.replaceAll(symbol.first, ostd::Utils::getHexStr(symbol.second.address, true, 2)); - return lineEdit.str(); + return lineEdit; } void Assembler::replaceLabelRefs(void) @@ -1029,7 +1029,7 @@ namespace dragon Assembler::eOperandType Assembler::parseOperand(ostd::String op, int16_t& outOp) { - ostd::StringEditor opEdit(op); + ostd::String opEdit(op); bool derefReg = false; if (opEdit.startsWith("*")) { @@ -1037,7 +1037,7 @@ namespace dragon opEdit.trim(); derefReg = true; } - int8_t reg = parseRegister(opEdit.str()); + int8_t reg = parseRegister(opEdit); if (reg != data::Registers::Last) { outOp = (int16_t)reg; @@ -1057,14 +1057,14 @@ namespace dragon } if (opEdit.startsWith("$")) { - if (m_labelTable.count(opEdit.str()) == 0) + if (m_labelTable.count(opEdit) == 0) { std::cout << "Unknown symbol: " << opEdit << "\n"; return eOperandType::Error; } - uint16_t labelAddr = m_labelTable[opEdit.str()].address; + uint16_t labelAddr = m_labelTable[opEdit].address; if (labelAddr == 0x0000) - m_labelTable[opEdit.str()].references.push_back(m_code.size()); + m_labelTable[opEdit].references.push_back(m_code.size()); outOp = (int16_t)labelAddr; return eOperandType::Label; } @@ -1072,7 +1072,7 @@ namespace dragon { opEdit = opEdit.substr(1, opEdit.len() - 1); opEdit.trim(); - outOp = (int16_t)ostd::Utils::solveIntegerExpression(opEdit.str()); + outOp = (int16_t)ostd::Utils::solveIntegerExpression(opEdit); return eOperandType::Immediate; } if (opEdit.startsWith("[") && opEdit.endsWith("]")) @@ -1083,7 +1083,7 @@ namespace dragon { opEdit = opEdit.substr(1, opEdit.len() - 1); opEdit.trim(); - outOp = (int16_t)ostd::Utils::solveIntegerExpression(opEdit.str()); + outOp = (int16_t)ostd::Utils::solveIntegerExpression(opEdit); return eOperandType::DerefMemory; } if (!opEdit.isNumeric()) @@ -1099,25 +1099,25 @@ namespace dragon uint8_t Assembler::parseRegister(ostd::String op) { - ostd::StringEditor opEdit(op); + ostd::String opEdit(op); opEdit.trim().toLower(); - if (opEdit.str() == "r1") return data::Registers::R1; - if (opEdit.str() == "r2") return data::Registers::R2; - if (opEdit.str() == "r3") return data::Registers::R3; - if (opEdit.str() == "r4") return data::Registers::R4; - if (opEdit.str() == "r5") return data::Registers::R5; - if (opEdit.str() == "r6") return data::Registers::R6; - if (opEdit.str() == "r7") return data::Registers::R7; - if (opEdit.str() == "r8") return data::Registers::R8; - if (opEdit.str() == "r9") return data::Registers::R9; - if (opEdit.str() == "r10") return data::Registers::R10; - if (opEdit.str() == "acc") return data::Registers::ACC; - if (opEdit.str() == "fp") return data::Registers::FP; - if (opEdit.str() == "sp") return data::Registers::SP; - if (opEdit.str() == "ip") return data::Registers::IP; - if (opEdit.str() == "pp") return data::Registers::PP; - if (opEdit.str() == "rv") return data::Registers::RV; - if (opEdit.str() == "fl") return data::Registers::FL; + if (opEdit == "r1") return data::Registers::R1; + if (opEdit == "r2") return data::Registers::R2; + if (opEdit == "r3") return data::Registers::R3; + if (opEdit == "r4") return data::Registers::R4; + if (opEdit == "r5") return data::Registers::R5; + if (opEdit == "r6") return data::Registers::R6; + if (opEdit == "r7") return data::Registers::R7; + if (opEdit == "r8") return data::Registers::R8; + if (opEdit == "r9") return data::Registers::R9; + if (opEdit == "r10") return data::Registers::R10; + if (opEdit == "acc") return data::Registers::ACC; + if (opEdit == "fp") return data::Registers::FP; + if (opEdit == "sp") return data::Registers::SP; + if (opEdit == "ip") return data::Registers::IP; + if (opEdit == "pp") return data::Registers::PP; + if (opEdit == "rv") return data::Registers::RV; + if (opEdit == "fl") return data::Registers::FL; return data::Registers::Last; } diff --git a/src/assembler/Assembler.hpp b/src/assembler/Assembler.hpp index 4cbb58b..ffbc2c3 100644 --- a/src/assembler/Assembler.hpp +++ b/src/assembler/Assembler.hpp @@ -16,6 +16,8 @@ namespace dragon public: struct tDisassemblyLine { uint32_t addr = 0; ostd::String code = ""; + inline bool operator<(const tDisassemblyLine& second) const { return addr < second.addr; } + inline bool operator>(const tDisassemblyLine& second) const { return addr > second.addr; } }; public: struct tSymbol { diff --git a/src/assembler/assembler_main.cpp b/src/assembler/assembler_main.cpp index 48cd970..d2d360c 100644 --- a/src/assembler/assembler_main.cpp +++ b/src/assembler/assembler_main.cpp @@ -2,7 +2,7 @@ #include #include -ostd::legacy::ConsoleOutputHandler out; +ostd::ConsoleOutputHandler out; struct tCommandLineArgs @@ -19,8 +19,8 @@ int main(int argc, char** argv) tCommandLineArgs args; if (argc < 4) { - out.col("red").p("Error: too few arguments.").nl(); - out.col("red").p(" Usage: ./dasm -o [...options...]").resetColors().nl(); + out.fg("red").p("Error: too few arguments.").nl(); + out.fg("red").p(" Usage: ./dasm -o [...options...]").reset().nl(); return 1; } else @@ -28,15 +28,15 @@ int main(int argc, char** argv) args.source_file_path = argv[1]; for (int32_t i = 2; i < argc; i++) { - ostd::StringEditor edit(argv[i]); - if (edit.str() == "-o") + ostd::String edit(argv[i]); + if (edit == "-o") { if (i == argc - 1) break; //TODO: Warning i++; args.dest_file_path = argv[i]; } - else if (edit.str() == "--save-disassembly") + else if (edit == "--save-disassembly") { if (i == argc - 1) break; //TODO: Warning @@ -44,7 +44,7 @@ int main(int argc, char** argv) args.disassembly_file_path = argv[i]; args.save_disassembly = true; } - else if (edit.str() == "--verbose") + else if (edit == "--verbose") args.verbose = true; } } diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index cfaa7a2..d3b3e99 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -2,6 +2,7 @@ #include "../runtime/DragonRuntime.hpp" #include "DisassemblyLoader.hpp" #include +#include namespace dragon { @@ -41,11 +42,11 @@ namespace dragon return ""; } - uint16_t Debugger::Utils::findSymbol(const DisassemblyList& labels, const ostd::StringEditor& symbol) + uint16_t Debugger::Utils::findSymbol(const DisassemblyList& labels, const ostd::String& symbol) { for (auto& label : labels) { - if (label.code == symbol.str()) + if (label.code == symbol) return label.addr; } return 0x0000; @@ -56,13 +57,14 @@ namespace dragon return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_'); } - ostd::StringEditor Debugger::Utils::fillString(const ostd::StringEditor& str, char fill, int32_t totalLength) + void Debugger::Utils::clearConsoleLine(void) { - int32_t fillLen = totalLength - str.len(); - if (fillLen < 1) return str; - ostd::StringEditor newStr = str; - newStr.add(ostd::Utils::duplicateChar(fill, fillLen)); - return newStr; + for (int32_t i = 0; i < ostd::Utils::getConsoleWidth(); i++) + out.p("\b"); + for (int32_t i = 0; i < ostd::Utils::getConsoleWidth(); i++) + out.p(" "); + for (int32_t i = 0; i < ostd::Utils::getConsoleWidth(); i++) + out.p("\b"); } @@ -76,60 +78,60 @@ namespace dragon rgxrstr.fg("0x[0-9A-Fa-f]+|0b[0-1]+|(? ").col(ostd::legacy::ConsoleCol::White); + out.fg(ostd::ConsoleColors::Magenta).p(" #/> ").fg(ostd::ConsoleColors::White); } void Debugger::Display::printStep(void) @@ -142,47 +144,38 @@ namespace dragon auto& _da = codeRegion[i]; bool currentLine = _da.addr == debugger.currentAddress; ostd::String label = Utils::findSymbol(debugger.labels, _da.addr); - bool specialSection = _da.code.starts_with("[") &&_da.code.ends_with("]"); - if (label.length() < debugger.labelLineLength) - { - label += ostd::Utils::duplicateChar(' ', debugger.labelLineLength - label.length()); - } - else if (label.length() > debugger.labelLineLength) - { - ostd::StringEditor edit(label); - edit = edit.substr(0, debugger.labelLineLength - 3); - edit.add("..."); - label = edit.str(); - } - out.col(ostd::legacy::ConsoleCol::Gray).p(label).p(" "); + bool specialSection = _da.code.startsWith("[") &&_da.code.endsWith("]"); + label.fixedLength(debugger.labelLineLength); + out.fg(ostd::ConsoleColors::Gray).p(label.cpp_str()).p(" "); if (currentLine) { - out.col(ostd::legacy::ConsoleCol::Black).col(ostd::legacy::ConsoleCol::OnYellow).p(ostd::Utils::getHexStr(_da.addr, true, 2)).p(" ").reset();; + out.fg(ostd::ConsoleColors::Black).bg(ostd::ConsoleColors::Yellow).p(ostd::Utils::getHexStr(_da.addr, true, 2).cpp_str()).p(" ").reset();; } else { if (specialSection) - out.col(ostd::legacy::ConsoleCol::Cyan); + out.fg(ostd::ConsoleColors::Cyan); + else if (_da.code == "debug_break") + out.fg(ostd::ConsoleColors::Red); else - out.col(ostd::legacy::ConsoleCol::BrightGray); - out.p(ostd::Utils::getHexStr(_da.addr, true, 2)).p(" "); + out.fg(ostd::ConsoleColors::BrightGray); + out.p(ostd::Utils::getHexStr(_da.addr, true, 2).cpp_str()).p(" "); } if (specialSection) - out.col(ostd::legacy::ConsoleCol::Cyan).p(_da.code).nl(); - else + out.fg(ostd::ConsoleColors::Cyan).p(_da.code.cpp_str()).nl(); colorCodeInstructions(_da.code, currentLine, debugger.labels); out.reset(); } int32_t cw = ostd::Utils::getConsoleWidth(); ostd::String str = ostd::Utils::duplicateChar('#', cw); - out.col(ostd::legacy::ConsoleCol::OnYellow).col(ostd::legacy::ConsoleCol::Black).p(str).reset().nl(); + out.bg(ostd::ConsoleColors::Yellow).fg(ostd::ConsoleColors::Black).p(str.cpp_str()).reset().nl(); } void Debugger::Display::printDiff(void) { out.clear(); - ostd::StringEditor str; + ostd::String str; str.add("|===============|================PREV================|================CURR================|=====|====REG====|====REG====|"); str.add("\n"); str.add("| InstAddr: |*%PREV_INST_ADDR%*******************|*%CURR_INST_ADDR%*******************| R1 |*%PREV_R1%*|*%CURR_R1%*|"); @@ -209,22 +202,26 @@ namespace dragon str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| IP: |*%PREV_IP%**************************|**%CURR_IP%*************************| R7 |*%PREV_R7%*|*%CURR_R7%*|"); + str.add("| SubRoutine: |*%PREV_SUB_ROUTINE%*****************|**%CURR_SUB_ROUTINE%****************| R6 |*%PREV_R7%*|*%CURR_R7%*|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| SP: |*%PREV_SP%**************************|**%CURR_SP%*************************| R8 |*%PREV_R8%*|*%CURR_R8%*|"); + str.add("| IP: |*%PREV_IP%**************************|**%CURR_IP%*************************| R7 |*%PREV_R8%*|*%CURR_R8%*|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| FP: |*%PREV_FP%**************************|**%CURR_FP%*************************| R9 |*%PREV_R9%*|*%CURR_R9%*|"); + str.add("| SP: |*%PREV_SP%**************************|**%CURR_SP%*************************| R8 |*%PREV_R9%*|*%CURR_R9%*|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|-----|-----------|-----------|"); str.add("\n"); - str.add("| RV: |*%PREV_RV%**************************|**%CURR_RV%*************************| R10 |*%PREV_R10%|*%CURR_R10%|"); + str.add("| FP: |*%PREV_FP%**************************|**%CURR_FP%*************************| R9 |*%PREV_R10%|*%CURR_R10%|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|=====|===========|===========|"); str.add("\n"); + str.add("| RV: |*%PREV_RV%**************************|**%CURR_RV%*************************|"); + str.add("\n"); + str.add("|---------------|------------------------------------|------------------------------------|"); + str.add("\n"); str.add("| PP: |*%PREV_PP%**************************|**%CURR_PP%*************************|"); str.add("\n"); str.add("|---------------|------------------------------------|------------------------------------|"); @@ -241,273 +238,296 @@ namespace dragon str.replaceAll("*", ""); int32_t item_len = 36; const dragon::DragonRuntime::tMachineDebugInfo& minfo = dragon::DragonRuntime::getMachineInfoDiff(); - ostd::StringEditor tmp = " ", tmpStyle = ""; + ostd::String tmp = " ", tmpStyle = ""; //Instruction Address { tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionAddress, true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_INST_ADDR%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_INST_ADDR%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionAddress, true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionAddress != minfo.previousInstructionAddress) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_INST_ADDR%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_INST_ADDR%", tmpStyle); } //Code { tmp = " ", tmpStyle = ""; - ostd::StringEditor prevCode = " ("; + ostd::String prevCode = " ("; prevCode.add(minfo.previousInstructionOpCode).add(") "); for (int32_t i = 0; i < minfo.previousInstructionFootprintSize; i++) prevCode.add(ostd::Utils::getHexStr(minfo.previousInstructionFootprint[i], false, 1)).add(" "); - tmp.add(prevCode.str()); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.add(prevCode); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Black,background:BrightGray]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_CODE%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_CODE%", tmpStyle); // tmp = " "; - // ostd::StringEditor currCode = " ("; + // ostd::String currCode = " ("; // currCode.add(minfo.currentInstructionOpCode).add(") "); // for (int32_t i = 0; i < minfo.currentInstructionFootprintSize; i++) // currCode.add(ostd::Utils::getHexStr(minfo.currentInstructionFootprint[i], false, 1)).add(" "); - // tmp.add(currCode.str()); - // tmp = fillString(tmp, ' ', item_len); - // if (currCode.str() != prevCode.str()) + // 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]"; - // tmpStyle.add(tmp.str()).add("[@@/]"); - // str.replaceAll("%CURR_CODE%", tmpStyle.str()); + // tmpStyle.add(tmp).add("[@@/]"); + // str.replaceAll("%CURR_CODE%", tmpStyle); } //Stack Frame { tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionStackFrameSize, true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_STACK_FRAME%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_STACK_FRAME%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionStackFrameSize, true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionStackFrameSize != minfo.previousInstructionStackFrameSize) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_STACK_FRAME%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_STACK_FRAME%", tmpStyle); } //Debug Break { tmp = " ", tmpStyle = ""; tmp.add(STR_BOOL(minfo.previousInstructionDebugBreak)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_DBG_BRK%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_DBG_BRK%", tmpStyle); tmp = " "; tmp.add(STR_BOOL(minfo.currentInstructionDebugBreak)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionDebugBreak != minfo.previousInstructionDebugBreak) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_DBG_BRK%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_DBG_BRK%", tmpStyle); } //INT Handler { tmp = " ", tmpStyle = ""; tmp.add(STR_BOOL(minfo.previousInstructionInterruptHandler)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_INT_HANDLER%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_INT_HANDLER%", tmpStyle); tmp = " "; tmp.add(STR_BOOL(minfo.currentInstructionInterruptHandler)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionInterruptHandler != minfo.previousInstructionInterruptHandler) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_INT_HANDLER%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_INT_HANDLER%", tmpStyle); } //Bios Mode { tmp = " ", tmpStyle = ""; tmp.add(STR_BOOL(minfo.previousInstructionBiosMode)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_BIOS_MODE%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_BIOS_MODE%", tmpStyle); tmp = " "; tmp.add(STR_BOOL(minfo.currentInstructionBiosMode)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionBiosMode != minfo.previousInstructionBiosMode) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_BIOS_MODE%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_BIOS_MODE%", tmpStyle); + } + + //SubRoutine Info + { + tmp = " ", tmpStyle = ""; + tmp.add(minfo.previousSubRoutineCounter).add(" ("); + tmp.add(STR_BOOL(minfo.previousIsInSubRoutine)).add(")"); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + ostd::String old_tmp = tmp; + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_SUB_ROUTINE%", tmpStyle); + + tmp = " "; + tmp.add(minfo.currentSubRoutineCounter).add(" ("); + tmp.add(STR_BOOL(minfo.currentIsInSubRoutine)).add(")"); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); + if (old_tmp != tmp) + tmpStyle = "[@@style foreground:Black,background:BrightRed]"; + else + tmpStyle = "[@@style foreground:Blue]"; + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_SUB_ROUTINE%", tmpStyle); } //System Registers { tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::IP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_IP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_IP%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::IP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::IP] != minfo.previousInstructionRegisters[dragon::data::Registers::IP]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_IP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_IP%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::SP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_SP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_SP%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::SP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::SP] != minfo.previousInstructionRegisters[dragon::data::Registers::SP]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_SP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_SP%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::FP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_FP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_FP%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::FP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::FP] != minfo.previousInstructionRegisters[dragon::data::Registers::FP]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_FP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_FP%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::RV], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_RV%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_RV%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::RV], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::RV] != minfo.previousInstructionRegisters[dragon::data::Registers::RV]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_RV%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_RV%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::PP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_PP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_PP%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::PP], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::PP] != minfo.previousInstructionRegisters[dragon::data::Registers::PP]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_PP%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_PP%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::FL], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_FL%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_FL%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::FL], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::FL] != minfo.previousInstructionRegisters[dragon::data::Registers::FL]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_FL%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_FL%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::ACC], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_ACC%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_ACC%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::ACC], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::ACC] != minfo.previousInstructionRegisters[dragon::data::Registers::ACC]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_ACC%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_ACC%", tmpStyle); } item_len = 11; @@ -515,233 +535,323 @@ namespace dragon { tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R1], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R1%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R1%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R1], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R1] != minfo.previousInstructionRegisters[dragon::data::Registers::R1]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R1%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R1%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R2], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R2%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R2%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R2], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R2] != minfo.previousInstructionRegisters[dragon::data::Registers::R2]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R2%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R2%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R3], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R3%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R3%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R3], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R3] != minfo.previousInstructionRegisters[dragon::data::Registers::R3]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R3%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R3%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R4], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R4%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R4%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R4], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R4] != minfo.previousInstructionRegisters[dragon::data::Registers::R4]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R4%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R4%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R5], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R5%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R5%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R5], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R5] != minfo.previousInstructionRegisters[dragon::data::Registers::R5]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R5%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R5%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R6], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R6%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R6%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R6], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R6] != minfo.previousInstructionRegisters[dragon::data::Registers::R6]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R6%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R6%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R7], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R7%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R7%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R7], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R7] != minfo.previousInstructionRegisters[dragon::data::Registers::R7]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R7%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R7%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R8], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R8%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R8%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R8], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R8] != minfo.previousInstructionRegisters[dragon::data::Registers::R8]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R8%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R8%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R9], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R9%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R9%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R9], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R9] != minfo.previousInstructionRegisters[dragon::data::Registers::R9]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R9%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R9%", tmpStyle); tmp = " ", tmpStyle = ""; tmp.add(ostd::Utils::getHexStr(minfo.previousInstructionRegisters[dragon::data::Registers::R10], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%PREV_R10%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%PREV_R10%", tmpStyle); tmp = " "; tmp.add(ostd::Utils::getHexStr(minfo.currentInstructionRegisters[dragon::data::Registers::R10], true, 2)); - tmp = Utils::fillString(tmp, ' ', item_len); + tmp.addPadding(item_len, ' ', ostd::String::ePaddingBehavior::AllowOddExtraLeft); if (minfo.currentInstructionRegisters[dragon::data::Registers::R10] != minfo.previousInstructionRegisters[dragon::data::Registers::R10]) tmpStyle = "[@@style foreground:Black,background:BrightRed]"; else tmpStyle = "[@@style foreground:Blue]"; - tmpStyle.add(tmp.str()).add("[@@/]"); - str.replaceAll("%CURR_R10%", tmpStyle.str()); + tmpStyle.add(tmp).add("[@@/]"); + str.replaceAll("%CURR_R10%", tmpStyle); } ostd::RegexRichString rgxstr(str); - rgxstr.fg("InstAddr|Code|StackFrame|DBG BRK|INT Handler|BIOS Mode", "Magenta"); + 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("PREV", "Red"); rgxstr.fg("CURR", "Green"); out.pStyled(rgxstr); - out.nl().nl().col(ostd::legacy::ConsoleCol::Yellow).p("Pres to continue execution...").nl().reset(); + out.nl().nl().fg(ostd::ConsoleColors::Yellow).p("Pres to continue execution...").nl().reset(); std::cin.get(); } - void Debugger::Display::printTrackedAddresses(const std::vector& trackedAddresses) + void Debugger::Display::printTrackedAddresses(void) { + out.clear(); + const dragon::DragonRuntime::tMachineDebugInfo& minfo = dragon::DragonRuntime::getMachineInfoDiff(); + if (minfo.trackedAddresses.size() == 0) return; + for (int32_t i = 0; i < minfo.trackedAddresses.size(); i++) + { + auto addr = minfo.trackedAddresses[i]; + ostd::String symbol = Utils::findSymbol(debugger.data, addr); + if (symbol == "") + symbol = Utils::findSymbol(debugger.labels, addr); + symbol.fixedLength(30); + out.p(symbol); + out.p(ostd::Utils::getHexStr(addr, true, 2)).p(" "); + out.p(ostd::Utils::getHexStr(minfo.previousInstructionTrackedValues[i], true, 1)).p(" "); + out.p(ostd::Utils::getHexStr(minfo.currentInstructionTrackedValues[i], true, 1)).p(" "); + out.nl(); + } + + out.nl().nl().fg(ostd::ConsoleColors::Yellow).p("Pres to continue execution...").nl().reset(); + std::cin.get(); } - ostd::StringEditor Debugger::Display::changeScreen(void) + void Debugger::Display::printStack(void) { - if (debugger.command.str() == "diff") + out.clear(); + + const dragon::DragonRuntime::tMachineDebugInfo& minfo = dragon::DragonRuntime::getMachineInfoDiff(); + uint16_t stack_ptr = DragonRuntime::cpu.readRegister(data::Registers::SP); + std::cout << " " << ostd::Utils::getHexStr(stack_ptr, true, 2) << " \n"; + ostd::Utils::printByteStream(*DragonRuntime::ram.getByteStream(), 0xFF80, 16, 8, out, stack_ptr, 1, "Stack"); + + out.nl(); + + for (auto& frame : dragon::DragonRuntime::cpu.m_debug_stackFrameStrings) + { + ostd::RegexRichString rgxrstr(frame); + rgxrstr.fg("0x[0-9A-Fa-f]+|0b[0-1]+|(? to continue execution...").nl().reset(); + std::cin.get(); + } + + void Debugger::Display::printCallStack(void) + { + out.clear(); + + const dragon::DragonRuntime::tMachineDebugInfo& minfo = dragon::DragonRuntime::getMachineInfoDiff(); + + auto& callStack = minfo.callStack; + int32_t depth = -1; + for (auto& call : callStack) + { + if (call.info.new_trim().toLower().startsWith("ret")) + depth--; + else + depth++; + if (depth < 0) depth = 0; + out.p(ostd::String().addLeftPadding(depth * 4)); + out.p(call.info.new_fixedLength(10)).p(" "); + ostd::String subroutine_name = Utils::findSymbol(debugger.labels, call.addr); + out.p(ostd::Utils::getHexStr(call.addr, true, 2)); + if (call.info.new_trim().toLower() == "call imm" && subroutine_name != "") + out.p(" (").p(subroutine_name).p(")"); + out.nl(); + } + + out.nl().nl().fg(ostd::ConsoleColors::Yellow).p("Pres to continue execution...").nl().reset(); + std::cin.get(); + } + + ostd::String Debugger::Display::changeScreen(void) + { + if (debugger.command == "diff") { printDiff(); printStep(); + printPrompt(); return getCommandInput(); } - else if (debugger.command.str() == "tracker") + else if (debugger.command == "tracker") { - printTrackedAddresses(debugger.trackedAddresses); + printTrackedAddresses(); printStep(); + printPrompt(); + return getCommandInput(); + } + else if (debugger.command == "stack") + { + printStack(); + printStep(); + printPrompt(); + return getCommandInput(); + } + else if (debugger.command == "call") + { + printCallStack(); + printStep(); + printPrompt(); return getCommandInput(); } return ""; @@ -757,7 +867,7 @@ namespace dragon while (dragon::data::ErrorHandler::hasError()) { auto err = dragon::data::ErrorHandler::popError(); - out.nl().col(ostd::legacy::ConsoleCol::Red).p("Error ").p(ostd::Utils::getHexStr(err.code, true, 8)).p(": ").p(err.text).nl(); + out.nl().fg(ostd::ConsoleColors::Red).p("Error ").p(ostd::Utils::getHexStr(err.code, true, 8).cpp_str()).p(": ").p(err.text.cpp_str()).nl(); } debugger.args.step_exec = true; } @@ -766,7 +876,7 @@ namespace dragon { if (argc < 2) { - out.col("red").p("Error, too few arguments.").resetColors().nl(); + out.fg("red").p("Error, too few arguments.").reset().nl(); return 128; } else @@ -774,18 +884,18 @@ namespace dragon debugger.args.machine_config_path = argv[1]; for (int32_t i = 2; i < argc; i++) { - ostd::StringEditor edit(argv[i]); - if (edit.str() == "--verbose-load") + ostd::String edit(argv[i]); + if (edit == "--verbose-load") debugger.args.verbose_load = true; - else if (edit.str() == "--step-exec") + else if (edit == "--step-exec") debugger.args.step_exec = true; - else if (edit.str() == "--track-step-diff") - debugger.args.track_step_diff = true; - else if (edit.str() == "--hide-vdisplay") + else if (edit == "--track-step-diff-off") + debugger.args.track_step_diff = false; + else if (edit == "--hide-vdisplay") debugger.args.hide_virtual_display = true; - else if (edit.str() == "--auto-start") + else if (edit == "--auto-start") debugger.args.auto_start_debug = true; - else if (edit.str() == "--force-load") + else if (edit == "--force-load") { if ((argc - 1) - i < 2) break; //TODO: Warning @@ -805,13 +915,18 @@ namespace dragon int32_t Debugger::initRuntime(void) { - int32_t init_state = dragon::DragonRuntime::initMachine(debugger.args.machine_config_path, debugger.args.verbose_load, debugger.args.track_step_diff, debugger.args.hide_virtual_display); + int32_t init_state = dragon::DragonRuntime::initMachine(debugger.args.machine_config_path, + debugger.args.verbose_load, + debugger.args.track_step_diff, + debugger.args.hide_virtual_display, + debugger.args.track_call_stack, + true); //CPU Debug Mode Enabled if (init_state != 0) return init_state; //TODO: Error if (debugger.args.force_load) dragon::DragonRuntime::forceLoad(debugger.args.force_load_file, debugger.args.force_load_mem_offset); - dragon::DisassemblyLoader::loadDirectory(debugger.disassemblyDirectory.str()); + dragon::DisassemblyLoader::loadDirectory(debugger.disassemblyDirectory); debugger.code = dragon::DisassemblyLoader::getCodeTable(); debugger.labels = dragon::DisassemblyLoader::getLabelTable(); debugger.data = dragon::DisassemblyLoader::getDataTable(); @@ -819,10 +934,45 @@ namespace dragon return 0; } - ostd::StringEditor Debugger::getCommandInput(void) + ostd::String Debugger::getCommandInput(void) { + // ostd::String cmd; + // ostd::KeyboardController keyboard; + + // ostd::eKeys key = ostd::eKeys::NoKeyPressed; + // int32_t commandHistoryIndex = ZERO(commandHistory.size() - 1); + // while (key != ostd::eKeys::Enter) + // { + // key = keyboard.waitForKeyPress(); + // if (key == ostd::eKeys::Up) + // { + // if (commandHistory.size() == 0) + // continue; + // Utils::clearConsoleLine(); + // Display::printPrompt(); + // out.p(commandHistory[commandHistoryIndex]); + // commandHistoryIndex = ZERO(commandHistoryIndex - 1); + // } + // else if (key == ostd::eKeys::Down) + // { + // if (commandHistory.size() == 0) + // continue; + // Utils::clearConsoleLine(); + // Display::printPrompt(); + // out.p(commandHistory[commandHistoryIndex]); + // commandHistoryIndex = CAP(commandHistoryIndex + 1, commandHistory.size() - 1); + // } + // else if (key == ostd::eKeys::Enter) + // { + // cmd = keyboard.getInputString(); + // commandHistory.push_back(cmd); + // } + // } + + // return cmd; + ostd::String cmd; - std::getline(std::cin, cmd); + std::getline(std::cin, cmd.cpp_str_ref()); return cmd; } diff --git a/src/debugger/Debugger.hpp b/src/debugger/Debugger.hpp index 24acb47..2b39272 100644 --- a/src/debugger/Debugger.hpp +++ b/src/debugger/Debugger.hpp @@ -17,9 +17,10 @@ namespace dragon bool verbose_load = false; bool force_load = false; bool step_exec = false; - bool track_step_diff = false; + bool track_step_diff = true; bool auto_start_debug = false; bool hide_virtual_display = false; + bool track_call_stack = true; ostd::String force_load_file = ""; uint16_t force_load_mem_offset = 0x00; }; @@ -31,20 +32,20 @@ namespace dragon DisassemblyList labels; DisassemblyList data; std::vector trackedAddresses; - ostd::StringEditor command; + ostd::String command; int32_t labelLineLength { 20 }; uint16_t currentAddress { 0 }; bool userQuit { false }; - ostd::StringEditor disassemblyDirectory { "disassembly" }; + ostd::String disassemblyDirectory { "disassembly" }; }; public: class Utils { public: static DisassemblyList findCodeRegion(const DisassemblyList& code, uint16_t address, uint16_t codeRegionMargin); static ostd::String findSymbol(const DisassemblyList& labels, uint16_t address); - static uint16_t findSymbol(const DisassemblyList& labels, const ostd::StringEditor& symbol); + static uint16_t findSymbol(const DisassemblyList& labels, const ostd::String& symbol); static bool isValidLabelNameChar(char c); - static ostd::StringEditor fillString(const ostd::StringEditor& str, char fill, int32_t totalLength); //TODO: Implement in omnia-framework + static void clearConsoleLine(void); }; public: class Display { @@ -54,19 +55,22 @@ namespace dragon static void printPrompt(void); static void printStep(void); static void printDiff(void); - static void printTrackedAddresses(const std::vector& trackedAddresses); - static ostd::StringEditor changeScreen(void); + static void printTrackedAddresses(void); + static void printStack(void); + static void printCallStack(void); + static ostd::String changeScreen(void); }; public: static void processErrors(void); static int32_t loadArguments(int argc, char** argv); static int32_t initRuntime(void); - static ostd::StringEditor getCommandInput(void); + static ostd::String getCommandInput(void); static inline tDebuggerData& data(void) { return debugger; } - static inline ostd::legacy::ConsoleOutputHandler& output(void) { return out; } + static inline ostd::ConsoleOutputHandler& output(void) { return out; } private: inline static tDebuggerData debugger; - inline static ostd::legacy::ConsoleOutputHandler out; + inline static ostd::ConsoleOutputHandler out; + inline static std::vector commandHistory; }; } \ No newline at end of file diff --git a/src/debugger/DisassemblyLoader.cpp b/src/debugger/DisassemblyLoader.cpp index f0f444f..ae0e97f 100644 --- a/src/debugger/DisassemblyLoader.cpp +++ b/src/debugger/DisassemblyLoader.cpp @@ -5,6 +5,8 @@ #include "../tools/Utils.hpp" +#include + namespace dragon { const DisassemblyTable DisassemblyTable::DefaultObject; @@ -31,24 +33,14 @@ namespace dragon ostd::String header_string = ""; serializer.r_NullTerminatedString(0, header_string); if (header_string != "{ DRAGON_DEBUG_DISASSEMBLY }") return; - addr += (header_string.length() + 1) * ostd::tTypeSize::BYTE; + addr += (header_string.len() + 1) * ostd::tTypeSize::BYTE; while (addr < serializer.size()) { serializer.r_DWord(addr, line_addr); addr += ostd::tTypeSize::DWORD; - // ostd::ByteStream str_stream; - // serializer.r_Byte(addr, line_code_char); - // addr += ostd::tTypeSize::BYTE; - // do - // { - // str_stream.push_back(line_code_char); - // serializer.r_Byte(addr, line_code_char); - // addr += ostd::tTypeSize::BYTE; - // } while(line_code_char != 0); - // ostd::String code_line = ostd::Utils::byteStreamToString(str_stream); ostd::String code_line = ""; serializer.r_NullTerminatedString(addr, code_line); - addr += (code_line.length() + 1) * ostd::tTypeSize::BYTE; + addr += (code_line.len() + 1) * ostd::tTypeSize::BYTE; if (code_line == "{ DATA }") { mode = MODE_DATA; @@ -69,19 +61,19 @@ namespace dragon line.code = code_line; if (mode == MODE_CODE) { - ostd::StringEditor codeEdit(line.code); + ostd::String codeEdit(line.code); codeEdit.trim(); if (codeEdit.contains(" ")) { - ostd::StringEditor part1 = codeEdit.substr(0, codeEdit.indexOf(" ")); - ostd::StringEditor part2 = codeEdit.substr(codeEdit.indexOf(" ") + 1); + ostd::String part1 = codeEdit.new_substr(0, codeEdit.indexOf(" ")); + ostd::String part2 = codeEdit.new_substr(codeEdit.indexOf(" ") + 1); part1.trim(); part2.trim(); int32_t opCodeLen = 10; if (part1.len() < opCodeLen) { - codeEdit = part1.str() + ostd::Utils::duplicateChar(' ', opCodeLen - part1.len()) + part2.str(); - line.code = codeEdit.str(); + codeEdit = part1 + ostd::Utils::duplicateChar(' ', opCodeLen - part1.len()) + part2; + line.code = codeEdit; } } m_code.push_back(line); @@ -116,6 +108,7 @@ namespace dragon std::vector fullTable; for (auto& table : m_tables) fullTable.insert(fullTable.end(), table.getCodeTable().begin(), table.getCodeTable().end()); + std::sort(fullTable.begin(), fullTable.end()); return fullTable; } @@ -124,6 +117,7 @@ namespace dragon std::vector fullTable; for (auto& table : m_tables) fullTable.insert(fullTable.end(), table.getDataTable().begin(), table.getDataTable().end()); + std::sort(fullTable.begin(), fullTable.end()); return fullTable; } @@ -132,6 +126,7 @@ namespace dragon std::vector fullTable; for (auto& table : m_tables) fullTable.insert(fullTable.end(), table.getLabelTable().begin(), table.getLabelTable().end()); + std::sort(fullTable.begin(), fullTable.end()); return fullTable; } } \ No newline at end of file diff --git a/src/debugger/debugger_main.cpp b/src/debugger/debugger_main.cpp index e942adf..78635e9 100644 --- a/src/debugger/debugger_main.cpp +++ b/src/debugger/debugger_main.cpp @@ -1,6 +1,50 @@ #include "Debugger.hpp" #include "../runtime/DragonRuntime.hpp" +void exec_watch_command(void) +{ + using namespace dragon; + + auto tokens = Debugger::data().command.tokenize(); + for (auto& addr : tokens) + { + Debugger::data().command = addr; + if (Debugger::data().command.isNumeric()) + Debugger::data().trackedAddresses.push_back((uint16_t)Debugger::data().command.toInt()); + else if (Debugger::data().command.startsWith("$")) + { + uint8_t nbytes = 1; + if (Debugger::data().command.contains("[") && Debugger::data().command.endsWith("]")) + { + ostd::String str_nbytes = Debugger::data().command.new_substr(Debugger::data().command.indexOf("[") + 1).trim(); + str_nbytes.substr(0, str_nbytes.len() - 1); + std::cout << str_nbytes << "\n"; + std::cout << Debugger::data().command << "\n"; + Debugger::data().command.substr(0, Debugger::data().command.indexOf("[")).trim(); + std::cout << Debugger::data().command << "\n"; + if (str_nbytes.isNumeric()) + nbytes = str_nbytes.toInt(); + if (nbytes < 1) nbytes = 1; + } + uint16_t addr = Debugger::Utils::findSymbol(Debugger::data().data, Debugger::data().command); + if (addr > 0) + { + for (int32_t i = 0; i < nbytes; i++) + Debugger::data().trackedAddresses.push_back(addr + i); + } + else + { + addr = Debugger::Utils::findSymbol(Debugger::data().labels, Debugger::data().command); + if (addr > 0) + { + for (int32_t i = 0; i < nbytes; i++) + Debugger::data().trackedAddresses.push_back(addr + i); + } + } + } + } + std::cout << (int)Debugger::data().trackedAddresses.size() << "\n"; +} int main(int argc, char** argv) { @@ -10,6 +54,8 @@ int main(int argc, char** argv) rValue = Debugger::initRuntime(); if (rValue != 0) return rValue; + + if (!Debugger::data().args.auto_start_debug) { while (true) @@ -17,33 +63,18 @@ int main(int argc, char** argv) Debugger::Display::printPrompt(); Debugger::data().command = Debugger::getCommandInput(); Debugger::data().command.trim().toLower(); - if (Debugger::data().command.str() == "r" || Debugger::data().command.str() == "run") + if (Debugger::data().command == "r" || Debugger::data().command == "run") break; - else if (Debugger::data().command.str() == "q" || Debugger::data().command.str() == "quit") + else if (Debugger::data().command == "q" || Debugger::data().command == "quit") return rValue; else if (Debugger::data().command.startsWith("watch ")) { - Debugger::data().command = Debugger::data().command.substr(6); - Debugger::data().command.trim(); - auto tokens = Debugger::data().command.tokenize(); - for (auto& addr : tokens) - { - Debugger::data().command = addr; - if (Debugger::data().command.isNumeric()) - Debugger::data().trackedAddresses.push_back((uint16_t)Debugger::data().command.toInt()); - else if (Debugger::data().command.startsWith("$")) - { - uint16_t addr = Debugger::Utils::findSymbol(Debugger::data().data, Debugger::data().command); - if (addr > 0) - Debugger::data().trackedAddresses.push_back(addr); - else - { - addr = Debugger::Utils::findSymbol(Debugger::data().labels, Debugger::data().command); - if (addr > 0) - Debugger::data().trackedAddresses.push_back(addr); - } - } - } + Debugger::data().command.substr(6).trim(); + exec_watch_command(); + } + else if (Debugger::data().command == "step") + { + Debugger::data().args.step_exec = true; } } } @@ -66,7 +97,7 @@ int main(int argc, char** argv) } if (!result || userQuit) { - Debugger::output().nl().col(ostd::legacy::ConsoleCol::Yellow).p("Execution Finished. Pres to exit...").nl().reset(); + Debugger::output().nl().fg(ostd::ConsoleColors::Yellow).p("Execution Finished. Pres to exit...").nl().reset(); std::cin.get(); break; } @@ -78,14 +109,14 @@ int main(int argc, char** argv) Debugger::data().args.step_exec = true; } Debugger::data().command.trim().toLower(); - while (Debugger::data().command.str() != "") + while (Debugger::data().command != "") { - if (Debugger::data().command.str() == "q" || Debugger::data().command.str() == "quit") + if (Debugger::data().command == "q" || Debugger::data().command == "quit") { userQuit = true; Debugger::data().command = ""; } - else if (Debugger::data().command.str() == "c" || Debugger::data().command.str() == "continue") + else if (Debugger::data().command == "c" || Debugger::data().command == "continue") { Debugger::data().args.step_exec = false; Debugger::data().command = ""; diff --git a/src/gui/DebuggerWindow.cpp b/src/gui/DebuggerWindow.cpp deleted file mode 100644 index 792d429..0000000 --- a/src/gui/DebuggerWindow.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "DebuggerWindow.hpp" - -namespace dragon -{ - -} \ No newline at end of file diff --git a/src/gui/DebuggerWindow.hpp b/src/gui/DebuggerWindow.hpp deleted file mode 100644 index 7666a76..0000000 --- a/src/gui/DebuggerWindow.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace dragon -{ - class DebuggerWindow - { - - }; -} // namespace dragon diff --git a/src/gui/RawTextRenderer.cpp b/src/gui/RawTextRenderer.cpp index 36d3aaf..34992e3 100644 --- a/src/gui/RawTextRenderer.cpp +++ b/src/gui/RawTextRenderer.cpp @@ -13,11 +13,11 @@ namespace dragon bool RawTextRenderer::drawString(ostd::String str, uint32_t column, uint32_t row, uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels, ostd::Color color, ostd::Color background) { - ostd::StringEditor se(str); - if (se.str() == "") return false; + ostd::String se(str); + if (se == "") return false; if (row >= CONSOLE_CHARS_V) return false; if (column >= CONSOLE_CHARS_H) return false; - if (column + str.length() > CONSOLE_CHARS_H) return false; + if (column + str.len() > CONSOLE_CHARS_H) return false; int32_t x = column * FONT_CHAR_W; int32_t y = row * FONT_CHAR_H; for (auto& c : str) diff --git a/src/gui/VirtualConsole.cpp b/src/gui/VirtualConsole.cpp deleted file mode 100644 index e2db9b9..0000000 --- a/src/gui/VirtualConsole.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "VirtualConsole.hpp" -#include "RawTextRenderer.hpp" -#include - -#include "../hardware/VirtualIODevices.hpp" -#include "../hardware/VirtualCPU.hpp" - -namespace dragon -{ - void VirtualConsole::initialize(void) - { - m_windowWidth = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16; - m_windowHeight = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9; - - SDL_Init(SDL_INIT_VIDEO); - m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE); - SDL_SetWindowResizable(m_window, SDL_FALSE); - m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED); - SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight); - m_screenTexture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, m_windowWidth, m_windowHeight); - m_fontSurface = SDL_LoadBMP("font.bmp"); - if (m_fontSurface == NULL) - out.bg(ostd::ConsoleColors::Red).p("Error loading font.").nl(); - m_fontPixels = (uint32_t*)m_fontSurface->pixels; - m_screenPixels = (uint32_t*)malloc(m_windowWidth * m_windowHeight * 4); - - dragon::RawTextRenderer::initialize(); - - vout.init(m_screenPixels, m_windowWidth, m_windowHeight, m_fontPixels); - vout.enableFixedScreen(); - - m_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Possible Memory Leak, palettes are never destroyed - - m_initialized = true; - m_running = true; - } - - void VirtualConsole::update(void) - { - if (!m_initialized) return; - Uint64 start = SDL_GetPerformanceCounter(); - handleEvents(); - if (m_redrawConsole) - { - uint8_t signal = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Signal); - switch (signal) - { - case tSignals::ClearScreen: - m_clearMemory = true; - break; - case tSignals::Continue: break; - default: break; - } - m_biosVideo.write8(hw::VirtualBIOSVideo::tRegisters::Signal, tSignals::Continue); - drawConsole(); - m_redrawConsole = false; - } - finalizeRender(); - Uint64 end = SDL_GetPerformanceCounter(); - float elapsed = (end - start) / (float)SDL_GetPerformanceFrequency(); - m_redrawAccumulator += elapsed; - if (m_redrawAccumulator >= 0.2f) - { - m_redrawConsole = true; - m_redrawAccumulator = 0.0f; - } - end = SDL_GetPerformanceCounter(); - elapsed = (end - start) / (float)SDL_GetPerformanceFrequency(); - m_timeAccumulator += elapsed; - if (m_timeAccumulator >= 0.5f) - { - m_title.clr().add("FPS: ").addi((int)(1.0f / elapsed)); - SDL_SetWindowTitle(m_window, m_title.c_str()); - m_timeAccumulator = 0.0f; - } - } - - void VirtualConsole::handleEvents(void) - { - if (!m_initialized) return; - SDL_Event event; - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) exit(0); - } - } - - void VirtualConsole::finalizeRender(void) - { - SDL_RenderClear(m_renderer); - SDL_UpdateTexture(m_screenTexture, NULL, m_screenPixels, m_windowWidth * 4); - SDL_RenderCopy(m_renderer, m_screenTexture, NULL, NULL); - SDL_RenderPresent(m_renderer); - } - - void VirtualConsole::drawConsole(void) - { - const uint8_t TRANSPARENCY_COLOR_INDEX = 0x5; - - uint8_t clearColor = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::ClearColor); - uint8_t palette = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Palette); - bool useTransparency = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::UseTransparencyOn0x5) != 0; - - if (palette >= m_palettes.size()) - palette = 0; //TODO: Error - - auto& pal = *m_palettes[palette]; - - ostd::Color clrCol = pal.getColor(clearColor); - if (m_clearMemory) - { - for (int y = 0; y < m_windowHeight; ++y) - { - for (int x = 0; x < m_windowWidth; ++x) - { - m_screenPixels[x + y * m_windowWidth] = clrCol.asInteger(); - } - } - m_clearMemory = false; - } - - ostd::Color fgCol; - ostd::Color bgCol; - uint16_t index = hw::VirtualBIOSVideo::tRegisters::VideoMemoryStart; - - // if (m_clearMemory) - // { - // for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2) - // { - // m_biosVideo.write8((uint16_t)i, 0x00); - // m_biosVideo.write8((uint16_t)(i + 1), clearColor); - // } - // m_clearMemory = false; - // } - - for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2) - { - uint8_t character = m_biosVideo.read8((uint16_t)i); - uint8_t colors = m_biosVideo.read8((uint16_t)(i + 1)); - uint8_t bgcol = (colors >> 4) & 0xF; - uint8_t fgcol = (colors & 0xF); - if (!isprint(character)) - { - character = ' '; - fgCol = pal.getColor(fgcol); - bgCol = clrCol; - } - else - { - fgCol = pal.getColor(fgcol); - bgCol = pal.getColor(bgcol); - } - vout.bgcol(bgCol).col(fgCol).p((char)character).flush().bgcol(clrCol); - } - vout.refreshScreen(); - m_cpu.handleInterrupt(data::InterruptCodes::BiosVideoScreenRefresh); - } -} \ No newline at end of file diff --git a/src/gui/VirtualConsole.hpp b/src/gui/VirtualConsole.hpp deleted file mode 100644 index 0ae5b03..0000000 --- a/src/gui/VirtualConsole.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "../tools/SDLInclude.hpp" - -#include -#include "VirtualConsoleOutputHandler.hpp" -#include "../tools/GlobalData.hpp" - -namespace dragon -{ - namespace hw - { - class VirtualBIOSVideo; - class VirtualCPU; - } - class VirtualConsole - { - public: struct tSignals - { - inline static constexpr uint8_t Continue = 0x00; - inline static constexpr uint8_t ClearScreen = 0x01; - }; - - public: - inline VirtualConsole(hw::VirtualBIOSVideo& biosVideo, hw::VirtualCPU& cpu) : m_biosVideo(biosVideo), m_cpu(cpu) { } - inline bool isInitialized(void) const { return m_initialized; } - inline bool isRunning(void) const { return m_running; } - void initialize(void); - void update(void); - - private: - void handleEvents(void); - void finalizeRender(void); - void drawConsole(void); - - private: - ostd::ConsoleOutputHandler out; - dragon::VirtualConsoleOutputHandler vout; - - SDL_Window* m_window { nullptr }; - SDL_Renderer* m_renderer { nullptr }; - SDL_Texture* m_screenTexture { nullptr }; - SDL_Surface* m_fontSurface { nullptr }; - - int32_t m_windowWidth { 0 }; - int32_t m_windowHeight { 0 }; - - uint32_t* m_fontPixels { nullptr }; - uint32_t* m_screenPixels { nullptr }; - - bool m_redrawConsole { true }; - float m_timeAccumulator { 0.0f }; - bool m_running { false }; - - ostd::StringEditor m_title { "" }; - float m_redrawAccumulator { 0.0f }; - bool m_initialized { false }; - bool m_clearMemory { false }; - - hw::VirtualBIOSVideo& m_biosVideo; - hw::VirtualCPU& m_cpu; - std::vector m_palettes; - }; -} \ No newline at end of file diff --git a/src/gui/VirtualConsoleOutputHandler.cpp b/src/gui/VirtualConsoleOutputHandler.cpp deleted file mode 100644 index 5e738b6..0000000 --- a/src/gui/VirtualConsoleOutputHandler.cpp +++ /dev/null @@ -1,303 +0,0 @@ -#include "VirtualConsoleOutputHandler.hpp" -#include "RawTextRenderer.hpp" - -#include -#include - -namespace dragon -{ - tRichChar RichString::at(uint32_t index) const - { - if (index >= m_text.size()) - { - OX_WARN("ox::RichString::at(...): Index out of bounds."); - return tRichChar(); - } - return { (unsigned char)m_text[index], m_foreground[index], m_background[index] }; - } - - void RichString::add(tRichChar rchar) - { - m_text += rchar.ascii; - m_foreground.push_back(rchar.foreground); - m_background.push_back(rchar.background); - } - - void RichString::add(ostd::String str, ostd::Color fg, ostd::Color bg) - { - for (auto& c : str) - { - m_text += c; - m_foreground.push_back(fg); - m_background.push_back(bg); - } - } - - void RichString::add(ostd::String str) - { - ostd::Color fcol(255); - ostd::Color bcol(0, 0); - if (m_text.length() > 0) - { - fcol = m_foreground[m_foreground.size() - 1]; - bcol = m_background[m_background.size() - 1]; - } - add(str, fcol, bcol); - } - - void RichString::clear(void) - { - m_text = ""; - m_background.clear(); - m_foreground.clear(); - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::col(ostd::String color) - { - //TODO: Maybe implement?? - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::col(const ostd::Color& color) - { - m_currentForegroundColor = color; - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::p(char c) - { - check_if_new_line(); - m_currentBufferEditor.add(c); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::p(const ostd::StringEditor& se) - { - check_if_new_line(); - m_currentBufferEditor.add(se.str()); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint8_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int8_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint16_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int16_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint32_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int32_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(uint64_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pi(int64_t i) - { - check_if_new_line(); - m_currentBufferEditor.addi(i); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pf(float f, uint8_t precision) - { - //TODO: Implement precision - check_if_new_line(); - m_currentBufferEditor.addf(f); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::pf(double f, uint8_t precision) - { - //TODO: Implement precision - check_if_new_line(); - m_currentBufferEditor.addf(f); - add_current_to_rich_buffer(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::nl(void) - { - m_newLine = true; - flush(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::flush(void) - { - if (!isInitialized()) return *this; - if (m_currentBuffer.getText() == "") return *this; - - m_lines.push_back(m_currentBuffer); - m_currentBuffer.clear(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::reset(void) - { - m_currentBuffer.clear(); - m_currentBufferEditor.clr(); - m_lines.clear(); - m_newLine = true; - resetColors(); - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::clear(void) - { - //TODO: Implement - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::bgcol(const ostd::Color& color) - { - m_currentBackgroundColor = color; - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::bgcol(ostd::String color) - { - //TODO: Maybe implement - return *this; - } - - ostd::legacy::IOutputHandler& VirtualConsoleOutputHandler::resetColors(void) - { - m_currentForegroundColor = m_defaultForegroundColor; - m_currentBackgroundColor = m_defaultBackgroundColor; - return *this; - } - - void VirtualConsoleOutputHandler::init(uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels) - { - m_screenPixels = screenPixels; - m_fontPixels = fontPixels; - m_screenHeight = screenHeight; - m_screenWidth = screenWidth; - - m_initialized = m_screenHeight > 0 && m_screenWidth > 0 && m_screenPixels != nullptr && m_fontPixels != nullptr; - } - - void VirtualConsoleOutputHandler::add_current_to_rich_buffer(void) - { - if (m_currentBuffer.getText().length() + m_currentBufferEditor.len() <= RawTextRenderer::CONSOLE_CHARS_H) - { - m_currentBuffer.add(m_currentBufferEditor.str(), m_currentForegroundColor, m_currentBackgroundColor); - m_currentBufferEditor.clr(); - if (m_currentBuffer.getText().length() == RawTextRenderer::CONSOLE_CHARS_H) - nl(); - else - m_newLine = false; - return; - } - int32_t extraStringLength = (m_currentBuffer.getText().length() + m_currentBufferEditor.len()) - RawTextRenderer::CONSOLE_CHARS_H; - ostd::String excess = m_currentBufferEditor.substr(RawTextRenderer::CONSOLE_CHARS_H); - ostd::String end = m_currentBufferEditor.substr(0, RawTextRenderer::CONSOLE_CHARS_H); - m_currentBuffer.add(end, m_currentForegroundColor, m_currentBackgroundColor); - nl(); - m_currentBufferEditor = excess; - add_current_to_rich_buffer(); - } - - void VirtualConsoleOutputHandler::check_if_new_line(void) - { - if (m_newLine) return; - if (m_lines.size() > 0) - { - m_currentBuffer = m_lines[m_lines.size() - 1]; - m_lines.pop_back(); - } - - } - - void VirtualConsoleOutputHandler::draw_rich_String(const RichString& rstr, uint32_t row) - { - for (int32_t i = 0; i < rstr.getText().length(); i++) - { - auto rchar = rstr.at(i); - RawTextRenderer::drawString(ostd::StringEditor().add(rchar.ascii).str(), i, row, m_screenPixels, m_screenWidth, m_screenHeight, m_fontPixels, rchar.foreground, rchar.background); - } - } - - void VirtualConsoleOutputHandler::refreshScreen(void) - { - uint32_t row = 0; - if (m_lines.size() > RawTextRenderer::CONSOLE_CHARS_V - 1) - { - if (m_fixedScreen) - { - for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V; i++) - { - draw_rich_String(m_lines[i], row); - row++; - } - } - else - { - for (int32_t i = m_lines.size() - RawTextRenderer::CONSOLE_CHARS_V + 1; i < m_lines.size(); i++) - { - draw_rich_String(m_lines[i], row); - row++; - } - } - } - else - { - for (auto& line : m_lines) - { - draw_rich_String(line, row); - row++; - } - } - - m_lines.clear(); - m_currentBuffer.clear(); - m_currentBufferEditor.clr(); - } -} \ No newline at end of file diff --git a/src/gui/VirtualConsoleOutputHandler.hpp b/src/gui/VirtualConsoleOutputHandler.hpp deleted file mode 100644 index 666b114..0000000 --- a/src/gui/VirtualConsoleOutputHandler.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include - -namespace dragon -{ - struct tRichChar - { - unsigned char ascii { 0 }; - ostd::Color foreground { 0, 0 }; - ostd::Color background { 0, 0 }; - }; - - class RichString //TODO: Legacy RichString should be replaced with new tStyledString - { - public: - inline RichString(void) { } - inline ostd::String getText(void) const { return m_text; } - tRichChar at(uint32_t index) const; - void add(tRichChar rchar); - void add(ostd::String str, ostd::Color fg, ostd::Color bg); - void add(ostd::String str); - void clear(void); - - private: - ostd::String m_text { "" }; - std::vector m_foreground; - std::vector m_background; - }; - - class VirtualConsoleOutputHandler : public ostd::legacy::IOutputHandler - { - public: - ostd::legacy::IOutputHandler& col(ostd::String color) override; - ostd::legacy::IOutputHandler& col(const ostd::Color& color) override; - ostd::legacy::IOutputHandler& p(char c) override; - ostd::legacy::IOutputHandler& p(const ostd::StringEditor& se) override; - ostd::legacy::IOutputHandler& pi(uint8_t i) override; - ostd::legacy::IOutputHandler& pi(int8_t i) override; - ostd::legacy::IOutputHandler& pi(uint16_t i) override; - ostd::legacy::IOutputHandler& pi(int16_t i) override; - ostd::legacy::IOutputHandler& pi(uint32_t i) override; - ostd::legacy::IOutputHandler& pi(int32_t i) override; - ostd::legacy::IOutputHandler& pi(uint64_t i) override; - ostd::legacy::IOutputHandler& pi(int64_t i) override; - ostd::legacy::IOutputHandler& pf(float f, uint8_t precision = 0) override; - ostd::legacy::IOutputHandler& pf(double f, uint8_t precision = 0) override; - ostd::legacy::IOutputHandler& nl(void) override; - inline ostd::legacy::IOutputHandler& pStyled(const ostd::StringEditor& styled) override { return *this; } //TODO: Implement - inline ostd::legacy::IOutputHandler& pStyled(const ostd::TextStyleBuilder::IRichStringBase& styled) override { return *this; } //TODO: Implement - inline ostd::legacy::IOutputHandler& pStyled(const ostd::TextStyleParser::tStyledString& styled) override { return *this; }; //TODO: Implement - ostd::legacy::IOutputHandler& flush(void) override; - ostd::legacy::IOutputHandler& reset(void) override; - ostd::legacy::IOutputHandler& clear(void) override; - - ostd::legacy::IOutputHandler& bgcol(const ostd::Color& color) override; - ostd::legacy::IOutputHandler& bgcol(ostd::String color) override; - ostd::legacy::IOutputHandler& resetColors(void) override; - - void init(uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels); - inline bool isInitialized(void) const { return m_initialized; } - inline bool isFixedScreen(void) const { return m_fixedScreen; } - inline void enableFixedScreen(bool fs = true) { m_fixedScreen = fs; } - - void refreshScreen(void); - - private: - void add_current_to_rich_buffer(void); - void check_if_new_line(void); - void draw_rich_String(const RichString& rstr, uint32_t row); - - private: - std::vector m_lines; - RichString m_currentBuffer; - ostd::StringEditor m_currentBufferEditor; - - // std::vector m_allLines; - // ostd::StringEditor m_buffer; - // int32_t m_currentRow { 0 }; - // int32_t m_currentColumn { 0 }; - ostd::Color m_currentForegroundColor { 255, 255, 255, 255 }; - ostd::Color m_currentBackgroundColor { 255, 255, 255, 0 }; - ostd::Color m_defaultForegroundColor { 255, 255, 255, 255 }; - ostd::Color m_defaultBackgroundColor { 255, 255, 255, 0 }; - - uint32_t* m_screenPixels { nullptr }; - uint32_t* m_fontPixels { nullptr }; - int32_t m_screenWidth { 0 }; - int32_t m_screenHeight { 0 }; - bool m_initialized { false }; - bool m_newLine { true }; - bool m_fixedScreen { false }; - }; -} \ No newline at end of file diff --git a/src/gui/Window.cpp b/src/gui/Window.cpp index dd624e9..f7329ce 100644 --- a/src/gui/Window.cpp +++ b/src/gui/Window.cpp @@ -2,25 +2,51 @@ namespace dragon { - void Window::initialize(int32_t width, int32_t height, const ostd::String& fontPath) + Window::~Window(void) { + onDestroy(); + SDL_FreeSurface(m_fontSurface); + SDL_DestroyRenderer(m_renderer); + SDL_DestroyWindow(m_window); + IMG_Quit(); + SDL_Quit(); + } + + void Window::initialize(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath) + { + if (m_initialized) return; m_windowWidth = width; m_windowHeight = height; - - SDL_Init(SDL_INIT_VIDEO); + m_title = windowTitle; + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + printf( "SDL could not initialize! Error: %s\n", SDL_GetError() ); + exit(1); + } + int imgFlags = IMG_INIT_PNG; + if (!(IMG_Init(imgFlags) & imgFlags)) + { + printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() ); + exit(2); + } m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE); SDL_SetWindowResizable(m_window, SDL_FALSE); m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED); SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight); - // m_screenTexture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, m_windowWidth, m_windowHeight); + SDL_SetWindowTitle(m_window, m_title.c_str()); m_fontSurface = SDL_LoadBMP(fontPath.c_str()); if (m_fontSurface == NULL) out.bg(ostd::ConsoleColors::Red).p("Error loading font.").reset().nl(); m_fontPixels = (uint32_t*)m_fontSurface->pixels; - // m_screenPixels = (uint32_t*)malloc(m_windowWidth * m_windowHeight * 4); m_initialized = true; m_running = true; + + setTypeName("lspp::app::Window"); + enableSignals(true); + validate(); + + onInitialize(); } void Window::update(void) @@ -28,24 +54,16 @@ namespace dragon if (!m_initialized) return; Uint64 start = SDL_GetPerformanceCounter(); handleEvents(); + onUpdate(); SDL_RenderClear(m_renderer); - for (int32_t i = 0; i < m_widgets.size(); i++) - { - if (m_widgets[i] == nullptr) continue; - m_widgets[i]->draw(); - } + onRender(); SDL_RenderPresent(m_renderer); - // finalizeRender(); Uint64 end = SDL_GetPerformanceCounter(); float elapsed = (end - start) / (float)SDL_GetPerformanceFrequency(); m_redrawAccumulator += elapsed; if (m_redrawAccumulator >= 0.2f) { - for (int32_t i = 0; i < m_widgets.size(); i++) - { - if (m_widgets[i] == nullptr) continue; - m_widgets[i]->fixedUpdate(); - } + onFixedUpdate(); m_redrawAccumulator = 0.0f; } end = SDL_GetPerformanceCounter(); @@ -53,46 +71,78 @@ namespace dragon m_timeAccumulator += elapsed; if (m_timeAccumulator >= 0.5f) { - for (int32_t i = 0; i < m_widgets.size(); i++) - { - if (m_widgets[i] == nullptr) continue; - m_widgets[i]->slowUpdate(); - } - m_title.clr().add("FPS: ").addi((int)(1.0f / elapsed)); - SDL_SetWindowTitle(m_window, m_title.c_str()); + onSlowUpdate(); + m_fps = (int32_t)(1.0f / elapsed); m_timeAccumulator = 0.0f; } } - bool Window::addWidget(Widget& widget) - { - widget.__init(*this); - m_widgets.push_back(&widget); - return true; - } - void Window::setSize(int32_t width, int32_t height) { if (!isInitialized()) return; SDL_SetWindowSize(m_window, width, height); } + void Window::setTitle(const ostd::String& title) + { + if (!isInitialized()) return; + m_title = title; + SDL_SetWindowTitle(m_window, m_title.c_str()); + } + void Window::handleEvents(void) { if (!m_initialized) return; + auto l_getMouseState = [this](void) -> MouseEventData { + int32_t mx = 0, my = 0; + uint32_t btn = SDL_GetMouseState(&mx, &my); + MouseEventData::eButton button = MouseEventData::eButton::None; + switch (btn) + { + case SDL_BUTTON(1): button = MouseEventData::eButton::Left; break; + case SDL_BUTTON(2): button = MouseEventData::eButton::Middle; break; + case SDL_BUTTON(3): button = MouseEventData::eButton::Right; break; + default: button = MouseEventData::eButton::None; break; + } + MouseEventData mmd(*this, mx, my, button); + return mmd; + }; SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { m_running = false; + ostd::SignalHandler::emitSignal(Signal_OnWindowClosed, ostd::tSignalPriority::Normal, *this); + } + else if (event.type == SDL_WINDOWEVENT) + { + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + WindowResizedData wrd(*this, m_windowWidth, m_windowHeight, 0, 0); + SDL_GetWindowSize(m_window, &m_windowWidth, &m_windowHeight); + wrd.new_width = m_windowWidth; + wrd.new_height = m_windowHeight; + ostd::SignalHandler::emitSignal(Signal_OnWindowResized, ostd::tSignalPriority::RealTime, wrd); + } + } + else if (event.type == SDL_MOUSEMOTION) + { + MouseEventData mmd = l_getMouseState(); + if (isMouseDragEventEnabled() && mmd.button != MouseEventData::eButton::None) + ostd::SignalHandler::emitSignal(Signal_OnMouseDragged, ostd::tSignalPriority::RealTime, mmd); + else + ostd::SignalHandler::emitSignal(Signal_OnMouseMoved, ostd::tSignalPriority::RealTime, mmd); + } + else if (event.type == SDL_MOUSEBUTTONDOWN) + { + MouseEventData mmd = l_getMouseState(); + ostd::SignalHandler::emitSignal(Signal_OnMousePressed, ostd::tSignalPriority::RealTime, mmd); + } + else if (event.type == SDL_MOUSEBUTTONUP) + { + MouseEventData mmd = l_getMouseState(); + ostd::SignalHandler::emitSignal(Signal_OnMouseReleased, ostd::tSignalPriority::RealTime, mmd); } } } - - void Window::finalizeRender(void) - { - // SDL_UpdateTexture(m_screenTexture, NULL, m_screenPixels, m_windowWidth * 4); - // SDL_RenderCopy(m_renderer, m_screenTexture, NULL, NULL); - } } \ No newline at end of file diff --git a/src/gui/Window.hpp b/src/gui/Window.hpp index 2823d5f..765a642 100644 --- a/src/gui/Window.hpp +++ b/src/gui/Window.hpp @@ -3,55 +3,105 @@ #include "../tools/SDLInclude.hpp" #include #include -#include "VirtualConsoleOutputHandler.hpp" -#include "../tools/GlobalData.hpp" -#include "../gui/widgets/Widget.hpp" +#include namespace dragon { - class Window + class Window : public ostd::BaseObject { public: inline Window(void) { } + ~Window(void); + inline Window(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath) { initialize(width, height, windowTitle, fontPath); } + void initialize(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath); + + void update(void); + void setSize(int32_t width, int32_t height); + void setTitle(const ostd::String& title); + + inline virtual void onRender(void) { } + inline virtual void onUpdate(void) { } + inline virtual void onFixedUpdate(void) { } + inline virtual void onSlowUpdate(void) { } + inline virtual void onInitialize(void) { } + inline virtual void onDestroy(void) { } + inline bool isInitialized(void) const { return m_initialized; } inline bool isRunning(void) const { return m_running; } inline void hide(void) { SDL_HideWindow(m_window); } inline void show(void) { SDL_ShowWindow(m_window); } - void initialize(int32_t width, int32_t height, const ostd::String& fontPath); - void update(void); - bool addWidget(Widget& widget); - void setSize(int32_t width, int32_t height); + inline ostd::String getTitle(void) const { return m_title; } + inline int32_t getFPS(void) const { return m_fps; } + inline int32_t getWindowWidth(void) const { return m_windowWidth; } + inline int32_t getWindowHeight(void) const { return m_windowHeight; } + inline SDL_Renderer* getSDLRenderer(void) const { return m_renderer; } + inline bool isMouseDragEventEnabled(void) const { return m_deagEventEnabled; } + inline void enableMouseDragEvent(bool enable = true) { m_deagEventEnabled = enable; } private: void handleEvents(void); - void finalizeRender(void); - private: + protected: ostd::ConsoleOutputHandler out; - std::vector m_widgets; - SDL_Window* m_window { nullptr }; SDL_Renderer* m_renderer { nullptr }; - // SDL_Texture* m_screenTexture { nullptr }; SDL_Surface* m_fontSurface { nullptr }; + uint32_t* m_fontPixels { nullptr }; + private: int32_t m_windowWidth { 0 }; int32_t m_windowHeight { 0 }; - - uint32_t* m_fontPixels { nullptr }; - // uint32_t* m_screenPixels { nullptr }; + ostd::String m_title { "" }; + int32_t m_fps { 0 }; float m_timeAccumulator { 0.0f }; - bool m_running { false }; - - ostd::StringEditor m_title { "" }; float m_redrawAccumulator { 0.0f }; + + bool m_deagEventEnabled { false }; + bool m_running { false }; bool m_initialized { false }; + public: //Signals - inline static const uint32_t Signal_OnMousePressed = ostd::SignalHandler::newCustomSignal(4096); + inline static const uint32_t Signal_OnMousePressed = ostd::SignalHandler::newCustomSignal(1000); + inline static const uint32_t Signal_OnMouseReleased = ostd::SignalHandler::newCustomSignal(1001); + inline static const uint32_t Signal_OnMouseMoved = ostd::SignalHandler::newCustomSignal(1002); + inline static const uint32_t Signal_OnMouseDragged = ostd::SignalHandler::newCustomSignal(1003); - friend class VirtualConsoleWidtget; + inline static const uint32_t Signal_OnWindowClosed = ostd::SignalHandler::newCustomSignal(2000); + inline static const uint32_t Signal_OnWindowResized = ostd::SignalHandler::newCustomSignal(2001); + }; + class WindowResizedData : public ostd::BaseObject + { + public: + inline WindowResizedData(Window& parent, int32_t _oldx, int32_t _oldy, int32_t _newx, int32_t _newy) : parentWindow(parent), old_width(_oldx), old_height(_oldy), new_width(_newx), new_height(_newy) + { + setTypeName("lspp::app::WindowResizedData"); + validate(); + } + + public: + int32_t new_width; + int32_t new_height; + int32_t old_width; + int32_t old_height; + Window& parentWindow; + }; + class MouseEventData : public ostd::BaseObject + { + public: enum class eButton { None = 0, Left, Middle, Right }; + public: + inline MouseEventData(Window& parent, int32_t mousex, int32_t mousey, eButton btn) : parentWindow(parent), position_x(mousex), position_y(mousey), button(btn) + { + setTypeName("lspp::app::MouseEventData"); + validate(); + } + + public: + int32_t position_x; + int32_t position_y; + eButton button; + Window& parentWindow; }; } \ No newline at end of file diff --git a/src/gui/widgets/VirtualConsoleWidget.cpp b/src/gui/widgets/VirtualConsoleWidget.cpp deleted file mode 100644 index 6445c96..0000000 --- a/src/gui/widgets/VirtualConsoleWidget.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "VirtualConsoleWidget.hpp" -#include "../../gui/RawTextRenderer.hpp" -#include "../../gui/Window.hpp" -#include "../../hardware/VirtualIODevices.hpp" -#include "../../hardware/VirtualCPU.hpp" - -namespace dragon -{ - void VirtualConsoleWidtget::init(void) - { - setw(RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W); //60 * 16; - seth(RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H); //60 * 9; - setPosition(0, 0); - - dragon::RawTextRenderer::initialize(); - - m_pixels = new uint32_t[getw() * geth()]; //TODO: Delete (Memory Leak) - - vout.init(m_pixels, getw(), geth(), m_parent->m_fontPixels); - vout.enableFixedScreen(); - - m_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Possible Memory Leak, palettes are never destroyed - - m_texture = SDL_CreateTexture(m_parent->m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, getw(), geth()); - - m_initialized = true; - validate(); - } - - void VirtualConsoleWidtget::draw(void) - { - if (isInvalid()) return; - SDL_Rect rect { (int)getx(), (int)gety(), (int)getw(), (int)geth() }; - SDL_RenderCopy(m_parent->m_renderer, m_texture, NULL, &rect); - } - - void VirtualConsoleWidtget::drawConsole(void) - { - if (isInvalid()) return; - const uint8_t TRANSPARENCY_COLOR_INDEX = 0x5; - - uint8_t clearColor = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::ClearColor); - uint8_t palette = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Palette); - bool useTransparency = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::UseTransparencyOn0x5) != 0; - - if (palette >= m_palettes.size()) - palette = 0; //TODO: Error - - auto& pal = *m_palettes[palette]; - - ostd::Color clrCol = pal.getColor(clearColor); - if (m_clearMemory) - { - for (int y = 0; y < m_parent->m_windowHeight; ++y) - { - for (int x = 0; x < m_parent->m_windowWidth; ++x) - { - m_pixels[x + y * m_parent->m_windowWidth] = clrCol.asInteger(); - } - } - m_clearMemory = false; - } - - ostd::Color fgCol; - ostd::Color bgCol; - uint16_t index = hw::VirtualBIOSVideo::tRegisters::VideoMemoryStart; - - // if (m_clearMemory) - // { - // for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2) - // { - // m_biosVideo.write8((uint16_t)i, 0x00); - // m_biosVideo.write8((uint16_t)(i + 1), clearColor); - // } - // m_clearMemory = false; - // } - - for (int32_t i = index; i < (index + (RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * 2)); i += 2) - { - uint8_t character = m_biosVideo.read8((uint16_t)i); - uint8_t colors = m_biosVideo.read8((uint16_t)(i + 1)); - uint8_t bgcol = (colors >> 4) & 0xF; - uint8_t fgcol = (colors & 0xF); - if (!isprint(character)) - { - character = ' '; - fgCol = pal.getColor(fgcol); - bgCol = clrCol; - } - else - { - fgCol = pal.getColor(fgcol); - bgCol = pal.getColor(bgcol); - } - vout.bgcol(bgCol).col(fgCol).p((char)character).flush().bgcol(clrCol); - } - vout.refreshScreen(); - m_cpu.handleInterrupt(data::InterruptCodes::BiosVideoScreenRefresh); - } - - void VirtualConsoleWidtget::update(void) - { - - } - - void VirtualConsoleWidtget::fixedUpdate(void) - { - if (isInvalid()) return; - uint8_t signal = m_biosVideo.read8(hw::VirtualBIOSVideo::tRegisters::Signal); - switch (signal) - { - case tSignals::ClearScreen: - m_clearMemory = true; - break; - case tSignals::Continue: break; - default: break; - } - m_biosVideo.write8(hw::VirtualBIOSVideo::tRegisters::Signal, tSignals::Continue); - drawConsole(); - SDL_UpdateTexture(m_texture, NULL, m_pixels, getw() * 4); - } - - void VirtualConsoleWidtget::slowUpdate(void) - { - - } - -} \ No newline at end of file diff --git a/src/gui/widgets/VirtualConsoleWidget.hpp b/src/gui/widgets/VirtualConsoleWidget.hpp deleted file mode 100644 index 8258e51..0000000 --- a/src/gui/widgets/VirtualConsoleWidget.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include "Widget.hpp" - -#include "../../tools/SDLInclude.hpp" - -#include "../../gui/VirtualConsoleOutputHandler.hpp" -#include "../../tools/GlobalData.hpp" - -namespace dragon -{ - namespace hw - { - class VirtualBIOSVideo; - class VirtualCPU; - } - class VirtualConsoleWidtget : public Widget - { - public: struct tSignals - { - inline static constexpr uint8_t Continue = 0x00; - inline static constexpr uint8_t ClearScreen = 0x01; - }; - public: - inline VirtualConsoleWidtget(hw::VirtualBIOSVideo& biosVideo, hw::VirtualCPU& cpu) : m_biosVideo(biosVideo), m_cpu(cpu) { invalidate(); } - void init(void) override; - void draw(void) override; - void update(void) override; - void fixedUpdate(void) override; - void slowUpdate(void) override; - - inline bool isInitialized(void) const { return m_initialized; } - - private: - void drawConsole(void); - - private: - dragon::VirtualConsoleOutputHandler vout; - - // SDL_Window* m_window { nullptr }; - // SDL_Renderer* m_renderer { nullptr }; - // SDL_Texture* m_screenTexture { nullptr }; - // SDL_Surface* m_fontSurface { nullptr }; - - // int32_t m_windowWidth { 0 }; - // int32_t m_windowHeight { 0 }; - - // uint32_t* m_fontPixels { nullptr }; - // uint32_t* m_screenPixels { nullptr }; - - uint32_t* m_pixels { nullptr }; - SDL_Texture* m_texture; - - // bool m_redrawConsole { true }; - // float m_timeAccumulator { 0.0f }; - // bool m_running { false }; - - // ostd::StringEditor m_title { "" }; - // float m_redrawAccumulator { 0.0f }; - bool m_initialized { false }; - bool m_clearMemory { false }; - - hw::VirtualBIOSVideo& m_biosVideo; - hw::VirtualCPU& m_cpu; - std::vector m_palettes; - }; -} \ No newline at end of file diff --git a/src/gui/widgets/Widget.hpp b/src/gui/widgets/Widget.hpp deleted file mode 100644 index cdcc23b..0000000 --- a/src/gui/widgets/Widget.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace dragon -{ - class Window; - class Widget : public ostd::Rectangle, public ostd::BaseObject - { - public: - void __init(Window& parent) { m_parent = &parent; init(); } - virtual void draw(void) { } - virtual void update(void) { } - virtual void fixedUpdate(void) { } - virtual void slowUpdate(void) { } - - protected: - virtual void init(void) { } - - protected: - Window* m_parent { nullptr }; - }; -} \ No newline at end of file diff --git a/src/hardware/MemoryMapper.cpp b/src/hardware/MemoryMapper.cpp index 518d8bd..4a01d4d 100644 --- a/src/hardware/MemoryMapper.cpp +++ b/src/hardware/MemoryMapper.cpp @@ -68,7 +68,7 @@ namespace dragon if (address >= region.startAddress && address <= region.endAddress) return ®ion; } - data::ErrorHandler::pushError(data::ErrorCodes::MM_RegionNotFound, ostd::StringEditor("Memory device not found for address: ").add(ostd::Utils::getHexStr(address, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::MM_RegionNotFound, ostd::String("Memory device not found for address: ").add(ostd::Utils::getHexStr(address, true, 2))); return nullptr; //TODO: Error } } diff --git a/src/hardware/MemoryMapper.hpp b/src/hardware/MemoryMapper.hpp index 525deec..be1ba90 100644 --- a/src/hardware/MemoryMapper.hpp +++ b/src/hardware/MemoryMapper.hpp @@ -1,6 +1,7 @@ #pragma once #include "IMemoryDevice.hpp" +#include #include namespace dragon diff --git a/src/hardware/VirtualCPU.cpp b/src/hardware/VirtualCPU.cpp index 8a98026..411fafe 100644 --- a/src/hardware/VirtualCPU.cpp +++ b/src/hardware/VirtualCPU.cpp @@ -1,6 +1,7 @@ #include "VirtualCPU.hpp" #include "../tools/GlobalData.hpp" +#include #include #include @@ -10,8 +11,8 @@ namespace dragon { VirtualCPU::VirtualCPU(IMemoryDevice& memory) : m_memory(memory) { - writeRegister(data::Registers::SP, (uint16_t)(0xFFFF - 1 - 1)); - writeRegister(data::Registers::FP, (uint16_t)(0xFFFF - 1 - 1)); + writeRegister(data::Registers::SP, (uint16_t)(0xFFFF - 1)); + writeRegister(data::Registers::FP, (uint16_t)(0xFFFF - 1)); } int16_t VirtualCPU::readRegister(uint8_t reg) @@ -62,6 +63,11 @@ namespace dragon void VirtualCPU::pushStackFrame(void) { + if (m_debugModeEnabled) + { + __debug_store_stack_frame_string_on_push(); + return; + } uint16_t argStartAddr = readRegister(data::Registers::SP) + 2; uint16_t argCount = m_memory.read16(argStartAddr); if (argCount == 0) @@ -82,7 +88,8 @@ namespace dragon pushToStack(readRegister(data::Registers::PP)); pushToStack(readRegister(data::Registers::ACC)); pushToStack(readRegister(data::Registers::IP)); - pushToStack(m_stackFrameSize + 2); + pushToStack(readRegister(data::Registers::FP)); + pushToStack(m_stackFrameSize); writeRegister(data::Registers::PP, argStartAddr); writeRegister(data::Registers::FP, readRegister(data::Registers::SP)); @@ -94,8 +101,9 @@ namespace dragon uint16_t framePointerAddr = readRegister(data::Registers::FP); writeRegister(data::Registers::SP, framePointerAddr); m_stackFrameSize = popFromStack(); - uint16_t tmpStackFrameSize = m_stackFrameSize; + // uint16_t tmpStackFrameSize = m_stackFrameSize; + writeRegister(data::Registers::FP, popFromStack()); writeRegister(data::Registers::IP, popFromStack()); writeRegister(data::Registers::ACC, popFromStack()); writeRegister(data::Registers::PP, popFromStack()); @@ -112,9 +120,12 @@ namespace dragon uint16_t nArgs = popFromStack(); for (int32_t i = 0; i < nArgs; i++) + { popFromStack(); + // writeRegister(data::Registers::FP, readRegister(data::Registers::FP) - 2); + } - writeRegister(data::Registers::FP, framePointerAddr + tmpStackFrameSize); + // writeRegister(data::Registers::FP, framePointerAddr + tmpStackFrameSize); } bool VirtualCPU::readFlag(uint8_t flg) @@ -134,7 +145,6 @@ namespace dragon void VirtualCPU::handleInterrupt(uint8_t intValue) { - // std::cout << "Interrupt: " << ostd::Utils::getHexStr(intValue, true, 1) << "\n"; uint16_t entryPointer = data::MemoryMapAddresses::IntVector_Start + (intValue * 3); uint8_t interruptStatus = m_memory.read8(entryPointer); if (interruptStatus != 0xFF) return; @@ -664,6 +674,7 @@ namespace dragon uint16_t subroutineAddr = fetch16(); pushStackFrame(); writeRegister(data::Registers::IP, subroutineAddr); + m_subroutineCounter++; } break; case data::OpCodes::CallReg: @@ -672,17 +683,22 @@ namespace dragon uint16_t subroutineAddr = readRegister(regAddr); pushStackFrame(); writeRegister(data::Registers::IP, subroutineAddr); + m_subroutineCounter++; } break; case data::OpCodes::Ret: { popStackFrame(); + // m_subroutineCounter = ZERO(m_subroutineCounter - 1); + m_subroutineCounter--; } break; case data::OpCodes::RetInt: { m_isInInterruptHandler = false; popStackFrame(); + // m_subroutineCounter = ZERO(m_subroutineCounter - 1); + m_subroutineCounter--; } break; case data::OpCodes::Int: @@ -691,11 +707,12 @@ namespace dragon if (!readFlag(data::Flags::InterruptsEnabled)) return true; handleInterrupt(intValue); + m_subroutineCounter++; } break; default: { - data::ErrorHandler::pushError(data::ErrorCodes::CPU_UnknownInstruction, ostd::StringEditor("Unknown instruction: ").add(ostd::Utils::getHexStr(inst, true, 1)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CPU_UnknownInstruction, ostd::String("Unknown instruction: ").add(ostd::Utils::getHexStr(inst, true, 1))); m_halt = true; return false; } @@ -703,5 +720,60 @@ namespace dragon return true; } + + void VirtualCPU::__debug_store_stack_frame_string_on_push(void) + { + if (!m_debugModeEnabled) return; + ostd::String stackFrameString = ""; + + uint16_t argStartAddr = readRegister(data::Registers::SP) + 2; + uint16_t argCount = m_memory.read16(argStartAddr); + if (argCount == 0) + argStartAddr = 0; + else + argStartAddr += (argCount * 2); + + stackFrameString.add("args: ").add(ostd::Utils::getHexStr(argStartAddr, true, 2)).add(", argc: ").add(argCount).add("\n"); + + pushToStack(readRegister(data::Registers::R1)); + stackFrameString.add("R1: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R1), true, 2)); + pushToStack(readRegister(data::Registers::R2)); + stackFrameString.add(" R2: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R2), true, 2)); + pushToStack(readRegister(data::Registers::R3)); + stackFrameString.add(" R3: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R3), true, 2)); + pushToStack(readRegister(data::Registers::R4)); + stackFrameString.add(" R4: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R4), true, 2)); + pushToStack(readRegister(data::Registers::R5)); + stackFrameString.add(" R5: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R5), true, 2)); + pushToStack(readRegister(data::Registers::R6)); + stackFrameString.add(" R6: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R6), true, 2)); + pushToStack(readRegister(data::Registers::R7)); + stackFrameString.add(" R7: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R7), true, 2)); + pushToStack(readRegister(data::Registers::R8)); + stackFrameString.add(" R8: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R8), true, 2)); + pushToStack(readRegister(data::Registers::R9)); + stackFrameString.add(" R9: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R9), true, 2)); + pushToStack(readRegister(data::Registers::R10)); + stackFrameString.add(" R10: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::R10), true, 2)); + stackFrameString.add("\n"); + pushToStack(readRegister(data::Registers::PP)); + stackFrameString.add("PP: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::PP), true, 2)); + pushToStack(readRegister(data::Registers::ACC)); + stackFrameString.add(" ACC: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::ACC), true, 2)); + pushToStack(readRegister(data::Registers::IP)); + stackFrameString.add(" IP: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::IP), true, 2)); + pushToStack(readRegister(data::Registers::FP)); + stackFrameString.add(" FP: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::FP), true, 2)); + stackFrameString.add("\n"); + pushToStack(m_stackFrameSize); + stackFrameString.add("StackFrame: ").add(m_stackFrameSize).add(", "); + + writeRegister(data::Registers::PP, argStartAddr); + writeRegister(data::Registers::FP, readRegister(data::Registers::SP)); + stackFrameString.add("New FP: ").add(ostd::Utils::getHexStr(readRegister(data::Registers::FP), true, 2)); + m_stackFrameSize = 0; + + m_debug_stackFrameStrings.push_back(stackFrameString); + } } } \ No newline at end of file diff --git a/src/hardware/VirtualCPU.hpp b/src/hardware/VirtualCPU.hpp index 4ffdf89..854a6e3 100644 --- a/src/hardware/VirtualCPU.hpp +++ b/src/hardware/VirtualCPU.hpp @@ -5,6 +5,8 @@ #include #include "IMemoryDevice.hpp" +#include "../debugger/Debugger.hpp" + namespace dragon { class DragonRuntime; @@ -36,6 +38,11 @@ namespace dragon inline bool isHalted(void) const { return m_halt; } inline uint8_t getCurrentInstruction(void) const { return m_currentInst; } inline bool isInDebugBreakPoint(void) const { return m_isDebugBreakPoint; } + inline bool isInSubRoutine(void) const { return m_subroutineCounter > 0; } + inline int32_t getSubRoutineCounter(void) const { return m_subroutineCounter; } + + private: + void __debug_store_stack_frame_string_on_push(void); private: int16_t m_registers[20]; @@ -47,8 +54,14 @@ namespace dragon bool m_biosMode { true }; bool m_isInInterruptHandler { false }; bool m_isDebugBreakPoint { false }; + bool m_debugModeEnabled { false }; + int32_t m_subroutineCounter { 0 }; + + std::vector m_debug_stackFrameStrings; friend class dragon::DragonRuntime; + friend class dragon::Debugger::Display; + friend class dragon::Debugger; }; } } \ No newline at end of file diff --git a/src/hardware/VirtualHardDrive.cpp b/src/hardware/VirtualHardDrive.cpp index 704abd9..a264c32 100644 --- a/src/hardware/VirtualHardDrive.cpp +++ b/src/hardware/VirtualHardDrive.cpp @@ -9,10 +9,10 @@ namespace dragon { void VirtualHardDrive::init(const ostd::String& dataFilePath) { - m_dataFile.open(dataFilePath, std::ios::out | std::ios::in | std::ios::binary); + m_dataFile.open(dataFilePath.cpp_str(), std::ios::out | std::ios::in | std::ios::binary); if(!m_dataFile) { - data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_UnableToMount, ostd::StringEditor("Unable to mount virtual HardDrive: ").add(dataFilePath).str()); + data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_UnableToMount, ostd::String("Unable to mount virtual HardDrive: ").add(dataFilePath)); return; } m_fileSize = m_dataFile.tellg(); diff --git a/src/hardware/VirtualIODevices.cpp b/src/hardware/VirtualIODevices.cpp index 4d2cef4..290f3e9 100644 --- a/src/hardware/VirtualIODevices.cpp +++ b/src/hardware/VirtualIODevices.cpp @@ -15,22 +15,22 @@ namespace dragon bool loaded = ostd::Utils::loadByteStreamFromFile(biosFilePath, m_bios); if (!loaded) data::ErrorHandler::pushError(data::ErrorCodes::BIOS_FailedToLoad, "Failed to load BIOS data."); - if (m_bios.size() != 1024) - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidSize, ostd::StringEditor("Invalid BIOS size: ").add(ostd::Utils::getHexStr(m_bios.size(), true, 2)).str()); + if (m_bios.size() != 4096) //TODO: Hardcoded + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidSize, ostd::String("Invalid BIOS size: ").add(ostd::Utils::getHexStr(m_bios.size(), true, 2))); m_initialized = true; } int8_t VirtualBIOS::read8(uint16_t addr) { if (addr >= m_bios.size()) - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Byte BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::String("Invalid Byte BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return m_bios[addr]; } int16_t VirtualBIOS::read16(uint16_t addr) { if (addr >= m_bios.size() - 1) - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Word BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::String("Invalid Word BIOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return ((m_bios[addr + 0] << 8) & 0xFF00U) | ( m_bios[addr + 1] & 0x00FFU); } @@ -66,14 +66,14 @@ namespace dragon int8_t InterruptVector::read8(uint16_t addr) { if (addr >= m_data.size()) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Byte IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Byte IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return m_data[addr]; } int16_t InterruptVector::read16(uint16_t addr) { if (addr >= m_data.size() - 1) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return ((m_data[addr + 0] << 8) & 0xFF00U) | ( m_data[addr + 1] & 0x00FFU); } @@ -81,7 +81,7 @@ namespace dragon int8_t InterruptVector::write8(uint16_t addr, int8_t value) { if (addr >= m_data.size()) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); m_data[addr] = value; return value; } @@ -89,7 +89,7 @@ namespace dragon int16_t InterruptVector::write16(uint16_t addr, int16_t value) { if (addr >= m_data.size() - 1) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); m_data[addr + 0] = (value >> 8) & 0xFF; m_data[addr + 1] = value & 0xFF; return value; @@ -179,14 +179,14 @@ namespace dragon int8_t VirtualBootloader::read8(uint16_t addr) { if (addr >= m_mbr.size()) - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Byte MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::String("Invalid Byte MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return m_mbr[addr]; } int16_t VirtualBootloader::read16(uint16_t addr) { if (addr >= m_mbr.size() - 1) - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::StringEditor("Invalid Word MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_InvalidAddress, ostd::String("Invalid Word MBR location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return ((m_mbr[addr + 0] << 8) & 0xFF00U) | ( m_mbr[addr + 1] & 0x00FFU); } @@ -194,7 +194,7 @@ namespace dragon int8_t VirtualBootloader::write8(uint16_t addr, int8_t value) { if (addr >= m_mbr.size()) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); m_mbr[addr] = value; return value; } @@ -202,7 +202,7 @@ namespace dragon int16_t VirtualBootloader::write16(uint16_t addr, int16_t value) { if (addr >= m_mbr.size() - 1) - data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::StringEditor("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::IntVector_InvalidAddress, ostd::String("Invalid Word IntVector location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); m_mbr[addr + 0] = (value >> 8) & 0xFF; m_mbr[addr + 1] = value & 0xFF; return value; @@ -216,57 +216,6 @@ namespace dragon - - VirtualBIOSVideo::VirtualBIOSVideo(VirtualRAM& memory) : m_memory(memory) - { - intptr_t iMemPtr = reinterpret_cast(memory.getByteStream()->data()); - iMemPtr += data::MemoryMapAddresses::BIOSVideo_Start; - m_dataPtr = reinterpret_cast(iMemPtr); - } - - int8_t VirtualBIOSVideo::read8(uint16_t addr) - { - if (addr >= m_size) - data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Byte BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); - return m_dataPtr[addr]; - } - - int16_t VirtualBIOSVideo::read16(uint16_t addr) - { - if (addr >= m_size - 1) - data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Word BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); - return ((m_dataPtr[addr + 0] << 8) & 0xFF00U) - | ( m_dataPtr[addr + 1] & 0x00FFU); - } - - int8_t VirtualBIOSVideo::write8(uint16_t addr, int8_t value) - { - if (addr >= m_size) - data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Byte BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); - m_dataPtr[addr] = value; - return value; - } - - int16_t VirtualBIOSVideo::write16(uint16_t addr, int16_t value) - { - if (addr >= m_size - 1) - data::ErrorHandler::pushError(data::ErrorCodes::BIOSVideo_InvalidAddress, ostd::StringEditor("Invalid read Word BiosVideo location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); - m_dataPtr[addr + 0] = (value >> 8) & 0xFF; - m_dataPtr[addr + 1] = value & 0xFF; - return value; - } - - ostd::ByteStream* VirtualBIOSVideo::getByteStream(void) - { - m_dataCopy.clear(); - m_dataCopy.insert(m_dataCopy.end(), &m_dataPtr[0], &m_dataPtr[m_size]); - return &m_dataCopy; - } - - - - - namespace interface { Disk::Disk(MemoryMapper& memory, VirtualCPU& cpu) : m_memory(memory), m_cpu(cpu) @@ -556,7 +505,7 @@ namespace dragon void CMOS::init(const ostd::String& cmosFilePath) { m_size = data::MemoryMapAddresses::CMOS_End - data::MemoryMapAddresses::CMOS_Start + 1; - m_dataFile.open(cmosFilePath, std::ios::out | std::ios::in | std::ios::binary); + m_dataFile.open(cmosFilePath.cpp_str(), std::ios::out | std::ios::in | std::ios::binary); if(!m_dataFile) { data::ErrorHandler::pushError(data::ErrorCodes::CMOS_UnableToMount, "Unable to mount virtual CMOS chip."); @@ -568,7 +517,7 @@ namespace dragon m_dataFile.seekg( 0, std::ios::beg ); if (m_fileSize != m_size) { - data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidSize, ostd::StringEditor("Invalid virtual CMOS chhip size: ").addi(m_fileSize).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidSize, ostd::String("Invalid virtual CMOS chhip size: ").add(m_fileSize)); return; } m_initialized = true; @@ -583,7 +532,7 @@ namespace dragon } if (addr >= m_size) { - data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::String("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return false; } int8_t value = 0; @@ -601,7 +550,7 @@ namespace dragon } if (addr >= m_size - 1) { - data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::String("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return 0; } int8_t b1 = read8(addr); @@ -619,7 +568,7 @@ namespace dragon } if (addr >= m_size) { - data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::String("Invalid Byte CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return 0; } m_dataFile.seekp(addr); @@ -636,7 +585,7 @@ namespace dragon } if (addr >= m_size - 1) { - data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::StringEditor("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2)).str()); + data::ErrorHandler::pushError(data::ErrorCodes::CMOS_InvalidAddress, ostd::String("Invalid Word CMOS location at address: ").add(ostd::Utils::getHexStr(addr, true, 2))); return 0; } int8_t b1 = (value >> 8) & 0xFF; diff --git a/src/hardware/VirtualIODevices.hpp b/src/hardware/VirtualIODevices.hpp index c67ea57..e853aea 100644 --- a/src/hardware/VirtualIODevices.hpp +++ b/src/hardware/VirtualIODevices.hpp @@ -86,34 +86,6 @@ namespace dragon private: ostd::ByteStream m_mbr; }; - class VirtualBIOSVideo : public IMemoryDevice - { - public: struct tRegisters - { - inline static constexpr uint16_t ClearColor = 0x00; - inline static constexpr uint16_t Palette = 0x01; - inline static constexpr uint16_t UseTransparencyOn0x5 = 0x02; - inline static constexpr uint16_t Signal = 0x03; - - inline static constexpr uint16_t VideoMemoryStart = 0x003C; - }; - - public: - VirtualBIOSVideo(VirtualRAM& memory); - int8_t read8(uint16_t addr) override; - int16_t read16(uint16_t addr) override; - int8_t write8(uint16_t addr, int8_t value) override; - int16_t write16(uint16_t addr, int16_t value) override; - - ostd::ByteStream* getByteStream(void) override; - - private: - uint16_t m_baseAddress { data::MemoryMapAddresses::BIOSVideo_Start }; - uint16_t m_size { (data::MemoryMapAddresses::BIOSVideo_End + 1) - data::MemoryMapAddresses::BIOSVideo_Start }; - ostd::Byte* m_dataPtr { nullptr }; - ostd::ByteStream m_dataCopy; - VirtualRAM& m_memory; - }; namespace interface { diff --git a/src/runtime/ConfigLoader.cpp b/src/runtime/ConfigLoader.cpp index fc5b342..1b9c8ae 100644 --- a/src/runtime/ConfigLoader.cpp +++ b/src/runtime/ConfigLoader.cpp @@ -12,13 +12,13 @@ namespace dragon auto lines = file.getLines(); for (auto& line : lines) { - ostd::StringEditor lineEdit = line; + ostd::String lineEdit = line; if (!lineEdit.contains("=")) continue; //TODO: Warning auto tokens = lineEdit.tokenize("="); if (tokens.count() != 2) continue; //TODO: Warning lineEdit = tokens.next(); lineEdit = lineEdit.toLower(); - if (lineEdit.str() == "disks") + if (lineEdit == "disks") { lineEdit = tokens.next(); tokens = lineEdit.tokenize(","); @@ -27,18 +27,18 @@ namespace dragon while (tokens.hasNext()) { lineEdit = tokens.next(); - config.vdisk_paths[disk_nr++] = lineEdit.str(); + config.vdisk_paths[disk_nr++] = lineEdit; } } - else if (lineEdit.str() == "bios") + else if (lineEdit == "bios") { lineEdit = tokens.next(); - config.bios_path = lineEdit.str(); + config.bios_path = lineEdit; } - else if (lineEdit.str() == "cmos") + else if (lineEdit == "cmos") { lineEdit = tokens.next(); - config.cmos_path = lineEdit.str(); + config.cmos_path = lineEdit; } else continue; //TODO: Warning } diff --git a/src/runtime/ConfigLoader.hpp b/src/runtime/ConfigLoader.hpp index 89ac58f..1d54ab2 100644 --- a/src/runtime/ConfigLoader.hpp +++ b/src/runtime/ConfigLoader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace dragon diff --git a/src/runtime/DragonRuntime.cpp b/src/runtime/DragonRuntime.cpp index ce04a64..dcf1526 100644 --- a/src/runtime/DragonRuntime.cpp +++ b/src/runtime/DragonRuntime.cpp @@ -1,42 +1,44 @@ #include "DragonRuntime.hpp" +#include +#include "../gui/RawTextRenderer.hpp" namespace dragon { void DragonRuntime::printRegisters(dragon::hw::VirtualCPU& cpu) { - out.col("green").p("IP: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::IP), true, 2)); + out.fg("green").p("IP: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::IP), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R1: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R1), true, 2)); + out.fg("yellow").p("R1: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R1), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R2: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R2), true, 2)).nl(); + out.fg("yellow").p("R2: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R2), true, 2).cpp_str()).nl(); - out.col("green").p("SP: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::SP), true, 2)); + out.fg("green").p("SP: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::SP), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R3: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R3), true, 2)); + out.fg("yellow").p("R3: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R3), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R4: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R4), true, 2)).nl(); + out.fg("yellow").p("R4: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R4), true, 2).cpp_str()).nl(); - out.col("green").p("FP: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::FP), true, 2)); + out.fg("green").p("FP: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::FP), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R5: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R5), true, 2)); + out.fg("yellow").p("R5: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R5), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R6: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R6), true, 2)).nl(); + out.fg("yellow").p("R6: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R6), true, 2).cpp_str()).nl(); - out.col("green").p("RV: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::RV), true, 2)); + out.fg("green").p("RV: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::RV), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R7: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R7), true, 2)); + out.fg("yellow").p("R7: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R7), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R8: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R8), true, 2)).nl(); + out.fg("yellow").p("R8: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R8), true, 2).cpp_str()).nl(); - out.col("green").p("PP: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::PP), true, 2)); + out.fg("green").p("PP: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::PP), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R9: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R9), true, 2)); + out.fg("yellow").p("R9: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R9), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("R10: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R10), true, 2)).nl(); + out.fg("yellow").p("R10: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::R10), true, 2).cpp_str()).nl(); - out.col("green").p("ACC: ").col("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::ACC), true, 2)); + out.fg("green").p("ACC: ").fg("white").p(ostd::Utils::getHexStr(cpu.readRegister(dragon::data::Registers::ACC), true, 2).cpp_str()); out.p(" "); - out.col("yellow").p("FL: ").col("white").p(ostd::Utils::getBinStr(cpu.readRegister(dragon::data::Registers::FL), true, 2)); + out.fg("yellow").p("FL: ").fg("white").p(ostd::Utils::getBinStr(cpu.readRegister(dragon::data::Registers::FL), true, 2).cpp_str()); } void DragonRuntime::processErrors(void) @@ -44,7 +46,7 @@ namespace dragon while (dragon::data::ErrorHandler::hasError()) { auto err = dragon::data::ErrorHandler::popError(); - out.nl().col(ostd::legacy::ConsoleCol::Red).p("Error ").p(ostd::Utils::getHexStr(err.code, true, 8)).p(": ").p(err.text).nl(); + out.nl().fg(ostd::ConsoleColors::Red).p("Error ").p(ostd::Utils::getHexStr(err.code, true, 8).cpp_str()).p(": ").p(err.text.cpp_str()).nl(); } } @@ -61,23 +63,29 @@ namespace dragon return list; } - int32_t DragonRuntime::initMachine(const ostd::String& configFilePath, bool verbose, bool trackMachineInfoDiff, bool hideVirtualDisplay) + int32_t DragonRuntime::initMachine(const ostd::String& configFilePath, + bool verbose, + bool trackMachineInfoDiff, + bool hideVirtualDisplay, + bool trackCallStack, + bool debugModeEnabled) { if (verbose) - out.p("Loading machine config: ").p(configFilePath).nl(); + out.p("Loading machine config: ").p(configFilePath.cpp_str()).nl(); machine_config = dragon::MachineConfigLoader::loadConfig(configFilePath); if (!machine_config.isValid()) return 1; //TODO: Error if (verbose) out.p(" Initializing virtual display:").nl(); - vDisplay.initialize(800, 600, "font.bmp"); - vDisplay.addWidget(vConsWidg); - vDisplay.setSize(vConsWidg.getw(), vConsWidg.geth()); + vDisplay.initialize(800, 600, "DragonVM", "font.bmp"); + int32_t w = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16; + int32_t h = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9; + vDisplay.setSize(w, h); if (hideVirtualDisplay) vDisplay.hide(); if (verbose) { - out.p(" Done. (").pi((int)vConsWidg.getw()).p("x").pi((int)vConsWidg.geth()).p(")"); + out.p(" Done. (").p(w).p("x").p(h).p(")"); if (hideVirtualDisplay) out.p(" - HIDDEN").nl(); else @@ -92,114 +100,105 @@ namespace dragon vDisks[disk_path.first] = dragon::hw::VirtualHardDrive(disk_path.second); vDiskInterface.connectDisk(vDisks[disk_path.first]); if (verbose) - out.p(" Disk").pi(disk_path.first).p(" connected: ").p(disk_path.second).nl(); + out.p(" Disk").p(disk_path.first).p(" connected: ").p(disk_path.second.cpp_str()).nl(); } if (verbose) - out.p(" Loading vBIOS file: ").p(machine_config.bios_path).nl(); + out.p(" Loading vBIOS file: ").p(machine_config.bios_path.cpp_str()).nl(); vBIOS.init(machine_config.bios_path); if (verbose) - out.p(" Loading vCMOS file: ").p(machine_config.cmos_path).nl(); + out.p(" Loading vCMOS file: ").p(machine_config.cmos_path.cpp_str()).nl(); vCMOS.init(machine_config.cmos_path); if (verbose) { out.p(" Initializing Memory Mapper:").nl(); out.p(" vBIOS: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOS_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOS_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOS_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOS_End, true, 2).cpp_str()); out.p(" (remap=false)").nl(); } memMap.mapDevice(vBIOS, dragon::data::MemoryMapAddresses::BIOS_Start, dragon::data::MemoryMapAddresses::BIOS_End, false, "vBIOS"); if (verbose) { out.p(" vCMOS: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::CMOS_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::CMOS_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::CMOS_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::CMOS_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(vCMOS, dragon::data::MemoryMapAddresses::CMOS_Start, dragon::data::MemoryMapAddresses::CMOS_End, true, "vCMOS"); if (verbose) { out.p(" intVec: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::IntVector_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::IntVector_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::IntVector_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::IntVector_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(intVec, dragon::data::MemoryMapAddresses::IntVector_Start, dragon::data::MemoryMapAddresses::IntVector_End, true, "intVec"); if (verbose) { out.p(" vKeyboard: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Keyboard_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Keyboard_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Keyboard_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Keyboard_End, true, 2).cpp_str()); out.p(" (remap=false)").nl(); } memMap.mapDevice(vKeyboard, dragon::data::MemoryMapAddresses::Keyboard_Start, dragon::data::MemoryMapAddresses::Keyboard_End, false, "vKeyboard"); if (verbose) { out.p(" vMouse: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Mouse_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Mouse_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Mouse_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Mouse_End, true, 2).cpp_str()); out.p(" (remap=false)").nl(); } memMap.mapDevice(vMouse, dragon::data::MemoryMapAddresses::Mouse_Start, dragon::data::MemoryMapAddresses::Mouse_End, false, "vMouse"); if (verbose) - { - out.p(" vBIOSVideo: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOSVideo_Start, true, 2)); - out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::BIOSVideo_End, true, 2)); - out.p(" (remap=true)").nl(); - } - memMap.mapDevice(vBIOSVideo, dragon::data::MemoryMapAddresses::BIOSVideo_Start, dragon::data::MemoryMapAddresses::BIOSVideo_End, true, "vBIOSVideo"); - if (verbose) { out.p(" vMBR: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::MBR_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::MBR_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::MBR_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::MBR_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(vMBR, dragon::data::MemoryMapAddresses::MBR_Start, dragon::data::MemoryMapAddresses::MBR_End, true, "vMBR"); if (verbose) { out.p(" vDiskInterface: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::DiskInterface_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::DiskInterface_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::DiskInterface_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::DiskInterface_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(vDiskInterface, dragon::data::MemoryMapAddresses::DiskInterface_Start, dragon::data::MemoryMapAddresses::DiskInterface_End, true, "vDiskInterface"); if (verbose) { out.p(" vGraphicsInterface: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::VideoCardInterface_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::VideoCardInterface_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::VideoCardInterface_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::VideoCardInterface_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(vGraphicsInterface, dragon::data::MemoryMapAddresses::VideoCardInterface_Start, dragon::data::MemoryMapAddresses::VideoCardInterface_End, true, "vGraphicsInterface"); if (verbose) { out.p(" vSerialInterface: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::SerialInterface_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::SerialInterface_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::SerialInterface_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::SerialInterface_End, true, 2).cpp_str()); out.p(" (remap=true)").nl(); } memMap.mapDevice(vSerialInterface, dragon::data::MemoryMapAddresses::SerialInterface_Start, dragon::data::MemoryMapAddresses::SerialInterface_End, true, "vSerialInterface"); if (verbose) { out.p(" RAM: "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Memory_Start, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Memory_Start, true, 2).cpp_str()); out.p(" to "); - out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Memory_End, true, 2)); + out.p(ostd::Utils::getHexStr(dragon::data::MemoryMapAddresses::Memory_End, true, 2).cpp_str()); out.p(" (remap=false)").nl(); } memMap.mapDevice(ram, dragon::data::MemoryMapAddresses::Memory_Start, dragon::data::MemoryMapAddresses::Memory_End, false, "RAM"); @@ -209,17 +208,22 @@ namespace dragon if (verbose) { out.p(" Initializing vCPU reset sequence:").nl(); - out.p(" BIOSVideo default colors: ").p(ostd::Utils::getHexStr(default_bios_video_color)).nl(); + // out.p(" BIOSVideo default colors: ").p(ostd::Utils::getHexStr(default_bios_video_color).cpp_str()).nl(); } - memMap.write8(dragon::data::MemoryMapAddresses::BIOSVideo_Start, default_bios_video_color); + // memMap.write8(dragon::data::MemoryMapAddresses::BIOSVideo_Start, default_bios_video_color); uint16_t reset_ip_addr = 0x0000; if (verbose) - out.p(" Reset IP register: ").p(ostd::Utils::getHexStr(reset_ip_addr, true, 2)).nl(); + out.p(" Reset IP register: ").p(ostd::Utils::getHexStr(reset_ip_addr, true, 2).cpp_str()).nl(); cpu.writeRegister(dragon::data::Registers::IP, reset_ip_addr); + if (verbose) + out.p(" Debug mode enabled: ").p(STR_BOOL(debugModeEnabled)).nl(); + cpu.m_debugModeEnabled = debugModeEnabled; + out.nl().nl(); s_trackMachineInfo = trackMachineInfoDiff; + s_trackCallStack = trackCallStack; return 0; } @@ -230,9 +234,11 @@ namespace dragon uint8_t currentInst = 0x00; uint32_t instSize = 0; ostd::ByteStream& ramData = *ram.getByteStream(); - while ((running || vDiskInterface.isBusy()) && cycleCounter++ < 2048) + // while ((running || vDiskInterface.isBusy()) && cycleCounter++ < 2048) + while (running || vDiskInterface.isBusy()) { - out.clear(); + if (basic_debug) + out.clear(); uint16_t addr = cpu.readRegister(dragon::data::Registers::IP); uint16_t spAddr = cpu.readRegister(dragon::data::Registers::SP); running = cpu.execute() && vDisplay.isRunning(); @@ -244,13 +250,12 @@ namespace dragon { instSize = dragon::data::OpCodes::getInstructionSIze(currentInst); ostd::Utils::printByteStream(ramData, dragon::data::MemoryMapAddresses::Memory_Start, 16, 10, newOut, addr, instSize, " MEMORY"); - ostd::Utils::printByteStream(*vBIOSVideo.getByteStream(), 0x0000, 16, 16, newOut, -1, 1, " Bios Video"); printRegisters(cpu); - out.nl().col("yellow").p("Current Instruction: ").col("white").p(ostd::Utils::getHexStr(currentInst, true, 1)); + out.nl().fg("yellow").p("Current Instruction: ").fg("white").p(ostd::Utils::getHexStr(currentInst, true, 1).cpp_str()); out.nl(); - out.col(ostd::legacy::ConsoleCol::Magenta).p("######### Reached Break Point at "); - out.p(ostd::Utils::getHexStr(addr, true, 2)); - out.nl().resetColors(); + out.fg(ostd::ConsoleColors::Magenta).p("######### Reached Break Point at "); + out.p(ostd::Utils::getHexStr(addr, true, 2).cpp_str()); + out.nl().reset(); std::cin.get(); continue; } @@ -263,13 +268,12 @@ namespace dragon } instSize = dragon::data::OpCodes::getInstructionSIze(currentInst); ostd::Utils::printByteStream(ramData, dragon::data::MemoryMapAddresses::Memory_Start, 16, 10, newOut, addr, instSize, " MEMORY"); - ostd::Utils::printByteStream(*vBIOSVideo.getByteStream(), 0x0000, 16, 16, newOut, -1, 1, " Bios Video"); printRegisters(cpu); - out.nl().col("yellow").p("Current Instruction: ").col("white").p(ostd::Utils::getHexStr(currentInst, true, 1)); + out.nl().fg("yellow").p("Current Instruction: ").fg("white").p(ostd::Utils::getHexStr(currentInst, true, 1).cpp_str()); out.nl(); - out.col(ostd::legacy::ConsoleCol::Red).p("######### Error occurred at "); - out.p(ostd::Utils::getHexStr(addr, true, 2)); - out.nl().resetColors(); + out.fg(ostd::ConsoleColors::Red).p("######### Error occurred at "); + out.p(ostd::Utils::getHexStr(addr, true, 2).cpp_str()); + out.nl().reset(); processErrors(); std::cin.get(); continue; @@ -280,6 +284,7 @@ namespace dragon bool DragonRuntime::runStep(std::vector trackedAddresses) { __get_machine_footprint(&s_machineInfo, trackedAddresses, true); + __track_call_stack(&s_machineInfo); bool running = cpu.execute() && vDisplay.isRunning(); vDisplay.update(); vDiskInterface.cycleStep(); @@ -332,11 +337,13 @@ namespace dragon uint8_t instSize = data::OpCodes::getInstructionSIze(memMap.read8(instAddr)); ostd::String opCode = data::OpCodes::getOpCodeString(memMap.read8(instAddr)); uint16_t stackFrameSize = cpu.m_stackFrameSize; + int32_t subRoutineCounter = cpu.m_subroutineCounter; bool debugBreak = cpu.m_isDebugBreakPoint; bool intHandler = cpu.m_isInInterruptHandler; bool biosMode = cpu.m_biosMode; + bool isInSubRoutine = cpu.isInSubRoutine(); if (previous) { @@ -344,6 +351,7 @@ namespace dragon minfo.previousInstructionFootprintSize = instSize; minfo.previousInstructionStackFrameSize = stackFrameSize; minfo.previousInstructionOpCode = opCode; + minfo.previousSubRoutineCounter = subRoutineCounter; for (int8_t i = 0; i < instSize; i++) minfo.previousInstructionFootprint[i] = memMap.read8(instAddr + i); @@ -357,6 +365,7 @@ namespace dragon minfo.previousInstructionDebugBreak = debugBreak; minfo.previousInstructionInterruptHandler = intHandler; minfo.previousInstructionBiosMode = biosMode; + minfo.previousIsInSubRoutine = isInSubRoutine; } else { @@ -364,6 +373,7 @@ namespace dragon 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); @@ -377,6 +387,43 @@ namespace dragon minfo.currentInstructionDebugBreak = debugBreak; minfo.currentInstructionInterruptHandler = intHandler; minfo.currentInstructionBiosMode = biosMode; + minfo.currentIsInSubRoutine = isInSubRoutine; } } + + void DragonRuntime::__track_call_stack(tMachineDebugInfo* machineInfo) + { + if (!s_trackCallStack || machineInfo == nullptr) return; + auto& minfo = *machineInfo; + + bool interrupts_enabled = cpu.readFlag(data::Flags::InterruptsEnabled); + + uint16_t instAddr = cpu.readRegister(data::Registers::IP); + uint8_t inst = memMap.read8(instAddr); + + if (inst == data::OpCodes::CallImm) + { + uint16_t call_addr = memMap.read16(instAddr + 1); + minfo.callStack.push_back({ "CALL IMM", call_addr }); + } + else if (inst == data::OpCodes::CallReg) + { + uint8_t reg_addr = memMap.read8(instAddr + 1); + uint16_t call_addr = cpu.readRegister(reg_addr); + minfo.callStack.push_back({ "CALL REG", call_addr }); + } + else if (interrupts_enabled && inst == data::OpCodes::Int) + { + uint8_t int_num = memMap.read8(instAddr + 1); + minfo.callStack.push_back({ "INT", int_num }); + } + else if (inst == data::OpCodes::Ret) + { + minfo.callStack.push_back({ "RET", 0x0000 }); + } + else if (interrupts_enabled && inst == data::OpCodes::RetInt) + { + minfo.callStack.push_back({ "RET INT", 0x0000 }); + } + } } \ No newline at end of file diff --git a/src/runtime/DragonRuntime.hpp b/src/runtime/DragonRuntime.hpp index 3acf05d..de93e04 100644 --- a/src/runtime/DragonRuntime.hpp +++ b/src/runtime/DragonRuntime.hpp @@ -1,7 +1,6 @@ #pragma once #include "../gui/Window.hpp" -#include "../gui/widgets/VirtualConsoleWidget.hpp" #include "../hardware/VirtualCPU.hpp" #include "../hardware/MemoryMapper.hpp" @@ -17,6 +16,11 @@ namespace dragon { class DragonRuntime { + public: struct tCallInfo { + ostd::String info; + uint16_t addr; + }; + public: struct tMachineDebugInfo { inline tMachineDebugInfo(void) { } @@ -26,6 +30,8 @@ namespace dragon int8_t currentInstructionFootprintSize { 0x00 }; uint16_t previousInstructionStackFrameSize { 0x00 }; uint16_t currentInstructionStackFrameSize { 0x00 }; + int32_t previousSubRoutineCounter { 0x00000000 }; + int32_t currentSubRoutineCounter { 0x00000000 }; ostd::String previousInstructionOpCode { "" }; ostd::String currentInstructionOpCode { "" }; @@ -45,14 +51,24 @@ namespace dragon bool currentInstructionInterruptHandler { false }; bool previousInstructionBiosMode { false }; bool currentInstructionBiosMode { false }; + bool previousIsInSubRoutine { false }; + bool currentIsInSubRoutine { false }; bool vCPUHalt { false }; + + + std::vector callStack; }; public: static void printRegisters(dragon::hw::VirtualCPU& cpu); static void processErrors(void); static std::vector getErrorList(void); - static int32_t initMachine(const ostd::String& configFilePath, bool verbose = false, bool trackMachineInfoDiff = false, bool hideVirtualDisplay = false); + static int32_t initMachine(const ostd::String& configFilePath, + bool verbose = false, + bool trackMachineInfoDiff = false, + bool hideVirtualDisplay = false, + bool rackCallStack = false, + bool debugModeEnabled = false); static void runMachine(int32_t cycleLimit, bool basic_debug, bool step_exec); static bool runStep(std::vector trackedAddresses = { }); static void forceLoad(const ostd::String& filePath, uint16_t loadAddress); @@ -62,9 +78,10 @@ namespace dragon private: static void __get_machine_footprint(tMachineDebugInfo* machineInfo, std::vector trackedAddresses, bool previous); + static void __track_call_stack(tMachineDebugInfo* machineInfo); public: - inline static ostd::legacy::ConsoleOutputHandler out; + inline static ostd::ConsoleOutputHandler out; inline static dragon::hw::MemoryMapper memMap; inline static dragon::hw::VirtualCPU cpu { memMap }; @@ -72,7 +89,6 @@ namespace dragon inline static dragon::hw::InterruptVector intVec; inline static dragon::hw::VirtualBIOS vBIOS; inline static dragon::hw::interface::CMOS vCMOS; - inline static dragon::hw::VirtualBIOSVideo vBIOSVideo { ram }; inline static dragon::hw::VirtualBootloader vMBR; inline static dragon::hw::VirtualKeyboard vKeyboard; inline static dragon::hw::VirtualMouse vMouse; @@ -83,12 +99,12 @@ namespace dragon inline static std::unordered_map vDisks; inline static dragon::Window vDisplay; - inline static dragon::VirtualConsoleWidtget vConsWidg { vBIOSVideo, cpu }; inline static dragon::tMachineConfig machine_config; private: inline static tMachineDebugInfo s_machineInfo; inline static bool s_trackMachineInfo { false }; + inline static bool s_trackCallStack { false }; }; } \ No newline at end of file diff --git a/src/runtime/runtime_main.cpp b/src/runtime/runtime_main.cpp index 4243f96..bf6a2bf 100644 --- a/src/runtime/runtime_main.cpp +++ b/src/runtime/runtime_main.cpp @@ -29,14 +29,14 @@ int main(int argc, char** argv) args.machine_config_path = argv[1]; for (int32_t i = 2; i < argc; i++) { - ostd::StringEditor edit(argv[i]); - if (edit.str() == "--debug") + ostd::String edit(argv[i]); + if (edit == "--debug") args.basic_debug = true; - else if (edit.str() == "--step") + else if (edit == "--step") args.step_exec = true; - else if (edit.str() == "--verbose-load") + else if (edit == "--verbose-load") args.verbose_load = true; - else if (edit.str() == "--limit-cycles") + else if (edit == "--limit-cycles") { if (i == argc - 1) break; //TODO: Warning @@ -46,7 +46,7 @@ int main(int argc, char** argv) continue; //TODO: Error args.cycle_limit = (int32_t)edit.toInt(); } - else if (edit.str() == "--force-load") + else if (edit == "--force-load") { if ((argc - 1) - i < 2) break; //TODO: Warning diff --git a/src/tools/GlobalData.hpp b/src/tools/GlobalData.hpp index bb94e4b..3a9797c 100644 --- a/src/tools/GlobalData.hpp +++ b/src/tools/GlobalData.hpp @@ -79,36 +79,33 @@ namespace dragon { public: inline static constexpr uint16_t BIOS_Start = 0x0000; - inline static constexpr uint16_t BIOS_End = 0x03FF; + inline static constexpr uint16_t BIOS_End = 0x0FFF; - inline static constexpr uint16_t CMOS_Start = 0x0400; - inline static constexpr uint16_t CMOS_End = 0x047F; + inline static constexpr uint16_t CMOS_Start = 0x1000; + inline static constexpr uint16_t CMOS_End = 0x107F; - inline static constexpr uint16_t IntVector_Start = 0x0480; - inline static constexpr uint16_t IntVector_End = 0x067F; + inline static constexpr uint16_t IntVector_Start = 0x1080; + inline static constexpr uint16_t IntVector_End = 0x127F; - inline static constexpr uint16_t Keyboard_Start = 0x0680; - inline static constexpr uint16_t Keyboard_End = 0x075F; + inline static constexpr uint16_t Keyboard_Start = 0x1280; + inline static constexpr uint16_t Keyboard_End = 0x135F; - inline static constexpr uint16_t Mouse_Start = 0x0760; - inline static constexpr uint16_t Mouse_End = 0x077F; + inline static constexpr uint16_t Mouse_Start = 0x1360; + inline static constexpr uint16_t Mouse_End = 0x137F; - inline static constexpr uint16_t BIOSVideo_Start = 0x0780; - inline static constexpr uint16_t BIOSVideo_End = 0x167F; + inline static constexpr uint16_t MBR_Start = 0x1380; + inline static constexpr uint16_t MBR_End = 0x157F; - inline static constexpr uint16_t MBR_Start = 0x1680; - inline static constexpr uint16_t MBR_End = 0x187F; + inline static constexpr uint16_t DiskInterface_Start = 0x1580; + inline static constexpr uint16_t DiskInterface_End = 0x15FF; - inline static constexpr uint16_t DiskInterface_Start = 0x1880; - inline static constexpr uint16_t DiskInterface_End = 0x18FF; + inline static constexpr uint16_t VideoCardInterface_Start = 0x1600; + inline static constexpr uint16_t VideoCardInterface_End = 0x16FF; - inline static constexpr uint16_t VideoCardInterface_Start = 0x1900; - inline static constexpr uint16_t VideoCardInterface_End = 0x19FF; + inline static constexpr uint16_t SerialInterface_Start = 0x1700; + inline static constexpr uint16_t SerialInterface_End = 0x173F; - inline static constexpr uint16_t SerialInterface_Start = 0x1A00; - inline static constexpr uint16_t SerialInterface_End = 0x1A3F; - - inline static constexpr uint16_t Memory_Start = 0x1A40; + inline static constexpr uint16_t Memory_Start = 0x1740; inline static constexpr uint16_t Memory_End = 0xFFFF; }; @@ -190,9 +187,9 @@ namespace dragon inline static constexpr uint8_t Keyboard = 0x10; inline static constexpr uint8_t Mouse = 0x11; inline static constexpr uint8_t BiosInterrupt = 0x20; + inline static constexpr uint8_t BiosVideoInterrupt = 0x30; inline static constexpr uint8_t DiskInterfaceFFinished = 0x80; - inline static constexpr uint8_t BiosVideoScreenRefresh = 0x81; }; class OpCodes diff --git a/src/tools/SDLInclude.hpp b/src/tools/SDLInclude.hpp index 56c17b3..06b6acb 100644 --- a/src/tools/SDLInclude.hpp +++ b/src/tools/SDLInclude.hpp @@ -4,4 +4,5 @@ #undef __linux__ #endif -#include \ No newline at end of file +#include +#include \ No newline at end of file diff --git a/src/tools/tools_main.cpp b/src/tools/tools_main.cpp index b9dc196..f9a7d5c 100644 --- a/src/tools/tools_main.cpp +++ b/src/tools/tools_main.cpp @@ -18,11 +18,11 @@ constexpr int ErrorLoadProgUnableToLoadDataFile = 8; constexpr int ErrorNoError = 0; -ostd::legacy::ConsoleOutputHandler out; +ostd::ConsoleOutputHandler out; bool createVirtualHardDrive(uint32_t sizeInBytes, const ostd::String& dataFilePath) { - std::ofstream rf(dataFilePath, std::ios::out | std::ios::binary); + std::ofstream rf(dataFilePath.cpp_str(), std::ios::out | std::ios::binary); if(!rf) return false; ostd::ByteStream stream; for (int32_t i = 0; i < sizeInBytes; i++) @@ -36,46 +36,46 @@ int main(int argc, char** argv) { if (argc < 2) { - out.col("red").p("Error: too few arguments.").nl(); - out.col("red").p(" Usage: ./dtools [...arguments...]").resetColors().nl(); + out.fg("red").p("Error: too few arguments.").nl(); + out.fg("red").p(" Usage: ./dtools [...arguments...]").reset().nl(); return ErrorTopLevelTooFewArgs; } - ostd::StringEditor tool = argv[1]; + ostd::String tool = argv[1]; tool = tool.trim().toLower(); //Nex Virtual Disk - if (tool.str() == "new-vdisk") + if (tool == "new-vdisk") { if (argc < 4) { - out.col("red").p("Error: too few arguments.").nl(); - out.col("red").p(" Usage: ./dtools new-vdisk ").resetColors().nl(); + out.fg("red").p("Error: too few arguments.").nl(); + out.fg("red").p(" Usage: ./dtools new-vdisk ").reset().nl(); return ErrorNewVDiskTooFewArgs; } ostd::String dest = argv[2]; ostd::String str_size = argv[3]; if (!ostd::Utils::isInt(str_size)) { - out.col("red").p("Error: parameter must be integer.").resetColors().nl(); + out.fg("red").p("Error: parameter must be integer.").reset().nl(); return ErrorNewVDiskNonIntSize; } bool result = createVirtualHardDrive(ostd::Utils::strToInt(str_size), dest); if (!result) { - out.col("red").p("Error: Unable to create virtual disk.").resetColors().nl(); + out.fg("red").p("Error: Unable to create virtual disk.").reset().nl(); return ErrorNewVDiskUnable; } - out.col("green").p("Success. Virtual disk created:").nl(); - out.p(" Path: ").p(dest).nl(); - out.p(" Size: ").p(str_size).resetColors().nl(); + out.fg("green").p("Success. Virtual disk created:").nl(); + out.p(" Path: ").p(dest.cpp_str()).nl(); + out.p(" Size: ").p(str_size.cpp_str()).reset().nl(); } //Load Program - else if (tool.str() == "load-program") + else if (tool == "load-program") { if (argc < 5) { - out.col("red").p("Error: too few arguments.").nl(); - out.col("red").p(" Usage: ./dtools load-program ").resetColors().nl(); + out.fg("red").p("Error: too few arguments.").nl(); + out.fg("red").p(" Usage: ./dtools load-program ").reset().nl(); return ErrorLoadProgTooFewArgs; } ostd::String vdisk_file = argv[2]; @@ -83,19 +83,19 @@ int main(int argc, char** argv) ostd::String str_addr = argv[4]; if (!ostd::Utils::isInt(str_addr)) { - out.col("red").p("Error: parameter must be integer.").resetColors().nl(); + out.fg("red").p("Error: parameter must be integer.").reset().nl(); return ErrorLoadProgNonIntAddr; } dragon::hw::VirtualHardDrive vHDD(vdisk_file); if (!vHDD.isInitialized()) { - out.col("red").p("Error: Unable to load virtual disk.").resetColors().nl(); + out.fg("red").p("Error: Unable to load virtual disk.").reset().nl(); return ErrorLoadProgUnableToLoadVDisk; } ostd::ByteStream code; if (!ostd::Utils::loadByteStreamFromFile(data_file, code)) { - out.col("red").p("Error: Unable to load data file.").resetColors().nl(); + out.fg("red").p("Error: Unable to load data file.").reset().nl(); return ErrorLoadProgUnableToLoadDataFile; } int16_t index = 0; @@ -106,16 +106,16 @@ int main(int argc, char** argv) index++; } vHDD.unmount(); - out.col("green").p("Success. Data writte to Virtual Disk:").nl(); - out.p(" Data Path: ").p(data_file).nl(); - out.p(" Disk Path: ").p(vdisk_file).nl(); - out.p(" Data Address: ").p(ostd::Utils::getHexStr(addr, true, 4)).nl(); - out.p(" Size: ").pi(code.size()).resetColors().nl(); + out.fg("green").p("Success. Data writte to Virtual Disk:").nl(); + out.p(" Data Path: ").p(data_file.cpp_str()).nl(); + out.p(" Disk Path: ").p(vdisk_file.cpp_str()).nl(); + out.p(" Data Address: ").p(ostd::Utils::getHexStr(addr, true, 4).cpp_str()).nl(); + out.p(" Size: ").p(code.size()).reset().nl(); } //Unknown else { - out.col("red").p("Error: Unknown tool.").resetColors().nl(); + out.fg("red").p("Error: Unknown tool.").reset().nl(); return ErrorTopLevelUnknownTool; } return ErrorNoError;