all repos — xyw @ 901c826cbfe0e9d3bc74f925fd40a3da88c757b4

A minimal virtual machine and assembler for terminals.

Changing some instructions to support both registers.
h3rald h3rald@h3rald.com
Mon, 02 Feb 2026 14:54:51 +0100
commit

901c826cbfe0e9d3bc74f925fd40a3da88c757b4

parent

eef2d4ae11690a014987ad0cd1b4240ecabd4ec5

1 files changed, 21 insertions(+), 5 deletions(-)

jump to
M xywrun.cxywrun.c

@@ -243,6 +243,12 @@ case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, rx=1, ry=0; init; body; } break; \

case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=0, ry=1; init; body; } break; \ } +//// Operations that support both registers +#define OPC_SR1r(opc, body) { \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const int w=0, rx=1, ry=1; xyw_byte a = *x; xyw_byte b = *y; body;(void)(w);(void)(a);(void)(b);(void)(rx);(void)(ry); } break; \ + case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=1, ry=1; xyw_word a = *xw; xyw_word b = *yw; body;(void)(w);(void)(a);(void)(b);(void)(rx);(void)(ry); } break; \ +} + // Create address based on direct page or full address #define ADDR(ad) w ? ad : (DIRECT_PAGE | ad) // Push a value to stack

@@ -255,7 +261,6 @@ // Get argument from y register or stack

#define ARGY (ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop())) // Get argument from x or y register or stack #define ARG (rx ? ARGX : (ry ? ARGY : POP())) -//#define ARG (rx ? (w ? *xw : *x) : (ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop()))) // Set value to x register or push to stack #define SETX(v) rx ? (w ? (*xw = v) : (*x = v)) : (w ? us_pushw(v) : us_push(v)) // Set value to y register or push to stack

@@ -296,16 +301,27 @@ {

// clang-format off /* BRK */ case 0x00: return 1; // Simply return from evaluation /* PSH */ OPC_SR1(0x01, , if (rx||ry) { PUSH(ARG); } else { (*pc)++; PUSH(READ(*pc)); if (w) { (*pc)++; } }) + /* PSH */ OPC_SR1r(0x01, PUSH(a); PUSH(b); ) /* POP */ OPC_SR1(0x02, , if (rx||ry) { SET(POP()); } else { POP(); } ); + /* POP */ OPC_SR1r(0x02, if (w) { xyw_word val = us_popw(); *xw = val; *yw = val; } else { xyw_byte val = us_pop(); *x = val; *y = val; } ); /* CLR */ OPC_SR1(0x03, , SET(0)); + /* CLR */ OPC_SR1r(0x03, if (w) { *xw = 0; *yw = 0; } else { *x = 0; *y = 0; } ); /* LDB */ OPC_SR1(0x04, , us_push(read(ADDR(ARG)))); + /* LDB */ OPC_SR1r(0x04, us_push(read(ADDR(ARGX))); us_push(read(ADDR(ARGY))); ); /* LDW */ OPC_SR1(0x05, , us_pushw(readw(ADDR(ARG)) )); - /* STB */ OPC_SR1(0x06, xyw_word addr = ADDR(ARG), write( addr, us_pop() )); - /* STW */ OPC_SR1(0x07, xyw_word addr = ADDR(ARG), writew( addr, us_popw() )); + /* LDW */ OPC_SR1r(0x05, us_pushw(readw(ADDR(ARGX))); us_pushw(readw(ADDR(ARGY))); ); + /* STB */ OPC_SR1(0x06, xyw_word addr = ADDR(ARG); xyw_byte val = us_pop(), write( addr, val )); + /* STB */ OPC_SR1r(0x06, xyw_byte val = us_pop(); write( ADDR(ARGX), val ); write( ADDR(ARGY), val ); ); + /* STW */ OPC_SR1(0x07, xyw_word addr = ADDR(ARG); xyw_word val = us_popw(), writew( addr, val )); + /* STW */ OPC_SR1r(0x07, xyw_word val = us_popw(); writew( ADDR(ARGX), val ); writew( ADDR(ARGY), val ); ); /* INC */ OPC_SR1(0x08, , SET(ARG + 1)); + /* INC */ OPC_SR1r(0x08, SET(ARGX + 1); SET(ARGY + 1); ); /* DEC */ OPC_SR1(0x09, , SET(ARG - 1)); - /* SHL */ OPC_SR1(0x0A, xyw_byte b = us_pop(), PUSH(ARG << b)); - /* SHR */ OPC_SR1(0x0B, xyw_byte b = us_pop(), PUSH(ARG >> b)); + /* DEC */ OPC_SR1r(0x09, SET(ARGX - 1); SET(ARGY - 1); ); + /* SHL */ OPC_SR1(0x0A, xyw_byte val = us_pop(), SET(ARG << val)); + /* SHL */ OPC_SR1r(0x0A, xyw_byte val = us_pop(); SET(ARGX << val); SET(ARGY << val); ); + /* SHR */ OPC_SR1(0x0B, xyw_byte val = us_pop(), SET(ARG >> val)); + /* SHR */ OPC_SR1r(0x0B, xyw_byte val = us_pop(); SET(ARGX >> val); SET(ARGY >> val); ); /* ADD */ OPC_SR2(0x0C, PUSH(a + b)); /* SUB */ OPC_SR2(0x0D, PUSH(a - b)); /* MUL */ OPC_SR2(0x0E, PUSH(a * b));