Refactoring.
h3rald h3rald@h3rald.com
Tue, 02 Dec 2025 12:59:21 +0100
1 files changed,
60 insertions(+),
40 deletions(-)
jump to
M
xywrun.c
→
xywrun.c
@@ -110,7 +110,7 @@ xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_OVERFLOW;
return; } xyw_dbg(" => %02X\n", val); - user_stack[(*u)++] = val; + xyw_memory[USER_STACK_START + (*u)++] = val; } static void us_pushw(xyw_word val)@@ -154,8 +154,9 @@ {
xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return -1; } - xyw_byte val = user_stack[--(*u)]; - user_stack[*u] = 0; + (*u) -= 1; + xyw_byte val = xyw_memory[USER_STACK_START + (*u)]; + xyw_memory[USER_STACK_START + (*u)] = 0; return val; }@@ -179,8 +180,9 @@ {
xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return; } - *x = user_stack[--(*u)]; - user_stack[*u] = 0; + (*u) -= 1; + *x = xyw_memory[USER_STACK_START + (*u)]; + xyw_memory[USER_STACK_START + (*u)] = 0; } static void POPy()@@ -190,8 +192,9 @@ {
xyw_memory[SYSTEM_ERROR] = XYW_ERROR_STACK_UNDERFLOW; return; } - *y = user_stack[--(*u)]; - user_stack[*u] = 0; + (*u) -= 1; + *y = xyw_memory[USER_STACK_START + (*u)]; + xyw_memory[USER_STACK_START + (*u)] = 0; } static void POPxw()@@ -338,28 +341,45 @@ {
*pc = ss_popw(); } +// clang-format off +//// Operations that support all mode combinations +#define OPC_XYW(opc, init, body) { \ + case opc: { const xyw_byte w = 0, a = POP(), b = POP(); init body; } break; \ + case XYW_MODE_X|opc: { const xyw_byte w = 0, a = *x, b = POP(); init body; } break; \ + case XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *y, b = POP(); init body; } break; \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *x, b = *y; init body; } break; \ + case XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = POPw(); xyw_word b = POPw(); init body; } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; xyw_word b = POPw(); init body; } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *yw; xyw_word b = POPw(); init body; } break; \ + case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; xyw_word b = *yw; init body; } break; \ +} + +//// Operations that support X or Y and W modes only +#define OPC_XorYW(opc, init, body) { \ + case opc: { const xyw_byte w = 0, a = POP(); init body; } break; \ + case XYW_MODE_X|opc: { const xyw_byte w = 0, a = *x; init body; } break; \ + case XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *y; init body; } break; \ + case XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = POPw(); init body; } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; init body; } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *yw; init body; } break; \ +} + +//// Operations that support W mode only +#define OPC_W(opc, init, body) { \ + case opc: { const xyw_byte w = 0; init body; } break; \ + case XYW_MODE_W|opc: { const xyw_byte w = 1; init body; } break; \ +} + +//// "Microcode" similar to Uxn's, to be used with above macros +#define PUSH(n) if (w) { us_pushw(n); } else { us_push(n); } + +// clang-format on + //// Macros for instruction implementations +//// TODO: Refactor to use above macros // clang-format off // Infix operations -#define InOP(opcode, op) \ - case opcode: us_push(POP() op POP()); break; \ - case XYW_MODE_X|opcode: us_push(*x op POP()); break; \ - case XYW_MODE_Y|opcode: us_push(*y op POP()); break; \ - case XYW_MODE_W|opcode: us_pushw(POPw() op POPw()); break; \ - case XYW_MODE_X|XYW_MODE_W|opcode: us_pushw(*xw op POPw()); break; \ - case XYW_MODE_Y|XYW_MODE_W|opcode: us_pushw(*yw op POPw()); break; \ - case XYW_MODE_X|XYW_MODE_Y|opcode: us_push(*x op *y); break; \ - case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opcode: us_pushw(*xw op *yw); break; - -// Unary operations -#define UnOP(opcode, op) \ - case opcode: us_push(op(POP())); break; \ - case XYW_MODE_X|opcode: us_push(op(*x)); break; \ - case XYW_MODE_Y|opcode: us_push(op(*y)); break; \ - case XYW_MODE_W|opcode: us_pushw(op(POPw())); break; \ - case XYW_MODE_X|XYW_MODE_W|opcode: us_pushw(op(*xw)); break; \ - case XYW_MODE_Y|XYW_MODE_W|opcode: us_pushw(op(*yw)); break; // Postfix-ish operations (INC/DEC) #define PoOP(opcode, op) \@@ -375,7 +395,7 @@ #define PrOP2(opcode, op) \
case opcode: op(POP(), POP()); break; \ case XYW_MODE_X|opcode: op(*x, POP()); break; \ case XYW_MODE_Y|opcode: op(*y, POP()); break; \ - case XYW_MODE_X|XYW_MODE_Y|opcode: op(*x, *y); break; \ + case XYW_MODE_X|XYW_MODE_Y|opcode: op(*x, *y); break; // Prefix operations with two 2-byte operands #define PrOP2w(opcode, op) \@@ -463,20 +483,20 @@ /* STP */ PrOP(0x07, STP);
/* STPw */ PrOPw(0x07, STPw); /* INC */ PoOP(0x08, + 1); /* DEC */ PoOP(0x09, - 1); - /* SHL */ InOP(0x0A, <<); - /* SHR */ InOP(0x0B, >>); - /* ADD */ InOP(0x0C, +); - /* SUB */ InOP(0x0D, -); - /* MUL */ InOP(0x0E, *); - /* DIV */ InOP(0x0F, /); - /* EQU */ InOP(0x10, ==); - /* NEQ */ InOP(0x11, !=); - /* GTH */ InOP(0x12, >); - /* LTH */ InOP(0x13, <); - /* AND */ InOP(0x14, &); - /* IOR */ InOP(0x15, |); - /* XOR */ InOP(0x16, ^); - /* NOT */ UnOP(0x17, ~); + /* SHL */ OPC_XYW(0x0A, , PUSH(b << a)); + /* SHR */ OPC_XYW(0x0B, , PUSH(b >> a)); + /* ADD */ OPC_XYW(0x0C, , PUSH(a + b)); + /* SUB */ OPC_XYW(0x0D, , PUSH(b - a)); + /* MUL */ OPC_XYW(0x0E, , PUSH(a * b)); + /* DIV */ OPC_XYW(0x0F, , PUSH(b / a)); + /* EQU */ OPC_XYW(0x10, , PUSH(b == a)); + /* NEQ */ OPC_XYW(0x11, , PUSH(b != a)); + /* GTH */ OPC_XYW(0x12, , PUSH(b > a)); + /* LTH */ OPC_XYW(0x13, , PUSH(b < a)); + /* AND */ OPC_XYW(0x14, , PUSH(b & a)); + /* IOR */ OPC_XYW(0x15, , PUSH(b | a)); + /* XOR */ OPC_XYW(0x16, , PUSH(b ^ a)); + /* NOT */ OPC_XorYW(0x17, , PUSH(~a)); /* SWP */ PrOP2(0x18, SWP); /* SWPw */ PrOP2w(0x18, SWPw); /* DUP */ PrOP(0x19, DUP);