all repos — xyw @ f3e372ef508e00222024c991003a9a4b5e14ac01

A minimal virtual machine and assembler for terminals.

Fixed label resolution.
h3rald h3rald@h3rald.com
Thu, 04 Dec 2025 15:28:13 +0100
commit

f3e372ef508e00222024c991003a9a4b5e14ac01

parent

8b28522294cec55794d1bc8a7698830d72db009e

2 files changed, 46 insertions(+), 8 deletions(-)

jump to
M xywasm.cxywasm.c

@@ -482,7 +482,9 @@ else if (sym->type == SYMBOL_TYPE_LABEL)

{ xyw_dbg("Label Ref:\t%s -> %04X\n", token, sym->address); // Push label address - push(sym->address); + append(PSH | XYW_MODE_W); + XYW_POKEW(&data[ptr], sym->address); + ptr += 2; } else if (sym->type == SYMBOL_TYPE_REF) {
M xywrun.cxywrun.c

@@ -243,6 +243,42 @@ case opc: { const xyw_byte w = 0; body; } break; \

case XYW_MODE_W|opc: { const xyw_byte w = 1; body; } break; \ } +#define OPC_LDB(opc) { \ + case opc: { us_push(read( DIRECT_PAGE | us_pop())); } break; \ + case XYW_MODE_W|opc: { us_push(read(us_popw())); } break; \ + case XYW_MODE_X|opc: { us_push(read(DIRECT_PAGE | *x)); } break; \ + case XYW_MODE_Y|opc: { us_push(read(DIRECT_PAGE | *y)); } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { us_push(read(*xw)); } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { us_push(read(*yw)); } break; \ +} + +#define OPC_LDW(opc) { \ + case opc: { us_pushw(readw( DIRECT_PAGE | us_pop())); } break; \ + case XYW_MODE_W|opc: { us_pushw(readw(us_popw())); } break; \ + case XYW_MODE_X|opc: { us_pushw(readw(DIRECT_PAGE | *x)); } break; \ + case XYW_MODE_Y|opc: { us_pushw(readw(DIRECT_PAGE | *y)); } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { us_pushw(readw(*xw)); } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { us_pushw(readw(*yw)); } break; \ +} + +#define OPC_STB(opc) { \ + case opc: { write(DIRECT_PAGE | us_pop(), us_pop()); } break; \ + case XYW_MODE_W|opc: { write(us_popw(), us_pop()); } 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; \

@@ -349,10 +385,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(w ? READ(ARGXYW) : READ(DIRECT_PAGE | ARGXYB))); - /* LDW */ OPC_SR1(0x05, , us_pushw(w ? READ(ARGXYW) : READ(DIRECT_PAGE | ARGXYB))); - /* STB */ OPC_SR2(0x06, write(DIRECT_PAGE | ARGXB, ARGY)); - /* STW */ OPC_SR2(0x07, writew(ARGXW, ARGY)); + /* LDB */ OPC_LDB(0x04); + /* LDW */ OPC_LDW(0x05); + /* STB */ OPC_STB(0x06); + /* STW */ OPC_STW(0x07); /* INC */ OPC_IDC(0x08, +1); /* DEC */ OPC_IDC(0x09, -1); /* SHL */ OPC_SR2(0x0A, PUSH(b << a));

@@ -373,14 +409,14 @@ /* SWP */ OPC_SWP(0x18);

/* DUP */ OPC_SR1(0x19, , PUSH(ARGXY)); /* 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(); break; - /* JCN */ OPC_SR1(0x1D, , if (ARGXY) { *pc = POP(); } ); + /* JMP */ case 0x1C: *pc = us_popw()-1; break; + /* JCN */ OPC_SR1(0x1D, , if (ARGXY) { *pc = POP()-1; } ); /* JSR */ case 0x1E: xyw_word addr = us_popw(); ss_pushw(*pc); *pc = addr-1; break; /* RTS */ case 0x1F: *pc = ss_popw()-1; break; // clang-format on } // TODO: error handling etc. - // At present, JSR and RTS set the pc to 1 value less than the actual address + // At present, JCN, JMP, JSR and RTS set the pc to 1 value less than the actual address // because we are relying on the fact that pc will be incremented at the end of the loop (*pc)++; }