%define segment 0x00100 %define self (0x7C00-(segment<<4)) ; 1 sector cpu 8086 org self jmp short init times (0x0B - ($-$$)) db 0 fdc: .ss: dw 0x200 ; sector size .sc: db 2 ; sectors per cluster .rsc: dw 1 ; reserved sector count .fn: db 2 ; number of file allocation tables .rde: dw 0x70 ; number of root directory entries .ts: dw 720 ; total number of sectors .mi: ; medium identifier db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB) .sf: ; sectors per fat dw 2 .spt: dw 9 ; sectors per track .nos: dw 2 ; number of sides (heads) .po: dd 0 ; partition offset (in LBA blocks) .lrgts: dd 0 .drv: db 0 ; drive number db 0 db 0x29 ; efdc signature .vid: dd 0 ; volume id .vlabel: db "2B" times (54 - ($-$$)) db " " .fstype: db "FAT12" times (62 - ($-$$)) db " " ; mformat keeps writing until here ; if we place init earlier, code gets overwritten times (62 - ($-$$)) nop init: cli jmp segment:main main: ; Stack grows down from 64k mov ax, cs mov ss, ax mov sp, BDOS mov ds, ax mov es, ax mov [fdc.drv], dl ; save drive number in fd mov ax, 1 mov cx, 8 mov dx, 0 mov bx, BDOS .loop: push ax push cx push dx ; add partition offset (required for HDD) add ax, [fdc.po] adc dx, [fdc.po+2] ; calculate CHS data div word [cs:fdc.spt] ; ax:temp = (lba / spt) inc dx ; dx:sector = (lba % spt) + 1 mov cl, dl ; sector number xor dx, dx div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads) ; dx:head = (tmp % heads) mov ch, al ; cylinder number mov dh, dl ; head number mov dl, [cs:fdc.drv] ; driver number mov ax, 0x0201 ; ah=0x02 al=0x01 int 0x13 mov bp, 0x3331 jc error pop dx pop cx pop ax ; count up for next sector add bx, 0x0200 add ax, 1 adc dx, 0 loop .loop mov dl, [fdc.drv] ; jump into bios cold boot entry point jmp segment:BIOS error: mov ax, bp mov ah, 0x0e mov bx, 7 int 0x10 mov al, 0x21 int 0x10 xor ax, ax int 0x16 int 0x19 times (0x1FE - ($-$$)) db 0 dw 0xAA55