all repos — xyw @ c54bdeb50c701fa4ba93d588094404ba709a0966

A minimal virtual machine and assembler for terminals.

Removed STA/STP specific macros.
h3rald h3rald@h3rald.com
Wed, 03 Dec 2025 09:57:27 +0100
commit

c54bdeb50c701fa4ba93d588094404ba709a0966

parent

32dd9979ac97267c51760c0b4e71aea1d8f54012

1 files changed, 18 insertions(+), 32 deletions(-)

jump to
M xywrun.cxywrun.c

@@ -162,33 +162,13 @@ case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; xyw_word b = *yw; body; } break; \

} //// Operations that support stack and one register -#define OPC_SR1(opc, body) { \ - case opc: { const xyw_byte w = 0, a = us_pop(); body; } break; \ - case XYW_MODE_X|opc: { const xyw_byte w = 0, a = *x; body; } break; \ - case XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *y; body; } break; \ - case XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = us_popw(); body; } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; body; } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *yw; body; } break; \ -} - -//// STA -#define OPC_STA(opc, body) { \ - case opc: { const xyw_word a = us_popw(); const xyw_byte w = 0, b = us_pop(); body; } break; \ - case XYW_MODE_X|opc: { const xyw_word a = us_popw(); const xyw_byte w = 0, b = *x; body; } break; \ - case XYW_MODE_Y|opc: { const xyw_word a = us_popw(); const xyw_byte w = 0, b = *y; body; } break; \ - case XYW_MODE_W|opc: { const xyw_word a = us_popw(); const xyw_byte w = 1; xyw_word b = us_popw(); body; } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = us_popw(), b = *xw; body; } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = us_popw(), b = *yw; body; } break; \ -} - -//// STP -#define OPC_STP(opc, body) { \ - case opc: { const xyw_word a = DIRECT_PAGE | us_pop(); const xyw_byte w = 0, b = us_pop(); body; } break; \ - case XYW_MODE_X|opc: { const xyw_word a = DIRECT_PAGE | us_pop(); const xyw_byte w = 0, b = *x; body; } break; \ - case XYW_MODE_Y|opc: { const xyw_word a = DIRECT_PAGE | us_pop(); const xyw_byte w = 0, b = *y; body; } break; \ - case XYW_MODE_W|opc: { const xyw_word a = DIRECT_PAGE | us_pop(); const xyw_byte w = 1; xyw_word b = us_popw(); body; } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = DIRECT_PAGE | us_pop(), b = *xw; body; } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = DIRECT_PAGE | us_pop(), b = *yw; body; } break; \ +#define OPC_SR1(opc, init, body) { \ + case opc: { const int w=0, rx=0, ry=0; init; body; } break; \ + case XYW_MODE_X|opc: { const int w=0, rx=1, ry=0; init; body; } break; \ + case XYW_MODE_Y|opc: { const int w=0, rx=0, ry=1; init; body; } break; \ + case XYW_MODE_W|opc: { const int w=1, rx=0, ry=0; init; body; } break; \ + 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 one register only and no stack

@@ -247,6 +227,12 @@ case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { xyw_word a = *xw; xyw_word b = *yw; *xw = b; *yw = a; } break; \

} //// "Microcode" similar to Uxn's, to be used with above macros +// Get argument from x or stack +#define ARGX rx ? (w ? *xw : *x) : (w ? us_popw() : us_pop()) +// Get argument from y or stack +#define ARGY ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop()) +// Get arguments from x/y or stack +#define ARGXY rx ? (rx ? (w ? *xw : *x) : (w ? us_popw() : us_pop())) : (ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop())) // Push a value to stack #define PUSH(n) do { if (w) { us_pushw(n); } else { us_push(n); } } while(0) // Pop value from stack

@@ -300,9 +286,9 @@ /* PSH */ OPC_PSH(0x01);

/* POP */ OPC_POP(0x02); /* LDR */ OPC_R1(0x03, PUSH(READ(a))); /* LDA */ OPC_S(0x04, READ(us_popw())); - /* STA */ OPC_STA(0x05, WRITE(a, b)); + /* STA */ OPC_SR1(0x05, xyw_word a = us_popw(), WRITE(a, ARGXY)); /* LDP */ OPC_S(0x06, READ(DIRECT_PAGE | us_pop())); - /* STP */ OPC_STP(0x07, WRITE(a, b)); + /* STP */ OPC_SR1(0x07, xyw_word a = DIRECT_PAGE | us_pop(), WRITE(a, ARGXY)); /* INC */ OPC_IDC(0x08, +1); /* DEC */ OPC_IDC(0x09, -1); /* SHL */ OPC_SR2(0x0A, PUSH(b << a));

@@ -318,13 +304,13 @@ /* LTH */ OPC_SR2(0x13, PUSH(b < a));

/* AND */ OPC_SR2(0x14, PUSH(b & a)); /* IOR */ OPC_SR2(0x15, PUSH(b | a)); /* XOR */ OPC_SR2(0x16, PUSH(b ^ a)); - /* NOT */ OPC_SR1(0x17, PUSH(~a)); + /* NOT */ OPC_SR1(0x17, , PUSH(~ARGXY)); /* SWP */ OPC_SWP(0x18); - /* DUP */ OPC_SR1(0x19, PUSH(a)); + /* DUP */ OPC_SR1(0x19, , PUSH(ARGXY)); /* OVR */ OPC_SR2(0x1A, PUSH(b); PUSH(a); PUSH(b)); /* ROT */ OPC_SR2(0x1B, PUSH(b); PUSH(POP()); PUSH(a)); /* JMP */ case 0x1C: *pc = us_popw(); break; - /* JCN */ OPC_SR1(0x1D, if (a) { *pc = POP(); } ); + /* JCN */ OPC_SR1(0x1D, , if (ARGXY) { *pc = POP(); } ); /* JSR */ case 0x1E: xyw_word addr = us_popw(); ss_pushw(*pc); *pc = addr; break; /* RTS */ case 0x1F: *pc = ss_popw(); break; // clang-format on