From d517fe25f1b64891beacf2e5be7d8cd5b7759925 Mon Sep 17 00:00:00 2001 From: xperia64 Date: Sun, 19 Jun 2022 16:51:29 -0400 Subject: [PATCH] Add accelerator input MMIO register, fix MMIO PCM modes --- Source/Core/Core/DSP/DSPAccelerator.cpp | 35 ++++++++++++++++--------- Source/Core/Core/DSP/DSPAccelerator.h | 13 +++++---- Source/Core/Core/DSP/DSPCore.h | 2 +- Source/Core/Core/DSP/DSPHWInterface.cpp | 5 ++++ Source/Core/Core/DSP/DSPTables.cpp | 2 +- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Source/Core/Core/DSP/DSPAccelerator.cpp b/Source/Core/Core/DSP/DSPAccelerator.cpp index 16be268bf6..5553a5a7b0 100644 --- a/Source/Core/Core/DSP/DSPAccelerator.cpp +++ b/Source/Core/Core/DSP/DSPAccelerator.cpp @@ -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 diff --git a/Source/Core/Core/DSP/DSPAccelerator.h b/Source/Core/Core/DSP/DSPAccelerator.h index c0411fe94a..54fc88baaa 100644 --- a/Source/Core/Core/DSP/DSPAccelerator.h +++ b/Source/Core/Core/DSP/DSPAccelerator.h @@ -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. diff --git a/Source/Core/Core/DSP/DSPCore.h b/Source/Core/Core/DSP/DSPCore.h index b8fa5683c4..c0a5c0dba7 100644 --- a/Source/Core/Core/DSP/DSPCore.h +++ b/Source/Core/Core/DSP/DSPCore.h @@ -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 diff --git a/Source/Core/Core/DSP/DSPHWInterface.cpp b/Source/Core/Core/DSP/DSPHWInterface.cpp index a812f181b1..8e1170f5cd 100644 --- a/Source/Core/Core/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/DSP/DSPHWInterface.cpp @@ -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(&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: { diff --git a/Source/Core/Core/DSP/DSPTables.cpp b/Source/Core/Core/DSP/DSPTables.cpp index 21502fe0c8..e691c90957 100644 --- a/Source/Core/Core/DSP/DSPTables.cpp +++ b/Source/Core/Core/DSP/DSPTables.cpp @@ -414,7 +414,7 @@ const std::array 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,},