all repos — xyw @ 364f21b11c14e3b2e7349144bbfb69949fe64358

A minimal virtual machine and assembler for terminals.

Implemented basic console IO (untested)
h3rald h3rald@h3rald.com
Wed, 03 Dec 2025 17:17:31 +0100
commit

364f21b11c14e3b2e7349144bbfb69949fe64358

parent

ff5582e7e2753386f6ee2048006420a36e513879

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

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

@@ -1,14 +1,36 @@

+#include <stdio.h> #include "../xyw.h" +/* console device */ +#define XYW_CONSOLE_INPUT 0x0 +#define XYW_CONSOLE_OUTPUT 0x1 +#define XYW_CONSOLE_ERROR 0x2 +#define XYW_CONSOLE_ON_KEYPRESS 0x3 + xyw_byte console_read(xyw_byte *data, xyw_byte addr, xyw_byte *error) { (void)error; + if (addr == XYW_CONSOLE_INPUT) + { + return (xyw_byte)getchar(); + } return data[addr]; } void console_write(xyw_byte *data, xyw_byte addr, xyw_byte val, xyw_byte *error) { (void)error; + switch (addr) + { + case XYW_CONSOLE_OUTPUT: + putchar(val); + fflush(stdout); + break; + case XYW_CONSOLE_ERROR: + fputc(val, stderr); + fflush(stderr); + break; + } data[addr] = val; }
M xywrun.cxywrun.c

@@ -14,19 +14,12 @@ #define SYSTEM_STACK_START 0xfe00

#define DEVICE_AREA_START 0xff00 /* system device */ -#define XYW_SYSTEM_STATE 0xff00 -#define XYW_SYSTEM_ERROR 0xff01 -#define XYW_SYSTEM_S 0xff02 -#define XYW_SYSTEM_U 0xff03 -#define XYW_SYSTEM_PAGE 0xff04 -#define XYW_SYSTEM_ON_ERROR 0xff05 - -/* console device */ -#define XYW_CONSOLE_BASE 0xff10 -#define XYW_CONSOLE_INPUT 0xff10 -#define XYW_CONSOLE_OUTPUT 0xff11 -#define XYW_CONSOLE_ERROR 0xff12 -#define XYW_CONSOLE_ON_KEYPRESS 0xff13 +#define SYSTEM_STATE 0xff00 +#define SYSTEM_ERROR 0xff01 +#define SYSTEM_S 0xff02 +#define SYSTEM_U 0xff03 +#define SYSTEM_PAGE 0xff04 +#define SYSTEM_ON_ERROR 0xff05 typedef enum {

@@ -43,16 +36,16 @@ xyw_byte xyw_memory[MEMORY_SIZE];

xyw_byte system_stack[STACK_SIZE]; xyw_byte user_stack[STACK_SIZE]; -#define DIRECT_PAGE (xyw_memory[XYW_SYSTEM_PAGE] << 8) +#define DIRECT_PAGE (xyw_memory[SYSTEM_PAGE] << 8) //// 1-byte pointers and registers -xyw_byte *s = &xyw_memory[XYW_SYSTEM_S]; -xyw_byte *u = &xyw_memory[XYW_SYSTEM_U]; +xyw_byte *s = &xyw_memory[SYSTEM_S]; +xyw_byte *u = &xyw_memory[SYSTEM_U]; static xyw_byte x_val = 0; // X register storage static xyw_byte y_val = 0; // Y register storage xyw_byte *x = &x_val; xyw_byte *y = &y_val; -xyw_byte *error = &xyw_memory[XYW_SYSTEM_ERROR]; +xyw_byte *error = &xyw_memory[SYSTEM_ERROR]; //// 2-byte registers static xyw_word pc_storage = 0; // Program counter storage

@@ -161,7 +154,7 @@ static xyw_word ss_popw()

{ if (*s < 2) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return -1; } xyw_word val = readw(SYSTEM_STACK_START + (*s) - 2);

@@ -174,7 +167,7 @@ static void ss_pushw(xyw_word val)

{ if (*s > STACK_SIZE - 2) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; return; } writew(SYSTEM_STACK_START + *s, val);

@@ -187,7 +180,7 @@ static void us_push(xyw_byte val)

{ if (*u > STACK_SIZE - 1) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; return; } xyw_dbg(" => %02X\n", val);

@@ -198,7 +191,7 @@ static void us_pushw(xyw_word val)

{ if (*u > STACK_SIZE - 2) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW; return; } writew(USER_STACK_START + *u, val);

@@ -210,7 +203,7 @@ static xyw_byte us_pop()

{ if (*u < 1) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return -1; } (*u) -= 1;

@@ -223,7 +216,7 @@ static xyw_word us_popw()

{ if (*u < 2) { - xyw_memory[XYW_SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; + xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return -1; } xyw_word val = readw(USER_STACK_START + (*u) - 2);

@@ -369,8 +362,8 @@ return -1;

} xyw_dbg("Loaded %zu bytes into memory\n", bytes_read); fclose(fp); - xyw_memory[XYW_SYSTEM_STATE] = 1; - while (xyw_memory[XYW_SYSTEM_STATE] && *pc < SYSTEM_MEMORY_START) + xyw_memory[SYSTEM_STATE] = 1; + while (xyw_memory[SYSTEM_STATE] && *pc < SYSTEM_MEMORY_START) { xyw_dbg("PC: %04X -> %02X (%s)\n", *pc, xyw_memory[*pc], xyw_instructions[xyw_memory[*pc] & 0x1F]); switch (xyw_memory[*pc])