Code: Select all
; Values for a Standart 3.5 Floppy
; RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec ? 1)) / BPB_BytsPerSec = 14 (round down)
; FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FatSz16) + RootDirSectors = 33
; DataSec = BPB_TotSec16 ? (BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FatSz16) + RootDirSectors)
; CountofClusters = DataSec / BPB_SecPerClus
; FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16) = 19
load_kernel:
clc ; clear the carry flag
mov ecx, 5 ; try to reset the drive 5 times
reset_drive:
xor ax, ax ; ax = 0
mov dl, [bootdrive] ; dl = bootdrive
int 0x13 ; reset drive
jnc reset_ok ; if carry flag = 0
loop reset_drive ; else try it again if ecx != 0
jmp error ; if ecx = 0 and the reset always failed, halt
reset_ok:
mov ecx, 14 ; RootDirSectors
xor ch,ch ; number of track/cylinder
mov cl, 19 ; number of sector
next_sector:
push ecx
call read_sector ; read one sector to
call check_file ; check if the kernel is there
je found_kernel ; if return
add cl, byte 1
pop ecx
loop next_sector ; else try next sector
jmp error
found_kernel:
pop ecx
ret
read_sector
mov ecx, 5 ; try to read the sector 5 times
read_sector_next_try:
mov ax, sector_buf
mov es, ax ; address of the buffer
mov bx, 0x0000 ; offset of the buffer
mov ah, 0x02 ; function number 2 (read from disk)
mov al, 0x01 ; number of sectors to read
mov dl, [bootdrive] ; set drive
mov dh, 0x00 ; read/write head number
int 0x13
jnc load_ok ; if all is ok return
loop read_sector_next_try; try once again if there is an error
jmp error ; if ecx = 0 and the read operation always failed, halt
load_ok:
ret
check_file:
; push ecx
mov ecx, 16 ; 16 entrys per sec
mov si, sector_buf
mov di, KERNEL_NAME
check_next_file:
; clc
push di
push si
push ecx
mov cx,11 ; 8.3 FAT filename
rep cmpsb
pop ecx
pop si
pop di
je found_it ; the cpu jumps the first try, also if di and si are different :-(
add si,32 ; bytes/dirent
loop check_next_file
found_it:
; pop ecx
ret
error:
mov si, msg_failed
call putstr
cli
hlt
jmp $-2