mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
32x: start reworking sheduling
This commit is contained in:
parent
9b5713af95
commit
ed4402a7df
17 changed files with 180 additions and 163 deletions
|
@ -2978,13 +2978,12 @@ void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid)
|
|||
1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
|
||||
}
|
||||
|
||||
void sh2_execute(SH2 *sh2c, int cycles)
|
||||
int sh2_execute(SH2 *sh2c, int cycles)
|
||||
{
|
||||
int ret_cycles;
|
||||
sh2 = sh2c; // XXX
|
||||
|
||||
sh2c->cycles_aim += cycles;
|
||||
cycles = sh2c->cycles_aim - sh2c->cycles_done;
|
||||
sh2c->cycles_timeslice = cycles;
|
||||
|
||||
// cycles are kept in SHR_SR unused bits (upper 20)
|
||||
// bit19 contains T saved for delay slot
|
||||
|
@ -2998,7 +2997,7 @@ void sh2_execute(SH2 *sh2c, int cycles)
|
|||
if (ret_cycles > 0)
|
||||
dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
|
||||
|
||||
sh2c->cycles_done += cycles - ret_cycles;
|
||||
return sh2c->cycles_timeslice - ret_cycles;
|
||||
}
|
||||
|
||||
#if (DRC_DEBUG & 2)
|
||||
|
|
|
@ -61,14 +61,15 @@ static unsigned int op_refs[0x10000];
|
|||
|
||||
#ifndef DRC_SH2
|
||||
|
||||
void sh2_execute(SH2 *sh2_, int cycles)
|
||||
int sh2_execute(SH2 *sh2_, int cycles)
|
||||
{
|
||||
sh2 = sh2_;
|
||||
sh2->cycles_aim += cycles;
|
||||
sh2->icount = cycles = sh2->cycles_aim - sh2->cycles_done;
|
||||
sh2->icount = cycles;
|
||||
|
||||
if (sh2->icount <= 0)
|
||||
return;
|
||||
return cycles;
|
||||
|
||||
sh2->cycles_timeslice = cycles;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -122,7 +123,7 @@ void sh2_execute(SH2 *sh2_, int cycles)
|
|||
}
|
||||
while (sh2->icount > 0 || sh2->delay); /* can't interrupt before delay */
|
||||
|
||||
sh2->cycles_done += cycles - sh2->icount;
|
||||
return sh2->cycles_timeslice - sh2->icount;
|
||||
}
|
||||
|
||||
#else // DRC_SH2
|
||||
|
|
|
@ -20,7 +20,7 @@ int sh2_init(SH2 *sh2, int is_slave)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
memset(sh2, 0, sizeof(*sh2));
|
||||
memset(sh2, 0, offsetof(SH2, mult_m68k_to_sh2));
|
||||
sh2->is_slave = is_slave;
|
||||
pdb_register_cpu(sh2, PDBCT_SH2, is_slave ? "ssh2" : "msh2");
|
||||
#ifdef DRC_SH2
|
||||
|
@ -59,7 +59,7 @@ void sh2_do_irq(SH2 *sh2, int level, int vector)
|
|||
sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2);
|
||||
|
||||
/* 13 cycles at best */
|
||||
sh2->cycles_done += 13;
|
||||
sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13);
|
||||
// sh2->icount -= 13;
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,6 @@ void sh2_pack(const SH2 *sh2, unsigned char *buff)
|
|||
|
||||
p[0] = sh2->pending_int_irq;
|
||||
p[1] = sh2->pending_int_vector;
|
||||
p[2] = sh2->cycles_aim;
|
||||
p[3] = sh2->cycles_done;
|
||||
}
|
||||
|
||||
void sh2_unpack(SH2 *sh2, const unsigned char *buff)
|
||||
|
@ -118,7 +116,5 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff)
|
|||
|
||||
sh2->pending_int_irq = p[0];
|
||||
sh2->pending_int_vector = p[1];
|
||||
sh2->cycles_aim = p[2];
|
||||
sh2->cycles_done = p[3];
|
||||
}
|
||||
|
||||
|
|
|
@ -52,10 +52,20 @@ typedef struct SH2_
|
|||
int REGPARM(2) (*irq_callback)(struct SH2_ *sh2, int level);
|
||||
int is_slave;
|
||||
|
||||
unsigned int cycles_aim; // subtract sh2_icount to get global counter
|
||||
unsigned int cycles_done;
|
||||
unsigned int cycles_timeslice;
|
||||
|
||||
// we use 68k reference cycles for easier sync
|
||||
unsigned int m68krcycles_done;
|
||||
unsigned int mult_m68k_to_sh2;
|
||||
unsigned int mult_sh2_to_m68k;
|
||||
} SH2;
|
||||
|
||||
#define CYCLE_MULT_SHIFT 10
|
||||
#define C_M68K_TO_SH2(xsh2, c) \
|
||||
((int)((c) * (xsh2).mult_m68k_to_sh2) >> CYCLE_MULT_SHIFT)
|
||||
#define C_SH2_TO_M68K(xsh2, c) \
|
||||
((int)((c + 3) * (xsh2).mult_sh2_to_m68k) >> CYCLE_MULT_SHIFT)
|
||||
|
||||
extern SH2 *sh2; // active sh2. XXX: consider removing
|
||||
|
||||
int sh2_init(SH2 *sh2, int is_slave);
|
||||
|
@ -67,7 +77,7 @@ void sh2_do_irq(SH2 *sh2, int level, int vector);
|
|||
void sh2_pack(const SH2 *sh2, unsigned char *buff);
|
||||
void sh2_unpack(SH2 *sh2, const unsigned char *buff);
|
||||
|
||||
void sh2_execute(SH2 *sh2, int cycles);
|
||||
int sh2_execute(SH2 *sh2, int cycles);
|
||||
|
||||
// regs, pending_int*, cycles, reserved
|
||||
#define SH2_STATE_SIZE ((24 + 2 + 2 + 12) * 4)
|
||||
|
|
146
pico/32x/32x.c
146
pico/32x/32x.c
|
@ -120,10 +120,16 @@ void p32x_reset_sh2s(void)
|
|||
sh2_set_vbr(1, vbr);
|
||||
// program will set S_OK
|
||||
}
|
||||
|
||||
msh2.m68krcycles_done = ssh2.m68krcycles_done = SekCyclesDoneT();
|
||||
}
|
||||
|
||||
void Pico32xInit(void)
|
||||
{
|
||||
if (msh2.mult_m68k_to_sh2 == 0 || msh2.mult_sh2_to_m68k == 0)
|
||||
Pico32xSetClocks(PICO_MSH2_HZ, 0);
|
||||
if (ssh2.mult_m68k_to_sh2 == 0 || ssh2.mult_sh2_to_m68k == 0)
|
||||
Pico32xSetClocks(0, PICO_MSH2_HZ);
|
||||
}
|
||||
|
||||
void PicoPower32x(void)
|
||||
|
@ -199,81 +205,76 @@ static void p32x_start_blank(void)
|
|||
p32x_poll_event(3, 1);
|
||||
}
|
||||
|
||||
static __inline void run_m68k(int cyc)
|
||||
#define sync_sh2s_normal p32x_sync_sh2s
|
||||
//#define sync_sh2s_lockstep p32x_sync_sh2s
|
||||
|
||||
void sync_sh2s_normal(unsigned int m68k_target)
|
||||
{
|
||||
pprof_start(m68k);
|
||||
unsigned int target = m68k_target;
|
||||
int msh2_cycles, ssh2_cycles;
|
||||
int done;
|
||||
|
||||
p32x_poll_event(3, 0);
|
||||
#if defined(EMU_C68K)
|
||||
PicoCpuCM68k.cycles = cyc;
|
||||
CycloneRun(&PicoCpuCM68k);
|
||||
SekCycleCnt += cyc - PicoCpuCM68k.cycles;
|
||||
#elif defined(EMU_M68K)
|
||||
SekCycleCnt += m68k_execute(cyc);
|
||||
#elif defined(EMU_F68K)
|
||||
SekCycleCnt += fm68k_emulate(cyc+1, 0, 0);
|
||||
#endif
|
||||
elprintf(EL_32X, "sh2 sync to %u (%u)", m68k_target, SekCycleCnt);
|
||||
|
||||
pprof_end(m68k);
|
||||
}
|
||||
if (!(Pico32x.regs[0] & P32XS_nRES))
|
||||
return; // rare
|
||||
|
||||
// ~1463.8, but due to cache misses and slow mem
|
||||
// it's much lower than that
|
||||
//#define SH2_LINE_CYCLES 735
|
||||
#define CYCLES_M68K2MSH2(x) (((x) * p32x_msh2_multiplier) >> 10)
|
||||
#define CYCLES_M68K2SSH2(x) (((x) * p32x_ssh2_multiplier) >> 10)
|
||||
{
|
||||
msh2_cycles = C_M68K_TO_SH2(msh2, target - msh2.m68krcycles_done);
|
||||
ssh2_cycles = C_M68K_TO_SH2(ssh2, target - ssh2.m68krcycles_done);
|
||||
|
||||
#define PICO_32X
|
||||
#define CPUS_RUN_SIMPLE(m68k_cycles,s68k_cycles) \
|
||||
{ \
|
||||
int slice; \
|
||||
SekCycleAim += m68k_cycles; \
|
||||
while (SekCycleCnt < SekCycleAim) { \
|
||||
slice = SekCycleCnt; \
|
||||
run_m68k(SekCycleAim - SekCycleCnt); \
|
||||
if (!(Pico32x.regs[0] & P32XS_nRES)) \
|
||||
continue; /* SH2s reseting */ \
|
||||
slice = SekCycleCnt - slice; /* real count from 68k */ \
|
||||
if (SekCycleCnt < SekCycleAim) \
|
||||
elprintf(EL_32X, "slice %d", slice); \
|
||||
if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) { \
|
||||
pprof_start(ssh2); \
|
||||
sh2_execute(&ssh2, CYCLES_M68K2SSH2(slice)); \
|
||||
pprof_end(ssh2); \
|
||||
} \
|
||||
if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) { \
|
||||
pprof_start(msh2); \
|
||||
sh2_execute(&msh2, CYCLES_M68K2MSH2(slice)); \
|
||||
pprof_end(msh2); \
|
||||
} \
|
||||
pprof_start(dummy); \
|
||||
pprof_end(dummy); \
|
||||
} \
|
||||
while (msh2_cycles > 0 || ssh2_cycles > 0) {
|
||||
elprintf(EL_32X, "sh2 exec %u,%u->%u",
|
||||
msh2.m68krcycles_done, ssh2.m68krcycles_done, target);
|
||||
|
||||
if (Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL)) {
|
||||
ssh2.m68krcycles_done = target;
|
||||
ssh2_cycles = 0;
|
||||
}
|
||||
else if (ssh2_cycles > 0) {
|
||||
done = sh2_execute(&ssh2, ssh2_cycles);
|
||||
ssh2.m68krcycles_done += C_SH2_TO_M68K(ssh2, done);
|
||||
|
||||
ssh2_cycles = C_M68K_TO_SH2(ssh2, target - ssh2.m68krcycles_done);
|
||||
}
|
||||
|
||||
if (Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL)) {
|
||||
msh2.m68krcycles_done = target;
|
||||
msh2_cycles = 0;
|
||||
}
|
||||
else if (msh2_cycles > 0) {
|
||||
done = sh2_execute(&msh2, msh2_cycles);
|
||||
msh2.m68krcycles_done += C_SH2_TO_M68K(msh2, done);
|
||||
|
||||
msh2_cycles = C_M68K_TO_SH2(msh2, target - msh2.m68krcycles_done);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define STEP_68K 24
|
||||
#define CPUS_RUN_LOCKSTEP(m68k_cycles,s68k_cycles) \
|
||||
{ \
|
||||
int slice; \
|
||||
SekCycleAim += m68k_cycles; \
|
||||
while (SekCycleCnt < SekCycleAim) { \
|
||||
slice = SekCycleCnt; \
|
||||
run_m68k(STEP_68K); \
|
||||
if (!(Pico32x.regs[0] & P32XS_nRES)) \
|
||||
continue; /* SH2s reseting */ \
|
||||
slice = SekCycleCnt - slice; /* real count from 68k */ \
|
||||
if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) { \
|
||||
sh2_execute(&ssh2, CYCLES_M68K2SSH2(slice)); \
|
||||
} \
|
||||
if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) { \
|
||||
sh2_execute(&msh2, CYCLES_M68K2MSH2(slice)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
void sync_sh2s_lockstep(unsigned int m68k_target)
|
||||
{
|
||||
unsigned int mcycles;
|
||||
|
||||
mcycles = msh2.m68krcycles_done;
|
||||
if (ssh2.m68krcycles_done < mcycles)
|
||||
mcycles = ssh2.m68krcycles_done;
|
||||
|
||||
while (mcycles < m68k_target) {
|
||||
mcycles += STEP_68K;
|
||||
sync_sh2s_normal(mcycles);
|
||||
}
|
||||
}
|
||||
|
||||
#define CPUS_RUN CPUS_RUN_SIMPLE
|
||||
//#define CPUS_RUN CPUS_RUN_LOCKSTEP
|
||||
#define CPUS_RUN(m68k_cycles,s68k_cycles) do { \
|
||||
SekRunM68k(m68k_cycles); \
|
||||
if (SekIsStoppedM68k()) \
|
||||
p32x_sync_sh2s(SekCycleCntT + SekCycleCnt); \
|
||||
} while (0)
|
||||
|
||||
#define PICO_32X
|
||||
#include "../pico_cmn.c"
|
||||
|
||||
void PicoFrame32x(void)
|
||||
|
@ -291,3 +292,20 @@ void PicoFrame32x(void)
|
|||
elprintf(EL_32X, "poll: %02x", Pico32x.emu_flags);
|
||||
}
|
||||
|
||||
// calculate multipliers against 68k clock (7670442)
|
||||
// normally * 3, but effectively slower due to high latencies everywhere
|
||||
// however using something lower breaks MK2 animations
|
||||
void Pico32xSetClocks(int msh2_hz, int ssh2_hz)
|
||||
{
|
||||
float m68k_clk = (float)(OSC_NTSC / 7);
|
||||
if (msh2_hz > 0) {
|
||||
msh2.mult_m68k_to_sh2 = (int)((float)msh2_hz * (1 << CYCLE_MULT_SHIFT) / m68k_clk);
|
||||
msh2.mult_sh2_to_m68k = (int)(m68k_clk * (1 << CYCLE_MULT_SHIFT) / (float)msh2_hz);
|
||||
}
|
||||
if (ssh2_hz > 0) {
|
||||
ssh2.mult_m68k_to_sh2 = (int)((float)ssh2_hz * (1 << CYCLE_MULT_SHIFT) / m68k_clk);
|
||||
ssh2.mult_sh2_to_m68k = (int)(m68k_clk * (1 << CYCLE_MULT_SHIFT) / (float)ssh2_hz);
|
||||
}
|
||||
}
|
||||
|
||||
// vim:shiftwidth=2:ts=2:expandtab
|
||||
|
|
|
@ -1558,4 +1558,4 @@ void Pico32xStateLoaded(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// vim:shiftwidth=2:expandtab
|
||||
// vim:shiftwidth=2:ts=2:expandtab
|
||||
|
|
|
@ -68,30 +68,6 @@ PICO_INTERNAL int PicoResetMCD(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __inline void SekRunM68k(int cyc)
|
||||
{
|
||||
int cyc_do;
|
||||
|
||||
pprof_start(m68k);
|
||||
|
||||
SekCycleAim+=cyc;
|
||||
if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
|
||||
#if defined(EMU_CORE_DEBUG)
|
||||
SekCycleCnt+=CM_compareRun(cyc_do, 0);
|
||||
#elif defined(EMU_C68K)
|
||||
PicoCpuCM68k.cycles=cyc_do;
|
||||
CycloneRun(&PicoCpuCM68k);
|
||||
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
|
||||
#elif defined(EMU_M68K)
|
||||
m68k_set_context(&PicoCpuMM68k);
|
||||
SekCycleCnt+=m68k_execute(cyc_do);
|
||||
#elif defined(EMU_F68K)
|
||||
g_m68kcontext=&PicoCpuFM68k;
|
||||
SekCycleCnt+=fm68k_emulate(cyc_do, 0, 0);
|
||||
#endif
|
||||
pprof_end(m68k);
|
||||
}
|
||||
|
||||
static __inline void SekRunS68k(int cyc)
|
||||
{
|
||||
int cyc_do;
|
||||
|
@ -106,9 +82,11 @@ static __inline void SekRunS68k(int cyc)
|
|||
#elif defined(EMU_M68K)
|
||||
m68k_set_context(&PicoCpuMS68k);
|
||||
SekCycleCntS68k+=m68k_execute(cyc_do);
|
||||
m68k_set_context(&PicoCpuMM68k);
|
||||
#elif defined(EMU_F68K)
|
||||
g_m68kcontext=&PicoCpuFS68k;
|
||||
SekCycleCntS68k+=fm68k_emulate(cyc_do, 0, 0);
|
||||
g_m68kcontext=&PicoCpuFM68k;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
26
pico/pico.c
26
pico/pico.c
|
@ -23,9 +23,6 @@ struct PicoSRAM SRam;
|
|||
int emustatus; // rapid_ym2612, multi_ym_updates
|
||||
int scanlines_total;
|
||||
|
||||
int p32x_msh2_multiplier = MSH2_MULTI_DEFAULT;
|
||||
int p32x_ssh2_multiplier = SSH2_MULTI_DEFAULT;
|
||||
|
||||
void (*PicoWriteSound)(int len) = NULL; // called at the best time to send sound buffer (PsndOut) to hardware
|
||||
void (*PicoResetHook)(void) = NULL;
|
||||
void (*PicoLineHook)(void) = NULL;
|
||||
|
@ -273,29 +270,6 @@ PICO_INTERNAL int CheckDMA(void)
|
|||
return burn;
|
||||
}
|
||||
|
||||
static __inline void SekRunM68k(int cyc)
|
||||
{
|
||||
int cyc_do;
|
||||
pprof_start(m68k);
|
||||
|
||||
SekCycleAim+=cyc;
|
||||
if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
|
||||
#if defined(EMU_CORE_DEBUG)
|
||||
// this means we do run-compare
|
||||
SekCycleCnt+=CM_compareRun(cyc_do, 0);
|
||||
#elif defined(EMU_C68K)
|
||||
PicoCpuCM68k.cycles=cyc_do;
|
||||
CycloneRun(&PicoCpuCM68k);
|
||||
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
|
||||
#elif defined(EMU_M68K)
|
||||
SekCycleCnt+=m68k_execute(cyc_do);
|
||||
#elif defined(EMU_F68K)
|
||||
SekCycleCnt+=fm68k_emulate(cyc_do+1, 0, 0);
|
||||
#endif
|
||||
|
||||
pprof_end(m68k);
|
||||
}
|
||||
|
||||
#include "pico_cmn.c"
|
||||
|
||||
int z80stopCycle;
|
||||
|
|
22
pico/pico.h
22
pico/pico.h
|
@ -212,18 +212,24 @@ extern unsigned short *PicoCramHigh; // pointer to CRAM buff (0x40 shorts), conv
|
|||
extern void (*PicoPrepareCram)(); // prepares PicoCramHigh for renderer to use
|
||||
|
||||
// pico.c (32x)
|
||||
// multipliers against 68k clock (7670442)
|
||||
// normally * 3, but effectively slower due to high latencies everywhere
|
||||
// however using something lower breaks MK2 animations
|
||||
extern int p32x_msh2_multiplier;
|
||||
extern int p32x_ssh2_multiplier;
|
||||
#define SH2_MULTI_SHIFT 10
|
||||
#define MSH2_MULTI_DEFAULT ((1 << SH2_MULTI_SHIFT) * 3)
|
||||
#define SSH2_MULTI_DEFAULT ((1 << SH2_MULTI_SHIFT) * 3)
|
||||
#ifndef NO_32X
|
||||
|
||||
void Pico32xSetClocks(int msh2_hz, int ssh2_hz);
|
||||
|
||||
// 32x/draw.c
|
||||
void PicoDraw32xSetFrameMode(int is_on, int only_32x);
|
||||
|
||||
#else
|
||||
|
||||
#define Pico32xSetClocks(msh2_khz, ssh2_khz)
|
||||
|
||||
#endif
|
||||
|
||||
// normally 68k clock (7670442) * 3, in reality but much lower
|
||||
// because of high memory latencies
|
||||
#define PICO_MSH2_HZ ((int)(7670442.0 * 2.4))
|
||||
#define PICO_SSH2_HZ ((int)(7670442.0 * 2.4))
|
||||
|
||||
// sound.c
|
||||
extern int PsndRate,PsndLen;
|
||||
extern short *PsndOut;
|
||||
|
|
|
@ -26,6 +26,29 @@
|
|||
SekRunM68k(m68k_cycles)
|
||||
#endif
|
||||
|
||||
static __inline void SekRunM68k(int cyc)
|
||||
{
|
||||
int cyc_do;
|
||||
pprof_start(m68k);
|
||||
|
||||
SekCycleAim+=cyc;
|
||||
if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;
|
||||
#if defined(EMU_CORE_DEBUG)
|
||||
// this means we do run-compare
|
||||
SekCycleCnt+=CM_compareRun(cyc_do, 0);
|
||||
#elif defined(EMU_C68K)
|
||||
PicoCpuCM68k.cycles=cyc_do;
|
||||
CycloneRun(&PicoCpuCM68k);
|
||||
SekCycleCnt+=cyc_do-PicoCpuCM68k.cycles;
|
||||
#elif defined(EMU_M68K)
|
||||
SekCycleCnt+=m68k_execute(cyc_do);
|
||||
#elif defined(EMU_F68K)
|
||||
SekCycleCnt+=fm68k_emulate(cyc_do+1, 0, 0);
|
||||
#endif
|
||||
|
||||
pprof_end(m68k);
|
||||
}
|
||||
|
||||
static int PicoFrameHints(void)
|
||||
{
|
||||
struct PicoVideo *pv=&Pico.video;
|
||||
|
|
|
@ -50,6 +50,7 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
|
|||
#define SekSr CycloneGetSr(&PicoCpuCM68k)
|
||||
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }
|
||||
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }
|
||||
#define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)
|
||||
#define SekIsStoppedS68k() (PicoCpuCS68k.state_flags&1)
|
||||
#define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))
|
||||
|
||||
|
@ -83,6 +84,7 @@ extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
|
|||
PicoCpuFS68k.execinfo &= ~FM68K_HALTED; \
|
||||
if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \
|
||||
}
|
||||
#define SekIsStoppedM68k() (PicoCpuFM68k.execinfo&FM68K_HALTED)
|
||||
#define SekIsStoppedS68k() (PicoCpuFS68k.execinfo&FM68K_HALTED)
|
||||
#define SekShouldInterrupt fm68k_would_interrupt()
|
||||
|
||||
|
@ -117,6 +119,7 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
|
|||
if(x) { SET_CYCLES(0); PicoCpuMS68k.stopped=STOP_LEVEL_STOP; } \
|
||||
else PicoCpuMS68k.stopped=0; \
|
||||
}
|
||||
#define SekIsStoppedM68k() (PicoCpuMM68k.stopped==STOP_LEVEL_STOP)
|
||||
#define SekIsStoppedS68k() (PicoCpuMS68k.stopped==STOP_LEVEL_STOP)
|
||||
#define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)
|
||||
|
||||
|
@ -235,13 +238,13 @@ extern SH2 sh2s[2];
|
|||
|
||||
#ifndef DRC_SH2
|
||||
# define ash2_end_run(after) if (sh2->icount > (after)) sh2->icount = after
|
||||
# define ash2_cycles_done() (sh2->cycles_aim - sh2->icount)
|
||||
# define ash2_cycles_done() (sh2->cycles_timeslice - sh2->icount)
|
||||
#else
|
||||
# define ash2_end_run(after) { \
|
||||
if ((sh2->sr >> 12) > (after)) \
|
||||
{ sh2->sr &= 0xfff; sh2->sr |= (after) << 12; } \
|
||||
}
|
||||
# define ash2_cycles_done() (sh2->cycles_aim - (sh2->sr >> 12))
|
||||
# define ash2_cycles_done() (sh2->cycles_timeslice - (sh2->sr >> 12))
|
||||
#endif
|
||||
|
||||
//#define sh2_pc(c) (c) ? ssh2.ppc : msh2.ppc
|
||||
|
@ -712,6 +715,7 @@ void PicoReset32x(void);
|
|||
void Pico32xStartup(void);
|
||||
void PicoUnload32x(void);
|
||||
void PicoFrame32x(void);
|
||||
void p32x_sync_sh2s(unsigned int m68k_target);
|
||||
void p32x_update_irls(int nested_call);
|
||||
void p32x_reset_sh2s(void);
|
||||
|
||||
|
|
|
@ -333,6 +333,8 @@ static int state_save(void *file)
|
|||
CHECKED_WRITE_BUFF(CHUNK_SDRAM, Pico32xMem->sdram);
|
||||
CHECKED_WRITE_BUFF(CHUNK_DRAM, Pico32xMem->dram);
|
||||
CHECKED_WRITE_BUFF(CHUNK_32XPAL, Pico32xMem->pal);
|
||||
|
||||
sh2s[0].m68krcycles_done = sh2s[1].m68krcycles_done = SekCycleCnt;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -690,4 +692,4 @@ void PicoTmpStateRestore(void *data)
|
|||
#endif
|
||||
}
|
||||
|
||||
// vim:shiftwidth=2:expandtab
|
||||
// vim:shiftwidth=2:ts=2:expandtab
|
||||
|
|
|
@ -319,11 +319,14 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
|
|||
return 1;
|
||||
|
||||
case MA_32XOPT_MSH2_CYCLES:
|
||||
case MA_32XOPT_SSH2_CYCLES: {
|
||||
int *mul = (me->id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
|
||||
*mul = ((unsigned int)atoi(val) << SH2_MULTI_SHIFT) / 7670;
|
||||
currentConfig.msh2_khz = atoi(val);
|
||||
Pico32xSetClocks(currentConfig.msh2_khz * 1000, 0);
|
||||
return 1;
|
||||
|
||||
case MA_32XOPT_SSH2_CYCLES:
|
||||
currentConfig.ssh2_khz = atoi(val);
|
||||
Pico32xSetClocks(0, currentConfig.ssh2_khz * 1000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* PSP */
|
||||
case MA_OPT3_SCALE:
|
||||
|
|
|
@ -548,6 +548,8 @@ void emu_prep_defconfig(void)
|
|||
defaultConfig.gamma = 100;
|
||||
defaultConfig.scaling = 0;
|
||||
defaultConfig.turbo_rate = 15;
|
||||
defaultConfig.msh2_khz = PICO_MSH2_HZ / 1000;
|
||||
defaultConfig.ssh2_khz = PICO_SSH2_HZ / 1000;
|
||||
|
||||
// platform specific overrides
|
||||
pemu_prep_defconfig();
|
||||
|
@ -561,8 +563,6 @@ void emu_set_defconfig(void)
|
|||
PicoRegionOverride = currentConfig.s_PicoRegion;
|
||||
PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;
|
||||
PicoCDBuffers = currentConfig.s_PicoCDBuffers;
|
||||
p32x_msh2_multiplier = MSH2_MULTI_DEFAULT;
|
||||
p32x_ssh2_multiplier = SSH2_MULTI_DEFAULT;
|
||||
}
|
||||
|
||||
int emu_read_config(const char *rom_fname, int no_defaults)
|
||||
|
|
|
@ -80,6 +80,8 @@ typedef struct _currentConfig_t {
|
|||
int renderer32x;
|
||||
int filter; // pandora
|
||||
int analog_deadzone;
|
||||
int msh2_khz;
|
||||
int ssh2_khz;
|
||||
} currentConfig_t;
|
||||
|
||||
extern currentConfig_t currentConfig, defaultConfig;
|
||||
|
|
|
@ -444,26 +444,28 @@ static int menu_loop_cd_options(int id, int keys)
|
|||
// convert from multiplier of VClk
|
||||
static int mh_opt_sh2cycles(int id, int keys)
|
||||
{
|
||||
int *mul = (id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
|
||||
int *khz = (id == MA_32XOPT_MSH2_CYCLES) ?
|
||||
¤tConfig.msh2_khz : ¤tConfig.ssh2_khz;
|
||||
|
||||
if (keys & (PBTN_LEFT|PBTN_RIGHT))
|
||||
*mul += (keys & PBTN_LEFT) ? -10 : 10;
|
||||
*khz += (keys & PBTN_LEFT) ? -50 : 50;
|
||||
if (keys & (PBTN_L|PBTN_R))
|
||||
*mul += (keys & PBTN_L) ? -100 : 100;
|
||||
*khz += (keys & PBTN_L) ? -500 : 500;
|
||||
|
||||
if (*mul < 1)
|
||||
*mul = 1;
|
||||
else if (*mul > (10 << SH2_MULTI_SHIFT))
|
||||
*mul = 10 << SH2_MULTI_SHIFT;
|
||||
if (*khz < 1)
|
||||
*khz = 1;
|
||||
else if (*khz > 0x7fffffff / 1000)
|
||||
*khz = 0x7fffffff / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *mgn_opt_sh2cycles(int id, int *offs)
|
||||
{
|
||||
int mul = (id == MA_32XOPT_MSH2_CYCLES) ? p32x_msh2_multiplier : p32x_ssh2_multiplier;
|
||||
int khz = (id == MA_32XOPT_MSH2_CYCLES) ?
|
||||
currentConfig.msh2_khz : currentConfig.ssh2_khz;
|
||||
|
||||
sprintf(static_buff, "%d", 7670 * mul >> SH2_MULTI_SHIFT);
|
||||
sprintf(static_buff, "%d", khz);
|
||||
return static_buff;
|
||||
}
|
||||
|
||||
|
@ -490,6 +492,8 @@ static int menu_loop_32x_options(int id, int keys)
|
|||
me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL);
|
||||
me_loop(e_menu_32x_options, &sel);
|
||||
|
||||
Pico32xSetClocks(currentConfig.msh2_khz * 1000, currentConfig.msh2_khz * 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -609,9 +609,6 @@ void retro_init(void)
|
|||
PicoAutoRgnOrder = 0x184; // US, EU, JP
|
||||
PicoCDBuffers = 0;
|
||||
|
||||
p32x_msh2_multiplier = MSH2_MULTI_DEFAULT;
|
||||
p32x_ssh2_multiplier = SSH2_MULTI_DEFAULT;
|
||||
|
||||
vout_width = 320;
|
||||
vout_height = 240;
|
||||
vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue