You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
5.9 KiB
237 lines
5.9 KiB
ORG 0x600 |
|
BITS 16 |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
; SLRboot |
|
; Bootloader for SingOS |
|
; version 0.3.0.0 |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
cli |
|
;jmp long 0x0000:start |
|
mov ax, 0x1000 |
|
mov ss, ax |
|
mov sp, 0xb000 |
|
push dx |
|
|
|
mov ax, 0x0 |
|
mov ds, ax ; ds is used by si |
|
mov es, ax ; es is used by di |
|
sti |
|
mov si, 0x7c00 |
|
mov di, 0x600 |
|
mov cx, 0x100 |
|
rep movsw |
|
jmp 0x0000:relocated |
|
|
|
relocated: |
|
mov ax, 0x0 |
|
mov ds, ax |
|
mov es, ax |
|
pop dx |
|
mov [disk_identifier], dl |
|
mov si, message ; Put address of the null-terminated string to output into 'si' |
|
call print ; Call our string-printing routine |
|
|
|
; Check for more than one active partition that we can start from. |
|
xor bx, bx |
|
xor cx, cx |
|
mov ax, [partition_1.active_partition] |
|
cmp al, 0x80 |
|
jne check_p_2 |
|
mov bx, 0x01 ; Partion 1 active |
|
inc cx |
|
|
|
check_p_2: |
|
mov ax, [partition_2.active_partition] |
|
cmp al, 0x80 |
|
jne check_p_3 |
|
inc cx |
|
mov bx, 0x02 ; Partion 2 active |
|
|
|
check_p_3: |
|
mov ax, [partition_3.active_partition] |
|
cmp al, 0x80 |
|
jne check_p_4 |
|
inc cx |
|
mov bx, 0x03 ; Partion 3 active |
|
|
|
check_p_4: |
|
mov al, [partition_4.active_partition] |
|
cmp ax, 0x80 |
|
jne eval_active_partion_number |
|
inc cx |
|
mov bx, 0x04 ; Partion 4 active |
|
cli |
|
hlt |
|
eval_active_partion_number: |
|
cmp cx, 1 |
|
|
|
je boot_partition |
|
; here goes wait call, for the user to enter debug mode. |
|
; Wating for 2 seconds: |
|
mov ah, 0x86 ; code for waiting interupt call |
|
mov cx, 0x001e ; high count of microseconds |
|
mov dx, 0x8480 ; low count |
|
int 0x15 |
|
.busy_wait_for_key: |
|
xor ax, ax |
|
mov ah, 0x01 ; BIOS call to wait for key |
|
int 0x16 |
|
|
|
boot_partition: |
|
; IMPORTANT bx, has to hold the value 1-4 for the partiotion that wanted to be booted. |
|
|
|
mov bx, 1 |
|
mov ax, partition_1 |
|
.loop: |
|
cmp bx, 1 |
|
je break |
|
add ax, 0x10 |
|
dec bx |
|
jmp .loop |
|
break: |
|
|
|
add ax, 8 ; This is the offset to fetch the LBA start adress of the partition record |
|
mov bx, ax |
|
xor ax, ax |
|
mov ax, [bx] ; first part of LBA |
|
mov WORD [DAPACK.lba_addr_dw_low], ax |
|
;call dumpax |
|
add bx, 2 ; next part |
|
mov ax, [bx] |
|
mov WORD [DAPACK.lba_addr_dw_low + 2], ax |
|
;call dumpax |
|
|
|
;mov WORD [DAPACK.lba_addr_dw_low], 2048 |
|
|
|
mov WORD [DAPACK.blkcnt], 0x01 |
|
mov WORD [DAPACK.db_addr_offset], 0x7c00 |
|
mov WORD [DAPACK.db_addr_segment], 0x0000 |
|
mov si, DAPACK ; address of "disk address packet" |
|
xor ax, ax |
|
mov ah, 0x42 ; READ |
|
mov dl, [disk_identifier] |
|
int 0x13 |
|
jc endcarrycheck ; An error ocurred when reading from disk. |
|
|
|
; If no error then jump to volume boot record |
|
notcarry: |
|
mov dl, [disk_identifier] |
|
jmp long 0x0:0x7c00 |
|
|
|
cli |
|
hlt |
|
|
|
; If we did not suceed to read from disk |
|
endcarrycheck: |
|
mov si, error_str |
|
call print |
|
cli ; Clear the Interrupt Flag (disable external interrupts) |
|
hlt ; Halt the CPU (until the next external interrupt) |
|
|
|
debug_mode: |
|
mov si, welcome_debug |
|
call print |
|
cli ; Clear the Interrupt Flag (disable external interrupts) |
|
hlt |
|
|
|
;Routine for printing a 'ax' as hex |
|
dumpax: |
|
pusha ; save registers |
|
mov bx, ax |
|
mov ah, 0xE ; Teletype output |
|
|
|
mov cx, 4 ; 4 nipples in a 16 bit word |
|
.loop: |
|
rol bx, 4 ; rotate to next nipple |
|
mov al, bl ; we copy to al because we need to mask only the low 4 bits |
|
and al, 1111b ; Do the masking |
|
add al, '0' ; convert to ASCII |
|
cmp al, '9' ; If we are greater than 9 ascii, we add 7 to make digit 10 be represented as 'A' |
|
jbe .skip ; -|- |
|
add al, 7 ; -|- |
|
.skip: ; -|- |
|
int 0x10 ; BIOS call 'output' |
|
loop .loop |
|
|
|
popa ; restore registers |
|
ret |
|
|
|
printCRLF: |
|
mov ah, 0xE |
|
mov al, 13 |
|
int 0x10 |
|
mov al, 10 |
|
int 0x10 |
|
ret |
|
|
|
; Routine for outputting string in 'si' register to screen |
|
print: |
|
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function |
|
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)] |
|
.printchar: |
|
lodsb ; Load byte at address SI into AL, and increment SI |
|
cmp al, 0 |
|
je .done ; If the character is zero (NUL), stop writing the string |
|
int 0x10 ; Otherwise, print the character via 'int 0x10' |
|
jmp .printchar ; Repeat for the next character |
|
.done: |
|
ret |
|
|
|
data: |
|
message db 'SLRboot for SingOS! v0.3.0.0',13,10,0 |
|
enter_debug_mode db 'Press d to enter bootloader debug mode',13,10,0 |
|
welcome_debug db 'Debug mode v.0.0.1:',13,10,0 |
|
error_str db 'Error', 0 |
|
boot_this_partition: dw 0 |
|
disk_identifier db 0 |
|
|
|
DAPACK: |
|
.dap_Size: db 0x10 ; This is always 16 bytes (0x10) |
|
.rev_byte: db 0x0 ; reserved byte, should always be zero |
|
.blkcnt: dw 0x0 ; int 13 resets this to # of blocks actually read/written |
|
.db_addr_offset: dw 0x0 ; memory buffer destination address (0:7c00) |
|
.db_addr_segment: dw 0x0 ; in memory page zero |
|
.lba_addr_dw_low: dd 0x0 ; put the lba to read in this spot |
|
.lba_addr_dw_high: dd 0x0 ; more storage bytes only for big lba's ( > 4 bytes ) |
|
|
|
|
|
; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature |
|
times 446-($-$$) db 0 ; First partion entry |
|
partition_1: |
|
.active_partition db 0x80 |
|
.start_CHS db 0x00, 0x00, 0x11;0x20, 0x21, 0x00 |
|
.disk_type db 0x83 |
|
.end_CHS db 0x8C, 0x3D, 0x0F |
|
.start_LBA db 0x10, 0x00, 0x00, 0x00 |
|
.size db 0x00, 0xC8, 0x03, 0x00 |
|
|
|
; sector number for 2.nd SingOS -> 16480 |
|
partition_2: |
|
.active_partition db 0x80 |
|
.start_CHS db 0x8C, 0x3E, 0x0F |
|
.disk_type db 0x83 |
|
.end_CHS db 0xFF, 0xFF, 0xFF |
|
.start_LBA db 0x61, 0x40, 0x00, 0x00 ;0x00, 0xD0, 0x03, 0x00 |
|
.size db 0x00, 0x28, 0x1C, 0x03 |
|
|
|
partition_3: |
|
.active_partition db 0x00 |
|
.start_CHS db 0x00, 0x00, 0x00 |
|
.disk_type db 0x00 |
|
.end_CHS db 0x00, 0x00, 0x00 |
|
.start_LBA db 0x00, 0x00, 0x00, 0x00 |
|
.size db 0x00, 0x00, 0x00, 0x00 |
|
|
|
partition_4: |
|
.active_partition db 0x00 |
|
.start_CHS db 0x00, 0x00, 0x00 |
|
.disk_type db 0x00 |
|
.end_CHS db 0x00, 0x00, 0x00 |
|
.start_LBA db 0x00, 0x00, 0x00, 0x00 |
|
.size db 0x00, 0x00, 0x00, 0x00 |
|
|
|
times 510-($-$$) db 0 |
|
dw 0xAA55 ; => 0x55 0xAA (little endian byte order) |
|
; bootloder debug_mode goes here |
|
|
|
times 8192-($-$$) db 0
|
|
|