Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow to overwrite the cycles per instruction
Some ROMs require a different average cycles per instruction count than the
default one (2 per emulated instruction). This setting is necessary because
mupen64plus is not cycle accurate. A complete simulation of pipeline, cache,
bus and so on is necessary to get it perfectly without this workaround.

Known titles which require a CounterPerOp of 1 are

 * 64 de Hakken!! Tamagotchi - Minna de Tamagotchi World
 * 64 Oozumou
 * A Bug's Life
 * Airboarder 64
 * Bass Hunter 64
 * Bass Rush - ECOGEAR PowerWorm Championship
 * Bassmasters 2000
 * Biohazard 2
 * Body Harvest
 * California Speed
 * Carmageddon 64
 * Charlie Blast's Territory
 * City Tour Grandprix - Zennihon GT Senshuken
 * Destruction Derby 64
 * Disney's Tarzan
 * Donkey Kong 64
 * Duck Dodgers Starring Daffy Duck
 * Duke Nukem - ZER0 H0UR
 * Excitebike 64
 * Fighting Force 64
 * Flying Dragon
 * Fushigi no Dungeon - Fuurai no Shiren 2 - Oni Shuurai! Shiren Jou!
 * GT 64 - Championship Edition
 * Hamster Monogatari 64
 * Harvest Moon 64
 * Hercules - The Legendary Journeys
 * Hexen
 * Hiryuu no Ken Twin
 * In-Fisherman Bass Hunter 64
 * International Superstar Soccer 64
 * Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!
 * Jikkyou G1 Stable
 * Jikkyou World Soccer 3
 * Madden NFL 2000
 * Madden NFL 2001
 * Madden NFL 2002
 * Madden NFL 99
 * Mario Party
 * Mario Party 2
 * Mario Party 3
 * Mario Story
 * Monopoly
 * Mystical Ninja 2 Starring Goemon
 * NBA In the Zone '99
 * NBA Showtime - NBA on NBC
 * Nightmare Creatures
 * Nintama Rantarou 64 Game Gallery
 * Nuclear Strike 64
 * Nushi Duri 64
 * Nushi Duri 64 - Shiokaze ni Notte
 * Paper Mario
 * Pro Mahjong Kiwame 64
 * Pro Mahjong Tsuwamono 64 - Jansou Battle ni Chousen
 * Quake II
 * Razor Freestyle Scooter
 * Ready 2 Rumble Boxing Round 2
 * Resident Evil 2
 * Roadsters Trophy
 * Rush 2 - Extreme Racing USA
 * San Francisco Rush 2049
 * Shadow Man
 * Tigger's Honey Hunt
 * Toy Story 2
 * Triple Play 2000
 * Ucchan Nanchan no Hono no Challenger - Denryuu Ira Ira Bou
 * Vigilante 8
 * Vigilante 8 - 2nd Offence
 * Virtual Pool 64
 * War Gods
 * WCW-nWo Revenge
 * Wipeout 64
 * HardCoded by Iceage
 * Spacer by Memir (POM '99)

Known titles which require a CounterPerOp of 3 are

 * BattleTanx
 * BattleTanx - Global Assault
 * Beetle Adventure Racing!
 * Disney's Donald Duck - Goin' Quackers
 * Donald Duck - Quack Attack
 * HSV Adventure Racing
 * Jikkyou Powerful Pro Yakyuu Basic Ban 2001
 * LEGO Racers
 * Monster Truck Madness 64
 * Pilotwings 64
 * Road Rash 64
 * Wave Race 64 - Shindou Edition
 * WCW Nitro
 * Wetrix
  • Loading branch information
ecsv committed Dec 13, 2013
1 parent 8e14cc9 commit 5d5ff6a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 15 deletions.
4 changes: 4 additions & 0 deletions doc/emuwiki-api-doc/Mupen64Plus_Core_Parameters.txt
Expand Up @@ -55,6 +55,10 @@ These are standard parameters which are used by the Mupen64Plus Core library. T
|M64TYPE_STRING
|Path to a directory to search when looking for shared data files in the <tt>ConfigGetSharedDataFilepath()</tt> function.
|-
|CountPerOp
|M64TYPE_INT
|Force number of cycles per emulated instruction when set greater than 0.
|-
|}

These configuration parameters are used in the Core's event loop to detect keyboard and joystick commands. They are stored in a configuration section called "CoreEvents" and may be altered by the front-end in order to adjust the behaviour of the emulator. These may be adjusted at any time and the effect of the change should occur immediately. The Keysym value stored is actually <tt>(SDLMod << 16) || SDLKey</tt>, so that keypresses with modifiers like shift, control, or alt may be used.
Expand Down
4 changes: 4 additions & 0 deletions src/main/main.c
Expand Up @@ -194,6 +194,7 @@ int main_set_core_defaults(void)
ConfigSetDefaultString(g_CoreConfig, "SaveStatePath", "", "Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserConfigPath}/save will be used");
ConfigSetDefaultString(g_CoreConfig, "SaveSRAMPath", "", "Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserConfigPath}/save will be used");
ConfigSetDefaultString(g_CoreConfig, "SharedDataPath", "", "Path to a directory to search when looking for shared data files");
ConfigSetDefaultInt(g_CoreConfig, "CountPerOp", 0, "Force number of cycles per emulated instruction");

/* handle upgrades */
if (bUpgrade)
Expand Down Expand Up @@ -734,6 +735,9 @@ m64p_error main_run(void)
savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement"));
savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot"));
no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump");
count_per_op = ConfigGetParamInt(g_CoreConfig, "CountPerOp");
if (count_per_op <= 0)
count_per_op = 2;

// initialize memory, and do byte-swapping if it's not been done yet
if (g_MemHasBeenBSwapped == 0)
Expand Down
4 changes: 2 additions & 2 deletions src/r4300/interupt.c
Expand Up @@ -423,9 +423,9 @@ void gen_interupt(void)

case COMPARE_INT:
remove_interupt_event();
Count+=2;
Count+=count_per_op;
add_interupt_event_count(COMPARE_INT, Compare);
Count-=2;
Count-=count_per_op;

Cause = (Cause | 0x8000) & 0xFFFFFF83;
if ((Status & 7) != 1) return;
Expand Down
3 changes: 2 additions & 1 deletion src/r4300/r4300.c
Expand Up @@ -45,6 +45,7 @@

unsigned int r4300emu = 0;
int no_compiled_jump = 0;
unsigned int count_per_op = 2;
int llbit, rompause;
#if NEW_DYNAREC != NEW_DYNAREC_ARM
int stop;
Expand Down Expand Up @@ -704,7 +705,7 @@ void update_count(void)
if (r4300emu != CORE_DYNAREC)
{
#endif
Count = Count + (PC->addr - last_addr)/2;
Count += ((PC->addr - last_addr) >> 2) * count_per_op;
last_addr = PC->addr;
#ifdef NEW_DYNAREC
}
Expand Down
1 change: 1 addition & 0 deletions src/r4300/r4300.h
Expand Up @@ -46,6 +46,7 @@ extern unsigned int last_addr;
extern char invalid_code[0x100000];
extern unsigned int jump_to_address;
extern int no_compiled_jump;
extern unsigned int count_per_op;

void init_blocks(void);
void free_blocks(void);
Expand Down
13 changes: 4 additions & 9 deletions src/r4300/x86/gr4300.c
Expand Up @@ -44,25 +44,20 @@ static int eax, ebx, ecx, edx, esp, ebp, esi, edi;
int branch_taken;

/* static functions */

static void genupdate_count(unsigned int addr)
{
#ifndef COMPARE_CORE
#ifndef DBG
#if !defined(COMPARE_CORE) && !defined(DBG)
mov_reg32_imm32(EAX, addr);
sub_reg32_m32(EAX, (unsigned int*)(&last_addr));
shr_reg32_imm8(EAX, 1);
shr_reg32_imm8(EAX, 2);
mov_reg32_m32(EDX, &count_per_op);
mul_reg32(EDX);
add_m32_reg32((unsigned int*)(&Count), EAX);
#else
mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
mov_reg32_imm32(EAX, (unsigned int)update_count);
call_reg32(EAX);
#endif
#else
mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
mov_reg32_imm32(EAX, (unsigned int)update_count);
call_reg32(EAX);
#endif
}

static void gencheck_interupt(unsigned int instr_structure)
Expand Down
7 changes: 4 additions & 3 deletions src/r4300/x86_64/gr4300.c
Expand Up @@ -84,13 +84,14 @@ static long long debug_reg_storage[8];
int branch_taken = 0;

/* static functions */

static void genupdate_count(unsigned int addr)
{
#if !defined(COMPARE_CORE) && !defined(DBG)
#if !defined(COMPARE_CORE) && !defined(DBG) && 0
mov_reg32_imm32(EAX, addr);
sub_xreg32_m32rel(EAX, (unsigned int*)(&last_addr));
shr_reg32_imm8(EAX, 1);
shr_reg32_imm8(EAX, 2);
mov_xreg32_m32rel(EDX, (void*)&count_per_op);
mul_reg32(EDX);
add_m32rel_xreg32((unsigned int*)(&Count), EAX);
#else
mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
Expand Down

0 comments on commit 5d5ff6a

Please sign in to comment.