Add accelerator input MMIO register, fix MMIO PCM modes

This commit is contained in:
xperia64 2022-06-19 16:51:29 -04:00 committed by Tillmann Karras
parent 0bb3de4d7b
commit ef714830b3
5 changed files with 38 additions and 19 deletions

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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:
{

View file

@ -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,},