mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-20 03:24:59 +00:00
Add accelerator input MMIO register, fix MMIO PCM modes
This commit is contained in:
parent
0bb3de4d7b
commit
ef714830b3
5 changed files with 38 additions and 19 deletions
|
@ -118,16 +118,6 @@ u16 Accelerator::ReadSample(const s16* coefs)
|
|||
if (m_reads_stopped)
|
||||
return 0x0000;
|
||||
|
||||
if (m_sample_format.raw_only)
|
||||
{
|
||||
// Seems to return garbage on hardware
|
||||
ERROR_LOG_FMT(
|
||||
DSPLLE,
|
||||
"dsp_read_accelerator_sample() tried sample read with raw only bit set for format {:#x}",
|
||||
m_sample_format.hex);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
if (m_sample_format.unk != 0)
|
||||
{
|
||||
WARN_LOG_FMT(DSPLLE, "dsp_read_accelerator_sample() format {:#x} has unknown upper bits set",
|
||||
|
@ -136,8 +126,18 @@ u16 Accelerator::ReadSample(const s16* coefs)
|
|||
|
||||
u16 val = 0;
|
||||
u8 step_size = 0;
|
||||
s16 raw_sample;
|
||||
if (m_sample_format.decode == FormatDecode::MMIOPCMHalt ||
|
||||
m_sample_format.decode == FormatDecode::MMIOPCMInc)
|
||||
{
|
||||
// The addresses can be complete nonsense in either of these modes
|
||||
raw_sample = m_input;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw_sample = GetCurrentSample();
|
||||
}
|
||||
|
||||
s16 raw_sample = GetCurrentSample();
|
||||
int coef_idx = (m_pred_scale >> 4) & 0x7;
|
||||
|
||||
s32 coef1 = coefs[coef_idx * 2 + 0];
|
||||
|
@ -184,7 +184,9 @@ u16 Accelerator::ReadSample(const s16* coefs)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case FormatDecode::MMIOPCMHalt:
|
||||
case FormatDecode::PCM: // 16-bit PCM audio
|
||||
case FormatDecode::MMIOPCMInc:
|
||||
{
|
||||
// Gain seems to only apply for PCM decoding
|
||||
u8 gain_shift = 0;
|
||||
|
@ -210,7 +212,10 @@ u16 Accelerator::ReadSample(const s16* coefs)
|
|||
m_yn2 = m_yn1;
|
||||
m_yn1 = val;
|
||||
step_size = 2;
|
||||
m_current_address += 1;
|
||||
if (m_sample_format.decode != FormatDecode::MMIOPCMHalt)
|
||||
{
|
||||
m_current_address += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -286,4 +291,10 @@ void Accelerator::SetPredScale(u16 pred_scale)
|
|||
{
|
||||
m_pred_scale = pred_scale & 0x7f;
|
||||
}
|
||||
|
||||
void Accelerator::SetInput(u16 input)
|
||||
{
|
||||
m_input = input;
|
||||
}
|
||||
|
||||
} // namespace DSP
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
s16 GetYn1() const { return m_yn1; }
|
||||
s16 GetYn2() const { return m_yn2; }
|
||||
u16 GetPredScale() const { return m_pred_scale; }
|
||||
u16 GetInput() const { return m_input; }
|
||||
void SetStartAddress(u32 address);
|
||||
void SetEndAddress(u32 address);
|
||||
void SetCurrentAddress(u32 address);
|
||||
|
@ -36,6 +37,7 @@ public:
|
|||
void SetYn1(s16 yn1);
|
||||
void SetYn2(s16 yn2);
|
||||
void SetPredScale(u16 pred_scale);
|
||||
void SetInput(u16 input);
|
||||
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
|
@ -62,8 +64,10 @@ protected:
|
|||
|
||||
enum class FormatDecode : u16
|
||||
{
|
||||
ADPCM = 0,
|
||||
PCM = 1,
|
||||
ADPCM = 0, // ADPCM reads from ARAM, ACCA increments
|
||||
MMIOPCMHalt = 1, // PCM Reads from ACIN, ACCA doesn't increment
|
||||
PCM = 2, // PCM reads from ARAM, ACCA increments
|
||||
MMIOPCMInc = 3 // PCM reads from ACIN, ACCA increments
|
||||
};
|
||||
|
||||
// When reading samples (at least in PCM mode), they are multiplied by the gain, then shifted
|
||||
|
@ -80,9 +84,7 @@ protected:
|
|||
{
|
||||
u16 hex;
|
||||
BitField<0, 2, FormatSize> size;
|
||||
BitField<2, 1, bool, u16>
|
||||
raw_only; // When this bit is set, sample reads seem broken, while raw accesses work
|
||||
BitField<3, 1, FormatDecode> decode;
|
||||
BitField<2, 2, FormatDecode> decode;
|
||||
BitField<4, 2, FormatGainCfg> gain_cfg;
|
||||
BitField<6, 10, u16> unk;
|
||||
} m_sample_format{0};
|
||||
|
@ -91,6 +93,7 @@ protected:
|
|||
s16 m_yn1 = 0;
|
||||
s16 m_yn2 = 0;
|
||||
u16 m_pred_scale = 0;
|
||||
u16 m_input = 0;
|
||||
|
||||
// When an ACCOV is triggered, the accelerator stops reading back anything
|
||||
// and updating the current address register, unless the YN2 register is written to.
|
||||
|
|
|
@ -166,7 +166,7 @@ enum : u32
|
|||
DSP_YN2 = 0xdc,
|
||||
DSP_ACDSAMP = 0xdd, // Accelerator sample reads, processed differently depending on FORMAT
|
||||
DSP_GAIN = 0xde,
|
||||
DSP_ACUNK2 = 0xdf, // Set to 0xc on my dumps
|
||||
DSP_ACIN = 0xdf, // Feeds PCM samples written here
|
||||
|
||||
DSP_AMDM = 0xef, // ARAM DMA Request Mask 0: DMA with ARAM unmasked 1: masked
|
||||
|
||||
|
|
|
@ -170,6 +170,9 @@ void SDSP::WriteIFX(u32 address, u16 value)
|
|||
case DSP_ACDRAW: // Raw accelerator write
|
||||
m_accelerator->WriteRaw(value);
|
||||
break;
|
||||
case DSP_ACIN:
|
||||
m_accelerator->SetInput(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((address & 0xff) >= 0xa0)
|
||||
|
@ -240,6 +243,8 @@ u16 SDSP::ReadIFXImpl(u16 address)
|
|||
return m_accelerator->ReadSample(reinterpret_cast<s16*>(&m_ifx_regs[DSP_COEF_A1_0]));
|
||||
case DSP_ACDRAW: // Raw accelerator read
|
||||
return m_accelerator->ReadRaw();
|
||||
case DSP_ACIN:
|
||||
return m_accelerator->GetInput();
|
||||
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -414,7 +414,7 @@ const std::array<pdlabel_t, 96> pdlabels =
|
|||
{0xffdc, "yn2", "yn2",},
|
||||
{0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",},
|
||||
{0xffde, "GAIN", "Gain",},
|
||||
{0xffdf, "0xffdf", nullptr,},
|
||||
{0xffdf, "ACIN", "Accelerator MMIO PCM input value",},
|
||||
|
||||
{0xffe0, "0xffe0",nullptr,},
|
||||
{0xffe1, "0xffe1",nullptr,},
|
||||
|
|
Loading…
Add table
Reference in a new issue