<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gbos.git/c/wget.c, branch master</title>
<subtitle>gbos - a tiny Unix-flavored OS for the Game Boy Color (kernel, shell, coreutils in C, RAM filesystem)</subtitle>
<id>https://git.sl0p.foo/gbos.git/atom/c/wget.c?h=master</id>
<link rel='self' href='https://git.sl0p.foo/gbos.git/atom/c/wget.c?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/'/>
<updated>2026-07-17T22:38:38Z</updated>
<entry>
<title>refactor: c/ -&gt; usr/, compiled program blobs out of the source tree</title>
<updated>2026-07-17T22:38:38Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T22:38:38Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c'/>
<id>urn:sha1:ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>net: wget-by-hostname + shared DNS resolver (a Game Boy fetches example.com)</title>
<updated>2026-07-17T11:11:53Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T11:11:53Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=a565bcd942efeb617f5424ae5a881211a7bd0216'/>
<id>urn:sha1:a565bcd942efeb617f5424ae5a881211a7bd0216</id>
<content type='text'>
resolve.h: shared helper that turns a dotted-quad or a hostname into an IPv4
address (DNS A query over a UDP socket to 1.1.1.1). nslookup now uses it and
slims down; wget uses it so you can name a host directly.

wget HOST|IP now: resolve -&gt; TCP connect -&gt; "GET / HTTP/1.0" with the real
Host header -&gt; stream the body to the LCD/console until EOF. One command does
DNS + TCP + HTTP, all on the kernel socket layer.

Verified over tunbridge's NAT against the real internet:

    /# wget example.com
    connecting 172.66.147.243
    HTTP/1.1 200 OK
    Server: cloudflare
    &lt;!doctype html&gt;&lt;html lang="en"&gt;&lt;head&gt;&lt;title&gt;Example Domain&lt;/title&gt;...
    &lt;/body&gt;&lt;/html&gt;
    [eof]

The full HTML page arrives across many TCP segments and is reassembled and
printed - real DNS, real TCP, real HTTP, fetched by a Game Boy by name.

(tunbridge.py already sets up + tears down the NAT, so the demo is a one-liner:
 sudo python3 tools/tunbridge.py "wget example.com")
</content>
</entry>
<entry>
<title>net: TCP sockets in the kernel - a Game Boy fetches HTTP over real TCP</title>
<updated>2026-07-17T11:06:38Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T11:06:38Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=c0e74377af490b93aa452a19652c61cead9c39ff'/>
<id>urn:sha1:c0e74377af490b93aa452a19652c61cead9c39ff</id>
<content type='text'>
Kernel TCP client on the socket layer: net_connect(SOCK_TCP) runs the 3-way
handshake in-kernel, send()/recv() drive the byte stream, close() does the FIN.

- Socket gains state + 32-bit snd_nxt/rcv_nxt (big-endian, add-with-carry-fold).
- tcp_send_seg builds IP+TCP with a pseudo-header checksum; the SYN carries an
  MSS option (200) so the peer never sends a segment larger than our 256-byte
  frame buffer (we don't do IP reassembly).
- tcp_in state machine: SYN_SENT-&gt;ESTABLISHED on SYN-ACK, buffers in-order data
  and ACKs it, handles FIN -&gt; recv() returns 0 (EOF).
- No retransmission: the GB&lt;-&gt;host link is lossless and the host's real TCP
  owns the internet side - which removes TCP's hardest part.
- net_pump now processes one frame per call so recv drains each segment before
  the next arrives (single rx slot, no overwrite).

wget.c is now a thin socket client: connect -&gt; send "GET / HTTP/1.0" -&gt; recv to
EOF -&gt; print. Verified end to end against a host HTTP server:

    /# wget 10.0.0.1
    HTTP/1.0 200 OK
    Hello from a real HTTP server, fetched by a Game Boy!

with a clean SYN/SYN-ACK/ACK ... PSH ... FIN/ACK trace on the wire.
</content>
</entry>
<entry>
<title>net: wget - real HTTP over the link port via the gateway</title>
<updated>2026-07-16T23:31:38Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T23:31:38Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=62171c761c72f7bc515b20361d043bfd239f71c9'/>
<id>urn:sha1:62171c761c72f7bc515b20361d043bfd239f71c9</id>
<content type='text'>
Grow the link-port demo from echo to actual network access. The Game Boy
still only does SLIP framing + display; the host gateway does DNS/TCP/HTTP.

- c/netlib.h: SLIP framing factored out (header-only, per-program copy).
  necho.c now uses it too.
- c/wget.c: `wget URL` frames the URL, then prints the reply body. The
  gateway streams the body back as typed frames: 'D'&lt;chunk&gt; ... 'E'.
- tools/gateway.py: add --mode http (urlopen the frame as a URL, cap the
  body, chunk it) alongside --mode echo; --cmd runs any gbos command.

Verified: `wget example.com` streams back the full Example Domain HTML onto
the terminal; `wget sl0p.foo` fetches the real page. A Game Boy on the web,
over the link cable.
</content>
</entry>
</feed>
