org 0x7C00 bpb: jmp _startup ; 2 bytes nop ; 1 byte .oem: db "OEM " ; OEM .bps: dw 0x200 ; bytes per sector .spc: db 1 ; sectors per cluster .rsectors: dw 2 ; number of reserved sectors .fats: db 2 ; number of file allocation tables .dirents: dw 2 ; Number of directory entries .sectors: dw 720 ; total number of sectors .mtd: ; media descriptor type db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB) .spfat: ; sectors per fat dw 0 .spt: dw 9 ; sectors per track .heads: dw 2 ; number of heads .hidsecs: dd 0 ; number of hidden sectors .lrgsectors: dd 0 ; large sector count .drivenum: db 0 ; drive number .winntflags: db 0 .signature: db 0x28 times (0x5A - ($-$$)) nop _startup: call adjust_bpb mov ax, 0x0500 mov es, ax mov si, 1 mov di, 0x7D00 mov cx, 0x10 call loadblk call dump .end: hlt jmp .end dump: mov si, 0x0000 mov cx, 0x10 .nextline: mov ax, si call print16 mov al, 0x3A call printc mov al, 0x20 call printc push cx mov cx, 0x0020 .words: es lodsb call print8 loop .words pop cx mov al, 0x0A call printc mov al, 0x0D call printc loop .nextline ret ; Adjust the bdp data from BIOS-supplied data (if) ; No args, no output adjust_bpb: push ax push cx push dx mov ah, 0x08 int 0x13 ; required, QEMU detects 360kB as 1200kB with CHS 80 2 15 jc .end ; skip if function does not exist inc dh mov [bpb.heads], dh mov ax, cx and ax, 0x003F mov [bpb.spt], ax ; no adjustment because sectors are 1-indexed mov ax, cx xchg al, ah mov cl,6 shr ah,cl inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders mul word [bpb.heads] ; number of tracks = number of cylinders * heads mul word [bpb.spt] ; number of sectors = number of tracks * sectors per track mov [bpb.sectors], ax .end: pop dx pop cx pop ax ret ; in si sector number, ; dl drive number ; es:0000 buffer ; out al error code, ; carry set if error loadblk: push bx push cx push dx xor dx, dx mov ax, si div word [bpb.spt] ; ax:temp = (lba / spt) inc dx ; dx:sector = (lba % spt) + 1 mov cl, dl ; for int 0x13 xor dx, dx div word [bpb.heads] ; ax:cylinder = (tmp / heads) ; dx:head = (tmp % heads) mov ch, al ; for int 0x13 mov ax, dx pop dx ; drive number comes back into dl mov dh, al ; for int 0x13 mov bx, 0x0000 mov ax, 0x0201 ; ah=0x02 al=0x01 int 0x13 call print16 lahf xchg ah, al call print8 mov al, 0x0A call printc mov al, 0x0D call printc pop cx pop bx ret %include "print.asm" times (0x1FE - ($-$$)) nop dw 0xAA55