;======================================================================
;CREATED BY ATOMIC_BIOS
;BOOT SECTOR FOR FAT12
;======================================================================
Org 0x7c00
;======================================================================
jmp Fstart
;======================================================================
nop
;======================================================================
OemID db "BIOSXXX",0
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01
ReservedSectors dw 0x0001
TotalFATs db 0x01
MaxRootEntries dw 0x00E0
TotalSectorsSmall dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFAT dw 0x0012
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Palette db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db 0xC3,0,0,0,0,0,0,0,0,0,0
SystemID db "FAT12 ",0
ImageName db "SAMUEL COM",0
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
datasector dw 0x0000
cluster dw 0x0000
xCrlf db 0x0D, 0x0A, 0x00
Cont db "รพ", 0x00
Loading db "OK", 0x00
xFail db "Err", 0x00
smode db 0x03
addrS dw 0x2000
addrO dw 0x0100
;======================================================================
Fstart:
mov bp, 0
mov si, 0
mov di, 0
mov ax, 0x40
mov es, ax
mov dword [es:6ch], 0x00000000
;======================================================================
mov ax, cs
mov ds, ax
mov es, ax
;======================================================================
mov ah, 0
mov al, byte [cs:smode]
int 0x10
;======================================================================
call VolumeLabel
;======================================================================
mov si, Loading
mov bl, 15
call ShowStr
;======================================================================
call LoadRoot
call FindFile
call LoadFat
call ReadFile
call Launch
;======================================================================
LoadRoot:
xor cx, cx
xor dx, dx
mov ax, 0x0020
mul WORD [cs:MaxRootEntries]
div WORD [cs:BytesPerSector]
xchg ax, cx
mov al, BYTE [cs:TotalFATs]
mul WORD [cs:SectorsPerFAT]
add ax, WORD [cs:ReservedSectors]
mov WORD [cs:datasector], ax
add WORD [cs:datasector], cx
mov bx, Buff1
call ReadSectors
ret
;======================================================================
FindFile:
mov di, Buff1
Loop1:
push cx
mov cx, 0x000B
mov si, ImageName
push di
rep cmpsb
pop di
pop cx
je AllDone
add di, 0x0020
loop Loop1
jmp Fail
AllDone:
ret
;======================================================================
LoadFat:
mov dx, WORD [cs:di + 0x001A]
mov WORD [cs:cluster], dx
mov ax, WORD [cs:ReservedSectors]
mov bx, Buff1
mov cx, WORD [cs:SectorsPerFAT]
call ReadSectors
ret
;======================================================================
ReadFile:
mov ax, word [cs:addrS]
mov es, ax
mov bx, word [cs:addrO]
push bx
LoadImage:
mov ax, WORD [cs:cluster]
pop bx
call ClusterLBA
xor cx, cx
mov cl, BYTE [cs:SectorsPerCluster]
call ReadSectors
push bx
mov ax, WORD [cs:cluster]
mov cx, ax
mov dx, ax
shr dx, 0x0001
add cx, dx
mov bx, Buff1
add bx, cx
mov dx, WORD [bx]
test ax, 0x0001
jnz OddBall
EvenBall:
and dx, 0000111111111111b
jmp Done1
OddBall:
shr dx, 0x0004
Done1:
mov WORD [cs:cluster], dx
cmp dx, 0x0FF0
jb LoadImage
Done:
pop ax
mov si, xCrlf
call ShowStr
ret
;======================================================================
Launch:
push WORD [cs:addrS]
push WORD [cs:addrO]
retf
;======================================================================
Fail:
mov si, xFail
mov bl, 15
call ShowStr
mov ah, 0x00
int 0x16
int 0x19
;======================================================================
;ShowStr
ShowStr:
lodsb
cmp al, 0
je Okay
mov ah, 0x0E
mov bh, 0x00
int 0x10
jmp ShowStr
Okay:
ret
;======================================================================
;ReadSectors
;reads cx sectors from disk starting at ax into
;memory location es:bx
ReadSectors:
Main:
mov di, 0x0005
Sloop:
push ax
push bx
push cx
call Lbachs
mov ah, byte [cs:io]
mov al, 0x01
mov ch, BYTE [cs:absoluteTrack]
mov cl, BYTE [cs:absoluteSector]
mov dh, BYTE [cs:absoluteHead]
mov dl, BYTE [cs:DriveNumber]
int 0x13
jnc Success
xor ax, ax
int 0x13
dec di
pop cx
pop bx
pop ax
jnz Sloop
int 0x19
Success:
push bx
mov bl, 14
mov si, Cont
call ShowStr
pop bx
pop cx
pop bx
pop ax
add bx, WORD [cs:BytesPerSector]
inc ax
loop Main
ret
;======================================================================
;ClusterLBA
;convert FAT cluster into LBA addressing scheme
;LBA = (cluster - 2) * sectors per cluster
ClusterLBA:
sub ax, 0x0002
xor cx, cx
mov cl, BYTE [cs:SectorsPerCluster]
mul cx
add ax, WORD [cs:datasector]
ret
;======================================================================
;Lbachs
;convert ax LBA addressing scheme to CHS addressing scheme
;absolute sector = (logical sector / sectors per track) + 1
;absolute head = (logical sector / sectors per track) MOD number of heads
;absolute track = logical sector / (sectors per track * number of heads)
Lbachs:
xor dx, dx
div WORD [cs:SectorsPerTrack]
inc dl
mov BYTE [cs:absoluteSector], dl
xor dx, dx
div WORD [cs:NumHeads]
mov BYTE [cs:absoluteHead], dl
mov BYTE [cs:absoluteTrack], al
ret
;======================================================================
io db 0x02
;======================================================================
rb 0x7c00+512-2-$
dw 0xAA55
Buff1 rb 512 * 0x12
;======================================================================