Return to Snippet

Revision: 7492
at July 26, 2008 15:03 by Fizyk


Updated Code
use16
org 7C00h

fat = 7E00h
main_cat = 9000h
free_mem = 0AC00h

jmp codestart
nop

db 'FizykOS '
dw 512
db 1
dw 1
db 2
dw 224
dw 2880
db 0F0h
dw 9
dw 18
dw 2
dw 0
db 0 ;0 = FAT12, 1 = FAT16, 2 = FAT32

codestart:

push cs
push cs
pop ds
pop es

;load FAT

mov ax,1
call sec_log_to_phys
mov ah,2
mov al,9
mov bx,fat
int 13h

;load root folder

mov ax,19
call sec_log_to_phys
mov ah,2
mov al,14
mov bx,main_cat
int 13h

;search for file kernel.bin
mov cx,224
loop_search_001:
mov si,free_mem
mov ax,32
mul cx
sub si,ax
push si
mov di,filename
push cx
mov cx,11
cld
repe cmpsb
pop cx
pop si
loopne loop_search_001
cmp cx,0
je not_found

;file found

add si,1Ah ;point at first cluster number

mov ax,[si] ;ax - number of the first cluster
mov bx,main_cat

loop_read_file:
push ax
call cluster_to_phys
mov ax,0201h
int 13h		;load cluster (sector)
add bx,512
pop ax
push ax
mov cx,3
mul cx		;multiply number by 3
shr ax,1	;and divide by 2
mov si,ax
mov cx,[si+fat]	;word at that address
pop ax
and ax,1
cmp ax,0	;was even?
je next_001
shr cx,4	;no, shift 4 bits right
jmp next_002
next_001:
and cx,0FFFh	;yes, and 0FFFh
next_002:
mov ax,cx	;result -> ax
cmp ax,0FF7h	;if > 0FF7h, end reading
ja file_loaded
jmp loop_read_file

file_loaded:

push 900h
push 900h
pop ds
pop es
jmp 900h:0	;jump to 0900:0000 (where the file was loaded)

not_found:
mov si,msg
loop_write:
cmp byte [si],0
je next_003
mov ah,0Eh
mov al,[si]
int 10h
inc si
jmp loop_write
next_003:
cli
hlt

;data area start = 1 + 18 + 14 = 33

cluster_to_phys: ;ax = cluster -> ax = logical sector
add ax,31
sec_log_to_phys: ;ax = logical -> cx = cylinder + sector, dh = head
push bx
xor dx,dx
mov bx,18
div bx		;ax = log div 18, dx = log mod 18
inc dx		;dx = physical sector
mov cx,ax	;cx = log div 18
push cx
and cx,1	;cx = (log div 18) mod 2 = head
mov dh,cl	;dh = head
pop cx
shr cx,1	;cx = (log div 18) div 2 = cylinder
rol cx,2	
shl cl,6
xor cl,cl
or cl,dl	;cx = cylinder & sector
xor dl,dl	;dl = 0 - floppy
pop bx
ret

filename db 'KERNEL  BIN',0
msg db 'kernel.bin not found.',0

times 7c00h+510-$ db 0

dw 0AA55h

Revision: 7491
at July 26, 2008 08:35 by Fizyk


Initial Code
use16
org 7C00h

fat = 7E00h
main_cat = 9000h
free_mem = 0AC00h

jmp codestart
nop

db 'FizykOS '
dw 512
db 1
dw 1
db 2
dw 224
dw 2880
db 0F0h
dw 9
dw 18
dw 2
dw 0
db 0 ;0 = FAT12, 1 = FAT16, 2 = FAT32

codestart:

push cs
push cs
pop ds
pop es

;wczytaj FAT

mov ax,1
call sec_log_to_phys
mov ah,2
mov al,9
mov bx,fat
int 13h

;wczytaj katalog główny

mov ax,19
call sec_log_to_phys
mov ah,2
mov al,14
mov bx,main_cat
int 13h

;szukaj pliku kernel.bin
mov cx,224
petla_szukaj_001:
mov si,free_mem
mov ax,32
mul cx
sub si,ax
push si
mov di,plik
push cx
mov cx,11
cld
repe cmpsb
pop cx
pop si
loopne petla_szukaj_001
cmp cx,0
je nie_znaleziono

;jezeli kod dotarl tutaj, to znalazlem plik :D

add si,1Ah ;zeby pokazywal na pierwszy klaster

mov ax,[si] ;ax - numer pierwszego klastra
mov bx,main_cat

petla_czytaj_plik:
push ax
call cluster_to_phys
mov ax,0201h
int 13h		;wczytaj klaster (sektor)
add bx,512
pop ax
push ax
mov cx,3
mul cx		;pomnoz numer klastra przez 3
shr ax,1	;i podziel przez 2
mov si,ax
mov cx,[si+fat]	;slowo spod tego adresu
pop ax
and ax,1
cmp ax,0	;czy bylo parzyste
je dalej_001
shr cx,4	;nie, przesuwamy o 4 bity w prawo
jmp dalej_002
dalej_001:
and cx,0FFFh	;tak, mnozymy logicznie przez FFF
dalej_002:
mov ax,cx	;wynik -> ax
cmp ax,0FF7h	;jesli wieksze niz 0FF7h, to koniec wczytywania
ja plik_wczytany
jmp petla_czytaj_plik

plik_wczytany:

push 900h
push 900h
pop ds
pop es
jmp 900h:0	;skok do 0900:0000, czyli tam, gdzie wczytałem plik

nie_znaleziono:
mov si,msg
petla_pisz:
cmp byte [si],0
je dalej_003
mov ah,0Eh
mov al,[si]
int 10h
inc si
jmp petla_pisz
dalej_003:
cli
hlt

;poczatek obszaru danych = 1 + 18 + 14 = 33

cluster_to_phys: ;ax = cluster -> ax = nr log
add ax,31
sec_log_to_phys: ;ax = nr log -> cx = sciezka + sektor, dh = głowica
push bx
xor dx,dx
mov bx,18
div bx		;ax = nr log div 18, dx = nr log mod 18
inc dx		;dx = fizyczny sektor
mov cx,ax	;cx = nr log div 18
push cx
and cx,1	;cx = (nr log div 18) mod 2 = nr głowicy
mov dh,cl	;dh = głowica
pop cx
shr cx,1	;cx = (nr log div 18) div 2 = nr sciezki
rol cx,2	
shl cl,6
xor cl,cl
or cl,dl	;cx = nr sciezki i sektora
xor dl,dl	;dl = 0 - dyskietka
pop bx
ret

plik db 'KERNEL  BIN',0
msg db 'Nie znaleziono kernel.bin',0

times 7c00h+510-$ db 0

dw 0AA55h

Initial URL


Initial Description
FASM 1.47

Initial Title
Bootloader FAT12

Initial Tags


Initial Language
Assembler