Refactoring macros.
h3rald h3rald@h3rald.com
Fri, 05 Dec 2025 14:45:07 +0100
1 files changed,
34 insertions(+),
29 deletions(-)
jump to
M
xywrun.c
→
xywrun.c
@@ -207,8 +207,10 @@ }
// clang-format off +#define UNUSED(x) (void)(x) + //// Operations that support stack and all registers -#define OPC_SR2(opc, body) { \ +#define OPC_SR2_old(opc, body) { \ case opc: { const int w = 0, rx=0, ry=0; xyw_byte a = us_pop(), b = us_pop(); body; } break; \ case XYW_MODE_X|opc: { const int w = 0, rx=1, ry=0; xyw_byte a = *x, b = us_pop(); body; } break; \ case XYW_MODE_Y|opc: { const int w = 0, rx=0, ry=1; xyw_byte a = *y, b = us_pop(); body; } break; \@@ -217,10 +219,22 @@ case XYW_MODE_W|opc: { const int w = 1, rx=0, ry=0; xyw_word a = us_popw(); xyw_word b = us_popw(); body; } break; \
case XYW_MODE_X|XYW_MODE_W|opc: { const int w = 1, rx=1, ry=0; xyw_word a = *xw; xyw_word b = us_popw(); body; } break; \ case XYW_MODE_Y|XYW_MODE_W|opc: { const int w = 1, rx=0, ry=1; xyw_word a = *yw; xyw_word b = us_popw(); body; } 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; } break; \ +} + +//// Operations that support stack and all registers +#define OPC_SR2(opc, body) { \ + case opc: { const int w = 0; xyw_byte a = us_pop(), b = us_pop(); body; } break; \ + case XYW_MODE_X|opc: { const int w = 0; xyw_byte a = *x, b = us_pop(); body; } break; \ + case XYW_MODE_Y|opc: { const int w = 0; xyw_byte a = *y, b = us_pop(); body; } break; \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const int w = 0; xyw_byte a = *x, b = *y; body; } break; \ + case XYW_MODE_W|opc: { const int w = 1; xyw_word a = us_popw(); xyw_word b = us_popw(); body; } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const int w = 1; xyw_word a = *xw; xyw_word b = us_popw(); body; } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const int w = 1; xyw_word a = *yw; xyw_word b = us_popw(); body; } break; \ + case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const int w = 1; xyw_word a = *xw; xyw_word b = *yw; body; } break; \ } //// Operations that support stack and one register -#define OPC_SR1(opc, body) { \ +#define OPC_SR1_old(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; \@@ -229,31 +243,21 @@ 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; \ } +#define OPC_SR1(opc, body) { \ + case opc: { const int w=0, r=0; xyw_byte a = us_pop(); body; } break; \ + case XYW_MODE_X|opc: { const int w=0, r=1; xyw_byte a = *x; body; } break; \ + case XYW_MODE_Y|opc: { const int w=0, r=0; xyw_byte a = *y; body; } break; \ + case XYW_MODE_W|opc: { const int w=1, r=0; xyw_word a = us_popw(); body; } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, r=1; xyw_word a = *xw; body; } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, r=0; xyw_word a = *yw; body; } break; \ +} + //// Operations that support stack only #define OPC_S(opc, body) { \ case opc: { const xyw_byte w = 0; body; } break; \ case XYW_MODE_W|opc: { const xyw_byte w = 1; body; } break; \ } -// TODO: Review -#define OPC_STB(opc) { \ - case opc: { xyw_byte a = us_pop(), v = us_pop(); write(DIRECT_PAGE | a, v); } break; \ - case XYW_MODE_W|opc: { xyw_word a = us_popw(), v = us_pop(); write(a, v); } break; \ - case XYW_MODE_X|opc: { write(DIRECT_PAGE | *x, us_pop()); } break; \ - case XYW_MODE_Y|opc: { write(DIRECT_PAGE | *y, us_pop()); } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { write(*xw, us_pop()); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { write(*yw, us_pop()); } break; \ -} - -#define OPC_STW(opc) { \ - case opc: { writew(DIRECT_PAGE | us_pop(), us_popw()); } break; \ - case XYW_MODE_W|opc: { writew(us_popw(), us_popw()); } break; \ - case XYW_MODE_X|opc: { writew(DIRECT_PAGE | *x, us_popw()); } break; \ - case XYW_MODE_Y|opc: { writew(DIRECT_PAGE | *y, us_popw()); } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { writew(*xw, us_popw()); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { writew(*yw, us_popw()); } break; \ -} - //// POP operations #define OPC_POP(opc) { \ case opc: { us_pop(); } break; \@@ -297,11 +301,12 @@ }
//// "Microcode" similar to Uxn's, to be used with above macros // 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())) +//#define ARG rx ? (rx ? (w ? *xw : *x) : (w ? us_popw() : us_pop())) : (ry ? (w ? *yw : *y) : (w ? us_popw() : us_pop())) +//#define ARG r ? (w ? (*xw) : (*x)) : (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) +#define PUSH(n) do { if (w) { us_pushw(n); } else { us_push(n); } } while(0) // Pop value from stack #define POP() (w ? us_popw() : (xyw_word)us_pop())@@ -345,10 +350,10 @@ // clang-format off
/* BRK */ case 0x00: return 0; // Halting execution for now /* PSH */ OPC_PSH(0x01); /* POP */ OPC_POP(0x02); - /* LDB */ OPC_SR1(0x04, us_push(read( ADDR(ARG)) )); - /* LDW */ OPC_SR1(0x05, us_pushw(readw( ADDR(ARG)) )); - /* STB */ OPC_STB(0x06); - /* STW */ OPC_STW(0x07); + /* LDB */ OPC_SR1(0x04, UNUSED(r); us_push(read( ADDR(a)) )); + /* LDW */ OPC_SR1(0x05, UNUSED(r); us_pushw(readw( ADDR(a)) )); + /* STB */ OPC_SR1(0x06, UNUSED(r); write( ADDR(a), us_pop() )); + /* STW */ OPC_SR1(0x07, UNUSED(r); writew( ADDR(a), us_popw() )); /* INC */ OPC_IDC(0x08, +1); /* DEC */ OPC_IDC(0x09, -1); /* SHL */ OPC_SR2(0x0A, PUSH(b << a));@@ -364,9 +369,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(~ARG)); + /* NOT */ OPC_SR1(0x17, UNUSED(r); PUSH(~a)); /* SWP */ OPC_SWP(0x18); - /* DUP */ OPC_SR1(0x19, PUSH(ARG)); + /* DUP */ OPC_SR1(0x19, UNUSED(r); PUSH(a)); /* 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;