all repos — xyw @ 52409605a05c1facf8527cbe6cae6dd43f0de8e7

A minimal virtual machine and assembler for terminals.

Changed instructions, again... not ok though.
h3rald h3rald@h3rald.com
Thu, 04 Dec 2025 14:28:00 +0100
commit

52409605a05c1facf8527cbe6cae6dd43f0de8e7

parent

ccafef89ab690f9057c9418df692f2d9a4740be1

2 files changed, 25 insertions(+), 22 deletions(-)

jump to
M xyw.cxyw.c

@@ -7,7 +7,7 @@

// Instruction mnemonics definition const char xyw_instructions[][4] = { "BRK", "PSH", "POP", "???", - "LDB", "LDW", "STB", "STW", + "LDP", "LDR", "STP", "STR", "INC", "DEC", "SHL", "SHR", "ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH",
M xywrun.cxywrun.c

@@ -209,14 +209,14 @@ // clang-format off

//// 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; \ + case opc: { const xyw_byte w = 0, rx=0, ry=0, a = us_pop(), b = us_pop(); body; } break; \ + case XYW_MODE_X|opc: { const xyw_byte w = 0, a = *x, b = us_pop(), rx=1, ry=0; body; } break; \ + case XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *y, b = us_pop(), rx=0, ry=1; body; } break; \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const xyw_byte w = 0, a = *x, b = *y, rx=1, ry=1; body; } break; \ + case XYW_MODE_W|opc: { const xyw_byte 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 xyw_byte 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 xyw_byte 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 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

@@ -287,22 +287,25 @@

//// "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 ? *x : us_pop() +// Get a word argument from x or stack +#define ARGXW rx ? *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 ? (rx ? *x : *y) : us_pop() +// Get a word argument from x/y or stack +#define ARGXYW rx ? (rx ? *xw : *yw) : us_popw() // Push a value to stack -#define PUSH(n) do { if (w) { us_pushw(n); } else { us_push(n); } } while(0) +#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()) -// Read a byte from absolute address or direct page -#define READB(addr) (w ? read(addr) : read(DIRECT_PAGE | addr)) -// Read a word from absolute address or direct page -#define READW(addr) (w ? readw(addr) : readw(DIRECT_PAGE | addr)) -// Write a byte to absolute address or direct page -#define WRITEB(addr, val) w ? write(addr, val) : write(DIRECT_PAGE | addr, val) -// Write a word to absolute address or direct page -#define WRITEW(addr, val) w ? writew(addr, val) : writew(DIRECT_PAGE | addr, val) +// Write a byte or word to the specified direct page or absolute address +#define WRITE(addr, val) ((w && !!a && !!b)? writew(addr, val) : write(addr, val)) + //// Initialize devices

@@ -344,10 +347,10 @@ /* 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_SR1(0x04, , us_push(READB(ARGXY))); - /* LDW */ OPC_SR1(0x05, , us_pushw(READW(ARGXY))); - /* STB */ OPC_SR2(0x06, WRITEB(b, a)); - /* STW */ OPC_SR2(0x07, WRITEW(b, a)); + /* LDP */ OPC_SR1(0x04, , PUSH(read(ARGXYB))); + /* LDR */ OPC_SR1(0x05, , PUSH(readw(ARGXYW))); + /* STP */ OPC_SR2(0x06, WRITE(DIRECT_PAGE | ARGXB, ARGY)); + /* STR */ OPC_SR2(0x07, WRITE(ARGXW, ARGY)); /* INC */ OPC_IDC(0x08, +1); /* DEC */ OPC_IDC(0x09, -1); /* SHL */ OPC_SR2(0x0A, PUSH(b << a));