Fix UC command

* UC0 should restore values pushed by US/TPx
* UC1 should stop when the stack top is a page call
* UC1/2 should restore status pushes by TPx
* UC1/2 should not consume the count for non-call stack frames
* Add support for UC3 command
This commit is contained in:
kichikuou
2023-02-10 20:56:53 +09:00
parent 4f1521ac90
commit 8087d11b2b
3 changed files with 63 additions and 28 deletions
+8 -4
View File
@@ -33,12 +33,16 @@ void commandUC() { /* 王道勇者 */
switch(mode) {
case 0:
sl_stackClear_allCall(); break;
sl_clearStack(true);
break;
case 1:
sl_stackClear_labelCall(num); break;
sl_dropLabelCalls(num);
break;
case 2:
sl_stackClear_pageCall(num); break;
default:
sl_dropPageCalls(num);
break;
case 3:
sl_clearStack(false);
break;
}
DEBUG_COMMAND("UC %d,%d:",mode,num);
+52 -21
View File
@@ -317,44 +317,75 @@ void sl_retFar2(void) {
}
/* UC0 */
void sl_stackClear_allCall(void) {
free(stack_buf);
stack_buf = calloc(stack_size, sizeof(int));
if (stack_buf == NULL)
NOMEMERR();
void sl_clearStack(bool restore) {
if (!restore) {
stack_top = stack_buf;
return;
}
while (stack_top > stack_buf) {
int *tmp = sl_pop();
switch (*tmp) {
case STACK_NEARJMP:
case STACK_FARJMP:
break;
case STACK_VARIABLE:
popVars(tmp);
break;
case STACK_TXXSTATE:
popState(tmp);
break;
default:
SYSERROR("broken stack");
}
free(tmp);
}
labelCallCnt = pageCallCnt = 0;
stack_top = stack_buf;
}
/* UC 2 */
void sl_stackClear_pageCall(int cnt) {
int *tmp;
while(cnt--) {
tmp = sl_pop();
if (*tmp == STACK_NEARJMP) {
void sl_dropPageCalls(int cnt) {
while (cnt > 0 && stack_top > stack_buf) {
int *tmp = sl_pop();
switch (*tmp) {
case STACK_NEARJMP:
labelCallCnt--;
} else if (*tmp == STACK_FARJMP) {
break;
case STACK_FARJMP:
pageCallCnt--;
} else if (*tmp == STACK_VARIABLE) {
cnt--;
break;
case STACK_VARIABLE:
popVars(tmp);
} else {
SYSERROR("Stack buffer is illegal");
break;
case STACK_TXXSTATE:
popState(tmp);
break;
default:
SYSERROR("broken stack");
}
free(tmp);
}
}
/* UC 1 */
void sl_stackClear_labelCall(int cnt) {
while (cnt--) {
void sl_dropLabelCalls(int cnt) {
while (cnt > 0 && stack_top > stack_buf && stack_top[-1] != STACK_FARJMP) {
int *tmp = sl_pop();
if (*tmp == STACK_NEARJMP) {
switch (*tmp) {
case STACK_NEARJMP:
labelCallCnt--;
} else if (*tmp == STACK_VARIABLE) {
cnt--;
break;
case STACK_VARIABLE:
popVars(tmp);
} else {
SYSERROR("No label call to pop");
break;
case STACK_TXXSTATE:
popState(tmp);
break;
default:
SYSERROR("broken stack");
}
free(tmp);
}
+3 -3
View File
@@ -69,9 +69,9 @@ void sl_callFar(int page);
void sl_callFar2(int page, int address);
void sl_retFar(void);
void sl_retFar2(void);
void sl_stackClear_allCall(void);
void sl_stackClear_labelCall(int cnt);
void sl_stackClear_pageCall(int cnt);
void sl_clearStack(bool restore);
void sl_dropLabelCalls(int cnt);
void sl_dropPageCalls(int cnt);
void sl_pushVar(struct VarRef *vref, int cnt);
void sl_popVar(struct VarRef *vref, int cnt);
int *sl_getStackInfo(int *size);