/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. Licensed under the StarForth License, Version 1.0 */ /** * repl.h - Emergency FORTH REPL for LithosAnanke kernel */ #ifndef STARKERNEL_REPL_H #define STARKERNEL_REPL_H #include "vm.h" #include "starkernel/homeblocks_sig.h" struct blkio_dev; #ifdef __cplusplus extern "C" { #endif /** * sk_repl - Run the emergency FORTH REPL on the serial console. * * Blocks until vm->halted is set (BYE word) or the VM encounters a halt. * Runs with interrupts enabled; the APIC heartbeat continues to fire. * * @param vm Mama VM instance (must be fully initialised) */ void sk_repl(VM *vm); /** * sk_repl_run - Bare REPL loop (no banner). * * Same as sk_repl but skips the version/welcome banner. Used by START * to enter a child VM's interpreter loop without reprinting the header. * * @param vm Fully initialised VM instance */ void sk_repl_run(VM *vm); /** * sk_repl_step - Execute one REPL turn on a VM and return. * * Prints the VM's prompt, reads one line, interprets it, prints ok/ERROR, * then returns. Used by the Compudynamics VM-STEP primitive so Hera can * give a single REPL quantum to a child VM without surrendering control * for the full sk_repl_run() loop. * * @param vm Fully initialised VM instance * @return 1 if the VM is still running, 0 if it halted during this turn */ int sk_repl_step(VM *vm); /** * sk_repl_set_active_vm - Redirect REPL input to a different VM (USE word). * * Pass NULL to restore default dispatch (Mama's VM). * The change takes effect on the next REPL iteration. * * @param vm Target VM, or NULL for default */ void sk_repl_set_active_vm(VM *vm); /** * sk_repl_get_active_vm - Return the current USE-redirected VM, or NULL. */ VM *sk_repl_get_active_vm(void); /** * sk_repl_get_homeblocks_dev / sk_repl_get_homeblocks_sig - The currently * attached home-blocks USB drive, or NULL if none is attached / the * attached drive didn't check out as HOMEBLOCKS_SIG_OK (FABRIC-3.md * §F.6/§F.9/§F.18). Both return NULL together; never one without the * other. */ struct blkio_dev *sk_repl_get_homeblocks_dev(void); const homeblocks_sig_t *sk_repl_get_homeblocks_sig(void); /** * sk_repl_get_attached_blk_dev - The currently attached USB block * device, regardless of home-blocks recognition (FABRIC-3.md * §F.8/§F.19) -- MINT's own target, since a blank/unminted drive never * sets sk_repl_get_homeblocks_dev() above. NULL if nothing is attached. */ struct blkio_dev *sk_repl_get_attached_blk_dev(void); /** * sk_console_getkey - Real body of the standard dictionary's KEY word * (called from shim.c's getchar()). Blocks until a key is available from * either input source (serial console or the PS2/virtio keyboard-event * bridge), servicing the heartbeat/idle loop while waiting so a KEY call * from inside any word never stalls the heartbeat. No echo -- that's the * caller's responsibility, same as any standard KEY. * * @param active_vm VM whose idle dispatch runs while waiting (see * sk_repl_idle()'s own doc comment on why this is a * parameter rather than read via sk_repl_get_active_vm()) * @return the key read, as an unsigned byte value */ int sk_console_getkey(VM *active_vm); /** * sk_console_key_available - Real body of the standard dictionary's * ?TERMINAL word (called from sf_terminal_ready()). Non-blocking peek: * returns 1 if a key is ready without consuming it (a following * sk_console_getkey() returns that exact key), 0 otherwise. */ int sk_console_key_available(void); /** * sk_console_readline - Real body of the standard dictionary's * QUERY/EXPECT words (called from shim.c's fgets()). Reads one line from * the console with echo and backspace support, servicing the heartbeat/ * idle loop while waiting -- the same line editor the REPL's own prompt * uses internally, so a mid-word EXPECT behaves identically to typing at * "ok>" itself. * * @param buf Destination buffer * @param size Buffer capacity, including the NUL terminator * @param active_vm VM whose idle dispatch runs while waiting * @return number of characters placed in buf, not counting the NUL */ int sk_console_readline(char *buf, int size, VM *active_vm); #ifdef __cplusplus } #endif #endif /* STARKERNEL_REPL_H */