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: