Implementing devices + refactoring.
h3rald h3rald@h3rald.com
Wed, 03 Dec 2025 16:07:20 +0100
M
xyw.c
→
xyw.c
@@ -15,6 +15,9 @@ "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[]) {@@ -52,7 +55,7 @@ else if (ext && strcmp(ext, ".xim") == 0)
{ // Load and run the .xim file // (Assuming a run function exists) - if (run(input_file) != 0) + if (xyw_run(input_file) != 0) { fprintf(stderr, "Execution failed for file: %s\n", input_file); return -1;
M
xyw.h
→
xyw.h
@@ -5,18 +5,38 @@ #define XYW_MODE_X 0x20
#define XYW_MODE_Y 0x40 #define XYW_MODE_W 0x80 #define XYW_TOTAL_INSTRUCTIONS 0x20 +#define XYW_TOTAL_DEVICES 0x10 // clang-format off -#define xyw_dbg(...) do { if (xyw_debug) fprintf(stdout, __VA_ARGS__); } while(0) +#define PEEKW(d) (*(d) << 8 | (d)[1]) +#define POKEW(d, v) { *(d) = (v) >> 8; (d)[1] = (v); } // clang-format on 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 struct xyw_device +{ + xyw_read read; + xyw_write write; + xyw_readw readw; + xyw_writew writew; +} xyw_device; + +// clang-format off +#define xyw_dbg(...) do { if (xyw_debug) fprintf(stdout, __VA_ARGS__); } while(0) +// clang-format on + extern const char xyw_instructions[][4]; extern int xyw_debug; +extern xyw_device xyw_devices[XYW_TOTAL_DEVICES]; int xyw_assemble(const char *input, const char *output); -int run(const char *input); +int xyw_run(const char *input); #endif // XYW_H
M
xywrun.c
→
xywrun.c
@@ -16,7 +16,7 @@ XYW_ERROR_NONE = 0,
XYW_ERROR_INVALID_INSTRUCTION, XYW_ERROR_STACK_UNDERFLOW, XYW_ERROR_STACK_OVERFLOW, - XYW_ERROR_DEVICE_ERROR + XYW_ERROR_DEVICE_UNAVAILABLE } xyw_error; /* system device */@@ -48,6 +48,7 @@ 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[SYSTEM_ERROR]; //// 2-byte registers static xyw_word pc_storage = 0; // Program counter storage@@ -57,28 +58,107 @@ xyw_word *pc = &pc_storage;
xyw_word *xw = &xw_storage; xyw_word *yw = &yw_storage; +//// Helpers to retrieve device number and address within the device +static inline xyw_byte get_device(xyw_word addr) +{ + return (addr - DEVICE_AREA_START) / 16; +} + +static inline xyw_byte get_device_address(xyw_word addr) +{ + return (addr - DEVICE_AREA_START) % 16; +} + //// Read/write memory helpers +// Device read/write dispatchers +static inline xyw_byte device_read(xyw_word addr, xyw_byte *error) +{ + xyw_byte dev_num = get_device(addr); + if (dev_num >= XYW_TOTAL_DEVICES || !xyw_devices[dev_num].read) + { + *error = XYW_ERROR_DEVICE_UNAVAILABLE; + return -1; + } + xyw_byte dev_addr = get_device_address(addr); + return xyw_devices[dev_num].read(dev_addr, error); +} + +static inline xyw_word device_readw(xyw_word addr, xyw_byte *error) +{ + xyw_byte dev_num = get_device(addr); + if (dev_num >= XYW_TOTAL_DEVICES || !xyw_devices[dev_num].readw) + { + *error = XYW_ERROR_DEVICE_UNAVAILABLE; + return -1; + } + xyw_byte dev_addr = get_device_address(addr); + return xyw_devices[dev_num].readw(dev_addr, error); +} + +static inline void device_write(xyw_word addr, xyw_byte val, xyw_byte *error) +{ + xyw_byte dev_num = get_device(addr); + if (dev_num >= XYW_TOTAL_DEVICES || !xyw_devices[dev_num].write) + { + *error = XYW_ERROR_DEVICE_UNAVAILABLE; + return; + } + xyw_byte dev_addr = get_device_address(addr); + xyw_devices[dev_num].write(dev_addr, val, error); +} + +static inline void device_writew(xyw_word addr, xyw_word val, xyw_byte *error) +{ + xyw_byte dev_num = get_device(addr); + if (dev_num >= XYW_TOTAL_DEVICES || !xyw_devices[dev_num].writew) + { + *error = XYW_ERROR_DEVICE_UNAVAILABLE; + return; + } + xyw_byte dev_addr = get_device_address(addr); + xyw_devices[dev_num].writew(dev_addr, val, error); +} + static inline xyw_word readw(xyw_word addr) { - return ((xyw_word)xyw_memory[addr] << 8) | xyw_memory[addr + 1]; + if (addr >= DEVICE_AREA_START) + { + return device_readw(xyw_memory[addr], error); + } + return PEEKW(&xyw_memory[addr]); } static inline void writew(xyw_word addr, xyw_word val) { - xyw_memory[addr] = (val >> 8) & 0xFF; - xyw_memory[addr + 1] = val & 0xFF; + if (addr >= DEVICE_AREA_START) + { + device_writew(xyw_memory[addr], val, error); + return; + } + POKEW(&xyw_memory[addr], val); } static inline xyw_byte read(xyw_word addr) { + if (addr >= DEVICE_AREA_START) + { + return device_read(addr, error); + } return xyw_memory[addr]; } static inline void write(xyw_word addr, xyw_byte val) { + if (addr >= DEVICE_AREA_START) + { + device_write(addr, val, error); + return; + } xyw_memory[addr] = val; } + +//// Device dispatchers //// System stack management@@ -248,12 +328,12 @@ #define PUSH(n) do { if (w) { us_pushw(n); } else { us_push(n); } } while(0)
// Pop value from stack #define POP() (w ? us_popw() : (xyw_word)us_pop()) // Read value from address -#define READ(addr) (w ? readw(addr) : (xyw_byte)read(addr)) +#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)) // clang-format on -int run(const char *input) +int xyw_run(const char *input) { // Load bytecode into memory