all repos — xyw @ c54e00b21018baefa7107d57ef6c34642eda51b3

A minimal virtual machine and assembler for terminals.

xyw.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
#ifndef XYW_H
#define XYW_H

// Registers and memory
#define XYW_MODE_X 0x80
#define XYW_MODE_Y 0x40
#define XYW_MODE_W 0x20
#define XYW_TOTAL_INSTRUCTIONS 0x20
#define XYW_TOTAL_DEVICES 0x10
#define XYW_DEVICE_AREA_START 0xff00
#define XYW_ARGUMENT_SEPARATOR 0x1E
#define XYW_END_OF_ARGUMENTS 0x1D

// System state flags (architectural constants for SYSTEM_STATE register)
#define XYW_STATE_RUNNING 0x01
#define XYW_STATE_WAITING 0x02
#define XYW_STATE_DEBUG   0x40
#define XYW_STATE_ERROR   0x80

// 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

typedef unsigned char xyw_byte;
typedef unsigned short xyw_word;

// clang-format off
#define XYW_PEEKW(d) (*(d) << 8 | (d)[1])
#define XYW_POKEW(d, v) { *(d) = (v) >> 8; (d)[1] = (v); }
#define XYW_DBG(...) do { if (xyw_debug) fprintf(stdout, __VA_ARGS__); } while(0)
// clang-format on

// 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_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);
typedef void (*xyw_restore)(xyw_byte *data, const xyw_byte *state);
typedef void (*xyw_tick)(xyw_byte *data);

#define XYW_DEVICE_STATE_SIZE 64

typedef struct xyw_device
{
    xyw_byte *data;
    xyw_setup setup;
    xyw_input input;
    xyw_output output;
    xyw_teardown teardown;
    xyw_poll poll;
    xyw_save save;
    xyw_restore restore;
    xyw_tick tick;
} xyw_device;

// Main Globals
extern xyw_device xyw_devices[XYW_TOTAL_DEVICES];
extern const char xyw_instructions[][4];
extern int xyw_debug;
extern int xyw_argc;
extern char *xyw_argv[];
extern int xyw_argv_processed;

// Exec args: set by VM exec logic, read by terminal during poll
#define XYW_EXEC_ARGS_SIZE 256
extern char xyw_exec_args[XYW_EXEC_ARGS_SIZE];
extern int xyw_exec_args_active;

// Main public API
int xyw_assemble(const char *input, const char *output);
int xyw_run(const char *input);
int xyw_eval(xyw_word pc);

// Privileged VM API (for device implementations)
extern xyw_byte xyw_memory[];
extern xyw_word *pc, *xw, *yw;
extern xyw_byte *x, *y;
extern xyw_byte *dev_error;

void xyw_vm_push_frame(xyw_word return_addr);
xyw_word xyw_vm_pop_frame(void);
xyw_byte xyw_vm_get_system_depth(void);

void xyw_vm_set_running(int running);
void xyw_vm_set_waiting(int waiting);
int xyw_vm_is_running(void);
int xyw_vm_is_waiting(void);
int xyw_vm_is_error_state(void);

void xyw_vm_reset(void);

// VM snapshot (for exec stack management by system device)
#define XYW_MEMORY_SIZE 0x10000
#define XYW_USER_STACK_SIZE 128
#define XYW_SYSTEM_STACK_SIZE 384

typedef struct {
    xyw_byte memory[XYW_MEMORY_SIZE];
    xyw_byte user_stack[XYW_USER_STACK_SIZE];
    xyw_byte system_stack[XYW_SYSTEM_STACK_SIZE];
    xyw_byte s, u, x_val, y_val;
    xyw_word pc_val, xw_val, yw_val;
    int argv_processed;
    char exec_args[XYW_EXEC_ARGS_SIZE];
    int exec_args_active;
    xyw_byte device_state[XYW_TOTAL_DEVICES][XYW_DEVICE_STATE_SIZE];
} xyw_vm_snapshot;

void xyw_vm_save_snapshot(xyw_vm_snapshot *snap);
void xyw_vm_restore_snapshot(xyw_vm_snapshot *snap);
int xyw_vm_load_image(const char *path, const char *args);
int xyw_system_try_restore_parent(void);

#endif // XYW_H