all repos — xyw @ b7c2e73abf08973731a8804e1f8dc0f84ee252a5

A minimal virtual machine and assembler for terminals.

Implementing argument parsing support (untested).
h3rald h3rald@h3rald.com
Wed, 04 Feb 2026 16:33:14 +0100
commit

b7c2e73abf08973731a8804e1f8dc0f84ee252a5

parent

66dc8e0b4f3b24282e2f7769f0d3ce18516bdbe2

4 files changed, 45 insertions(+), 11 deletions(-)

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

@@ -5,6 +5,7 @@ /* terminal device */

#define TERMINAL_INPUT 0x0 #define TERMINAL_OUTPUT 0x1 #define TERMINAL_ON_KEYPRESS 0x2 +#define TERMINAL_ON_ARGUMENT 0x4 void terminal_output(xyw_byte *data, xyw_byte addr, xyw_byte *error) {

@@ -13,10 +14,20 @@ switch (addr)

{ case TERMINAL_INPUT: { - xyw_word vector = XYW_PEEKW(&data[TERMINAL_ON_KEYPRESS]); - if (vector) + xyw_word handler; + if (!xyw_arguments_processed) + { + // Process input as arguments (separated by XYW_ARGUMENT_SEPARATOR) until XYW_END_OF_ARGUMENTS + handler = XYW_PEEKW(&data[TERMINAL_ON_ARGUMENT]); + } + else + { + // Process stdin keypress + handler = XYW_PEEKW(&data[TERMINAL_ON_KEYPRESS]); + } + if (handler) { - xyw_eval(vector); + xyw_eval(handler); } break; }
M xyw.cxyw.c

@@ -3,6 +3,9 @@ #include <string.h>

#include "xyw.h" int xyw_debug = 0; +int xyw_arguments_processed = 0; +char *xyw_argv[32]; +int xyw_argc = 0; // Instruction mnemonics definition const char xyw_instructions[][4] = {

@@ -29,6 +32,8 @@

int main(int argc, char *argv[]) { (void)argc; + xyw_argc = argc; + *xyw_argv = *argv; for (int i = 1; i < argc; i++) {
M xyw.hxyw.h

@@ -6,6 +6,8 @@ #define XYW_MODE_Y 0x40

#define XYW_MODE_W 0x80 #define XYW_TOTAL_INSTRUCTIONS 0x20 #define XYW_TOTAL_DEVICES 0x10 +#define XYW_ARGUMENT_SEPARATOR 0x0A +#define XYW_END_OF_ARGUMENTS 0x1D // clang-format off #define XYW_PEEKW(d) (*(d) << 8 | (d)[1])

@@ -33,7 +35,10 @@ // clang-format on

extern const char xyw_instructions[][4]; extern int xyw_debug; +extern int xyw_argc; +extern char *xyw_argv[]; extern xyw_device xyw_devices[XYW_TOTAL_DEVICES]; +extern int xyw_arguments_processed; int xyw_assemble(const char *input, const char *output); int xyw_run(const char *input);
M xywrun.cxywrun.c

@@ -27,6 +27,7 @@

/* Terminal device addresses */ #define TERMINAL_INPUT 0xff10 #define TERMINAL_ON_KEYPRESS 0xff12 +#define TERMINAL_ON_ARGUMENT 0xff14 #ifdef _WIN32 #include <conio.h>

@@ -44,11 +45,8 @@ typedef enum

{ XYW_ERROR_NONE = 0, XYW_ERROR_DIVISION_BY_ZERO, - XYW_ERROR_INVALID_INSTRUCTION, XYW_ERROR_STACK_UNDERFLOW, XYW_ERROR_STACK_OVERFLOW, - XYW_ERROR_DEVICE_UNAVAILABLE, - XYW_ERROR_INVALID_DEVICE_PORT } xyw_error; #define SYSTEM_STATE_RUNNING 0x01

@@ -296,7 +294,7 @@

//// Internal VM state xyw_byte error_handler_entry_s = 0; -int process_handlers() +int process_events() { // Error handling if (xyw_memory[SYSTEM_ERROR] != XYW_ERROR_NONE && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR))

@@ -318,6 +316,21 @@ // No error handler, halt execution

return xyw_memory[SYSTEM_ERROR]; } } + // Process terminal arguments if not already done + if (!xyw_arguments_processed && XYW_PEEKW(&xyw_memory[TERMINAL_ON_ARGUMENT]) && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + { + for (int i = 1; i < xyw_argc; i++) + { + const char *arg = xyw_argv[i]; + for (size_t j = 0; arg[j] != '\0'; j++) + { + write(TERMINAL_INPUT, (xyw_byte)arg[j]); + } + write(TERMINAL_INPUT, XYW_ARGUMENT_SEPARATOR); + } + write(TERMINAL_INPUT, XYW_END_OF_ARGUMENTS); + xyw_arguments_processed = 1; + } return 0; }

@@ -333,7 +346,7 @@ xyw_memory[SYSTEM_STATE] |= SYSTEM_STATE_DEBUG;

} while ((xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_RUNNING) && *pc < SYSTEM_MEMORY_START) { - process_handlers(); + 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); switch (xyw_memory[*pc]) {

@@ -432,10 +445,10 @@ int eval_result = xyw_eval(0x0000);

if (!eval_result) { // If terminal handler is set, enter stdin reading loop - xyw_word terminal_handler = XYW_PEEKW(&xyw_memory[TERMINAL_ON_KEYPRESS]); - if (terminal_handler) + 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", terminal_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) { int c = getch();