all repos — xyw @ f6833929f178103c195a4b1aa0ca604b04f1f3d2

A minimal virtual machine and assembler for terminals.

Fixed ROT and OVR to make sure they work properly and match docs (x/y registers not used).
h3rald h3rald@h3rald.com
Fri, 10 Jul 2026 17:25:28 +0200
commit

f6833929f178103c195a4b1aa0ca604b04f1f3d2

parent

7a7f5e080b37a860387bf893746a37aa83e72a5f

1 files changed, 26 insertions(+), 2 deletions(-)

jump to
M xywrun.cxywrun.c

@@ -277,6 +277,30 @@ 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; \ } +// OVR: Duplicates the second stack item: a b -- a b a +#define OPC_OVR(opc) { \ + case opc: { \ + xyw_byte b = us_pop(); xyw_byte a = us_pop(); \ + us_push(a); us_push(b); us_push(a); \ + } break; \ + case XYW_MODE_W|opc: { \ + xyw_word b = us_popw(); xyw_word a = us_popw(); \ + us_pushw(a); us_pushw(b); us_pushw(a); \ + } break; \ +} + +// ROT: Rotates the third stack item to the top: a b c -- b c a +#define OPC_ROT(opc) { \ + case opc: { \ + xyw_byte c = us_pop(); xyw_byte b = us_pop(); xyw_byte a = us_pop(); \ + us_push(b); us_push(c); us_push(a); \ + } break; \ + case XYW_MODE_W|opc: { \ + xyw_word c = us_popw(); xyw_word b = us_popw(); xyw_word a = us_popw(); \ + us_pushw(b); us_pushw(c); us_pushw(a); \ + } break; \ +} + // Create address based on direct page or full address #define ADDR(ad) (w ? (ad) : (DIRECT_PAGE | (ad))) // Push a value to stack

@@ -454,8 +478,8 @@ /* XOR */ OPC_SR2(0x17, PUSH(a ^ b));

/* DUP */ OPC_SR1(0x18, , SET(TOP)); /* DUP */ OPC_SR1r(0x18, SETX(TOP); SETY(TOP); ); /* SWP */ OPC_SR2(0x19, if ((rx||ry)) { SET(b); } else { PUSH(b); PUSH(a); } ); - /* OVR */ OPC_SR2(0x1A, PUSH(b); PUSH(a); PUSH(b)); - /* ROT */ OPC_SR2(0x1B, PUSH(b); PUSH(POP()); PUSH(a)); + /* OVR */ OPC_OVR(0x1A); + /* ROT */ OPC_ROT(0x1B); /* JMP */ OPC_SR1(0x1C, , *pc = ADDR(ARG)-1;); /* JCN */ OPC_SR1(0x1D, , xyw_word addr = ADDR(ARG); xyw_byte cond = us_pop(); if (cond) { *pc = addr-1; }); /* JSR */ OPC_SR1(0x1E, xyw_word addr = ADDR(ARG), ss_push_frame(*pc+1); *pc = addr-1;);