247 lines
3.9 KiB
NASM
247 lines
3.9 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
|
||
call calcsource
|
||
;Set the destination
|
||
mov si, buffer
|
||
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 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 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
|
||
;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:
|
||
|