all repos — xyw @ 66dc8e0b4f3b24282e2f7769f0d3ce18516bdbe2

A minimal virtual machine and assembler for terminals.

Minor refactoring.
h3rald h3rald@h3rald.com
Wed, 04 Feb 2026 14:49:03 +0100
commit

66dc8e0b4f3b24282e2f7769f0d3ce18516bdbe2

parent

3a3510ba2ec2d99e5d54979f199abd584d738f26

1 files changed, 36 insertions(+), 27 deletions(-)

jump to
M xywrun.cxywrun.c

@@ -293,12 +293,39 @@ // ...

}; // clang-format on +//// Internal VM state +xyw_byte error_handler_entry_s = 0; + +int process_handlers() +{ + // Error handling + if (xyw_memory[SYSTEM_ERROR] != XYW_ERROR_NONE && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + { + xyw_word on_error_handler = XYW_PEEKW(&xyw_memory[SYSTEM_ON_ERROR]); + // If an error handler is set, jump to it + if (on_error_handler != 0) + { + xyw_dbg("Error occurred: %02X, jumping to error handler at %04X\n", xyw_memory[SYSTEM_ERROR], on_error_handler); + // Enter error state + xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_ERROR; + error_handler_entry_s = *s; // Record stack depth before pushing return address + ss_pushw(*pc); + *pc = on_error_handler; + } + else + { + // No error handler, halt execution + return xyw_memory[SYSTEM_ERROR]; + } + } + + return 0; +} + //// Main evaluation function - runs from current pc until BRK -//// Returns 1 on success, 0 on error int xyw_eval(xyw_word start_pc) { *pc = start_pc; - xyw_byte error_handler_entry_s = 0; if (xyw_memory[SYSTEM_STATE] & xyw_debug) {

@@ -306,29 +333,12 @@ xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_DEBUG;

} while ((xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING) && *pc < SYSTEM_MEMORY_START) { - if (xyw_memory[SYSTEM_ERROR] != XYW_ERROR_NONE && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) - { - xyw_word on_error_handler = XYW_PEEKW(&xyw_memory[SYSTEM_ON_ERROR]); - // If an error handler is set, jump to it - if (on_error_handler != 0) - { - // Enter error state - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_ERROR; - error_handler_entry_s = *s; // Record stack depth before pushing return address - ss_pushw(*pc); - *pc = on_error_handler; - } - else - { - // No error handler, halt execution - return xyw_memory[SYSTEM_ERROR]; - } - } + process_handlers(); 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); switch (xyw_memory[*pc]) { // clang-format off - /* BRK */ case 0x00: return 1; // Simply return from evaluation + /* BRK */ case 0x00: return 0; // Simply return from evaluation /* PSH */ OPC_SR1(0x01, , if (rx||ry) { PUSH(ARG); } else { (*pc)++; PUSH(READ(*pc)); if (w) { (*pc)++; } }) /* PSH */ OPC_SR1r(0x01, PUSH(a); PUSH(b); ) /* POP */ OPC_SR1(0x02, , if (rx||ry) { SET(POP()); } else { POP(); } );

@@ -419,14 +429,13 @@ // Set direct page to device page by default

xyw_memory[SYSTEM_PAGE] = 0xff; int eval_result = xyw_eval(0x0000); - if (eval_result) + if (!eval_result) { - xyw_word terminal_vector = XYW_PEEKW(&xyw_memory[TERMINAL_ON_KEYPRESS]); - - // If terminal vector is set, enter stdin reading loop - if (terminal_vector) + // If terminal handler is set, enter stdin reading loop + xyw_word terminal_handler = XYW_PEEKW(&xyw_memory[TERMINAL_ON_KEYPRESS]); + if (terminal_handler) { - xyw_dbg("terminal.on_keypress vector set to %04X, entering input loop\n", terminal_vector); + xyw_dbg("terminal.on_keypress handler set to %04X, entering input loop\n", terminal_handler); while (xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING) { int c = getch();