some instruction progress

This commit is contained in:
Luxferre
2022-08-08 11:07:24 +03:00
parent d2f4b058d2
commit 898f1f22d3
+122 -15
View File
@@ -245,35 +245,61 @@ uchar popLit() {
return ram.literal_stack[--ram.lsp]; return ram.literal_stack[--ram.lsp];
} }
/* check literal stack and push 4 top values as hex short literal if not empty and discard the rest of the stack */ /* clear the literal stack */
void attemptPushNumericLiteral() { void clearLit() {
ram.lsp = 0; /* clear the literal stack */
}
/* shape 2-byte vlaue on the main stack from the 4 values of the literal stack */
void pushLitVal(strict) {
uchar p1, p2, p3, p4;
if(ram.lsp < 4) { /* if we don't strictly expect 4 bytes, do nothing */
if(strict) trapout(STACK_UNDERFLOW);
else {
ram.lsp = 0; /* clear the literal stack */
return;
}
}
else {
p4 = popLit();
p3 = popLit();
p2 = popLit();
p1 = popLit();
pushMain((p1<<12) | (p2<<8) | (p3<<4) | p4);
ram.lsp = 0; /* clear the literal stack */
}
} }
/* Main interpreter loop */ /* Main interpreter loop */
void equi_main_loop() { void equi_main_loop() {
uchar instr; uchar instr, i;
/* reset all stacks before running and reinit CLT */
ram.msp = ram.rsp = ram.lsp = ram.cltp = 0;
/* reset pc */
ram.pc = 65535;
while(1) { /* iterate over the instructions in the command buffer */ while(1) { /* iterate over the instructions in the command buffer */
instr = ram.cmdbuf[++ram.pc]; instr = ram.cmdbuf[++ram.pc];
/* first, check for II mode */ /* first, check for II mode */
if(ram.II) { if(ram.II) {
if(instr == ')') if(instr == INS_IIEND)
ram.II = 0; /* unset instruction ignore mode flag */ ram.II = 0; /* unset instruction ignore mode flag */
continue; continue;
} }
/* then, check for compilation mode */ /* then, check for compilation mode */
if(ram.CM) { if(ram.CM) {
if(instr == ';') { /* trigger word compilation logic as per the spec */ if(instr == INS_CMEND) { /* trigger word compilation logic as per the spec */
ram.cmdbuf[ram.pc] = 'R'; /* in-place patch this instruction to R */ ram.cmdbuf[ram.pc] = INS_RET; /* in-place patch this instruction to R */
/* compiled words are saved vice versa to save code size */
for(i=0;i<CLT_ENTRY_LEN;++i)
ram.clt[ram.cltp].name[i] = popLit();
ram.lsp = 0; /* clear the literal stack */
ram.clt[ram.cltp].loc = ram.cbp; /* stored the compiled code location from the most recent CBP value */ ram.clt[ram.cltp].loc = ram.cbp; /* stored the compiled code location from the most recent CBP value */
++ram.cltp; /* increase the word */ ++ram.cltp; /* increase the word */
if(ram.cltp == CLT_ENTRIES_MAX) { if(ram.cltp == CLT_ENTRIES_MAX) {
trapout(CLT_OVERFLOW); trapout(CLT_OVERFLOW);
break; break;
} }
ram.CM = 0; /* unset compilation mode flag */ ram.CM = 0; /* unset compilation mode flag */
} }
continue; continue;
@@ -285,11 +311,92 @@ void equi_main_loop() {
continue; continue;
} }
/* then trigger literal auto-push if applicable */ /* then trigger literal auto-push if applicable */
if(instr != '"' && instr != '\'' && instr != '#' && instr != ':') if(ram.lsp > 0 && instr != INS_LITSTR && instr != INS_LITCALL && instr != INS_LITINT && instr != INS_CMSTART)
attemptPushNumericLiteral(); pushLitVal(0);
switch(instr) { switch(instr) { /* then perform all main interpretation logic */
case INS_IISTART: /* instruction ignore start */
default: ram.II = 1; /* raise II flag */
break;
case INS_CMSTART: /* compilation start */
ram.cbp = ram.pc + 1; /* save CBP */
ram.CM = 1; /* raise CM flag */
break;
case INS_QUIT: /* gracefully quit the interpretation mode */
goto brx;
case INS_LITINT: /* literal stack -> main stack as short */
pushLitVal(1);
break;
case INS_LITSTR:
break;
case INS_LITCALL:
break;
case INS_RET:
ram.pc = popRet();
break;
case INS_M2R:
break;
case INS_R2M:
break;
case INS_LOAD:
break;
case INS_STORE:
break;
case INS_STOREBYTE:
break;
case INS_DROP:
break;
case INS_DUP:
break;
case INS_SWAP:
break;
case INS_ROT:
break;
case INS_OVER:
break;
case INS_JUMP:
break;
case INS_IF:
break;
case INS_EXPOINT: /* Locate execution point */
pushMain(ram.pc + 1);
break;
case INS_GT:
break;
case INS_LT:
break;
case INS_EQ:
break;
case INS_ADD:
break;
case INS_SUB:
break;
case INS_MUL:
break;
case INS_DIV:
break;
case INS_NEG:
break;
case INS_NOT:
break;
case INS_AND:
break;
case INS_OR:
break;
case INS_XOR:
break;
case INS_COUT:
break;
case INS_NBKIN:
case INS_BKIN:
break;
case INS_PORTIO:
break;
case INS_PERSIST_READ:
break;
case INS_PERSIST_WRITE:
break;
default: /* all characters not processed before are invalid instructions */
trapout(INVALID_INSTRUCTION);
goto brx; goto brx;
} }
continue; continue;
@@ -333,12 +440,12 @@ int main(int argc, char* argv[]) {
cputc(instr); /* echo it */ cputc(instr); /* echo it */
#endif #endif
--ram.ibp; --ram.ibp;
} else if(instr == '(') { /* process II just to avoid quitting in command mode */ } else if(instr == INS_IISTART) { /* process II just to avoid quitting in command mode */
#ifdef __CC65__ #ifdef __CC65__
cputc(instr); /* echo it */ cputc(instr); /* echo it */
#endif #endif
ram.II = 1; ram.II = 1;
} else if(instr == ')') { /* process II just to avoid quitting in command mode */ } else if(instr == INS_IIEND) { /* process II just to avoid quitting in command mode */
#ifdef __CC65__ #ifdef __CC65__
cputc(instr); /* echo it */ cputc(instr); /* echo it */
#endif #endif