browser

devlog-opcode-macros.c

devlog-opcode-macros.c
calendarsave
//// Operations that support stack and all registers
#define OPC_SR2(opc, body) { \
    case opc: { const xyw_byte w = 0, a = us_pop(), b = us_pop(); body; } break; \
    case XYW_MODE_X|opc: { const xyw_byte w = 0, a = *x, b = us_pop(); body; } break; \
    case XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *y, b = us_pop(); body; } break; \
    case XYW_MODE_X|XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *x, b = *y; body; } break; \
    case XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = us_popw(); xyw_word b = us_popw(); body; } break; \
    case XYW_MODE_X|XYW_MODE_W|opc: { const xyw_byte w = 1; xyw_word a = *xw; xyw_word b = us_popw(); body; } break; \
    case XYW_MODE_Y|XYW_MODE_W|opc: { const xyw_byte 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 xyw_byte w = 1; xyw_word a = *xw; xyw_word b = *yw; body; } break; \
}

/// ... more macros like these... you get the picture ;)

//// 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; \
}

/// "Microcode" similar to Uxn's, to be used with above macros

// Push a value to stack
#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())
// Read value from address
#define READ(addr) (w ? mget(addr) : (xyw_byte)xyw_memory[addr])
// Write value to address
#define WRITE(addr, val) do { if (w) { mset(addr, val); } else { xyw_memory[addr] = val; } } while(0)