diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d183a0..2cbaf79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ list(APPEND RUNTIME_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualMMU.cpp ${CMAKE_CURRENT_LIST_DIR}/src/tools/Utils.cpp ${CMAKE_CURRENT_LIST_DIR}/src/tools/GlobalData.cpp @@ -60,6 +61,7 @@ list(APPEND DEBUGGER_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualHardDrive.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualDisplay.cpp ${CMAKE_CURRENT_LIST_DIR}/src/hardware/CPUExtensions.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualMMU.cpp ${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp ${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp diff --git a/create_win_release.sh b/create_win_release.sh deleted file mode 100644 index 40e793f..0000000 --- a/create_win_release.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -rm -r ./win-release - -./compile - -cd bin - -printf "${green}Compiling vBIOS...\n${clear}" -./dasm dss/bios/entry.dss -o dragon/bios.bin --save-disassembly disassembly/bios.dds --verbose --save-exports - -printf "\n${green}Creating Virtual Disk...\n${clear}" -rm dragon/disk1.dr -./dtools new-vdisk dragon/disk1.dr 1048576 - -printf "\n${green}Compiling MBR Block...\n${clear}" -./dasm dss/drake/entry.dss -o dragon/drake.bin --save-disassembly disassembly/drake.dds --verbose - -printf "\n${green}Loading MBR Block...\n${clear}" -./dtools load-binary dragon/disk1.dr dragon/drake.bin 0x00000000 - -printf "${green}Compiling Test Program 1...\n" -./dasm dss/tests/test1.dss -o test1.bin --save-disassembly disassembly/test1.dds --verbose -printf "${green}Compiling Test Program 2...\n" -./dasm dss/tests/test2.dss -o test2.bin --save-disassembly disassembly/test2.dds --verbose - -printf "${green}Creating Windows Release...\n" -cd .. -mkdir win-release -mkdir win-release/disassembly -cp ./bin/dasm.exe ./win-release -cp ./bin/ddb.exe ./win-release -cp ./bin/dtools.exe ./win-release -cp ./bin/dvm.exe ./win-release -cp ./bin/font.bmp ./win-release - -cp -r ./bin/config ./win-release -cp -r ./bin/disassembly/bios.dds ./win-release/disassembly -cp -r ./bin/disassembly/drake.dds ./win-release/disassembly -cp -r ./bin/disassembly/test1.dds ./win-release/disassembly -cp -r ./bin/disassembly/test2.dds ./win-release/disassembly -cp -r ./bin/dragon ./win-release - -rm ./bin/disassembly/test1.dds -rm ./bin/disassembly/test2.dds - -mkdir ./win-release/dss4 -mkdir ./win-release/dss/bios -mkdir ./win-release/dss/drake -cp ./bin/dss/bios/* ./win-release/dss/bios -cp ./bin/dss/drake/* ./win-release/dss/drake -cp ./bin/dss/tests/test1.dss ./win-release/dss -cp ./bin/dss/tests/test2.dss ./win-release/dss - -cp C:/msys64/ucrt64/bin/libgcc_s_seh-1.dll ./win-release -cp C:/msys64/ucrt64/bin/libstdc++-6.dll ./win-release -cp C:/msys64/ucrt64/bin/libwinpthread-1.dll ./win-release -cp C:/msys64/ucrt64/bin/SDL2.dll ./win-release -cp C:/msys64/ucrt64/bin/libostd.dll ./win-release - -cp ./extra/scripts/run-test-1.bat ./win-release -cp ./extra/scripts/run-test-2.bat ./win-release \ No newline at end of file diff --git a/extra/config/testMachine.dvm b/extra/config/testMachine.dvm index 2b46009..d023769 100644 --- a/extra/config/testMachine.dvm +++ b/extra/config/testMachine.dvm @@ -4,6 +4,7 @@ CMOS = dragon/cmos.dr cpuext = extmov, extalu fixed_clock = true clock_rate_sec = 644 +memory_extension_pages = 16 SingleColor_foreground = #009900FF SingleColor_background = #111111FF \ No newline at end of file diff --git a/extra/dragon info/dpt_4_partitions_on_4_mb_disk.bin b/extra/dragon info/dpt_4_partitions_on_4_mb_disk.bin deleted file mode 100644 index 807d1e4..0000000 Binary files a/extra/dragon info/dpt_4_partitions_on_4_mb_disk.bin and /dev/null differ diff --git a/extra/dragon info/dpt_4_partitions_on_4_mb_disk.txt b/extra/dragon info/dpt_4_partitions_on_4_mb_disk.txt deleted file mode 100644 index b539018..0000000 --- a/extra/dragon info/dpt_4_partitions_on_4_mb_disk.txt +++ /dev/null @@ -1,42 +0,0 @@ -F1 CA 00 02 04 FF FF FF FF FF FF FF - -00 00 04 00 -00 00 14 00 -00 00 -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -42 4F 4F 54 53 45 43 54 4F 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -00 00 18 00 -00 01 68 00 -00 00 -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -00 01 80 00 -00 1F 40 00 -00 01 -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -44 72 61 67 6F 6E 4F 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -00 20 C0 00 -00 1F 40 00 -00 00 -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -54 65 73 74 20 50 61 72 74 69 74 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -00 20 C0 00 -00 1F 40 00 -00 00 -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - - -Disk: 4096 kb -============= -boot + dpt 1 kb 1024 bytes (9x400) 0x0000.0000 -> 0x0000.03FF -------------- -boot-ssector 5 kb 5120 bytes (0x1400) 0x0000.0400 -> 0x0000.17FF -Unallocated 90 kb 92160 bytes (0x16800) 0x0000.1800 -> 0x0001.7FFF -DragonOS 2000 kb 2048000 bytes (0x1F4000) 0x0001.8000 -> 0x0020.BFFF -Test Partition 2000 kb 2048000 bytes (0x1F4000) 0x0020.C000 -> 0x0040.0000 diff --git a/extra/dragon info/dscript_mockup_1.dsc b/extra/dragon info/dscript_mockup_1.dsc deleted file mode 100644 index dccdebc..0000000 --- a/extra/dragon info/dscript_mockup_1.dsc +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __SOME_DEFINE__ -#define __SOME_DEFINE__ 0 - -#include - - -struct SomeStruct { - //var data1; - int data2; - int data3 = 0; - string data4 = "Hello"; //string type is basically a byte array with a 0 at the end - int[10] data6; //Array - int[] data7 = { 2, 5, 7 }; //Array - int* data8; //Pointer - SomeStruct* data9 = null; -}; - -fn main(void) -> int { - let myVar: SomeStruct; - (*myVar.data8) = 12; - let myVar2: int* = myVar.data8; - myFunction(myVar2, 10); - dstd::print("The result is %d!", (*myVar2)); -} - -fn myFunction(int* num1_ptr, int num2) -> void { - (*num1_ptr) = (*num1_ptr) + num2; -} - -namespace dstd { - fn print(string fmt, var args@) -> int { - let _args_len: int = args_count(args); - let _args_counter: int = 0; - let _ctrl_char: bool = false; - let _ret_val: int = 0; - for (byte c in fmt) { - if (!_ctrl_char) { - _ret_val = __internal_dstd::__print_char_in_display_mode(__internal_dstd::__display_modes::__text_single_color, c); - continue; - } - if (c == '%') { _ctrl_char = true; continue; } - if (_ctrl_char) { - if (c == 'd') { - _ctrl_char = false; - if (_args_len < 1) { - continue; - } - let _integer: int = args_get_int(_args_counter); - _args_counter++; - _ret_val = __internal_dstd::__print_integer_in_display_mode(__internal_dstd::__display_modes::__text_single_color, _integer); - } - } - } - } -} - -#endif \ No newline at end of file diff --git a/extra/dragon info/dscript_mockup_2.dsc b/extra/dragon info/dscript_mockup_2.dsc deleted file mode 100644 index d7b37e4..0000000 --- a/extra/dragon info/dscript_mockup_2.dsc +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __SOME_DEFINE__ -#define __SOME_DEFINE__ - -#include - -#data_alloc(128) // Total data memory allocated - -//Types: byte, word, word, string, bool - -struct SomeStruct { - var data1: byte = 0; - var data2: word; - var data3: string = "Hello"; //Basically equivalent to var data3: byte[] = { 'H', 'e', 'l', 'l', 'o', 0 } - var data4: bool = false; // and are respectively replaced with <1> and <0>, and - // is actually equivalent to - var data5: byte[] = { 4, 1, 4, 2 }; - var data6: word[10]; -} - -/** DASM Translation - - @struct SomeStruct - data1:1 > 0x00 - data2:4; - data3:6 > 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00 - data4:1 > 0x00 - data5:4 > 0x04, 0x01, 0x04, 0x02 - data6:20 - @end -**/ - -fn testFunction(var param1:word, var param2:string) -> word { - if (length == 0) { - return 0; - } else { - return param1; - } -} - -/** DASM Translation - - __fn_testFunction_2_word_byteptr__: - arg R1 ## param1 (word) - arg R2 ## param2 (string) - mov ACC, 6 - ret -**/ - -fn strlen(var str:string) -> word { - if (str == null) { return 0; } - var c:byte = str[0]; - var counter:word = 0; - while (c != 0) { - counter++; - c = str[counter]; - } - return counter; -} - -fn strlen(var str:string) -> word { - dasm { - arg R1 - mov R2, 0 - _strlen_loop: - movb ACC, *R1 - inc R1 - jeq $_strlen_loop_end, 0 - inc R2 - jmp $_strlen_loop - _strlen_loop_end: - mov RV, R2 - ret - } -} - -/** DASM Translation - - __fn_strlen_1_byteptr__: - arg R1 ## param2 (string) - mov ACC, R1 - jne $__fn_strlen_1_byteptr__branch_1_end__, 0 - __fn_strlen_1_byteptr__branch_1__: - mov RV, 0 - jmp $__fn_strlen_1_byteptr__end__ - __fn_strlen_1_byteptr__branch_1_end__: - omovb *FP, *R1, -1 ## c - omov *FP, 0x0000, -3 ## counter - __fn_strlen_1_byteptr__loop_1__: - movbo ACC, *FP, -1 - jeq, $__fn_strlen_1_byteptr__loop_1_end__, 0 - movo ACC, *FP, -3 - inc ACC - omov *FP, ACC, -3 - omovb *FP, *ACC, -1 - jmp $__fn_strlen_1_byteptr__loop_1__ - __fn_strlen_1_byteptr__loop_1_end__: - movo RV, *FP, -3 - __fn_strlen_1_byteptr__end__ - ret -**/ - -#endif \ No newline at end of file diff --git a/extra/dragon info/font_big.bmp b/extra/dragon info/font_big.bmp deleted file mode 100644 index 133414b..0000000 Binary files a/extra/dragon info/font_big.bmp and /dev/null differ diff --git a/extra/dragon info/info b/extra/dragon info/info deleted file mode 100644 index 7a72510..0000000 --- a/extra/dragon info/info +++ /dev/null @@ -1,168 +0,0 @@ -#========================================================================================================================================== -# Memory Map -#========================================================================================================================================== - - -0x0000 BIOS (4096 Bytes) (write to this section is disabled) -0x0FFF -------- -0x1000 CMOS (128 Bytes) (write to this section is only allowed in BIOS Mode) - MemStart: (2 bytes) 0x0000 - MemSize: (2 bytes) 0x0002 - ClockSpeed: (2 bytes) 0x0004 - BootDisk: 0x0010 - - DiskList: (2 bytes) 0x007E -0x107F -------- -0x1080 INTERRUPT VECTOR (512 Bytes) - Status: 1 Byte - 0xFF: Enabled - 0x00: Disabled - Handler Address: 2 Byte - ...Repeat... -0x127F -------- -0x1280 KEYBOARD MAPPING (224 Bytes) (write to this section is only allowed in BIOS Mode) - 0x00: Modifiers (2 bytes) - 0b00000000.00000001: Left Shift - 0b00000000.00000010: Left Ctrl - 0b00000000.00000100: Left Alt - 0b00000000.00001000: Left Super - 0b00000000.00010000: Right Shift - 0b00000000.00100000: Right Control - 0b00000000.01000000: Right Alt - 0b00000000.10000000: Right Super - 0b00000001.00000000: Caps Lock - 0b00000010.00000000: Num Lock - 0b00000100.00000000: Scroll Lock - 0x02: KeyCode (2 bytes) -0x135F -------- -0x1360 MOUSE MAPPING (32 Bytes) -0x137F -------- -0x1380 BOOTLOADER (512 Bytes) -0x157F -------- -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 -------- -0x1600 VIDEO CARD INTERFACE (256 Bytes) - 0x00: Video Mode (1 Byte) - 0x00: Text Single Color - # 0x01: Text 16-color - # 0x02: Text 256-color - # 0x03: Text True Color Mode - # 0x04: GFX Single Color - # 0x05: GFX 16-color - # 0x06: GFX 256-color - # 0x07: GFX True Color Mode - # 0x01: Clear Color (1 Byte) - # 0x02: Palette (1 Byte) - 0x03: Signal (1 Byte) - 0x00: Continue - - 0x02: Text Single Color - Direct Print Character - 0x03: Text Single Color - Store character in buffer - 0x04: Text SIngle Color - Direct Print buffer & Flush Buffer - 0x05: Text Single Color - Flush Buffer - 0x06: Text Single Color - Print Buffer Without Flushing - 0x07: Text Single Color - Print Buffered String - - 0xE0: Refresh Screen - 0xE1: Clear Screen - 0x04: Text Single Color Character (1 Byte) - 0x05: Text Single Color Inverted colors (1 Byte) - 0x06: (2 bytes) Text Single Color Buffered String Address -0x16FF -------- -0x1700 GENERIC SERIAL INTERFACE (64 Bytes) -0x173F -------- -0x1740 RAM (59583 Bytes) -0xFFFF - - - -#========================================================================================================================================== -# INTERRUPTS -#========================================================================================================================================== - - - - -BIOS Specific - Software Interrupts: -==================================== -0x20: BIOS Interrupt (Uses R10 register for specific functionality) - 0x00: Set Interrupt Handler - 0x01: Clear Interrupt Handler - 0x10: Disk Interface -0x30: BIOS Video Interrupt (Uses R10 register for specific functionality) - 0x01: Print Char in Text Single Mode (char stored in R9 register) - 0x02: New Line in Text Single Mode - 0x03: Print Null-Terminated String in Text Single Mode (string address stored in R9 register) - 0x04: Print Integer in Text Single Mode (integer stored in R9 register) - 0x05: Store Integer in buffer in Text Single Mode (integer stored in R9 register) - 0x06: Store character in buffer in Text Single Mode (integer stored in R9 register) - 0x07: Print buffer no flush in Text Single Mode - 0x08: Print buffer and flush in Text Single Mode - 0x09: Flush buffer in Text Single Mode - 0x0A: Store Null-Terminated String in buffer in Text Single Mode (string address stored in R9 register) - 0x0B: Toggles inverted colors in Text Single Mode - - 0xE0: Refresh Screen - 0xE1: Clear Screen - - -Machine Specific - Hardware Interrupts: -======================================= -MAX INTERRUPT 0xAA -0x80: Disk Interface Finished -0xA0: Keyboard Interface - Key Pressed -0xA1: Keyboard Interface - Key Released -0xA2: Keyboard Interface - Text Entered - - - -#========================================================================================================================================== -# DPT - Partition Table -#========================================================================================================================================== - -Disk Address: 0x200 - 0x400 (512 bytes) -Header: (0x200 - 0x20B) (12 bytes) - 0x000: (2 bytes) - 0xF1CA - This number identifies this block as a DPT partition table - 0x002: (2 bytes) - DPT version - 0x004: (1 byte) - Partition count (max 5) - 0x005: (7 bytes) - Reserved -Partition Table: (0x20C - 0x3FF) (500 bytes) - Entry: (100 bytes) (x5) - 0x00: (4 bytes) - Start Address - 0x04: (4 bytes) - Size - 0x08: (2 bytes) - Flags - 0x08: (26 bytes) - Reserved - 0x24: (64 bytes) - Partition label diff --git a/extra/dragon info/regular_expressions.txt b/extra/dragon info/regular_expressions.txt deleted file mode 100644 index 51f085c..0000000 --- a/extra/dragon info/regular_expressions.txt +++ /dev/null @@ -1,10 +0,0 @@ -Regex: Javascript - -Number Constants -0x[0-9A-Fa-f]+|0b[0-1]+|(? .data $string "Hello BOOTSECTOR!!" + $ddd + $dpt_block .code mov R10, 0xE0 @@ -10,3 +14,34 @@ mov R9, $string int 0x30 + push 0 + call $_load_dpt_block + debug_break + +end_loop: + jmp $end_loop + hlt + + + +_load_dpt_block: + mov [$ddd.Mode], DiskMode.READ + mov [$ddd.Disk], 0x00 + mov [$ddd.Sector], 0x0000 + mov [$ddd.Address], 0x0200 + mov [$ddd.DataSize], 512 + mov [$ddd.MemoryAddress], $dpt_block.ID + and FL, 0b1111111111111110 ## Disable interrupts + mov FL, ACC + push $ddd.Mode + push 1 + call $_disk_load_from_ddd_blocking + or FL, 0b0000000000000001 ## Enable interrupts + mov FL, ACC + ret + + +@include + +.fixed 5120, 0xFF + diff --git a/extra/dss/drake/disk.dss b/extra/dss/drake/disk.dss index 7b9b803..9d5fc0f 100644 --- a/extra/dss/drake/disk.dss +++ b/extra/dss/drake/disk.dss @@ -41,7 +41,7 @@ Sector:2 > 0x00, 0x00 Address:2 > 0x00, 0x00 DataSize:2 > 0x00, 0x00 - MemoryAddress: > 0x00, 0x00 + MemoryAddress:2 > 0x00, 0x00 @end .code diff --git a/extra/dss/drake/dpt.dss b/extra/dss/drake/dpt.dss index 9a3be0c..e19a87c 100644 --- a/extra/dss/drake/dpt.dss +++ b/extra/dss/drake/dpt.dss @@ -1,4 +1,4 @@ -@uard _DPT_DSS_ +@guard _DPT_DSS_ @group DPTStructure DISK_ADDR 0x0200 diff --git a/extra/dss/drake/loader.dss b/extra/dss/drake/loader.dss index e674d0f..236a2f1 100644 --- a/extra/dss/drake/loader.dss +++ b/extra/dss/drake/loader.dss @@ -2,10 +2,6 @@ @include <../bios_api.dss> -@define S_REG_1 0x07 -@define S_REG_2 0x08 -@define S_REG_3 0x09 - .data $_drake_logo_line_1 " ___ ___ ___ __ ______" $_drake_logo_line_2 " / _ \/ _ \/ _ | / //_/ __/" @@ -13,25 +9,30 @@ $_drake_logo_line_4 "/____/_/|_/_/ |_/_/|_/___/ " $_logo_padding " " + $ddd + .code mov R10, 0xE0 int 0x30 push 0 call $_print_logo + + mov [$ddd.Mode], DiskMode.READ + mov [$ddd.Disk], 0x00 + mov [$ddd.Sector], 0x0000 + mov [$ddd.Address], 0x0400 + mov [$ddd.DataSize], 5120 + mov [$ddd.MemoryAddress], MemoryAddresses.RAM + and FL, 0b1111111111111110 ## Disable interrupts - mov FL, ACC - push 0 - call $_load_boot_sector + mov FL, ACC + push $ddd.Mode + push 1 + call $_disk_load_from_ddd_blocking or FL, 0b0000000000000001 ## Enable interrupts mov FL, ACC - - mov reg(S_REG_3), MemoryAddresses.RAM - inc reg(S_REG_3) - mov R1, *reg(S_REG_3) - addip R1, reg(S_REG_3) - mov *reg(S_REG_3), R1 - dec reg(S_REG_3) + jmp MemoryAddresses.RAM _infinite_loop: @@ -55,20 +56,6 @@ _print_logo_loop: jls $_print_logo_loop, R6 ret -_load_boot_sector: - movb [{MemoryAddresses.DISK_INTERFACE + 0x1}], 0x00 ## Mode = Read - movb R1, [{ MemoryAddresses.CMOS + 0x10 }] - movb [{MemoryAddresses.DISK_INTERFACE + 0x2}], R1 ## Disk = Default - mov [{MemoryAddresses.DISK_INTERFACE + 0x3}],0x0000 ## Sector - mov [{MemoryAddresses.DISK_INTERFACE + 0x5}],0x0400 ## Address - mov [{MemoryAddresses.DISK_INTERFACE + 0x7}], 1024 ## Size - mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], MemoryAddresses.RAM ## MemoryAddress - movb [MemoryAddresses.DISK_INTERFACE], 0x00 ## Signal = Start -_load_boot_sector_block_wait_loop: - debug_break - mov ACC, [{MemoryAddresses.DISK_INTERFACE + 0xB}] ## Moving register into ACC - jne $_load_boot_sector_block_wait_loop, 0x00 ## If register not Free, loop around and wait - ret - +@include .fixed 512, 0x00 diff --git a/extra/info/info b/extra/info/info new file mode 100644 index 0000000..93a4db7 --- /dev/null +++ b/extra/info/info @@ -0,0 +1,219 @@ +#========================================================================================================================================== +# Memory Map +#========================================================================================================================================== + 0x0000 BIOS (4096 Bytes) (write to this section is disabled) + 0x0FFF + ------- + 0x1000 CMOS (128 Bytes) (write to this section is only allowed in BIOS Mode) + MemStart: (2 bytes) 0x0000 + MemSize: (2 bytes) 0x0002 + ClockSpeed: (2 bytes) 0x0004 + BootDisk: 0x0010 + + DiskList: (2 bytes) 0x007E + 0x107F + ------- + 0x1080 INTERRUPT VECTOR (512 Bytes) + Status: 1 Byte + 0xFF: Enabled + 0x00: Disabled + Handler Address: 2 Byte + ...Repeat... + 0x127F + ------- + 0x1280 KEYBOARD MAPPING (224 Bytes) (write to this section is only allowed in BIOS Mode) + 0x00: Modifiers (2 bytes) + 0b00000000.00000001: Left Shift + 0b00000000.00000010: Left Ctrl + 0b00000000.00000100: Left Alt + 0b00000000.00001000: Left Super + 0b00000000.00010000: Right Shift + 0b00000000.00100000: Right Control + 0b00000000.01000000: Right Alt + 0b00000000.10000000: Right Super + 0b00000001.00000000: Caps Lock + 0b00000010.00000000: Num Lock + 0b00000100.00000000: Scroll Lock + 0x02: KeyCode (2 bytes) + 0x135F + ------- + 0x1360 MOUSE MAPPING (32 Bytes) + 0x137F + ------- + 0x1380 BOOTLOADER (512 Bytes) + 0x157F + ------- + 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 + ------- + 0x1600 VIDEO CARD INTERFACE (256 Bytes) + 0x00: Video Mode (1 Byte) + 0x00: Text Single Color + # 0x01: Text 16-color + # 0x02: Text 256-color + # 0x03: Text True Color Mode + # 0x04: GFX Single Color + # 0x05: GFX 16-color + # 0x06: GFX 256-color + # 0x07: GFX True Color Mode + # 0x01: Clear Color (1 Byte) + # 0x02: Palette (1 Byte) + 0x03: Signal (1 Byte) + 0x00: Continue + + 0x02: Text Single Color - Direct Print Character + 0x03: Text Single Color - Store character in buffer + 0x04: Text SIngle Color - Direct Print buffer & Flush Buffer + 0x05: Text Single Color - Flush Buffer + 0x06: Text Single Color - Print Buffer Without Flushing + 0x07: Text Single Color - Print Buffered String + + 0xE0: Refresh Screen + 0xE1: Clear Screen + 0x04: Text Single Color Character (1 Byte) + 0x05: Text Single Color Inverted colors (1 Byte) + 0x06: (2 bytes) Text Single Color Buffered String Address + 0x16FF + ------- + 0x1700 GENERIC SERIAL INTERFACE (64 Bytes) + 0x173F + ------- + 0x1740 RAM (59583 Bytes) + 0xFFFF + + + +#========================================================================================================================================== +# INTERRUPTS +#========================================================================================================================================== + BIOS Specific - Software Interrupts: + ==================================== + 0x20: BIOS Interrupt (Uses R10 register for specific functionality) + 0x00: Set Interrupt Handler + 0x01: Clear Interrupt Handler + 0x10: Disk Interface + 0x30: BIOS Video Interrupt (Uses R10 register for specific functionality) + 0x01: Print Char in Text Single Mode (char stored in R9 register) + 0x02: New Line in Text Single Mode + 0x03: Print Null-Terminated String in Text Single Mode (string address stored in R9 register) + 0x04: Print Integer in Text Single Mode (integer stored in R9 register) + 0x05: Store Integer in buffer in Text Single Mode (integer stored in R9 register) + 0x06: Store character in buffer in Text Single Mode (integer stored in R9 register) + 0x07: Print buffer no flush in Text Single Mode + 0x08: Print buffer and flush in Text Single Mode + 0x09: Flush buffer in Text Single Mode + 0x0A: Store Null-Terminated String in buffer in Text Single Mode (string address stored in R9 register) + 0x0B: Toggles inverted colors in Text Single Mode + + 0xE0: Refresh Screen + 0xE1: Clear Screen + + + Machine Specific - Hardware Interrupts: + ======================================= + MAX INTERRUPT 0xAA + 0x80: Disk Interface Finished + 0xA0: Keyboard Interface - Key Pressed + 0xA1: Keyboard Interface - Key Released + 0xA2: Keyboard Interface - Text Entered + + + +#========================================================================================================================================== +# DPT - Partition Table +#========================================================================================================================================== + + Disk Address: 0x200 - 0x400 (512 bytes) + Header: (0x200 - 0x20B) (12 bytes) + 0x000: (2 bytes) - 0xF1CA - This number identifies this block as a DPT partition table + 0x002: (2 bytes) - DPT version + 0x004: (1 byte) - Partition count (max 5) + 0x005: (7 bytes) - Reserved + Partition Table: (0x20C - 0x3FF) (500 bytes) + Entry: (100 bytes) (x5) + 0x00: (4 bytes) - Start Address + 0x04: (4 bytes) - Size + 0x08: (2 bytes) - Flags + 0x08: (26 bytes) - Reserved + 0x24: (64 bytes) - Partition label + + + +#========================================================================================================================================== +# Regex +#========================================================================================================================================== + Type: Javascript + + Number Constants + 0x[0-9A-Fa-f]+|0b[0-1]+|(? 0x0000.03FF + ------------- + boot-ssector 5 kb 5120 bytes (0x1400) 0x0000.0400 -> 0x0000.17FF + Unallocated 90 kb 92160 bytes (0x16800) 0x0000.1800 -> 0x0001.7FFF + DragonOS 2000 kb 2048000 bytes (0x1F4000) 0x0001.8000 -> 0x0020.BFFF + Test Partition 2000 kb 2048000 bytes (0x1F4000) 0x0020.C000 -> 0x0040.0000 diff --git a/extra/info/todo.txt b/extra/info/todo.txt new file mode 100644 index 0000000..7958361 --- /dev/null +++ b/extra/info/todo.txt @@ -0,0 +1,26 @@ +Assembler: + Add evaluation of direct struct instance name as as struct's first member + Add Struct export functionality + Add single Define export functionality + Add subroutine addres export functionality + +Bugs: + Fix VM closing when reaching hlt instruction + +Refactor: + Move all possible default values into data::DefaultValues class (in ) + +External: + Redo script to create windows Release + + + +Done: + *Inverted Colors in Text-Single-Color + *show where interrupts are disabled (in call-tree view) + *Text visualization for hardware interrupts (in call-tree view) + *Add possibility to specify instruction sets in machine config + *Add possibility to specify required instruction sets in dasm + *Add "Extended mov" instruction set + *Remove old offset mov + *Implelemnt extmov mnemonics in dasm: \ No newline at end of file diff --git a/extra/make_and_debug b/extra/make_and_debug index 6ee9871..b8e5a76 100755 --- a/extra/make_and_debug +++ b/extra/make_and_debug @@ -15,13 +15,9 @@ if [ $? -eq 0 ]; then cd scripts /bin/bash ./bios_flash cp ../dss/bios_api.dss ../../extra/dss/bios_api.dss - /bin/bash ./load_mbr + /bin/bash ./build_drake cd .. - printf "${green}Compiling Test Program...\n" - ./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose printf "\n${green}Running Application...\n\n${clear}" - ./dtools load-binary dragon/disk1.dr activeTest.bin 0x00000400 - # ./ddb config/testMachine.dvm --force-load activeTest.bin 0x00 --verbose-load ./ddb config/testMachine.dvm --verbose-load cp dragon/disk1.dr ../extra/dragon/disk1.dr cp dragon/cmos.dr ../extra/dragon/cmos.dr diff --git a/extra/make_and_run b/extra/make_and_run index 4605bc7..4c67165 100755 --- a/extra/make_and_run +++ b/extra/make_and_run @@ -15,14 +15,10 @@ if [ $? -eq 0 ]; then cd scripts /bin/bash ./bios_flash cp ../dss/bios_api.dss ../../extra/dss/bios_api.dss - /bin/bash ./load_mbr + /bin/bash ./build_drake cd .. - printf "${green}Compiling Test Program...\n" - ./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose printf "\n${green}Running Application...\n\n${clear}" - ./dtools load-binary dragon/disk1.dr activeTest.bin 0x00000400 ./dvm config/testMachine.dvm - # ./dvm config/testMachine.dvm --force-load activeTest.bin 0x00 cp dragon/disk1.dr ../extra/dragon/disk1.dr cp dragon/cmos.dr ../extra/dragon/cmos.dr fi diff --git a/extra/scripts/build_drake b/extra/scripts/build_drake new file mode 100644 index 0000000..4e7ce0e --- /dev/null +++ b/extra/scripts/build_drake @@ -0,0 +1,23 @@ +#!/bin/bash + +green='\033[0;32m' +clear='\033[0m' + +printf "\n${green}Compiling Drake...\n${clear}" +cd .. +cp ../extra/dss/drake/* ./dss/drake/ + +printf "\n${green}1) loader.dss\n${clear}" +./dasm dss/drake/loader.dss -o dragon/drake_loader.bin --extalu --save-disassembly disassembly/drake_loader.dds --verbose +./dtools load-binary dragon/disk1.dr dragon/drake_loader.bin 0x00000000 + +printf "\n${green}2) bootsector.dss\n${clear}" +./dasm dss/drake/bootsector.dss -o dragon/drake_bootsector.bin --extalu --save-disassembly disassembly/drake_bootsector.dds --verbose +./dtools load-binary dragon/disk1.dr dragon/drake_bootsector.bin 0x00000400 + +printf "\n" + + +cp dragon/disk1.dr ../extra/dragon/disk1.dr +rm dragon/drake_loader.bin +rm dragon/drake_bootsector.bin diff --git a/extra/scripts/load_mbr b/extra/scripts/load_mbr deleted file mode 100644 index d6e376c..0000000 --- a/extra/scripts/load_mbr +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -green='\033[0;32m' -clear='\033[0m' - -printf "\n${green}Reloading MBR Block...\n${clear}" -cd .. -cp ../extra/dss/drake/* ./dss/drake/ -./dasm dss/drake/loader.dss -o dragon/drake_loader.bin --extalu --save-disassembly disassembly/drake_loader.dds --verbose -./dtools load-binary dragon/disk1.dr dragon/drake_loader.bin 0x00000000 -printf "\n" -cp dragon/disk1.dr ../extra/dragon/disk1.dr -rm dragon/drake_loader.bin diff --git a/extra/scripts/run-test-1.bat b/extra/scripts/run-test-1.bat deleted file mode 100644 index a1e9d8c..0000000 --- a/extra/scripts/run-test-1.bat +++ /dev/null @@ -1,2 +0,0 @@ -dasm dss/tests/test1.dss -o test1.bin --save-disassembly disassembly/test1.dds --verbose -ddb config/testMachine.dvm --force-load test1.bin 0x00 --verbose-load --hide-vdisplay \ No newline at end of file diff --git a/extra/scripts/run-test-2.bat b/extra/scripts/run-test-2.bat deleted file mode 100644 index 918bb9a..0000000 --- a/extra/scripts/run-test-2.bat +++ /dev/null @@ -1,2 +0,0 @@ -dasm dss/tests/test2.dss -o test2.bin --save-disassembly disassembly/test2.dds --verbose -ddb config/testMachine.dvm --force-load test2.bin 0x00 --verbose-load --hide-vdisplay \ No newline at end of file diff --git a/src/hardware/VirtualIODevices.cpp b/src/hardware/VirtualIODevices.cpp index c3cdd4b..503728c 100644 --- a/src/hardware/VirtualIODevices.cpp +++ b/src/hardware/VirtualIODevices.cpp @@ -44,13 +44,13 @@ namespace dragon int8_t VirtualBIOS::write8(uint16_t addr, int8_t value) { - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, "Attempting to write to BIOS memory map."); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, ostd::String("Attempting to write to BIOS memory map.").add(addr)); return 0x00; } int16_t VirtualBIOS::write16(uint16_t addr, int16_t value) { - data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, "Attempting to write to BIOS memory map."); + data::ErrorHandler::pushError(data::ErrorCodes::BIOS_WriteAttempt, ostd::String("Attempting to write to BIOS memory map.").add(addr)); return 0x0000; } diff --git a/src/hardware/VirtualMMU.cpp b/src/hardware/VirtualMMU.cpp new file mode 100644 index 0000000..a36d5ee --- /dev/null +++ b/src/hardware/VirtualMMU.cpp @@ -0,0 +1,14 @@ +#include "VirtualMMU.hpp" + +namespace dragon +{ + namespace hw + { + VirtualMMU& VirtualMMU::init(void) + { + m_data.init(VirtualMMU::MMUSize); + m_data.enableAutoResize(false); + return *this; + } + } +} \ No newline at end of file diff --git a/src/hardware/VirtualMMU.hpp b/src/hardware/VirtualMMU.hpp new file mode 100644 index 0000000..f0b42c6 --- /dev/null +++ b/src/hardware/VirtualMMU.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace dragon +{ + namespace hw + { + class VirtualMMU //TODO: Implement for later use + { + public: + inline VirtualMMU(void) { init(); } + VirtualMMU& init(void); + + private: + ostd::serial::SerialIO m_data; + + public: + inline static constexpr uint16_t MMUSize = 6144; + inline static constexpr uint16_t PageSize = 512; + }; + } +} \ No newline at end of file diff --git a/src/hardware/VirtualRAM.cpp b/src/hardware/VirtualRAM.cpp index 3c87002..986af3b 100644 --- a/src/hardware/VirtualRAM.cpp +++ b/src/hardware/VirtualRAM.cpp @@ -10,6 +10,7 @@ namespace dragon VirtualRAM::VirtualRAM(void) { m_memory.init(0xFFFF); + m_memory.enableAutoResize(false); } int8_t VirtualRAM::read8(uint16_t addr) diff --git a/src/runtime/ConfigLoader.cpp b/src/runtime/ConfigLoader.cpp index 9e9e2bc..46c5a55 100644 --- a/src/runtime/ConfigLoader.cpp +++ b/src/runtime/ConfigLoader.cpp @@ -89,6 +89,19 @@ namespace dragon config.fixed_clock = false; else continue; //TODO: Error } + else if (lineEdit == "memory_extension_pages") + { + lineEdit = tokens.next(); + lineEdit.trim().toLower(); + if (!lineEdit.isNumeric()) continue; //TODO: Error + config.memory_extension_pages = lineEdit.toInt(); + + //TODO: Warnings + if (config.memory_extension_pages < 0) + config.memory_extension_pages = 0; + if (config.memory_extension_pages > data::DefaultValues::MaxMemoryExtensionPages) + config.memory_extension_pages = data::DefaultValues::MaxMemoryExtensionPages; + } else continue; //TODO: Warning } return validate_machine_config(config); diff --git a/src/runtime/ConfigLoader.hpp b/src/runtime/ConfigLoader.hpp index f9a8ad8..3c5108d 100644 --- a/src/runtime/ConfigLoader.hpp +++ b/src/runtime/ConfigLoader.hpp @@ -11,6 +11,7 @@ namespace dragon std::map vdisk_paths; std::map cpuext_list; int32_t clock_rate_sec { 500 }; + uint8_t memory_extension_pages { 0 }; bool fixed_clock { true }; ostd::String bios_path; ostd::String cmos_path; diff --git a/src/tools/GlobalData.hpp b/src/tools/GlobalData.hpp index 58e2f16..bccc62b 100644 --- a/src/tools/GlobalData.hpp +++ b/src/tools/GlobalData.hpp @@ -227,7 +227,6 @@ namespace dragon inline static constexpr uint8_t Boot = 0; }; public: - inline static constexpr uint16_t DiskAddress = 0x200; inline static constexpr uint16_t DPTID = 0x000; inline static constexpr uint16_t DPTVersionMaj = 0x002; @@ -241,8 +240,20 @@ namespace dragon inline static constexpr uint16_t EntryFlags = 0x008; inline static constexpr uint16_t EntryPartitionLabel = 0x024; + + + inline static constexpr uint16_t HeaderReservedSizeBytes= 7; + inline static constexpr uint16_t DiskAddress = 0x200; inline static constexpr uint16_t DPT_ID_CODE = 0xF1CA; inline static constexpr uint16_t EntrySizeBytes = 100; + inline static constexpr uint16_t EntryLabelSizeBytes = 64; + inline static constexpr uint16_t EntryReservedSizeBytes = 26; + inline static constexpr uint16_t HeaderSizeBytes = 12; + inline static constexpr uint16_t DPTBlockSizeBytes = 512; + inline static constexpr uint8_t CurrentDPTVersionMaj = 0x00; + inline static constexpr uint8_t CurrentDPTVersionMin = 0x02; + inline static constexpr uint32_t DiskStartAddr = 0x00000400; + inline static constexpr uint8_t MaxPartCount = 5; }; class CPUExtension @@ -362,5 +373,11 @@ namespace dragon static ostd::String getOpCodeString(uint8_t opCode); static uint8_t getInstructionSIze(uint8_t opCode); }; + + class DefaultValues + { + public: + inline static constexpr uint8_t MaxMemoryExtensionPages = 255; + }; } } \ No newline at end of file diff --git a/src/tools/Tools.cpp b/src/tools/Tools.cpp index 2728acf..ccd04de 100644 --- a/src/tools/Tools.cpp +++ b/src/tools/Tools.cpp @@ -45,6 +45,12 @@ namespace dragon if (rValue != ErrorNoError) return rValue; } + else if (tool == "new-dpt") + { + rValue = tool_new_dpt(argc, argv); + if (rValue != ErrorNoError) + return rValue; + } else if (tool == "--help") { print_application_help(); @@ -151,7 +157,7 @@ namespace dragon return ErrorReadDPTSmallDisk; } ostd::ByteStream outData; - if (!vHDD.read(data::DPTStructure::DiskAddress, 512, outData)) + if (!vHDD.read(data::DPTStructure::DiskAddress, data::DPTStructure::DPTBlockSizeBytes, outData)) { out.fg(ostd::ConsoleColors::Red).p("Error: Unable to read from disk.").reset().nl(); return ErrorReadDPTUnableToRead; @@ -175,6 +181,11 @@ namespace dragon uint32_t version_min = (uint32_t)outData8; dpt_block.r_Byte(data::DPTStructure::PartitionCount, outData8); uint32_t part_count = (uint32_t)outData8; + if (part_count > data::DPTStructure::MaxPartCount) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Too many partitions. Maximum is ").p(data::DPTStructure::MaxPartCount).p(".").reset().nl(); + return ErrorReadDPTNoPartitionTable; + } struct tPartitionData { uint32_t startAddress { 0 }; uint32_t size { 0 }; @@ -222,7 +233,6 @@ namespace dragon out.p(ostd::String("=").new_fixedLength(5 * len, '=')).nl(); for (int32_t i = 0; i < partitionList.size(); i++) { - bool comma = false; auto& part = partitionList[i]; if (part.label == "") part.label = ""; @@ -231,13 +241,18 @@ namespace dragon print_part_size(part.size, out, len); out.p(ostd::Utils::getHexStr(part.startAddress, true, 4).new_fixedLength(len)); out.p(ostd::Utils::getHexStr(part.startAddress + part.size, true, 4).new_fixedLength(len)); - if (ostd::Bits::get(part.flags, data::DPTStructure::tFlags::Boot)) + ostd::String flags_str = ""; + for (uint8_t bit = 0; bit < sizeof(part.flags) * 8; bit++) { - if (comma) - out.p(", "); - out.fg(ostd::ConsoleColors::Yellow).p("Boot").fg(ostd::ConsoleColors::Cyan); + if (m_dpt_flags_str.count(bit) == 0) + continue; + if (ostd::Bits::get(part.flags, bit)) + flags_str += m_dpt_flags_str[bit] + ","; } - out.nl(); + if (flags_str.len() > 0) + flags_str.substr(0, flags_str.len() - 1); + + out.fg(ostd::ConsoleColors::Yellow).p(flags_str).fg(ostd::ConsoleColors::Cyan).nl(); } out.fg(ostd::ConsoleColors::BrightGray); out.p(ostd::String("=").new_fixedLength(5 * len, '=')).nl(); @@ -245,6 +260,188 @@ namespace dragon return ErrorNoError; } + int32_t Tools::tool_new_dpt(int argc, char** argv) + { + if (argc < 5) + { + out.fg(ostd::ConsoleColors::Red).p("Error: too few arguments.").nl(); + out.fg(ostd::ConsoleColors::Red).p(" Usage: ./dtools new-dpt -p -s SIZE [-l LABEL] [-f FLAG1] [-f FLAG2] [-p SIZE ...]").reset().nl(); + return ErrorLoadProgTooFewArgs; + } + ostd::String vdisk_file = argv[2]; + dragon::hw::VirtualHardDrive vHDD(vdisk_file); + if (!vHDD.isInitialized()) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Unable to load virtual disk.").reset().nl(); + return ErrorLoadProgUnableToLoadVDisk; + } + uint64_t disk_size = vHDD.getSize(); + + auto& _dpt_flags_str = m_dpt_flags_str; + auto get_flag_from_str = [_dpt_flags_str](const ostd::String& flag_str) -> int8_t { + for (auto& flag : _dpt_flags_str) + { + if (flag.second == flag_str) + return flag.first; + } + return -1; + }; + auto make_bytestream = [](uint16_t size, ostd::Byte value = 0xFF) -> ostd::ByteStream { + + ostd::ByteStream stream; + for (int16_t i = 0; i < size; i++) + stream.push_back(value); + return stream; + }; + struct tPartData { + uint32_t size { 0 }; + uint32_t address { 0 }; + std::vector flags; + ostd::String label { "" }; + }; + + std::vector partitions; + + int32_t arg_index = 3; + bool has_args = true; + bool part_started = false; + tPartData _part_data; + uint32_t part_start_addr = data::DPTStructure::DiskStartAddr; + while (has_args) + { + ostd::String arg = argv[arg_index]; + arg.trim(); + if (part_started) + { + if (arg.new_toLower() == "-p") + { + part_started = false; + partitions.push_back(_part_data); + _part_data = tPartData(); + continue; + } + else if (arg.new_toLower() == "-l") + { + if (arg_index >= argc - 1) + { + out.fg(ostd::ConsoleColors::Red).p("Error: No partition label specified after -l parameter.").reset().nl(); + return ErrorNewDPTNoPartitionLabel; + } + arg_index++; + _part_data.label = argv[arg_index]; + } + else if (arg.new_toLower() == "-f") + { + if (arg_index >= argc - 1) + { + out.fg(ostd::ConsoleColors::Red).p("Error: No partition flag specified after -f parameter.").reset().nl(); + return ErrorNewDPTNoPartitionFlag; + } + arg_index++; + int8_t flag = get_flag_from_str(argv[arg_index]); + if (flag < 0) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Unknown partition flag.").reset().nl(); + return ErrorNewDPTUnknownFlag; + } + _part_data.flags.push_back(flag); + } + } + else + { + if (arg.new_toLower() == "-p") + { + if (arg_index >= argc - 1) + { + out.fg(ostd::ConsoleColors::Red).p("Error: No partition size specified.").reset().nl(); + return ErrorNewDPTNoPartitionSize; + } + else if (!ostd::Utils::isInt(argv[arg_index + 1])) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Partition size must be an integer.").reset().nl(); + return ErrorNewDPTInvalidPartitionSize; + } + arg_index++; + uint32_t part_size = ostd::String(argv[arg_index]).toInt(); + if (part_start_addr + part_size > disk_size) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Not enough space on disk.").reset().nl(); + return ErrorNewDPTDiskOverflow; + } + _part_data.size = part_size; + _part_data.address = part_start_addr; + part_start_addr += part_size; + part_started = true; + } + } + arg_index++; + if (arg_index >= argc || partitions.size() > data::DPTStructure::MaxPartCount) + has_args = false; + } + if (part_started) + partitions.push_back(_part_data); + + if (partitions.size() > data::DPTStructure::MaxPartCount) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Too many partitions.").reset().nl(); + return ErrorNewDPTTooManyPartitions; + } + + //HEADER + ostd::StreamIndex addr = 0; + ostd::serial::SerialIO dpt_block(data::DPTStructure::DPTBlockSizeBytes); + dpt_block.enableAutoResize(false); + dpt_block.w_Word(addr, data::DPTStructure::DPT_ID_CODE); + addr += ostd::tTypeSize::WORD; + dpt_block.w_Byte(addr, data::DPTStructure::CurrentDPTVersionMaj); + addr += ostd::tTypeSize::BYTE; + dpt_block.w_Byte(addr, data::DPTStructure::CurrentDPTVersionMin); + addr += ostd::tTypeSize::BYTE; + dpt_block.w_Byte(addr, (ostd::Byte)(partitions.size())); + addr += ostd::tTypeSize::BYTE; + uint16_t reserved_size = data::DPTStructure::HeaderReservedSizeBytes; + dpt_block.w_ByteStream(addr, make_bytestream(reserved_size), false); + addr += reserved_size; + + //PARTITIONS + for (auto& part : partitions) + { + dpt_block.w_DWord(addr, part.address); + addr += ostd::tTypeSize::DWORD; + dpt_block.w_DWord(addr, part.size); + addr += ostd::tTypeSize::DWORD; + + ostd::BitField_16 flags; + flags.value = 0; + for (auto& bit : part.flags) + ostd::Bits::set(flags, bit); + dpt_block.w_Word(addr, flags.value); + addr += ostd::tTypeSize::WORD; + + reserved_size = data::DPTStructure::EntryReservedSizeBytes; + dpt_block.w_ByteStream(addr, make_bytestream(reserved_size), false); + addr += reserved_size; + + if (part.label.len() >= data::DPTStructure::EntryLabelSizeBytes) + part.label.fixedLength(data::DPTStructure::EntryLabelSizeBytes - 1, ' ', ""); + dpt_block.w_String(addr, part.label, false, true); + addr += data::DPTStructure::EntryLabelSizeBytes; + } + + int16_t index = 0; + for (auto& b : dpt_block.getData()) + { + vHDD.write(data::DPTStructure::DiskAddress + index, b); + index++; + } + vHDD.unmount(); + out.nl().fg(ostd::ConsoleColors::Green).p("Success. DPT Block created on Virtual Disk:").nl(); + out.p(" Disk Path: ").p(vdisk_file.cpp_str()).nl(); + out.p(" DPT Block Address: ").p(ostd::Utils::getHexStr(data::DPTStructure::DiskAddress, true, 4).cpp_str()).nl(); + out.p(" DPT Block Size: ").p(data::DPTStructure::DPTBlockSizeBytes).nl(); + return ErrorNoError; + } + void Tools::print_application_help(void) { out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available tools:").nl().nl(); @@ -264,6 +461,14 @@ namespace dragon out.fg(ostd::ConsoleColors::Green).p("The tool is used to read the partition table of a Virtual Disk File.").nl(); out.p(" Path to the Virtual Disk file.").nl().nl(); + out.fg(ostd::ConsoleColors::Blue).p("new-dpt -p -s SIZE [-l LABEL] [-f FLAG1] [-f FLAG2] [-p SIZE ...]").nl(); + out.fg(ostd::ConsoleColors::Green).p("The tool is used to create a new DPT-BLOCK on Virtual Disk File.").nl(); + out.p(" Path to the Virtual Disk file.").nl(); + out.p(" -p Used to start creating a partition.").nl(); + out.p(" -s Used to specify the partition's size.").nl(); + out.p(" -l (optional) Used to specify the partition's label.").nl(); + out.p(" -f (optional) Used to specify one single flag for the partition. Use multiple -f parameters for multiple flags.").nl().nl(); + out.fg(ostd::ConsoleColors::Magenta).p("Usage: ./dtools [...arguments...]").nl().nl().reset(); } diff --git a/src/tools/Tools.hpp b/src/tools/Tools.hpp index 65a2a35..4585dc7 100644 --- a/src/tools/Tools.hpp +++ b/src/tools/Tools.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "GlobalData.hpp" namespace dragon { @@ -15,12 +16,17 @@ namespace dragon static int32_t tool_new_virtual_disk(int argc, char** argv); static int32_t tool_load_binary(int argc, char** argv); static int32_t tool_read_dpt(int argc, char** argv); + static int32_t tool_new_dpt(int argc, char** argv); static void print_application_help(void); static int32_t get_tool(int argc, char** argv, ostd::String& outTool); private: inline static ostd::ConsoleOutputHandler out; + inline static std::unordered_map m_dpt_flags_str { + { data::DPTStructure::tFlags::Boot, "boot" } + }; + public: inline static constexpr int32_t ErrorNoError = 0; inline static constexpr int32_t ErrorTopLevelTooFewArgs = 1; @@ -37,6 +43,13 @@ namespace dragon inline static constexpr int32_t ErrorReadDPTSmallDisk = 12; inline static constexpr int32_t ErrorReadDPTUnableToRead = 13; inline static constexpr int32_t ErrorReadDPTNoPartitionTable = 14; + inline static constexpr int32_t ErrorNewDPTNoPartitionSize = 15; + inline static constexpr int32_t ErrorNewDPTInvalidPartitionSize = 16; + inline static constexpr int32_t ErrorNewDPTNoPartitionLabel = 17; + inline static constexpr int32_t ErrorNewDPTNoPartitionFlag = 18; + inline static constexpr int32_t ErrorNewDPTDiskOverflow = 19; + inline static constexpr int32_t ErrorNewDPTUnknownFlag = 20; + inline static constexpr int32_t ErrorNewDPTTooManyPartitions = 21; }; } \ No newline at end of file