DSP: Add cycles parameter to all Update functions in HLE, might be useful someday :p A couple more signatures for the idle skip detector. no big functional changes
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2932 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
541832e4f0
commit
0c4d4835ac
|
@ -27,9 +27,9 @@ typedef void (__cdecl* TDSP_WriteMailBox)(bool _CPUMailbox, unsigned short);
|
||||||
typedef unsigned short (__cdecl* TDSP_ReadMailBox)(bool _CPUMailbox);
|
typedef unsigned short (__cdecl* TDSP_ReadMailBox)(bool _CPUMailbox);
|
||||||
typedef unsigned short (__cdecl* TDSP_ReadControlRegister)();
|
typedef unsigned short (__cdecl* TDSP_ReadControlRegister)();
|
||||||
typedef unsigned short (__cdecl* TDSP_WriteControlRegister)(unsigned short);
|
typedef unsigned short (__cdecl* TDSP_WriteControlRegister)(unsigned short);
|
||||||
typedef void (__cdecl* TDSP_SendAIBuffer)(unsigned int address, int sample_rate);
|
typedef void (__cdecl *TDSP_SendAIBuffer)(unsigned int address, int sample_rate);
|
||||||
typedef void (__cdecl* TDSP_Update)(int cycles);
|
typedef void (__cdecl *TDSP_Update)(int cycles);
|
||||||
typedef void (__cdecl* TDSP_StopSoundStream)();
|
typedef void (__cdecl *TDSP_StopSoundStream)();
|
||||||
|
|
||||||
class PluginDSP : public CPlugin
|
class PluginDSP : public CPlugin
|
||||||
{
|
{
|
||||||
|
|
|
@ -268,7 +268,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
_uReturnValue = g_AR_MODE;
|
_uReturnValue = g_AR_MODE;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x5016: // ready flag ?
|
case 0x5016: // ready flag?
|
||||||
_uReturnValue = g_AR_READY_FLAG;
|
_uReturnValue = g_AR_READY_FLAG;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -276,12 +276,12 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
_uReturnValue = 0x000;
|
_uReturnValue = 0x000;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case AR_DMA_MMADDR_H: _uReturnValue = g_arDMA.MMAddr>>16; return;
|
case AR_DMA_MMADDR_H: _uReturnValue = g_arDMA.MMAddr >> 16; return;
|
||||||
case AR_DMA_MMADDR_L: _uReturnValue = g_arDMA.MMAddr&0xFFFF; return;
|
case AR_DMA_MMADDR_L: _uReturnValue = g_arDMA.MMAddr & 0xFFFF; return;
|
||||||
case AR_DMA_ARADDR_H: _uReturnValue = g_arDMA.ARAddr>>16; return;
|
case AR_DMA_ARADDR_H: _uReturnValue = g_arDMA.ARAddr >> 16; return;
|
||||||
case AR_DMA_ARADDR_L: _uReturnValue = g_arDMA.ARAddr&0xFFFF; return;
|
case AR_DMA_ARADDR_L: _uReturnValue = g_arDMA.ARAddr & 0xFFFF; return;
|
||||||
case AR_DMA_CNT_H: _uReturnValue = g_arDMA.Cnt.Hex>>16; return;
|
case AR_DMA_CNT_H: _uReturnValue = g_arDMA.Cnt.Hex >> 16; return;
|
||||||
case AR_DMA_CNT_L: _uReturnValue = g_arDMA.Cnt.Hex&0xFFFF; return;
|
case AR_DMA_CNT_L: _uReturnValue = g_arDMA.Cnt.Hex & 0xFFFF; return;
|
||||||
|
|
||||||
// ==================================================================================
|
// ==================================================================================
|
||||||
// DMA_REGS 0x5030+
|
// DMA_REGS 0x5030+
|
||||||
|
@ -296,7 +296,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case AUDIO_DMA_START_HI:
|
case AUDIO_DMA_START_HI:
|
||||||
_uReturnValue = g_audioDMA.SourceAddress>>16;
|
_uReturnValue = g_audioDMA.SourceAddress >> 16;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case AUDIO_DMA_CONTROL_LEN:
|
case AUDIO_DMA_CONTROL_LEN:
|
||||||
|
@ -626,42 +626,39 @@ u8 ReadARAM(u32 _iAddress)
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x", _iAddress);
|
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x", _iAddress);
|
||||||
|
|
||||||
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
||||||
if(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||||
{
|
{
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
//LOGV(DSPINTERFACE, 0, "ARAM (r) 0x%08x 0x%08x 0x%08x", WII_MASK, _iAddress, (_iAddress & WII_MASK));
|
||||||
|
|
||||||
// Does this make any sense?
|
// Does this make any sense?
|
||||||
if(_iAddress > WII_MASK)
|
if (_iAddress > WII_MASK)
|
||||||
{
|
{
|
||||||
if(_iAddress > WII_MEM2)
|
if (_iAddress > WII_MEM2)
|
||||||
_iAddress = (_iAddress & WII_MEM2);
|
_iAddress = (_iAddress & WII_MEM2);
|
||||||
return g_MEM2[_iAddress];
|
return g_MEM2[_iAddress];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(_iAddress > WII_MASK)
|
return g_ARAM[_iAddress & ARAM_MASK];
|
||||||
_iAddress = (_iAddress & WII_MASK);
|
|
||||||
return g_ARAM[_iAddress];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return g_ARAM[_iAddress & ARAM_MASK];
|
return g_ARAM[_iAddress & ARAM_MASK];
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* GetARAMPtr()
|
u8 *GetARAMPtr()
|
||||||
{
|
{
|
||||||
return g_ARAM;
|
return g_ARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should this really be a function? The hardware only supports block DMA.
|
||||||
|
|
||||||
void WriteARAM(u8 _iValue, u32 _iAddress)
|
void WriteARAM(u8 _iValue, u32 _iAddress)
|
||||||
{
|
{
|
||||||
//LOGV(DSPINTERFACE, 0, "ARAM (w) 0x%08x = 0x%08x", _iAddress, (_iAddress & ARAM_MASK));
|
// LOGV(DSPINTERFACE, 0, "ARAM (w) 0x%08x = 0x%08x", _iAddress, (_iAddress & ARAM_MASK));
|
||||||
|
|
||||||
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
// _dbg_assert_(DSPINTERFACE,(_iAddress) < ARAM_SIZE);
|
||||||
//rouge leader writes WAY outside
|
// rouge leader writes WAY outside
|
||||||
//not really surprising since it uses a totally different memory model :P
|
// not really surprising since it uses a totally different memory model :P
|
||||||
g_ARAM[_iAddress & ARAM_MASK] = _iValue;
|
g_ARAM[_iAddress & ARAM_MASK] = _iValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,12 +90,13 @@ u32 CPU_CORE_CLOCK = 486000000u; // 486 mhz (its not 485, stop bugg
|
||||||
s64 fakeDec;
|
s64 fakeDec;
|
||||||
u64 startTimeBaseTicks;
|
u64 startTimeBaseTicks;
|
||||||
|
|
||||||
// ratio of TB and Decrementer to clock cycles
|
// Ratio of TB and Decrementer to clock cycles.
|
||||||
// With TB clk at 1/4 of BUS clk
|
// TB clk is 1/4 of BUS clk. And it seems BUS clk is really 1/3 of CPU clk.
|
||||||
// and it seems BUS clk is really 1/3 of CPU clk
|
// So, ratio is 1 / (1/4 * 1/3 = 1/12) = 12.
|
||||||
// note: ZWW is ok and faster with TIMER_RATIO=8 though.
|
// note: ZWW is ok and faster with TIMER_RATIO=8 though.
|
||||||
// !!! POSSIBLE STABLE PERF BOOST HACK THERE !!!
|
// !!! POSSIBLE STABLE PERF BOOST HACK THERE !!!
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
TIMER_RATIO = 12
|
TIMER_RATIO = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,32 +110,32 @@ int et_IPC_HLE;
|
||||||
int et_FakeGPWD; // for DC watchdog hack
|
int et_FakeGPWD; // for DC watchdog hack
|
||||||
|
|
||||||
// These are badly educated guesses
|
// These are badly educated guesses
|
||||||
// Feel free to experiment
|
// Feel free to experiment. Set these in Init below.
|
||||||
int
|
int
|
||||||
// update VI often to let it go through its scanlines with decent accuracy
|
// update VI often to let it go through its scanlines with decent accuracy
|
||||||
// Maybe should actually align this with the scanline update? Current method in
|
// Maybe should actually align this with the scanline update? Current method in
|
||||||
// VideoInterface::Update is stupid!
|
// VideoInterface::Update is stupid!
|
||||||
VI_PERIOD = GetTicksPerSecond() / (60*120),
|
VI_PERIOD,
|
||||||
|
|
||||||
// TODO: The SI interfact actually has a register that determines the polling frequency.
|
// TODO: The SI in fact actually has a register that determines the polling frequency.
|
||||||
// We should obey that instead of arbitrarly checking at 60fps.
|
// We should obey that instead of arbitrarly checking at 60fps.
|
||||||
SI_PERIOD = GetTicksPerSecond() / 60, //once a frame is good for controllers
|
SI_PERIOD, // once a frame is good for controllers
|
||||||
|
|
||||||
// This one should simply be determined by the increasing counter in AI.
|
// This one should simply be determined by the increasing counter in AI.
|
||||||
AI_PERIOD = GetTicksPerSecond() / 80,
|
AI_PERIOD,
|
||||||
|
|
||||||
// These shouldn't be period controlled either, most likely.
|
// These shouldn't be period controlled either, most likely.
|
||||||
DSP_PERIOD = GetTicksPerSecond() / 250,
|
DSP_PERIOD,
|
||||||
|
|
||||||
// This is completely arbitrary. If we find that we need lower latency, we can just
|
// This is completely arbitrary. If we find that we need lower latency, we can just
|
||||||
// increase this number.
|
// increase this number.
|
||||||
IPC_HLE_PERIOD = GetTicksPerSecond() / 250,
|
IPC_HLE_PERIOD,
|
||||||
|
|
||||||
// For DC watchdog hack
|
// For DC watchdog hack
|
||||||
// Once every 4 frame-period seems to be enough (arbitrary taking 60fps as the ref).
|
// Once every 4 frame-period seems to be enough (arbitrary taking 60fps as the ref).
|
||||||
// TODO: make it VI output frame rate compliant (30/60 and 25/50)
|
// TODO: make it VI output frame rate compliant (30/60 and 25/50)
|
||||||
// Assuming game's frame-finish-watchdog wait more than 4 emulated frame-period before starting its mess.
|
// Assuming game's frame-finish-watchdog wait more than 4 emulated frame-period before starting its mess.
|
||||||
FAKE_GP_WATCHDOG_PERIOD = GetTicksPerSecond() / 15;
|
FAKE_GP_WATCHDOG_PERIOD;
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,14 +154,15 @@ void AICallback(u64 userdata, int cyclesLate)
|
||||||
// Update disk streaming. All that code really needs a revamp, including replacing the codec with the one
|
// Update disk streaming. All that code really needs a revamp, including replacing the codec with the one
|
||||||
// from in_cube.
|
// from in_cube.
|
||||||
AudioInterface::Update();
|
AudioInterface::Update();
|
||||||
CoreTiming::ScheduleEvent(AI_PERIOD-cyclesLate, et_AI);
|
CoreTiming::ScheduleEvent(AI_PERIOD - cyclesLate, et_AI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DSP/CPU timeslicing.
|
||||||
void DSPCallback(u64 userdata, int cyclesLate)
|
void DSPCallback(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
// ~1/6th as many cycles as the period PPC-side.
|
// ~1/6th as many cycles as the period PPC-side.
|
||||||
CPluginManager::GetInstance().GetDSP()->DSP_Update(DSP_PERIOD / 6);
|
CPluginManager::GetInstance().GetDSP()->DSP_Update(DSP_PERIOD / 6);
|
||||||
CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, et_DSP);
|
CoreTiming::ScheduleEvent(DSP_PERIOD - cyclesLate, et_DSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioFifoCallback(u64 userdata, int cyclesLate)
|
void AudioFifoCallback(u64 userdata, int cyclesLate)
|
||||||
|
@ -235,6 +237,7 @@ void FakeGPWatchdogCallback(u64 userdata, int cyclesLate)
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
|
FAKE_GP_WATCHDOG_PERIOD = GetTicksPerSecond() / 15;
|
||||||
if (Core::GetStartupParameter().bWii)
|
if (Core::GetStartupParameter().bWii)
|
||||||
{
|
{
|
||||||
CPU_CORE_CLOCK = 729000000u;
|
CPU_CORE_CLOCK = 729000000u;
|
||||||
|
@ -268,6 +271,8 @@ void Init()
|
||||||
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
|
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
|
||||||
et_AudioFifo = CoreTiming::RegisterEvent("AudioFifoCallback", AudioFifoCallback);
|
et_AudioFifo = CoreTiming::RegisterEvent("AudioFifoCallback", AudioFifoCallback);
|
||||||
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
||||||
|
// Always register this. Increases chances of DC/SC save state compatibility.
|
||||||
|
et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback);
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
|
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
|
||||||
CoreTiming::ScheduleEvent(VI_PERIOD, et_VI);
|
CoreTiming::ScheduleEvent(VI_PERIOD, et_VI);
|
||||||
|
@ -278,7 +283,6 @@ void Init()
|
||||||
// For DC watchdog hack
|
// For DC watchdog hack
|
||||||
if (Core::GetStartupParameter().bUseDualCore)
|
if (Core::GetStartupParameter().bUseDualCore)
|
||||||
{
|
{
|
||||||
et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback);
|
|
||||||
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD, et_FakeGPWD);
|
CoreTiming::ScheduleEvent(FAKE_GP_WATCHDOG_PERIOD, et_FakeGPWD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,10 @@ CDSPHandler::~CDSPHandler()
|
||||||
m_pUCode = NULL;
|
m_pUCode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDSPHandler::Update()
|
void CDSPHandler::Update(int cycles)
|
||||||
{
|
{
|
||||||
if (m_pUCode != NULL)
|
if (m_pUCode != NULL)
|
||||||
m_pUCode->Update();
|
m_pUCode->Update(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value)
|
unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
class CDSPHandler
|
class CDSPHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
unsigned short WriteControlRegister(unsigned short _Value);
|
unsigned short WriteControlRegister(unsigned short _Value);
|
||||||
unsigned short ReadControlRegister();
|
unsigned short ReadControlRegister();
|
||||||
void SendMailToDSP(u32 _uMail);
|
void SendMailToDSP(u32 _uMail);
|
||||||
|
|
|
@ -415,7 +415,6 @@ void CUCode_AX::HandleMail(u32 _uMail)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DSPHLE, " >>>> u32 MAIL : AXTask Mail (%08x)", _uMail);
|
DEBUG_LOG(DSPHLE, " >>>> u32 MAIL : AXTask Mail (%08x)", _uMail);
|
||||||
AXTask(_uMail);
|
AXTask(_uMail);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +422,7 @@ void CUCode_AX::HandleMail(u32 _uMail)
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Update with DSP Interrupt
|
// Update with DSP Interrupt
|
||||||
// -----------
|
// -----------
|
||||||
void CUCode_AX::Update()
|
void CUCode_AX::Update(int cycles)
|
||||||
{
|
{
|
||||||
// check if we have to sent something
|
// check if we have to sent something
|
||||||
if (!m_rMailHandler.IsEmpty())
|
if (!m_rMailHandler.IsEmpty())
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void MixAdd(short* _pBuffer, int _iSize);
|
void MixAdd(short* _pBuffer, int _iSize);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
//template<class ParamBlockType>
|
//template<class ParamBlockType>
|
||||||
|
|
|
@ -225,7 +225,7 @@ void CUCode_AXWii::MixAdd_(short* _pBuffer, int _iSize, ParamBlockType &PBs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_AXWii::Update()
|
void CUCode_AXWii::Update(int cycles)
|
||||||
{
|
{
|
||||||
// check if we have to sent something
|
// check if we have to sent something
|
||||||
if (!m_rMailHandler.IsEmpty())
|
if (!m_rMailHandler.IsEmpty())
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
template<class ParamBlockType>
|
template<class ParamBlockType>
|
||||||
//void Logging(short* _pBuffer, int _iSize, int a, bool Wii, ParamBlockType &PBs, int numberOfPBs);
|
//void Logging(short* _pBuffer, int _iSize, int a, bool Wii, ParamBlockType &PBs, int numberOfPBs);
|
||||||
void MixAdd_(short* _pBuffer, int _iSize, ParamBlockType &PBs);
|
void MixAdd_(short* _pBuffer, int _iSize, ParamBlockType &PBs);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
|
|
||||||
// The logging function for the debugger
|
// The logging function for the debugger
|
||||||
void Logging(short* _pBuffer, int _iSize, int a);
|
void Logging(short* _pBuffer, int _iSize, int a);
|
||||||
|
|
|
@ -35,7 +35,7 @@ CUCode_CARD::~CUCode_CARD()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_CARD::Update()
|
void CUCode_CARD::Update(int cycles)
|
||||||
{
|
{
|
||||||
// check if we have to sent something
|
// check if we have to sent something
|
||||||
if (!m_rMailHandler.IsEmpty())
|
if (!m_rMailHandler.IsEmpty())
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual ~CUCode_CARD();
|
virtual ~CUCode_CARD();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,7 +38,7 @@ void CUCode_InitAudioSystem::Init()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_InitAudioSystem::Update()
|
void CUCode_InitAudioSystem::Update(int cycles)
|
||||||
{
|
{
|
||||||
if (m_rMailHandler.IsEmpty())
|
if (m_rMailHandler.IsEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
virtual ~CUCode_InitAudioSystem();
|
virtual ~CUCode_InitAudioSystem();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -87,7 +87,7 @@ void CUCode_Jac::HandleMail(u32 _uMail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_Jac::Update()
|
void CUCode_Jac::Update(int cycles)
|
||||||
{
|
{
|
||||||
// check if we have to sent something
|
// check if we have to sent something
|
||||||
/* if (!g_MailHandler.empty())
|
/* if (!g_MailHandler.empty())
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
virtual ~CUCode_Jac();
|
virtual ~CUCode_Jac();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@ CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler)
|
||||||
CUCode_Rom::~CUCode_Rom()
|
CUCode_Rom::~CUCode_Rom()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CUCode_Rom::Update()
|
void CUCode_Rom::Update(int cycles)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CUCode_Rom::HandleMail(u32 _uMail)
|
void CUCode_Rom::HandleMail(u32 _uMail)
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
virtual ~CUCode_Rom();
|
virtual ~CUCode_Rom();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SUCode
|
struct SUCode
|
||||||
|
|
|
@ -47,7 +47,7 @@ CUCode_Zelda::~CUCode_Zelda()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_Zelda::Update()
|
void CUCode_Zelda::Update(int cycles)
|
||||||
{
|
{
|
||||||
// check if we have to sent something
|
// check if we have to sent something
|
||||||
if (!m_rMailHandler.IsEmpty())
|
if (!m_rMailHandler.IsEmpty())
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
virtual ~CUCode_Zelda();
|
virtual ~CUCode_Zelda();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update();
|
void Update(int cycles);
|
||||||
void MixAdd(short* buffer, int size);
|
void MixAdd(short* buffer, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void HandleMail(u32 _uMail) = 0;
|
virtual void HandleMail(u32 _uMail) = 0;
|
||||||
virtual void Update(void) = 0;
|
|
||||||
|
// Cycles are out of the 81/121mhz the DSP runs at.
|
||||||
|
virtual void Update(int cycles) = 0;
|
||||||
virtual void MixAdd(short* buffer, int size) {}
|
virtual void MixAdd(short* buffer, int size) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -308,7 +308,8 @@ unsigned short DSP_ReadControlRegister()
|
||||||
|
|
||||||
void DSP_Update(int cycles)
|
void DSP_Update(int cycles)
|
||||||
{
|
{
|
||||||
CDSPHandler::GetInstance().Update();
|
// This is called OFTEN - better not do anything expensive!
|
||||||
|
CDSPHandler::GetInstance().Update(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other Audio will pass through here. The kind of audio that sometimes are
|
/* Other Audio will pass through here. The kind of audio that sometimes are
|
||||||
|
|
|
@ -27,20 +27,30 @@ u8 inst_flags[ISPACE];
|
||||||
|
|
||||||
// Good candidates for idle skipping is mail wait loops. If we're time slicing
|
// Good candidates for idle skipping is mail wait loops. If we're time slicing
|
||||||
// between the main CPU and the DSP, if the DSP runs into one of these, it might
|
// between the main CPU and the DSP, if the DSP runs into one of these, it might
|
||||||
// as well give up its time slice immediately.
|
// as well give up its time slice immediately, after executing once.
|
||||||
|
|
||||||
// Max signature length is 6. A 0 in a signature is ignored.
|
// Max signature length is 6. A 0 in a signature is ignored.
|
||||||
#define NUM_IDLE_SIGS 2
|
#define NUM_IDLE_SIGS 4
|
||||||
#define MAX_IDLE_SIG_SIZE 6
|
#define MAX_IDLE_SIG_SIZE 6
|
||||||
|
|
||||||
|
// 0xFFFF means ignore.
|
||||||
const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
|
const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
|
||||||
{
|
{
|
||||||
|
{ 0x26fc, // LRS $30, @DMBH
|
||||||
|
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
||||||
|
0x029d, 0xFFFF, // JLZ 0x027a
|
||||||
|
0x02df, 0 }, // RET
|
||||||
{ 0x27fc, // LRS $31, @DMBH
|
{ 0x27fc, // LRS $31, @DMBH
|
||||||
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
||||||
0x029d, 0x027a, // JLZ 0x027a
|
0x029d, 0xFFFF, // JLZ 0x027a
|
||||||
|
0x02df, 0 }, // RET
|
||||||
|
{ 0x26fe, // LRS $30, @CMBH
|
||||||
|
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
||||||
|
0x029c, 0xFFFF, // JLNZ 0x0280
|
||||||
0x02df, 0 }, // RET
|
0x02df, 0 }, // RET
|
||||||
{ 0x27fe, // LRS $31, @CMBH
|
{ 0x27fe, // LRS $31, @CMBH
|
||||||
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
||||||
0x029c, 0x0280, // JLNZ 0x0280
|
0x029c, 0xFFFF, // JLNZ 0x0280
|
||||||
0x02df, 0 }, // RET
|
0x02df, 0 }, // RET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +90,8 @@ void AnalyzeRange(int start_addr, int end_addr)
|
||||||
{
|
{
|
||||||
if (idle_skip_sigs[s][i] == 0)
|
if (idle_skip_sigs[s][i] == 0)
|
||||||
found = true;
|
found = true;
|
||||||
|
if (idle_skip_sigs[s][i] == 0xFFFF)
|
||||||
|
continue;
|
||||||
if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i))
|
if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue