Merge pull request #5440 from ligfx/axhledelayinterrupt

AX-HLE: delay sending interrupt when done processing command list
This commit is contained in:
Markus Wick 2017-05-23 14:29:45 +02:00 committed by GitHub
commit 3a2ec8c8a1
6 changed files with 27 additions and 18 deletions

View File

@ -3,16 +3,9 @@
[Core]
# Values set here will override the main Dolphin settings.
MMU = 1
# LLE audio enabled by default for a listenable output
DSPHLE = False
[DSP]
# Ensure the LLE recompiler gets selected and not interpreter.
EnableJIT = True
[EmuState]
# The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = Needs LLE audio for proper sound.
EmulationStateId = 4
[OnLoad]

View File

@ -408,15 +408,14 @@ static void GenerateDSPInterrupt(u64 DSPIntType, s64 cyclesLate)
// DSP_CONTROL - we mask by (INT_DSP | INT_ARAM | INT_AID) just to ensure people
// don't call this with bogus values.
s_dspState.Hex |= (DSPIntType & (INT_DSP | INT_ARAM | INT_AID));
UpdateInterrupts();
}
// CALLED FROM DSP EMULATOR, POSSIBLY THREADED
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type)
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, int cycles_into_future)
{
// TODO: Maybe rethink this? The timing is unpredictable.
CoreTiming::ScheduleEvent(0, s_et_GenerateDSPInterrupt, type, CoreTiming::FromThread::ANY);
CoreTiming::ScheduleEvent(cycles_into_future, s_et_GenerateDSPInterrupt, type,
CoreTiming::FromThread::ANY);
}
// called whenever SystemTimers thinks the DSP deserves a few more cycles

View File

@ -69,7 +69,8 @@ DSPEmulator* GetDSPEmulator();
void DoState(PointerWrap& p);
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type);
// TODO: Maybe rethink this? The timing is unpredictable.
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, int cycles_into_future = 0);
// Audio/DSP Helper
u8 ReadARAM(u32 address);

View File

@ -22,21 +22,21 @@ CMailHandler::~CMailHandler()
Clear();
}
void CMailHandler::PushMail(u32 _Mail, bool interrupt)
void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future)
{
if (interrupt)
{
if (m_Mails.empty())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP, cycles_into_future);
}
else
{
m_Mails.front().second = true;
}
}
m_Mails.emplace(_Mail, false);
DEBUG_LOG(DSP_MAIL, "DSP writes 0x%08x", _Mail);
m_Mails.emplace(mail, false);
DEBUG_LOG(DSP_MAIL, "DSP writes 0x%08x", mail);
}
u16 CMailHandler::ReadDSPMailboxHigh()

View File

@ -21,7 +21,8 @@ public:
CMailHandler();
~CMailHandler();
void PushMail(u32 _Mail, bool interrupt = false);
// TODO: figure out correct timing for interrupts rather than defaulting to "immediately."
void PushMail(u32 mail, bool interrupt = false, int cycles_into_future = 0);
void Clear();
void Halt(bool _Halt);
void DoState(PointerWrap& p);

View File

@ -77,7 +77,22 @@ void AXUCode::LoadResamplingCoefficients()
void AXUCode::SignalWorkEnd()
{
// Signal end of processing
m_mail_handler.PushMail(DSP_YIELD, true);
// TODO: figure out how many cycles this is actually supposed to take
// The Clone Wars hangs upon initial boot if this interrupt happens too quickly after submitting a
// command list. When played in DSP-LLE, the interrupt lags by about 160,000 cycles, though any
// value greater than or equal to 814 will work here. In other games, the lag can be as small as
// 50,000 cycles (in Metroid Prime) and as large as 718,092 cycles (in Tales of Symphonia!).
// On the PowerPC side, hthh_ discovered that The Clone Wars tracks a "AXCommandListCycles"
// variable which matches the aforementioned 160,000 cycles. It's initialized to ~2500 cycles for
// a minimal, empty command list, so that should be a safe number for pretty much anything a game
// does.
// For more information, see https://bugs.dolphin-emu.org/issues/10265.
constexpr int AX_EMPTY_COMMAND_LIST_CYCLES = 2500;
m_mail_handler.PushMail(DSP_YIELD, true, AX_EMPTY_COMMAND_LIST_CYCLES);
}
void AXUCode::HandleCommandList()