Skip to content

Commit

Permalink
documenting VM hacks
Browse files Browse the repository at this point in the history
issue #17
  • Loading branch information
felipesanches committed Jun 1, 2017
1 parent f1a0960 commit 889934f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 7 deletions.
40 changes: 38 additions & 2 deletions src/devices/cpu/anotherworld/anotherworld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.

Expand All @@ -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;
}
Expand Down
19 changes: 14 additions & 5 deletions src/devices/cpu/anotherworld/anotherworld.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <fstream>
#include <iostream>

Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/devices/cpu/anotherworld/anotherworld_dasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 889934f

Please sign in to comment.