From dd5d329dff65786bd5aa90cb4dccbd4cdab4d031 Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Mon, 29 Sep 2025 17:57:42 +0200 Subject: [PATCH] Refactor boot with polio.com first, then polmon --- Makefile | 6 +- flat1000.ld | 20 ++++++ polio.s | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 flat1000.ld create mode 100644 polio.s diff --git a/Makefile b/Makefile index f48a8ec..68fb208 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,8 @@ fat12boot.bin: fat12boot.elf polmon.elf: LDFLAGS += -T flat1000.ld polmon.elf: polmon.o stdlib.o +polio.elf: LDFLAGS += -T flat0600.ld +polio.elf: polio.s fat12.o wozmon.o: polmon.cc wozmon.o: CPPFLAGS = -DWOZMON=1 @@ -49,8 +51,8 @@ wozmon.bin: wozmon.elf polos.img: fat12boot.bin polmon.com polio.com dd if=/dev/zero of=$@ bs=512 count=720 mformat -i $@ -t 40 -h 2 -s 9 - mcopy -i $@ polio.com ::/polio.com - mcopy -i $@ polmon.com ::/polmon.com + mcopy -i $@ polio.com ::/ + mcopy -i $@ polmon.com ::/ dd if=fat12boot.bin of=$@ conv=notrunc .PHONY: clean diff --git a/flat1000.ld b/flat1000.ld new file mode 100644 index 0000000..cfd4329 --- /dev/null +++ b/flat1000.ld @@ -0,0 +1,20 @@ +SECTIONS { + . = 0x1000; + + .text : { + KEEP(*(.init)) + *(.text*) + } + + .rodata : { + *(.rodata*) + } + + .bss (NOLOAD) : { + * (.bss) + } + + .data : { + *(.data) + } +} diff --git a/polio.s b/polio.s new file mode 100644 index 0000000..95e4045 --- /dev/null +++ b/polio.s @@ -0,0 +1,189 @@ + .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