Skip to content

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.

TitleRun targetLicenseVerdict
NetHack 3.6.7Native ARM LinuxNGPL (free, source-available)Bundle
Umoria 5.7.xNative ARM LinuxGPL-3.0-or-laterBundle
DrugWars (original 1984)DOSBoxNo license — Dell holds copyrightSide-load only; bundle a clean substitute (Dopewars, GPL-2) instead
NFL Challenge (1985)DOSBoxAbandonware — XOR Corp defunct, rights ambiguousSide-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.


  • 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 stripped TERM profile (or nethack -X).
  • Input: Movement is the gating concern. OPTIONS=number_pad:1 maps numpad 1–9 → b j n h _ l y k ucalculator 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.
  • 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.
  • 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”

When the player triggers the entry gesture, nOSh:

  1. Releases the SDL framebuffer by closing the KMSDRM context (the same path used during a graceful shutdown, with a re-open path on resume).
  2. Releases the evdev input grab on /dev/input/event* so the child process can claim it via standard ncurses / SDL input.
  3. Mutes audio: sends a single UART command (PSG_SILENCE) to the Pico 2 coprocessor per the coprocessor-protocol.md spec; the Pico stops emitting on I2S. v1 audio policy is mute.
  4. 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.
  5. Spawns the child with posix_spawn under the same nosh user, 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.

Child exit returns to the launcher (or directly to Bare Deck if exit was from the launcher itself):

  1. Wait on child via SIGCHLD. Capture exit code (logged to /tmp/legacy-terminal.log for debugging).
  2. Reclaim framebuffer / evdev / audio in the inverse order they were released. Pico 2 receives PSG_RESUME.
  3. HUD wake — rows 0 and 24 redraw.
  4. 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/).
/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).


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:

  1. Ship LICENSE at /opt/legacy-terminal/LICENSE containing the GPL-2 text (DOSBox), GPL-3 text (Umoria), GPL-2 text (Dopewars), and NGPL text (NetHack), with attribution headers per project.
  2. Ship the modified source at /opt/legacy-terminal/src/dosbox-staging-<version>.tar.gz alongside the binary. GPL §3a (machine-readable source accompanying object code) is the simplest compliance form.
  3. 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.
  4. Add a DOSBox by The DOSBox Team — GPL-2 credit line to the launcher splash so attribution is operator-visible, not just buried in LICENSE.

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.


These need a decision before any implementation work begins.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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)/2 rootfs split if we cross it.

  7. 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.