DragonVM/extra/dss/drake/bootsector.dss

280 lines
No EOL
7.7 KiB
Text

.load 0x1740
.entry _drake_bootsector_entry_point
.fixed 5120, 0xFF
@include <../sdk/bios_api.dss>
@include <../sdk/palette.dss>
@define OS_LOAD_ADDR 0x2C00
## =========================================================================================================================
.data
## Disk data structures
$ddd <DiskDriverData>
$dpt_block <DPTBlock>
$bootstrap_block:32
$bootstrap_addr:4
$textCell <Text16VModeCell>
$counter 0x00
$current_char 65
$dpt_version_str "DPT Version "
$drake_version_str "Drake 0.2 -- "
$invalid_dpt_block_str "Error: Invalid DPT Block..."
$no_part_found_str "Error: No bootable partitions found..."
## =========================================================================================================================
.code
## =========================================================================================================================
_drake_bootsector_entry_point:
## Load DPT block from disk 0
push $ddd ## Empty DiskDriverData used to load from disk
push $dpt_block ## Empty DPT Block to store the partition table
push 2
call $_load_dpt_block
## Enable Text16 Video Mode
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_16_COLORS
## Validate DPT Block
mov ACC, [$dpt_block]
jne $_invalid_dpt_block, 0xF1CA
jmp $_endless_loop
_invalid_dpt_block: ## TODO: Fix screen drawing on error
push $invalid_dpt_block_str
push 1
call $_print_error_msg
jmp $_main_end
_endless_loop:
## Clear screen
push DefaultPalette.Black
push 1
call $_clear_screen
## Print system info
push 0
call $_print_system_info
mov R10, $dpt_block.PartCount
movb ACC, *R10
jge $_no_partitions_found, 1
mov R10, $dpt_block.PartCount
movb R10, *R10
push $dpt_block.Entries
push R10
push $bootstrap_addr
push 3
call $_test_partitions
mov ACC, RV
jeq $_no_partitions_found, 0xFF
mov R1, $ddd
mov R4, $bootstrap_addr
mov R3, R1 ## Copy $ddd address into R3
movb *R1, DiskMode.READ ## $ddd.Mode
inc R1
movb *R1, 0x00 ## $ddd.Disk
inc R1
mov *R1, *R4 ## $ddd.Sector
addip R1, 2
addip R4, 2
mov *R1, *R4 ## $ddd.Address
addip R1, 2
mov *R1, 1024 ## $ddd.DataSize
addip R1, 2
mov *R1, OS_LOAD_ADDR ## $ddd.MemoryAddress
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
int 0x20 ## Bios interrupt
jmp OS_LOAD_ADDR
jmp $_main_end
_no_partitions_found:
push $no_part_found_str
push 1
call $_print_error_msg
jmp $_main_end
## jmp $_endless_loop
_main_end:
hlt
## =========================================================================================================================
## =========================================================================================================================
_test_partitions: ## _test_partitions(DPTBlock* dpt_entries_block, (1 Byte) dpt_entries_count, (4 Bytes*) part_addr)
arg R1 ## dpt_entries_block
arg R2 ## dpt_entries_count
arg R4 ## part_addr
mov R3, 0 ## Entry counter
_test_partitions_loop:
push $ddd
push $bootstrap_block
push R3
push 3
call $_load_bootstrap_block
mov ACC, $bootstrap_block
mov ACC, *ACC
jeq $_test_partitions_found, DPTBootPartStructure.ID_CODE
inc R3
mov ACC, R3
jle $_test_partitions_not_found, R2
jmp $_test_partitions_loop
_test_partitions_found:
mov R10, R3
mulip R10, DPTStructure.ENTRY_SIZE_B
addip R10, R1
mov *R4, *R10
addip R4, 2
addip R10, 2
mov *R4, *R10
mov R9, *R4
addip R9, DPTBootPartStructure.HEADER_SIZE_B ## TODO: This doesn't take into account integer overflow, since it is a 32-Bit address
mov *R4, R9
mov RV, R3
ret
_test_partitions_not_found:
mov *R4, 0xFFFF
addip R4, 2
mov *R4, 0xFFFF
mov RV, 0xFF
ret
## =========================================================================================================================
## =========================================================================================================================
_load_bootstrap_block: ## _load_bootstrap_block(DiskDriverData* ddd, (32 Byte*) bootstrap_block, (1 Byte) dpt_entry)
arg R1 ## @Param: ddd
arg R2 ## @Param: bootstrap_block
arg R7 ## @Param: dpt_entry
mov R3, R1 ## Copy $ddd address into R3
movb *R1, DiskMode.READ ## $ddd.Mode
inc R1
movb *R1, 0x00 ## $ddd.Disk
inc R1
mov R10, $dpt_block.Entries
mulip R7, DPTStructure.ENTRY_SIZE_B
addip R10, R7
mov *R1, *R10 ## $ddd.Sector
addip R1, 2
addip R10, 2
mov *R1, *R10 ## $ddd.Address
addip R1, 2
mov *R1, DPTBootPartStructure.HEADER_SIZE_B ## $ddd.DataSize
addip R1, 2
mov *R1, R2 ## $ddd.MemoryAddress
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
int 0x20 ## Bios interrupt
ret
## =========================================================================================================================
## =========================================================================================================================
_load_dpt_block: ## _load_dpt_block(DiskDriverData* ddd, DPTBlock* dpt_block)
arg R1 ## @Param: ddd
arg R2 ## @Param: dpt_block
mov R3, R1 ## Copy $ddd address into R3
movb *R1, DiskMode.READ ## $ddd.Mode
inc R1
movb *R1, 0x00 ## $ddd.Disk
inc R1
mov *R1, 0x0000 ## $ddd.Sector
addip R1, 2
mov *R1, 0x0200 ## $ddd.Address
addip R1, 2
mov *R1, 512 ## $ddd.DataSize
addip R1, 2
mov *R1, R2 ## $ddd.MemoryAddress
mov R9, R3 ## Move original $ddd address into R9 (for int 0x20)
mov R10, 0x12 ## int 0x20 parameter for load_from_ddd_blocking
int 0x20 ## Bios interrupt
ret
## =========================================================================================================================
## =========================================================================================================================
_print_error_msg: ## _print_error_msg(string* error_msg)
arg R1 ## @Param: error_msg
## TODO: Clear the screen
movb [$textCell.CoordX], 0
movb [$textCell.CoordY], 1
movb [$textCell.Foreground], DefaultPalette.Red
movb [$textCell.Background], DefaultPalette.Black
mov R10, 0x22
mov R8, R1
mov R9, $textCell
int 0x30
ret
## =========================================================================================================================
## =========================================================================================================================
_print_system_info:
movb [$textCell.CoordX], 0
movb [$textCell.CoordY], 0
movb [$textCell.Foreground], DefaultPalette.Green
movb [$textCell.Background], DefaultPalette.Black
mov R10, 0x22
mov R8, $drake_version_str
mov R9, $textCell
int 0x30
movb [$textCell.CoordX], 13
mov R10, 0x22
mov R8, $dpt_version_str
mov R9, $textCell
int 0x30
movb [$textCell.CoordX], 26
mov R10, 0x23
movb R8, [{ $dpt_block + 2 }]
mov R9, $textCell
int 0x30
movb [$textCell.CoordX], 27
movb [$textCell.Character], 0x2E
mov R10, 0x21
mov R9, $textCell
int 0x30
movb [$textCell.CoordX], 28
mov R10, 0x23
movb R8, [{ $dpt_block + 3 }]
mov R9, $textCell
int 0x30
ret
## =========================================================================================================================
## =========================================================================================================================
_clear_screen: ## _clear_screen(int8_t color)
arg R1
movb [$textCell.Foreground], R1
movb [$textCell.Background], R1
movb [$textCell.Character], 0x20
mov R10, 0x24
mov R9, $textCell
int 0x30
ret
## =========================================================================================================================