diff options
| author | user <user@clank> | 2026-09-22 17:12:52 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-22 17:12:52 +0200 |
| commit | 30e67fe0f4e66e2161ca61f870f8947d50287995 (patch) | |
| tree | a04189f34687a4d600903100feca18aedc5d1604 /README.md | |
| parent | net: passive open (listen/accept) + own sockets + close promptly (diff) | |
| download | gbos-30e67fe0f4e66e2161ca61f870f8947d50287995.tar.gz gbos-30e67fe0f4e66e2161ca61f870f8947d50287995.tar.xz gbos-30e67fe0f4e66e2161ca61f870f8947d50287995.zip | |
usr: httpd - the Game Boy serves its filesystem over HTTP
/# httpd &
host$ curl http://10.0.0.2/ -> a listing of the cart RAM
host$ curl http://10.0.0.2/readme -> the file, from battery-backed SRAM
GET only. "/" serves /index.html if present, else a generated listing; any
directory lists with every entry linked, so you can click around a 1997
handheld's disk from a browser. Content type from the extension. No
Content-Length: HTTP/1.0 + Connection: close delimits the body by closing,
which suits a stack with one in-flight segment.
All output goes through one 200-byte buffer, so each net_send is a full
segment instead of one tiny segment per string.
It drains the whole request, not just the request line. That is not
politeness: leaving the rest unread means those segments are never
acknowledged, so the client retransmits headers for a minute, never sends
its FIN, and its dead connection keeps arriving at port 80 long after we
re-listen. One curl with 1.4 KB of headers stalled every following request
for 30-120s.
It deliberately does NOT read the keyboard either. Backgrounded - the useful
way to run it - every key it polled would be a key stolen from the shell's
prompt. It is a daemon: kill(1) stops it, and the kernel reclaims its socket.
Verified with curl: index, byte-exact file bodies, nested paths, directory
listings, 404, 501, a 1.4 KB request spanning segments, browser user-agents,
three parallel clients (0.1/1.1/2.1s), the shell staying usable alongside it,
and six kill/restart cycles - more than there are sockets.
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -26,6 +26,10 @@ into the on-screen console. Regenerate it anytime with `tools/gbdemo` (below).* `nc` (netcat: `nc HOST PORT` interactively, or `nc -s HOST PORT < file` to pipe a request in and print the reply), `chat`, and a colorized **IRC client** (`irc HOST [NICK]`, `/join` and friends, SELECT for the keyboard). +- **It serves, too**: the kernel does passive opens (`listen`/`accept`), and + `httpd` puts the cart's filesystem on the web — `httpd &`, then point a + browser at the Game Boy: files are served from battery-backed RAM and + directories come back as clickable listings. - **A network to plug into**: `tools/gbhub` is a virtual switch + DHCP server + NAT gateway — spawn a fleet of Game Boys that ping *each other* and reach the real internet; `tools/gbjoin` attaches an interactive GB to it, and @@ -33,7 +37,7 @@ into the on-screen console. Regenerate it anytime with `tools/gbdemo` (below).* - **40×18 color terminal** on the LCD (4×8 font, two chars per tile, ANSI-ish colors) + an **on-screen keyboard** on the window layer (SELECT toggles it). - **Persistent filesystem** on battery-backed cart RAM: inodes, nested - directories, per-process cwd — survives power-off. + directories, per-process cwd — survives power-off (files up to 3 KiB). - **A C toolchain**: userland is plain C compiled with SDCC (`sm83`); ~35 tools ship in `usr/` (`cat`, `wc`, `head`, `grep`, `cp`, `more`, `ls`, `uptime`, …). Adding a program is one `.c` file + a table entry. @@ -51,6 +55,10 @@ make # -> gbos.gb (needs RGBDS + SDCC) sudo tools/gbhub --daemon # virtual net + DHCP + NAT (needs root) tools/gbjoin # a windowed GB joins 10.0.0.0/24 tools/gbtype 'ping 10.0.0.3' # or type into it from the host + +# serve the Game Boy's filesystem to your browser: +tools/gbtype 'httpd &' # then open http://10.0.0.2/ +curl http://10.0.0.2/readme # files straight out of cart RAM ``` On the Game Boy: **SELECT** toggles the on-screen keyboard, d-pad + **A** |
