427 lines
No EOL
12 KiB
Text
427 lines
No EOL
12 KiB
Text
.load 0x1740
|
|
.entry _drake_bootsector_entry_point
|
|
.fixed 5120, 0xFF
|
|
|
|
@include <../bios_api.dss>
|
|
@include <palette.dss>
|
|
@include <keyboard_driver.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
|
|
|
|
## Init Keyboard driver
|
|
## push $_key_pressed ## KeyPressed handler address passed to the _init_keyboard subroutine
|
|
## push 1
|
|
## call $_init_keyboard
|
|
|
|
## Enable Double buffering
|
|
## mov R2, [VGA_Registers.FLAGS]
|
|
## or R2, 0b0000000000000001
|
|
## mov [VGA_Registers.FLAGS], ACC
|
|
|
|
## @call(_clear_screen, DefaultPalette.DarkBlue)
|
|
## @_clear_screen(DefaultPalette.DarkBlue)
|
|
|
|
## mov R10, 0x22
|
|
## mov R8, { $dpt_block + DPTStructure.ENTRIES_START + (2 * DPTStructure.ENTRY_SIZE_B) + DPTStructure.ENTRY_PART_LBL }
|
|
## mov R9, $textCell
|
|
## int 0x30
|
|
|
|
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
|
|
|
|
## Draw main box
|
|
## push 0
|
|
## call $_print_main_box
|
|
|
|
## Swap the buffers
|
|
## push 0
|
|
## call $_swap_buffers
|
|
|
|
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
|
|
|
|
debug_break
|
|
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
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
_redraw_screen:
|
|
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.FORCE_REDRAW_SCREEN
|
|
ret
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
## _swap_buffers:
|
|
## movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.SWAP_BUFFERS
|
|
## ret
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
## _key_pressed:
|
|
## mov ACC, [Keyboard_Registers.KEYCODE]
|
|
## jne $_key_pressed_end, 0x0127
|
|
## _key_pressed_end:
|
|
## ret
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
## _print_main_box:
|
|
## movb [$textCell.CoordX], 5
|
|
## movb [$textCell.CoordY], 2
|
|
## movb [$textCell.Foreground], DefaultPalette.Sky
|
|
## movb [$textCell.Background], DefaultPalette.DarkBlue
|
|
## movb [$textCell.Character], 0x3D
|
|
##
|
|
## mov R8, [CMOS_Settings.SCREEN_WIDTH]
|
|
## subip R8, 10
|
|
##
|
|
## push $textCell
|
|
## push R8
|
|
## push 2
|
|
## call $_draw_horizontal_line
|
|
##
|
|
## movb [$textCell.CoordX], 5
|
|
## movb [$textCell.CoordY], 12
|
|
## push $textCell
|
|
## push R8
|
|
## push 2
|
|
## call $_draw_horizontal_line
|
|
##
|
|
## movb [$textCell.CoordX], 4
|
|
## movb [$textCell.CoordY], 2
|
|
## movb [$textCell.Character], 0x7C
|
|
## push $textCell
|
|
## push 11
|
|
## push 2
|
|
## call $_draw_vertical_line
|
|
##
|
|
## addip R8, 5
|
|
## movb [$textCell.CoordX], R8
|
|
## movb [$textCell.CoordY], 2
|
|
## push $textCell
|
|
## push 11
|
|
## push 2
|
|
## call $_draw_vertical_line
|
|
## ret
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
## _draw_horizontal_line: ## _draw_horizontal_line(TextCell16* cell, int8_t length)
|
|
## arg R1 ## @Param: cell
|
|
## arg R2 ## @Param: length
|
|
## mov R3, R1
|
|
## addip R3, 3
|
|
## movb R4, *R3
|
|
##
|
|
## mov R10, 0x21
|
|
## mov R9, R1
|
|
## _draw_horizontal_line_loop:
|
|
## int 0x30
|
|
## movb R5, *R3
|
|
## inc R5
|
|
## movb *R3, R5
|
|
## sub R5, R4
|
|
## jgr $_draw_horizontal_line_loop, R2
|
|
## ret
|
|
## =========================================================================================================================
|
|
|
|
|
|
|
|
|
|
## =========================================================================================================================
|
|
## _draw_vertical_line: ## _draw_line(TextCell16* cell, int8_t length)
|
|
## arg R1 ## @Param: cell
|
|
## arg R2 ## @Param: length
|
|
## mov R3, R1
|
|
## addip R3, 4
|
|
## movb R4, *R3
|
|
##
|
|
## mov R10, 0x21
|
|
## mov R9, R1
|
|
## _draw_vertical_line_loop:
|
|
## int 0x30
|
|
## movb R5, *R3
|
|
## inc R5
|
|
## movb *R3, R5
|
|
## sub R5, R4
|
|
## jgr $_draw_vertical_line_loop, R2
|
|
## ret
|
|
## ========================================================================================================================= |