.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 $dpt_block $bootstrap_block:32 $bootstrap_addr:4 $textCell $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 ## =========================================================================================================================