StupidOS/boot/fat12.inc

181 lines
3.9 KiB
PHP

ATTR_READ_ONLY = 0x01
ATTR_HIDDEN = 0x02
ATTR_SYSTEM = 0x04
ATTR_VOLUME_ID = 0x08
ATTR_DIRECTORY = 0x10
ATTR_ARCHIVE = 0x20
struc fat_entry
{
.name db 8 dup ?
.ext db 3 dup ?
.attrs db ?
.reserved dw ?
.creation_time dw ?
.creation_date dw ?
.access_date dw ?
.reserved2 dw ?
.mod_time dw ?
.mod_date dw ?
.start dw ?
.size dd ?
}
virtual at di
fat_entry fat_entry
end virtual
; CHS to LBA
; LBA = (C * HPC + H) * SPT + (S - 1)
;;; Read sectors from disk to buffer
;;;
;;; @param AX LBA starting sector
;;; @param CX sector count
;;; @param ES:BX buffer
;;;
disk_read_sectors:
; https://en.wikipedia.org/wiki/Logical_block_addressing
; convert LBA to CHS
; HPC = Head per Cluster
; SPT = Sector per Track
; S = (LBA % SPT) + 1
push ax
push bx
push cx
xor dx, dx
div word [sectors_per_track]
inc dx
mov [S], dx
; H = (LBA / SPT) % HPC
; C = LBA / (HPC * SPT)
xor dx, dx
div word [heads_per_cylinder]
mov [C], ax
mov [H], dx
; read sectors
mov ah, 0x2
mov al, 0x1
mov ch, byte [C]
mov cl, byte [S]
mov dh, byte [H]
mov dl, [drive_number]
int 0x13
jc @f
pop cx
pop bx
pop ax
add bx, word [bytes_per_sector]
inc ax
loop disk_read_sectors
ret
@@:
mov si, msg_error_sector
call bios_print
ret
C dw 0x00
H dw 0x00
S dw 0x00
fat_load_root:
mov ax, DISK_BUFFER/0x10
mov es, ax
; load root directory
mov ax, [sectors_per_FAT]
xor cx, cx
mov cl, [FAT_count]
mul cx
add ax, [reserved_sectors]
push ax
mov bx, [bytes_per_sector]
mov cl, 0x5
shr bx, cl
mov ax, [root_dir_entries]
xor dx, dx
div bx
mov cx, ax
pop ax
mov [data_start], ax
add [data_start], cx
xor bx, bx
call disk_read_sectors
ret
;; @param SI filename to search
fat_search_root:
mov cx, [root_dir_entries]
mov di, 0x0
@@:
push si
push cx
mov cx, 0xB ; name(8) + ext(3)
push di
rep cmpsb
pop di
pop cx
pop si
je .file_found
add di, 0x20
loop @b
; set carry if not found
stc
ret
.file_found:
mov ax, [es:fat_entry.start]
clc
ret
;;; @param AX cluster
;;; @param ES:BX buffer
fat_load_binary:
push ax
sub ax, 0x2
xor cx, cx
mov cl, [sectors_per_cluster]
mul cx
add ax, [data_start]
xor cx, cx
mov cl, [sectors_per_cluster]
call disk_read_sectors
pop ax
mov cx, ax
mov dx, ax
shr dx, 0x1
add cx, dx
push bx
mov bx, DISK_BUFFER
add bx, cx
mov dx, [bx]
pop bx
test ax, 0x1
jnz .odd_cluster
.even_cluster:
and dx, 0xFFF
jmp .end
.odd_cluster:
shr dx, 0x4
.end:
mov ax, dx
cmp dx, 0xFF0
jb fat_load_binary
ret
msg_error_sector db "ERROR: reading sector", CR, LF, 0
data_start dw 0x0