176 lines
4.0 KiB
NASM
176 lines
4.0 KiB
NASM
; Reset the disk system using int 13h / AH = 00h
|
|
disk_reset:
|
|
pusha
|
|
stc
|
|
mov ah, 00h
|
|
int 13h
|
|
popa
|
|
ret
|
|
|
|
; ------------------------------------
|
|
|
|
; Load the root directory into memory (into disk_buffer which is 24000h)
|
|
disk_load_root:
|
|
pusha
|
|
mov ax, 19 ; First sector of root entry
|
|
call math_lba_to_chs ; Assigns ch, cl and dh the correct values
|
|
xor ax,ax
|
|
mov dl, [ebr_drive_number] ; Drive number
|
|
mov ah, 02h ; BIOS ah code for read disk sectors to memory
|
|
mov al, 0Ch ; Root directory has 12 sectors
|
|
|
|
mov si, root_buffer ; ES:BX should point to our buffer
|
|
mov bx, si
|
|
|
|
; repeat drive read 3 times (incase of random error)
|
|
mov di, 3 ; counter
|
|
; This is basically
|
|
; for di in range(3,1,1):
|
|
; We test to see if we can read the disk 3 times
|
|
.try_read_disk: ; Try read the floppy three times
|
|
; When the disk is tried to be read, the CF flag will be
|
|
; set if there's an error, so we just clear it to return it to
|
|
; the default state
|
|
stc ; sets the cf flag
|
|
int 13h
|
|
jnc .done_read ; jump if cf = 0
|
|
|
|
call disk_reset ; Reset drivers of disk
|
|
|
|
dec di ; di -= 1
|
|
test di, di ; if di = 0
|
|
jnz .try_read_disk
|
|
jmp .disk_error
|
|
.disk_error:
|
|
mov si, disk_read_fail
|
|
call os_print_string
|
|
popa
|
|
ret
|
|
.done_read:
|
|
popa
|
|
ret
|
|
|
|
; ---------------------------------------------
|
|
|
|
; Reads a certain number of sectors into memory
|
|
; int 13h/ah = 02h read disk sectors into memory
|
|
; al = number of sectors to read
|
|
; ch = cylinder number
|
|
; cl = sector number
|
|
; dh = head number
|
|
; dl = drive number
|
|
; es:bx = points to data buffer
|
|
disk_read:
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push di
|
|
|
|
|
|
; cl = sector
|
|
; ch = cylinder
|
|
; dh = head
|
|
; dl = drive
|
|
call math_lba_to_chs ; Get the chs address
|
|
|
|
mov ah, 02h ; BIOS ah code for read disk sectors to memory
|
|
|
|
; repeat drive read 3 times (incase of random error)
|
|
mov di, 3 ; counter
|
|
|
|
; This is basically
|
|
; for di in range(3,1,1):
|
|
; We test to see if we can read the disk 3 times
|
|
.retry:
|
|
; When the disk is tried to be read, the CF flag will be
|
|
; set if there's an error, so we just clear it to return it to
|
|
; the default state
|
|
stc ; sets the cf flag
|
|
int 13h
|
|
jnc .done_read ; jump if cf = 0
|
|
|
|
call .disk_reset ; Reset drivers of disk
|
|
|
|
dec di ; di -= 1
|
|
test di, di ; if di = 0
|
|
jnz .retry
|
|
|
|
.fail_disk_read:
|
|
pop di
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
; int 13h / ah = 00h reset disk system
|
|
.disk_reset:
|
|
pusha
|
|
mov ah, 0 ; Reset drive
|
|
stc
|
|
int 13h
|
|
jc .fail_disk_read
|
|
popa
|
|
ret
|
|
|
|
.done_read:
|
|
pop di
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
; -------------------------------------
|
|
|
|
disk_load_file:
|
|
pusha
|
|
mov di, fat12_file_name
|
|
call os_format_fat_filename
|
|
|
|
; Prepare values
|
|
mov si, root_buffer
|
|
xor bx,bx
|
|
.search_root:
|
|
mov di, fat12_file_name ; Move the name of the kernel into di
|
|
mov cx, 11 ; length of 'KERNEL BIN'
|
|
push si ; Preserve si
|
|
repe cmpsb ; Repeat a comparison of bytes between file name and current bytes until it finds a match
|
|
pop si ; Retrieve si
|
|
je .found_file
|
|
|
|
add si, 32 ; increment di to the next directory entry
|
|
inc bx
|
|
cmp bx, [bdb_dir_entries_count] ; Have we reached the number of directories that exist
|
|
jl .search_root ; Repeat search
|
|
|
|
jmp .file_not_found ; If the last dir has been searched, then there is no kernel
|
|
.found_file:
|
|
mov ax, [si+26] ; ax is now a pointer to the pointer to the file relative to the data segments :D
|
|
add ax, 20h
|
|
mov [file_cluster], ax
|
|
; Setup registers for disk read
|
|
mov bx, data_buffer
|
|
mov dl, [ebr_drive_number]
|
|
|
|
call disk_read ; Load file from disk into memory
|
|
jmp .done
|
|
.file_not_found:
|
|
mov si, file_not_found
|
|
call os_print_string
|
|
jmp .done
|
|
.done:
|
|
popa
|
|
ret
|
|
|
|
|
|
|
|
section .data:
|
|
disk_read_fail: db 'Error: Could not read disk\n', 0
|
|
file_not_found: db 'File not found\n', 0
|
|
file_found: db 'File found\n', 0
|
|
loading_root: db 'Loading root diretory\n', 0
|
|
file_cluster: dw 0
|
|
fat12_file_name: db ' '
|