Merge pull request #792 from booto/dsp-cleanup

DSP cleanup
This commit is contained in:
Matthew Parlane
2014-08-19 20:28:51 +12:00
2 changed files with 34 additions and 38 deletions

View File

@ -199,19 +199,20 @@ void DoState(PointerWrap &p)
} }
void UpdateInterrupts(); static void UpdateInterrupts();
void Do_ARAM_DMA(); static void Do_ARAM_DMA();
void WriteARAM(u8 _iValue, u32 _iAddress); static void GenerateDSPInterrupt(u64 DSPIntType, int cyclesLate = 0);
bool Update_DSP_ReadRegister();
void Update_DSP_WriteRegister();
static int et_GenerateDSPInterrupt; static int et_GenerateDSPInterrupt;
static int et_CompleteARAM;
static void GenerateDSPInterrupt_Wrapper(u64 userdata, int cyclesLate) static void CompleteARAM(u64 userdata, int cyclesLate)
{ {
GenerateDSPInterrupt((DSPInterruptType)(userdata&0xFFFF), (bool)((userdata>>16) & 1)); g_dspState.DSPControl.DMAState = 0;
GenerateDSPInterrupt(INT_ARAM);
} }
DSPEmulator *GetDSPEmulator() DSPEmulator *GetDSPEmulator()
{ {
return dsp_emulator; return dsp_emulator;
@ -248,7 +249,8 @@ void Init(bool hle)
g_AR_MODE = 1; // ARAM Controller has init'd g_AR_MODE = 1; // ARAM Controller has init'd
g_AR_REFRESH = 156; // 156MHz g_AR_REFRESH = 156; // 156MHz
et_GenerateDSPInterrupt = CoreTiming::RegisterEvent("DSPint", GenerateDSPInterrupt_Wrapper); et_GenerateDSPInterrupt = CoreTiming::RegisterEvent("DSPint", GenerateDSPInterrupt);
et_CompleteARAM = CoreTiming::RegisterEvent("ARAMint", CompleteARAM);
} }
void Shutdown() void Shutdown()
@ -406,7 +408,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
// We make the samples ready as soon as possible // We make the samples ready as soon as possible
void *address = Memory::GetPointer(g_audioDMA.SourceAddress); void *address = Memory::GetPointer(g_audioDMA.SourceAddress);
AudioCommon::SendAIBuffer((short*)address, g_audioDMA.AudioDMAControl.NumBlocks * 8); AudioCommon::SendAIBuffer((short*)address, g_audioDMA.AudioDMAControl.NumBlocks * 8);
CoreTiming::ScheduleEvent_Threadsafe(80, et_GenerateDSPInterrupt, INT_AID | (1 << 16)); CoreTiming::ScheduleEvent_Threadsafe(80, et_GenerateDSPInterrupt, INT_AID);
} }
}) })
); );
@ -429,36 +431,31 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
} }
// UpdateInterrupts // UpdateInterrupts
void UpdateInterrupts() static void UpdateInterrupts()
{ {
if ((g_dspState.DSPControl.AID & g_dspState.DSPControl.AID_mask) || // For each interrupt bit in DSP_CONTROL, the interrupt enablemask is the bit directly
(g_dspState.DSPControl.ARAM & g_dspState.DSPControl.ARAM_mask) || // to the left of it. By doing:
(g_dspState.DSPControl.DSP & g_dspState.DSPControl.DSP_mask)) // (DSP_CONTROL>>1) & DSP_CONTROL & MASK_OF_ALL_INTERRUPT_BITS
{ // We can check if any of the interrupts are enabled and active, all at once.
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, true); bool ints_set = (((g_dspState.DSPControl.Hex >> 1) & g_dspState.DSPControl.Hex & (INT_DSP | INT_ARAM | INT_AID)) != 0);
}
else ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, ints_set);
{
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, false);
}
} }
void GenerateDSPInterrupt(DSPInterruptType type, bool _bSet) static void GenerateDSPInterrupt(u64 DSPIntType, int cyclesLate)
{ {
switch (type) // The INT_* enumeration members have values that reflect their bit positions in
{ // DSP_CONTROL - we mask by (INT_DSP | INT_ARAM | INT_AID) just to ensure people
case INT_DSP: g_dspState.DSPControl.DSP = _bSet ? 1 : 0; break; // don't call this with bogus values.
case INT_ARAM: g_dspState.DSPControl.ARAM = _bSet ? 1 : 0; if (_bSet) g_dspState.DSPControl.DMAState = 0; break; g_dspState.DSPControl.Hex |= (DSPIntType & (INT_DSP | INT_ARAM | INT_AID));
case INT_AID: g_dspState.DSPControl.AID = _bSet ? 1 : 0; break;
}
UpdateInterrupts(); UpdateInterrupts();
} }
// CALLED FROM DSP EMULATOR, POSSIBLY THREADED // CALLED FROM DSP EMULATOR, POSSIBLY THREADED
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, bool _bSet) void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type)
{ {
CoreTiming::ScheduleEvent_Threadsafe_Immediate(et_GenerateDSPInterrupt, type | (_bSet<<16)); CoreTiming::ScheduleEvent_Threadsafe_Immediate(et_GenerateDSPInterrupt, type);
CoreTiming::ForceExceptionCheck(100); CoreTiming::ForceExceptionCheck(100);
} }
@ -515,19 +512,19 @@ void UpdateAudioDMA()
} }
} }
void Do_ARAM_DMA() static void Do_ARAM_DMA()
{ {
g_dspState.DSPControl.DMAState = 1;
if (g_arDMA.Cnt.count == 32) if (g_arDMA.Cnt.count == 32)
{ {
// Beyond Good and Evil (GGEE41) sends count 32 // Beyond Good and Evil (GGEE41) sends count 32
// Lost Kingdoms 2 needs the exception check here in DSP HLE mode // Lost Kingdoms 2 needs the exception check here in DSP HLE mode
GenerateDSPInterrupt(INT_ARAM); CompleteARAM(0, 0);
CoreTiming::ForceExceptionCheck(100); CoreTiming::ForceExceptionCheck(100);
} }
else else
{ {
g_dspState.DSPControl.DMAState = 1; CoreTiming::ScheduleEvent_Threadsafe(0, et_CompleteARAM);
CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16));
// Force an early exception check on large transfers. Fixes RE2 audio. // Force an early exception check on large transfers. Fixes RE2 audio.
// NFS:HP2 (<= 6144) // NFS:HP2 (<= 6144)

View File

@ -15,9 +15,9 @@ namespace DSP
enum DSPInterruptType enum DSPInterruptType
{ {
INT_DSP = 0, INT_DSP = 0x80,
INT_ARAM = 1, INT_ARAM = 0x20,
INT_AID = 2 INT_AID = 0x08,
}; };
// aram size and mask // aram size and mask
@ -65,8 +65,7 @@ DSPEmulator *GetDSPEmulator();
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true); void GenerateDSPInterruptFromDSPEmu(DSPInterruptType _DSPInterruptType);
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType _DSPInterruptType, bool _bSet = true);
// Audio/DSP Helper // Audio/DSP Helper
u8 ReadARAM(const u32 _uAddress); u8 ReadARAM(const u32 _uAddress);