.asm
Assembly
(text/assembly)
bits 16

KERNEL_FLAT_ADDRESS: equ 0x00100000

; void load_kernel()
load_kernel:
	.setup:
		mov si, loadingKernelMessage
		call print_string

		maxSectorsPerRead: equ 32
		sectorsAlreadyRead: dw 0
		numberOfSectorsToReadNext: dw 0

	.calculate_number_of_sectors:
		mov ax, word [kernelNumberOfSectors]
		sub ax, word [sectorsAlreadyRead]
		cmp ax, maxSectorsPerRead
		jle .do_read
		mov ax, maxSectorsPerRead

	.do_read:
		mov [numberOfSectorsToReadNext], ax

		; Compute destination offset relative to 1MB using a real-mode segment we can actually encode.
		movzx eax, word [sectorsAlreadyRead]
		shl eax, 9
		mov bx, 0x1000
		add bx, ax
		mov ax, 0xf000
		mov es, ax

		mov cx, word [kernelStartSector]
		add cx, word [sectorsAlreadyRead]
		mov ax, word [numberOfSectorsToReadNext]
		call read_disk

		mov ax, word [sectorsAlreadyRead]
		add ax, word [numberOfSectorsToReadNext]
		mov word [sectorsAlreadyRead], ax

		cmp ax, word [kernelNumberOfSectors]
		jl .calculate_number_of_sectors

	.done:
		mov si, loadedKernelMessage
		call print_string
		ret

loadingKernelMessage: db "Info: Loading kernel...", CR, LF, 0
loadedKernelMessage: db "Info: Loaded kernel!", CR, LF, 0