Boot menu and loader by Dengg David.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24931 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2be56e7576
commit
20abf32b6d
376
src/apps/bootman/bootman.S
Normal file
376
src/apps/bootman/bootman.S
Normal file
@ -0,0 +1,376 @@
|
||||
;
|
||||
; Copyright 2007, Dengg David, david-d@gmx.at. All rights reserved.
|
||||
; Distributed under the terms of the MIT License.
|
||||
;
|
||||
%assign BIOS_VIDEO_SERVICES 0x10
|
||||
%assign BIOS_KEYBOARD_SERVICES 0x16
|
||||
%assign WRITE_CHAR 0x0e ; al - char
|
||||
; bh - page
|
||||
; bl - foreground color (graphics mode only)
|
||||
|
||||
[bits 16] ; Real Mode yeah
|
||||
start:
|
||||
; ======================= SCREEN SETUP =================================
|
||||
mov ax, 0x07C0 ; Segment Location 0x07C0
|
||||
mov ds, ax ; Set Data Segment to 0x07C0
|
||||
mov es, ax ; Set Extra Segment to 0x07C0
|
||||
mov ss, ax ; Set Stack Segment to 0x07C0
|
||||
mov sp, 0xFFFF
|
||||
|
||||
mov ah, 0x00 ; Set Screen Resolution to 640x480
|
||||
mov al, 0x12
|
||||
mov bx, 0x0
|
||||
mov cx, 0x1
|
||||
int 0x10
|
||||
|
||||
mov ah, 0x02 ; Set cursor position
|
||||
mov dx, 0x0120
|
||||
int 0x10
|
||||
|
||||
|
||||
mov si, signation ; Print "Haiku Bootmanager"
|
||||
call printstr
|
||||
|
||||
|
||||
mov ah, 0x02 ; Set cursor position
|
||||
mov dx, 0x1B1B
|
||||
int 0x10
|
||||
|
||||
mov si, select_os ; Print "Select Os..."
|
||||
call printstr
|
||||
|
||||
mov ah, 0
|
||||
int 0x16
|
||||
|
||||
; ======================= LOAD 3 MORE SECTORS INTO MEM =================
|
||||
load_from_disk: ; load 3 more sectors into mem
|
||||
mov ah, 0x42
|
||||
mov dl, 0x80
|
||||
mov si, DAP
|
||||
int 0x13
|
||||
mov si, error
|
||||
jc printstr
|
||||
jmp secsec ; Jump into the second sector
|
||||
|
||||
ende:
|
||||
mov ah, 0x0e
|
||||
mov al, 'F'
|
||||
mov bx, 0x2
|
||||
mov cx, 0x1
|
||||
int 0x10
|
||||
jmp $ ; Final Loopy. Never reached
|
||||
|
||||
%if 0
|
||||
printstr: ; Poor mans printf
|
||||
lodsb
|
||||
mov ah, 0x0E
|
||||
mov bx, 0x0F
|
||||
mov cx, 0x01
|
||||
int 0x10
|
||||
cmp al, 0x00
|
||||
jnz printstr
|
||||
ret
|
||||
%else
|
||||
printstr:
|
||||
; page and foreground color
|
||||
jmp .loop_condition
|
||||
.loop
|
||||
mov ah, WRITE_CHAR
|
||||
mov bx, 0x0F
|
||||
mov cx, 1
|
||||
int BIOS_VIDEO_SERVICES
|
||||
.loop_condition
|
||||
lodsb
|
||||
cmp al, 0
|
||||
jnz .loop
|
||||
ret
|
||||
%endif
|
||||
|
||||
DAP:
|
||||
db 0x10 ; Size of DAP
|
||||
db 0x00 ; unused (zero)
|
||||
db 0x03 ; number of sectors to read
|
||||
db 0x00 ; unused (zero)
|
||||
dw 0x0200 ; segment:offset pointer to buffer
|
||||
dw 0x07C0 ; segment:offset pointer to buffer
|
||||
dw 0x0001 ; LBA address
|
||||
dw 0x0000
|
||||
dw 0x0000
|
||||
dw 0x0000
|
||||
|
||||
WinDAP:
|
||||
db 0x0B ; Size of DAP
|
||||
db 0x00 ; unused (zero)
|
||||
db 0x01 ; number of sectors to read
|
||||
db 0x00 ; unused (zero)
|
||||
dw 0x0000 ; segment:offset pointer to buffer
|
||||
dw 0x07C0 ; segment:offset pointer to buffer
|
||||
dw 0x003F ; LBA address
|
||||
dw 0x0000
|
||||
|
||||
|
||||
signation:
|
||||
db 'Haiku Bootmanager', 0x00
|
||||
select_os:
|
||||
db 'Select an OS from the menu', 0x00
|
||||
|
||||
times 510 -($-$$) db 'B' ; Fill the missing space to reach 510 byte and set the
|
||||
dw 0xAA55 ; magic marker "AA55" (to identify a valid bootrecord)
|
||||
|
||||
; ======================================================================
|
||||
; ======================= SECOND SECTOR ================================
|
||||
; ======================================================================
|
||||
|
||||
secsec:
|
||||
; ======================= Center list ==================================
|
||||
xor bx,bx ; Get ready for the Division
|
||||
xor ax, ax ; Get ready for the Division
|
||||
mov al, [list_items]
|
||||
mov bl, 2 ; Divide by two
|
||||
div bl ; Divide
|
||||
|
||||
mov bl, 12
|
||||
sub bl, al ; Substract from 12 (screen is 80x25)
|
||||
mov dh, bl
|
||||
mov [first_position], dx
|
||||
|
||||
; ======================= Print the OS list ============================
|
||||
print_list:
|
||||
mov dx, [first_position]
|
||||
mov [position], dx
|
||||
|
||||
mov ah, 0x02 ; Set cursor position
|
||||
int 0x10
|
||||
mov si, list ; Load the List
|
||||
xor cx,cx ; Load listitems to CX
|
||||
mov byte [colour], 0x0000 ; Reset Colour
|
||||
print_list_loop:
|
||||
lodsb ; Get lenght of string from list into al
|
||||
; Get the Text to be in the middle (40 - lenght/2)
|
||||
xor bx,bx ; Get ready for the Division
|
||||
mov ah, 0x00
|
||||
mov bl, 2 ; Divide by two
|
||||
div bl ; Divide
|
||||
|
||||
mov bl, 40
|
||||
sub bl, al ; Substract from 40 (screen is 80x25)
|
||||
mov al, bl
|
||||
mov dx, [position] ; Get last position
|
||||
inc dh ; Next line
|
||||
mov dl, al ; Move it to the place where the row should be for the interrupt (DL)
|
||||
|
||||
mov ah, 0x02 ; Set cursor position
|
||||
mov [position], dx
|
||||
int 0x10
|
||||
|
||||
mov dx, [selection]
|
||||
mov byte bl, [colour] ; Load Colour
|
||||
and bx, 0x03 ; Just
|
||||
inc bl ; Colours ... 1-4
|
||||
cmp cx, [selection]
|
||||
jnz no_highlight
|
||||
xor bx, 0x08 ; Highlight selected item
|
||||
no_highlight:
|
||||
mov byte [colour], bl ; Store Colour
|
||||
call print_list_item
|
||||
inc cx
|
||||
cmp cx, [list_items]
|
||||
jne print_list_loop
|
||||
|
||||
; ================== Wait for a key and do something with it ==================
|
||||
|
||||
main_loopy:
|
||||
mov ah, 0x02 ; Set cursor position
|
||||
mov dx, 0x181C
|
||||
int 0x10
|
||||
|
||||
mov ah, 0x00 ; Keyboard Read: wait for key
|
||||
int 0x16 ; AL = ASCII Code, AH = Scancode
|
||||
cmp ah, 0x50
|
||||
jz key_down ; Was it key_down, key_up... ?
|
||||
cmp ah, 0x48
|
||||
jz key_up
|
||||
cmp ah, 0x1C
|
||||
jz key_enter
|
||||
|
||||
jmp main_loopy
|
||||
|
||||
key_down:
|
||||
mov ax, [selection]
|
||||
mov bx, [list_items]
|
||||
dec bx
|
||||
cmp ax, bx
|
||||
je key_down_no ; Are we at the bottom of the list?
|
||||
inc ax
|
||||
mov [selection], ax
|
||||
key_down_no:
|
||||
jmp print_list
|
||||
key_up:
|
||||
mov ax, [selection]
|
||||
mov bx, [list_items]
|
||||
cmp ax, 0
|
||||
je key_down_no ; Are we at the top of the list?
|
||||
dec ax
|
||||
mov [selection], ax
|
||||
key_up_no:
|
||||
jmp print_list
|
||||
|
||||
|
||||
; ========================== Chainload ==========================
|
||||
|
||||
key_enter:
|
||||
mov cx, [selection]
|
||||
mov si, list
|
||||
inc cx
|
||||
load_LBA:
|
||||
lodsb
|
||||
cmp al, 0x80
|
||||
jne load_LBA
|
||||
loop load_LBA
|
||||
|
||||
lodsw
|
||||
mov [LBA_selectionA], ax
|
||||
lodsw
|
||||
mov [LBA_selectionB], ax
|
||||
|
||||
mov si, ChainLoad_DAP ; Load the List
|
||||
mov ax, [LBA_selectionA]
|
||||
mov word [si+8], ax
|
||||
mov ax, [LBA_selectionB]
|
||||
mov word [si+10], ax
|
||||
|
||||
mov ah, 0x42
|
||||
mov dl, 0x80
|
||||
mov si, ChainLoad_DAP
|
||||
int 0x13
|
||||
mov si, error_lfd
|
||||
jc print_debug
|
||||
|
||||
mov si, 0x0
|
||||
xor ax, ax
|
||||
mov si, error_nb
|
||||
mov byte al, [0x01FE]
|
||||
cmp al, 0x55
|
||||
jne print_debug
|
||||
|
||||
mov byte al, [0x01FF]
|
||||
cmp al, 0xAA
|
||||
jne print_debug
|
||||
|
||||
mov si, yeah ; Yeah
|
||||
jmp print_debug
|
||||
|
||||
|
||||
|
||||
|
||||
fin:
|
||||
mov ah, 0x0e
|
||||
mov al, 'F'
|
||||
mov bx, 0x2
|
||||
mov cx, 0x1
|
||||
int 0x10
|
||||
jmp $
|
||||
|
||||
|
||||
; ====================== THE print_list function ================
|
||||
|
||||
print_list_item:
|
||||
print_list_item_loop:
|
||||
lodsb
|
||||
cmp al,0x80
|
||||
jz print_list_item_end
|
||||
mov ah, 0x0E
|
||||
int 0x10
|
||||
jmp print_list_item_loop
|
||||
print_list_item_end:
|
||||
lodsw
|
||||
lodsw
|
||||
ret
|
||||
|
||||
print_debug: ; Poor mans printf again
|
||||
lodsb
|
||||
mov ah, 0x0E
|
||||
mov bx, 0x0F
|
||||
mov cx, 0x01
|
||||
int 0x10
|
||||
cmp al, 0x00
|
||||
jnz print_debug
|
||||
jmp $
|
||||
|
||||
; ================================ DATA ===========================
|
||||
|
||||
error_lfd:
|
||||
db 'Error loading Sectors', 0x00
|
||||
error_nb:
|
||||
db 'Not a bootable partition', 0x00
|
||||
LBA_selectionA:
|
||||
dw 0x0000
|
||||
LBA_selectionB:
|
||||
dw 0x0000
|
||||
selection:
|
||||
dw 0x0000
|
||||
position:
|
||||
dw 0x091D
|
||||
lenght:
|
||||
dw 0x0000
|
||||
colour:
|
||||
dw 0x0000
|
||||
first_position:
|
||||
dw 0x091F
|
||||
nobots:
|
||||
db 'Boot sector signature not found', 0x00
|
||||
error:
|
||||
db 'Error loading sectors', 0x00
|
||||
yeah:
|
||||
db 'Boot!', 0x00
|
||||
|
||||
|
||||
|
||||
list_items:
|
||||
dw 0x06
|
||||
list:
|
||||
db 0x05
|
||||
db 'HAIKU' , 0x80
|
||||
dw 0x003E
|
||||
dw 0x0000
|
||||
|
||||
db 0x07
|
||||
db 'FreeBSD' , 0x80
|
||||
dw 0x003F
|
||||
dw 0x0000
|
||||
|
||||
db 0x03
|
||||
db 'DOS' , 0x80
|
||||
dw 0x003E
|
||||
dw 0x0000
|
||||
|
||||
db 0x05
|
||||
db 'LINUX' , 0x80
|
||||
dw 0x003F
|
||||
dw 0x0000
|
||||
|
||||
db 0x07
|
||||
db 'BeOS R5' , 0x80
|
||||
dw 0x003F
|
||||
dw 0x0000
|
||||
|
||||
db 0x07
|
||||
db 'OpenBSD' , 0x80
|
||||
dw 0xAAAA
|
||||
dw 0x0000
|
||||
|
||||
ChainLoad_DAP:
|
||||
db 0x10 ; Size of DAP
|
||||
db 0x00 ; unused (zero)
|
||||
db 0x01 ; number of sectors to read
|
||||
db 0x00 ; unused (zero)
|
||||
dw 0x0000 ; segment:offset pointer to buffer
|
||||
dw 0x07C0 ; segment:offset pointer to buffer
|
||||
dw 0x003F ; LBA address
|
||||
dw 0x0000
|
||||
dw 0x0000
|
||||
dw 0x0000
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user