From b2bbf7c560a766ba2ab937d2fbd9474a258c4784 Mon Sep 17 00:00:00 2001 From: OmniaX-dev Date: Sun, 7 Apr 2024 01:16:44 +0200 Subject: [PATCH] Implemented DPT (Partition table) + started work on Drake (bootloader) --- build.nr | 2 +- create_win_release.sh | 5 +- extra/dpt_2_partitions_on_4_mb_disk.bin | Bin 0 -> 512 bytes .../dpt_2_partitions_on_4_mb_disk.txt | 42 ++++++ extra/dragon info/info | 8 +- extra/dragon/bios.bin | Bin 4096 -> 4096 bytes extra/dragon/cmos.dr | Bin 128 -> 128 bytes extra/dragon/disk1.dr | Bin 4194304 -> 4194304 bytes extra/dss/activeTest.dss | 4 +- extra/dss/bios/data.dss | 4 +- extra/dss/bios/drivers.dss | 4 +- extra/dss/bios/utils.dss | 2 - extra/dss/bios_api.dss | 48 +++++++ extra/dss/drake.dss | 7 - extra/dss/drake/disk.dss | 66 +++++++++ extra/dss/drake/dpt.dss | 23 ++++ extra/dss/drake/entry.dss | 61 +++++++++ extra/make_and_debug | 5 +- extra/make_and_run | 5 +- extra/scripts/load_mbr | 4 +- src/hardware/VirtualIODevices.cpp | 10 +- src/hardware/VirtualIODevices.hpp | 4 +- src/runtime/DragonRuntime.cpp | 10 +- src/tools/GlobalData.hpp | 26 ++++ src/tools/Tools.cpp | 127 ++++++++++++++++++ src/tools/Tools.hpp | 7 + 26 files changed, 444 insertions(+), 30 deletions(-) create mode 100644 extra/dpt_2_partitions_on_4_mb_disk.bin create mode 100644 extra/dragon info/dpt_2_partitions_on_4_mb_disk.txt create mode 100644 extra/dss/bios_api.dss delete mode 100644 extra/dss/drake.dss create mode 100644 extra/dss/drake/disk.dss create mode 100644 extra/dss/drake/dpt.dss create mode 100644 extra/dss/drake/entry.dss diff --git a/build.nr b/build.nr index 2973cf2..7b222bc 100644 --- a/build.nr +++ b/build.nr @@ -1 +1 @@ -1592 +1593 diff --git a/create_win_release.sh b/create_win_release.sh index e3cc50d..40e793f 100644 --- a/create_win_release.sh +++ b/create_win_release.sh @@ -14,7 +14,7 @@ rm dragon/disk1.dr ./dtools new-vdisk dragon/disk1.dr 1048576 printf "\n${green}Compiling MBR Block...\n${clear}" -./dasm dss/drake.dss -o dragon/drake.bin --save-disassembly disassembly/drake.dds --verbose +./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 @@ -46,8 +46,9 @@ 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.dss ./win-release/dss +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 diff --git a/extra/dpt_2_partitions_on_4_mb_disk.bin b/extra/dpt_2_partitions_on_4_mb_disk.bin new file mode 100644 index 0000000000000000000000000000000000000000..807d1e4382fbf1d538ee375ba13c94a8b006a125 GIT binary patch literal 512 zcmex(ih+scKLju^urM$%hyXEE01M^h?;jHE>Kx)91XM;AkYHe7%mC`dVmMTYEMt*1 zF*YzT$U6Y-!EJ|2QDS<2o_{d1Hj>y12OxIf@kdB%afw1eVo^zENoIZ?Nv1;-6JZA# IrlM#80N#+9tN;K2 literal 0 HcmV?d00001 diff --git a/extra/dragon info/dpt_2_partitions_on_4_mb_disk.txt b/extra/dragon info/dpt_2_partitions_on_4_mb_disk.txt new file mode 100644 index 0000000..b539018 --- /dev/null +++ b/extra/dragon info/dpt_2_partitions_on_4_mb_disk.txt @@ -0,0 +1,42 @@ +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/info b/extra/dragon info/info index de764e6..7a72510 100644 --- a/extra/dragon info/info +++ b/extra/dragon info/info @@ -12,8 +12,7 @@ ClockSpeed: (2 bytes) 0x0004 BootDisk: 0x0010 - ICC_ - ICC_OutputAddr: (2 bytes) 0x007E + DiskList: (2 bytes) 0x007E 0x107F ------- 0x1080 INTERRUPT VECTOR (512 Bytes) @@ -164,5 +163,6 @@ Partition Table: (0x20C - 0x3FF) (500 bytes) Entry: (100 bytes) (x5) 0x00: (4 bytes) - Start Address 0x04: (4 bytes) - Size - 0x08: (28 bytes) - Reserved - 0x40: (64 bytes) - Partition label + 0x08: (2 bytes) - Flags + 0x08: (26 bytes) - Reserved + 0x24: (64 bytes) - Partition label diff --git a/extra/dragon/bios.bin b/extra/dragon/bios.bin index 8b67f0035743479d3c31daf6b065d31c55e08f91..b08040f87c4663c3d03325971cf9b9e88d1fabec 100644 GIT binary patch delta 513 zcmY+Au}dpK5XQf|-I>*m#q9~_D-;d|NkAm6U~$&3F$qa+A$DS%QVx?wUK4ml{ssH@ zKs&)w3$gQQYib)C%jdak1a)DV@3%Aa&9K9KnE(B$w;mFQ=4-wUbm-r1^-7L70AKGR z3J{~5A6Aa%MURk(zJL>b35dQyROU7 zeX|+dwWuDGi#o~6ja#gO11AZi(=(B?@Z9N1hT zr1cN5usArdRS@lrjeo!eti^x8i@TQ;7R!9UGdrJ|-B~@WPanE_KgxjqMSTPeY4K!r zL4i0M{`?dsn*#0jY!!H0-5ZqZJ_72#z_e~LKXG@bi$NH~BNRhkrBs$!yT7@IZow$+ zpitU_ReAuY^cbY{46LN^N-wab^a@v$jv-3#&`~1M1rnuPFcL|!(z^AzSk>5q9o|H^l!zktzL_60Tw?@2iemQ!LNc}4ym z#Ex104WKKl*5B?58o4e!Dg_v`nfQbJtNlh=f2jTtSYBhuGFbEnwh`0%gGcec3e*A= delta 8 PcmZo*Y+#&F&&U7(3ey4; diff --git a/extra/dragon/disk1.dr b/extra/dragon/disk1.dr index d2e730b46d1233a0cab446f82af99849014ca88e..8f2b38c7daf2eae949eeeadcd84979796e9fdaba 100644 GIT binary patch delta 769 zcma)3O=}ZT6upT_)L4@<$&3@VwJ)u$)>da~{pgoA+7<*CsV2pZFa%n)5E_XAHv=6l z2N5^UZxQ#d{S~@#<3?95go$s`C?chJ;huZXdH1~ccrOToWT11$H%m$>&-4BU&0|T2 zDCHk1o!`yBRZx^q zk-H{RGnY2HQQAmndZhVC5;5`Zif=A-kt^;ZFM^C@v}K@@N1^y5a*aYRadOtK~M@k}zCkM`l#;wUjATnIhqxOrgB+$fj(-w?kn3ifj3 z`gWuH&Paa!NhF9QafnC}X(B@$CXNtCi7au97$A-lIU-MhFo*(CBuv60P7pRxB2E&g zh||O%F+`jph6zQKi4kIyI7^HX`ZAD9xssubWGoZ8mZ{8SE;n*3cXBTe@+eR8EHCmZ MZ}Ki5Uwr 0x00 + Disk:1 > 0x00 + Sector:2 > 0x00, 0x00 + Address:2 > 0x00, 0x00 + DataSize:2 > 0x00, 0x00 + MemoryAddress: > 0x00, 0x00 +@end + +.code + +_disk_load_from_ddd_blocking: + arg R1 + movb [{DISK_INTERFACE_ADDR + DiskRegisters.MODE_SELECTOR}], *R1 + inc R1 + movb [{DISK_INTERFACE_ADDR + DiskRegisters.DISK_SELECTOR}], *R1 + inc R1 + mov [{DISK_INTERFACE_ADDR + DiskRegisters.SECTOR_SELECTOR}], *R1 + addip R1, 2 + mov [{DISK_INTERFACE_ADDR + DiskRegisters.ADDRESS_SELECTOR}], *R1 + addip R1, 2 + mov [{DISK_INTERFACE_ADDR + DiskRegisters.DATA_SIZE}], *R1 + addip R1, 2 + mov [{DISK_INTERFACE_ADDR + DiskRegisters.MEMORY_ADDRESS}], *R1 + movb [{DISK_INTERFACE_ADDR + DiskRegisters.SIGNAL}], DiskSignals.START +_disk_load_from_ddd_blocking_wait_loop: + mov ACC, [{DISK_INTERFACE_ADDR + DiskRegisters.RO_STATUS}] + jne $_disk_load_from_ddd_blocking_wait_loop, DiskStatus.FREE + ret \ No newline at end of file diff --git a/extra/dss/drake/dpt.dss b/extra/dss/drake/dpt.dss new file mode 100644 index 0000000..9a3be0c --- /dev/null +++ b/extra/dss/drake/dpt.dss @@ -0,0 +1,23 @@ +@uard _DPT_DSS_ + +@group DPTStructure + DISK_ADDR 0x0200 + ENTRIES_START 0x000C + + ENTRY_START_ADDR 0x0000 + ENTRY_PART_SIZE 0x0004 + ENTRY_FLAGS 0x0008 + ENTRY_PART_LBL 0x0024 + + ID_CODE 0xF1CA + ENTRY_SIZE_B 100 +@end + +@struct DPTBlock + ID:2 + VersionMaj:1 + VersionMin:1 + PartCount:1 + Reserved:7 + Entries:500 +@end \ No newline at end of file diff --git a/extra/dss/drake/entry.dss b/extra/dss/drake/entry.dss new file mode 100644 index 0000000..e04346e --- /dev/null +++ b/extra/dss/drake/entry.dss @@ -0,0 +1,61 @@ +.load 0x1380 + +@include <../bios_api.dss> + +.data + $_drake_logo_line_1 " ___ ___ ___ __ ______" + $_drake_logo_line_2 " / _ \/ _ \/ _ | / //_/ __/" + $_drake_logo_line_3 " / // / , _/ __ |/ ,< / _/ " + $_drake_logo_line_4 "/____/_/|_/_/ |_/_/|_/___/ " + $_logo_padding " " + + +.code + mov R10, 0xE0 + int 0x30 + push 0 + call $_print_logo + and FL, 0b1111111111111110 ## Disable interrupts + mov FL, ACC + push 0 + call $_load_boot_sector + or FL, 0b0000000000000001 ## Enable interrupts + mov FL, ACC + jmp MemoryAddresses.RAM +_infinite_loop: + jmp $_infinite_loop + hlt + +_print_logo: + mov R5, $_drake_logo_line_1 + mov R6, 0 + mov ACC, 6 +_print_logo_loop: + mov R10, 0x0C + inc R6 + mov R9, $_logo_padding + int 0x30 + mov R9, R5 + int 0x30 + mov R10, 0x02 + int 0x30 + addip R5, 29 + 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: + 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 + + +.fixed 512, 0x00 diff --git a/extra/make_and_debug b/extra/make_and_debug index 07bb9e3..d8cc29f 100755 --- a/extra/make_and_debug +++ b/extra/make_and_debug @@ -19,7 +19,10 @@ if [ $? -eq 0 ]; then 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}" - ./ddb config/testMachine.dvm --force-load activeTest.bin 0x00 --verbose-load + ./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 + cp dss/bios_api.dss ../extra/dss/bios_api.dss fi diff --git a/extra/make_and_run b/extra/make_and_run index 1862670..bf0da44 100755 --- a/extra/make_and_run +++ b/extra/make_and_run @@ -19,7 +19,10 @@ if [ $? -eq 0 ]; then 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}" - ./dvm config/testMachine.dvm --force-load activeTest.bin 0x00 + ./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 + cp dss/bios_api.dss ../extra/dss/bios_api.dss fi diff --git a/extra/scripts/load_mbr b/extra/scripts/load_mbr index 865c596..b33cd73 100644 --- a/extra/scripts/load_mbr +++ b/extra/scripts/load_mbr @@ -5,8 +5,8 @@ clear='\033[0m' printf "\n${green}Reloading MBR Block...\n${clear}" cd .. -cp ../extra/dss/drake.dss ./dss/drake.dss -./dasm dss/drake.dss -o dragon/drake.bin --save-disassembly disassembly/drake.dds --verbose +cp ../extra/dss/drake/* ./dss/drake/ +./dasm dss/drake/entry.dss -o dragon/drake.bin --extalu --save-disassembly disassembly/drake.dds --verbose ./dtools load-binary dragon/disk1.dr dragon/drake.bin 0x00000000 printf "\n" cp dragon/disk1.dr ../extra/dragon/disk1.dr diff --git a/src/hardware/VirtualIODevices.cpp b/src/hardware/VirtualIODevices.cpp index 2469249..c3cdd4b 100644 --- a/src/hardware/VirtualIODevices.cpp +++ b/src/hardware/VirtualIODevices.cpp @@ -626,18 +626,20 @@ namespace dragon m_busy = true; } - data::VDiskID Disk::connectDisk(VirtualHardDrive& hdd) + bool Disk::connectDisk(VirtualHardDrive& hdd, data::VDiskID disk_id) { for (auto& disk : m_connectedDisks) { if (disk.second->isSame(hdd)) { data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_DiskAlreadyConnected, "Attempt to connect already connected Disk to Controller"); - return 0; + return false; } } - m_connectedDisks[Disk::s_nextDiskID] = &hdd; - return Disk::s_nextDiskID++; + m_connectedDisks[disk_id] = &hdd; + return true; + // m_connectedDisks[Disk::s_nextDiskID] = &hdd; + // return Disk::s_nextDiskID++; } bool Disk::disconnectDisk(data::VDiskID diskID) diff --git a/src/hardware/VirtualIODevices.hpp b/src/hardware/VirtualIODevices.hpp index 3f64bdf..45bd5eb 100644 --- a/src/hardware/VirtualIODevices.hpp +++ b/src/hardware/VirtualIODevices.hpp @@ -328,7 +328,7 @@ namespace dragon ostd::ByteStream* getByteStream(void) override; void cycleStep(void); - data::VDiskID connectDisk(VirtualHardDrive& hdd); + bool connectDisk(VirtualHardDrive& hdd, data::VDiskID disk_id); bool disconnectDisk(data::VDiskID diskID); inline bool isBusy(void) const { return m_busy; } @@ -340,7 +340,7 @@ namespace dragon MemoryMapper& m_memory; VirtualCPU& m_cpu; - inline static data::VDiskID s_nextDiskID = 0; + // inline static data::VDiskID s_nextDiskID = 0; }; class Graphics : public IMemoryDevice diff --git a/src/runtime/DragonRuntime.cpp b/src/runtime/DragonRuntime.cpp index ea4a1a1..ef3879d 100644 --- a/src/runtime/DragonRuntime.cpp +++ b/src/runtime/DragonRuntime.cpp @@ -165,7 +165,7 @@ namespace dragon for (auto const& disk_path : machine_config.vdisk_paths) { vDisks[disk_path.first] = dragon::hw::VirtualHardDrive(disk_path.second); - vDiskInterface.connectDisk(vDisks[disk_path.first]); + vDiskInterface.connectDisk(vDisks[disk_path.first], disk_path.first); if (verbose) out.fg(ostd::ConsoleColors::BrightYellow).p(" Disk").p(disk_path.first).p(" connected: ").p(disk_path.second.cpp_str()).nl(); } @@ -318,6 +318,14 @@ namespace dragon vCMOS.write16(data::CMOSRegisters::MemoryStart, data::MemoryMapAddresses::Memory_Start); vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End); vCMOS.write16(data::CMOSRegisters::ClockSpeed, machine_config.clock_rate_sec); + ostd::BitField_16 disk_list_bitfield; + disk_list_bitfield.value = 0; + for (int32_t i = 0; i < 16; i++) + { + if (vDisks.count(i) > 0) + ostd::Bits::set(disk_list_bitfield, i); + } + vCMOS.write16(data::CMOSRegisters::DiskList, disk_list_bitfield.value); if (verbose) out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl(); diff --git a/src/tools/GlobalData.hpp b/src/tools/GlobalData.hpp index 29bacb7..7fa8b63 100644 --- a/src/tools/GlobalData.hpp +++ b/src/tools/GlobalData.hpp @@ -216,6 +216,32 @@ namespace dragon inline static constexpr uint8_t MemorySize = 0x02; inline static constexpr uint8_t ClockSpeed = 0x04; inline static constexpr uint8_t BootDisk = 0x10; + + inline static constexpr uint8_t DiskList = 0x7E; + }; + + class DPTStructure + { + public: struct tFlags { + 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; + inline static constexpr uint16_t DPTVersionMin = 0x003; + inline static constexpr uint16_t PartitionCount = 0x004; + + inline static constexpr uint16_t EntriesStart = 0x00C; + + inline static constexpr uint16_t EntryStartAddress = 0x000; + inline static constexpr uint16_t EntryPartitionSize = 0x004; + inline static constexpr uint16_t EntryFlags = 0x008; + inline static constexpr uint16_t EntryPartitionLabel = 0x024; + + inline static constexpr uint16_t DPT_ID_CODE = 0xF1CA; + inline static constexpr uint16_t EntrySizeBytes = 100; }; class CPUExtension diff --git a/src/tools/Tools.cpp b/src/tools/Tools.cpp index 1eb6f8c..2728acf 100644 --- a/src/tools/Tools.cpp +++ b/src/tools/Tools.cpp @@ -3,6 +3,8 @@ #include #include #include "../hardware/VirtualHardDrive.hpp" +#include "GlobalData.hpp" +#include namespace dragon { @@ -37,6 +39,12 @@ namespace dragon if (rValue != ErrorNoError) return rValue; } + else if (tool == "read-dpt") + { + rValue = tool_read_dpt(argc, argv); + if (rValue != ErrorNoError) + return rValue; + } else if (tool == "--help") { print_application_help(); @@ -122,6 +130,121 @@ namespace dragon return ErrorNoError; } + int32_t Tools::tool_read_dpt(int argc, char** argv) + { + if (argc < 3) + { + out.fg(ostd::ConsoleColors::Red).p("Error: too few arguments.").nl(); + out.fg(ostd::ConsoleColors::Red).p(" Usage: ./dtools read-dpt ").reset().nl(); + return ErrorReadDPTTooFewArgs; + } + 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 ErrorReadDPTUnableToLoadVDisk; + } + if (vHDD.getSize() < 1024) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Disk too small.").reset().nl(); + return ErrorReadDPTSmallDisk; + } + ostd::ByteStream outData; + if (!vHDD.read(data::DPTStructure::DiskAddress, 512, outData)) + { + out.fg(ostd::ConsoleColors::Red).p("Error: Unable to read from disk.").reset().nl(); + return ErrorReadDPTUnableToRead; + } + // ostd::Utils::printByteStream(outData, 0, 16, 32, out); + ostd::serial::SerialIO dpt_block(outData); + int8_t outData8 = 0; + int16_t outData16 = 0; + int32_t outData32 = 0; + //TODO: Add errors for all read calls + dpt_block.r_Word(data::DPTStructure::DPTID, outData16); + uint16_t code = (uint16_t)outData16; + if (code != data::DPTStructure::DPT_ID_CODE) + { + out.fg(ostd::ConsoleColors::Red).p("Error: No DPT partition table on virtual disk.").reset().nl(); + return ErrorReadDPTNoPartitionTable; + } + dpt_block.r_Byte(data::DPTStructure::DPTVersionMaj, outData8); + uint32_t version_maj = (uint32_t)outData8; + dpt_block.r_Byte(data::DPTStructure::DPTVersionMin, outData8); + uint32_t version_min = (uint32_t)outData8; + dpt_block.r_Byte(data::DPTStructure::PartitionCount, outData8); + uint32_t part_count = (uint32_t)outData8; + struct tPartitionData { + uint32_t startAddress { 0 }; + uint32_t size { 0 }; + ostd::BitField_16 flags { 0 }; + ostd::String label { "" }; + }; + std::vector partitionList; + for (int32_t i = 0; i < part_count; i++) + { + tPartitionData pdata; + uint32_t entry_addr = data::DPTStructure::EntriesStart + (data::DPTStructure::EntrySizeBytes * i); + dpt_block.r_DWord(entry_addr + data::DPTStructure::EntryStartAddress, outData32); + pdata.startAddress = (uint32_t)outData32; + dpt_block.r_DWord(entry_addr + data::DPTStructure::EntryPartitionSize, outData32); + pdata.size = (uint32_t)outData32; + dpt_block.r_Word(entry_addr + data::DPTStructure::EntryFlags, outData16); + pdata.flags.value = (uint16_t)outData16; + dpt_block.r_NullTerminatedString(entry_addr + data::DPTStructure::EntryPartitionLabel, pdata.label); + pdata.label.trim(); + partitionList.push_back(pdata); + } + out.fg(ostd::ConsoleColors::BrightRed).p("Disk: ").p(vdisk_file).p(" (").p(vHDD.getSize()).p(" bytes)").nl(); + auto print_part_size = [](uint32_t size, ostd::ConsoleOutputHandler& out, uint16_t line_len) { + double dsize = size; + ostd::String units[4] = { " bytes", " Kb", " Mb", " Gb" }; + int32_t unit_index = 0; + while (dsize > 1024 && unit_index < 3) + { + unit_index++; + dsize /= 1024.0; + } + out.p(ostd::String("").add(dsize, 2).add(units[unit_index]).new_fixedLength(line_len)); + }; + uint16_t len = 20; + out.nl().fg(ostd::ConsoleColors::BrightGray); + out.p(ostd::String("=").new_fixedLength(5 * len, '=')).nl(); + out.fg(ostd::ConsoleColors::Blue); + out.p(" "); + out.p(ostd::String("LABEL").new_fixedLength(len)); + out.p(ostd::String("SIZE").new_fixedLength(len)); + out.p(ostd::String("START").new_fixedLength(len)); + out.p(ostd::String("END").new_fixedLength(len)); + out.p(ostd::String("FLAGS").new_fixedLength(len)); + out.nl().fg(ostd::ConsoleColors::BrightGray); + 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 = ""; + out.fg(ostd::ConsoleColors::Cyan).p(" "); + out.p(part.label.new_fixedLength(len)); + 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)) + { + if (comma) + out.p(", "); + out.fg(ostd::ConsoleColors::Yellow).p("Boot").fg(ostd::ConsoleColors::Cyan); + } + out.nl(); + } + out.fg(ostd::ConsoleColors::BrightGray); + out.p(ostd::String("=").new_fixedLength(5 * len, '=')).nl(); + out.reset().nl(); + return ErrorNoError; + } + void Tools::print_application_help(void) { out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available tools:").nl().nl(); @@ -137,6 +260,10 @@ namespace dragon out.p(" Path of the destination Virtual Disk file to be created.").nl(); out.p(" Size of the new Virtual Disk file, in bytes .").nl().nl(); + out.fg(ostd::ConsoleColors::Blue).p("read-dpt ").nl(); + 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::Magenta).p("Usage: ./dtools [...arguments...]").nl().nl().reset(); } diff --git a/src/tools/Tools.hpp b/src/tools/Tools.hpp index 84c014d..65a2a35 100644 --- a/src/tools/Tools.hpp +++ b/src/tools/Tools.hpp @@ -14,6 +14,7 @@ namespace dragon private: 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 void print_application_help(void); static int32_t get_tool(int argc, char** argv, ostd::String& outTool); @@ -31,5 +32,11 @@ namespace dragon inline static constexpr int32_t ErrorLoadProgNonIntAddr = 7; inline static constexpr int32_t ErrorLoadProgUnableToLoadVDisk = 8; inline static constexpr int32_t ErrorLoadProgUnableToLoadDataFile = 9; + inline static constexpr int32_t ErrorReadDPTTooFewArgs = 10; + inline static constexpr int32_t ErrorReadDPTUnableToLoadVDisk = 11; + inline static constexpr int32_t ErrorReadDPTSmallDisk = 12; + inline static constexpr int32_t ErrorReadDPTUnableToRead = 13; + inline static constexpr int32_t ErrorReadDPTNoPartitionTable = 14; + }; } \ No newline at end of file