EttinOS/src/BOOT.ASM

225 lines
3.5 KiB
NASM

CPU 8086
ORG 0x7c00
jmp start
nop
;Disk description tables
%ifdef F1440
;1.44 MB 3.5" floppy disk (enable with the argument -d F1440 when building)
oemlabel db "ETTINOS "
sectorsize dw 0x200 ;bytes
clustersize db 0x1 ;sectors
bootsectors dw 0x1
fats db 0x2
rootentries dw 0xe0
logicalsectors dw 0xb40
mediadescriptor db 0xf0
sectorsperfat dw 0x9
sectorspertrack dw 0x12
sides dw 0x2
hiddensectors dd 0x0
largesectors dd 0x0
driveid dw 0x0
drivesignature db 0x29
volumeid dd 0x0
volumelabel db "ETTINOS "
filesystem db "FAT12 "
%else
;360 KiB 5.25" floppy disk (default)
oemlabel db "ETTINOS "
sectorsize dw 0x200 ;bytes
clustersize db 0x2 ;sectors
bootsectors dw 0x1
fats db 0x2
rootentries dw 0x70
logicalsectors dw 0x2d0
mediadescriptor db 0xfd
sectorsperfat dw 0x2
sectorspertrack dw 0x9
sides dw 0x2
hiddensectors dd 0x0
largesectors dd 0x0
driveid dw 0x0
drivesignature db 0x29
volumeid dd 0x0
volumelabel db "ETTINOS "
filesystem db "FAT12 "
%endif
start:
;Setup
;Set up the data, stack, and extra segments
mov ax, 0x0
mov ds, ax
mov ss, ax
mov es, ax
;Set up the stack
cli
mov sp, stack
add sp, 0x100
sti
;Store the boot device number
mov [bootdev], dl
;Load the root
;Set the source
mov ah, 0x0
mov al, [fats]
mul word [sectorsperfat]
add ax, [bootsectors]
push ax
call calcsource
;Set the destination
mov si, 0x7f00
mov bx, si
;Set the size
push dx
mov ax, [rootentries]
mov dx, 0x20
mul dx
mov dx, 0x0
div word [sectorsize]
pop dx
push ax
;Load
mov ah, 0x2
int 0x13
;Search the root for the system
;Set DI to the root
mov di, 0x7f00
;Initialise the search loop
mov cx, word [rootentries]
mov ax, 0x0
search:
;Store CX in the stack
push cx
;Check for the system FAT
mov si, sysfile
mov cx, 0xb
rep cmpsb
je loadfat
;Set DI to the next entry
add ax, 0x20
mov di, 0x7f00
add di, ax
;Load CX from the stack
pop cx
loop search
;Load the system entry
loadfat:
;Load CX from the stack
pop cx
;Store the first cluster
mov ax, word [es:di+0xf]
mov word [cluster], ax
;Set the source
mov ax, 0x1
call calcsource
;Set the destination
mov di, 0x7f00
mov bx, di
;Set the size
mov ax, [sectorsperfat]
;Load
mov ah, 0x2
int 0x13
;Load the system file
;Load a cluster
loadcluster:
;Set the source
pop cx
pop bx
mov ax, word [cluster]
sub ax, 0x2
mul byte [clustersize]
add ax, bx
add ax, cx
push bx
push cx
call calcsource
;Set the destination
mov bx, word [pointer]
;Set the size
;mov al, 0x1
mov al, [clustersize]
;Load
mov ah, 0x2
int 0x13
;Calculate the next cluster
mov ax, [cluster]
mov dx, 0x0
mov bx, 0x3
mul bx
mov bx, 0x2
div bx
mov si, 0x7f00
add si, ax
mov ax, word [ds:si]
or dx, dx
jz even
odd:
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
jmp contcalc
even:
and ax, 0xfff
contcalc:
mov word [cluster], ax
cmp ax, 0xff8
jge boot
mov ax, [sectorsize]
mul word [clustersize]
add word [pointer], ax
jmp loadcluster
;Boot the system
boot:
jmp 0x0:0x500
;Data
bootdev db 0x0
sysfile db "SYSTEM BIN"
cluster dw 0x0
pointer dw 0x500
;Calculate the source arguments for loading data from the disk
calcsource:
push ax
push bx
mov bx, ax
mov dx, 0x0
div word [sectorspertrack]
add dl, 0x1
mov cl, dl
mov ax, bx
mov dx, 0x0
div word [sectorspertrack]
mov dx, 0x0
div word [sides]
mov dh, dl
mov ch, al
pop bx
pop ax
mov dl, byte [bootdev]
ret
;Pad the binary to a full sector and make the disk bootable
;Padding
times 0x1fe-($-$$) db 0x0
;Boot signature
dw 0xaa55
stack: