Added more error codes, fixed minor inconsistencies.
@@ -114,9 +114,10 @@ #endif
return -1; // active handler, no event yet } -void clock_setup(xyw_byte *data) +void clock_setup(xyw_byte *data, xyw_byte *error) { (void)data; + (void)error; clock_timer_active = 0; clock_timer_elapsed_pending = 0; #ifdef _WIN32
@@ -1,6 +1,6 @@
#include "../xyw.h" -void clock_setup(xyw_byte *data); +void clock_setup(xyw_byte *data, xyw_byte *error); xyw_byte clock_input(xyw_byte *data, xyw_byte addr, xyw_byte *error); void clock_output(xyw_byte *data, xyw_byte addr, xyw_byte *error); int clock_poll(xyw_byte *data);
@@ -578,8 +578,9 @@
XYW_POKEW(&data[FILE_SUCCESS], 1); } -void file_setup(xyw_byte *data) +void file_setup(xyw_byte *data, xyw_byte *error) { + (void)error; // Close any open file file_close();
@@ -1,5 +1,5 @@
#include "../xyw.h" -void file_setup(xyw_byte *data); +void file_setup(xyw_byte *data, xyw_byte *error); xyw_byte file_input(xyw_byte *data, xyw_byte addr, xyw_byte *error); void file_output(xyw_byte *data, xyw_byte addr, xyw_byte *error);
@@ -24,9 +24,10 @@ 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) +void system_setup(xyw_byte *data, xyw_byte *error) { (void)data; + (void)error; srand(time(NULL)); error_handler_entry_s = 0; error_handler_armed = 0;
@@ -1,6 +1,6 @@
#include "../xyw.h" -void system_setup(xyw_byte *data); +void system_setup(xyw_byte *data, xyw_byte *error); 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);
@@ -16,7 +16,8 @@ #define TERMINAL_OUTPUT 0x1
#define TERMINAL_ON_KEYPRESS 0x2 #define TERMINAL_ON_ARGUMENT 0x4 -#define POLL_INTERVAL_MS 100 +#define TERMINAL_POLL_INTERVAL_MS 100 +#define TERMINAL_ERROR_NOT_A_TTY 0x11 //// Platform-specific non-blocking key input@@ -33,7 +34,7 @@ }
#else static int getch_timeout(int timeout_ms) { - (void)timeout_ms; // bounded by VMIN=0/VTIME in terminal_init() + (void)timeout_ms; // bounded by VMIN=0/VTIME in terminal_setup() int c = getchar(); return (c == EOF) ? 0 : c; }@@ -126,7 +127,7 @@ // Keypress handling
xyw_word on_keypress_handler = XYW_PEEKW(&data[TERMINAL_ON_KEYPRESS]); if (on_keypress_handler) { - int c = getch_timeout(POLL_INTERVAL_MS); + int c = getch_timeout(TERMINAL_POLL_INTERVAL_MS); if (c > 0) { if (c == 3 || c == 4)@@ -148,9 +149,10 @@ }
//// Device init/teardown/IO -void terminal_init(xyw_byte *data) +void terminal_setup(xyw_byte *data, xyw_byte *error) { (void)data; + (void)error; // Reset arg feeding state for fresh image arg_index = 1; arg_char_pos = 0;@@ -160,12 +162,14 @@ struct termios raw;
if (!isatty(STDIN_FILENO)) { + *error = TERMINAL_ERROR_NOT_A_TTY; return; } if (tcgetattr(STDIN_FILENO, &terminal_orig_termios) != 0) { XYW_DBG("terminal: tcgetattr failed, raw mode not enabled\n"); + *error = TERMINAL_ERROR_NOT_A_TTY; return; }@@ -177,6 +181,7 @@
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) != 0) { XYW_DBG("terminal: tcsetattr failed, raw mode not enabled\n"); + *error = TERMINAL_ERROR_NOT_A_TTY; return; }
@@ -1,6 +1,6 @@
#include "../xyw.h" -void terminal_init(xyw_byte *data); +void terminal_setup(xyw_byte *data, xyw_byte *error); void terminal_output(xyw_byte *data, xyw_byte addr, xyw_byte *error); xyw_byte terminal_input(xyw_byte *data, xyw_byte addr, xyw_byte *error); void terminal_teardown(xyw_byte *data);
@@ -22,11 +22,14 @@
// System Errors #define XYW_SYSTEM_ERROR_NONE 0x00 #define XYW_SYSTEM_ERROR_DIVISION_BY_ZERO 0x01 -#define XYW_SYSTEM_ERROR_STACK_UNDERFLOW 0x02 -#define XYW_SYSTEM_ERROR_STACK_OVERFLOW 0x03 -#define XYW_SYSTEM_ERROR_EXEC_DEPTH_EXCEEDED 0x04 -#define XYW_SYSTEM_ERROR_IMAGE_NOT_FOUND 0x05 -#define XYW_SYSTEM_ERROR_IMAGE_READ_ERROR 0x06 +#define XYW_SYSTEM_ERROR_USER_STACK_UNDERFLOW 0x02 +#define XYW_SYSTEM_ERROR_USER_STACK_OVERFLOW 0x03 +#define XYW_SYSTEM_ERROR_SYSTEM_STACK_UNDERFLOW 0x04 +#define XYW_SYSTEM_ERROR_SYSTEM_STACK_OVERFLOW 0x05 +#define XYW_SYSTEM_ERROR_EXEC_DEPTH_EXCEEDED 0x06 +#define XYW_SYSTEM_ERROR_IMAGE_NOT_FOUND 0x07 +#define XYW_SYSTEM_ERROR_IMAGE_READ_ERROR 0x08 +#define XYW_SYSTEM_ERROR_INVALID_OPCODE 0x09 typedef unsigned char xyw_byte; typedef unsigned short xyw_word;@@ -40,7 +43,7 @@
// Devices API typedef xyw_byte (*xyw_input)(xyw_byte *data, xyw_byte addr, xyw_byte *error); typedef void (*xyw_output)(xyw_byte *data, xyw_byte addr, xyw_byte *error); -typedef void (*xyw_setup)(xyw_byte *data); +typedef void (*xyw_setup)(xyw_byte *data, xyw_byte *error); typedef void (*xyw_teardown)(xyw_byte *data); typedef int (*xyw_poll)(xyw_byte *data); // returns: 1=dispatched, 0=inactive, -1=active but no event typedef void (*xyw_save)(xyw_byte *data, xyw_byte *state);
@@ -119,7 +119,7 @@ static void ss_push_frame(xyw_word return_addr)
{ if (s >= SYSTEM_MAX_FRAMES) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_SYSTEM_STACK_OVERFLOW; return; } xyw_byte *base = &system_stack[s * SYSTEM_FRAME_SIZE];@@ -138,7 +138,7 @@ static xyw_word ss_pop_frame()
{ if (s < 1) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_SYSTEM_STACK_UNDERFLOW; return -1; } s--;@@ -218,7 +218,7 @@ static void us_push(xyw_byte val)
{ if (u > XYW_USER_STACK_SIZE - 1) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_USER_STACK_OVERFLOW; return; } XYW_DBG(" => %02X\n", val);@@ -229,7 +229,7 @@ static void us_pushw(xyw_word val)
{ if (u > XYW_USER_STACK_SIZE - 2) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_USER_STACK_OVERFLOW; return; } user_stack[u] = (xyw_byte)(val >> 8);@@ -242,7 +242,7 @@ static xyw_byte us_pop()
{ if (u < 1) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_USER_STACK_UNDERFLOW; return -1; } u -= 1;@@ -255,7 +255,7 @@ static xyw_word us_popw()
{ if (u < 2) { - xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_USER_STACK_UNDERFLOW; return -1; } xyw_word val = (xyw_word)((user_stack[u - 2] << 8) | user_stack[u - 1]);@@ -351,7 +351,7 @@ xyw_device xyw_devices[XYW_TOTAL_DEVICES] = {
// System device {DEV_DATA(0), system_setup, system_input, system_output, 0, 0, system_save, system_restore, system_tick}, // Terminal device - {DEV_DATA(1), terminal_init, terminal_input, terminal_output, terminal_teardown, terminal_poll, terminal_save, terminal_restore, 0}, + {DEV_DATA(1), terminal_setup, terminal_input, terminal_output, terminal_teardown, terminal_poll, terminal_save, terminal_restore, 0}, // Clock device {DEV_DATA(2), clock_setup, clock_input, clock_output, 0, clock_poll, 0, 0, 0}, // File device@@ -412,9 +412,13 @@ xyw_exec_args_active = snap->exec_args_active;
for (int i = 0; i < XYW_TOTAL_DEVICES; i++) { if (xyw_devices[i].restore) + { xyw_devices[i].restore(xyw_devices[i].data, snap->device_state[i]); + } else if (xyw_devices[i].setup) - xyw_devices[i].setup(xyw_devices[i].data); + { + xyw_devices[i].setup(xyw_devices[i].data, dev_error); + } } }@@ -440,9 +444,13 @@ }
xyw_memory[SYSTEM_STATE] |= XYW_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_devices[i].setup(xyw_devices[i].data, dev_error); + } + } + xyw_memory[SYSTEM_PAGE] = 0xff; *pc = 0x0000;@@ -580,6 +588,9 @@ /* JCN */ OPC_SR1(0x1D, , xyw_word addr = ADDR(ARG); xyw_byte cond = us_pop(); if (cond) { *pc = addr-1; });
/* JSR */ OPC_SR1(0x1E, xyw_word addr = ADDR(ARG), ss_push_frame(*pc+1); *pc = addr-1;); /* RTS */ case 0x1F: *pc = ss_pop_frame()-1; + break; + default: + xyw_memory[SYSTEM_ERROR] = XYW_SYSTEM_ERROR_INVALID_OPCODE; break; // clang-format on }