Files
LithosAnanake/src/word_source/scroll_words.c
T
Robert Allan JamesandClaude Sonnet 5 1f3ec3554e starkernel: REPL scrollback, ~1000 lines (FABRIC.md item 4.4q)
Scope decided with Captain Bob before implementation: ring buffer +
recall on today's full-screen vt100 grid, not also confining REPL text
to the 4.4o 640x480 box (that confinement stays open as its own future
item, not a third silent deferral). No keyboard input path exists yet
(M8 unstarted), so the trigger is two new FORTH words, SCROLL-BACK
( n -- ) / SCROLL-FWD ( n -- ), exercised via serial injection.

vt100.c gains a text-only 1000-line ring buffer (kmalloc'd, tens of KB
-- not pixel snapshots, which would be ~1000x larger for no benefit)
plus a shadow buffer mirroring the current screen. scroll_up() now
pushes evicted rows into the ring before the pixel scroll. History is
one continuous sequence (ring then shadow); scrolling always redraws
from that sequence -- no separate pixel-scroll path for scrollback,
decided up front to avoid retrofitting later.

New src/word_source/scroll_words.c (Module 31), thin wrappers over
console_fb_scroll_back()/_fwd() -> vt100_scroll_back()/_fwd(). Bug
caught during live testing: both words initially used an off-by-one
underflow check (dsp < 1) copied from a different, older dsp
convention elsewhere in this codebase; vm_pop() (which these words
actually call) uses dsp as a 0-based top-of-stack index, so the check
rejected every legitimate single-argument call. Fixed by removing the
separate precheck and relying on vm_pop()'s own guard.

Live-verified on all three architectures (exceeds this item's
amd64-minimum bar): generated 50+ lines via a FORTH loop, confirmed
SCROLL-BACK recovers correctly older content, and on amd64 confirmed
SCROLL-FWD returns to genuinely live state (not a frozen snapshot) by
showing the injected commands' own echo. Known limitation confirmed by
direct pixel measurement: redrawn lines lose their original SGR color
(not stored per-cell) -- text recovers exactly, color does not.

Three-arch verified: Failed: 0, dict-hashes identical across all
three (values changed correctly from prior items -- two new words
were added).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 21:23:25 -04:00

53 lines
1.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James
All rights reserved.
Licensed under the StarForth License, Version 1.0
*/
/* scroll_words.c — REPL scrollback entry points (FABRIC.md item 4.4q).
* Kernel-only; no-op on hosted builds. */
#include "include/scroll_words.h"
#include "../../include/log.h"
#include "../../include/word_registry.h"
#ifdef __STARKERNEL__
#include "starkernel/console.h"
/* SCROLL-BACK ( n -- ) -- move the REPL scrollback view back n lines.
* Relies on vm_pop()'s own underflow guard (sets vm->error, logs, returns
* 0) rather than a separate dsp precheck -- this codebase has more than
* one dsp convention across older word_source files (some treat it as a
* top-of-stack index, some as a raw count); vm_pop() is the one this word
* actually calls, so deferring to its own check sidesteps the mismatch
* entirely instead of risking silently picking the wrong one. */
static void scroll_word_back(VM *vm) {
cell_t n = vm_pop(vm);
if (vm->error) return;
if (n < 0) n = 0;
console_fb_scroll_back((uint32_t)n);
}
/* SCROLL-FWD ( n -- ) -- move the REPL scrollback view forward n lines
* (toward live). Same underflow-handling rationale as SCROLL-BACK above. */
static void scroll_word_fwd(VM *vm) {
cell_t n = vm_pop(vm);
if (vm->error) return;
if (n < 0) n = 0;
console_fb_scroll_fwd((uint32_t)n);
}
#endif /* __STARKERNEL__ */
void register_scroll_words(VM *vm)
{
#ifdef __STARKERNEL__
register_word(vm, "SCROLL-BACK", scroll_word_back);
register_word(vm, "SCROLL-FWD", scroll_word_fwd);
#else
(void) vm;
#endif
}