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

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