DSP: Fix missing masking for accelerator registers
Based on hardware tests, masking occurs for the accelerator registers. This fixes Red Steel and Far Cry Vengeance, which rely on this behavior when reading back the current playback position from the DSP.
This commit is contained in:
parent
9e0df284aa
commit
3475ba8918
|
@ -9,6 +9,7 @@
|
|||
#include "Common/MathUtil.h"
|
||||
|
||||
#include "Core/DSP/DSPCore.h"
|
||||
#include "Core/DSP/DSPHWInterface.h"
|
||||
#include "Core/DSP/DSPHost.h"
|
||||
|
||||
namespace DSP
|
||||
|
@ -177,8 +178,8 @@ u16 dsp_read_accelerator()
|
|||
DSPCore_SetException(EXP_ACCOV);
|
||||
}
|
||||
|
||||
g_dsp.ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||
g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff;
|
||||
gdsp_ifx_write(DSP_ACCAH, Address >> 16);
|
||||
gdsp_ifx_write(DSP_ACCAL, Address & 0xffff);
|
||||
return val;
|
||||
}
|
||||
} // namespace DSP
|
||||
|
|
|
@ -156,6 +156,18 @@ void gdsp_ifx_write(u32 addr, u32 val)
|
|||
dsp_step_accelerator();
|
||||
break;
|
||||
*/
|
||||
|
||||
// Masking occurs for the start and end addresses as soon as the registers are written to.
|
||||
case DSP_ACSAH:
|
||||
case DSP_ACEAH:
|
||||
g_dsp.ifx_regs[addr & 0xff] = val & 0x3fff;
|
||||
break;
|
||||
|
||||
// This also happens for the current address, but with a different mask.
|
||||
case DSP_ACCAH:
|
||||
g_dsp.ifx_regs[addr & 0xff] = val & 0xbfff;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((addr & 0xff) >= 0xa0)
|
||||
{
|
||||
|
|
|
@ -171,9 +171,12 @@ static bool acc_end_reached;
|
|||
void AcceleratorSetup(PB_TYPE* pb, u32* cur_addr)
|
||||
{
|
||||
acc_pb = pb;
|
||||
acc_loop_addr = HILO_TO_32(pb->audio_addr.loop_addr);
|
||||
acc_end_addr = HILO_TO_32(pb->audio_addr.end_addr);
|
||||
// Masking occurs for the start and end addresses as soon as the registers are written to.
|
||||
acc_loop_addr = HILO_TO_32(pb->audio_addr.loop_addr) & 0x3fffffff;
|
||||
acc_end_addr = HILO_TO_32(pb->audio_addr.end_addr) & 0x3fffffff;
|
||||
acc_cur_addr = cur_addr;
|
||||
// It also happens for the current address, but with a different mask.
|
||||
*acc_cur_addr &= 0xbfffffff;
|
||||
acc_end_reached = false;
|
||||
}
|
||||
|
||||
|
@ -456,8 +459,8 @@ void GetInputSamples(PB_TYPE& pb, s16* samples, u16 count, const s16* coeffs)
|
|||
pb.src.cur_addr_frac = (curr_pos & 0xFFFF);
|
||||
|
||||
// Update current position in the PB.
|
||||
pb.audio_addr.cur_addr_hi = (u16)(cur_addr >> 16);
|
||||
pb.audio_addr.cur_addr_lo = (u16)(cur_addr & 0xFFFF);
|
||||
pb.audio_addr.cur_addr_hi = static_cast<u16>(cur_addr >> 16) & 0xbfff;
|
||||
pb.audio_addr.cur_addr_lo = static_cast<u16>(cur_addr);
|
||||
}
|
||||
|
||||
// Add samples to an output buffer, with optional volume ramping.
|
||||
|
|
Loading…
Reference in New Issue