.arch i8086,jumps .code16 .intel_syntax noprefix .section .init .global _start _start: jmp main diskpointer = 0x1e*4 dbtbase = 0x0500 .section .text.dosdbt .local dosdbt dosdbt: # assumes es=0 push si push di push ds mov si, diskpointer lds si, [si] mov di, dbtbase mov cx, 0x0a # size of the dbt cld rep movsb # move dbt to dbtbase pop ds mov al, 9 # sectors per track mov si, dbtbase mov [si+4], al # set number of sectors mov di, diskpointer mov [di], si # new int1eh offset mov [di+2], ds # and segment pop di pop si ret .section .text.int80stuff # near copy [param 2] bytes, es:[param 0] -> es:[param 1] copy: mov si, [bp+0] # source mov di, [bp+2] # destination mov cx, [bp+4] # length cld rep movsb ret ## floppy stuff # same as read but with a different int13h:ah value writesector: mov ax, 0x0301 # write command, 1 sector jmp 0f # params: addr, c, h, s # return status in ah, sectors read (1 or 0) in al readsector: mov ax, 0x0201 # read command, 1 sector 0: mov bx, [bp+0] # addr mov ch, [bp+2] # c mov dh, [bp+4] # h mov cl, [bp+6] # s int 0x13 ret # params: c, h # returns: status in ah, 0 in al? buffer = 0xe000 # buffer needs to be big enough for a whole track # (for some reason), so 9 * 512 bytes = 0x1200 bytes sectors = 9 formattrack: mov bx, buffer xor cx, cx 0: cmp cl, sectors jnl 1f mov di, cx and di, 0x0f # max 15 sectors shl di, 1 shl di, 1 # di = cl*4 lea di, [bx+di] mov al, [bp+0] # track number mov [di+0], al mov al, [bp+2] # head number mov [di+1], al mov al, cl # sector number inc al mov [di+2], al movb [di+3], 0x02 # 512 bytes per sector inc cl jmp 0b 1: mov ah, 0x05 # format track mov al, sectors mov dl, 0 # first drive mov ch, [bp+0] # track number mov dh, [bp+2] # head number mov cl, 1 # sector number (first sector?) int 0x13 ret readfile: mov ax, [bp+0] mov dx, [bp+2] call fat12_readfile ret .section .rodata.polmon_str polmon_str: .ascii "POLMON COM" polmon_addr = 0x1000 .section .text.main .global main main: cli mov ax, 0x2000 # stack address mov sp, ax # ss should already be 0 sti call dosdbt mov ax, 0x1a00 # first sector of first fat mov dx, 0x1c00 # first sector of root dir call fat12_init mov si, 0x80*4 movw [si], offset int80h movw [si+2], 0 mov ax, offset polmon_str mov dx, polmon_addr call fat12_readfile test ax, ax jnz 0f jmp polmon_addr 0: mov ax, 0x0e42 mov bh, 0 int 0x10 cli hlt .section .text.int80h int80h: push bx push si push di push bp push ds push es xor cx, cx mov es, cx mov ds, cx shl ah cmp ah, offset int80h_entries jge 0f mov al, ah xor ah, ah mov si, ax mov bp, sp lea bp, [bp + 18] # 12 for us, 6 for the interrupt call [int80h_table+si] jmp 1f 0: mov ax, -1 1: pop es pop ds pop bp pop di pop si pop bx iret .section .rodata.int80h int80h_table: .word offset copy # 0x00 .word offset readsector # 0x01 .word offset writesector # 0x02 .word offset formattrack # 0x03 .word offset readfile # 0x04 int80h_entries = . - int80h_table