From ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c Mon Sep 17 00:00:00 2001 From: user Date: Sat, 18 Jul 2026 00:38:38 +0200 Subject: refactor: c/ -> usr/, compiled program blobs out of the source tree Userland sources live in usr/ (fits the Unix theme better than 'c'). SDCC output .bin blobs land in build/usr/ with the other build artifacts instead of littering the source dir; programs.asm INCBINs them from there. Byte-identical ROM. --- usr/sock.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 usr/sock.h (limited to 'usr/sock.h') diff --git a/usr/sock.h b/usr/sock.h new file mode 100644 index 0000000..876e85c --- /dev/null +++ b/usr/sock.h @@ -0,0 +1,71 @@ +#ifndef SOCK_H +#define SOCK_H +/* gbos socket API - the kernel owns SLIP/IP/ICMP/UDP/TCP; programs just do + socket()/connect()/send()/recv()/close(). Header-only: one copy per program. + The netreq layout must match include/gbos.inc (NR_* / NET_* / SOCK_*). */ +#include "gbos.h" + +#define SOCK_ICMP 1 +#define SOCK_UDP 2 +#define SOCK_TCP 3 + +struct netreq { + unsigned char op; + unsigned char sock; + unsigned char *buf; + unsigned char len; + unsigned char ip[4]; + unsigned char port_hi, port_lo; +}; +static struct netreq _nr; + +/* -> socket id, or 0xFF if the table is full */ +static unsigned char net_socket(unsigned char type) { + _nr.op = 0; _nr.sock = type; + return sys_net(&_nr); +} +/* set the remote address/port for send()/recv() */ +static unsigned char net_connect(unsigned char s, const unsigned char *ip, unsigned int port) { + unsigned char i; + _nr.op = 1; _nr.sock = s; + for (i = 0; i < 4; i++) _nr.ip[i] = ip[i]; + _nr.port_hi = (unsigned char)(port >> 8); _nr.port_lo = (unsigned char)port; + return sys_net(&_nr); +} +/* send 'len' payload bytes to the connected peer -> 0 ok / 0xFF error */ +static unsigned char net_send(unsigned char s, void *buf, unsigned char len) { + _nr.op = 2; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = len; + return sys_net(&_nr); +} +/* receive up to 'max' payload bytes -> length, or 0xFF on timeout */ +static unsigned char net_recv(unsigned char s, void *buf, unsigned char max) { + _nr.op = 3; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max; + return sys_net(&_nr); +} +/* non-blocking recv: one RX pump -> length, 0xFE if nothing buffered yet, + 0 on TCP EOF. Loop it with msleep() to own your timeout (see ping). */ +static unsigned char net_recv_nb(unsigned char s, void *buf, unsigned char max) { + _nr.op = 8; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max; + return sys_net(&_nr); +} +/* set the local (source) port - needed so UDP replies demux back to us */ +static unsigned char net_bind(unsigned char s, unsigned int port) { + _nr.op = 5; _nr.sock = s; + _nr.port_hi = (unsigned char)(port >> 8); _nr.port_lo = (unsigned char)port; + return sys_net(&_nr); +} +static void net_close(unsigned char s) { + _nr.op = 4; _nr.sock = s; sys_net(&_nr); +} +/* pump the RX path once (answers inbound pings) without blocking */ +static void net_poll(void) { + _nr.op = 6; sys_net(&_nr); +} +/* set our IPv4 address (the DHCP client calls this once it has a lease) */ +static void net_setip(const unsigned char *ip) { + unsigned char i; + _nr.op = 7; + for (i = 0; i < 4; i++) _nr.ip[i] = ip[i]; + sys_net(&_nr); +} +#endif -- cgit v1.3.1-sl0p