EttinOS/src/BOOT.ASM

257 lines
4.1 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)
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
%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
%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, 0x0
sti
;Store the boot drive number
mov [drive], dl
;Load the root
;Set the source
mov ah, 0x0
mov al, [fats]
mul word [sectorsperfat]
add ax, [bootsectors]
push ax
;Set the destination
mov si, buffer
mov bx, si
;Set the size
mov ax, [rootentries]
mov dx, 0x20
mul dx
mov dx, 0x0
div word [sectorsize]
mov cx, ax
pop ax
push ax
push cx
loadroot:
push cx
call calcsource
;Set the size
push ax
mov al, 0x1
;Load
mov ah, 0x2
int 0x13
pop ax
;Set the next sector
add ax, 0x1
add bx, word [sectorsize]
pop cx
loop loadroot
;Search the root for the system entry
;Set DI to the root
mov di, buffer
;Initialise the search loop
mov cx, word [rootentries]
mov ax, 0x0
search:
;Store CX in the stack
push cx
;Check for the system entry
mov si, sysfile
mov cx, 0xb
rep cmpsb
je loadentry
;Set DI to the next entry
add ax, 0x20
mov di, buffer
add di, ax
;Load CX from the stack
pop cx
loop search
;Print an error message if the system is not found
mov si, errormsg
printerror:
;Load a character
lodsb
;Check for the string end
cmp al, 0x0
je $
;Print the character
mov ah, 0xe
int 0x10
;Repeat
jmp printerror
;Load the system entry
loadentry:
;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, buffer
mov bx, di
;Set the size
mov ax, [sectorsperfat]
;Load
mov ah, 0x2
int 0x13
;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
;Set the destination
mov bx, word [pointer]
;Load a sector
mov ch, 0x0
mov cl, byte [clustersize]
loadsector:
push cx
call calcsource
;Set the size
push ax
mov al, 0x1
;Load
mov ah, 0x2
int 0x13
pop ax
;Set the next sector
add ax, 0x1
add bx, word [sectorsize]
pop cx
loop loadsector
;Calculate the next cluster
mov ax, [cluster]
mov dx, 0x0
mov bx, 0x3
mul bx
mov bx, 0x2
div bx
mov si, buffer
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
;Clear the stack and boot the system
boot:
;Clear
pop cx
pop bx
;Pass the drive number to the system
mov dl, byte [drive]
;Boot
jmp 0x0:0x500
;Data
drive db 0x0
sysfile db "SYSTEM BIN"
errormsg db "System not found", 0xd, 0xa, 0x0
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 [drive]
ret
;Pad the binary to a full sector and make the disk bootable
;Padding
times 0x1fe-($-$$) db 0x0
;Boot signature
dw 0xaa55
;File system buffer
buffer: