mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-11 00:38:18 +03:00
Implement scenario jump for ain v1
In ain v1, destination addresses of scenario jumps are stored in the SLBL section of the ain.
This commit is contained in:
@@ -287,6 +287,16 @@ static int get_function_by_name(const char *name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int scenario_label_addr(const char *lname)
|
||||
{
|
||||
for (int i = 0; i < ain->nr_scenario_labels; i++) {
|
||||
if (!strcmp(ain->scenario_labels[i].name, lname)) {
|
||||
return ain->scenario_labels[i].address;
|
||||
}
|
||||
}
|
||||
VM_ERROR("Invalid scenario label: %s", display_sjis0(lname));
|
||||
}
|
||||
|
||||
static int alloc_scenario_page(const char *fname)
|
||||
{
|
||||
int fno, slot;
|
||||
@@ -304,6 +314,16 @@ static int alloc_scenario_page(const char *fname)
|
||||
return slot;
|
||||
}
|
||||
|
||||
static void scenario_jump(int address)
|
||||
{
|
||||
// flush call stack
|
||||
for (int i = call_stack_ptr - 1; i >= 0; i--) {
|
||||
heap_unref(call_stack[i].page_slot);
|
||||
}
|
||||
call_stack_ptr = 0;
|
||||
instr_ptr = address;
|
||||
}
|
||||
|
||||
static void scenario_call(int slot)
|
||||
{
|
||||
int fno = heap[slot].page->index;
|
||||
@@ -939,15 +959,23 @@ static enum opcode execute_instruction(enum opcode opcode)
|
||||
}
|
||||
case CALLONJUMP: {
|
||||
int str = stack_pop().i;
|
||||
// XXX: I am GUESSING that the VM pre-allocates the scenario function's
|
||||
// local page here. It certainly pushes what appears to be a page
|
||||
// index to the stack.
|
||||
stack_push(alloc_scenario_page(heap_get_string(str)->text));
|
||||
if (ain->scenario_labels) {
|
||||
stack_push(scenario_label_addr(heap_get_string(str)->text));
|
||||
} else {
|
||||
// XXX: I am GUESSING that the VM pre-allocates the scenario function's
|
||||
// local page here. It certainly pushes what appears to be a page
|
||||
// index to the stack.
|
||||
stack_push(alloc_scenario_page(heap_get_string(str)->text));
|
||||
}
|
||||
heap_unref(str);
|
||||
break;
|
||||
}
|
||||
case SJUMP: {
|
||||
scenario_call(stack_pop().i);
|
||||
if (ain->scenario_labels) {
|
||||
scenario_jump(stack_pop().i);
|
||||
} else {
|
||||
scenario_call(stack_pop().i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case _MSG: {
|
||||
|
||||
Reference in New Issue
Block a user