From 2ba1546dec3ca866d3eec92397c675c355b6ac4d Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Wed, 1 Oct 2025 23:24:59 +0200 Subject: [PATCH] Refactor parallel comms a bit --- Makefile | 4 ++- ftp.asm | 28 +++++++++++++++------ mushroom.s | 70 +++++++++++++++++++--------------------------------- paracomm.c | 26 ++++++++++++++----- paracomm.h | 12 ++++++--- polio-main.c | 40 ++++++++++++------------------ polio.s | 3 ++- stdlib.c | 20 +++++++++++++++ 8 files changed, 116 insertions(+), 87 deletions(-) diff --git a/Makefile b/Makefile index 597d503..e8dd3bc 100644 --- a/Makefile +++ b/Makefile @@ -31,11 +31,13 @@ fat12boot.elf: LDFLAGS += -T bootsect.ld fat12boot.bin: fat12boot.elf +stdlib.o: CFLAGS := $(filter-out -flto, $(CFLAGS)) + polmon.elf: LDFLAGS += -T flat1000.ld polmon.elf: polmon.o stdlib.o polio.elf: LDFLAGS += -T flat0600.ld -polio.elf: polio-main.o polio.s fat12.o paracomm.o +polio.elf: polio-main.o polio.s fat12.o paracomm.o stdlib.o wozmon.o: polmon.cc wozmon.o: CPPFLAGS = -DWOZMON=1 diff --git a/ftp.asm b/ftp.asm index 269fbd4..99a26ef 100644 --- a/ftp.asm +++ b/ftp.asm @@ -1,6 +1,7 @@ CPU 8086 chunksize equ 0x20 +devicedelay equ 0x08 _start: push bp @@ -13,24 +14,35 @@ _start: mov bx, [bp-8] mov [bx], byte 0x42 l0: - cmp word [bp-4], 0xf400 + cmp word [bp-4], 0xf600 jb l1 - add sp, 8 +l2: + mov sp, bp pop bp ret l1: + mov ah, 0x07 + int 0x80 + test al, al + jnz l1 push word [bp-2] push word [bp-4] mov ah, 0x05 int 0x80 - add sp, 4 + test al, al + jz l2 + mov ah, 0 + add [bp-4], ax push word [bp-6] push word [bp-8] mov ah, 0x06 int 0x80 - add sp, 4 - add word [bp-4], chunksize - mov cx, 0x200 -l2: dec cx - jnz l2 + add sp, 8 + mov cx, devicedelay +l3: + mov ah, 0x07 + push cx + int 0x80 + pop cx + loop l3 ; give the device some time to answer jmp l0 diff --git a/mushroom.s b/mushroom.s index 48f7448..76a100e 100644 --- a/mushroom.s +++ b/mushroom.s @@ -16,13 +16,14 @@ _start: .section .bss kBufSize = 77 -kParaDelay = 500 kDividerRow = 23 +kRecvBufSize = 128 curpos: .word 0 inputsize: .byte 0 escaped: .byte 0 inputbuf: .zero kBufSize +recvbuf: .zero kRecvBufSize # XXX: funky call # inputs: @@ -109,15 +110,6 @@ addtext: pop di ret - .section .text.paracb -paracb: - push si - mov si, ax - mov cl, dl - call addtext - pop si - ret - .section .text.sendbuffer sendbuffer: push bp @@ -167,22 +159,17 @@ drawchar: .section .text.parasend parasend: -1: - test cl, cl - jz 0f - mov al, [si] + mov ah, 0x06 # send parallel push cx - call paracomm_send - pop cx - test al, al - jnz 2f - inc si - dec cl - jmp 1b -0: - mov al, '\n' - call paracomm_send -2: + push si + int 0x80 + mov cx, 1 + push cx + mov cx, offset .l1 + 1 + push cx + mov ah, 0x06 # send parallel + int 0x80 + add sp, 8 ret prompt: @@ -212,8 +199,6 @@ main: movb escaped, 0 mov ax, 0x0002 int 0x10 - mov ax, offset paracb - call paracomm_init mov si, offset .l2 mov cl, l2len call addtext @@ -259,21 +244,18 @@ main: 4: call sendbuffer # send input buffer 1: - call paracomm_nextbyte - mov dx, 0x3bc - out dx, al - add dl, 2 - mov al, 1 - out dx, al - mov cx, kParaDelay -2: loop 2b - mov al, 0 - out dx, al - mov cx, kParaDelay -3: loop 3b - dec dl - in al, dx - mov cl, 4 - shr al, cl - call paracomm_feed + mov ah, 0x07 # do parallel comms + int 0x80 + mov ax, kRecvBufSize + push ax + mov ax, offset recvbuf + push ax + mov ah, 0x05 # recv + int 0x80 + test al, al + mov cl, al + pop si + pop bx + jz 0b + call addtext jmp 0b diff --git a/paracomm.c b/paracomm.c index fb140ce..88a1493 100644 --- a/paracomm.c +++ b/paracomm.c @@ -1,6 +1,7 @@ #include "paracomm.h" #include +#include #define kMosiIdleByte 0x00 #define kMosiStartByte 0x42 @@ -21,7 +22,6 @@ static uint8_t miso_recvbuf[256]; static uint8_t miso_size; static uint8_t miso_received_nibbles; static uint8_t miso_state; -static void (*miso_cb)(const uint8_t*, uint8_t); static void swapbuffers() { mosi_sendbuf = mosi_workbuf[mosi_workbuf_idx]; @@ -92,23 +92,19 @@ void paracomm_feed(uint8_t n) { miso_received_nibbles += 1; if (miso_received_nibbles == 2 * miso_size) { - if (miso_cb != 0) { - miso_cb(miso_recvbuf, miso_size); - } miso_state = 0; } } break; } } -void paracomm_init(miso_cb_t cb) { +void paracomm_init() { mosi_size = 0; mosi_workbuf_idx = 0; mosi_workbuf_size = 0; mosi_state = 0; miso_state = 0; - miso_cb = cb; } int paracomm_send(uint8_t b) { @@ -122,3 +118,21 @@ int paracomm_send(uint8_t b) { return 0; } + +uint8_t paracomm_recv(uint8_t* buf, uint8_t size) { + if (miso_state != 0) { + return 0; + } + if (size > miso_size) { + size = miso_size; + } + memcpy(buf, miso_recvbuf, size); + memcpy(miso_recvbuf, miso_recvbuf+size, miso_size - size); + miso_size -= size; + + return size; +} + +uint8_t paracomm_busy() { + return mosi_state != 0 || miso_state != 0; +} diff --git a/paracomm.h b/paracomm.h index f150163..4b5930c 100644 --- a/paracomm.h +++ b/paracomm.h @@ -2,18 +2,24 @@ #include -typedef void (*miso_cb_t)(const uint8_t* buff, uint8_t size); - /** Must call first **/ -void paracomm_init(miso_cb_t miso_cb); +void paracomm_init(); /** Sends a single byte. * Returns: 0 if no error, non-0 otherwise. */ int paracomm_send(uint8_t b); +/** Receive some bytes. + * Returns: number of bytes copied + */ +uint8_t paracomm_recv(uint8_t* buf, uint8_t size); + /** Call after reading a nibble from the port */ void paracomm_feed(uint8_t n); /** Yields the next byte to send out the port */ uint8_t paracomm_nextbyte(); + +/** Returns non-zero if busy */ +uint8_t paracomm_busy(); diff --git a/polio-main.c b/polio-main.c index 0adb3f3..d94a186 100644 --- a/polio-main.c +++ b/polio-main.c @@ -1,4 +1,6 @@ #include +#include +#include #include "fat12.h" #include "paracomm.h" @@ -11,21 +13,18 @@ #define kParallelStatusPort 0x3bd #define kParallelControlPort 0x3be #define kParaDelay 400 +#define kRecvBufferSize 256 void dosdbt(); void int80h(); -uint8_t* parabuf; +uint8_t parabuf[kRecvBufferSize]; 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; + // we'll mercilessly erase old data with new data + memcpy(parabuf, buf, size); + parasize = size; } static void die() { @@ -52,7 +51,7 @@ static void __delay__(int n) { } } -static void paraxfer() { +uint8_t xferpara() { uint8_t mosib = paracomm_nextbyte(); __outb__(kParallelDataPort, mosib); __outb__(kParallelControlPort, 1); @@ -61,30 +60,23 @@ static void paraxfer() { __delay__(kParaDelay); uint8_t mison = __inb__(kParallelStatusPort) >> 4; paracomm_feed(mison); + + return paracomm_busy(); } -void pararecv(uint8_t* addr, uint8_t size) { - parabuf = addr; - parasize = size; - for (int i = 0; i < 1 + 2 + size * 2; i++) { - if (!parasize) { +uint8_t parasend(uint8_t* addr, uint8_t size) { + uint8_t i; + for (i = 0; i < size; i++) { + if (paracomm_send(addr[i])) { 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(); } + return i; } int main() { dosdbt(); + parasize = 0; paracomm_init(paracb); fat12_init(kFatAddr, kRootDirAddr); diff --git a/polio.s b/polio.s index 49ea080..6865d11 100644 --- a/polio.s +++ b/polio.s @@ -143,7 +143,7 @@ recvpara: mov ax, [bp+0] add ax, si mov dx, [bp+2] - call pararecv + call paracomm_recv ret .section .text.int80h @@ -186,5 +186,6 @@ int80h_table: .word offset readfile # 0x04 .word offset recvpara # 0x05 .word offset sendpara # 0x06 + .word offset xferpara # 0x07 int80h_entries = . - int80h_table diff --git a/stdlib.c b/stdlib.c index e3ccc1f..2f2949a 100644 --- a/stdlib.c +++ b/stdlib.c @@ -1,3 +1,6 @@ +#include +#include + int getchar() { register char c asm("al"); asm volatile("movb $0x00, %%ah\n\t" @@ -23,3 +26,20 @@ int puts(const char* s) { } return 0; } + +void* memcpy(void* dest, const void* src, size_t n) { + uint8_t* d = dest; + const uint8_t* s = src; + for (int i = 0; i < n; i++) { + d[i] = s[i]; + } + return dest; +} + +void* memset(void* ptr, int val, size_t len) { + uint8_t* p = ptr; + while (len--) { + *p++ = val; + } + return ptr; +}