From c4b9a1b1c4f8c211f765a089b34b66a2d046f3be Mon Sep 17 00:00:00 2001 From: user Date: Fri, 17 Jul 2026 01:39:29 +0200 Subject: net: chat client - async receive + OSK send over the link port The application layer of the link-port demo, and it ties the whole system together: the LCD terminal displays, the on-screen keyboard types, and the link port carries a live chat. Kernel: sys_srecv_nb (non-blocking link receive; A=byte, CF=none) and sys_pollin (poll the OSK for a typed char without blocking) - syscalls 31/32. Both are what a poll loop needs to receive and type at once. Userland: c/chat.c runs a poll loop - it feeds non-blocking bytes through a SLIP receive state machine and prints whole incoming frames as messages, while pollin() drives the on-screen keyboard; SELECT shows the keys, type a line, START sends it as a frame. libc srecv_nb()/pollin(). Host: tools/gateway.py --mode chat is a simple bot peer (echoes each GB message and injects a few async ones); --keys can drive the OSK for tests. Verified: the gateway pushes 'welcome', ' hey gameboy!', ' nice link cable' unprompted and the GB displays all three (async receive); typing 'hi' on the OSK echoes it and emits the SLIP frame \xC0hi\xC0 (send). A Game Boy in the chat, keyboard on screen, over the link cable. --- c/libc.s | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'c/libc.s') diff --git a/c/libc.s b/c/libc.s index 50d7860..7897a79 100644 --- a/c/libc.s +++ b/c/libc.s @@ -1,6 +1,6 @@ .module libc .globl _writes, _putc, _puts, _nl, _strlen, _readc, _sexit, _getpid, _getargs - .globl _open, _close, _fgetc, _fputc, _flist, _fremove, _pipe, _ssend, _srecv + .globl _open, _close, _fgetc, _fputc, _flist, _fremove, _pipe, _ssend, _srecv, _srecv_nb, _pollin ;; SDCC sm83 sdcccall(1): 1st arg -> A (byte) or DE (pointer); ret A / BC. ;; rst $30 (the trap) clobbers BC/DE/HL; SDCC treats them caller-saved, so ;; wrappers need not preserve them - but we compute cleanly regardless. @@ -105,6 +105,23 @@ _srecv: rst #0x30 ret + ;; int srecv_nb(void) -> byte, or -1 if none (non-blocking) +_srecv_nb: + ld c, #31 ; SYS_SRECVNB + rst #0x30 + jr c, 1$ + ld c, a + ld b, #0 + ret +1$: ld bc, #0xffff + ret + + ;; unsigned char pollin(void) -> A (typed OSK char, or 0) +_pollin: + ld c, #32 ; SYS_POLLIN + rst #0x30 + ret + ;; unsigned char open(const char *name /*DE*/, unsigned char mode /*A*/) -> A(fd) _open: ld b, a ; B = mode -- cgit v1.3.1-sl0p