all repos — xyw @ 846f9715bd78b9352ebdc1a4bf6f5589e28ea513

A minimal virtual machine and assembler for terminals.

Added waiting state.
h3rald h3rald@h3rald.com
Fri, 06 Feb 2026 10:44:52 +0100
commit

846f9715bd78b9352ebdc1a4bf6f5589e28ea513

parent

c632e3a4cdd4d21b1f431030eb3723bbed10ae9d

2 files changed, 25 insertions(+), 7 deletions(-)

jump to
M devices/terminal.cdevices/terminal.c

@@ -15,7 +15,7 @@ {

case TERMINAL_INPUT: { xyw_word handler; - if (!xyw_arguments_processed) + if (!xyw_arguments_processed && XYW_PEEKW(&data[TERMINAL_ON_ARGUMENT])) { // Process input as arguments (separated by XYW_ARGUMENT_SEPARATOR) until XYW_END_OF_ARGUMENTS handler = XYW_PEEKW(&data[TERMINAL_ON_ARGUMENT]);
M xywrun.cxywrun.c

@@ -50,6 +50,7 @@ XYW_ERROR_STACK_OVERFLOW,

} xyw_error; #define SYSTEM_STATE_RUNNING 0x01 +#define SYSTEM_STATE_WAITING 0x02 #define SYSTEM_STATE_DEBUG 0x40 #define SYSTEM_STATE_ERROR 0x80

@@ -291,13 +292,28 @@ // ...

}; // clang-format on +static int system_error_state() +{ + return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR; +} + +static int system_running_state() +{ + return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING; +} + +static int system_waiting_state() +{ + return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_WAITING; +} + //// Internal VM state xyw_byte error_handler_entry_s = 0; -int process_events() +static int process_events() { // Error handling - if (xyw_memory[SYSTEM_ERROR] != XYW_ERROR_NONE && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + if (xyw_memory[SYSTEM_ERROR] != XYW_ERROR_NONE && !system_error_state()) { xyw_word on_error_handler = XYW_PEEKW(&xyw_memory[SYSTEM_ON_ERROR]); // If an error handler is set, jump to it

@@ -318,7 +334,7 @@ }

} // Process terminal arguments if not already done static int argument_processing_active = 0; - if (!xyw_arguments_processed && !argument_processing_active && XYW_PEEKW(&xyw_memory[TERMINAL_ON_ARGUMENT]) && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + if (!xyw_arguments_processed && !argument_processing_active && XYW_PEEKW(&xyw_memory[TERMINAL_ON_ARGUMENT]) && !(system_error_state())) { argument_processing_active = 1; // Prevent re-entry for (int i = 1; i < xyw_argc; i++)

@@ -351,7 +367,7 @@ if (xyw_memory[SYSTEM_STATE] & xyw_debug)

{ xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_DEBUG; } - while ((xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING) && *pc < SYSTEM_MEMORY_START) + while ((system_running_state()) && *pc < SYSTEM_MEMORY_START) { process_events(); xyw_dbg(" -- PC: %04X -> %02X (%s) [U:%02X|S:%02X|X:%02X|Y:%02X|XW:%04X|YW:%04X]\n", *pc, xyw_memory[*pc], xyw_instructions[xyw_memory[*pc] & 0x1F], *u, *s, *x, *y, *xw, *yw);

@@ -405,7 +421,7 @@ /* JSR */ OPC_SR1(0x1E, xyw_word addr = ADDR(ARG), ss_pushw(*pc+1); *pc = addr-1;);

/* RTS */ case 0x1F: *pc = ss_popw()-1; // If returning from error handler, clear flag to allow re-trigger - if ((xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR) && *s == error_handler_entry_s) { + if ((system_error_state()) && *s == error_handler_entry_s) { xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_ERROR; error_handler_entry_s = 0; }

@@ -456,14 +472,16 @@ xyw_word on_keypress_handler = XYW_PEEKW(&xyw_memory[TERMINAL_ON_KEYPRESS]);

if (on_keypress_handler) { xyw_dbg("terminal.on_keypress handler set to %04X, entering input loop\n", on_keypress_handler); - while (xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING) + while (system_running_state() || system_waiting_state()) { + xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_WAITING; int c = getch(); // if CTRL+C or CTRL+D is pressed, exit if (c == 3 || c == 4) { return 0; } + xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_RUNNING; write(TERMINAL_INPUT, (xyw_byte)c); } }