Refactored macros in terms of SR1 and SR2
h3rald h3rald@h3rald.com
Mon, 08 Dec 2025 22:16:55 +0100
1 files changed,
18 insertions(+),
44 deletions(-)
jump to
M
xywrun.c
→
xywrun.c
@@ -209,14 +209,14 @@ // clang-format off
//// Operations that support stack and all registers #define OPC_SR2(opc, body) { \ - case opc: { const int w = 0; xyw_byte b = us_pop(), a = us_pop(); body; } break; \ - case XYW_MODE_X|opc: { const int w = 0; xyw_byte b = *x, a = us_pop(); body; } break; \ - case XYW_MODE_Y|opc: { const int w = 0; xyw_byte b = *y, a = 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 b = us_popw(); xyw_word a = us_popw(); body; } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { const int w = 1; xyw_word b = *xw; xyw_word a = us_popw(); body; } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { const int w = 1; xyw_word b = *yw; xyw_word a = 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; \ + case opc: { const int w=0, rx=0, ry=0; xyw_byte b = us_pop(), a = us_pop(); body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_X|opc: { const int w=0, rx=1, ry=0; xyw_byte b = *x, a = us_pop(); body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_Y|opc: { const int w=0, rx=0, ry=1; xyw_byte b = *y, a = us_pop(); body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const int w=0, rx=1, ry=1; xyw_byte a = *x, b = *y; body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_W|opc: { const int w=1, rx=0, ry=0; xyw_word b = us_popw(); xyw_word a = us_popw(); body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, rx=1, ry=0; xyw_word b = *xw; xyw_word a = us_popw(); body; (void)(rx); (void)(ry); } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=0, ry=1; xyw_word b = *yw; xyw_word a = us_popw(); body; (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)(rx); (void)(ry); } break; \ } //// Operations that support stack and one register@@ -229,38 +229,6 @@ 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; \ } -//// POP operations -#define OPC_POP(opc) { \ - case opc: { us_pop(); } break; \ - case XYW_MODE_X|opc: { *x = us_pop(); } break; \ - case XYW_MODE_Y|opc: { *y = us_pop(); } break; \ - case XYW_MODE_W|opc: { us_pop(); } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { *xw = us_popw(); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { *yw = us_popw(); } break; \ -} - -//// PSH operations -#define OPC_PSH(opc) { \ - case opc: { (*pc)++; us_push(xyw_memory[*pc]); } break; \ - case XYW_MODE_X|opc: { us_push(*x); } break; \ - case XYW_MODE_Y|opc: { us_push(*y); } break; \ - case XYW_MODE_W|opc: { (*pc)++; us_pushw(readw(*pc)); (*pc)++; } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { us_pushw(*xw); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { us_pushw(*yw); } break; \ -} - -//// SWP operations -#define OPC_SWP(opc) { \ - case opc: { xyw_byte a = us_pop(); xyw_byte b = us_pop(); us_push(a); us_push(b); } break; \ - case XYW_MODE_W|opc: { xyw_word a = us_popw(); xyw_word b = us_popw(); us_pushw(a); us_pushw(b); } break; \ - case XYW_MODE_X|opc: { xyw_byte a = us_pop(); xyw_byte b = *x; *x = a; us_push(b); } break; \ - case XYW_MODE_Y|opc: { xyw_byte a = us_pop(); xyw_byte b = *y; *y = a; us_push(b); } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { xyw_word a = us_popw(); xyw_word b = *xw; *xw = a; us_pushw(b); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { xyw_word a = us_popw(); xyw_word b = *yw; *yw = a; us_pushw(b); } break; \ - case XYW_MODE_X|XYW_MODE_Y|opc: { xyw_byte a = *x; xyw_byte b = *y; *x = b; *y = a; } break; \ - case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { xyw_word a = *xw; xyw_word b = *yw; *xw = b; *yw = a; } break; \ -} - // Create address based on direct page or full address #define ADDR(ad) w ? ad : (DIRECT_PAGE | ad) // Push a value to stack@@ -269,8 +237,14 @@ // Pop value from stack
#define POP() (w ? us_popw() : (xyw_word)us_pop()) // Get argument from x or y register or stack #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 +#define SETY(v) ry ? (w ? (*yw = v) : (*y = v)) : (w ? us_pushw(v) : us_push(v)) // Set value to x or y register or push to stack -#define SET(v) (rx ? ((w) ? (*xw = v) : (*x = v)) : (ry ? ((w) ? (*yw = v) : (*y = v)) : (w ? us_pushw(v) : us_push(v)))) +#define SET(v) do { if (rx) { SETX(v); } else if (ry) { SETY(v); } else { PUSH(v); } } while(0) +// Read a value from memory +#define READ(addr) (w ? readw(addr) : read(addr)) //// Initialize devices@@ -310,8 +284,8 @@ switch (xyw_memory[*pc])
{ // clang-format off /* BRK */ case 0x00: return 0; // Halting execution for now - /* PSH */ OPC_PSH(0x01); - /* POP */ OPC_POP(0x02); + /* PSH */ OPC_SR1(0x01, , if (rx||ry) { PUSH(ARG); } else { (*pc)++; PUSH(READ(*pc)); if (w) { (*pc)++; } }) + /* POP */ OPC_SR1(0x02, , if (rx||ry) { SET(POP()); } else { POP(); } ); /* CLR */ OPC_SR1(0x03, , SET(0)); /* LDB */ OPC_SR1(0x04, , us_push(read( ADDR(ARG)) )); /* LDW */ OPC_SR1(0x05, , us_pushw(readw( ADDR(ARG)) ));@@ -333,7 +307,7 @@ /* AND */ OPC_SR2(0x14, PUSH(a & b));
/* IOR */ OPC_SR2(0x15, PUSH(a | b)); /* XOR */ OPC_SR2(0x16, PUSH(a ^ b)); /* NOT */ OPC_SR1(0x17, , SET(~ARG)); - /* SWP */ OPC_SWP(0x18); + /* SWP */ OPC_SR2(0x18, if ((rx||ry)) { SET(b); } else { PUSH(a); PUSH(b); } ); /* 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));