mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-06 21:58:04 +03:00
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:
+8
-4
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user