fcb1 equ 0x5C org 0x100 jmp main %include "scan.inc" %include "print.inc" drvnum db 0 track dw 39 main mov di, 0x81 mov al, 0x20 mov ch, 0 mov cl, [0x80] repe scasb repne scasb test cx, cx jnz rddrv call putsh db "BIOS drive number not specified", 0x0A, 0x0D, 0 int 0x20 rddrv mov si, di call lodnum mov dx, ax test dx, ~0x83 jnz drverr mov byte [drvnum], dl test dl, 0x80 jz floppy call drverr drverr call putsh db "Failed to access drive", 0x0A, 0x0D, 0 int 0x20 ; read bios parameter block floppy mov ax, 0x0201 mov cx, 0x0001 mov dh, 0 mov bx, prog int 0x13 jc drverr mov ax, [prog+0x016] cmp ax, 12 jbe .gok call putsh db "Unsupported FAT size", 0x0A, 0x0D, 0 int 0x20 .gok nop ; calculate start of cluster area mov ax, [prog+0x011] ; number of dir entries mov cl, 5 shl ax, cl mov bx, [prog+0x0B] ; bytes per sector div bx mov cx, ax mov ax, [prog+0x016] ; logical sectors per fat mov bl, [prog+0x010] ; number of fats mov bh, 0 mul bx add ax, cx add ax, [prog+0x00E] ; reserved sectors mov si, ax ; calculate sector offset of target track mov ax, [prog+0x018] ; sectors per track mul word [prog+0x01A] ; number of heads mul word [track] ; calculate cluster offset of target track -> SI sub ax, si mov bl, [prog+0x00D] ; sectors per cluster mov bh, 0 xor dx, dx div bx mov si, ax ; calculate cluster length of target track -> DI mov ax, [prog+0x018] ; sectors per track add ax, dx ; remainder ; add sectors per cluster minus one add ax, bx dec ax ; divide by sectors per cluster and floor xor dx, dx div bx mov di, ax ; load fat table call debug ret ; TODO: ; calculate offset into fat table ; check that all relevant clusters are 0 or 0xFFF7 ; set all relevant clusters to 0xFFF7 ; track is now available for direct writing ; set up boot code mov di, prog mov ax, 0x7FEB stosw mov byte [di], 0x80 add di, 0x7F - b_ld + b_rst mov si, b_rst mov cx, b_end - b_rst rep movsb ; write back bootsector mov ax, 0x0301 mov cx, 0x0001 mov dh, 0 mov bx, prog int 0x13 jc drverr mov dx, fcb1 mov ah, 0xF int 0x21 test al, al jz .fok .ferr call putsh db "Failed to read input file", 0x0A, 0x0D, 0 ret .fok mov si, prog ; apply our target address .rloop mov dx, si mov ah, 0x1A int 0x21 ; increment address for next iteration add si, 0x80 ; do a read mov dx, fcb1 mov ah, 0x14 int 0x21 ; success: continue cmp al, 0 jz .rloop ; eof: break cmp al, 1 jz .cok ; segment wrap: fail cmp al, 2 jz .ferr ; we assume al=3: eof .cok nop mov ax, si sub ax, args add ax, 0x1FF mov cl, 9 shr ax, cl call debug ret ; code to copy into boot sector b_rst mov ah, 0 int 0x13 b_ld mov ax, 0x60 mov ds, ax mov es, ax mov ss, ax xor sp, sp mov ax, 0x0208 ; read, 8 sectors b_len equ $ - 2 mov cx, 0x2701 ; track 39, sector 1 b_trck equ $ - 1 b_strt equ $ - 2 mov dh, 0 ; head 0 xor bx, bx ; es:bx=0x60:0 int 0x13 jc b_rst mov byte [4], dl jmp 0x60:0x100 b_end equ $ align 2 psp equ $ args equ psp + 0x80 prog equ psp + 0x100