CPU 8086 ORG 0x7c00 jmp start nop ;Disk description tables %ifdef F1440 ;1.44 MB 3.5" floppy disk (enable by passing -d F1440 to NASM) 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: ;Set up the data segment mov ax, 0x0 mov ds, ax ;Set up the stack cli mov ax, 0x0 mov ss, ax mov sp, 0x7c00 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, 0x7e00 mov bx, ds mov es, bx 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 FAT mov ax, ds mov es, ax mov di, 0x7e00 ;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, 0x7e00 add di, ax ;Load CX from the stack pop cx loop search ;Load the system FAT 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, 0x7e00 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 bx pop ax push ax push bx add ax, bx sub ax, 0x2 add ax, word [cluster] call calcsource ;Set the destination mov ax, 0x0 mov es, ax mov bx, word [pointer] ;Set the size mov al, 0x1 ;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, 0x7e00 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 add word [pointer], 0x200 jmp loadcluster boot: jmp 0x0:0x9e00 sysfile db "SYSTEM BIN" bootdev db 0x0 cluster dw 0x0 pointer dw 0x9e00 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 ;Padding times 0x1fe-($-$$) db 0x0 ;Boot signature dw 0xaa55