diff --git a/Makefile b/Makefile index 4fde358..705b090 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ polmon.elf: LDFLAGS += -T flat1000.ld polmon.elf: polmon.o stdlib.o polio.elf: LDFLAGS += -T flat0600.ld -polio.elf: polio.s fat12.o +polio.elf: polio-main.o polio.s fat12.o paracomm.o wozmon.o: polmon.cc wozmon.o: CPPFLAGS = -DWOZMON=1 diff --git a/polio-main.c b/polio-main.c new file mode 100644 index 0000000..0adb3f3 --- /dev/null +++ b/polio-main.c @@ -0,0 +1,101 @@ +#include + +#include "fat12.h" +#include "paracomm.h" + +#define kFatAddr ((void*)0x1a00) +#define kRootDirAddr ((void*)0x1c00) +#define kPolmonAddr ((void*)0x1000) +#define kInt80Vector ((uint16_t*)(0x80 * 4)) +#define kParallelDataPort 0x3bc +#define kParallelStatusPort 0x3bd +#define kParallelControlPort 0x3be +#define kParaDelay 400 + +void dosdbt(); +void int80h(); + +uint8_t* parabuf; +uint8_t parasize; + +static void paracb(const uint8_t* buf, uint8_t size) { + if (size > parasize) { + return paracb(buf, parasize); + } + for (int i = 0; i < size; i++) { + parabuf[i] = buf[i]; + } + parasize = 0; +} + +static void die() { + while (1) { + } +} + +static void __outb__(uint16_t port, uint8_t data) { + register uint16_t p asm("dx") = port; + register uint8_t d asm("al") = data; + asm volatile("outb %0, %1" ::"r"(d), "r"(p)); +} + +static uint8_t __inb__(uint16_t port) { + register uint16_t p asm("dx") = port; + register uint8_t d asm("al"); + asm volatile("inb %1, %0" : "=r"(d) : "r"(p)); + return d; +} + +static void __delay__(int n) { + for (int i = 0; i < n; i++) { + asm volatile(""); + } +} + +static void paraxfer() { + uint8_t mosib = paracomm_nextbyte(); + __outb__(kParallelDataPort, mosib); + __outb__(kParallelControlPort, 1); + __delay__(kParaDelay); + __outb__(kParallelControlPort, 0); + __delay__(kParaDelay); + uint8_t mison = __inb__(kParallelStatusPort) >> 4; + paracomm_feed(mison); +} + +void pararecv(uint8_t* addr, uint8_t size) { + parabuf = addr; + parasize = size; + for (int i = 0; i < 1 + 2 + size * 2; i++) { + if (!parasize) { + break; + } + paraxfer(); + } +} + +void parasend(uint8_t* addr, uint8_t size) { + for (int i = 0; i < size; i++) { + paracomm_send(addr[i]); + } + for (int i = 0; i < size + 2; i++) { + paraxfer(); + } +} + +int main() { + dosdbt(); + paracomm_init(paracb); + + fat12_init(kFatAddr, kRootDirAddr); + + uint16_t* int80v = kInt80Vector; + int80v[0] = (uint16_t)int80h; + int80v[1] = 0; + + if (fat12_readfile("POLMON COM", kPolmonAddr)) { + die(); + } + + asm volatile("jmp *%0" ::"r"(kPolmonAddr)); +} diff --git a/polio.s b/polio.s index 95e4045..5db7ffb 100644 --- a/polio.s +++ b/polio.s @@ -5,6 +5,10 @@ .section .init .global _start _start: + cli + mov ax, 0x2000 # stack address + mov sp, ax # ss should already be 0 + sti jmp main @@ -12,7 +16,7 @@ diskpointer = 0x1e*4 dbtbase = 0x0500 .section .text.dosdbt - .local dosdbt + .global dosdbt dosdbt: # assumes es=0 push si push di @@ -103,51 +107,27 @@ formattrack: int 0x13 ret - readfile: mov ax, [bp+0] mov dx, [bp+2] call fat12_readfile ret +sendpara: + mov ax, [bp+0] + mov dx, [bp+2] + call parasend + 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 +recvpara: + mov ax, [bp+0] + mov dx, [bp+2] + call pararecv + ret .section .text.int80h + .global int80h int80h: - push bx push si push di push bp @@ -163,7 +143,7 @@ int80h: xor ah, ah mov si, ax mov bp, sp - lea bp, [bp + 18] # 12 for us, 6 for the interrupt + lea bp, [bp + 16] # 10 for us, 6 for the interrupt call [int80h_table+si] jmp 1f 0: @@ -174,10 +154,8 @@ int80h: pop bp pop di pop si - pop bx iret - .section .rodata.int80h int80h_table: .word offset copy # 0x00 @@ -185,5 +163,7 @@ int80h_table: .word offset writesector # 0x02 .word offset formattrack # 0x03 .word offset readfile # 0x04 + .word offset recvpara # 0x05 + .word offset sendpara # 0x06 int80h_entries = . - int80h_table