nightloader/stage_1/utility.asm

101 lines
2.2 KiB
NASM

section .text
; ax: start_sector (lower)
; bl: start_sector (upper)
; cx: sector_count
; dh: drive
; es: buffer_address (upper)
; di: buffer_address (lower)
load_sectors:
.prolog:
push ax
push bx
push cx
push dx
xor si, si ; current sector index
; sets the arguments for the first run of '.load_data'
; which loads until the first CHS - cylinder boundary
.set_first_load_args:
; the first read only reads up to the next cylinder boundary,
; but potentially less (if not that many sectors have been requested)
; TODO================================================================================
mov bx, sp
add bx, 4
mov cx, [bx] ; get sector count
sub cx, si ; cx = num_missing_sectors
mov bx, sp
mov bx, [bx]
cmp cx, bx
js .load_data ; if there are more sectors needed after the
; next cylinder boundary
; if not that many sectors are needed, just read as
; many sectors as are needed in total
mov cx, bx
jmp .load_data
; sets the arguments for a run of '.load_data' after the
; first one; aligned on a CHS - cylinder boundary
.set_load_args:
mov bx, sp
add bx, 4
mov cx, [bx]
sub cx, si ; cx = num_missing_sectors
cmp cx, 64
js .load_data
; if this goes here, there are more than 64 sectors missing
; -> clamp them to 64 so they can be loaded.
mov cl, 64
jmp .load_data ; redundant
; loads at most 64 sectors from the disk into the main memory
; ax: scratchpad
; bx: start_sector (low part)
; ch: start_sector (high part)
; cl: num_sectors
.load_data:
mov bx, sp
mov ah, 0x02
mov al, cl
mov dl, [bx] ; drive
mov dh, bh ; head
mov cl, ch ; sector
mov ch, bl ; cylinder
mov bx, di ; buffer address (lower)
int 0x13
.continue_if_needed:
; check if there still are sectors missing to load
mov bx, sp
add bx, 4
mov cx, [bx] ; sector_count
cmp si, cx
js .set_load_args
.epilog:
pop dx
pop cx
pop bx
pop ax
ret