Implemented DPT (Partition table) + started work on Drake (bootloader)

This commit is contained in:
OmniaX-dev 2024-04-07 01:16:44 +02:00
parent 79261a67a2
commit b2bbf7c560
26 changed files with 444 additions and 30 deletions

View file

@ -1 +1 @@
1592 1593

View file

@ -14,7 +14,7 @@ rm dragon/disk1.dr
./dtools new-vdisk dragon/disk1.dr 1048576 ./dtools new-vdisk dragon/disk1.dr 1048576
printf "\n${green}Compiling MBR Block...\n${clear}" 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}" printf "\n${green}Loading MBR Block...\n${clear}"
./dtools load-binary dragon/disk1.dr dragon/drake.bin 0x00000000 ./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/dss4
mkdir ./win-release/dss/bios mkdir ./win-release/dss/bios
mkdir ./win-release/dss/drake
cp ./bin/dss/bios/* ./win-release/dss/bios 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/test1.dss ./win-release/dss
cp ./bin/dss/tests/test2.dss ./win-release/dss cp ./bin/dss/tests/test2.dss ./win-release/dss

Binary file not shown.

View file

@ -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

View file

@ -12,8 +12,7 @@
ClockSpeed: (2 bytes) 0x0004 ClockSpeed: (2 bytes) 0x0004
BootDisk: 0x0010 BootDisk: 0x0010
ICC_ DiskList: (2 bytes) 0x007E
ICC_OutputAddr: (2 bytes) 0x007E
0x107F 0x107F
------- -------
0x1080 INTERRUPT VECTOR (512 Bytes) 0x1080 INTERRUPT VECTOR (512 Bytes)
@ -164,5 +163,6 @@ Partition Table: (0x20C - 0x3FF) (500 bytes)
Entry: (100 bytes) (x5) Entry: (100 bytes) (x5)
0x00: (4 bytes) - Start Address 0x00: (4 bytes) - Start Address
0x04: (4 bytes) - Size 0x04: (4 bytes) - Size
0x08: (28 bytes) - Reserved 0x08: (2 bytes) - Flags
0x40: (64 bytes) - Partition label 0x08: (26 bytes) - Reserved
0x24: (64 bytes) - Partition label

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -4,6 +4,8 @@
$string "Hello World!!" $string "Hello World!!"
.code .code
mov R10, 0xE0
int 0x30
mov R10, 0x0C mov R10, 0x0C
mov R9, $string mov R9, $string
int 0x30 int 0x30
@ -12,4 +14,4 @@ end_loop:
jmp $end_loop jmp $end_loop
hlt hlt
.fixed 512, 0x00 .fixed 1024, 0x00

View file

@ -4,7 +4,7 @@
## ============================= Memory Mapped Devices and Registers ============================= ## ============================= Memory Mapped Devices and Registers =============================
@export_comment /BIOS_API "These are the base addresses of the memory map." @export_comment /BIOS_API "These are the base addresses of the memory map."
@group MemoryAddresses @group /BIOS_API MemoryAddresses
MBR 0x1380 MBR 0x1380
INT_VEC 0x1080 INT_VEC 0x1080
DISK_INTERFACE 0x1580 DISK_INTERFACE 0x1580
@ -19,6 +19,8 @@
MEM_SIZE { MemoryAddresses.CMOS + 0x0002 } MEM_SIZE { MemoryAddresses.CMOS + 0x0002 }
CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 } CLOCK_SPEED { MemoryAddresses.CMOS + 0x0004 }
BOOT_DISK { MemoryAddresses.CMOS + 0x0010 } BOOT_DISK { MemoryAddresses.CMOS + 0x0010 }
DISK_LIST { MemoryAddresses.CMOS + 0x007E }
@end @end

View file

@ -4,6 +4,7 @@
_int_20_handler: _int_20_handler:
mov ACC, R10 mov ACC, R10
jeq $_int_20_disk_interface, 0x0010 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_set_new_interrupt_handler, 0x0000
jeq $_int_20_clear_interrupt, 0x0001 jeq $_int_20_clear_interrupt, 0x0001
jmp $_int_20_end jmp $_int_20_end
@ -24,6 +25,8 @@ _int_20_disk_interface:
mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], *R9 ## Memory Address mov [{MemoryAddresses.DISK_INTERFACE + 0x9}], *R9 ## Memory Address
movb [MemoryAddresses.DISK_INTERFACE], 0x00 ## Signal set to "Start Operation" movb [MemoryAddresses.DISK_INTERFACE], 0x00 ## Signal set to "Start Operation"
jmp $_int_20_end jmp $_int_20_end
_int_20_disk_interface_get_disk_list:
jmp $_int_20_end
_int_20_set_new_interrupt_handler: _int_20_set_new_interrupt_handler:
push R8 ## Interrupt Code push R8 ## Interrupt Code
push R9 ## Handler Address push R9 ## Handler Address
@ -117,7 +120,6 @@ _int_30_invert_colors_text_single_normal:
jmp $_int_30_end jmp $_int_30_end
_int_30_print_string_buffered: _int_30_print_string_buffered:
mov [VGA_Registers.TEXT_SIGNLE_STR], R9 mov [VGA_Registers.TEXT_SIGNLE_STR], R9
debug_break
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_STRING movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_STRING
jmp $_int_30_end jmp $_int_30_end

View file

@ -45,7 +45,6 @@ _set_interrupt_vector_entry_end:
_print_integer: _print_integer:
mov R1, 0 mov R1, 0
arg ACC arg ACC
debug_break
jne $_print_integer_loop, 0 jne $_print_integer_loop, 0
push 48 ## '0' ASCII is 48 push 48 ## '0' ASCII is 48
inc R1 inc R1
@ -56,7 +55,6 @@ _print_integer_loop:
addipu RV, 48 addipu RV, 48
push RV push RV
inc R1 inc R1
debug_break
jmp $_print_integer_loop jmp $_print_integer_loop
_print_integer_loop_end: _print_integer_loop_end:
pop R9 pop R9

48
extra/dss/bios_api.dss Normal file
View file

@ -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
## --

View file

@ -1,7 +0,0 @@
.load 0x1380
.code
jmp 0x1740
hlt
.fixed 512, 0x00

66
extra/dss/drake/disk.dss Normal file
View file

@ -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

23
extra/dss/drake/dpt.dss Normal file
View file

@ -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

61
extra/dss/drake/entry.dss Normal file
View file

@ -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 <Status> register into ACC
jne $_load_boot_sector_block_wait_loop, 0x00 ## If <Status> register not Free, loop around and wait
ret
.fixed 512, 0x00

View file

@ -19,7 +19,10 @@ if [ $? -eq 0 ]; then
printf "${green}Compiling Test Program...\n" printf "${green}Compiling Test Program...\n"
./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose ./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose
printf "\n${green}Running Application...\n\n${clear}" 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/disk1.dr ../extra/dragon/disk1.dr
cp dragon/cmos.dr ../extra/dragon/cmos.dr cp dragon/cmos.dr ../extra/dragon/cmos.dr
cp dss/bios_api.dss ../extra/dss/bios_api.dss
fi fi

View file

@ -19,7 +19,10 @@ if [ $? -eq 0 ]; then
printf "${green}Compiling Test Program...\n" printf "${green}Compiling Test Program...\n"
./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose ./dasm dss/activeTest.dss -o activeTest.bin --extmov --extalu --save-disassembly disassembly/activeTest.dds --verbose
printf "\n${green}Running Application...\n\n${clear}" 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/disk1.dr ../extra/dragon/disk1.dr
cp dragon/cmos.dr ../extra/dragon/cmos.dr cp dragon/cmos.dr ../extra/dragon/cmos.dr
cp dss/bios_api.dss ../extra/dss/bios_api.dss
fi fi

View file

@ -5,8 +5,8 @@ clear='\033[0m'
printf "\n${green}Reloading MBR Block...\n${clear}" printf "\n${green}Reloading MBR Block...\n${clear}"
cd .. cd ..
cp ../extra/dss/drake.dss ./dss/drake.dss cp ../extra/dss/drake/* ./dss/drake/
./dasm dss/drake.dss -o dragon/drake.bin --save-disassembly disassembly/drake.dds --verbose ./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 ./dtools load-binary dragon/disk1.dr dragon/drake.bin 0x00000000
printf "\n" printf "\n"
cp dragon/disk1.dr ../extra/dragon/disk1.dr cp dragon/disk1.dr ../extra/dragon/disk1.dr

View file

@ -626,18 +626,20 @@ namespace dragon
m_busy = true; m_busy = true;
} }
data::VDiskID Disk::connectDisk(VirtualHardDrive& hdd) bool Disk::connectDisk(VirtualHardDrive& hdd, data::VDiskID disk_id)
{ {
for (auto& disk : m_connectedDisks) for (auto& disk : m_connectedDisks)
{ {
if (disk.second->isSame(hdd)) if (disk.second->isSame(hdd))
{ {
data::ErrorHandler::pushError(data::ErrorCodes::HardDrive_DiskAlreadyConnected, "Attempt to connect already connected Disk to Controller"); 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; m_connectedDisks[disk_id] = &hdd;
return Disk::s_nextDiskID++; return true;
// m_connectedDisks[Disk::s_nextDiskID] = &hdd;
// return Disk::s_nextDiskID++;
} }
bool Disk::disconnectDisk(data::VDiskID diskID) bool Disk::disconnectDisk(data::VDiskID diskID)

View file

@ -328,7 +328,7 @@ namespace dragon
ostd::ByteStream* getByteStream(void) override; ostd::ByteStream* getByteStream(void) override;
void cycleStep(void); void cycleStep(void);
data::VDiskID connectDisk(VirtualHardDrive& hdd); bool connectDisk(VirtualHardDrive& hdd, data::VDiskID disk_id);
bool disconnectDisk(data::VDiskID diskID); bool disconnectDisk(data::VDiskID diskID);
inline bool isBusy(void) const { return m_busy; } inline bool isBusy(void) const { return m_busy; }
@ -340,7 +340,7 @@ namespace dragon
MemoryMapper& m_memory; MemoryMapper& m_memory;
VirtualCPU& m_cpu; VirtualCPU& m_cpu;
inline static data::VDiskID s_nextDiskID = 0; // inline static data::VDiskID s_nextDiskID = 0;
}; };
class Graphics : public IMemoryDevice class Graphics : public IMemoryDevice

View file

@ -165,7 +165,7 @@ namespace dragon
for (auto const& disk_path : machine_config.vdisk_paths) for (auto const& disk_path : machine_config.vdisk_paths)
{ {
vDisks[disk_path.first] = dragon::hw::VirtualHardDrive(disk_path.second); 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) if (verbose)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Disk").p(disk_path.first).p(" connected: ").p(disk_path.second.cpp_str()).nl(); 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::MemoryStart, data::MemoryMapAddresses::Memory_Start);
vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End); vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End);
vCMOS.write16(data::CMOSRegisters::ClockSpeed, machine_config.clock_rate_sec); 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) if (verbose)
out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl(); out.fg(ostd::ConsoleColors::BrightYellow).p(" Loading CMOS Machine info").nl();

View file

@ -216,6 +216,32 @@ namespace dragon
inline static constexpr uint8_t MemorySize = 0x02; inline static constexpr uint8_t MemorySize = 0x02;
inline static constexpr uint8_t ClockSpeed = 0x04; inline static constexpr uint8_t ClockSpeed = 0x04;
inline static constexpr uint8_t BootDisk = 0x10; 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 class CPUExtension

View file

@ -3,6 +3,8 @@
#include <ostd/Utils.hpp> #include <ostd/Utils.hpp>
#include <fstream> #include <fstream>
#include "../hardware/VirtualHardDrive.hpp" #include "../hardware/VirtualHardDrive.hpp"
#include "GlobalData.hpp"
#include <ostd/Serial.hpp>
namespace dragon namespace dragon
{ {
@ -37,6 +39,12 @@ namespace dragon
if (rValue != ErrorNoError) if (rValue != ErrorNoError)
return rValue; return rValue;
} }
else if (tool == "read-dpt")
{
rValue = tool_read_dpt(argc, argv);
if (rValue != ErrorNoError)
return rValue;
}
else if (tool == "--help") else if (tool == "--help")
{ {
print_application_help(); print_application_help();
@ -122,6 +130,121 @@ namespace dragon
return ErrorNoError; 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 <virtual_disk_file>").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<tPartitionData> 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 = "<NO-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) void Tools::print_application_help(void)
{ {
out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available tools:").nl().nl(); out.nl().fg(ostd::ConsoleColors::Yellow).p("List of available tools:").nl().nl();
@ -137,6 +260,10 @@ namespace dragon
out.p(" <destination_file> Path of the destination Virtual Disk file to be created.").nl(); out.p(" <destination_file> Path of the destination Virtual Disk file to be created.").nl();
out.p(" <size_in_bytes> Size of the new Virtual Disk file, in bytes .").nl().nl(); out.p(" <size_in_bytes> Size of the new Virtual Disk file, in bytes .").nl().nl();
out.fg(ostd::ConsoleColors::Blue).p("read-dpt <virtual_disk_file>").nl();
out.fg(ostd::ConsoleColors::Green).p("The <read-dpt> tool is used to read the partition table of a Virtual Disk File.").nl();
out.p(" <virtual_disk_file> Path to the Virtual Disk file.").nl().nl();
out.fg(ostd::ConsoleColors::Magenta).p("Usage: ./dtools <tool_name> [...arguments...]").nl().nl().reset(); out.fg(ostd::ConsoleColors::Magenta).p("Usage: ./dtools <tool_name> [...arguments...]").nl().nl().reset();
} }

View file

@ -14,6 +14,7 @@ namespace dragon
private: private:
static int32_t tool_new_virtual_disk(int argc, char** argv); 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_load_binary(int argc, char** argv);
static int32_t tool_read_dpt(int argc, char** argv);
static void print_application_help(void); static void print_application_help(void);
static int32_t get_tool(int argc, char** argv, ostd::String& outTool); 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 ErrorLoadProgNonIntAddr = 7;
inline static constexpr int32_t ErrorLoadProgUnableToLoadVDisk = 8; inline static constexpr int32_t ErrorLoadProgUnableToLoadVDisk = 8;
inline static constexpr int32_t ErrorLoadProgUnableToLoadDataFile = 9; 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;
}; };
} }