Merge pull request #12485 from AdmiralCurtiss/globals-dsp
Core/DSPHLE: Clean up global System access.
This commit is contained in:
commit
63453bda4d
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
DSPEmulator::~DSPEmulator() = default;
|
DSPEmulator::~DSPEmulator() = default;
|
||||||
|
|
||||||
std::unique_ptr<DSPEmulator> CreateDSPEmulator(bool hle)
|
std::unique_ptr<DSPEmulator> CreateDSPEmulator(Core::System& system, bool hle)
|
||||||
{
|
{
|
||||||
if (hle)
|
if (hle)
|
||||||
return std::make_unique<DSP::HLE::DSPHLE>();
|
return std::make_unique<DSP::HLE::DSPHLE>(system);
|
||||||
|
|
||||||
return std::make_unique<DSP::LLE::DSPLLE>();
|
return std::make_unique<DSP::LLE::DSPLLE>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
class DSPEmulator
|
class DSPEmulator
|
||||||
|
@ -34,4 +38,4 @@ protected:
|
||||||
bool m_wii = false;
|
bool m_wii = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<DSPEmulator> CreateDSPEmulator(bool hle);
|
std::unique_ptr<DSPEmulator> CreateDSPEmulator(Core::System& system, bool hle);
|
||||||
|
|
|
@ -119,7 +119,7 @@ void DSPManager::Init(bool hle)
|
||||||
|
|
||||||
void DSPManager::Reinit(bool hle)
|
void DSPManager::Reinit(bool hle)
|
||||||
{
|
{
|
||||||
m_dsp_emulator = CreateDSPEmulator(hle);
|
m_dsp_emulator = CreateDSPEmulator(m_system, hle);
|
||||||
m_is_lle = m_dsp_emulator->IsLLE();
|
m_is_lle = m_dsp_emulator->IsLLE();
|
||||||
|
|
||||||
if (SConfig::GetInstance().bWii)
|
if (SConfig::GetInstance().bWii)
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
DSPHLE::DSPHLE() = default;
|
DSPHLE::DSPHLE(Core::System& system) : m_mail_handler(system.GetDSP()), m_system(system)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DSPHLE::~DSPHLE() = default;
|
DSPHLE::~DSPHLE() = default;
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ u32 DSPHLE::DSP_UpdateRate()
|
||||||
{
|
{
|
||||||
// AX HLE uses 3ms (Wii) or 5ms (GC) timing period
|
// AX HLE uses 3ms (Wii) or 5ms (GC) timing period
|
||||||
// But to be sure, just update the HLE every ms.
|
// But to be sure, just update the HLE every ms.
|
||||||
return Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond() / 1000;
|
return m_system.GetSystemTimers().GetTicksPerSecond() / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPHLE::SendMailToDSP(u32 mail)
|
void DSPHLE::SendMailToDSP(u32 mail)
|
||||||
|
@ -221,8 +223,7 @@ u16 DSPHLE::DSP_WriteControlRegister(u16 value)
|
||||||
SetUCode(UCODE_INIT_AUDIO_SYSTEM);
|
SetUCode(UCODE_INIT_AUDIO_SYSTEM);
|
||||||
temp.DSPInitCode = 1;
|
temp.DSPInitCode = 1;
|
||||||
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
||||||
m_control_reg_init_code_clear_time =
|
m_control_reg_init_code_clear_time = m_system.GetSystemTimers().GetFakeTimeBase() + 130;
|
||||||
Core::System::GetInstance().GetSystemTimers().GetFakeTimeBase() + 130;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dsp_control.Hex = temp.Hex;
|
m_dsp_control.Hex = temp.Hex;
|
||||||
|
@ -233,11 +234,10 @@ u16 DSPHLE::DSP_ReadControlRegister()
|
||||||
{
|
{
|
||||||
if (m_dsp_control.DSPInitCode != 0)
|
if (m_dsp_control.DSPInitCode != 0)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
if (m_system.GetSystemTimers().GetFakeTimeBase() >= m_control_reg_init_code_clear_time)
|
||||||
if (system.GetSystemTimers().GetFakeTimeBase() >= m_control_reg_init_code_clear_time)
|
|
||||||
m_dsp_control.DSPInitCode = 0;
|
m_dsp_control.DSPInitCode = 0;
|
||||||
else
|
else
|
||||||
system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
m_system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||||
}
|
}
|
||||||
return m_dsp_control.Hex;
|
return m_dsp_control.Hex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include "Core/HW/DSP.h"
|
#include "Core/HW/DSP.h"
|
||||||
#include "Core/HW/DSPHLE/MailHandler.h"
|
#include "Core/HW/DSPHLE/MailHandler.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
|
@ -19,7 +23,11 @@ class UCodeInterface;
|
||||||
class DSPHLE : public DSPEmulator
|
class DSPHLE : public DSPEmulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSPHLE();
|
explicit DSPHLE(Core::System& system);
|
||||||
|
DSPHLE(const DSPHLE& other) = delete;
|
||||||
|
DSPHLE(DSPHLE&& other) = delete;
|
||||||
|
DSPHLE& operator=(const DSPHLE& other) = delete;
|
||||||
|
DSPHLE& operator=(DSPHLE&& other) = delete;
|
||||||
~DSPHLE();
|
~DSPHLE();
|
||||||
|
|
||||||
bool Initialize(bool wii, bool dsp_thread) override;
|
bool Initialize(bool wii, bool dsp_thread) override;
|
||||||
|
@ -42,6 +50,8 @@ public:
|
||||||
void SetUCode(u32 crc);
|
void SetUCode(u32 crc);
|
||||||
void SwapUCode(u32 crc);
|
void SwapUCode(u32 crc);
|
||||||
|
|
||||||
|
Core::System& GetSystem() const { return m_system; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SendMailToDSP(u32 mail);
|
void SendMailToDSP(u32 mail);
|
||||||
|
|
||||||
|
@ -67,5 +77,7 @@ private:
|
||||||
DSP::UDSPControl m_dsp_control;
|
DSP::UDSPControl m_dsp_control;
|
||||||
u64 m_control_reg_init_code_clear_time = 0;
|
u64 m_control_reg_init_code_clear_time = 0;
|
||||||
CMailHandler m_mail_handler;
|
CMailHandler m_mail_handler;
|
||||||
|
|
||||||
|
Core::System& m_system;
|
||||||
};
|
};
|
||||||
} // namespace DSP::HLE
|
} // namespace DSP::HLE
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Core/HW/DSP.h"
|
#include "Core/HW/DSP.h"
|
||||||
#include "Core/System.h"
|
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
CMailHandler::CMailHandler()
|
CMailHandler::CMailHandler(DSP::DSPManager& dsp) : m_dsp(dsp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +25,7 @@ void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future)
|
||||||
{
|
{
|
||||||
if (m_pending_mails.empty())
|
if (m_pending_mails.empty())
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP,
|
m_dsp.GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP, cycles_into_future);
|
||||||
cycles_into_future);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -60,7 +58,7 @@ u16 CMailHandler::ReadDSPMailboxLow()
|
||||||
|
|
||||||
if (generate_interrupt)
|
if (generate_interrupt)
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsp.GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear the top bit of the high mail word after the mail has been read.
|
// Clear the top bit of the high mail word after the mail has been read.
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace DSP
|
||||||
|
{
|
||||||
|
class DSPManager;
|
||||||
|
}
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
|
@ -15,7 +19,11 @@ namespace DSP::HLE
|
||||||
class CMailHandler
|
class CMailHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMailHandler();
|
explicit CMailHandler(DSP::DSPManager& dsp);
|
||||||
|
CMailHandler(const CMailHandler& other) = delete;
|
||||||
|
CMailHandler(CMailHandler&& other) = delete;
|
||||||
|
CMailHandler& operator=(const CMailHandler& other) = delete;
|
||||||
|
CMailHandler& operator=(CMailHandler&& other) = delete;
|
||||||
~CMailHandler();
|
~CMailHandler();
|
||||||
|
|
||||||
// TODO: figure out correct timing for interrupts rather than defaulting to "immediately."
|
// TODO: figure out correct timing for interrupts rather than defaulting to "immediately."
|
||||||
|
@ -44,5 +52,7 @@ private:
|
||||||
u32 m_last_mail = 0;
|
u32 m_last_mail = 0;
|
||||||
// When halted, the DSP itself is not running, but the last mail can be read.
|
// When halted, the DSP itself is not running, but the last mail can be read.
|
||||||
bool m_halted = false;
|
bool m_halted = false;
|
||||||
|
|
||||||
|
DSP::DSPManager& m_dsp;
|
||||||
};
|
};
|
||||||
} // namespace DSP::HLE
|
} // namespace DSP::HLE
|
||||||
|
|
|
@ -81,7 +81,8 @@ bool AESndUCode::UseNewFlagMasks() const
|
||||||
m_crc == HASH_2022_PAD || m_crc == HASH_2023;
|
m_crc == HASH_2022_PAD || m_crc == HASH_2023;
|
||||||
}
|
}
|
||||||
|
|
||||||
AESndUCode::AESndUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc)
|
AESndUCode::AESndUCode(DSPHLE* dsphle, u32 crc)
|
||||||
|
: UCodeInterface(dsphle, crc), m_accelerator(dsphle->GetSystem().GetDSP())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ void AESndUCode::Update()
|
||||||
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
|
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
|
||||||
if (m_mail_handler.HasPending())
|
if (m_mail_handler.HasPending())
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsphle->GetSystem().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,14 +155,18 @@ void AESndUCode::HandleMail(u32 mail)
|
||||||
// No mail is sent in response
|
// No mail is sent in response
|
||||||
break;
|
break;
|
||||||
case MAIL_SEND_SAMPLES:
|
case MAIL_SEND_SAMPLES:
|
||||||
|
{
|
||||||
DEBUG_LOG_FMT(DSPHLE, "AESndUCode - MAIL_SEND_SAMPLES");
|
DEBUG_LOG_FMT(DSPHLE, "AESndUCode - MAIL_SEND_SAMPLES");
|
||||||
// send_samples
|
// send_samples
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U16(m_parameter_block.out_buf + i * sizeof(u16), m_output_buffer[i]);
|
HLEMemory_Write_U16(memory, m_parameter_block.out_buf + i * sizeof(u16),
|
||||||
|
m_output_buffer[i]);
|
||||||
}
|
}
|
||||||
m_mail_handler.PushMail(DSP_SYNC, true);
|
m_mail_handler.PushMail(DSP_SYNC, true);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MAIL_TERMINATE:
|
case MAIL_TERMINATE:
|
||||||
INFO_LOG_FMT(DSPHLE, "AESndUCode - MAIL_TERMINATE: {:08x}", mail);
|
INFO_LOG_FMT(DSPHLE, "AESndUCode - MAIL_TERMINATE: {:08x}", mail);
|
||||||
if (m_crc != HASH_2022_PAD && m_crc != HASH_2023)
|
if (m_crc != HASH_2022_PAD && m_crc != HASH_2023)
|
||||||
|
@ -197,42 +202,50 @@ void AESndUCode::HandleMail(u32 mail)
|
||||||
|
|
||||||
void AESndUCode::DMAInParameterBlock()
|
void AESndUCode::DMAInParameterBlock()
|
||||||
{
|
{
|
||||||
m_parameter_block.out_buf = HLEMemory_Read_U32(m_parameter_block_addr + 0);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
m_parameter_block.buf_start = HLEMemory_Read_U32(m_parameter_block_addr + 4);
|
m_parameter_block.out_buf = HLEMemory_Read_U32(memory, m_parameter_block_addr + 0);
|
||||||
m_parameter_block.buf_end = HLEMemory_Read_U32(m_parameter_block_addr + 8);
|
m_parameter_block.buf_start = HLEMemory_Read_U32(memory, m_parameter_block_addr + 4);
|
||||||
m_parameter_block.buf_curr = HLEMemory_Read_U32(m_parameter_block_addr + 12);
|
m_parameter_block.buf_end = HLEMemory_Read_U32(memory, m_parameter_block_addr + 8);
|
||||||
m_parameter_block.yn1 = HLEMemory_Read_U16(m_parameter_block_addr + 16);
|
m_parameter_block.buf_curr = HLEMemory_Read_U32(memory, m_parameter_block_addr + 12);
|
||||||
m_parameter_block.yn2 = HLEMemory_Read_U16(m_parameter_block_addr + 18);
|
m_parameter_block.yn1 = HLEMemory_Read_U16(memory, m_parameter_block_addr + 16);
|
||||||
m_parameter_block.pds = HLEMemory_Read_U16(m_parameter_block_addr + 20);
|
m_parameter_block.yn2 = HLEMemory_Read_U16(memory, m_parameter_block_addr + 18);
|
||||||
m_parameter_block.freq = HLEMemory_Read_U32(m_parameter_block_addr + 22);
|
m_parameter_block.pds = HLEMemory_Read_U16(memory, m_parameter_block_addr + 20);
|
||||||
m_parameter_block.counter = HLEMemory_Read_U16(m_parameter_block_addr + 26);
|
m_parameter_block.freq = HLEMemory_Read_U32(memory, m_parameter_block_addr + 22);
|
||||||
m_parameter_block.left = HLEMemory_Read_U16(m_parameter_block_addr + 28);
|
m_parameter_block.counter = HLEMemory_Read_U16(memory, m_parameter_block_addr + 26);
|
||||||
m_parameter_block.right = HLEMemory_Read_U16(m_parameter_block_addr + 30);
|
m_parameter_block.left = HLEMemory_Read_U16(memory, m_parameter_block_addr + 28);
|
||||||
m_parameter_block.volume_l = HLEMemory_Read_U16(m_parameter_block_addr + 32);
|
m_parameter_block.right = HLEMemory_Read_U16(memory, m_parameter_block_addr + 30);
|
||||||
m_parameter_block.volume_r = HLEMemory_Read_U16(m_parameter_block_addr + 34);
|
m_parameter_block.volume_l = HLEMemory_Read_U16(memory, m_parameter_block_addr + 32);
|
||||||
m_parameter_block.delay = HLEMemory_Read_U32(m_parameter_block_addr + 36);
|
m_parameter_block.volume_r = HLEMemory_Read_U16(memory, m_parameter_block_addr + 34);
|
||||||
m_parameter_block.flags = HLEMemory_Read_U32(m_parameter_block_addr + 40);
|
m_parameter_block.delay = HLEMemory_Read_U32(memory, m_parameter_block_addr + 36);
|
||||||
|
m_parameter_block.flags = HLEMemory_Read_U32(memory, m_parameter_block_addr + 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AESndUCode::DMAOutParameterBlock()
|
void AESndUCode::DMAOutParameterBlock()
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 0, m_parameter_block.out_buf);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 4, m_parameter_block.buf_start);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 0, m_parameter_block.out_buf);
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 8, m_parameter_block.buf_end);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 4, m_parameter_block.buf_start);
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 12, m_parameter_block.buf_curr);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 8, m_parameter_block.buf_end);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 16, m_parameter_block.yn1);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 12, m_parameter_block.buf_curr);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 18, m_parameter_block.yn2);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 16, m_parameter_block.yn1);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 20, m_parameter_block.pds);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 18, m_parameter_block.yn2);
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 22, m_parameter_block.freq);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 20, m_parameter_block.pds);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 26, m_parameter_block.counter);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 22, m_parameter_block.freq);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 28, m_parameter_block.left);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 26, m_parameter_block.counter);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 30, m_parameter_block.right);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 28, m_parameter_block.left);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 32, m_parameter_block.volume_l);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 30, m_parameter_block.right);
|
||||||
HLEMemory_Write_U16(m_parameter_block_addr + 34, m_parameter_block.volume_r);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 32, m_parameter_block.volume_l);
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 36, m_parameter_block.delay);
|
HLEMemory_Write_U16(memory, m_parameter_block_addr + 34, m_parameter_block.volume_r);
|
||||||
HLEMemory_Write_U32(m_parameter_block_addr + 40, m_parameter_block.flags);
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 36, m_parameter_block.delay);
|
||||||
|
HLEMemory_Write_U32(memory, m_parameter_block_addr + 40, m_parameter_block.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AESndAccelerator::AESndAccelerator(DSP::DSPManager& dsp) : m_dsp(dsp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AESndAccelerator::~AESndAccelerator() = default;
|
||||||
|
|
||||||
void AESndAccelerator::OnEndException()
|
void AESndAccelerator::OnEndException()
|
||||||
{
|
{
|
||||||
// exception5 - this updates internal state
|
// exception5 - this updates internal state
|
||||||
|
@ -243,12 +256,12 @@ void AESndAccelerator::OnEndException()
|
||||||
|
|
||||||
u8 AESndAccelerator::ReadMemory(u32 address)
|
u8 AESndAccelerator::ReadMemory(u32 address)
|
||||||
{
|
{
|
||||||
return Core::System::GetInstance().GetDSP().ReadARAM(address);
|
return m_dsp.ReadARAM(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AESndAccelerator::WriteMemory(u32 address, u8 value)
|
void AESndAccelerator::WriteMemory(u32 address, u8 value)
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().WriteARAM(value, address);
|
m_dsp.WriteARAM(value, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::array<s16, 16> ACCELERATOR_COEFS = {}; // all zeros
|
static constexpr std::array<s16, 16> ACCELERATOR_COEFS = {}; // all zeros
|
||||||
|
|
|
@ -10,16 +10,32 @@
|
||||||
#include "Core/DSP/DSPAccelerator.h"
|
#include "Core/DSP/DSPAccelerator.h"
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
|
|
||||||
|
namespace DSP
|
||||||
|
{
|
||||||
|
class DSPManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
class DSPHLE;
|
class DSPHLE;
|
||||||
|
|
||||||
class AESndAccelerator final : public Accelerator
|
class AESndAccelerator final : public Accelerator
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
explicit AESndAccelerator(DSP::DSPManager& dsp);
|
||||||
|
AESndAccelerator(const AESndAccelerator&) = delete;
|
||||||
|
AESndAccelerator(AESndAccelerator&&) = delete;
|
||||||
|
AESndAccelerator& operator=(const AESndAccelerator&) = delete;
|
||||||
|
AESndAccelerator& operator=(AESndAccelerator&&) = delete;
|
||||||
|
~AESndAccelerator();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnEndException() override;
|
void OnEndException() override;
|
||||||
u8 ReadMemory(u32 address) override;
|
u8 ReadMemory(u32 address) override;
|
||||||
void WriteMemory(u32 address, u8 value) override;
|
void WriteMemory(u32 address, u8 value) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DSP::DSPManager& m_dsp;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AESndUCode final : public UCodeInterface
|
class AESndUCode final : public UCodeInterface
|
||||||
|
|
|
@ -80,7 +80,7 @@ void ASndUCode::Update()
|
||||||
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
|
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
|
||||||
if (m_mail_handler.HasPending())
|
if (m_mail_handler.HasPending())
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsphle->GetSystem().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,17 +128,20 @@ void ASndUCode::HandleMail(u32 mail)
|
||||||
// Mail is handled by DoMixing()
|
// Mail is handled by DoMixing()
|
||||||
break;
|
break;
|
||||||
case MAIL_INPUT_SAMPLES_2:
|
case MAIL_INPUT_SAMPLES_2:
|
||||||
|
{
|
||||||
WARN_LOG_FMT(DSPHLE, "ASndUCode - MAIL_INPUT_SAMPLES_2: {:08x} - not normally used", mail);
|
WARN_LOG_FMT(DSPHLE, "ASndUCode - MAIL_INPUT_SAMPLES_2: {:08x} - not normally used", mail);
|
||||||
// input_samples2
|
// input_samples2
|
||||||
DMAInVoiceData(); // first do_dma call
|
DMAInVoiceData(); // first do_dma call
|
||||||
// second do_dma call
|
// second do_dma call
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
||||||
{
|
{
|
||||||
m_output_buffer[i] = HLEMemory_Read_U16(m_current_voice.out_buf + i * sizeof(u16));
|
m_output_buffer[i] = HLEMemory_Read_U16(memory, m_current_voice.out_buf + i * sizeof(u16));
|
||||||
}
|
}
|
||||||
DoMixing(DSP_SYNC);
|
DoMixing(DSP_SYNC);
|
||||||
// Mail is handled by DoMixing()
|
// Mail is handled by DoMixing()
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MAIL_SET_VOICE_DATA_BUFFER:
|
case MAIL_SET_VOICE_DATA_BUFFER:
|
||||||
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - MAIL_SET_VOICE_DATA_BUFFER: {:08x}", mail);
|
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - MAIL_SET_VOICE_DATA_BUFFER: {:08x}", mail);
|
||||||
m_next_mail_is_voice_addr = true;
|
m_next_mail_is_voice_addr = true;
|
||||||
|
@ -153,13 +156,16 @@ void ASndUCode::HandleMail(u32 mail)
|
||||||
// Mail is handled by DoMixing()
|
// Mail is handled by DoMixing()
|
||||||
break;
|
break;
|
||||||
case MAIN_SEND_SAMPLES:
|
case MAIN_SEND_SAMPLES:
|
||||||
|
{
|
||||||
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - MAIN_SEND_SAMPLES: {:08x}", mail);
|
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - MAIN_SEND_SAMPLES: {:08x}", mail);
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U16(m_current_voice.out_buf + i * sizeof(u16), m_output_buffer[i]);
|
HLEMemory_Write_U16(memory, m_current_voice.out_buf + i * sizeof(u16), m_output_buffer[i]);
|
||||||
}
|
}
|
||||||
m_mail_handler.PushMail(DSP_SYNC, true);
|
m_mail_handler.PushMail(DSP_SYNC, true);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MAIL_ROM_DUMP_WORD:
|
case MAIL_ROM_DUMP_WORD:
|
||||||
WARN_LOG_FMT(DSPHLE, "ASndUCode - MAIL_ROM_DUMP_WORD: {:08x} - not normally used", mail);
|
WARN_LOG_FMT(DSPHLE, "ASndUCode - MAIL_ROM_DUMP_WORD: {:08x} - not normally used", mail);
|
||||||
// Reads instruction at 0x8000 | (mail >> 16), and sends it back in DMBL. DMBH is 0.
|
// Reads instruction at 0x8000 | (mail >> 16), and sends it back in DMBL. DMBH is 0.
|
||||||
|
@ -196,51 +202,53 @@ void ASndUCode::HandleMail(u32 mail)
|
||||||
|
|
||||||
void ASndUCode::DMAInVoiceData()
|
void ASndUCode::DMAInVoiceData()
|
||||||
{
|
{
|
||||||
m_current_voice.out_buf = HLEMemory_Read_U32(m_voice_addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
m_current_voice.delay_samples = HLEMemory_Read_U32(m_voice_addr + 4);
|
m_current_voice.out_buf = HLEMemory_Read_U32(memory, m_voice_addr);
|
||||||
u32 new_flags = HLEMemory_Read_U32(m_voice_addr + 8);
|
m_current_voice.delay_samples = HLEMemory_Read_U32(memory, m_voice_addr + 4);
|
||||||
|
u32 new_flags = HLEMemory_Read_U32(memory, m_voice_addr + 8);
|
||||||
if (m_current_voice.flags != new_flags)
|
if (m_current_voice.flags != new_flags)
|
||||||
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - flags: {:08x}", new_flags);
|
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - flags: {:08x}", new_flags);
|
||||||
m_current_voice.flags = new_flags;
|
m_current_voice.flags = new_flags;
|
||||||
m_current_voice.start_addr = HLEMemory_Read_U32(m_voice_addr + 12);
|
m_current_voice.start_addr = HLEMemory_Read_U32(memory, m_voice_addr + 12);
|
||||||
m_current_voice.end_addr = HLEMemory_Read_U32(m_voice_addr + 16);
|
m_current_voice.end_addr = HLEMemory_Read_U32(memory, m_voice_addr + 16);
|
||||||
m_current_voice.freq = HLEMemory_Read_U32(m_voice_addr + 20);
|
m_current_voice.freq = HLEMemory_Read_U32(memory, m_voice_addr + 20);
|
||||||
m_current_voice.left = HLEMemory_Read_U16(m_voice_addr + 24);
|
m_current_voice.left = HLEMemory_Read_U16(memory, m_voice_addr + 24);
|
||||||
m_current_voice.right = HLEMemory_Read_U16(m_voice_addr + 26);
|
m_current_voice.right = HLEMemory_Read_U16(memory, m_voice_addr + 26);
|
||||||
m_current_voice.counter = HLEMemory_Read_U32(m_voice_addr + 28);
|
m_current_voice.counter = HLEMemory_Read_U32(memory, m_voice_addr + 28);
|
||||||
m_current_voice.volume_l = HLEMemory_Read_U16(m_voice_addr + 32);
|
m_current_voice.volume_l = HLEMemory_Read_U16(memory, m_voice_addr + 32);
|
||||||
m_current_voice.volume_r = HLEMemory_Read_U16(m_voice_addr + 34);
|
m_current_voice.volume_r = HLEMemory_Read_U16(memory, m_voice_addr + 34);
|
||||||
m_current_voice.start_addr2 = HLEMemory_Read_U32(m_voice_addr + 36);
|
m_current_voice.start_addr2 = HLEMemory_Read_U32(memory, m_voice_addr + 36);
|
||||||
m_current_voice.end_addr2 = HLEMemory_Read_U32(m_voice_addr + 40);
|
m_current_voice.end_addr2 = HLEMemory_Read_U32(memory, m_voice_addr + 40);
|
||||||
m_current_voice.volume2_l = HLEMemory_Read_U16(m_voice_addr + 44);
|
m_current_voice.volume2_l = HLEMemory_Read_U16(memory, m_voice_addr + 44);
|
||||||
m_current_voice.volume2_r = HLEMemory_Read_U16(m_voice_addr + 46);
|
m_current_voice.volume2_r = HLEMemory_Read_U16(memory, m_voice_addr + 46);
|
||||||
m_current_voice.backup_addr = HLEMemory_Read_U32(m_voice_addr + 48);
|
m_current_voice.backup_addr = HLEMemory_Read_U32(memory, m_voice_addr + 48);
|
||||||
m_current_voice.tick_counter = HLEMemory_Read_U32(m_voice_addr + 52);
|
m_current_voice.tick_counter = HLEMemory_Read_U32(memory, m_voice_addr + 52);
|
||||||
m_current_voice.cb = HLEMemory_Read_U32(m_voice_addr + 56);
|
m_current_voice.cb = HLEMemory_Read_U32(memory, m_voice_addr + 56);
|
||||||
m_current_voice._pad = HLEMemory_Read_U32(m_voice_addr + 60);
|
m_current_voice._pad = HLEMemory_Read_U32(memory, m_voice_addr + 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASndUCode::DMAOutVoiceData()
|
void ASndUCode::DMAOutVoiceData()
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U32(m_voice_addr, m_current_voice.out_buf);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
HLEMemory_Write_U32(m_voice_addr + 4, m_current_voice.delay_samples);
|
HLEMemory_Write_U32(memory, m_voice_addr, m_current_voice.out_buf);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 8, m_current_voice.flags);
|
HLEMemory_Write_U32(memory, m_voice_addr + 4, m_current_voice.delay_samples);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 12, m_current_voice.start_addr);
|
HLEMemory_Write_U32(memory, m_voice_addr + 8, m_current_voice.flags);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 16, m_current_voice.end_addr);
|
HLEMemory_Write_U32(memory, m_voice_addr + 12, m_current_voice.start_addr);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 20, m_current_voice.freq);
|
HLEMemory_Write_U32(memory, m_voice_addr + 16, m_current_voice.end_addr);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 24, m_current_voice.left);
|
HLEMemory_Write_U32(memory, m_voice_addr + 20, m_current_voice.freq);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 26, m_current_voice.right);
|
HLEMemory_Write_U16(memory, m_voice_addr + 24, m_current_voice.left);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 28, m_current_voice.counter);
|
HLEMemory_Write_U16(memory, m_voice_addr + 26, m_current_voice.right);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 32, m_current_voice.volume_l);
|
HLEMemory_Write_U32(memory, m_voice_addr + 28, m_current_voice.counter);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 34, m_current_voice.volume_r);
|
HLEMemory_Write_U16(memory, m_voice_addr + 32, m_current_voice.volume_l);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 36, m_current_voice.start_addr2);
|
HLEMemory_Write_U16(memory, m_voice_addr + 34, m_current_voice.volume_r);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 40, m_current_voice.end_addr2);
|
HLEMemory_Write_U32(memory, m_voice_addr + 36, m_current_voice.start_addr2);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 44, m_current_voice.volume2_l);
|
HLEMemory_Write_U32(memory, m_voice_addr + 40, m_current_voice.end_addr2);
|
||||||
HLEMemory_Write_U16(m_voice_addr + 46, m_current_voice.volume2_r);
|
HLEMemory_Write_U16(memory, m_voice_addr + 44, m_current_voice.volume2_l);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 48, m_current_voice.backup_addr);
|
HLEMemory_Write_U16(memory, m_voice_addr + 46, m_current_voice.volume2_r);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 52, m_current_voice.tick_counter);
|
HLEMemory_Write_U32(memory, m_voice_addr + 48, m_current_voice.backup_addr);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 56, m_current_voice.cb);
|
HLEMemory_Write_U32(memory, m_voice_addr + 52, m_current_voice.tick_counter);
|
||||||
HLEMemory_Write_U32(m_voice_addr + 60, m_current_voice._pad);
|
HLEMemory_Write_U32(memory, m_voice_addr + 56, m_current_voice.cb);
|
||||||
|
HLEMemory_Write_U32(memory, m_voice_addr + 60, m_current_voice._pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASndUCode::DoMixing(u32 return_mail)
|
void ASndUCode::DoMixing(u32 return_mail)
|
||||||
|
@ -449,9 +457,10 @@ void ASndUCode::DMAInSampleData()
|
||||||
// The only difference is that this one forces the address to be aligned, while when
|
// The only difference is that this one forces the address to be aligned, while when
|
||||||
// jump_load_smp_dma is used, the address is expected to already be aligned.
|
// jump_load_smp_dma is used, the address is expected to already be aligned.
|
||||||
const u32 addr = m_current_voice.start_addr & ~INPUT_SAMPLE_BUFFER_BYTE_MASK;
|
const u32 addr = m_current_voice.start_addr & ~INPUT_SAMPLE_BUFFER_BYTE_MASK;
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
|
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
|
||||||
{
|
{
|
||||||
m_input_sample_buffer[i] = HLEMemory_Read_U16(addr + i * sizeof(u16));
|
m_input_sample_buffer[i] = HLEMemory_Read_U16(memory, addr + i * sizeof(u16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,9 +470,10 @@ void ASndUCode::DMAInSampleDataAssumeAligned()
|
||||||
// This is technically not a function, but instead is directly jumped to and then jumps to $ar3
|
// This is technically not a function, but instead is directly jumped to and then jumps to $ar3
|
||||||
// (which is set to an address from sample_selector). We can just treat it as a function though.
|
// (which is set to an address from sample_selector). We can just treat it as a function though.
|
||||||
const u32 addr = m_current_voice.start_addr;
|
const u32 addr = m_current_voice.start_addr;
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
|
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
|
||||||
{
|
{
|
||||||
m_input_sample_buffer[i] = HLEMemory_Read_U16(addr + i * sizeof(u16));
|
m_input_sample_buffer[i] = HLEMemory_Read_U16(memory, addr + i * sizeof(u16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ void AXUCode::Initialize()
|
||||||
{
|
{
|
||||||
InitializeShared();
|
InitializeShared();
|
||||||
|
|
||||||
m_accelerator = std::make_unique<HLEAccelerator>();
|
m_accelerator = std::make_unique<HLEAccelerator>(m_dsphle->GetSystem().GetDSP());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXUCode::InitializeShared()
|
void AXUCode::InitializeShared()
|
||||||
|
@ -390,9 +390,10 @@ void AXUCode::DownloadAndMixWithVolume(u32 addr, u16 vol_main, u16 vol_auxa, u16
|
||||||
int** buffers[3] = {buffers_main, buffers_auxa, buffers_auxb};
|
int** buffers[3] = {buffers_main, buffers_auxa, buffers_auxb};
|
||||||
u16 volumes[3] = {vol_main, vol_auxa, vol_auxb};
|
u16 volumes[3] = {vol_main, vol_auxa, vol_auxb};
|
||||||
|
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < 3; ++i)
|
for (u32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(addr);
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, addr);
|
||||||
u16 volume = volumes[i];
|
u16 volume = volumes[i];
|
||||||
for (u32 j = 0; j < 3; ++j)
|
for (u32 j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
|
@ -415,16 +416,17 @@ void AXUCode::ProcessPBList(u32 pb_addr)
|
||||||
|
|
||||||
AXPB pb;
|
AXPB pb;
|
||||||
|
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
while (pb_addr)
|
while (pb_addr)
|
||||||
{
|
{
|
||||||
AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround,
|
AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround,
|
||||||
m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround,
|
m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround,
|
||||||
m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}};
|
m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround}};
|
||||||
|
|
||||||
ReadPB(pb_addr, pb, m_crc);
|
ReadPB(memory, pb_addr, pb, m_crc);
|
||||||
|
|
||||||
u32 updates_addr = HILO_TO_32(pb.updates.data);
|
u32 updates_addr = HILO_TO_32(pb.updates.data);
|
||||||
u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr);
|
u16* updates = (u16*)HLEMemory_Get_Pointer(memory, updates_addr);
|
||||||
|
|
||||||
for (int curr_ms = 0; curr_ms < 5; ++curr_ms)
|
for (int curr_ms = 0; curr_ms < 5; ++curr_ms)
|
||||||
{
|
{
|
||||||
|
@ -439,7 +441,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
|
||||||
ptr += spms;
|
ptr += spms;
|
||||||
}
|
}
|
||||||
|
|
||||||
WritePB(pb_addr, pb, m_crc);
|
WritePB(memory, pb_addr, pb, m_crc);
|
||||||
pb_addr = HILO_TO_32(pb.next_pb);
|
pb_addr = HILO_TO_32(pb.next_pb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,9 +466,10 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we need to send the contents of our AUX buffers to the CPU.
|
// First, we need to send the contents of our AUX buffers to the CPU.
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
if (write_addr)
|
if (write_addr)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(write_addr);
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, write_addr);
|
||||||
for (auto& buffer : buffers)
|
for (auto& buffer : buffers)
|
||||||
for (u32 j = 0; j < 5 * 32; ++j)
|
for (u32 j = 0; j < 5 * 32; ++j)
|
||||||
*ptr++ = Common::swap32(buffer[j]);
|
*ptr++ = Common::swap32(buffer[j]);
|
||||||
|
@ -474,7 +477,7 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr)
|
||||||
|
|
||||||
// Then, we read the new temp from the CPU and add to our current
|
// Then, we read the new temp from the CPU and add to our current
|
||||||
// temp.
|
// temp.
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(read_addr);
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, read_addr);
|
||||||
for (auto& sample : m_samples_main_left)
|
for (auto& sample : m_samples_main_left)
|
||||||
sample += (int)Common::swap32(*ptr++);
|
sample += (int)Common::swap32(*ptr++);
|
||||||
for (auto& sample : m_samples_main_right)
|
for (auto& sample : m_samples_main_right)
|
||||||
|
@ -493,12 +496,13 @@ void AXUCode::UploadLRS(u32 dst_addr)
|
||||||
buffers[1][i] = Common::swap32(m_samples_main_right[i]);
|
buffers[1][i] = Common::swap32(m_samples_main_right[i]);
|
||||||
buffers[2][i] = Common::swap32(m_samples_main_surround[i]);
|
buffers[2][i] = Common::swap32(m_samples_main_surround[i]);
|
||||||
}
|
}
|
||||||
memcpy(HLEMemory_Get_Pointer(dst_addr), buffers, sizeof(buffers));
|
memcpy(HLEMemory_Get_Pointer(m_dsphle->GetSystem().GetMemory(), dst_addr), buffers,
|
||||||
|
sizeof(buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXUCode::SetMainLR(u32 src_addr)
|
void AXUCode::SetMainLR(u32 src_addr)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(src_addr);
|
int* ptr = (int*)HLEMemory_Get_Pointer(m_dsphle->GetSystem().GetMemory(), src_addr);
|
||||||
for (u32 i = 0; i < 5 * 32; ++i)
|
for (u32 i = 0; i < 5 * 32; ++i)
|
||||||
{
|
{
|
||||||
int samp = (int)Common::swap32(*ptr++);
|
int samp = (int)Common::swap32(*ptr++);
|
||||||
|
@ -545,7 +549,8 @@ void AXUCode::RunCompressor(u16 threshold, u16 release_frames, u32 table_addr, u
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply the selected ramp
|
// apply the selected ramp
|
||||||
u16* ramp = (u16*)HLEMemory_Get_Pointer(table_addr + table_offset);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
u16* ramp = (u16*)HLEMemory_Get_Pointer(memory, table_addr + table_offset);
|
||||||
for (u32 i = 0; i < 32 * millis; ++i)
|
for (u32 i = 0; i < 32 * millis; ++i)
|
||||||
{
|
{
|
||||||
u16 coef = Common::swap16(*ramp++);
|
u16 coef = Common::swap16(*ramp++);
|
||||||
|
@ -560,7 +565,8 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr)
|
||||||
|
|
||||||
for (u32 i = 0; i < 5 * 32; ++i)
|
for (u32 i = 0; i < 5 * 32; ++i)
|
||||||
surround_buffer[i] = Common::swap32(m_samples_main_surround[i]);
|
surround_buffer[i] = Common::swap32(m_samples_main_surround[i]);
|
||||||
memcpy(HLEMemory_Get_Pointer(surround_addr), surround_buffer, sizeof(surround_buffer));
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), surround_buffer, sizeof(surround_buffer));
|
||||||
|
|
||||||
// 32 samples per ms, 5 ms, 2 channels
|
// 32 samples per ms, 5 ms, 2 channels
|
||||||
short buffer[5 * 32 * 2];
|
short buffer[5 * 32 * 2];
|
||||||
|
@ -575,20 +581,21 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr)
|
||||||
buffer[2 * i + 1] = Common::swap16(left);
|
buffer[2 * i + 1] = Common::swap16(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(HLEMemory_Get_Pointer(lr_addr), buffer, sizeof(buffer));
|
memcpy(HLEMemory_Get_Pointer(memory, lr_addr), buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
|
void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
|
||||||
{
|
{
|
||||||
// Upload AUXB L/R
|
// Upload AUXB L/R
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(ul_addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, ul_addr);
|
||||||
for (auto& sample : m_samples_auxB_left)
|
for (auto& sample : m_samples_auxB_left)
|
||||||
*ptr++ = Common::swap32(sample);
|
*ptr++ = Common::swap32(sample);
|
||||||
for (auto& sample : m_samples_auxB_right)
|
for (auto& sample : m_samples_auxB_right)
|
||||||
*ptr++ = Common::swap32(sample);
|
*ptr++ = Common::swap32(sample);
|
||||||
|
|
||||||
// Mix AUXB L/R to MAIN L/R, and replace AUXB L/R
|
// Mix AUXB L/R to MAIN L/R, and replace AUXB L/R
|
||||||
ptr = (int*)HLEMemory_Get_Pointer(dl_addr);
|
ptr = (int*)HLEMemory_Get_Pointer(memory, dl_addr);
|
||||||
for (u32 i = 0; i < 5 * 32; ++i)
|
for (u32 i = 0; i < 5 * 32; ++i)
|
||||||
{
|
{
|
||||||
int samp = Common::swap32(*ptr++);
|
int samp = Common::swap32(*ptr++);
|
||||||
|
@ -605,7 +612,8 @@ void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
|
||||||
|
|
||||||
void AXUCode::SetOppositeLR(u32 src_addr)
|
void AXUCode::SetOppositeLR(u32 src_addr)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(src_addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, src_addr);
|
||||||
for (u32 i = 0; i < 5 * 32; ++i)
|
for (u32 i = 0; i < 5 * 32; ++i)
|
||||||
{
|
{
|
||||||
int inp = Common::swap32(*ptr++);
|
int inp = Common::swap32(*ptr++);
|
||||||
|
@ -626,7 +634,8 @@ void AXUCode::SendAUXAndMix(u32 auxa_lrs_up, u32 auxb_s_up, u32 main_l_dl, u32 m
|
||||||
};
|
};
|
||||||
|
|
||||||
// Upload AUXA LRS
|
// Upload AUXA LRS
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(auxa_lrs_up);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, auxa_lrs_up);
|
||||||
for (const auto& up_buffer : up_buffers)
|
for (const auto& up_buffer : up_buffers)
|
||||||
{
|
{
|
||||||
for (u32 j = 0; j < 32 * 5; ++j)
|
for (u32 j = 0; j < 32 * 5; ++j)
|
||||||
|
@ -634,7 +643,7 @@ void AXUCode::SendAUXAndMix(u32 auxa_lrs_up, u32 auxb_s_up, u32 main_l_dl, u32 m
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload AUXB S
|
// Upload AUXB S
|
||||||
ptr = (int*)HLEMemory_Get_Pointer(auxb_s_up);
|
ptr = (int*)HLEMemory_Get_Pointer(memory, auxb_s_up);
|
||||||
for (auto& sample : m_samples_auxB_surround)
|
for (auto& sample : m_samples_auxB_surround)
|
||||||
*ptr++ = Common::swap32(sample);
|
*ptr++ = Common::swap32(sample);
|
||||||
|
|
||||||
|
@ -655,7 +664,7 @@ void AXUCode::SendAUXAndMix(u32 auxa_lrs_up, u32 auxb_s_up, u32 main_l_dl, u32 m
|
||||||
// Download and mix
|
// Download and mix
|
||||||
for (size_t i = 0; i < dl_buffers.size(); ++i)
|
for (size_t i = 0; i < dl_buffers.size(); ++i)
|
||||||
{
|
{
|
||||||
const int* dl_src = (int*)HLEMemory_Get_Pointer(dl_addrs[i]);
|
const int* dl_src = (int*)HLEMemory_Get_Pointer(memory, dl_addrs[i]);
|
||||||
for (size_t j = 0; j < 32 * 5; ++j)
|
for (size_t j = 0; j < 32 * 5; ++j)
|
||||||
dl_buffers[i][j] += (int)Common::swap32(*dl_src++);
|
dl_buffers[i][j] += (int)Common::swap32(*dl_src++);
|
||||||
}
|
}
|
||||||
|
@ -743,8 +752,9 @@ void AXUCode::CopyCmdList(u32 addr, u16 size)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < size; ++i, addr += 2)
|
for (u32 i = 0; i < size; ++i, addr += 2)
|
||||||
m_cmdlist[i] = HLEMemory_Read_U16(addr);
|
m_cmdlist[i] = HLEMemory_Read_U16(memory, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXUCode::Update()
|
void AXUCode::Update()
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Swap.h"
|
#include "Common/Swap.h"
|
||||||
|
#include "Core/HW/DSPHLE/DSPHLE.h"
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
@ -154,7 +155,7 @@ protected:
|
||||||
template <int Millis, size_t BufCount>
|
template <int Millis, size_t BufCount>
|
||||||
void InitMixingBuffers(u32 init_addr, const std::array<BufferDesc, BufCount>& buffers)
|
void InitMixingBuffers(u32 init_addr, const std::array<BufferDesc, BufCount>& buffers)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_dsphle->GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
std::array<u16, 3 * BufCount> init_array;
|
std::array<u16, 3 * BufCount> init_array;
|
||||||
memory.CopyFromEmuSwapped(init_array.data(), init_addr, sizeof(init_array));
|
memory.CopyFromEmuSwapped(init_array.data(), init_addr, sizeof(init_array));
|
||||||
|
|
|
@ -100,11 +100,8 @@ bool HasLpf(u32 crc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a PB from MRAM/ARAM
|
// Read a PB from MRAM/ARAM
|
||||||
void ReadPB(u32 addr, PB_TYPE& pb, u32 crc)
|
void ReadPB(Memory::MemoryManager& memory, u32 addr, PB_TYPE& pb, u32 crc)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (HasLpf(crc))
|
if (HasLpf(crc))
|
||||||
{
|
{
|
||||||
u16* dst = (u16*)&pb;
|
u16* dst = (u16*)&pb;
|
||||||
|
@ -127,11 +124,8 @@ void ReadPB(u32 addr, PB_TYPE& pb, u32 crc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a PB back to MRAM/ARAM
|
// Write a PB back to MRAM/ARAM
|
||||||
void WritePB(u32 addr, const PB_TYPE& pb, u32 crc)
|
void WritePB(Memory::MemoryManager& memory, u32 addr, const PB_TYPE& pb, u32 crc)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (HasLpf(crc))
|
if (HasLpf(crc))
|
||||||
{
|
{
|
||||||
const u16* src = (const u16*)&pb;
|
const u16* src = (const u16*)&pb;
|
||||||
|
@ -156,6 +150,13 @@ void WritePB(u32 addr, const PB_TYPE& pb, u32 crc)
|
||||||
class HLEAccelerator final : public Accelerator
|
class HLEAccelerator final : public Accelerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit HLEAccelerator(DSP::DSPManager& dsp) : m_dsp(dsp) {}
|
||||||
|
HLEAccelerator(const HLEAccelerator&) = delete;
|
||||||
|
HLEAccelerator(HLEAccelerator&&) = delete;
|
||||||
|
HLEAccelerator& operator=(const HLEAccelerator&) = delete;
|
||||||
|
HLEAccelerator& operator=(HLEAccelerator&&) = delete;
|
||||||
|
~HLEAccelerator() = default;
|
||||||
|
|
||||||
PB_TYPE* acc_pb = nullptr;
|
PB_TYPE* acc_pb = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -188,14 +189,12 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ReadMemory(u32 address) override
|
u8 ReadMemory(u32 address) override { return m_dsp.ReadARAM(address); }
|
||||||
{
|
|
||||||
return Core::System::GetInstance().GetDSP().ReadARAM(address);
|
void WriteMemory(u32 address, u8 value) override { m_dsp.WriteARAM(value, address); }
|
||||||
}
|
|
||||||
void WriteMemory(u32 address, u8 value) override
|
private:
|
||||||
{
|
DSP::DSPManager& m_dsp;
|
||||||
Core::System::GetInstance().GetDSP().WriteARAM(value, address);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sets up the simulated accelerator.
|
// Sets up the simulated accelerator.
|
||||||
|
|
|
@ -34,7 +34,7 @@ void AXWiiUCode::Initialize()
|
||||||
{
|
{
|
||||||
InitializeShared();
|
InitializeShared();
|
||||||
|
|
||||||
m_accelerator = std::make_unique<HLEAccelerator>();
|
m_accelerator = std::make_unique<HLEAccelerator>(m_dsphle->GetSystem().GetDSP());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXWiiUCode::HandleCommandList()
|
void AXWiiUCode::HandleCommandList()
|
||||||
|
@ -271,7 +271,8 @@ void AXWiiUCode::SetupProcessing(u32 init_addr)
|
||||||
|
|
||||||
void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
|
void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(val_addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, val_addr);
|
||||||
for (int i = 0; i < 32 * 3; ++i)
|
for (int i = 0; i < 32 * 3; ++i)
|
||||||
{
|
{
|
||||||
int val = (int)Common::swap32(*ptr++);
|
int val = (int)Common::swap32(*ptr++);
|
||||||
|
@ -285,7 +286,8 @@ void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
|
||||||
|
|
||||||
void AXWiiUCode::AddSubToLR(u32 val_addr)
|
void AXWiiUCode::AddSubToLR(u32 val_addr)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(val_addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, val_addr);
|
||||||
for (int i = 0; i < 32 * 3; ++i)
|
for (int i = 0; i < 32 * 3; ++i)
|
||||||
{
|
{
|
||||||
int val = (int)Common::swap32(*ptr++);
|
int val = (int)Common::swap32(*ptr++);
|
||||||
|
@ -371,7 +373,8 @@ bool AXWiiUCode::ExtractUpdatesFields(AXPBWii& pb, u16* num_updates, u16* update
|
||||||
u16 addr_hi = pb_mem[44];
|
u16 addr_hi = pb_mem[44];
|
||||||
u16 addr_lo = pb_mem[45];
|
u16 addr_lo = pb_mem[45];
|
||||||
u32 addr = HILO_TO_32(addr);
|
u32 addr = HILO_TO_32(addr);
|
||||||
u16* ptr = (u16*)HLEMemory_Get_Pointer(addr);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
u16* ptr = (u16*)HLEMemory_Get_Pointer(memory, addr);
|
||||||
|
|
||||||
*updates_addr = addr;
|
*updates_addr = addr;
|
||||||
|
|
||||||
|
@ -423,6 +426,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
||||||
|
|
||||||
AXPBWii pb;
|
AXPBWii pb;
|
||||||
|
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
while (pb_addr)
|
while (pb_addr)
|
||||||
{
|
{
|
||||||
AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround,
|
AXBuffers buffers = {{m_samples_main_left, m_samples_main_right, m_samples_main_surround,
|
||||||
|
@ -433,7 +437,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
||||||
m_samples_aux1, m_samples_wm2, m_samples_aux2,
|
m_samples_aux1, m_samples_wm2, m_samples_aux2,
|
||||||
m_samples_wm3, m_samples_aux3}};
|
m_samples_wm3, m_samples_aux3}};
|
||||||
|
|
||||||
ReadPB(pb_addr, pb, m_crc);
|
ReadPB(memory, pb_addr, pb, m_crc);
|
||||||
|
|
||||||
u16 num_updates[3];
|
u16 num_updates[3];
|
||||||
u16 updates[1024];
|
u16 updates[1024];
|
||||||
|
@ -460,7 +464,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
||||||
m_coeffs_checksum ? m_coeffs.data() : nullptr);
|
m_coeffs_checksum ? m_coeffs.data() : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
WritePB(pb_addr, pb, m_crc);
|
WritePB(memory, pb_addr, pb, m_crc);
|
||||||
pb_addr = HILO_TO_32(pb.next_pb);
|
pb_addr = HILO_TO_32(pb.next_pb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,9 +510,10 @@ void AXWiiUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 vo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the content of AUX buffers to the CPU
|
// Send the content of AUX buffers to the CPU
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
if (write_addr)
|
if (write_addr)
|
||||||
{
|
{
|
||||||
int* ptr = (int*)HLEMemory_Get_Pointer(write_addr);
|
int* ptr = (int*)HLEMemory_Get_Pointer(memory, write_addr);
|
||||||
for (const auto& buffer : buffers)
|
for (const auto& buffer : buffers)
|
||||||
{
|
{
|
||||||
for (u32 j = 0; j < 3 * 32; ++j)
|
for (u32 j = 0; j < 3 * 32; ++j)
|
||||||
|
@ -517,7 +522,7 @@ void AXWiiUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 vo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then read the buffers from the CPU and add to our main buffers.
|
// Then read the buffers from the CPU and add to our main buffers.
|
||||||
const int* ptr = (int*)HLEMemory_Get_Pointer(read_addr);
|
const int* ptr = (int*)HLEMemory_Get_Pointer(memory, read_addr);
|
||||||
for (auto& main_buffer : main_buffers)
|
for (auto& main_buffer : main_buffers)
|
||||||
{
|
{
|
||||||
for (u32 j = 0; j < 3 * 32; ++j)
|
for (u32 j = 0; j < 3 * 32; ++j)
|
||||||
|
@ -536,7 +541,8 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
|
||||||
int* aux_surround = aux_id ? m_samples_auxB_surround : m_samples_auxA_surround;
|
int* aux_surround = aux_id ? m_samples_auxB_surround : m_samples_auxA_surround;
|
||||||
int* auxc_buffer = aux_id ? m_samples_auxC_surround : m_samples_auxC_right;
|
int* auxc_buffer = aux_id ? m_samples_auxC_surround : m_samples_auxC_right;
|
||||||
|
|
||||||
int* upload_ptr = (int*)HLEMemory_Get_Pointer(addresses[0]);
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
int* upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[0]);
|
||||||
for (u32 i = 0; i < 96; ++i)
|
for (u32 i = 0; i < 96; ++i)
|
||||||
*upload_ptr++ = Common::swap32(aux_left[i]);
|
*upload_ptr++ = Common::swap32(aux_left[i]);
|
||||||
for (u32 i = 0; i < 96; ++i)
|
for (u32 i = 0; i < 96; ++i)
|
||||||
|
@ -544,7 +550,7 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
|
||||||
for (u32 i = 0; i < 96; ++i)
|
for (u32 i = 0; i < 96; ++i)
|
||||||
*upload_ptr++ = Common::swap32(aux_surround[i]);
|
*upload_ptr++ = Common::swap32(aux_surround[i]);
|
||||||
|
|
||||||
upload_ptr = (int*)HLEMemory_Get_Pointer(addresses[1]);
|
upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[1]);
|
||||||
for (u32 i = 0; i < 96; ++i)
|
for (u32 i = 0; i < 96; ++i)
|
||||||
*upload_ptr++ = Common::swap32(auxc_buffer[i]);
|
*upload_ptr++ = Common::swap32(auxc_buffer[i]);
|
||||||
|
|
||||||
|
@ -556,7 +562,7 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
|
||||||
m_samples_auxC_left};
|
m_samples_auxC_left};
|
||||||
for (u32 mix_i = 0; mix_i < 4; ++mix_i)
|
for (u32 mix_i = 0; mix_i < 4; ++mix_i)
|
||||||
{
|
{
|
||||||
int* dl_ptr = (int*)HLEMemory_Get_Pointer(addresses[2 + mix_i]);
|
int* dl_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[2 + mix_i]);
|
||||||
for (u32 i = 0; i < 96; ++i)
|
for (u32 i = 0; i < 96; ++i)
|
||||||
aux_left[i] = Common::swap32(dl_ptr[i]);
|
aux_left[i] = Common::swap32(dl_ptr[i]);
|
||||||
|
|
||||||
|
@ -579,14 +585,16 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool
|
||||||
|
|
||||||
for (size_t i = 0; i < upload_buffer.size(); ++i)
|
for (size_t i = 0; i < upload_buffer.size(); ++i)
|
||||||
upload_buffer[i] = Common::swap32(m_samples_main_surround[i]);
|
upload_buffer[i] = Common::swap32(m_samples_main_surround[i]);
|
||||||
memcpy(HLEMemory_Get_Pointer(surround_addr), upload_buffer.data(), sizeof(upload_buffer));
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), upload_buffer.data(), sizeof(upload_buffer));
|
||||||
|
|
||||||
if (upload_auxc)
|
if (upload_auxc)
|
||||||
{
|
{
|
||||||
surround_addr += sizeof(upload_buffer);
|
surround_addr += sizeof(upload_buffer);
|
||||||
for (size_t i = 0; i < upload_buffer.size(); ++i)
|
for (size_t i = 0; i < upload_buffer.size(); ++i)
|
||||||
upload_buffer[i] = Common::swap32(m_samples_auxC_left[i]);
|
upload_buffer[i] = Common::swap32(m_samples_auxC_left[i]);
|
||||||
memcpy(HLEMemory_Get_Pointer(surround_addr), upload_buffer.data(), sizeof(upload_buffer));
|
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), upload_buffer.data(),
|
||||||
|
sizeof(upload_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp internal buffers to 16 bits.
|
// Clamp internal buffers to 16 bits.
|
||||||
|
@ -610,7 +618,7 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool
|
||||||
buffer[2 * i + 1] = Common::swap16(m_samples_main_left[i]);
|
buffer[2 * i + 1] = Common::swap16(m_samples_main_left[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(HLEMemory_Get_Pointer(lr_addr), buffer.data(), sizeof(buffer));
|
memcpy(HLEMemory_Get_Pointer(memory, lr_addr), buffer.data(), sizeof(buffer));
|
||||||
m_mail_handler.PushMail(DSP_SYNC, true);
|
m_mail_handler.PushMail(DSP_SYNC, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,10 +626,11 @@ void AXWiiUCode::OutputWMSamples(u32* addresses)
|
||||||
{
|
{
|
||||||
int* buffers[] = {m_samples_wm0, m_samples_wm1, m_samples_wm2, m_samples_wm3};
|
int* buffers[] = {m_samples_wm0, m_samples_wm1, m_samples_wm2, m_samples_wm3};
|
||||||
|
|
||||||
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
for (u32 i = 0; i < 4; ++i)
|
for (u32 i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
int* in = buffers[i];
|
int* in = buffers[i];
|
||||||
u16* out = (u16*)HLEMemory_Get_Pointer(addresses[i]);
|
u16* out = (u16*)HLEMemory_Get_Pointer(memory, addresses[i]);
|
||||||
for (u32 j = 0; j < 3 * 6; ++j)
|
for (u32 j = 0; j < 3 * 6; ++j)
|
||||||
{
|
{
|
||||||
int sample = std::clamp(in[j], -32767, 32767);
|
int sample = std::clamp(in[j], -32767, 32767);
|
||||||
|
|
|
@ -28,7 +28,7 @@ void CARDUCode::Update()
|
||||||
// check if we have something to send
|
// check if we have something to send
|
||||||
if (m_mail_handler.HasPending())
|
if (m_mail_handler.HasPending())
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsphle->GetSystem().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,26 +15,26 @@
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
void ProcessGBACrypto(u32 address)
|
void ProcessGBACrypto(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
// Nonce challenge (first read from GBA, hence already little-endian)
|
// Nonce challenge (first read from GBA, hence already little-endian)
|
||||||
const u32 challenge = HLEMemory_Read_U32LE(address);
|
const u32 challenge = HLEMemory_Read_U32LE(memory, address);
|
||||||
|
|
||||||
// Palette of pulsing logo on GBA during transmission [0,6]
|
// Palette of pulsing logo on GBA during transmission [0,6]
|
||||||
const u32 logo_palette = HLEMemory_Read_U32(address + 4);
|
const u32 logo_palette = HLEMemory_Read_U32(memory, address + 4);
|
||||||
|
|
||||||
// Speed and direction of palette interpolation [-4,4]
|
// Speed and direction of palette interpolation [-4,4]
|
||||||
const u32 logo_speed_32 = HLEMemory_Read_U32(address + 8);
|
const u32 logo_speed_32 = HLEMemory_Read_U32(memory, address + 8);
|
||||||
|
|
||||||
// Length of JoyBoot program to upload
|
// Length of JoyBoot program to upload
|
||||||
const u32 length = HLEMemory_Read_U32(address + 12);
|
const u32 length = HLEMemory_Read_U32(memory, address + 12);
|
||||||
|
|
||||||
// Address to return results to game
|
// Address to return results to game
|
||||||
const u32 dest_addr = HLEMemory_Read_U32(address + 16);
|
const u32 dest_addr = HLEMemory_Read_U32(memory, address + 16);
|
||||||
|
|
||||||
// Unwrap key from challenge using 'sedo' magic number (to encrypt JoyBoot program)
|
// Unwrap key from challenge using 'sedo' magic number (to encrypt JoyBoot program)
|
||||||
const u32 key = challenge ^ 0x6f646573;
|
const u32 key = challenge ^ 0x6f646573;
|
||||||
HLEMemory_Write_U32(dest_addr, key);
|
HLEMemory_Write_U32(memory, dest_addr, key);
|
||||||
|
|
||||||
// Pack palette parameters
|
// Pack palette parameters
|
||||||
u16 palette_speed_coded;
|
u16 palette_speed_coded;
|
||||||
|
@ -62,7 +62,7 @@ void ProcessGBACrypto(u32 address)
|
||||||
|
|
||||||
// Wrap with 'Kawa' or 'sedo' (Kawasedo is the author of the BIOS cipher)
|
// Wrap with 'Kawa' or 'sedo' (Kawasedo is the author of the BIOS cipher)
|
||||||
t3 ^= ((t3 & 0x200) != 0 ? 0x6f646573 : 0x6177614b);
|
t3 ^= ((t3 & 0x200) != 0 ? 0x6f646573 : 0x6177614b);
|
||||||
HLEMemory_Write_U32(dest_addr + 4, t3);
|
HLEMemory_Write_U32(memory, dest_addr + 4, t3);
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
DEBUG_LOG_FMT(DSPHLE,
|
DEBUG_LOG_FMT(DSPHLE,
|
||||||
|
@ -85,7 +85,7 @@ void GBAUCode::Update()
|
||||||
// check if we have something to send
|
// check if we have something to send
|
||||||
if (m_mail_handler.HasPending())
|
if (m_mail_handler.HasPending())
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsphle->GetSystem().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ void GBAUCode::HandleMail(u32 mail)
|
||||||
{
|
{
|
||||||
const u32 address = mail & 0x0fff'ffff;
|
const u32 address = mail & 0x0fff'ffff;
|
||||||
|
|
||||||
ProcessGBACrypto(address);
|
ProcessGBACrypto(m_dsphle->GetSystem().GetMemory(), address);
|
||||||
|
|
||||||
m_mail_handler.PushMail(DSP_DONE);
|
m_mail_handler.PushMail(DSP_DONE);
|
||||||
m_mail_state = MailState::WaitingForNextTask;
|
m_mail_state = MailState::WaitingForNextTask;
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
|
|
||||||
|
namespace Memory
|
||||||
|
{
|
||||||
|
class MemoryManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
class DSPHLE;
|
class DSPHLE;
|
||||||
|
@ -13,7 +18,7 @@ class DSPHLE;
|
||||||
// Computes two 32 bit integers to be returned to the game, based on the
|
// Computes two 32 bit integers to be returned to the game, based on the
|
||||||
// provided crypto parameters at the provided MRAM address. The integers are
|
// provided crypto parameters at the provided MRAM address. The integers are
|
||||||
// written back to RAM at the dest address provided in the crypto parameters.
|
// written back to RAM at the dest address provided in the crypto parameters.
|
||||||
void ProcessGBACrypto(u32 address);
|
void ProcessGBACrypto(Memory::MemoryManager& memory, u32 address);
|
||||||
|
|
||||||
class GBAUCode final : public UCodeInterface
|
class GBAUCode final : public UCodeInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "Core/HW/DSPHLE/DSPHLE.h"
|
#include "Core/HW/DSPHLE/DSPHLE.h"
|
||||||
#include "Core/HW/DSPHLE/MailHandler.h"
|
#include "Core/HW/DSPHLE/MailHandler.h"
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
|
@ -94,13 +95,14 @@ void ROMUCode::HandleMail(u32 mail)
|
||||||
|
|
||||||
void ROMUCode::BootUCode()
|
void ROMUCode::BootUCode()
|
||||||
{
|
{
|
||||||
const u32 ector_crc =
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
Common::HashEctor(static_cast<u8*>(HLEMemory_Get_Pointer(m_current_ucode.m_ram_address)),
|
const u32 ector_crc = Common::HashEctor(
|
||||||
m_current_ucode.m_length);
|
static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_current_ucode.m_ram_address)),
|
||||||
|
m_current_ucode.m_length);
|
||||||
|
|
||||||
if (Config::Get(Config::MAIN_DUMP_UCODE))
|
if (Config::Get(Config::MAIN_DUMP_UCODE))
|
||||||
{
|
{
|
||||||
DSP::DumpDSPCode(static_cast<u8*>(HLEMemory_Get_Pointer(m_current_ucode.m_ram_address)),
|
DSP::DumpDSPCode(static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_current_ucode.m_ram_address)),
|
||||||
m_current_ucode.m_length, ector_crc);
|
m_current_ucode.m_length, ector_crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,33 +39,24 @@ constexpr bool ExramRead(u32 address)
|
||||||
return (address & 0x10000000) != 0;
|
return (address & 0x10000000) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 HLEMemory_Read_U8(u32 address)
|
u8 HLEMemory_Read_U8(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
return memory.GetEXRAM()[address & memory.GetExRamMask()];
|
return memory.GetEXRAM()[address & memory.GetExRamMask()];
|
||||||
|
|
||||||
return memory.GetRAM()[address & memory.GetRamMask()];
|
return memory.GetRAM()[address & memory.GetRamMask()];
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEMemory_Write_U8(u32 address, u8 value)
|
void HLEMemory_Write_U8(Memory::MemoryManager& memory, u32 address, u8 value)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
memory.GetEXRAM()[address & memory.GetExRamMask()] = value;
|
memory.GetEXRAM()[address & memory.GetExRamMask()] = value;
|
||||||
else
|
else
|
||||||
memory.GetRAM()[address & memory.GetRamMask()] = value;
|
memory.GetRAM()[address & memory.GetRamMask()] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 HLEMemory_Read_U16LE(u32 address)
|
u16 HLEMemory_Read_U16LE(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
u16 value;
|
u16 value;
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
|
@ -76,32 +67,26 @@ u16 HLEMemory_Read_U16LE(u32 address)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 HLEMemory_Read_U16(u32 address)
|
u16 HLEMemory_Read_U16(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
return Common::swap16(HLEMemory_Read_U16LE(address));
|
return Common::swap16(HLEMemory_Read_U16LE(memory, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEMemory_Write_U16LE(u32 address, u16 value)
|
void HLEMemory_Write_U16LE(Memory::MemoryManager& memory, u32 address, u16 value)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u16));
|
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u16));
|
||||||
else
|
else
|
||||||
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u16));
|
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u16));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEMemory_Write_U16(u32 address, u16 value)
|
void HLEMemory_Write_U16(Memory::MemoryManager& memory, u32 address, u16 value)
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U16LE(address, Common::swap16(value));
|
HLEMemory_Write_U16LE(memory, address, Common::swap16(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 HLEMemory_Read_U32LE(u32 address)
|
u32 HLEMemory_Read_U32LE(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
|
@ -112,32 +97,26 @@ u32 HLEMemory_Read_U32LE(u32 address)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 HLEMemory_Read_U32(u32 address)
|
u32 HLEMemory_Read_U32(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
return Common::swap32(HLEMemory_Read_U32LE(address));
|
return Common::swap32(HLEMemory_Read_U32LE(memory, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEMemory_Write_U32LE(u32 address, u32 value)
|
void HLEMemory_Write_U32LE(Memory::MemoryManager& memory, u32 address, u32 value)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u32));
|
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u32));
|
||||||
else
|
else
|
||||||
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u32));
|
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEMemory_Write_U32(u32 address, u32 value)
|
void HLEMemory_Write_U32(Memory::MemoryManager& memory, u32 address, u32 value)
|
||||||
{
|
{
|
||||||
HLEMemory_Write_U32LE(address, Common::swap32(value));
|
HLEMemory_Write_U32LE(memory, address, Common::swap32(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void* HLEMemory_Get_Pointer(u32 address)
|
void* HLEMemory_Get_Pointer(Memory::MemoryManager& memory, u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
|
|
||||||
if (ExramRead(address))
|
if (ExramRead(address))
|
||||||
return &memory.GetEXRAM()[address & memory.GetExRamMask()];
|
return &memory.GetEXRAM()[address & memory.GetExRamMask()];
|
||||||
|
|
||||||
|
@ -204,14 +183,13 @@ void UCodeInterface::PrepareBootUCode(u32 mail)
|
||||||
m_needs_resume_mail = true;
|
m_needs_resume_mail = true;
|
||||||
m_upload_setup_in_progress = false;
|
m_upload_setup_in_progress = false;
|
||||||
|
|
||||||
const u32 ector_crc =
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
Common::HashEctor(static_cast<u8*>(HLEMemory_Get_Pointer(m_next_ucode.iram_mram_addr)),
|
const u32 ector_crc = Common::HashEctor(
|
||||||
m_next_ucode.iram_size);
|
static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_next_ucode.iram_mram_addr)),
|
||||||
|
m_next_ucode.iram_size);
|
||||||
|
|
||||||
if (Config::Get(Config::MAIN_DUMP_UCODE))
|
if (Config::Get(Config::MAIN_DUMP_UCODE))
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
|
||||||
DSP::DumpDSPCode(memory.GetPointer(m_next_ucode.iram_mram_addr), m_next_ucode.iram_size,
|
DSP::DumpDSPCode(memory.GetPointer(m_next_ucode.iram_mram_addr), m_next_ucode.iram_size,
|
||||||
ector_crc);
|
ector_crc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace Memory
|
||||||
|
{
|
||||||
|
class MemoryManager;
|
||||||
|
}
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
|
@ -19,22 +23,22 @@ class DSPHLE;
|
||||||
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
|
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
|
||||||
#define UCODE_NULL 0xFFFFFFFF
|
#define UCODE_NULL 0xFFFFFFFF
|
||||||
|
|
||||||
u8 HLEMemory_Read_U8(u32 address);
|
u8 HLEMemory_Read_U8(Memory::MemoryManager& memory, u32 address);
|
||||||
void HLEMemory_Write_U8(u32 address, u8 value);
|
void HLEMemory_Write_U8(Memory::MemoryManager& memory, u32 address, u8 value);
|
||||||
|
|
||||||
u16 HLEMemory_Read_U16LE(u32 address);
|
u16 HLEMemory_Read_U16LE(Memory::MemoryManager& memory, u32 address);
|
||||||
u16 HLEMemory_Read_U16(u32 address);
|
u16 HLEMemory_Read_U16(Memory::MemoryManager& memory, u32 address);
|
||||||
|
|
||||||
void HLEMemory_Write_U16LE(u32 address, u16 value);
|
void HLEMemory_Write_U16LE(Memory::MemoryManager& memory, u32 address, u16 value);
|
||||||
void HLEMemory_Write_U16(u32 address, u16 value);
|
void HLEMemory_Write_U16(Memory::MemoryManager& memory, u32 address, u16 value);
|
||||||
|
|
||||||
u32 HLEMemory_Read_U32LE(u32 address);
|
u32 HLEMemory_Read_U32LE(Memory::MemoryManager& memory, u32 address);
|
||||||
u32 HLEMemory_Read_U32(u32 address);
|
u32 HLEMemory_Read_U32(Memory::MemoryManager& memory, u32 address);
|
||||||
|
|
||||||
void HLEMemory_Write_U32LE(u32 address, u32 value);
|
void HLEMemory_Write_U32LE(Memory::MemoryManager& memory, u32 address, u32 value);
|
||||||
void HLEMemory_Write_U32(u32 address, u32 value);
|
void HLEMemory_Write_U32(Memory::MemoryManager& memory, u32 address, u32 value);
|
||||||
|
|
||||||
void* HLEMemory_Get_Pointer(u32 address);
|
void* HLEMemory_Get_Pointer(Memory::MemoryManager& memory, u32 address);
|
||||||
|
|
||||||
class UCodeInterface
|
class UCodeInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,7 +118,8 @@ static const std::map<u32, u32> UCODE_FLAGS = {
|
||||||
// * The Legend of Zelda: Twilight Princess / Wii (type ????, CRC ????)
|
// * The Legend of Zelda: Twilight Princess / Wii (type ????, CRC ????)
|
||||||
};
|
};
|
||||||
|
|
||||||
ZeldaUCode::ZeldaUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc)
|
ZeldaUCode::ZeldaUCode(DSPHLE* dsphle, u32 crc)
|
||||||
|
: UCodeInterface(dsphle, crc), m_renderer(dsphle->GetSystem())
|
||||||
{
|
{
|
||||||
auto it = UCODE_FLAGS.find(crc);
|
auto it = UCODE_FLAGS.find(crc);
|
||||||
if (it == UCODE_FLAGS.end())
|
if (it == UCODE_FLAGS.end())
|
||||||
|
@ -369,7 +370,7 @@ void ZeldaUCode::HandleMailLight(u32 mail)
|
||||||
m_sync_max_voice_id = 0xFFFFFFFF;
|
m_sync_max_voice_id = 0xFFFFFFFF;
|
||||||
m_sync_voice_skip_flags.fill(0xFFFF);
|
m_sync_voice_skip_flags.fill(0xFFFF);
|
||||||
RenderAudio();
|
RenderAudio();
|
||||||
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
m_dsphle->GetSystem().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MailState::HALTED:
|
case MailState::HALTED:
|
||||||
|
@ -470,7 +471,8 @@ void ZeldaUCode::RunPendingCommands()
|
||||||
|
|
||||||
m_renderer.SetVPBBaseAddress(Read32());
|
m_renderer.SetVPBBaseAddress(Read32());
|
||||||
|
|
||||||
u16* data_ptr = (u16*)HLEMemory_Get_Pointer(Read32());
|
auto& memory = m_dsphle->GetSystem().GetMemory();
|
||||||
|
u16* data_ptr = (u16*)HLEMemory_Get_Pointer(memory, Read32());
|
||||||
|
|
||||||
std::array<s16, 0x100> resampling_coeffs;
|
std::array<s16, 0x100> resampling_coeffs;
|
||||||
for (size_t i = 0; i < 0x100; ++i)
|
for (size_t i = 0; i < 0x100; ++i)
|
||||||
|
@ -492,7 +494,7 @@ void ZeldaUCode::RunPendingCommands()
|
||||||
m_renderer.SetSineTable(std::move(sine_table));
|
m_renderer.SetSineTable(std::move(sine_table));
|
||||||
}
|
}
|
||||||
|
|
||||||
u16* afc_coeffs_ptr = (u16*)HLEMemory_Get_Pointer(Read32());
|
u16* afc_coeffs_ptr = (u16*)HLEMemory_Get_Pointer(memory, Read32());
|
||||||
std::array<s16, 0x20> afc_coeffs;
|
std::array<s16, 0x20> afc_coeffs;
|
||||||
for (size_t i = 0; i < 0x20; ++i)
|
for (size_t i = 0; i < 0x20; ++i)
|
||||||
afc_coeffs[i] = Common::swap16(afc_coeffs_ptr[i]);
|
afc_coeffs[i] = Common::swap16(afc_coeffs_ptr[i]);
|
||||||
|
@ -542,7 +544,7 @@ void ZeldaUCode::RunPendingCommands()
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
if (m_flags & SUPPORTS_GBA_CRYPTO)
|
if (m_flags & SUPPORTS_GBA_CRYPTO)
|
||||||
{
|
{
|
||||||
ProcessGBACrypto(Read32());
|
ProcessGBACrypto(m_dsphle->GetSystem().GetMemory(), Read32());
|
||||||
}
|
}
|
||||||
else if (m_flags & WEIRD_CMD_0C)
|
else if (m_flags & WEIRD_CMD_0C)
|
||||||
{
|
{
|
||||||
|
@ -965,6 +967,12 @@ struct ReverbPB
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
ZeldaAudioRenderer::ZeldaAudioRenderer(Core::System& system) : m_system(system)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeldaAudioRenderer::~ZeldaAudioRenderer() = default;
|
||||||
|
|
||||||
void ZeldaAudioRenderer::PrepareFrame()
|
void ZeldaAudioRenderer::PrepareFrame()
|
||||||
{
|
{
|
||||||
if (m_prepared)
|
if (m_prepared)
|
||||||
|
@ -1047,7 +1055,8 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
|
||||||
&m_buf_front_right_reverb_last8,
|
&m_buf_front_right_reverb_last8,
|
||||||
};
|
};
|
||||||
|
|
||||||
u16* rpb_base_ptr = (u16*)HLEMemory_Get_Pointer(m_reverb_pb_base_addr);
|
auto& memory = m_system.GetMemory();
|
||||||
|
u16* rpb_base_ptr = (u16*)HLEMemory_Get_Pointer(memory, m_reverb_pb_base_addr);
|
||||||
for (u16 rpb_idx = 0; rpb_idx < 4; ++rpb_idx)
|
for (u16 rpb_idx = 0; rpb_idx < 4; ++rpb_idx)
|
||||||
{
|
{
|
||||||
ReverbPB rpb;
|
ReverbPB rpb;
|
||||||
|
@ -1061,7 +1070,7 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
|
||||||
u16 mram_buffer_idx = m_reverb_pb_frames_count[rpb_idx];
|
u16 mram_buffer_idx = m_reverb_pb_frames_count[rpb_idx];
|
||||||
|
|
||||||
u32 mram_addr = rpb.GetCircularBufferBase() + mram_buffer_idx * 0x50 * sizeof(s16);
|
u32 mram_addr = rpb.GetCircularBufferBase() + mram_buffer_idx * 0x50 * sizeof(s16);
|
||||||
s16* mram_ptr = (s16*)HLEMemory_Get_Pointer(mram_addr);
|
s16* mram_ptr = (s16*)HLEMemory_Get_Pointer(memory, mram_addr);
|
||||||
|
|
||||||
if (!post_rendering)
|
if (!post_rendering)
|
||||||
{
|
{
|
||||||
|
@ -1316,8 +1325,9 @@ void ZeldaAudioRenderer::FinalizeFrame()
|
||||||
ApplyVolumeInPlace_4_12(&m_buf_front_left, m_output_volume);
|
ApplyVolumeInPlace_4_12(&m_buf_front_left, m_output_volume);
|
||||||
ApplyVolumeInPlace_4_12(&m_buf_front_right, m_output_volume);
|
ApplyVolumeInPlace_4_12(&m_buf_front_right, m_output_volume);
|
||||||
|
|
||||||
u16* ram_left_buffer = (u16*)HLEMemory_Get_Pointer(m_output_lbuf_addr);
|
auto& memory = m_system.GetMemory();
|
||||||
u16* ram_right_buffer = (u16*)HLEMemory_Get_Pointer(m_output_rbuf_addr);
|
u16* ram_left_buffer = (u16*)HLEMemory_Get_Pointer(memory, m_output_lbuf_addr);
|
||||||
|
u16* ram_right_buffer = (u16*)HLEMemory_Get_Pointer(memory, m_output_rbuf_addr);
|
||||||
for (size_t i = 0; i < m_buf_front_left.size(); ++i)
|
for (size_t i = 0; i < m_buf_front_left.size(); ++i)
|
||||||
{
|
{
|
||||||
ram_left_buffer[i] = Common::swap16(m_buf_front_left[i]);
|
ram_left_buffer[i] = Common::swap16(m_buf_front_left[i]);
|
||||||
|
@ -1335,8 +1345,9 @@ void ZeldaAudioRenderer::FinalizeFrame()
|
||||||
|
|
||||||
void ZeldaAudioRenderer::FetchVPB(u16 voice_id, VPB* vpb)
|
void ZeldaAudioRenderer::FetchVPB(u16 voice_id, VPB* vpb)
|
||||||
{
|
{
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
u16* vpb_words = (u16*)vpb;
|
u16* vpb_words = (u16*)vpb;
|
||||||
u16* ram_vpbs = (u16*)HLEMemory_Get_Pointer(m_vpb_base_addr);
|
u16* ram_vpbs = (u16*)HLEMemory_Get_Pointer(memory, m_vpb_base_addr);
|
||||||
|
|
||||||
// A few versions of the UCode have VPB of size 0x80 (vs. the standard
|
// A few versions of the UCode have VPB of size 0x80 (vs. the standard
|
||||||
// 0xC0). The whole 0x40-0x80 part is gone. Handle that by moving things
|
// 0xC0). The whole 0x40-0x80 part is gone. Handle that by moving things
|
||||||
|
@ -1353,8 +1364,9 @@ void ZeldaAudioRenderer::FetchVPB(u16 voice_id, VPB* vpb)
|
||||||
|
|
||||||
void ZeldaAudioRenderer::StoreVPB(u16 voice_id, VPB* vpb)
|
void ZeldaAudioRenderer::StoreVPB(u16 voice_id, VPB* vpb)
|
||||||
{
|
{
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
u16* vpb_words = (u16*)vpb;
|
u16* vpb_words = (u16*)vpb;
|
||||||
u16* ram_vpbs = (u16*)HLEMemory_Get_Pointer(m_vpb_base_addr);
|
u16* ram_vpbs = (u16*)HLEMemory_Get_Pointer(memory, m_vpb_base_addr);
|
||||||
|
|
||||||
size_t vpb_size = (m_flags & TINY_VPB) ? 0x80 : 0xC0;
|
size_t vpb_size = (m_flags & TINY_VPB) ? 0x80 : 0xC0;
|
||||||
size_t base_idx = voice_id * vpb_size;
|
size_t base_idx = voice_id * vpb_size;
|
||||||
|
@ -1538,9 +1550,9 @@ void ZeldaAudioRenderer::Resample(VPB* vpb, const s16* src, MixingBuffer* dst)
|
||||||
void* ZeldaAudioRenderer::GetARAMPtr(u32 offset) const
|
void* ZeldaAudioRenderer::GetARAMPtr(u32 offset) const
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().bWii)
|
if (SConfig::GetInstance().bWii)
|
||||||
return HLEMemory_Get_Pointer(m_aram_base_addr + offset);
|
return HLEMemory_Get_Pointer(m_system.GetMemory(), m_aram_base_addr + offset);
|
||||||
else
|
else
|
||||||
return reinterpret_cast<u8*>(Core::System::GetInstance().GetDSP().GetARAMPtr()) + offset;
|
return reinterpret_cast<u8*>(m_system.GetDSP().GetARAMPtr()) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -1773,8 +1785,9 @@ void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
|
||||||
|
|
||||||
void ZeldaAudioRenderer::DownloadRawSamplesFromMRAM(s16* dst, VPB* vpb, u16 requested_samples_count)
|
void ZeldaAudioRenderer::DownloadRawSamplesFromMRAM(s16* dst, VPB* vpb, u16 requested_samples_count)
|
||||||
{
|
{
|
||||||
|
auto& memory = m_system.GetMemory();
|
||||||
u32 addr = vpb->GetBaseAddress() + vpb->current_position_h * sizeof(u16);
|
u32 addr = vpb->GetBaseAddress() + vpb->current_position_h * sizeof(u16);
|
||||||
s16* src_ptr = (s16*)HLEMemory_Get_Pointer(addr);
|
s16* src_ptr = (s16*)HLEMemory_Get_Pointer(memory, addr);
|
||||||
|
|
||||||
if (requested_samples_count > vpb->GetRemainingLength())
|
if (requested_samples_count > vpb->GetRemainingLength())
|
||||||
{
|
{
|
||||||
|
@ -1803,7 +1816,7 @@ void ZeldaAudioRenderer::DownloadRawSamplesFromMRAM(s16* dst, VPB* vpb, u16 requ
|
||||||
for (u16 i = 0; i < vpb->samples_before_loop; ++i)
|
for (u16 i = 0; i < vpb->samples_before_loop; ++i)
|
||||||
*dst++ = Common::swap16(*src_ptr++);
|
*dst++ = Common::swap16(*src_ptr++);
|
||||||
vpb->SetBaseAddress(vpb->GetLoopAddress());
|
vpb->SetBaseAddress(vpb->GetLoopAddress());
|
||||||
src_ptr = (s16*)HLEMemory_Get_Pointer(vpb->GetLoopAddress());
|
src_ptr = (s16*)HLEMemory_Get_Pointer(memory, vpb->GetLoopAddress());
|
||||||
for (u16 i = vpb->samples_before_loop; i < requested_samples_count; ++i)
|
for (u16 i = vpb->samples_before_loop; i < requested_samples_count; ++i)
|
||||||
*dst++ = Common::swap16(*src_ptr++);
|
*dst++ = Common::swap16(*src_ptr++);
|
||||||
vpb->current_position_h = requested_samples_count - vpb->samples_before_loop;
|
vpb->current_position_h = requested_samples_count - vpb->samples_before_loop;
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DSP::HLE
|
namespace DSP::HLE
|
||||||
{
|
{
|
||||||
class DSPHLE;
|
class DSPHLE;
|
||||||
|
@ -16,6 +21,13 @@ class DSPHLE;
|
||||||
class ZeldaAudioRenderer
|
class ZeldaAudioRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit ZeldaAudioRenderer(Core::System& system);
|
||||||
|
ZeldaAudioRenderer(const ZeldaAudioRenderer&) = delete;
|
||||||
|
ZeldaAudioRenderer(ZeldaAudioRenderer&&) = delete;
|
||||||
|
ZeldaAudioRenderer& operator=(const ZeldaAudioRenderer&) = delete;
|
||||||
|
ZeldaAudioRenderer& operator=(ZeldaAudioRenderer&&) = delete;
|
||||||
|
~ZeldaAudioRenderer();
|
||||||
|
|
||||||
void PrepareFrame();
|
void PrepareFrame();
|
||||||
void AddVoice(u16 voice_id);
|
void AddVoice(u16 voice_id);
|
||||||
void FinalizeFrame();
|
void FinalizeFrame();
|
||||||
|
@ -183,6 +195,8 @@ private:
|
||||||
std::array<s16, 8> m_buf_front_left_reverb_last8{};
|
std::array<s16, 8> m_buf_front_left_reverb_last8{};
|
||||||
std::array<s16, 8> m_buf_front_right_reverb_last8{};
|
std::array<s16, 8> m_buf_front_right_reverb_last8{};
|
||||||
u32 m_reverb_pb_base_addr = 0;
|
u32 m_reverb_pb_base_addr = 0;
|
||||||
|
|
||||||
|
Core::System& m_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ZeldaUCode final : public UCodeInterface
|
class ZeldaUCode final : public UCodeInterface
|
||||||
|
|
Loading…
Reference in New Issue