Skip to content

NoshAPI — Primitives by Category

The NoshAPI is the FFI surface that the nOSh runtime exposes to cartridge Lisp. ADR-0005 enumerated 54 primitives across three capability tiers (all-carts, mission-context, REPL-read-only); ADR-0007 layered on the mission-script grammar; runtime evolution has added CIPHER-LINE primitives. This page is the implementer-facing categorized index — what each primitive is named, what it takes, what it returns, what it does in one sentence, and how stable it is.


MarkerMeaning
v1Stable, in ADR-0005 v1.0 enumeration. Cartridges may rely on signature and semantics.
v1+Stable, added by an accepted ADR after ADR-0005 v1.0 (e.g. ADR-0016’s emacs-extend-*). Treat as v1.
evolvingSpecified but the signature or semantics may shift before launch. Cartridge authors should expect possible breaking changes.

Type tags follow ADR-0005’s table — Bool, Number, String, Symbol, Cell (opaque), Bytes (byte array), Unit (returns nil).


Primary 80×25 text grid. Cartridges may not write Row 0 or Row 24 (firmware-owned).

Lisp nameSignatureReturnsSemanticsStability
text-clear() UnitClear text framebuffer (does not affect bitmap area).v1
text-putc(col row char)UnitPlace a single character at (col, row); ASCII 0–127.v1
text-puts(col row string)UnitPrint null-terminated string at (col, row), left-aligned, clipped at grid boundary.v1
text-printf(col row fmt arg...)UnitPrintf-style formatted text; supports %d %u %x %c %s; max 128 bytes.v1
text-scroll(lines)UnitScroll text up (positive) or down (negative); range −25 to +25.v1
text-cursor(col row visible)UnitShow / hide text cursor at (col, row).v1
text-invert(col row len)UnitInvert text color for len characters; emphasis primitive.v1

Display: bitmap (960×600 logical framebuffer)

Section titled “Display: bitmap (960×600 logical framebuffer)”

Per ADR-0014, the canvas is 960×600 logical pixels (the 1024×600 Elecrow has 32 px horizontal letterbox per side that cartridges never see). All bitmap primitives below are bounds-checked against 960×600.

Lisp nameSignatureReturnsSemanticsStability
gfx-clear()UnitClear bitmap framebuffer.v1
gfx-pixel(x y on)UnitSet / clear pixel; x 0–959, y 0–599.v1
gfx-line(x0 y0 x1 y1)UnitBresenham line.v1
gfx-rect(x y w h filled)UnitFilled or outline rectangle.v1
gfx-circle(cx cy r)UnitCircle outline at center (cx, cy).v1
gfx-blit(x y bytes w h)UnitBlit packed 1-bpp bitmap (byte length = (w*h+7)/8).v1
Lisp nameSignatureReturnsSemanticsStability
split-view(bitmap-rows)UnitSet split-view: top bitmap-rows pixels are graphics, remainder text.v1
display-mode()SymbolQuery current mode: :text, :graphics, or :split.v1

YM2149 emulation via the runtime’s psg.c. Direct register access is provided for advanced use; most carts use the higher-level helpers.

Lisp nameSignatureReturnsSemanticsStability
psg-write(reg val)UnitWrite PSG register reg (0–14) with val (0–255). Direct hardware-style access.v1
psg-read(reg)NumberRead current value of register.v1
Lisp nameSignatureReturnsSemanticsStability
sound-tone(channel freq vol)UnitPlay tone on channel 0–2 at frequency (Hz) and volume 0–15.v1
sound-noise(period)UnitSet noise period (0–31).v1
sound-envelope(shape period)UnitSet envelope shape (0–15) and period.v1
sound-silence()UnitMute all channels and noise.v1
Lisp nameSignatureReturnsSemanticsStability
sfx-keyclick()UnitShort click; key-confirmation feedback.v1
sfx-boot()UnitAscending boot tones (~300 ms).v1
sfx-select()UnitSelection beep.v1
sfx-confirm()UnitConfirmation tone.v1
sfx-error()UnitError buzz.v1
sfx-alert()UnitAlert ping.v1

Lisp nameSignatureReturnsSemanticsStability
spawn-cell(type-symbol)CellAllocate cell of given type; type must be registered in cart init.v1
destroy-cell(cell)UnitReturn cell to free pool; handle becomes invalid.v1
Lisp nameSignatureReturnsSemanticsStability
drill-into(cell)UnitPush cell onto nav stack; fires ON_EXIT then ON_ENTER.v1
navigate-back()UnitPop nav stack; fires lifecycle handlers.v1
current-cell()CellTop of nav stack, or nil if empty.v1
set-root(cell)UnitReset nav stack to cell; usually called once at cart init.v1
next-sibling()UnitMove to next sibling in current list (no-op at last).v1
prev-sibling()UnitMove to previous sibling (no-op at first).v1
Lisp nameSignatureReturnsSemanticsStability
list-push(parent cell)UnitAppend cell as child of parent.v1
list-get(parent index)CellGet Nth child (0-indexed); nil if out of range.v1
list-length(parent)NumberCount children.v1
is-leaf(cell)BoolTrue if cell has no children.v1
link-cells(parent child)UnitEstablish parent/child relation; equivalent to list-push.v1
unlink-cell(cell)UnitRemove from parent + sibling chain; orphaned but not destroyed.v1

Lisp nameSignatureReturnsSemanticsStability
lfsr-seed(seed)UnitInitialize 32-bit LFSR.v1
lfsr-next()NumberAdvance LFSR; return next pseudo-random 32-bit value.v1
lfsr-range(min max)NumberPseudo-random integer in [min, max] inclusive.v1
lfsr-shuffle(array-length)UnitFisher-Yates shuffle in-place. Per ADR-0005 §“Known Unknowns” #1, the Lisp surface for in-place array mutation is unresolved; treat as evolving.evolving

Available to all carts. Read-only on this tier; mutation requires mission context.

Lisp nameSignatureReturnsSemanticsStability
deck-state()CellReference to Universal Deck State (record-style accessor).v1
get-handle()StringOperator handle, max 16 chars.v1
get-credits()NumberCurrent credit balance.v1
get-reputation()NumberCurrent reputation points.v1
has-capability(bit-index)BoolTest cartridge-history capability bit (0–31).v1

Lisp nameSignatureReturnsSemanticsStability
draw-threat-bar(level max col row)UnitDraw level/max filled blocks; max 16 cells wide.v1
draw-progress-bar(pct col row width)UnitDraw percentage-filled bar; width 1–32 cells.v1
draw-bordered-box(col row w h title)UnitBox outline with optional centered title.v1

Mission context (Tier 2 — active phase only)

Section titled “Mission context (Tier 2 — active phase only)”

Available only when a mission phase is active; calls outside mission context raise :not-in-mission.

Lisp nameSignatureReturnsSemanticsStability
phase-advance()UnitAdvance to next phase in chain; calls lifecycle handlers; auto-completes at last phase.v1
mission-complete()UnitMark mission complete; award payout; pop mission context.v1
award-credits(amount)UnitAdd (or subtract, if negative) credits to deck balance.v1
modify-reputation(delta)UnitAdjust reputation; clamped at [0, 32767].v1
set-phase-data(key value)UnitStore key-value in current phase’s persistent data (survives phase boundaries within the mission).v1
get-phase-data(key)AnyRetrieve phase data; nil if unset.v1
set-capability(bit-index)UnitSet cartridge-history bit; marks the module as completed.v1

Scripted-mission-only context (per ADR-0007)

Section titled “Scripted-mission-only context (per ADR-0007)”
Lisp nameSignatureReturnsSemanticsStability
mission-input()AnyInput value provided by mission template.v1
mission-context()AnyLocal mission state (read-only).v1
mission-deck-state()AnyRead-only deck-state snapshot (Tier 2 grant).v1
current-mission-phase()SymbolPhase metadata (Tier 2 grant).v1
cartridge-data(cart-id)AnyRead from another loaded cartridge (Tier 2; requires :grants clause).v1
pass()UnitAcceptance contract: signal mission success.v1
fail(clause...)UnitAcceptance contract: signal failure with clause-level diagnostics.v1

Per software/runtime/cipher-voice.md §11. CIPHER is OLED-exclusive (Spec Hygiene Rule 6). The Null cartridge has a sanctioned main-grid escape; no other cart may bypass.

Lisp nameSignatureReturnsSemanticsStability
cipher-emit(mode-or-nil &optional :event ev)UnitPush a mode hint or forced silence into the next tick; optionally bind a synthetic event.v1
cipher-push-event(event-record)UnitPush event onto stream + memory store; runtime stamps :t and :tag.v1
cipher-extend-grammar(grammar-fragment)BoolAdd a cipher-grammar block at runtime; only legal during :mission-brief / :bare-deck beats.v1
cipher-set-mode-weights(beat delta-list)UnitTemporary mode-weight bias scoped to current mission or cart unload.v1
cipher-stack-head(n)ListRead top N entries of coherence stack.v1
cipher-main-grid-escape()UnitNull cartridge only — sanctioned exception to OLED-exclusive rule. Rejected for any other cart.v1
aux-timer-start(:tag :duration-ms :on-fire ev)NumberStart runtime-managed countdown; expiry pushes event; max 600,000 ms. Returns timer handle.v1
aux-timer-stop(handle)BoolCancel timer; #t if live, #f if already fired.v1
aux-show-seed(seed-bytes :label string)UnitFreeze CIPHER-LINE Row 1 to a captured seed; enter seed-capture mode.v1
aux-status-render(row content :priority pri)UnitRender to CIPHER-LINE Row 1 or Row 4; tickers if overflow; priority arbitrates concurrent writers.v1

Cartridges contribute to nEmacs / REPL completion via two FFI primitives extending ADR-0009’s static ranking model:

Lisp nameSignatureReturnsSemanticsStability
emacs-extend-grammar(sexp)UnitCart contributes grammar productions for legal-form filtering in the predictive palette.v1+
emacs-extend-vocabulary(list-of-strings)UnitCart contributes domain terms; each receives the +5 vocabulary boost in token ranking.v1+
prompt-text(prompt max-len)StringModal text-entry dialog (Nokia multi-tap on CIPHER-LINE Row 4); returns the entered string or nil on cancel.v1+

Per ADR-0005 §“Tier 3,” the player REPL exposes only the read-only subset of the above:

  • Display: display-mode.
  • State: get-handle, get-credits, get-reputation, has-capability, deck-state.
  • Cells (inspect): current-cell, list-get, list-length, is-leaf.
  • Procedural: lfsr-seed, lfsr-next, lfsr-range.

All mutating primitives — text-*, gfx-*, sound-*, spawn-cell, destroy-cell, drill-into, navigate-back, phase-advance, mission-complete, award-credits, modify-reputation, set-capability, cipher-push-event, aux-* — are forbidden in the REPL. Player REPL is for inspection and scripted automation, not for mutating mission state.


The CIPHER-LINE event-record schema, the cart-format cipher-grammar block layout, and the Lisp ↔ C type marshalling table all live where they’re authoritative — not duplicated here. See:

  • Event records, modes, grammar productions: ../../runtime/cipher-voice.md.
  • Cart-format binary layout for grammar/vocabulary blocks: adr/ADR-0006-cart-format-v2.md (filesystem-versioned).
  • Type mapping (C ↔ Lisp): ADR-0005 §“Type Mapping.”
  • Open questions (array mutation FFI, error trace depth, mission-context shape): ADR-0005 §“Known Unknowns / Follow-ups.”