all repos — xyw @ 8764fae314a41e64b965282339428b0632b4f583

A minimal virtual machine and assembler for terminals.

xyw.c

 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
#include <stdio.h>

typedef unsigned char xyw_byte;
typedef unsigned short xyw_short;

#define MEMORY_SIZE 0xffff
#define STACK_SIZE 0xff
#define DEVICE_AREA_START 0x0000
#define SYSTEM_STACK_START 0x0100
#define USER_STACK_START 0x0200
#define USER_MEMORY_START 0x0300

/* system device */
#define SYSTEM_STATE 0x00
#define SYSTEM_ERROR 0x01
#define SYSTEM_SSP 0x02
#define SYSTEM_USP 0x03
#define SYSTEM_X 0x04
#define SYSTEM_Y 0x05
#define SYSTEM_XW 0x06
#define SYSTEM_YW 0x08
#define SYSTEM_PC 0x0A
#define SYSTEM_ON_ERROR 0x0C

/* console device */
#define CONSOLE_BASE 0x10
#define CONSOLE_INPUT 0x10
#define CONSOLE_OUTPUT 0x11
#define CONSOLE_ERROR 0x12
#define CONSOLE_ON_KEYPRESS 0x13

/* clock device */
#define CLOCK_YEAR 0x20
#define CLOCK_MONTH 0x22
#define CLOCK_WEEK 0x23
#define CLOCK_MONTHDAY 0x24
#define CLOCK_WEEKDAY 0x25
#define CLOCK_HOUR 0x26
#define CLOCK_MINUTE 0x27
#define CLOCK_SECOND 0x28
#define CLOCK_TIMER 0x29
#define CLOCK_ON_TIMER_ELAPSED 0x2B

/* file device */
#define FILE_PATH 0x30
#define FILE_OPERATION 0x32
#define FILE_STATE 0x33
#define FILE_TYPE 0x34
#define FILE_READ 0x35
#define FILE_WRITE 0x36
#define FILE_APPEND 0x37

/* video device */
#define VIDEO_WIDTH 0x40
#define VIDEO_HEIGHT 0x41
#define VIDEO_FILL 0x42
#define VIDEO_X 0x43
#define VIDEO_Y 0x44
#define VIDEO_ON_RENDER 0x45

/* audio device */
#define AUDIO_STATE 0x50
#define AUDIO_SAMPLES 0x51
#define AUDIO_N_SAMPLES 0x53
#define AUDIO_ON_STOP 0x55

xyw_byte xyw_memory[MEMORY_SIZE];

//// 1-byte pointers
xyw_byte *ssp = &xyw_memory[SYSTEM_STACK_START];
xyw_byte *usp = &xyw_memory[USER_STACK_START];
xyw_byte *x = &xyw_memory[SYSTEM_X];
xyw_byte *y = &xyw_memory[SYSTEM_Y];

//// Helpers to manage 2-byte values to memory (big-endian)

static inline xyw_short mget(xyw_short addr)
{
    return ((xyw_short)xyw_memory[addr] << 8) | xyw_memory[addr + 1];
}

static inline void mset(xyw_short addr, xyw_short val)
{
    xyw_memory[addr] = (val >> 8) & 0xFF;
    xyw_memory[addr + 1] = val & 0xFF;
}

static inline void madd(xyw_short addr, int delta)
{
    xyw_short val = mget(addr);
    mset(addr, (xyw_short)(val + delta));
}

//// Helpers for common registers

static inline xyw_short pc(void) { return mget(SYSTEM_PC); }
static inline void pc_set(xyw_short val) { mset(SYSTEM_PC, val); }
static inline void pc_add(int delta) { madd(SYSTEM_PC, delta); }
static inline xyw_short xw(void) { return mget(SYSTEM_XW); }
static inline void xw_set(xyw_short val) { mset(SYSTEM_XW, val); }
static inline void xw_add(int delta) { madd(SYSTEM_XW, delta); }
static inline xyw_short yw(void) { return mget(SYSTEM_YW); }
static inline void yw_set(xyw_short val) { mset(SYSTEM_YW, val); }
static inline void yw_add(int delta) { madd(SYSTEM_YW, delta); }