mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-14 06:45:09 +01:00
Add experimental overclock option.
This reduces all cycle costs by half for the primary CPU. There is a delay upon loading before overclocking is applied as a workaround for some games that detect PAL/NTSC systems by counting cycles in a frame at startup.
This commit is contained in:
parent
accc1c030e
commit
2135365d5c
@ -437,9 +437,11 @@ endif
|
||||
|
||||
LIBRETRO_CFLAGS += $(INCFLAGS) $(INCFLAGS_PLATFORM)
|
||||
LIBRETRO_CFLAGS += $(BPP_DEFINES) \
|
||||
$(ENDIANNESS_DEFINES) \
|
||||
$(PLATFORM_DEFINES) \
|
||||
-D__LIBRETRO__
|
||||
$(ENDIANNESS_DEFINES) \
|
||||
$(PLATFORM_DEFINES) \
|
||||
-D__LIBRETRO__ \
|
||||
-DM68K_ALLOW_OVERCLOCK \
|
||||
-DZ80_ALLOW_OVERCLOCK
|
||||
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
LIBRETRO_CFLAGS += -DINLINE="static _inline"
|
||||
|
@ -268,6 +268,10 @@ typedef struct
|
||||
|
||||
uint address_space; /* Current FC code */
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
uint8 overclock_ratio;
|
||||
#endif
|
||||
|
||||
/* Callbacks to host */
|
||||
int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
|
||||
void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
|
||||
|
@ -319,6 +319,10 @@ void m68k_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
m68k.overclock_ratio = 1;
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
m68k_set_int_ack_callback(NULL);
|
||||
#endif
|
||||
|
@ -514,7 +514,11 @@
|
||||
|
||||
/* ---------------------------- Cycle Counting ---------------------------- */
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
#define USE_CYCLES(A) m68ki_cpu.cycles += (A) / m68ki_cpu.overclock_ratio
|
||||
#else
|
||||
#define USE_CYCLES(A) m68ki_cpu.cycles += (A)
|
||||
#endif
|
||||
#define SET_CYCLES(A) m68ki_cpu.cycles = (A)
|
||||
|
||||
|
||||
|
@ -284,6 +284,10 @@ void s68k_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
s68k.overclock_ratio = 1;
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
s68k_set_int_ack_callback(NULL);
|
||||
#endif
|
||||
|
@ -201,8 +201,18 @@
|
||||
#define IFF2 Z80.iff2
|
||||
#define HALT Z80.halt
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
#define USE_CYCLES(A) Z80.cycles += (A) / z80_overclock_ratio
|
||||
#else
|
||||
#define USE_CYCLES(A) Z80.cycles += (A)
|
||||
#endif
|
||||
|
||||
Z80_Regs Z80;
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
UINT8 z80_overclock_ratio;
|
||||
#endif
|
||||
|
||||
unsigned char *z80_readmap[64];
|
||||
unsigned char *z80_writemap[64];
|
||||
|
||||
@ -473,7 +483,7 @@ INLINE void BURNODD(int cycles, int opcodes, int cyclesum)
|
||||
if( cycles > 0 )
|
||||
{
|
||||
R += (cycles / cyclesum) * opcodes;
|
||||
Z80.cycles += (cycles / cyclesum) * cyclesum * 15;
|
||||
USE_CYCLES((cycles / cyclesum) * cyclesum * 15);
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,7 +495,7 @@ INLINE void BURNODD(int cycles, int opcodes, int cyclesum)
|
||||
/***************************************************************
|
||||
* adjust cycle count by n T-states
|
||||
***************************************************************/
|
||||
#define CC(prefix,opcode) Z80.cycles += cc[Z80_TABLE_##prefix][opcode]
|
||||
#define CC(prefix,opcode) USE_CYCLES(cc[Z80_TABLE_##prefix][opcode])
|
||||
|
||||
/***************************************************************
|
||||
* execute an opcode
|
||||
@ -3228,7 +3238,7 @@ static void take_interrupt(void)
|
||||
PUSH( pc );
|
||||
PCD = 0x0038;
|
||||
/* RST $38 + 'interrupt latency' cycles */
|
||||
Z80.cycles += cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff];
|
||||
USE_CYCLES(cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3243,7 +3253,7 @@ static void take_interrupt(void)
|
||||
RM16( irq_vector, &Z80.pc );
|
||||
LOG(("Z80 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, PCD));
|
||||
/* CALL $xxxx + 'interrupt latency' cycles */
|
||||
Z80.cycles += cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff];
|
||||
USE_CYCLES(cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3257,18 +3267,18 @@ static void take_interrupt(void)
|
||||
PUSH( pc );
|
||||
PCD = irq_vector & 0xffff;
|
||||
/* CALL $xxxx + 'interrupt latency' cycles */
|
||||
Z80.cycles += cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff];
|
||||
USE_CYCLES(cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff]);
|
||||
break;
|
||||
case 0xc30000: /* jump */
|
||||
PCD = irq_vector & 0xffff;
|
||||
/* JP $xxxx + 2 cycles */
|
||||
Z80.cycles += cc[Z80_TABLE_op][0xc3] + cc[Z80_TABLE_ex][0xff];
|
||||
USE_CYCLES(cc[Z80_TABLE_op][0xc3] + cc[Z80_TABLE_ex][0xff]);
|
||||
break;
|
||||
default: /* rst (or other opcodes?) */
|
||||
PUSH( pc );
|
||||
PCD = irq_vector & 0x0038;
|
||||
/* RST $xx + 2 cycles */
|
||||
Z80.cycles += cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff];
|
||||
USE_CYCLES(cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3358,6 +3368,9 @@ void z80_init(const void *config, int (*irqcallback)(int))
|
||||
memset(&Z80, 0, sizeof(Z80));
|
||||
Z80.daisy = config;
|
||||
Z80.irq_callback = irqcallback;
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
z80_overclock_ratio = 1;
|
||||
#endif
|
||||
|
||||
/* Clear registers values (NB: should be random on real hardware ?) */
|
||||
AF = BC = DE = HL = SP = IX = IY =0;
|
||||
@ -3449,7 +3462,7 @@ void z80_set_nmi_line(unsigned int state)
|
||||
PCD = 0x0066;
|
||||
WZ=PCD;
|
||||
|
||||
Z80.cycles += 11*15;
|
||||
USE_CYCLES(11*15);
|
||||
}
|
||||
|
||||
Z80.nmi_state = state;
|
||||
|
@ -51,6 +51,10 @@ typedef struct
|
||||
|
||||
extern Z80_Regs Z80;
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
extern UINT8 z80_overclock_ratio;
|
||||
#endif
|
||||
|
||||
extern unsigned char *z80_readmap[64];
|
||||
extern unsigned char *z80_writemap[64];
|
||||
|
||||
|
@ -54,6 +54,12 @@
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#if defined(M68K_ALLOW_OVERCLOCK) || defined(Z80_ALLOW_OVERCLOCK)
|
||||
#define HAVE_OVERCLOCK
|
||||
/* Overclocking frame delay (hack) */
|
||||
#define OVERCLOCK_FRAME_DELAY 100
|
||||
#endif
|
||||
|
||||
#define RETRO_DEVICE_MDPAD_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
|
||||
#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
|
||||
#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2)
|
||||
@ -150,6 +156,14 @@ static char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789";
|
||||
|
||||
static char arvalidchars[] = "0123456789ABCDEF";
|
||||
|
||||
/* Some games appear to calibrate music playback speed for PAL/NTSC by
|
||||
actually counting CPU cycles per frame during startup, resulting in
|
||||
hilariously fast music. Delay overclocking for a while as a
|
||||
workaround */
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
static uint32_t overclock_delay;
|
||||
#endif
|
||||
|
||||
#define SOUND_FREQUENCY 44100
|
||||
|
||||
/* Hide the EQ settings for now */
|
||||
@ -526,6 +540,9 @@ static void config_default(void)
|
||||
config.bios = 0;
|
||||
config.lock_on = 0;
|
||||
config.lcd = 0; /* 0.8 fixed point */
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
config.overclock = 0;
|
||||
#endif
|
||||
|
||||
/* video options */
|
||||
config.overscan = 0;
|
||||
@ -1236,8 +1253,22 @@ static void check_variables(void)
|
||||
config.invert_mouse = 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
var.key = "genesis_plus_gx_overclock";
|
||||
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
|
||||
{
|
||||
if (strcmp(var.value, "1x") == 0)
|
||||
config.overclock = 0;
|
||||
else if (strcmp(var.value, "2x") == 0)
|
||||
config.overclock = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (reinit)
|
||||
{
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
#endif
|
||||
audio_init(SOUND_FREQUENCY, 0);
|
||||
memcpy(temp, sram.sram, sizeof(temp));
|
||||
system_init();
|
||||
@ -1677,6 +1708,9 @@ void retro_set_environment(retro_environment_t cb)
|
||||
{ "genesis_plus_gx_render", "Interlaced mode 2 output; single field|double field" },
|
||||
{ "genesis_plus_gx_gun_cursor", "Show Lightgun crosshair; disabled|enabled" },
|
||||
{ "genesis_plus_gx_invert_mouse", "Invert Mouse Y-axis; disabled|enabled" },
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
{ "genesis_plus_gx_overclock", "Overclock CPU; 1x|2x" },
|
||||
#endif
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
@ -2020,6 +2054,10 @@ bool retro_unserialize(const void *data, size_t size)
|
||||
if (!state_load((uint8_t*)data))
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2184,6 +2222,9 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
#endif
|
||||
audio_init(SOUND_FREQUENCY, 0);
|
||||
system_init();
|
||||
system_reset();
|
||||
@ -2299,6 +2340,9 @@ void retro_deinit(void)
|
||||
|
||||
void retro_reset(void)
|
||||
{
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
#endif
|
||||
gen_reset(0);
|
||||
}
|
||||
|
||||
@ -2307,12 +2351,42 @@ void retro_run(void)
|
||||
bool updated = false;
|
||||
is_running = true;
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
/* update overclock delay */
|
||||
if (overclock_delay)
|
||||
overclock_delay--;
|
||||
#endif
|
||||
|
||||
if (system_hw == SYSTEM_MCD)
|
||||
{
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
if (config.overclock && overclock_delay == 0)
|
||||
m68k.overclock_ratio = 2;
|
||||
else
|
||||
m68k.overclock_ratio = 1;
|
||||
#endif
|
||||
system_frame_scd(0);
|
||||
}
|
||||
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
if (config.overclock && overclock_delay == 0)
|
||||
m68k.overclock_ratio = 2;
|
||||
else
|
||||
m68k.overclock_ratio = 1;
|
||||
#endif
|
||||
system_frame_gen(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
if (config.overclock && overclock_delay == 0)
|
||||
z80_overclock_ratio = 2;
|
||||
else
|
||||
z80_overclock_ratio = 1;
|
||||
#endif
|
||||
system_frame_sms(0);
|
||||
}
|
||||
|
||||
if (bitmap.viewport.changed & 9)
|
||||
{
|
||||
|
@ -120,6 +120,7 @@ struct
|
||||
t_input_config input[MAX_INPUTS];
|
||||
uint8 invert_mouse;
|
||||
uint8 gun_cursor;
|
||||
uint8 overclock;
|
||||
} config;
|
||||
|
||||
extern char GG_ROM[256];
|
||||
|
Loading…
Reference in New Issue
Block a user