; Today's code will first boot into 16 bit and then go to 32 bit.
; Since we need space larger than 512 bytes, we should write a code that is able to run program other than the bootup sector.
;
; Give credits to http://3zanders.co.uk/2017/10/16/writing-a-bootloader3/
; Comments partially added by Yu Wang
; -------------------------------------------------------------------

bits 16
org 0x7c00

boot:
	; enable A20 bit
	mov ax, 0x2401
	int 0x15      

	; set vga to be normal mode 
	mov ax, 0x3
	int 0x10

	mov [disk], dl  ; store disk id to [disk] from DL. When bootup, BIOS sets disk id to DL implicitly. 

	mov ah, 0x2     ; AH=0x02: read sectors. More can be found https://en.wikipedia.org/wiki/INT_13H
	mov al, 1       ; sectors to read
	mov ch, 0       ; cylinder idx
	mov dh, 0       ; head idx
	mov cl, 2       ; sector idx
	mov dl, [disk]  ; disk idx
	mov bx, copy_target ;target code pointer
	int 0x13        ; Call BIOS interrupt to operate disk 
	
	cli 					; Clear interrupt flag;
	lgdt [gdt_pointer] 		; Load Global/Interrupt Descriptor Table Register 
	mov eax, cr0 			; CR0 has various control flags that modify the basic operation of the processor
	or eax,0x1 				; EAX |= 0x01 set the protected mode bit on special CPU reg cr0
	mov cr0, eax			;
	mov ax, DATA_SEG
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	jmp CODE_SEG:boot2

gdt_start:
	dq 0x0
gdt_code:
	dw 0xFFFF
	dw 0x0
	db 0x0
	db 10011010b
	db 11001111b
	db 0x0
gdt_data:
	dw 0xFFFF
	dw 0x0
	db 0x0
	db 10010010b
	db 11001111b
	db 0x0
gdt_end:
gdt_pointer:
	dw gdt_end - gdt_start
	dd gdt_start

disk:
	db 0x0
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

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

; Compare to previous two days code, the following code are in the second 512-byte sector.
copy_target:
bits 32

hello: db "Hello more than 512 bytes world!!", 0
boot2:
	mov esi,hello
	mov ebx,0xb8000
.loop:
	lodsb
	or al,al
	jz halt
	or eax, 0x0F00       ; Setting font color to white (F)
	mov word [ebx], ax
	add ebx, 2
	jmp .loop
halt:
	cli
	hlt

times 1024 - ($-$$) db 0