Refactor boot with polio.com first, then polmon

This commit is contained in:
2025-09-29 17:57:42 +02:00
parent 044e58ef12
commit dd5d329dff
3 changed files with 213 additions and 2 deletions

View File

@@ -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

20
flat1000.ld Normal file
View File

@@ -0,0 +1,20 @@
SECTIONS {
. = 0x1000;
.text : {
KEEP(*(.init))
*(.text*)
}
.rodata : {
*(.rodata*)
}
.bss (NOLOAD) : {
* (.bss)
}
.data : {
*(.data)
}
}

189
polio.s Normal file
View File

@@ -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