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];
}
/* check literal stack and push 4 top values as hex short literal if not empty and discard the rest of the stack */
void attemptPushNumericLiteral() {
/* clear the literal stack */
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 */
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 */
instr = ram.cmdbuf[++ram.pc];
/* first, check for II mode */
if(ram.II) {
if(instr == ')')
if(instr == INS_IIEND)
ram.II = 0; /* unset instruction ignore mode flag */
continue;
}
/* then, check for compilation mode */
if(ram.CM) {
if(instr == ';') { /* trigger word compilation logic as per the spec */
ram.cmdbuf[ram.pc] = 'R'; /* in-place patch this instruction to R */
if(instr == INS_CMEND) { /* trigger word compilation logic as per the spec */
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.cltp; /* increase the word */
if(ram.cltp == CLT_ENTRIES_MAX) {
trapout(CLT_OVERFLOW);
break;
}
ram.CM = 0; /* unset compilation mode flag */
}
continue;
@@ -285,11 +311,92 @@ void equi_main_loop() {
continue;
}
/* then trigger literal auto-push if applicable */
if(instr != '"' && instr != '\'' && instr != '#' && instr != ':')
attemptPushNumericLiteral();
switch(instr) {
default:
if(ram.lsp > 0 && instr != INS_LITSTR && instr != INS_LITCALL && instr != INS_LITINT && instr != INS_CMSTART)
pushLitVal(0);
switch(instr) { /* then perform all main interpretation logic */
case INS_IISTART: /* instruction ignore start */
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;
}
continue;
@@ -333,12 +440,12 @@ int main(int argc, char* argv[]) {
cputc(instr); /* echo it */
#endif
--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__
cputc(instr); /* echo it */
#endif
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__
cputc(instr); /* echo it */
#endif