all repos — xyw @ ff5582e7e2753386f6ee2048006420a36e513879

A minimal virtual machine and assembler for terminals.

Implemented device stubs
h3rald h3rald@h3rald.com
Wed, 03 Dec 2025 17:12:49 +0100
commit

ff5582e7e2753386f6ee2048006420a36e513879

parent

4e816282d361f040ba2e89d9d9afe8875d126e51

4 files changed, 69 insertions(+), 31 deletions(-)

jump to
A devices/console.c

@@ -0,0 +1,25 @@

+#include "../xyw.h" + +xyw_byte console_read(xyw_byte *data, xyw_byte addr, xyw_byte *error) +{ + (void)error; + return data[addr]; +} + +void console_write(xyw_byte *data, xyw_byte addr, xyw_byte val, xyw_byte *error) +{ + (void)error; + data[addr] = val; +} + +xyw_word console_readw(xyw_byte *data, xyw_byte addr, xyw_byte *error) +{ + (void)error; + return XYW_PEEKW(&data[addr]); +} + +void console_writew(xyw_byte *data, xyw_byte addr, xyw_word val, xyw_byte *error) +{ + (void)error; + XYW_POKEW(&data[addr], val); +}
M xyw.cxyw.c

@@ -15,9 +15,6 @@ "AND", "IOR", "XOR", "NOT",

"SWP", "DUP", "OVR", "ROT", "JMP", "JCN", "JSR", "RTS"}; -// Device table. Populate elsewhere or leave null for unavailable devices. -xyw_device xyw_devices[XYW_TOTAL_DEVICES] = {0}; - //// Main Function int main(int argc, char *argv[]) {
M xyw.hxyw.h

@@ -12,28 +12,13 @@ #define XYW_PEEKW(d) (*(d) << 8 | (d)[1])

#define XYW_POKEW(d, v) { *(d) = (v) >> 8; (d)[1] = (v); } // clang-format on -/* 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 - typedef unsigned char xyw_byte; typedef unsigned short xyw_word; -typedef xyw_byte (*xyw_read)(xyw_byte addr, xyw_byte *error); -typedef void (*xyw_write)(xyw_byte addr, xyw_byte val, xyw_byte *error); -typedef xyw_word (*xyw_readw)(xyw_byte addr, xyw_byte *error); -typedef void (*xyw_writew)(xyw_byte addr, xyw_word val, xyw_byte *error); +typedef xyw_byte (*xyw_read)(xyw_byte *data, xyw_byte addr, xyw_byte *error); +typedef void (*xyw_write)(xyw_byte *data, xyw_byte addr, xyw_byte val, xyw_byte *error); +typedef xyw_word (*xyw_readw)(xyw_byte *data, xyw_byte addr, xyw_byte *error); +typedef void (*xyw_writew)(xyw_byte *data, xyw_byte addr, xyw_word val, xyw_byte *error); typedef struct xyw_device {
M xywrun.cxywrun.c

@@ -2,6 +2,7 @@ #include <stdio.h>

#include "xyw.h" #include "devices/system.c" +#include "devices/console.c" #define MEMORY_SIZE 0xffff #define STACK_SIZE 0xff

@@ -11,6 +12,21 @@ #define SYSTEM_MEMORY_START 0xfd00

#define USER_STACK_START 0xfd00 #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 typedef enum {

@@ -52,7 +68,12 @@ {

return (addr - DEVICE_AREA_START) / 16; } -static inline xyw_byte get_device_port(xyw_word addr) +static inline xyw_byte *get_device_data(xyw_word addr) +{ + return xyw_devices[get_device(addr)].data; +} + +static inline xyw_byte get_device_address(xyw_word addr) { // Should return a number between 0 and 15, add validation xyw_byte port = (addr - DEVICE_AREA_START) % 16;

@@ -76,8 +97,8 @@ {

*error = XYW_ERROR_DEVICE_UNAVAILABLE; return (xyw_word)-1; } - xyw_byte dev_addr = get_device_port(addr); - return xyw_devices[dev_num].readw(dev_addr, error); + xyw_byte dev_addr = get_device_address(addr); + return xyw_devices[dev_num].readw(get_device_data(addr), dev_addr, error); } return XYW_PEEKW(&xyw_memory[addr]); }

@@ -92,8 +113,8 @@ {

*error = XYW_ERROR_DEVICE_UNAVAILABLE; return; } - xyw_byte dev_addr = get_device_port(addr); - xyw_devices[dev_num].writew(dev_addr, val, error); + xyw_byte dev_addr = get_device_address(addr); + xyw_devices[dev_num].writew(get_device_data(addr), dev_addr, val, error); return; } XYW_POKEW(&xyw_memory[addr], val);

@@ -109,8 +130,8 @@ {

*error = XYW_ERROR_DEVICE_UNAVAILABLE; return (xyw_byte)-1; } - xyw_byte dev_addr = get_device_port(addr); - return xyw_devices[dev_num].read(dev_addr, error); + xyw_byte dev_addr = get_device_address(addr); + return xyw_devices[dev_num].read(get_device_data(addr), dev_addr, error); } return xyw_memory[addr]; }

@@ -125,8 +146,8 @@ {

*error = XYW_ERROR_DEVICE_UNAVAILABLE; return; } - xyw_byte dev_addr = get_device_port(addr); - xyw_devices[dev_num].write(dev_addr, val, error); + xyw_byte dev_addr = get_device_address(addr); + xyw_devices[dev_num].write(get_device_data(addr), dev_addr, val, error); return; } xyw_memory[addr] = val;

@@ -305,6 +326,16 @@ // Read value from address

#define READ(addr) (w ? readw(addr) : (xyw_byte)xyw_memory[addr]) // Write value as word or byte depending on width flag 'w' #define WRITE(addr, val) w ? writew(addr, val) : write(addr, (xyw_byte)(val)) + +//// Initialize devices + +xyw_device xyw_devices[XYW_TOTAL_DEVICES] = { + // System device (not implemented yet) + {&xyw_memory[0xff00], system_read, system_write, system_readw, system_writew}, + // Console device + {&xyw_memory[0xff10], console_read, console_write, console_readw, console_writew}, + // ... +}; // clang-format on int xyw_run(const char *input)