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 0000000..807d1e4 Binary files /dev/null and b/extra/dpt_2_partitions_on_4_mb_disk.bin differ 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 8b67f00..b08040f 100644 Binary files a/extra/dragon/bios.bin and b/extra/dragon/bios.bin differ diff --git a/extra/dragon/cmos.dr b/extra/dragon/cmos.dr index a305b77..85b346b 100644 Binary files a/extra/dragon/cmos.dr and b/extra/dragon/cmos.dr differ diff --git a/extra/dragon/disk1.dr b/extra/dragon/disk1.dr index d2e730b..8f2b38c 100644 Binary files a/extra/dragon/disk1.dr and b/extra/dragon/disk1.dr differ diff --git a/extra/dss/activeTest.dss b/extra/dss/activeTest.dss index c669ec4..b148ff9 100644 --- a/extra/dss/activeTest.dss +++ b/extra/dss/activeTest.dss @@ -4,6 +4,8 @@ $string "Hello World!!" .code + mov R10, 0xE0 + int 0x30 mov R10, 0x0C mov R9, $string int 0x30 @@ -12,4 +14,4 @@ end_loop: jmp $end_loop hlt -.fixed 512, 0x00 \ No newline at end of file +.fixed 1024, 0x00 \ No newline at end of file diff --git a/extra/dss/bios/data.dss b/extra/dss/bios/data.dss index 41ea5be..d9a1f94 100644 --- a/extra/dss/bios/data.dss +++ b/extra/dss/bios/data.dss @@ -4,7 +4,7 @@ ## ============================= Memory Mapped Devices and Registers ============================= @export_comment /BIOS_API "These are the base addresses of the memory map." -@group MemoryAddresses +@group /BIOS_API MemoryAddresses MBR 0x1380 INT_VEC 0x1080 DISK_INTERFACE 0x1580 @@ -19,6 +19,8 @@ MEM_SIZE { MemoryAddresses.CMOS + 0x0002 } CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 } BOOT_DISK { MemoryAddresses.CMOS + 0x0010 } + + DISK_LIST { MemoryAddresses.CMOS + 0x007E } @end diff --git a/extra/dss/bios/drivers.dss b/extra/dss/bios/drivers.dss index 810b1c2..a938ffd 100644 --- a/extra/dss/bios/drivers.dss +++ b/extra/dss/bios/drivers.dss @@ -4,6 +4,7 @@ _int_20_handler: mov ACC, R10 jeq $_int_20_disk_interface, 0x0010 + jeq $_int_20_disk_interface_get_disk_list, 0x0011 jeq $_int_20_set_new_interrupt_handler, 0x0000 jeq $_int_20_clear_interrupt, 0x0001 jmp $_int_20_end @@ -24,6 +25,8 @@ _int_20_disk_interface: mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], *R9 ## Memory Address movb [MemoryAddresses.DISK_INTERFACE], 0x00 ## Signal set to "Start Operation" jmp $_int_20_end +_int_20_disk_interface_get_disk_list: + jmp $_int_20_end _int_20_set_new_interrupt_handler: push R8 ## Interrupt Code push R9 ## Handler Address @@ -117,7 +120,6 @@ _int_30_invert_colors_text_single_normal: jmp $_int_30_end _int_30_print_string_buffered: mov [VGA_Registers.TEXT_SIGNLE_STR], R9 - debug_break movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_STRING jmp $_int_30_end diff --git a/extra/dss/bios/utils.dss b/extra/dss/bios/utils.dss index 957350d..2add339 100644 --- a/extra/dss/bios/utils.dss +++ b/extra/dss/bios/utils.dss @@ -45,7 +45,6 @@ _set_interrupt_vector_entry_end: _print_integer: mov R1, 0 arg ACC - debug_break jne $_print_integer_loop, 0 push 48 ## '0' ASCII is 48 inc R1 @@ -56,7 +55,6 @@ _print_integer_loop: addipu RV, 48 push RV inc R1 - debug_break jmp $_print_integer_loop _print_integer_loop_end: pop R9 diff --git a/extra/dss/bios_api.dss b/extra/dss/bios_api.dss new file mode 100644 index 0000000..a25f9a0 --- /dev/null +++ b/extra/dss/bios_api.dss @@ -0,0 +1,48 @@ +## -- +## -- This file is automatically generated by the DragonAssembler (version 0.3.1592) +## -- Please do not modify this file in any way. +## -- + +@guard __AUTO_GEN_GUARD_BIOS_API_DSS__ + +## -- These are the base addresses of the memory map. +@define MemoryAddresses.MBR 0x1380 +@define MemoryAddresses.INT_VEC 0x1080 +@define MemoryAddresses.DISK_INTERFACE 0x1580 +@define MemoryAddresses.RAM 0x1740 +@define MemoryAddresses.CMOS 0x1000 +@define MemoryAddresses.VGA 0x1600 +## -- + +## -- These are the Hardware Interrupt codes of this machine. +@define HW_Int.DISK_INTERFACE_FINISHED 0x80 +@define HW_Int.KEY_PRESSED 0xA0 +@define HW_Int.KEY_RELEASED 0xA1 +@define HW_Int.TEXT_ENTERED 0xA2 +## -- + +## -- These are the memory-mapped registers used to interact with the video card's interface. +@define VGA_Registers.VIDEO_MODE 0x1600 +@define VGA_Registers.SIGNAL 0x1603 +@define VGA_Registers.TEXT_SINGLE_CHAR 0x1604 +@define VGA_Registers.TEXT_SIGNLE_INVERT 0x1605 +@define VGA_Registers.TEXT_SIGNLE_STR 0x1606 +@define VGA_Registers.BUFF_START 0x16E0 +## -- + +## -- These are the different Video Modes that the video card supports. +@define VGA_VideoModes.TEXT_SINGLE_COLOR 0x00 +## -- + +## -- These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode. +@define Sig_VGA_Text_Single_Color.CONTINUE 0x00 +@define Sig_VGA_Text_Single_Color.PRINT_CHAR 0x02 +@define Sig_VGA_Text_Single_Color.STORE_CHAR 0x03 +@define Sig_VGA_Text_Single_Color.PRINT_FLUSH_BUFF 0x04 +@define Sig_VGA_Text_Single_Color.FLUSH_BUFF 0x05 +@define Sig_VGA_Text_Single_Color.PRINT_BUFF 0x06 +@define Sig_VGA_Text_Single_Color.PRINT_STRING 0x07 +@define Sig_VGA_Text_Single_Color.REFRESH_SCREEN 0xE0 +@define Sig_VGA_Text_Single_Color.CLEAR_SCREEN 0xE1 +## -- + diff --git a/extra/dss/drake.dss b/extra/dss/drake.dss deleted file mode 100644 index e01c709..0000000 --- a/extra/dss/drake.dss +++ /dev/null @@ -1,7 +0,0 @@ -.load 0x1380 - -.code - jmp 0x1740 - hlt - -.fixed 512, 0x00 diff --git a/extra/dss/drake/disk.dss b/extra/dss/drake/disk.dss new file mode 100644 index 0000000..7b9b803 --- /dev/null +++ b/extra/dss/drake/disk.dss @@ -0,0 +1,66 @@ +@guard _DISK_DSS_ + +@define DISK_INTERFACE_ADDR 0x1580 + +@group DiskMode + READ 0x00 + WRITE 0x01 +@end + +@group DiskSignals + START 0x00 + CANCEL 0x01 + IGNORE 0xFF +@end + +@group DiskStatus + FREE 0x00 + WRITING 0x01 + READING 0x02 +@end + +@group DiskRegisters + SIGNAL 0x00 + MODE_SELECTOR 0x01 + DISK_SELECTOR 0x02 + SECTOR_SELECTOR 0x03 + ADDRESS_SELECTOR 0x05 + DATA_SIZE 0x07 + MEMORY_ADDRESS 0x09 + RO_STATUS 0x0B + RO_CURRENT_DISK 0x0C + RO_CURRENT_SECTOR 0x0D + RO_CURRENT_ADDRESS 0x0F + RO_REST_DATA_SIZE 0x11 + RO_MEMORY_ADDRESS 0x13 +@end + +@struct DiskDriverData + Mode:1 > 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