aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: d0c3e8b798cd9cd7ee6d997b5cf08083a3e25242 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# gbos

A tiny **Unix-flavored OS for the Game Boy Color** — a from-scratch cooperative
microkernel with fork/exec, a shell with pipes, a persistent filesystem, a
color terminal on the LCD, and a **real TCP/IP stack over the link cable**.
It boots, gets a DHCP lease, pings, resolves DNS, fetches web pages, and hangs
out on IRC. On a 1997 handheld (well, an emulated one).

![gbos: boot, ping, IRC — all on a Game Boy Color](demo/gbos-demo.gif)

*Real capture: cold boot → DHCP lease → `ping` → an IRC session, typed live
into the on-screen console. Regenerate it anytime with `tools/gbdemo` (below).*

## What's in the box

- **Processes, the V7 way**: `fork`/`exec`/`wait`/`exit`, zombies + reaping,
  background jobs (`spin &`), `ps`, `kill` — round-robin cooperative
  scheduling across banked memory with an HRAM context switch.
- **A shell** (written in C, running *on* the GB) with I/O redirection
  (`>` `<` `>>`) and pipes (`|`), argument passing, and a cwd-aware prompt —
  with `grep` to put on the other end of the pipe, `tee` to fork it, and
  `more` to page anything longer than the 18-row screen.
- **Shell scripts**: a shell fed from a file (`sh < script`) runs it with no
  prompt and no echo, and init runs **`/rc`** at boot if the cart has one —
  so a Game Boy can come up with its own startup script.
- **Networking, for real**: the kernel owns SLIP over the link port, IPv4,
  ICMP, UDP and TCP; userland gets BSD-ish sockets via one syscall. On top:
  `dhcp` (boot-time lease), `ping`, `nslookup` (real DNS), `wget` (HTTP),
  `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`, one
  socket per client), so the Game Boy runs daemons. `httpd` puts the cart's
  filesystem on the web — `httpd &`, then point a browser at it: files come
  from battery-backed RAM, directories as clickable listings. `ircd` is a
  real IRC server — `ircd &`, then `irssi -c 10.0.0.2`: NICK/USER/JOIN/
  PRIVMSG/PING/NAMES/PART/QUIT, with the channel relayed between clients.
  A laptop and a second Game Boy can sit in the same channel, hosted by a
  Game Boy.
- **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
  `tools/gbtype` types into any GB's shell from the host.
- **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 (files up to 3 KiB).
  `ls -l` and `df` report sizes and free space; `poweroff` is the only safe
  way to stop the machine (the battery save is written on a clean exit).
- **`/bin` in the tree**: the builtins are not files on the disk, but they
  show up as one anyway — `ls /bin` enumerates the kernel's own command
  table, `cd /bin` works, and `xxd -l 16 /bin/uname` dumps the program's ROM
  bank. Read-only, since it is ROM.
- **A C toolchain**: userland is plain C compiled with SDCC (`sm83`); ~50
  tools ship in `usr/` (`cat`, `wc`, `head`, `tail`, `grep`, `cp`, `mv`,
  `tee`, `tr`, `cut`, `uniq`, `rev`, `more`, `ls`, `df`, `xxd`,
  `touch`, `sleep`, `uptime`, …) — `help` lists them all on
  the Game Boy itself. Adding a program is one `.c` file + a table entry.

## Quick start

```sh
git config core.hooksPath hooks        # once: clang-format pre-commit hook
make                                   # -> gbos.gb  (needs RGBDS + SDCC)

# solo, in the sl0pboy emulator (~/dev/gbc):
~/dev/gbc/build/sl0pboy --sixel 3 --chrome gbos.gb

# networked — hub in one terminal, Game Boys in others:
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

# or host an IRC network on it:
tools/gbtype 'ircd &'                  # then, from the host:
irssi -c 10.0.0.2                      # /join #gbos
tools/gbtype -g 1 'irc 10.0.0.2 gb2'   # a second GB joins the same channel
```

On the Game Boy: **SELECT** toggles the on-screen keyboard, d-pad + **A**
types, **START** sends the line.

```
/# uname -a
gbos sm83 (Game Boy Color)
/# ping 10.0.0.1
PING 10.0.0.1
  reply from 10.0.0.1 seq=1
  ...
-- 4/4 received
/# irc 10.0.0.1 sl0pboy
-!- registering as sl0pboy (SELECT = keyboard)
```

## The demo GIF

The GIF above is produced by a scripted, self-syncing demo driver:
`tools/gbdemo` runs a step file (`demo/readme.gbd`), injects console text and
button events at the right moments — syncing on the *actual screen contents*
(the terminal's WRAM shadow, read over the emulator's debug socket) rather
than timers — while the emulator records every frame, then renders the GIF:

```sh
sudo tools/gbhub --daemon              # network up (once)
tools/gbdemo demo/readme.gbd           # inside tmux; writes demo/gbos-demo.gif
```

Edit `demo/readme.gbd` to choreograph your own (verbs: `type`, `slowtype`,
`key`, `waitfor`, `record`, `gif`, …).

## Docs

- [docs/internals.md](docs/internals.md) — the full technical breakdown:
  memory model, syscall ABI, fork/exec/context-switch internals, the network
  stack, the filesystem layout, C toolchain notes, war stories, roadmap.

Built and tested against the [sl0pboy](../gbc) emulator; runs on anything that
emulates a CGB + MBC5 cartridge with battery RAM. No MMU, no protection, no
regrets.