KN-86 Legacy Terminal — DOS Easter Egg Research Memo
Notion task: GWP-269
Personal-enjoyment feature for Josh’s own device. Not a marketed capability. No GTM, no public launch blurb.
A hidden Legacy Terminal mode on the KN-86 — entered via a Bare Deck SYS-tab gesture, modelled on the ADR-0011 updater ritual — is feasible. Architecture is mode-swap, not co-execution: nOSh suspends, hands the framebuffer/input/audio to the child process, and resumes on exit. Of the four candidate titles, only one actually needs DOSBox — the other three have well-maintained native ARM Linux builds.
| Title | Run target | License | Verdict |
|---|---|---|---|
| NetHack 3.6.7 | Native ARM Linux | NGPL (free, source-available) | Bundle |
| Umoria 5.7.x | Native ARM Linux | GPL-3.0-or-later | Bundle |
| DrugWars (original 1984) | DOSBox | No license — Dell holds copyright | Side-load only; bundle a clean substitute (Dopewars, GPL-2) instead |
| NFL Challenge (1985) | DOSBox | Abandonware — XOR Corp defunct, rights ambiguous | Side-load only |
Headline architectural call: white-label DOSBox Staging in /opt/legacy-terminal/ on the read-only rootfs, native binaries (NetHack, Umoria, Dopewars) alongside it. Save state lands on /home/shared/legacy-terminal/saves/ (p6) so it survives every A/B slot swap, matching the Universal Deck State convention from ADR-0011. Audio is muted by default in v1 — none of these titles need it.
Per-title profiles
Section titled “Per-title profiles”1. NetHack 3.6.7 — BUNDLE
Section titled “1. NetHack 3.6.7 — BUNDLE”- License / IP: NetHack General Public License (NGPL), derived from the Bison GPL (1989, M. Stephenson). Distribute object code provided source is available on request. Pull source from nethack.org, build during
stage-kn86-runtime, ship the source tarball alongside the binary. No royalty, no rights-holder negotiation. - Best run target: Native ARM Linux build via Unix make +
hints/linux. Last maintained 3.6.7 (2023); 3.7-dev is active. Snap also ships an ARM build; baking from source is preferred for footprint and reproducibility. - Display fit: Native 80×25 text, ASCII + box-drawing. Uses tty curses output. CP437 box-drawing is already in the KN-86 font ROM per
character-set.md. Flatten the 16-color tty palette to amber via a strippedTERMprofile (ornethack -X). - Input: Movement is the gating concern.
OPTIONS=number_pad:1maps numpad 1–9 →b j n h _ l y k u— calculator layout; KN-86 is phone-style (ADR-0016§5). Fix is a thin firmware shim that translates phone-numpad scancodes → calculator-numpad keysyms before the child PTY sees them. Letter commands (i,,,?) ride on a 14-key F-key overlay covering ~80% of normal play; rare commands fall back to Nokia multi-tap (ADR-0016§6). - Text-entry needs: Minimal — character name, pets, save-file selection. Multi-tap suffices.
- Audio: Silent by default. Mute.
- Pi Zero 2 W viability: Trivial — ~3 MB compiled, single-digit-percent CPU on Pi 3-class hardware.
- Verdict — BUNDLE. Clean license, straightforward build, fits the platform with one input shim.
2. Umoria 5.7.x — BUNDLE
Section titled “2. Umoria 5.7.x — BUNDLE”- License / IP: GPL-3.0-or-later since David Grabiner relicensed Moria 5.6 in 2008. Clone dungeons-of-moria/umoria, build during
stage-kn86-runtime, ship source archive — same compliance pattern as NetHack. - Best run target: Native ARM Linux via CMake. Standard C++17 + ncurses builds clean on aarch64 Debian. Last release 5.7.x.
- Display fit: Native 80×24 text — one row narrower than our 80×25, fits cleanly with a single dead bottom row. Same CP437 + amber-flatten story as NetHack.
- Input: Two schemes — original (calculator numpad 7-8-9 / 4-6 / 1-2-3) and roguelike (vi-keys
yhjklbn). Same remap-shim as NetHack handles the numpad path; F-key overlay covers letter commands (i,w,r). - Text-entry needs: Minimal — character name, save slot, occasional inscriptions. Multi-tap.
- Audio: Silent. Mute.
- Pi Zero 2 W viability: Trivial — single-binary curses app, static dungeon generator.
- Verdict — BUNDLE. GPL-3 is the simplest compliance story on this list; shares the remap table with NetHack.
3. DrugWars — SIDE-LOAD ONLY (bundle Dopewars instead)
Section titled “3. DrugWars — SIDE-LOAD ONLY (bundle Dopewars instead)”- License / IP: John E. Dell wrote the original on a TRS-80 in 1984 and ported to DOS. No formal license — Dell retains copyright; the game spread via unauthorized BBS upload and has been gray-area ever since. The DOS Games Archive and Internet Archive carry copies, but neither holds redistribution rights. Bundling the original is not clean.
- Recommended substitute: Dopewars (Ben Webb, dopewars.sourceforge.net) — GPL-2, native Linux curses port, mechanically faithful, packaged in Debian. Bundle Dopewars in place of DrugWars.
- Best run target (Dopewars): Native ARM Linux. Builds clean on Raspberry Pi OS arm64. Older upstream release (~2016) but Debian package tree is current.
- Display fit: Native curses 80×24, mostly menu-driven, no graphics mode. Trivial.
- Input: Pure menu navigation. Phone-numpad 8/2/5 maps directly — no calculator remap needed. Letter commands ride F-key overlay. Easiest input fit of the four.
- Text-entry needs: Player name on startup. Multi-tap.
- Audio: Silent. Mute.
- Pi Zero 2 W viability: Trivial.
- Verdict — SIDE-LOAD ONLY for original DrugWars; BUNDLE Dopewars. Label the launcher entry “DOPEWARS (DrugWars-like)” with one-line attribution to Dell.
4. NFL Challenge — SIDE-LOAD ONLY
Section titled “4. NFL Challenge — SIDE-LOAD ONLY”- License / IP: Released by XOR Corporation in 1985; XOR dissolved in the early 1990s after announcing an unshipped Premium Edition. No successor rights holder is documented. Catalogued on abandonware sites (MyAbandonware, Old-Games.com) but abandonware is a community convention, not a license. NFL trademark exposure is also live. Do not bundle.
- Best run target: DOSBox Staging. No native port exists; the 28-team statistical engine depends on DOS interrupt-level behaviour. DOSBox is the only path.
- Display fit: DOS text mode + partial CGA graphics for the play diagram (X’s and O’s overhead). Text mode is 80×25 native. Color screens flatten to brightness-modulated amber on our display.
- Input: Menu-driven, keyboard-canonical. Digits select play numbers; Enter confirms; Esc backs out. Phone-numpad maps directly to digits. F-keys cover Enter / Esc / time-out / two-minute drill / substitutions. Lowest input demand of the four.
- Text-entry needs: None during play. Roster names are pre-loaded.
- Audio: PC speaker at most. Mute.
- Pi Zero 2 W viability: DOSBox Staging’s ARM64 dynarec is improving but has documented performance issues on Pi 4/5 — the upstream report (dosbox-staging issue #3152) was filed against bookworm; KN-86 now targets Debian 13 trixie per ADR-0026, and Stage 0 bring-up will re-validate the dynarec on the trixie kernel. NFL Challenge is a 1985 text-mode title and community reports confirm pre-1990 DOS games run on the original Pi Zero. Pi Zero 2 W (quad A53 @ 1 GHz) is Pi 3-class; Pi 3 with DOSBox emulates ~60 MHz 486 — 6× margin over what this game needs. Should run, bench-test before committing.
- Verdict — SIDE-LOAD ONLY. Ship DOSBox + a stub launcher entry; the user drops
.EXE+ data on/home/shared/legacy-terminal/sideloads/. Device stays clean of contested IP, easter egg preserved.
Architecture sketch — nOSh ↔ Legacy Terminal handoff
Section titled “Architecture sketch — nOSh ↔ Legacy Terminal handoff”Suspend / handoff
Section titled “Suspend / handoff”When the player triggers the entry gesture, nOSh:
- Releases the SDL framebuffer by closing the KMSDRM context (the same path used during a graceful shutdown, with a re-open path on resume).
- Releases the evdev input grab on
/dev/input/event*so the child process can claim it via standard ncurses / SDL input. - Mutes audio: sends a single UART command (
PSG_SILENCE) to the Pico 2 coprocessor per thecoprocessor-protocol.mdspec; the Pico stops emitting on I2S. v1 audio policy is mute. - Pauses HUD render loop: rows 0/24 stop being drawn. The full 80×25 grid is the child’s canvas for the duration of the session — mode-specific, not a canonical-spec change.
- Spawns the child with
posix_spawnunder the samenoshuser, no privilege change. Child PID and start time recorded for the resume gate.
Launcher selection — Bare Deck SYS-tab gesture
Section titled “Launcher selection — Bare Deck SYS-tab gesture”Per the GWP-269 brief, the launcher surface is a hidden Bare Deck SYS-tab gesture, modelled on the SYS+LINK updater pattern from ADR-0011. From the bare-deck terminal (no cartridge loaded), holding SYS and tapping INFO four times in sequence enters the Legacy Terminal launcher. Specific gesture is tunable; the principle is: not discoverable accidentally, not advertised in any UI string, but reproducible once known.
The launcher renders a four-entry menu:
LEGACY TERMINAL > NETHACK 3.6 UMORIA 5.7 DOPEWARS SIDE-LOAD...Each entry is backed by a small TOML manifest in /opt/legacy-terminal/titles/<id>.toml declaring binary path, working directory, save directory, input-remap profile (which numpad shim to apply, F-key overlay to install). SIDE-LOAD... opens a picker against /home/shared/legacy-terminal/sideloads/ listing user-supplied DOS executables and routing them through DOSBox Staging.
Resume
Section titled “Resume”Child exit returns to the launcher (or directly to Bare Deck if exit was from the launcher itself):
- Wait on child via
SIGCHLD. Capture exit code (logged to/tmp/legacy-terminal.logfor debugging). - Reclaim framebuffer / evdev / audio in the inverse order they were released. Pico 2 receives
PSG_RESUME. - HUD wake — rows 0 and 24 redraw.
- nOSh state restored from in-memory snapshot taken at suspend; mission board, phase chain, deck state untouched (Legacy Terminal never wrote to p6 in any path other than
/home/shared/legacy-terminal/saves/).
Storage layout
Section titled “Storage layout”/opt/legacy-terminal/ (read-only rootfs, baked in stage-kn86-runtime)├── bin/│ ├── nethack│ ├── umoria│ ├── dopewars│ └── dosbox-staging (white-labeled launcher chrome)├── share/│ ├── nethack/ (game data)│ ├── umoria/│ └── dopewars/├── titles/│ ├── nethack.toml│ ├── umoria.toml│ ├── dopewars.toml│ └── sideload-dosbox.toml├── LICENSE (DOSBox GPL, NGPL, Umoria GPL-3, Dopewars GPL-2)└── src/ (source archives — GPL/NGPL compliance)
/home/shared/legacy-terminal/ (p6, persists across A/B slot swaps)├── saves/│ ├── nethack/│ ├── umoria/│ └── dopewars/└── sideloads/ (user-dropped DOS executables for DOSBox)Footprint estimate: NetHack ~3 MB, Umoria ~2 MB, Dopewars ~1 MB, DOSBox Staging ~30 MB, source archives ~10 MB. Under 50 MB total, comfortable inside the rootfs partition (p4/p5 split per ADR-0011 and system-image-build.md).
DOSBox white-label feasibility
Section titled “DOSBox white-label feasibility”Base recommendation: DOSBox Staging. Active fork (dosbox-staging on GitHub), modern ARM64 dynarec work, ongoing performance improvements. Upstream DOSBox is mature but slow-cadence; DOSBox-X is feature-heavy and overkill for our four-title side-load surface. Pin to a tagged release of DOSBox Staging in tools/sd-provision/pi-gen-pin.env (matching the kernel/pi-gen pin pattern).
GPL compliance — concrete steps:
- Ship
LICENSEat/opt/legacy-terminal/LICENSEcontaining the GPL-2 text (DOSBox), GPL-3 text (Umoria), GPL-2 text (Dopewars), and NGPL text (NetHack), with attribution headers per project. - Ship the modified source at
/opt/legacy-terminal/src/dosbox-staging-<version>.tar.gzalongside the binary. GPL §3a (machine-readable source accompanying object code) is the simplest compliance form. - Restrict modifications to launcher chrome only — splash screen text, branded amber color profile, autoexec hooks for the title manifests. The DOSBox engine, CPU core, and audio path stay upstream-pristine. This keeps source-availability obligations narrow and review-friendly.
- Add a
DOSBox by The DOSBox Team — GPL-2credit line to the launcher splash so attribution is operator-visible, not just buried inLICENSE.
Pi Zero 2 W build viability: DOSBox Staging builds on aarch64 Debian via standard meson / ninja. Bench-flag the dynrec_arm64 core selection in dosbox-staging.conf (it’s the post-2024 path that supersedes the older dynamic core on ARM). Audio underrun on slow SD cards is a documented gotcha — mitigated by our v1 mute policy. Performance for pre-1990 text-mode titles on Pi 3-class CPU is well-attested; bench-test NFL Challenge specifically before declaring side-load support, since it’s the only DOSBox-dependent title in scope.
Open questions / risks
Section titled “Open questions / risks”These need a decision before any implementation work begins.
-
Audio routing in v2. v1 mutes during Legacy Terminal. If we ever want PC-speaker / AdLib audio routed to MAX98357A, the Pico 2 needs a “PCM passthrough” mode, or device-tree needs to temporarily reassign I2S to the Pi. Recommendation: stay muted; revisit only if a specific title’s audio is gameplay-critical.
-
NFL Challenge IP path. XOR Corp dissolved circa 1992; no successor rights holder is documented. Even side-load assumes the user obtained a copy through a path they can defend. Recommendation: ship the side-load capability without bundling NFL Challenge anywhere, document in the launcher that the user provides their own
.EXE. -
DrugWars substitution disclosure. If we ship Dopewars under the “DrugWars” launcher label, players may assume it’s the original. Recommendation: label the launcher entry “DOPEWARS (DrugWars-like)” with a short attribution note in the title splash. Honest, faithful to the substitute’s actual identity.
-
Numpad remap-shim ownership. The phone-numpad ↔ calculator-numpad translation is a thin per-title static table. Open: does this shim live in the Legacy Terminal launcher (cleanest), or as an evdev intercept in nOSh’s input layer (more invasive, but reusable)? Recommendation: in the launcher — it’s title-specific and shouldn’t bleed into nOSh’s normal input dispatch.
-
F-key letter overlay. The 14 function keys need to render as a soft alphabet during Legacy Terminal sessions for the roguelikes. The keycap legends don’t change, so the overlay needs to live on CIPHER-LINE row 1 or row 4 (currently the modeline / multi-tap echo). Open: which CIPHER-LINE rows are usable while a roguelike is in foreground, given that nOSh’s normal CIPHER scrollback also pauses in mode-swap? Recommendation: repurpose CIPHER-LINE row 4 as the F-key legend strip during Legacy Terminal sessions. Document as a mode-specific row reassignment, parallel to the row 0/24 main-grid carve-out.
-
Image-build footprint. ~50 MB across binaries + source archives + DOSBox is comfortable today. If we later add titles, footprint grows. Open: at what total Legacy Terminal footprint do we revisit partition sizing? Recommendation: soft cap at 200 MB; revisit
(rest)/2rootfs split if we cross it. -
Side-load discovery. When the user drops an executable into
sideloads/, how does the launcher know whether to route it through DOSBox vs. attempt a native invocation? Recommendation: simple extension-based routing —*.EXE/*.COM→ DOSBox; anything else → not supported in v1.
Memo ends. All decisions in this document are recommendations from research; nothing implements until Josh signs off.