mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +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
@ -439,7 +439,9 @@ LIBRETRO_CFLAGS += $(INCFLAGS) $(INCFLAGS_PLATFORM)
|
|||||||
LIBRETRO_CFLAGS += $(BPP_DEFINES) \
|
LIBRETRO_CFLAGS += $(BPP_DEFINES) \
|
||||||
$(ENDIANNESS_DEFINES) \
|
$(ENDIANNESS_DEFINES) \
|
||||||
$(PLATFORM_DEFINES) \
|
$(PLATFORM_DEFINES) \
|
||||||
-D__LIBRETRO__
|
-D__LIBRETRO__ \
|
||||||
|
-DM68K_ALLOW_OVERCLOCK \
|
||||||
|
-DZ80_ALLOW_OVERCLOCK
|
||||||
|
|
||||||
ifneq (,$(findstring msvc,$(platform)))
|
ifneq (,$(findstring msvc,$(platform)))
|
||||||
LIBRETRO_CFLAGS += -DINLINE="static _inline"
|
LIBRETRO_CFLAGS += -DINLINE="static _inline"
|
||||||
|
@ -268,6 +268,10 @@ typedef struct
|
|||||||
|
|
||||||
uint address_space; /* Current FC code */
|
uint address_space; /* Current FC code */
|
||||||
|
|
||||||
|
#ifdef M68K_ALLOW_OVERCLOCK
|
||||||
|
uint8 overclock_ratio;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Callbacks to host */
|
/* Callbacks to host */
|
||||||
int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
|
int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */
|
||||||
void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
|
void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */
|
||||||
|
@ -319,6 +319,10 @@ void m68k_init(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef M68K_ALLOW_OVERCLOCK
|
||||||
|
m68k.overclock_ratio = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||||
m68k_set_int_ack_callback(NULL);
|
m68k_set_int_ack_callback(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -514,7 +514,11 @@
|
|||||||
|
|
||||||
/* ---------------------------- Cycle Counting ---------------------------- */
|
/* ---------------------------- 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)
|
#define USE_CYCLES(A) m68ki_cpu.cycles += (A)
|
||||||
|
#endif
|
||||||
#define SET_CYCLES(A) m68ki_cpu.cycles = (A)
|
#define SET_CYCLES(A) m68ki_cpu.cycles = (A)
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,6 +284,10 @@ void s68k_init(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef M68K_ALLOW_OVERCLOCK
|
||||||
|
s68k.overclock_ratio = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||||
s68k_set_int_ack_callback(NULL);
|
s68k_set_int_ack_callback(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -201,8 +201,18 @@
|
|||||||
#define IFF2 Z80.iff2
|
#define IFF2 Z80.iff2
|
||||||
#define HALT Z80.halt
|
#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;
|
Z80_Regs Z80;
|
||||||
|
|
||||||
|
#ifdef Z80_ALLOW_OVERCLOCK
|
||||||
|
UINT8 z80_overclock_ratio;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char *z80_readmap[64];
|
unsigned char *z80_readmap[64];
|
||||||
unsigned char *z80_writemap[64];
|
unsigned char *z80_writemap[64];
|
||||||
|
|
||||||
@ -473,7 +483,7 @@ INLINE void BURNODD(int cycles, int opcodes, int cyclesum)
|
|||||||
if( cycles > 0 )
|
if( cycles > 0 )
|
||||||
{
|
{
|
||||||
R += (cycles / cyclesum) * opcodes;
|
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
|
* 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
|
* execute an opcode
|
||||||
@ -3228,7 +3238,7 @@ static void take_interrupt(void)
|
|||||||
PUSH( pc );
|
PUSH( pc );
|
||||||
PCD = 0x0038;
|
PCD = 0x0038;
|
||||||
/* RST $38 + 'interrupt latency' cycles */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
@ -3243,7 +3253,7 @@ static void take_interrupt(void)
|
|||||||
RM16( irq_vector, &Z80.pc );
|
RM16( irq_vector, &Z80.pc );
|
||||||
LOG(("Z80 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, PCD));
|
LOG(("Z80 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, PCD));
|
||||||
/* CALL $xxxx + 'interrupt latency' cycles */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
@ -3257,18 +3267,18 @@ static void take_interrupt(void)
|
|||||||
PUSH( pc );
|
PUSH( pc );
|
||||||
PCD = irq_vector & 0xffff;
|
PCD = irq_vector & 0xffff;
|
||||||
/* CALL $xxxx + 'interrupt latency' cycles */
|
/* 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;
|
break;
|
||||||
case 0xc30000: /* jump */
|
case 0xc30000: /* jump */
|
||||||
PCD = irq_vector & 0xffff;
|
PCD = irq_vector & 0xffff;
|
||||||
/* JP $xxxx + 2 cycles */
|
/* 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;
|
break;
|
||||||
default: /* rst (or other opcodes?) */
|
default: /* rst (or other opcodes?) */
|
||||||
PUSH( pc );
|
PUSH( pc );
|
||||||
PCD = irq_vector & 0x0038;
|
PCD = irq_vector & 0x0038;
|
||||||
/* RST $xx + 2 cycles */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3358,6 +3368,9 @@ void z80_init(const void *config, int (*irqcallback)(int))
|
|||||||
memset(&Z80, 0, sizeof(Z80));
|
memset(&Z80, 0, sizeof(Z80));
|
||||||
Z80.daisy = config;
|
Z80.daisy = config;
|
||||||
Z80.irq_callback = irqcallback;
|
Z80.irq_callback = irqcallback;
|
||||||
|
#ifdef Z80_ALLOW_OVERCLOCK
|
||||||
|
z80_overclock_ratio = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clear registers values (NB: should be random on real hardware ?) */
|
/* Clear registers values (NB: should be random on real hardware ?) */
|
||||||
AF = BC = DE = HL = SP = IX = IY =0;
|
AF = BC = DE = HL = SP = IX = IY =0;
|
||||||
@ -3449,7 +3462,7 @@ void z80_set_nmi_line(unsigned int state)
|
|||||||
PCD = 0x0066;
|
PCD = 0x0066;
|
||||||
WZ=PCD;
|
WZ=PCD;
|
||||||
|
|
||||||
Z80.cycles += 11*15;
|
USE_CYCLES(11*15);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z80.nmi_state = state;
|
Z80.nmi_state = state;
|
||||||
|
@ -51,6 +51,10 @@ typedef struct
|
|||||||
|
|
||||||
extern Z80_Regs Z80;
|
extern Z80_Regs Z80;
|
||||||
|
|
||||||
|
#ifdef Z80_ALLOW_OVERCLOCK
|
||||||
|
extern UINT8 z80_overclock_ratio;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern unsigned char *z80_readmap[64];
|
extern unsigned char *z80_readmap[64];
|
||||||
extern unsigned char *z80_writemap[64];
|
extern unsigned char *z80_writemap[64];
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@
|
|||||||
#include <xtl.h>
|
#include <xtl.h>
|
||||||
#endif
|
#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_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
|
||||||
#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
|
#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
|
||||||
#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2)
|
#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2)
|
||||||
@ -150,6 +156,14 @@ static char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789";
|
|||||||
|
|
||||||
static char arvalidchars[] = "0123456789ABCDEF";
|
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
|
#define SOUND_FREQUENCY 44100
|
||||||
|
|
||||||
/* Hide the EQ settings for now */
|
/* Hide the EQ settings for now */
|
||||||
@ -526,6 +540,9 @@ static void config_default(void)
|
|||||||
config.bios = 0;
|
config.bios = 0;
|
||||||
config.lock_on = 0;
|
config.lock_on = 0;
|
||||||
config.lcd = 0; /* 0.8 fixed point */
|
config.lcd = 0; /* 0.8 fixed point */
|
||||||
|
#ifdef HAVE_OVERCLOCK
|
||||||
|
config.overclock = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* video options */
|
/* video options */
|
||||||
config.overscan = 0;
|
config.overscan = 0;
|
||||||
@ -1236,8 +1253,22 @@ static void check_variables(void)
|
|||||||
config.invert_mouse = 1;
|
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)
|
if (reinit)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_OVERCLOCK
|
||||||
|
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||||
|
#endif
|
||||||
audio_init(SOUND_FREQUENCY, 0);
|
audio_init(SOUND_FREQUENCY, 0);
|
||||||
memcpy(temp, sram.sram, sizeof(temp));
|
memcpy(temp, sram.sram, sizeof(temp));
|
||||||
system_init();
|
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_render", "Interlaced mode 2 output; single field|double field" },
|
||||||
{ "genesis_plus_gx_gun_cursor", "Show Lightgun crosshair; disabled|enabled" },
|
{ "genesis_plus_gx_gun_cursor", "Show Lightgun crosshair; disabled|enabled" },
|
||||||
{ "genesis_plus_gx_invert_mouse", "Invert Mouse Y-axis; 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 },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2020,6 +2054,10 @@ bool retro_unserialize(const void *data, size_t size)
|
|||||||
if (!state_load((uint8_t*)data))
|
if (!state_load((uint8_t*)data))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_OVERCLOCK
|
||||||
|
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
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);
|
audio_init(SOUND_FREQUENCY, 0);
|
||||||
system_init();
|
system_init();
|
||||||
system_reset();
|
system_reset();
|
||||||
@ -2299,6 +2340,9 @@ void retro_deinit(void)
|
|||||||
|
|
||||||
void retro_reset(void)
|
void retro_reset(void)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_OVERCLOCK
|
||||||
|
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||||
|
#endif
|
||||||
gen_reset(0);
|
gen_reset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2307,12 +2351,42 @@ void retro_run(void)
|
|||||||
bool updated = false;
|
bool updated = false;
|
||||||
is_running = true;
|
is_running = true;
|
||||||
|
|
||||||
|
#ifdef HAVE_OVERCLOCK
|
||||||
|
/* update overclock delay */
|
||||||
|
if (overclock_delay)
|
||||||
|
overclock_delay--;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (system_hw == SYSTEM_MCD)
|
if (system_hw == SYSTEM_MCD)
|
||||||
system_frame_scd(0);
|
{
|
||||||
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
#ifdef M68K_ALLOW_OVERCLOCK
|
||||||
system_frame_gen(0);
|
if (config.overclock && overclock_delay == 0)
|
||||||
|
m68k.overclock_ratio = 2;
|
||||||
else
|
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);
|
system_frame_sms(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (bitmap.viewport.changed & 9)
|
if (bitmap.viewport.changed & 9)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,7 @@ struct
|
|||||||
t_input_config input[MAX_INPUTS];
|
t_input_config input[MAX_INPUTS];
|
||||||
uint8 invert_mouse;
|
uint8 invert_mouse;
|
||||||
uint8 gun_cursor;
|
uint8 gun_cursor;
|
||||||
|
uint8 overclock;
|
||||||
} config;
|
} config;
|
||||||
|
|
||||||
extern char GG_ROM[256];
|
extern char GG_ROM[256];
|
||||||
|
Loading…
Reference in New Issue
Block a user