diff --git a/src/devices/cpu/anotherworld/anotherworld.cpp b/src/devices/cpu/anotherworld/anotherworld.cpp index 354e131d39548..f40c1d6278831 100644 --- a/src/devices/cpu/anotherworld/anotherworld.cpp +++ b/src/devices/cpu/anotherworld/anotherworld.cpp @@ -232,7 +232,22 @@ void another_world_cpu_device::device_reset() thread->requested_state = NO_REQUEST; } - write_vm_variable(0x54, 0x0081); //TODO: figure out why this is supposedly needed. +#ifdef VM_HACK_INIT_VAR_54_WITH_81 + // Without this, the Interplay logo does not show up + // while running the MSDOS bytecode: + write_vm_variable(0x54, 0x0081); + + //TODO: check if this var is read or written anywhere + // else during gameplay. Ideally run the whole game with + // a watchpoint monitoring this one. + +// Some clues: +// [14 - 007F]: 0A jl [HACK_VAR_54], 0x80, 0x00BF +// [14 - 00E4]: 0A jge [HACK_VAR_54], 0x80, 0x00F6 +// [14 - 0165]: 14 and [HACK_VAR_54], 0x0001 +// [14 - 0169]: 0A je [HACK_VAR_54], 0x00, 0x0199 +// [18 - 3EAB]: 00 mov [HACK_VAR_54], 0xFFFB +#endif #ifdef BYPASS_PROTECTION //This is a hack to skip the code wheel @@ -572,12 +587,29 @@ void another_world_cpu_device::execute_instruction() { uint8_t pageId = fetch_byte(); //printf("blitFramebuffer(pageId:%d, PAUSE_SLICES:%d)\n", pageId, read_vm_variable(VM_VARIABLE_PAUSE_SLICES)); -#if 1 + +#ifdef VM_HACK_SWITCH_FROM_INTRO_TO_LAKE //Nasty hack....was this present in the original assembly ??!! //This seems to be necessary for switching from the intro sequence to the lake stage if (m_currentPartId == GAME_PART(0) && read_vm_variable(0x67) == 1) write_vm_variable(0xDC, 0x21); + +// Some clues: +// [32 - 0D41]: 00 mov [HACK_VAR_67], 0x0001 +// [3F - 0D46]: 00 mov [HACK_VAR_67], 0x0000 +// [00 - 00B2]: 0A jne [HACK_VAR_DC], 0x21, 0x00B9 +// [03 - 00B2]: 0A jne [HACK_VAR_DC], 0x21, 0x00B9 +// [3F - 19BB]: 00 mov [HACK_VAR_67], 0x0002 +// [3F - 1954]: 0A jne [HACK_VAR_67], [0x65], 0x196F +// [2E - 35E2]: 0A jne [HACK_VAR_67], 0x01, 0x35E1 +// [30 - 01F0]: 0A je [HACK_VAR_67], 0x05, 0x01E9 +// [30 - 01F6]: 0A je [HACK_VAR_67], 0x02, 0x01E9 +// [30 - 0226]: 0A je [HACK_VAR_67], 0x05, 0x0238 + +// Much more with: +// grep HACK_VAR_67 address_log.txt|sort|uniq|less #endif + // The bytecode will set vmVariables[VM_VARIABLE_PAUSE_SLICES] from 1 to 5 // The virtual machine hence indicate how long the image should be displayed. @@ -587,9 +619,13 @@ void another_world_cpu_device::execute_instruction() m_icount -= (int) read_vm_variable(VM_VARIABLE_PAUSE_SLICES); #endif +#ifdef VM_HACK_BLITFRAMEBUFFER_VAR_F7 //Why ? write_vm_variable(0xF7, 0x0000); +// Some clues: +// [14 - 0A1B]: 02 add [0x37], [HACK_VAR_F7] +#endif ((another_world_state*) owner())->updateDisplay(pageId); return; } diff --git a/src/devices/cpu/anotherworld/anotherworld.h b/src/devices/cpu/anotherworld/anotherworld.h index e7470d902a164..77d74af5249bf 100644 --- a/src/devices/cpu/anotherworld/anotherworld.h +++ b/src/devices/cpu/anotherworld/anotherworld.h @@ -5,6 +5,16 @@ #ifndef __ANOTHERWORLD_H__ #define __ANOTHERWORLD_H__ +//VM irregularities (see: https://github.com/felipesanches/mame/issues/17) +#define VM_HACK_SWITCH_FROM_INTRO_TO_LAKE // Seems needed both on Amiga and MSDOS bytecode. +#define VM_HACK_BLITFRAMEBUFFER_VAR_F7 // Seems to be unnecessary. +#define VM_HACK_INIT_VAR_54_WITH_81 // Without this one, the Interplay logo does not show up with MSDOS bytecode + +//a few optional features for easing VM debugging: +#define DUMP_VM_EXECUTION_LOG +//#define SPEEDUP_VM_EXECUTION +//#define BYPASS_PROTECTION + #include #include @@ -39,11 +49,6 @@ enum { #define NUM_THREADS 64 #define GAME_PART(n) (0x3E80 + n) -//a few optional features for easing VM debugging: -#define DUMP_VM_EXECUTION_LOG -//#define SPEEDUP_VM_EXECUTION -//#define BYPASS_PROTECTION - #define AS_PROGRAM AS_0 #define AS_DATA AS_1 #define AS_PALETTE AS_2 @@ -52,9 +57,13 @@ enum { enum ScriptVars { VM_VARIABLE_RANDOM_SEED = 0x3C, + VM_VARIABLE_HACK_VAR_54 = 0x54, // Interplay logo TODO: verify this + VM_VARIABLE_HACK_VAR_67 = 0x67, // switch from intro to lake TODO: verify this VM_VARIABLE_LAST_KEYCHAR = 0xDA, + VM_VARIABLE_HACK_VAR_DC = 0xDC, // switch from intro to lake TODO: verify this VM_VARIABLE_HERO_POS_UP_DOWN = 0xE5, VM_VARIABLE_MUS_MARK = 0xF4, + VM_VARIABLE_HACK_VAR_F7 = 0xF7, // Blitframebuffer (not needed?) TODO: verify this VM_VARIABLE_SCROLL_Y = 0xF9, VM_VARIABLE_HERO_ACTION = 0xFA, VM_VARIABLE_HERO_POS_JUMP_DOWN = 0xFB, diff --git a/src/devices/cpu/anotherworld/anotherworld_dasm.cpp b/src/devices/cpu/anotherworld/anotherworld_dasm.cpp index d82875d2c439f..7c75e2f524fea 100644 --- a/src/devices/cpu/anotherworld/anotherworld_dasm.cpp +++ b/src/devices/cpu/anotherworld/anotherworld_dasm.cpp @@ -18,6 +18,10 @@ static void getVariableName(char* s, uint8_t id){ case VM_VARIABLE_HERO_POS_MASK: sprintf(s, "HERO_POS_MASK"); break; case VM_VARIABLE_HERO_ACTION_POS_MASK: sprintf(s, "HERO_ACTION_POS_MASK"); break; case VM_VARIABLE_PAUSE_SLICES: sprintf(s, "PAUSE_SLICES"); break; + case VM_VARIABLE_HACK_VAR_54: sprintf(s, "HACK_VAR_54"); break; + case VM_VARIABLE_HACK_VAR_67: sprintf(s, "HACK_VAR_67"); break; + case VM_VARIABLE_HACK_VAR_DC: sprintf(s, "HACK_VAR_DC"); break; + case VM_VARIABLE_HACK_VAR_F7: sprintf(s, "HACK_VAR_F7"); break; default: sprintf(s, "0x%02X", id); break; }