[bits 16]
[extern _kernel_size]
[extern _bootloader_stage1_size]
[extern _kernel_loc]

;TODO clean up unreal mode
jmp stage0 
times 3-($-$$) db 0x90 ; a temporary dirty fix to emulate a floppy disk insted of a hard risk 
times 59 db 0          ; (TODO support hard disks) 

stage0:

jmp 0:.entry
.entry:

mov ax, 0
mov ds, ax
mov bp, ax 

mov ds, ax
mov es, ax

mov ax, 0x8fc0
mov ss, ax
mov ax, 0xfffe 
mov sp, ax

mov al, 0x92
or al, 2
out 0x92, al

mov [.boot_device], dl

mov bx, .loadstage2_msg
mov cx, 0 
call bios_print

; TODO put in an error message and a maximum fail count
.load_stage1:
mov al, _bootloader_stage1_size
mov cl, 0x2       ; read sector 2 
mov dx, 0x0       ; dest segment 0
mov bx, 0x7e00    ; dest offst 0 
call bios_disk.load_sectors 


jmp mbr_end.entry

.boot_device: db 0

.loadstage2_msg: db "Loading (stage 2) bootloader...", 0

%include "bootloader/bios_functions/bios_disk.asm"
%include "bootloader/bios_functions/print.asm"

times 510 - ($-$$) db 0  
dw 0xaa55

%include "bootloader/gdt.asm"

boot_msg:
.debugmsg: db "debugeroni", 0
.kernel_loaded: db `Kernel loaded!\r\nBooting to protected, then long mode...`, 0
.stage2_loaded: db `Done loading bootloader!\r\nLoading kernel...`, 0




mbr_end:
.entry:
; entering unreal mode
mov bx, boot_msg.stage2_loaded
mov cx, 0
call bios_print


cli
push ds

lgdt [protected_gdt.descriptor]

mov eax, cr0
or al, 1
mov cr0, eax

jmp $+2

mov bx, 0x10 ; descriptor 2, the data descriptor
mov ds, bx   ; put it into the segment register
mov es, bx   ; 

and al, 0xfe
mov cr0, eax

pop ds
sti
;we are now in unreal mode

mov cl, 5   ; starting sector TODO automate this
mov edi, _kernel_loc
.loop:
mov al, 0x1   ; sector count
mov dx, 0x0   ; dest addr segment
mov bx, 0x500 ; dest addr offset
call bios_disk.load_sectors


inc cl

push cx

mov esi, 0x500
mov ecx, 512
a32 rep movsb
nop

mov bx, boot_msg.debugmsg
mov cx, 0
call bios_print

pop cx

cmp cl, _kernel_size
je .loop_end

jmp .loop

.loop_end:

mov bx, boot_msg.kernel_loaded
mov cx, 0
call bios_print


call detect_arch
call vbe_init
done:

call enter_longmode
jmp $

%include "bootloader/cpu_check.asm"
%include "bootloader/video.asm"
%include "bootloader/enter_kernel.asm"
times 2048 - ($ - $$) db 0
