Moved snapshot save/restore to system device, other fixes and refactorings.
@@ -1,5 +1,4 @@
#include <stdio.h> -#include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <errno.h>@@ -15,8 +14,6 @@ #define PATH_SEP '/'
#endif #include "../xyw.h" - -extern xyw_byte xyw_memory[]; // file device #define FILE_PATH 0x0
@@ -1,6 +1,7 @@
#include <time.h> #include <stdlib.h> #include <stdio.h> +#include <string.h> #include "../xyw.h" #define SYSTEM_STATE 0x00@@ -10,13 +11,17 @@ #define SYSTEM_RANDOM 0x03
#define SYSTEM_ON_ERROR 0x04 #define SYSTEM_IMAGE_EXEC 0x06 -#define SYSTEM_STATE_RUNNING 0x01 -#define SYSTEM_STATE_ERROR 0x80 +#define MAX_IMAGE_EXEC_DEPTH 8 +#define MAX_IMAGE_EXEC_PATH_LENGTH 256 -#define XYW_ERROR_NONE 0 +/// Error handler tracking +static xyw_byte error_handler_entry_s = 0; -/// Error handler tracking (accessible by xywrun.c for snapshot/reset) -xyw_byte error_handler_entry_s = 0; +/// Exec stack management +static xyw_vm_snapshot exec_stack[MAX_IMAGE_EXEC_DEPTH]; +static int exec_stack_depth = 0; +static int exec_pending = 0; +static char exec_path_buf[MAX_IMAGE_EXEC_PATH_LENGTH]; void system_setup(xyw_byte *data) {@@ -33,6 +38,20 @@ (void)error;
return data[addr]; } +static void get_string_from_memory(xyw_word addr, char *buf, size_t bufsize) +{ + size_t i; + for (i = 0; i < bufsize - 1 && xyw_memory[addr + i] != 0; i++) + buf[i] = xyw_memory[addr + i]; + buf[i] = '\0'; +} + +static void request_exec(xyw_word path_addr) +{ + get_string_from_memory(path_addr, exec_path_buf, sizeof(exec_path_buf)); + exec_pending = 1; +} + void system_output(xyw_byte *data, xyw_byte addr, xyw_byte *error) { (void)error;@@ -40,29 +59,71 @@ if (addr == SYSTEM_IMAGE_EXEC + 1)
{ xyw_word target = XYW_PEEKW(&data[SYSTEM_IMAGE_EXEC]); if (target != 0) - xyw_request_exec(target); + request_exec(target); + } +} + +static void split_exec_string(char *full, char **path, char **argstart) +{ + char *sp = strchr(full, ' '); + if (sp) + { + *sp = '\0'; + *argstart = sp + 1; + } + else + { + *argstart = NULL; + } + *path = full; +} + +static void handle_exec_requests(xyw_byte *data) +{ + if (!exec_pending) + return; + exec_pending = 0; + + if (exec_stack_depth >= MAX_IMAGE_EXEC_DEPTH) + { + data[SYSTEM_ERROR] = XYW_ERROR_EXEC_DEPTH_EXCEEDED; + return; + } + xyw_vm_save_snapshot(&exec_stack[exec_stack_depth++]); + + char path_copy[MAX_IMAGE_EXEC_PATH_LENGTH]; + strncpy(path_copy, exec_path_buf, sizeof(path_copy) - 1); + path_copy[sizeof(path_copy) - 1] = '\0'; + char *path, *argstart; + split_exec_string(path_copy, &path, &argstart); + + xyw_vm_reset(); + if (xyw_vm_load_image(path, argstart) != 0) + { + // Restore parent state so error handler can run in the caller's context + xyw_vm_restore_snapshot(&exec_stack[--exec_stack_depth]); } } void system_tick(xyw_byte *data) { // Check if returning from error handler (after RTS popped the frame) - if ((data[SYSTEM_STATE] & SYSTEM_STATE_ERROR) && + if ((data[SYSTEM_STATE] & XYW_STATE_ERROR) && error_handler_entry_s != 0 && xyw_vm_get_system_depth() == error_handler_entry_s) { - data[SYSTEM_STATE] &= ~SYSTEM_STATE_ERROR; + data[SYSTEM_STATE] &= ~XYW_STATE_ERROR; error_handler_entry_s = 0; } // Check for new error condition - if (data[SYSTEM_ERROR] != XYW_ERROR_NONE && !(data[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + if (data[SYSTEM_ERROR] != XYW_ERROR_NONE && !(data[SYSTEM_STATE] & XYW_STATE_ERROR)) { xyw_word on_error_handler = XYW_PEEKW(&data[SYSTEM_ON_ERROR]); if (on_error_handler != 0) { XYW_DBG("Error occurred: %02X, jumping to error handler at %04X\n", data[SYSTEM_ERROR], on_error_handler); - data[SYSTEM_STATE] |= SYSTEM_STATE_ERROR; + data[SYSTEM_STATE] |= XYW_STATE_ERROR; error_handler_entry_s = xyw_vm_get_system_depth(); xyw_vm_push_frame(*pc); *pc = on_error_handler;@@ -70,7 +131,32 @@ }
else { // No error handler: halt execution - data[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; + data[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; } } + + // Handle exec requests + handle_exec_requests(data); +} + +void system_save(xyw_byte *data, xyw_byte *state) +{ + (void)data; + state[0] = error_handler_entry_s; +} + +void system_restore(xyw_byte *data, const xyw_byte *state) +{ + (void)data; + error_handler_entry_s = state[0]; +} + +int xyw_system_try_restore_parent(void) +{ + if (exec_stack_depth > 0) + { + xyw_vm_restore_snapshot(&exec_stack[--exec_stack_depth]); + return 1; + } + return 0; }
@@ -4,6 +4,7 @@ void system_setup(xyw_byte *data);
xyw_byte system_input(xyw_byte *data, xyw_byte addr, xyw_byte *error); void system_output(xyw_byte *data, xyw_byte addr, xyw_byte *error); void system_tick(xyw_byte *data); +void system_save(xyw_byte *data, xyw_byte *state); +void system_restore(xyw_byte *data, const xyw_byte *state); -/// Error handler stack depth tracking (saved/restored in snapshots) -extern xyw_byte error_handler_entry_s;+int xyw_system_try_restore_parent(void);
@@ -61,7 +61,6 @@ // Main public API
int xyw_assemble(const char *input, const char *output); int xyw_run(const char *input); int xyw_eval(xyw_word pc); -void xyw_request_exec(xyw_word path_addr); // Privileged VM API (for device implementations) extern xyw_byte xyw_memory[];@@ -69,6 +68,24 @@ extern xyw_word *pc, *xw, *yw;
extern xyw_byte *x, *y; extern xyw_byte *dev_error; +// System state flags (architectural constants for SYSTEM_STATE register) +#define XYW_STATE_RUNNING 0x01 +#define XYW_STATE_WAITING 0x02 +#define XYW_STATE_DEBUG 0x40 +#define XYW_STATE_ERROR 0x80 + +// Error codes (architectural constants for SYSTEM_ERROR register) +typedef enum +{ + XYW_ERROR_NONE = 0, + XYW_ERROR_DIVISION_BY_ZERO, + XYW_ERROR_STACK_UNDERFLOW, + XYW_ERROR_STACK_OVERFLOW, + XYW_ERROR_EXEC_DEPTH_EXCEEDED, + XYW_ERROR_IMAGE_NOT_FOUND, + XYW_ERROR_IMAGE_READ_ERROR, +} xyw_error; + void xyw_vm_push_frame(xyw_word return_addr); xyw_word xyw_vm_pop_frame(void); xyw_byte xyw_vm_get_system_depth(void);@@ -80,5 +97,26 @@ int xyw_vm_is_waiting(void);
int xyw_vm_is_error_state(void); void xyw_vm_reset(void); + +// VM snapshot (for exec stack management by system device) +#define XYW_MEMORY_SIZE 0x10000 +#define XYW_USER_STACK_SIZE 128 +#define XYW_SYSTEM_STACK_SIZE 384 + +typedef struct { + xyw_byte memory[XYW_MEMORY_SIZE]; + xyw_byte user_stack[XYW_USER_STACK_SIZE]; + xyw_byte system_stack[XYW_SYSTEM_STACK_SIZE]; + xyw_byte s, u, x_val, y_val; + xyw_word pc_val, xw_val, yw_val; + int argv_processed; + char exec_args[XYW_EXEC_ARGS_SIZE]; + int exec_args_active; + xyw_byte device_state[XYW_TOTAL_DEVICES][XYW_DEVICE_STATE_SIZE]; +} xyw_vm_snapshot; + +void xyw_vm_save_snapshot(xyw_vm_snapshot *snap); +void xyw_vm_restore_snapshot(xyw_vm_snapshot *snap); +int xyw_vm_load_image(const char *path, const char *args); #endif // XYW_H
@@ -9,49 +9,23 @@ #include "devices/clock.h"
#include "devices/file.h" #include "devices/beeper.h" -#define MEMORY_SIZE 0x10000 - -#define USER_STACK_SIZE 128 #define SYSTEM_FRAME_SIZE 8 #define SYSTEM_MAX_FRAMES 48 -#define USER_MEMORY_START 0x000 -#define DEVICE_AREA_START 0xff00 - -#define MAX_IMAGE_EXEC_DEPTH 8 -#define MAX_IMAGE_EXEC_PATH_LENGTH 256 - -/* system device addresses */ +/* system device addresses (architectural register locations) */ #define SYSTEM_STATE 0xff00 #define SYSTEM_ERROR 0xff01 #define SYSTEM_PAGE 0xff02 -#define SYSTEM_RANDOM 0xff03 - -typedef enum -{ - XYW_ERROR_NONE = 0, - XYW_ERROR_DIVISION_BY_ZERO, - XYW_ERROR_STACK_UNDERFLOW, - XYW_ERROR_STACK_OVERFLOW, - XYW_ERROR_EXEC_DEPTH_EXCEEDED, - XYW_ERROR_IMAGE_NOT_FOUND, - XYW_ERROR_IMAGE_READ_ERROR, -} xyw_error; - -#define SYSTEM_STATE_RUNNING 0x01 -#define SYSTEM_STATE_WAITING 0x02 -#define SYSTEM_STATE_DEBUG 0x40 -#define SYSTEM_STATE_ERROR 0x80 /// Main memory -xyw_byte xyw_memory[MEMORY_SIZE]; +xyw_byte xyw_memory[XYW_MEMORY_SIZE]; /// Exec args (set by exec logic, consumed by terminal poll) char xyw_exec_args[XYW_EXEC_ARGS_SIZE]; int xyw_exec_args_active = 0; /// Stacks (not part of addressable memory) -static xyw_byte user_stack[USER_STACK_SIZE]; +static xyw_byte user_stack[XYW_USER_STACK_SIZE]; static xyw_byte system_stack[SYSTEM_MAX_FRAMES * SYSTEM_FRAME_SIZE]; static xyw_byte s = 0; // system stack frame index static xyw_byte u = 0; // user stack pointer@@ -76,9 +50,9 @@
//// Helpers to retrieve device number and address within the device static inline int get_device(xyw_word addr) { - if (addr < DEVICE_AREA_START) + if (addr < XYW_DEVICE_AREA_START) return -1; - return (addr - DEVICE_AREA_START) / 16; + return (addr - XYW_DEVICE_AREA_START) / 16; } static inline xyw_byte *get_device_data(xyw_word addr)@@ -89,7 +63,7 @@
static inline xyw_byte get_device_address(xyw_word addr) { // Given $FF41, it should return $01 - return (xyw_byte)((addr - DEVICE_AREA_START) & 0x0F); + return (xyw_byte)((addr - XYW_DEVICE_AREA_START) & 0x0F); } //// Read/write memory helpers@@ -131,8 +105,6 @@ // and trigger output handlers for both bytes
writeb(addr, (xyw_byte)(val >> 8)); writeb(addr + 1, (xyw_byte)(val & 0xFF)); } - -//// Device dispatchers //// System stack management (frame-based) // Each frame is SYSTEM_FRAME_SIZE (8) bytes:@@ -185,17 +157,17 @@ //// Internal VM state
static int system_error_state() { - return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR; + return xyw_memory[SYSTEM_STATE] & XYW_STATE_ERROR; } static int system_running_state() { - return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING; + return xyw_memory[SYSTEM_STATE] & XYW_STATE_RUNNING; } static int system_waiting_state() { - return xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_WAITING; + return xyw_memory[SYSTEM_STATE] & XYW_STATE_WAITING; } //// Privileged VM API (public wrappers)@@ -207,17 +179,17 @@
void xyw_vm_set_running(int running) { if (running) - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_RUNNING; + xyw_memory[SYSTEM_STATE] |= XYW_STATE_RUNNING; else - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; } void xyw_vm_set_waiting(int waiting) { if (waiting) - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_WAITING; + xyw_memory[SYSTEM_STATE] |= XYW_STATE_WAITING; else - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_WAITING; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_WAITING; } int xyw_vm_is_running(void) { return system_running_state(); }@@ -236,7 +208,6 @@ y_val = 0;
xw_storage = 0; yw_storage = 0; pc_storage = 0; - error_handler_entry_s = 0; xyw_argv_processed = 0; xyw_exec_args_active = 0; }@@ -245,7 +216,7 @@ //// User stack management
static void us_push(xyw_byte val) { - if (u > USER_STACK_SIZE - 1) + if (u > XYW_USER_STACK_SIZE - 1) { xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; return;@@ -256,7 +227,7 @@ }
static void us_pushw(xyw_word val) { - if (u > USER_STACK_SIZE - 2) + if (u > XYW_USER_STACK_SIZE - 2) { xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; return;@@ -374,17 +345,19 @@ #define TOP (w ? (xyw_word)((user_stack[u - 2] << 8) | user_stack[u - 1]) : (xyw_word)user_stack[u - 1])
//// Initialize devices +#define DEV_DATA(n) (&xyw_memory[XYW_DEVICE_AREA_START + (n) * 16]) + xyw_device xyw_devices[XYW_TOTAL_DEVICES] = { // System device - {&xyw_memory[0xff00], system_setup, system_input, system_output, 0, 0, 0, 0, system_tick}, + {DEV_DATA(0), system_setup, system_input, system_output, 0, 0, system_save, system_restore, system_tick}, // Terminal device - {&xyw_memory[0xff10], terminal_init, terminal_input, terminal_output, terminal_teardown, terminal_poll, terminal_save, terminal_restore, 0}, + {DEV_DATA(1), terminal_init, terminal_input, terminal_output, terminal_teardown, terminal_poll, terminal_save, terminal_restore, 0}, // Clock device - {&xyw_memory[0xff20], clock_setup, clock_input, clock_output, 0, clock_poll, 0, 0, 0}, + {DEV_DATA(2), clock_setup, clock_input, clock_output, 0, clock_poll, 0, 0, 0}, // File device - {&xyw_memory[0xff30], file_setup, file_input, file_output, 0, 0, 0, 0, 0}, + {DEV_DATA(3), file_setup, file_input, file_output, 0, 0, 0, 0, 0}, // Beeper device - {&xyw_memory[0xff40], 0, beeper_input, beeper_output, beeper_teardown, 0, 0, 0, 0}, + {DEV_DATA(4), 0, beeper_input, beeper_output, beeper_teardown, 0, 0, 0, 0}, // ... }; // clang-format on@@ -397,117 +370,11 @@ return 1;
return 0; } -//// Snapshot management - -typedef struct { - xyw_byte memory[MEMORY_SIZE]; - xyw_byte user_stack[USER_STACK_SIZE]; - xyw_byte system_stack[SYSTEM_MAX_FRAMES * SYSTEM_FRAME_SIZE]; - xyw_byte s, u, x_val, y_val; - xyw_word pc_val, xw_val, yw_val; - xyw_byte error_handler_entry_s; - int argv_processed; - char exec_args[XYW_EXEC_ARGS_SIZE]; - int exec_args_active; - xyw_byte device_state[XYW_TOTAL_DEVICES][XYW_DEVICE_STATE_SIZE]; -} xyw_image_snapshot; - -static xyw_image_snapshot exec_stack[MAX_IMAGE_EXEC_DEPTH]; -static int exec_stack_depth = 0; -static int exec_pending = 0; -static char exec_path_buf[MAX_IMAGE_EXEC_PATH_LENGTH]; - -// Read a null-terminated string out of VM memory into a local buffer -static void get_string_from_memory(xyw_word addr, char *buf, size_t bufsize) -{ - size_t i; - for (i = 0; i < bufsize - 1 && xyw_memory[addr + i] != 0; i++) - buf[i] = xyw_memory[addr + i]; - buf[i] = '\0'; -} - -void xyw_request_exec(xyw_word path_addr) -{ - get_string_from_memory(path_addr, exec_path_buf, sizeof(exec_path_buf)); - exec_pending = 1; -} - -static void split_exec_string(char *full, char **path, char **argstart) -{ - char *sp = strchr(full, ' '); - if (sp) - { - *sp = '\0'; - *argstart = sp + 1; - } - else - { - *argstart = NULL; - } - *path = full; -} - -static void reset_vm_state(void) -{ - memset(xyw_memory, 0, sizeof(xyw_memory)); - memset(user_stack, 0, sizeof(user_stack)); - memset(system_stack, 0, sizeof(system_stack)); - s = 0; - u = 0; - x_val = 0; - y_val = 0; - xw_storage = 0; - yw_storage = 0; - pc_storage = 0; - error_handler_entry_s = 0; - xyw_argv_processed = 0; - xyw_exec_args_active = 0; -} +//// Privileged snapshot/load API -static int load_and_launch(const char *path, char *argstart) +void xyw_vm_save_snapshot(xyw_vm_snapshot *snap) { - FILE *fp = fopen(path, "rb"); - if (!fp) - { - fprintf(stderr, "Error - Could not open file [%s]\n", path); - xyw_memory[SYSTEM_ERROR] = XYW_ERROR_IMAGE_NOT_FOUND; - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; - return -1; - } - size_t bytes_read = fread(&xyw_memory[USER_MEMORY_START], 1, MEMORY_SIZE - USER_MEMORY_START, fp); - fclose(fp); - if (bytes_read == 0) - { - fprintf(stderr, "Error - Could not read file contents [%s]\n", path); - xyw_memory[SYSTEM_ERROR] = XYW_ERROR_IMAGE_READ_ERROR; - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; - return -1; - } - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_RUNNING; - - for (int i = 0; i < XYW_TOTAL_DEVICES; i++) - if (xyw_devices[i].setup) - xyw_devices[i].setup(xyw_devices[i].data); - - xyw_memory[SYSTEM_PAGE] = 0xff; - *pc = 0x0000; - - // Store sub-image arguments for deferred feeding via terminal poll - if (argstart) - { - snprintf(xyw_exec_args, XYW_EXEC_ARGS_SIZE, "%s %s", path, argstart); - xyw_exec_args_active = 1; - } - else - { - xyw_exec_args_active = 0; - } - return 0; -} - -static void save_snapshot(xyw_image_snapshot *snap) -{ - XYW_DBG("== Saving snapshot"); + XYW_DBG("== Saving snapshot\n"); memcpy(snap->memory, xyw_memory, sizeof(xyw_memory)); memcpy(snap->user_stack, user_stack, sizeof(user_stack)); memcpy(snap->system_stack, system_stack, sizeof(system_stack));@@ -518,7 +385,6 @@ snap->y_val = y_val;
snap->pc_val = *pc; snap->xw_val = *xw; snap->yw_val = *yw; - snap->error_handler_entry_s = error_handler_entry_s; snap->argv_processed = xyw_argv_processed; memcpy(snap->exec_args, xyw_exec_args, sizeof(xyw_exec_args)); snap->exec_args_active = xyw_exec_args_active;@@ -527,9 +393,9 @@ if (xyw_devices[i].save)
xyw_devices[i].save(xyw_devices[i].data, snap->device_state[i]); } -static void restore_snapshot(xyw_image_snapshot *snap) +void xyw_vm_restore_snapshot(xyw_vm_snapshot *snap) { - XYW_DBG("== Restoring snapshot"); + XYW_DBG("== Restoring snapshot\n"); memcpy(xyw_memory, snap->memory, sizeof(xyw_memory)); memcpy(user_stack, snap->user_stack, sizeof(user_stack)); memcpy(system_stack, snap->system_stack, sizeof(system_stack));@@ -540,7 +406,6 @@ y_val = snap->y_val;
*pc = snap->pc_val; *xw = snap->xw_val; *yw = snap->yw_val; - error_handler_entry_s = snap->error_handler_entry_s; xyw_argv_processed = snap->argv_processed; memcpy(xyw_exec_args, snap->exec_args, sizeof(xyw_exec_args)); xyw_exec_args_active = snap->exec_args_active;@@ -553,31 +418,44 @@ xyw_devices[i].setup(xyw_devices[i].data);
} } -static void handle_exec_requests(void) +int xyw_vm_load_image(const char *path, const char *args) { - if (!exec_pending) - return; - exec_pending = 0; - - if (exec_stack_depth >= MAX_IMAGE_EXEC_DEPTH) + FILE *fp = fopen(path, "rb"); + if (!fp) + { + fprintf(stderr, "Error - Could not open file [%s]\n", path); + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_IMAGE_NOT_FOUND; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; + return -1; + } + size_t bytes_read = fread(&xyw_memory[0x000], 1, XYW_MEMORY_SIZE - 0x000, fp); + fclose(fp); + if (bytes_read == 0) { - xyw_memory[SYSTEM_ERROR] = XYW_ERROR_EXEC_DEPTH_EXCEEDED; - return; + fprintf(stderr, "Error - Could not read file contents [%s]\n", path); + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_IMAGE_READ_ERROR; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; + return -1; } - save_snapshot(&exec_stack[exec_stack_depth++]); + xyw_memory[SYSTEM_STATE] |= XYW_STATE_RUNNING; - char path_copy[MAX_IMAGE_EXEC_PATH_LENGTH]; - strncpy(path_copy, exec_path_buf, sizeof(path_copy) - 1); - path_copy[sizeof(path_copy) - 1] = '\0'; - char *path, *argstart; - split_exec_string(path_copy, &path, &argstart); + for (int i = 0; i < XYW_TOTAL_DEVICES; i++) + if (xyw_devices[i].setup) + xyw_devices[i].setup(xyw_devices[i].data); - reset_vm_state(); - if (load_and_launch(path, argstart) != 0) + xyw_memory[SYSTEM_PAGE] = 0xff; + *pc = 0x0000; + + if (args) + { + snprintf(xyw_exec_args, XYW_EXEC_ARGS_SIZE, "%s %s", path, args); + xyw_exec_args_active = 1; + } + else { - // Restore parent state so error handler can run in the caller's context - restore_snapshot(&exec_stack[--exec_stack_depth]); + xyw_exec_args_active = 0; } + return 0; } //// Main evaluation function - runs from current pc until BRK@@ -593,19 +471,19 @@ xyw_word saved_yw = *yw;
if (xyw_debug) { - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_DEBUG; + xyw_memory[SYSTEM_STATE] |= XYW_STATE_DEBUG; } while (1) { - if (*pc >= DEVICE_AREA_START) + if (*pc >= XYW_DEVICE_AREA_START) { - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; } if (!system_running_state()) { if (system_waiting_state()) { - // Poll devices for events, then fall back to legacy handler. + // Poll devices for events // poll returns: 1=dispatched, 0=no active handler, -1=active but no event yet int dispatched = 0; while (system_waiting_state())@@ -625,21 +503,19 @@ if (dispatched)
{ continue; // handler was dispatched, go execute it } - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_WAITING; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_WAITING; } - if (exec_stack_depth > 0) + if (xyw_system_try_restore_parent()) { - restore_snapshot(&exec_stack[--exec_stack_depth]); continue; // resume the parent exactly where it left off } break; // no parent -- genuinely done } - // Tick devices (error handling, etc.) + // Tick devices (error handling, exec requests, etc.) for (int i = 0; i < XYW_TOTAL_DEVICES; i++) if (xyw_devices[i].tick) xyw_devices[i].tick(xyw_devices[i].data); - handle_exec_requests(); if (!system_running_state()) { continue;@@ -649,10 +525,10 @@ switch (xyw_memory[*pc])
{ // clang-format off /* HLT */ case 0x00: - xyw_memory[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING; + xyw_memory[SYSTEM_STATE] &= ~XYW_STATE_RUNNING; if (has_poll_devices()) { - xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_WAITING; + xyw_memory[SYSTEM_STATE] |= XYW_STATE_WAITING; } break; /* NOP */ case 0x01: break;@@ -729,7 +605,7 @@ int xyw_run(const char *input)
{ atexit(xyw_teardown_devices); - if (load_and_launch(input, NULL) != 0) + if (xyw_vm_load_image(input, NULL) != 0) { return -1; }