; Original code by Mike Gonta, Public Domain 2010
START_ADDRESS equ 100000h
FAT_TABLE equ 7E00h
ROOT_DIRECTORY equ 9000h
use32
org 7C00h
jmp boot32
nop
db ' boot32 '
dw 512 ; bytes per sector
db 1 ; sectors per cluster
dw 1 ; reserved sector count
db 2 ; number of FATs
dw 16*14 ; root directory entries
dw 18*2*80 ; sector count
db 0F0h ; media byte
dw 9 ; sectors per fat
dw 18 ; sectors per track
dw 2 ; number of heads
dd 0 ; hidden sectors
dd 0 ; number of sectors huge
db 0 ; drive number
db 0 ; reserved
db 29h ; signature
dd 0 ; volume ID
db ' ' ; volume label
db 'FAT12 ' ; file system type
boot32:
mov esi, loading
call print32
mov esi, return
call print32
mov edi, directory_name
mov esi, file_name
mov ecx, 8
.1:
mov al, [esi]
lea esi, [esi+1]
test al, al
je .3
cmp al, '.'
je .extension
call convert_char
mov [edi], al
lea edi, [edi+1]
sub ecx, 1
jne .1
mov al, [esi]
lea esi, [esi+1]
cmp al, '.'
jne .3
.extension:
mov edi, directory_name+8
mov ecx, 3
.2:
mov al, [esi]
lea esi, [esi+1]
test al, al
je .3
call convert_char
mov [edi], al
lea edi, [edi+1]
sub ecx, 1
jne .2
.3:
mov eax, 1
mov ebx, FAT_TABLE
mov ebp, 209h ; read 9 sectors
call read_logical_sector
mov eax, 19
mov ebx, ROOT_DIRECTORY
mov ebp, 20Eh ; read 14 sectors
call read_logical_sector
mov esi, directory_name
.next_entry:
mov eax, [ebx]
cmp eax, [esi]
jne .4
mov eax, [ebx+4]
cmp eax, [esi+4]
jne .4
mov eax, [ebx+8]
xor eax, [esi+8]
and eax, 0FFFFFFh
je .found_entry
.4:
add ebx, 32 ; size of root entry
cmp ebx, ROOT_DIRECTORY+16*14*32
jne .next_entry
jmp boot32_exit
.found_entry:
movzx eax, WORD [ebx+26]
mov ebx, START_ADDRESS
.next_sector:
push eax
add eax, 1+9*2+14-2
mov ebp, 201h
call read_logical_sector
jc boot32_exit
add ebx, 512
pop eax
lea eax, [eax+eax*2] ; times 3
shr eax, 1 ; divided by 2
movzx eax, WORD [FAT_TABLE+eax]
jnc .5
shr eax, 4
.5:
and eax, 0FFFh
cmp eax, 0FF6h
jb .next_sector
mov esi, line_feed
call print32
jmp START_ADDRESS
read_logical_sector: ; eax=logical sector address
push ebx ; ebp=eax value for int 13h
xor edx, edx
mov ebx, 18
div ebx
add edx, 1
mov ecx, edx ; sector in cl
xor edx, edx
mov ebx, 2
div ebx
mov dh, dl ; head in dh
mov dl, 0
mov ch, al ; cylinder in ch
pop ebx
mov eax, ebp
mov ebp, 2 ; 3 tries
.1:
push eax
int 13h
jnc .2
sub ebp, 1
jc .2
xor eax, eax
int 13h
pop eax
jmp .1
.2:
pop ebp
ret
print32:
mov ah, 0Eh
xor bh, bh
.1:
mov al, [esi]
lea esi, [esi+1]
test al, al
je .2
int 10h
jmp .1
.2:
ret
convert_char:
cmp al, 'a'
jb .1
cmp al, 'z'
ja .1
sub al, ' '
.1:
ret
boot32_exit:
mov esi, file_name
call print32
mov esi, file_not_found
call print32
int 18h
directory_name: db ' '
return:
db ' . . .', 13, 0
file_not_found:
db ' file not found!', 13
line_feed:
db 10, 13, 10, 0
times (512-24)-($-$$) db 0
loading:
db 'Loading '
file_name:
db 'Kernel.bin'
times 12-($-file_name) db 0
dw 0
dw 0AA55h
fat1: ; empty FAT12 file system
db 0F0h, 0FFh, 0FFh
times 512*9-($-fat1) db 0
fat2:
db 0F0h, 0FFh, 0FFh
times 512*9-($-fat2) db 0
root:
times 512*14-($-root) db 0
Mike Gonta
look and see - many look but few see