all repos — xyw @ 1cb27c3473d37b755ef2d2e48fbfb27f4d10a65a

A minimal virtual machine and assembler for terminals.

Refactoring macros
h3rald h3rald@h3rald.com
Fri, 05 Dec 2025 13:40:09 +0100
commit

1cb27c3473d37b755ef2d2e48fbfb27f4d10a65a

parent

838b748a55d21c0e1aa1e65df684c316d274839d

1 files changed, 13 insertions(+), 36 deletions(-)

jump to
M xywrun.cxywrun.c

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

} //// Operations that support stack and one register -#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 -#define OPC_R1(opc, body) { \ - 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_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; \ +#define OPC_SR1(opc, body) { \ + case opc: { const int w=0, rx=0, ry=0; body; } break; \ + case XYW_MODE_X|opc: { const int w=0, rx=1, ry=0; body; } break; \ + case XYW_MODE_Y|opc: { const int w=0, rx=0, ry=1; body; } break; \ + case XYW_MODE_W|opc: { const int w=1, rx=0, ry=0; body; } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, rx=1, ry=0; body; } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=0, ry=1; body; } break; \ } //// Operations that support stack only

@@ -322,28 +314,14 @@ 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 a byte argument from x or stack -#define ARGXB (rx && !!a && !!b) ? *x : us_pop() -// Get a word argument from x or stack -#define ARGXW (rx && !!a && !!b) ? *xw : us_popw() -// 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())) -// Get a byte argument from x/y or stack -#define ARGXYB (rx && !!ry) ? (rx ? *x : *y) : us_pop() -// Get a word argument from x/y or stack -#define ARGXYW (rx && !!ry) ? (rx ? *xw : *yw) : us_popw() +// Get argument from x/y or stack +#define ARG rx ? (rx ? (w ? *xw : *x) : (w ? us_popw() : us_pop())) : (ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop())) +// Create address based on direct page or full address +#define ADDR(ad) w ? ad : (DIRECT_PAGE | ad) // Push a value to stack #define PUSH(n) do { if (w && !!rx && !!ry) { us_pushw(n); } else { us_push(n); } } while(0) // Pop value from stack #define POP() (w ? us_popw() : (xyw_word)us_pop()) -// Write a byte or word to the specified direct page or absolute address -#define WRITE(addr, val) ((w)? writew(addr, val) : write(addr, val)) -// Read a byte or word (depending on w) from the specified direct page or absolute address -#define READ(addr) ((w)? readw(addr) : read(addr)) //// Initialize devices

@@ -385,7 +363,6 @@ // clang-format off

/* BRK */ case 0x00: return 0; // Halting execution for now /* PSH */ OPC_PSH(0x01); /* POP */ OPC_POP(0x02); - ///* LDR */ OPC_R1(0x03, PUSH(READ(a))); // TBD /* LDB */ OPC_LDB(0x04); /* LDW */ OPC_LDW(0x05); /* STB */ OPC_STB(0x06);

@@ -405,9 +382,9 @@ /* 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(~ARGXY)); + /* NOT */ OPC_SR1(0x17, PUSH(~ARG)); /* SWP */ OPC_SWP(0x18); - /* DUP */ OPC_SR1(0x19, , PUSH(ARGXY)); + /* DUP */ OPC_SR1(0x19, PUSH(ARG)); /* 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()-1; break;