DSP: Remove HLEMemory functions

During my quest to rid Dolphin of the memory-unsafe GetPointer function,
I didn't realize that DSPHLE had its own set of memory access functions
that were essentially duplicating the standard ones. This commit gets
rid of them and replaces calls to them with calls to MemoryManager.
This commit is contained in:
JosJuice 2026-01-05 15:54:14 +01:00
parent 89a03199b1
commit 2098b4b1ca
14 changed files with 214 additions and 356 deletions

View File

@ -603,4 +603,9 @@ u8* DSPManager::GetARAMPtr() const
return m_aram.ptr;
}
u32 DSPManager::GetARAMSize() const
{
return m_aram.size;
}
} // end of namespace DSP

View File

@ -97,6 +97,7 @@ public:
// Debugger Helper
u8* GetARAMPtr() const;
u32 GetARAMSize() const;
void UpdateAudioDMA();
void UpdateDSPSlice(int cycles);

View File

@ -16,6 +16,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
namespace DSP::HLE
@ -159,11 +160,8 @@ void AESndUCode::HandleMail(u32 mail)
DEBUG_LOG_FMT(DSPHLE, "AESndUCode - MAIL_SEND_SAMPLES");
// send_samples
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
{
HLEMemory_Write_U16(memory, m_parameter_block.out_buf + i * sizeof(u16),
m_output_buffer[i]);
}
memory.CopyToEmuSwapped(m_parameter_block.out_buf, m_output_buffer.data(),
sizeof(m_output_buffer));
m_mail_handler.PushMail(DSP_SYNC, true);
break;
}
@ -203,41 +201,41 @@ void AESndUCode::HandleMail(u32 mail)
void AESndUCode::DMAInParameterBlock()
{
auto& memory = m_dsphle->GetSystem().GetMemory();
m_parameter_block.out_buf = HLEMemory_Read_U32(memory, m_parameter_block_addr + 0);
m_parameter_block.buf_start = HLEMemory_Read_U32(memory, m_parameter_block_addr + 4);
m_parameter_block.buf_end = HLEMemory_Read_U32(memory, m_parameter_block_addr + 8);
m_parameter_block.buf_curr = HLEMemory_Read_U32(memory, m_parameter_block_addr + 12);
m_parameter_block.yn1 = HLEMemory_Read_U16(memory, m_parameter_block_addr + 16);
m_parameter_block.yn2 = HLEMemory_Read_U16(memory, m_parameter_block_addr + 18);
m_parameter_block.pds = HLEMemory_Read_U16(memory, m_parameter_block_addr + 20);
m_parameter_block.freq = HLEMemory_Read_U32(memory, m_parameter_block_addr + 22);
m_parameter_block.counter = HLEMemory_Read_U16(memory, m_parameter_block_addr + 26);
m_parameter_block.left = HLEMemory_Read_U16(memory, m_parameter_block_addr + 28);
m_parameter_block.right = HLEMemory_Read_U16(memory, m_parameter_block_addr + 30);
m_parameter_block.volume_l = HLEMemory_Read_U16(memory, m_parameter_block_addr + 32);
m_parameter_block.volume_r = HLEMemory_Read_U16(memory, m_parameter_block_addr + 34);
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);
m_parameter_block.out_buf = memory.Read_U32(m_parameter_block_addr + 0);
m_parameter_block.buf_start = memory.Read_U32(m_parameter_block_addr + 4);
m_parameter_block.buf_end = memory.Read_U32(m_parameter_block_addr + 8);
m_parameter_block.buf_curr = memory.Read_U32(m_parameter_block_addr + 12);
m_parameter_block.yn1 = memory.Read_U16(m_parameter_block_addr + 16);
m_parameter_block.yn2 = memory.Read_U16(m_parameter_block_addr + 18);
m_parameter_block.pds = memory.Read_U16(m_parameter_block_addr + 20);
m_parameter_block.freq = memory.Read_U32(m_parameter_block_addr + 22);
m_parameter_block.counter = memory.Read_U16(m_parameter_block_addr + 26);
m_parameter_block.left = memory.Read_U16(m_parameter_block_addr + 28);
m_parameter_block.right = memory.Read_U16(m_parameter_block_addr + 30);
m_parameter_block.volume_l = memory.Read_U16(m_parameter_block_addr + 32);
m_parameter_block.volume_r = memory.Read_U16(m_parameter_block_addr + 34);
m_parameter_block.delay = memory.Read_U32(m_parameter_block_addr + 36);
m_parameter_block.flags = memory.Read_U32(m_parameter_block_addr + 40);
}
void AESndUCode::DMAOutParameterBlock()
{
auto& memory = m_dsphle->GetSystem().GetMemory();
HLEMemory_Write_U32(memory, m_parameter_block_addr + 0, m_parameter_block.out_buf);
HLEMemory_Write_U32(memory, m_parameter_block_addr + 4, m_parameter_block.buf_start);
HLEMemory_Write_U32(memory, m_parameter_block_addr + 8, m_parameter_block.buf_end);
HLEMemory_Write_U32(memory, m_parameter_block_addr + 12, m_parameter_block.buf_curr);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 16, m_parameter_block.yn1);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 18, m_parameter_block.yn2);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 20, m_parameter_block.pds);
HLEMemory_Write_U32(memory, m_parameter_block_addr + 22, m_parameter_block.freq);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 26, m_parameter_block.counter);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 28, m_parameter_block.left);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 30, m_parameter_block.right);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 32, m_parameter_block.volume_l);
HLEMemory_Write_U16(memory, m_parameter_block_addr + 34, m_parameter_block.volume_r);
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);
memory.Write_U32(m_parameter_block.out_buf, m_parameter_block_addr + 0);
memory.Write_U32(m_parameter_block.buf_start, m_parameter_block_addr + 4);
memory.Write_U32(m_parameter_block.buf_end, m_parameter_block_addr + 8);
memory.Write_U32(m_parameter_block.buf_curr, m_parameter_block_addr + 12);
memory.Write_U16(m_parameter_block.yn1, m_parameter_block_addr + 16);
memory.Write_U16(m_parameter_block.yn2, m_parameter_block_addr + 18);
memory.Write_U16(m_parameter_block.pds, m_parameter_block_addr + 20);
memory.Write_U32(m_parameter_block.freq, m_parameter_block_addr + 22);
memory.Write_U16(m_parameter_block.counter, m_parameter_block_addr + 26);
memory.Write_U16(m_parameter_block.left, m_parameter_block_addr + 28);
memory.Write_U16(m_parameter_block.right, m_parameter_block_addr + 30);
memory.Write_U16(m_parameter_block.volume_l, m_parameter_block_addr + 32);
memory.Write_U16(m_parameter_block.volume_r, m_parameter_block_addr + 34);
memory.Write_U32(m_parameter_block.delay, m_parameter_block_addr + 36);
memory.Write_U32(m_parameter_block.flags, m_parameter_block_addr + 40);
}
AESndAccelerator::AESndAccelerator(DSPManager& dsp) : m_dsp(dsp)

View File

@ -15,6 +15,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
namespace DSP::HLE
@ -136,10 +137,8 @@ void ASndUCode::HandleMail(u32 mail)
DMAInVoiceData(); // first do_dma call
// second do_dma call
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < NUM_OUTPUT_SAMPLES * 2; i++)
{
m_output_buffer[i] = HLEMemory_Read_U16(memory, m_current_voice.out_buf + i * sizeof(u16));
}
memory.CopyFromEmuSwapped(m_output_buffer.data(), m_current_voice.out_buf,
sizeof(m_output_buffer));
DoMixing(DSP_SYNC);
// Mail is handled by DoMixing()
break;
@ -161,10 +160,8 @@ void ASndUCode::HandleMail(u32 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++)
{
HLEMemory_Write_U16(memory, m_current_voice.out_buf + i * sizeof(u16), m_output_buffer[i]);
}
memory.CopyToEmuSwapped(m_current_voice.out_buf, m_output_buffer.data(),
sizeof(m_output_buffer));
m_mail_handler.PushMail(DSP_SYNC, true);
break;
}
@ -205,52 +202,52 @@ void ASndUCode::HandleMail(u32 mail)
void ASndUCode::DMAInVoiceData()
{
auto& memory = m_dsphle->GetSystem().GetMemory();
m_current_voice.out_buf = HLEMemory_Read_U32(memory, m_voice_addr);
m_current_voice.delay_samples = HLEMemory_Read_U32(memory, m_voice_addr + 4);
u32 new_flags = HLEMemory_Read_U32(memory, m_voice_addr + 8);
m_current_voice.out_buf = memory.Read_U32(m_voice_addr);
m_current_voice.delay_samples = memory.Read_U32(m_voice_addr + 4);
u32 new_flags = memory.Read_U32(m_voice_addr + 8);
if (m_current_voice.flags != new_flags)
DEBUG_LOG_FMT(DSPHLE, "ASndUCode - flags: {:08x}", new_flags);
m_current_voice.flags = new_flags;
m_current_voice.start_addr = HLEMemory_Read_U32(memory, m_voice_addr + 12);
m_current_voice.end_addr = HLEMemory_Read_U32(memory, m_voice_addr + 16);
m_current_voice.freq = HLEMemory_Read_U32(memory, m_voice_addr + 20);
m_current_voice.left = HLEMemory_Read_U16(memory, m_voice_addr + 24);
m_current_voice.right = HLEMemory_Read_U16(memory, m_voice_addr + 26);
m_current_voice.counter = HLEMemory_Read_U32(memory, m_voice_addr + 28);
m_current_voice.volume_l = HLEMemory_Read_U16(memory, m_voice_addr + 32);
m_current_voice.volume_r = HLEMemory_Read_U16(memory, m_voice_addr + 34);
m_current_voice.start_addr2 = HLEMemory_Read_U32(memory, m_voice_addr + 36);
m_current_voice.end_addr2 = HLEMemory_Read_U32(memory, m_voice_addr + 40);
m_current_voice.volume2_l = HLEMemory_Read_U16(memory, m_voice_addr + 44);
m_current_voice.volume2_r = HLEMemory_Read_U16(memory, m_voice_addr + 46);
m_current_voice.backup_addr = HLEMemory_Read_U32(memory, m_voice_addr + 48);
m_current_voice.tick_counter = HLEMemory_Read_U32(memory, m_voice_addr + 52);
m_current_voice.cb = HLEMemory_Read_U32(memory, m_voice_addr + 56);
m_current_voice._pad = HLEMemory_Read_U32(memory, m_voice_addr + 60);
m_current_voice.start_addr = memory.Read_U32(m_voice_addr + 12);
m_current_voice.end_addr = memory.Read_U32(m_voice_addr + 16);
m_current_voice.freq = memory.Read_U32(m_voice_addr + 20);
m_current_voice.left = memory.Read_U16(m_voice_addr + 24);
m_current_voice.right = memory.Read_U16(m_voice_addr + 26);
m_current_voice.counter = memory.Read_U32(m_voice_addr + 28);
m_current_voice.volume_l = memory.Read_U16(m_voice_addr + 32);
m_current_voice.volume_r = memory.Read_U16(m_voice_addr + 34);
m_current_voice.start_addr2 = memory.Read_U32(m_voice_addr + 36);
m_current_voice.end_addr2 = memory.Read_U32(m_voice_addr + 40);
m_current_voice.volume2_l = memory.Read_U16(m_voice_addr + 44);
m_current_voice.volume2_r = memory.Read_U16(m_voice_addr + 46);
m_current_voice.backup_addr = memory.Read_U32(m_voice_addr + 48);
m_current_voice.tick_counter = memory.Read_U32(m_voice_addr + 52);
m_current_voice.cb = memory.Read_U32(m_voice_addr + 56);
m_current_voice._pad = memory.Read_U32(m_voice_addr + 60);
}
void ASndUCode::DMAOutVoiceData()
{
auto& memory = m_dsphle->GetSystem().GetMemory();
HLEMemory_Write_U32(memory, m_voice_addr, m_current_voice.out_buf);
HLEMemory_Write_U32(memory, m_voice_addr + 4, m_current_voice.delay_samples);
HLEMemory_Write_U32(memory, m_voice_addr + 8, m_current_voice.flags);
HLEMemory_Write_U32(memory, m_voice_addr + 12, m_current_voice.start_addr);
HLEMemory_Write_U32(memory, m_voice_addr + 16, m_current_voice.end_addr);
HLEMemory_Write_U32(memory, m_voice_addr + 20, m_current_voice.freq);
HLEMemory_Write_U16(memory, m_voice_addr + 24, m_current_voice.left);
HLEMemory_Write_U16(memory, m_voice_addr + 26, m_current_voice.right);
HLEMemory_Write_U32(memory, m_voice_addr + 28, m_current_voice.counter);
HLEMemory_Write_U16(memory, m_voice_addr + 32, m_current_voice.volume_l);
HLEMemory_Write_U16(memory, m_voice_addr + 34, m_current_voice.volume_r);
HLEMemory_Write_U32(memory, m_voice_addr + 36, m_current_voice.start_addr2);
HLEMemory_Write_U32(memory, m_voice_addr + 40, m_current_voice.end_addr2);
HLEMemory_Write_U16(memory, m_voice_addr + 44, m_current_voice.volume2_l);
HLEMemory_Write_U16(memory, m_voice_addr + 46, m_current_voice.volume2_r);
HLEMemory_Write_U32(memory, m_voice_addr + 48, m_current_voice.backup_addr);
HLEMemory_Write_U32(memory, m_voice_addr + 52, m_current_voice.tick_counter);
HLEMemory_Write_U32(memory, m_voice_addr + 56, m_current_voice.cb);
HLEMemory_Write_U32(memory, m_voice_addr + 60, m_current_voice._pad);
memory.Write_U32(m_current_voice.out_buf, m_voice_addr);
memory.Write_U32(m_current_voice.delay_samples, m_voice_addr + 4);
memory.Write_U32(m_current_voice.flags, m_voice_addr + 8);
memory.Write_U32(m_current_voice.start_addr, m_voice_addr + 12);
memory.Write_U32(m_current_voice.end_addr, m_voice_addr + 16);
memory.Write_U32(m_current_voice.freq, m_voice_addr + 20);
memory.Write_U16(m_current_voice.left, m_voice_addr + 24);
memory.Write_U16(m_current_voice.right, m_voice_addr + 26);
memory.Write_U32(m_current_voice.counter, m_voice_addr + 28);
memory.Write_U16(m_current_voice.volume_l, m_voice_addr + 32);
memory.Write_U16(m_current_voice.volume_r, m_voice_addr + 34);
memory.Write_U32(m_current_voice.start_addr2, m_voice_addr + 36);
memory.Write_U32(m_current_voice.end_addr2, m_voice_addr + 40);
memory.Write_U16(m_current_voice.volume2_l, m_voice_addr + 44);
memory.Write_U16(m_current_voice.volume2_r, m_voice_addr + 46);
memory.Write_U32(m_current_voice.backup_addr, m_voice_addr + 48);
memory.Write_U32(m_current_voice.tick_counter, m_voice_addr + 52);
memory.Write_U32(m_current_voice.cb, m_voice_addr + 56);
memory.Write_U32(m_current_voice._pad, m_voice_addr + 60);
}
void ASndUCode::DoMixing(u32 return_mail)
@ -461,10 +458,7 @@ void ASndUCode::DMAInSampleData()
// 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;
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
{
m_input_sample_buffer[i] = HLEMemory_Read_U16(memory, addr + i * sizeof(u16));
}
memory.CopyFromEmuSwapped(m_input_sample_buffer.data(), addr, INPUT_SAMPLE_BUFFER_SIZE_BYTES);
}
void ASndUCode::DMAInSampleDataAssumeAligned()
@ -474,10 +468,7 @@ void ASndUCode::DMAInSampleDataAssumeAligned()
// (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;
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u16 i = 0; i < INPUT_SAMPLE_BUFFER_SIZE_WORDS; i++)
{
m_input_sample_buffer[i] = HLEMemory_Read_U16(memory, addr + i * sizeof(u16));
}
memory.CopyFromEmuSwapped(m_input_sample_buffer.data(), addr, INPUT_SAMPLE_BUFFER_SIZE_BYTES);
}
std::pair<s16, s16> ASndUCode::ReadSampleMono8Bits() const

View File

@ -21,6 +21,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/AXStructs.h"
#include "Core/HW/Memmap.h"
#define AX_GC
#include "Core/HW/DSPHLE/UCodes/AXVoice.h"
@ -390,7 +391,7 @@ void AXUCode::DownloadAndMixWithVolume(u32 addr, u16 vol_main, u16 vol_auxa, u16
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < 3; ++i)
{
int* ptr = (int*)HLEMemory_Get_Pointer(memory, addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(addr, 3 * 5 * 32 * sizeof(int)));
u16 volume = volumes[i];
for (u32 j = 0; j < 3; ++j)
{
@ -515,15 +516,19 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr)
auto& memory = m_dsphle->GetSystem().GetMemory();
if (write_addr)
{
int* ptr = (int*)HLEMemory_Get_Pointer(memory, write_addr);
for (auto& buffer : buffers)
for (u32 j = 0; j < 5 * 32; ++j)
*ptr++ = Common::swap32(buffer[j]);
{
memory.CopyToEmuSwapped(write_addr, buffer, 5 * 32 * sizeof(int));
write_addr += 5 * 32 * sizeof(int);
}
}
// Then, we read the new temp from the CPU and add to our current
// temp.
int* ptr = (int*)HLEMemory_Get_Pointer(memory, read_addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(
read_addr, sizeof(m_samples_main_left) + sizeof(m_samples_main_right) +
sizeof(m_samples_main_surround)));
for (auto& sample : m_samples_main_left)
sample += (int)Common::swap32(*ptr++);
for (auto& sample : m_samples_main_right)
@ -534,21 +539,19 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr)
void AXUCode::UploadLRS(u32 dst_addr)
{
int buffers[3][5 * 32];
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < 5 * 32; ++i)
for (const auto& samples : {m_samples_main_left, m_samples_main_right, m_samples_main_surround})
{
buffers[0][i] = Common::swap32(m_samples_main_left[i]);
buffers[1][i] = Common::swap32(m_samples_main_right[i]);
buffers[2][i] = Common::swap32(m_samples_main_surround[i]);
memory.CopyToEmuSwapped(dst_addr, samples, 5 * 32 * sizeof(int));
dst_addr += 5 * 32 * sizeof(int);
}
memcpy(HLEMemory_Get_Pointer(m_dsphle->GetSystem().GetMemory(), dst_addr), buffers,
sizeof(buffers));
}
void AXUCode::SetMainLR(u32 src_addr)
{
int* ptr = (int*)HLEMemory_Get_Pointer(m_dsphle->GetSystem().GetMemory(), src_addr);
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(src_addr, 5 * 32 * sizeof(int)));
for (u32 i = 0; i < 5 * 32; ++i)
{
int samp = (int)Common::swap32(*ptr++);
@ -596,7 +599,8 @@ void AXUCode::RunCompressor(u16 threshold, u16 release_frames, u32 table_addr, u
// apply the selected ramp
auto& memory = m_dsphle->GetSystem().GetMemory();
u16* ramp = (u16*)HLEMemory_Get_Pointer(memory, table_addr + table_offset);
u16* ramp = reinterpret_cast<u16*>(
memory.GetPointerForRange(table_addr + table_offset, 32 * millis * sizeof(u16)));
for (u32 i = 0; i < 32 * millis; ++i)
{
u16 coef = Common::swap16(*ramp++);
@ -607,12 +611,8 @@ void AXUCode::RunCompressor(u16 threshold, u16 release_frames, u32 table_addr, u
void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr)
{
int surround_buffer[5 * 32];
for (u32 i = 0; i < 5 * 32; ++i)
surround_buffer[i] = Common::swap32(m_samples_main_surround[i]);
auto& memory = m_dsphle->GetSystem().GetMemory();
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), surround_buffer, sizeof(surround_buffer));
memory.CopyToEmuSwapped(surround_addr, m_samples_main_surround, 5 * 32 * sizeof(int));
// 32 samples per ms, 5 ms, 2 channels
short buffer[5 * 32 * 2];
@ -627,21 +627,19 @@ void AXUCode::OutputSamples(u32 lr_addr, u32 surround_addr)
buffer[2 * i + 1] = Common::swap16(left);
}
memcpy(HLEMemory_Get_Pointer(memory, lr_addr), buffer, sizeof(buffer));
memory.CopyToEmu(lr_addr, buffer, sizeof(buffer));
}
void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
{
// Upload AUXB L/R
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, ul_addr);
for (auto& sample : m_samples_auxB_left)
*ptr++ = Common::swap32(sample);
for (auto& sample : m_samples_auxB_right)
*ptr++ = Common::swap32(sample);
memory.CopyToEmuSwapped(ul_addr, m_samples_auxB_left, sizeof(m_samples_auxB_left));
memory.CopyToEmuSwapped(ul_addr + sizeof(m_samples_auxB_left), m_samples_auxB_right,
sizeof(m_samples_auxB_right));
// Mix AUXB L/R to MAIN L/R, and replace AUXB L/R
ptr = (int*)HLEMemory_Get_Pointer(memory, dl_addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(dl_addr, 2 * 5 * 32 * sizeof(int)));
for (u32 i = 0; i < 5 * 32; ++i)
{
int samp = Common::swap32(*ptr++);
@ -659,7 +657,7 @@ void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
void AXUCode::SetOppositeLR(u32 src_addr)
{
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, src_addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(src_addr, 5 * 32 * sizeof(int)));
for (u32 i = 0; i < 5 * 32; ++i)
{
int inp = Common::swap32(*ptr++);
@ -672,26 +670,16 @@ void AXUCode::SetOppositeLR(u32 src_addr)
void AXUCode::SendAUXAndMix(u32 auxa_lrs_up, u32 auxb_s_up, u32 main_l_dl, u32 main_r_dl,
u32 auxb_l_dl, u32 auxb_r_dl)
{
// Buffers to upload first
const std::array<const int*, 3> up_buffers{
m_samples_auxA_left,
m_samples_auxA_right,
m_samples_auxA_surround,
};
// Upload AUXA LRS
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, auxa_lrs_up);
for (const auto& up_buffer : up_buffers)
{
for (u32 j = 0; j < 32 * 5; ++j)
*ptr++ = Common::swap32(up_buffer[j]);
}
memory.CopyToEmuSwapped(auxa_lrs_up, m_samples_auxA_left, 32 * 5 * sizeof(int));
memory.CopyToEmuSwapped(auxa_lrs_up + 32 * 5 * sizeof(int), m_samples_auxA_right,
32 * 5 * sizeof(int));
memory.CopyToEmuSwapped(auxa_lrs_up + 2 * 32 * 5 * sizeof(int), m_samples_auxA_surround,
32 * 5 * sizeof(int));
// Upload AUXB S
ptr = (int*)HLEMemory_Get_Pointer(memory, auxb_s_up);
for (auto& sample : m_samples_auxB_surround)
*ptr++ = Common::swap32(sample);
memory.CopyToEmuSwapped(auxb_s_up, m_samples_auxB_surround, sizeof(m_samples_auxB_surround));
// Download buffers and addresses
const std::array<int*, 4> dl_buffers{
@ -710,7 +698,8 @@ void AXUCode::SendAUXAndMix(u32 auxa_lrs_up, u32 auxb_s_up, u32 main_l_dl, u32 m
// Download and mix
for (size_t i = 0; i < dl_buffers.size(); ++i)
{
const int* dl_src = (int*)HLEMemory_Get_Pointer(memory, dl_addrs[i]);
const int* dl_src =
reinterpret_cast<int*>(memory.GetPointerForRange(dl_addrs[i], 32 * 5 * sizeof(int)));
for (size_t j = 0; j < 32 * 5; ++j)
dl_buffers[i][j] += (int)Common::swap32(*dl_src++);
}
@ -799,8 +788,7 @@ void AXUCode::CopyCmdList(u32 addr, u16 size)
}
auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < size; ++i, addr += 2)
m_cmdlist[i] = HLEMemory_Read_U16(memory, addr);
memory.CopyFromEmuSwapped(m_cmdlist, addr, size * sizeof(u16));
}
void AXUCode::Update()

View File

@ -17,6 +17,7 @@
#include "Core/HW/DSPHLE/UCodes/AXStructs.h"
#include "Core/HW/DSPHLE/UCodes/AXVoice.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
namespace DSP::HLE
{
@ -274,7 +275,7 @@ void AXWiiUCode::SetupProcessing(u32 init_addr)
void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
{
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, val_addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(val_addr, 32 * 3 * sizeof(int)));
for (int i = 0; i < 32 * 3; ++i)
{
int val = (int)Common::swap32(*ptr++);
@ -289,7 +290,7 @@ void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
void AXWiiUCode::AddSubToLR(u32 val_addr)
{
auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, val_addr);
int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(val_addr, 2 * 32 * 3 * sizeof(int)));
for (int i = 0; i < 32 * 3; ++i)
{
int val = (int)Common::swap32(*ptr++);
@ -526,16 +527,16 @@ void AXWiiUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 vo
auto& memory = m_dsphle->GetSystem().GetMemory();
if (write_addr)
{
int* ptr = (int*)HLEMemory_Get_Pointer(memory, write_addr);
for (const auto& buffer : buffers)
{
for (u32 j = 0; j < 3 * 32; ++j)
*ptr++ = Common::swap32(buffer[j]);
memory.CopyToEmuSwapped(write_addr, buffer, 3 * 32 * sizeof(int));
write_addr += 3 * 32 * sizeof(int);
}
}
// Then read the buffers from the CPU and add to our main buffers.
const int* ptr = (int*)HLEMemory_Get_Pointer(memory, read_addr);
const int* ptr = reinterpret_cast<int*>(
memory.GetPointerForRange(read_addr, main_buffers.size() * 3 * 32 * sizeof(int)));
for (auto& main_buffer : main_buffers)
{
for (u32 j = 0; j < 3 * 32; ++j)
@ -555,17 +556,11 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
int* auxc_buffer = aux_id ? m_samples_auxC_surround : m_samples_auxC_right;
auto& memory = m_dsphle->GetSystem().GetMemory();
int* upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[0]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_left[i]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_right[i]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_surround[i]);
memory.CopyToEmuSwapped(addresses[0], aux_left, 96 * sizeof(int));
memory.CopyToEmuSwapped(addresses[0] + 96 * sizeof(int), aux_right, 96 * sizeof(int));
memory.CopyToEmuSwapped(addresses[0] + 2 * 96 * sizeof(int), aux_surround, 96 * sizeof(int));
upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[1]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(auxc_buffer[i]);
memory.CopyToEmuSwapped(addresses[1], auxc_buffer, 96 * sizeof(int));
u16 volume_ramp[96];
GenerateVolumeRamp(volume_ramp, m_last_aux_volumes[aux_id], volume, 96);
@ -575,9 +570,7 @@ void AXWiiUCode::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
m_samples_auxC_left};
for (u32 mix_i = 0; mix_i < 4; ++mix_i)
{
int* dl_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[2 + mix_i]);
for (u32 i = 0; i < 96; ++i)
aux_left[i] = Common::swap32(dl_ptr[i]);
memory.CopyFromEmuSwapped(aux_left, addresses[2 + mix_i], 96 * sizeof(int));
for (u32 i = 0; i < 96; ++i)
{
@ -594,20 +587,13 @@ void AXWiiUCode::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume, bool
GenerateVolumeRamp(volume_ramp.data(), m_last_main_volume, volume, volume_ramp.size());
m_last_main_volume = volume;
std::array<int, 3 * 32> upload_buffer{};
for (size_t i = 0; i < upload_buffer.size(); ++i)
upload_buffer[i] = Common::swap32(m_samples_main_surround[i]);
auto& memory = m_dsphle->GetSystem().GetMemory();
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), upload_buffer.data(), sizeof(upload_buffer));
memory.CopyToEmuSwapped(surround_addr, m_samples_main_surround, 3 * 32 * sizeof(int));
if (upload_auxc)
{
surround_addr += sizeof(upload_buffer);
for (size_t i = 0; i < upload_buffer.size(); ++i)
upload_buffer[i] = Common::swap32(m_samples_auxC_left[i]);
memcpy(HLEMemory_Get_Pointer(memory, surround_addr), upload_buffer.data(),
sizeof(upload_buffer));
memory.CopyToEmuSwapped(surround_addr + 3 * 32 * sizeof(int), m_samples_auxC_left,
3 * 32 * sizeof(int));
}
// Clamp internal buffers to 16 bits.
@ -632,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]);
}
memcpy(HLEMemory_Get_Pointer(memory, lr_addr), buffer.data(), sizeof(buffer));
memory.CopyToEmu(lr_addr, buffer.data(), sizeof(buffer));
m_mail_handler.PushMail(DSP_SYNC, true);
}
@ -644,7 +630,7 @@ void AXWiiUCode::OutputWMSamples(u32* addresses)
for (u32 i = 0; i < 4; ++i)
{
int* in = buffers[i];
u16* out = (u16*)HLEMemory_Get_Pointer(memory, addresses[i]);
u16* out = reinterpret_cast<u16*>(memory.GetPointerForRange(addresses[i], 3 * 6 * sizeof(s16)));
for (u32 j = 0; j < 3 * 6; ++j)
{
s16 sample = ClampS16(in[j]);

View File

@ -11,6 +11,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
namespace DSP::HLE
@ -18,23 +19,23 @@ namespace DSP::HLE
void ProcessGBACrypto(Memory::MemoryManager& memory, u32 address)
{
// Nonce challenge (first read from GBA, hence already little-endian)
const u32 challenge = HLEMemory_Read_U32LE(memory, address);
const u32 challenge = memory.Read_U32_Swap(address);
// Palette of pulsing logo on GBA during transmission [0,6]
const u32 logo_palette = HLEMemory_Read_U32(memory, address + 4);
const u32 logo_palette = memory.Read_U32(address + 4);
// Speed and direction of palette interpolation [-4,4]
const u32 logo_speed_32 = HLEMemory_Read_U32(memory, address + 8);
const u32 logo_speed_32 = memory.Read_U32(address + 8);
// Length of JoyBoot program to upload
const u32 length = HLEMemory_Read_U32(memory, address + 12);
const u32 length = memory.Read_U32(address + 12);
// Address to return results to game
const u32 dest_addr = HLEMemory_Read_U32(memory, address + 16);
const u32 dest_addr = memory.Read_U32(address + 16);
// Unwrap key from challenge using 'sedo' magic number (to encrypt JoyBoot program)
const u32 key = challenge ^ 0x6f646573;
HLEMemory_Write_U32(memory, dest_addr, key);
memory.Write_U32(key, dest_addr);
// Pack palette parameters
u16 palette_speed_coded;
@ -62,7 +63,7 @@ void ProcessGBACrypto(Memory::MemoryManager& memory, u32 address)
// Wrap with 'Kawa' or 'sedo' (Kawasedo is the author of the BIOS cipher)
t3 ^= ((t3 & 0x200) != 0 ? 0x6f646573 : 0x6177614b);
HLEMemory_Write_U32(memory, dest_addr + 4, t3);
memory.Write_U32(t3, dest_addr + 4);
// Done!
DEBUG_LOG_FMT(DSPHLE,

View File

@ -19,6 +19,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
namespace DSP::HLE
@ -96,15 +97,12 @@ void ROMUCode::HandleMail(u32 mail)
void ROMUCode::BootUCode()
{
auto& memory = m_dsphle->GetSystem().GetMemory();
const u32 ector_crc = Common::HashEctor(
static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_current_ucode.m_ram_address)),
m_current_ucode.m_length);
const u8* pointer =
memory.GetPointerForRange(m_current_ucode.m_ram_address, m_current_ucode.m_length);
const u32 ector_crc = Common::HashEctor(pointer, m_current_ucode.m_length);
if (Config::Get(Config::MAIN_DUMP_UCODE))
{
DumpDSPCode(static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_current_ucode.m_ram_address)),
m_current_ucode.m_length, ector_crc);
}
DumpDSPCode(pointer, m_current_ucode.m_length, ector_crc);
INFO_LOG_FMT(DSPHLE, "CurrentUCode SOURCE Addr: {:#010x}", m_current_ucode.m_ram_address);
INFO_LOG_FMT(DSPHLE, "CurrentUCode Length: {:#010x}", m_current_ucode.m_length);

View File

@ -34,95 +34,6 @@
namespace DSP::HLE
{
constexpr bool ExramRead(u32 address)
{
return (address & 0x10000000) != 0;
}
u8 HLEMemory_Read_U8(Memory::MemoryManager& memory, u32 address)
{
if (ExramRead(address))
return memory.GetEXRAM()[address & memory.GetExRamMask()];
return memory.GetRAM()[address & memory.GetRamMask()];
}
void HLEMemory_Write_U8(Memory::MemoryManager& memory, u32 address, u8 value)
{
if (ExramRead(address))
memory.GetEXRAM()[address & memory.GetExRamMask()] = value;
else
memory.GetRAM()[address & memory.GetRamMask()] = value;
}
u16 HLEMemory_Read_U16LE(Memory::MemoryManager& memory, u32 address)
{
u16 value;
if (ExramRead(address))
std::memcpy(&value, &memory.GetEXRAM()[address & memory.GetExRamMask()], sizeof(u16));
else
std::memcpy(&value, &memory.GetRAM()[address & memory.GetRamMask()], sizeof(u16));
return value;
}
u16 HLEMemory_Read_U16(Memory::MemoryManager& memory, u32 address)
{
return Common::swap16(HLEMemory_Read_U16LE(memory, address));
}
void HLEMemory_Write_U16LE(Memory::MemoryManager& memory, u32 address, u16 value)
{
if (ExramRead(address))
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u16));
else
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u16));
}
void HLEMemory_Write_U16(Memory::MemoryManager& memory, u32 address, u16 value)
{
HLEMemory_Write_U16LE(memory, address, Common::swap16(value));
}
u32 HLEMemory_Read_U32LE(Memory::MemoryManager& memory, u32 address)
{
u32 value;
if (ExramRead(address))
std::memcpy(&value, &memory.GetEXRAM()[address & memory.GetExRamMask()], sizeof(u32));
else
std::memcpy(&value, &memory.GetRAM()[address & memory.GetRamMask()], sizeof(u32));
return value;
}
u32 HLEMemory_Read_U32(Memory::MemoryManager& memory, u32 address)
{
return Common::swap32(HLEMemory_Read_U32LE(memory, address));
}
void HLEMemory_Write_U32LE(Memory::MemoryManager& memory, u32 address, u32 value)
{
if (ExramRead(address))
std::memcpy(&memory.GetEXRAM()[address & memory.GetExRamMask()], &value, sizeof(u32));
else
std::memcpy(&memory.GetRAM()[address & memory.GetRamMask()], &value, sizeof(u32));
}
void HLEMemory_Write_U32(Memory::MemoryManager& memory, u32 address, u32 value)
{
HLEMemory_Write_U32LE(memory, address, Common::swap32(value));
}
void* HLEMemory_Get_Pointer(Memory::MemoryManager& memory, u32 address)
{
if (ExramRead(address))
return &memory.GetEXRAM()[address & memory.GetExRamMask()];
return &memory.GetRAM()[address & memory.GetRamMask()];
}
UCodeInterface::UCodeInterface(DSPHLE* dsphle, u32 crc)
: m_mail_handler(dsphle->AccessMailHandler()), m_dsphle(dsphle), m_crc(crc)
{
@ -184,16 +95,12 @@ void UCodeInterface::PrepareBootUCode(u32 mail)
m_upload_setup_in_progress = false;
auto& memory = m_dsphle->GetSystem().GetMemory();
const u32 ector_crc = Common::HashEctor(
static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_next_ucode.iram_mram_addr)),
m_next_ucode.iram_size);
const u8* pointer =
memory.GetPointerForRange(m_next_ucode.iram_mram_addr, m_next_ucode.iram_size);
const u32 ector_crc = Common::HashEctor(pointer, m_next_ucode.iram_size);
if (Config::Get(Config::MAIN_DUMP_UCODE))
{
const u8* pointer =
memory.GetPointerForRange(m_next_ucode.iram_mram_addr, m_next_ucode.iram_size);
DumpDSPCode(pointer, m_next_ucode.iram_size, ector_crc);
}
DEBUG_LOG_FMT(DSPHLE, "PrepareBootUCode {:#010x}", ector_crc);
DEBUG_LOG_FMT(DSPHLE, "DRAM -> MRAM: src {:04x} dst {:08x} size {:04x}",

View File

@ -23,23 +23,6 @@ class DSPHLE;
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
#define UCODE_NULL 0xFFFFFFFF
u8 HLEMemory_Read_U8(Memory::MemoryManager& memory, u32 address);
void HLEMemory_Write_U8(Memory::MemoryManager& memory, u32 address, u8 value);
u16 HLEMemory_Read_U16LE(Memory::MemoryManager& memory, u32 address);
u16 HLEMemory_Read_U16(Memory::MemoryManager& memory, u32 address);
void HLEMemory_Write_U16LE(Memory::MemoryManager& memory, u32 address, u16 value);
void HLEMemory_Write_U16(Memory::MemoryManager& memory, u32 address, u16 value);
u32 HLEMemory_Read_U32LE(Memory::MemoryManager& memory, u32 address);
u32 HLEMemory_Read_U32(Memory::MemoryManager& memory, u32 address);
void HLEMemory_Write_U32LE(Memory::MemoryManager& memory, u32 address, u32 value);
void HLEMemory_Write_U32(Memory::MemoryManager& memory, u32 address, u32 value);
void* HLEMemory_Get_Pointer(Memory::MemoryManager& memory, u32 address);
class UCodeInterface
{
public:

View File

@ -17,6 +17,7 @@
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/GBA.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
namespace DSP::HLE
@ -470,32 +471,27 @@ void ZeldaUCode::RunPendingCommands()
m_renderer.SetVPBBaseAddress(Read32());
auto& memory = m_dsphle->GetSystem().GetMemory();
u16* data_ptr = (u16*)HLEMemory_Get_Pointer(memory, Read32());
u32 address = Read32();
std::array<s16, 0x100> resampling_coeffs;
for (size_t i = 0; i < 0x100; ++i)
resampling_coeffs[i] = Common::swap16(data_ptr[i]);
std::array<s16, 0x100> resampling_coeffs{};
memory.CopyFromEmuSwapped(resampling_coeffs.data(), address, sizeof(resampling_coeffs));
m_renderer.SetResamplingCoeffs(std::move(resampling_coeffs));
std::array<s16, 0x100> const_patterns;
for (size_t i = 0; i < 0x100; ++i)
const_patterns[i] = Common::swap16(data_ptr[0x100 + i]);
std::array<s16, 0x100> const_patterns{};
memory.CopyFromEmuSwapped(const_patterns.data(), address + 0x200, sizeof(const_patterns));
m_renderer.SetConstPatterns(std::move(const_patterns));
// The sine table is only used for Dolby mixing
// which the light protocol doesn't support.
if ((m_flags & LIGHT_PROTOCOL) == 0)
{
std::array<s16, 0x80> sine_table;
for (size_t i = 0; i < 0x80; ++i)
sine_table[i] = Common::swap16(data_ptr[0x200 + i]);
std::array<s16, 0x80> sine_table{};
memory.CopyFromEmuSwapped(sine_table.data(), address + 0x400, sizeof(sine_table));
m_renderer.SetSineTable(std::move(sine_table));
}
u16* afc_coeffs_ptr = (u16*)HLEMemory_Get_Pointer(memory, Read32());
std::array<s16, 0x20> afc_coeffs;
for (size_t i = 0; i < 0x20; ++i)
afc_coeffs[i] = Common::swap16(afc_coeffs_ptr[i]);
std::array<s16, 0x20> afc_coeffs{};
memory.CopyFromEmuSwapped(afc_coeffs.data(), Read32(), sizeof(afc_coeffs));
m_renderer.SetAfcCoeffs(std::move(afc_coeffs));
m_renderer.SetReverbPBBaseAddress(Read32());
@ -1087,13 +1083,11 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
};
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)
{
ReverbPB rpb;
u16* rpb_raw_ptr = reinterpret_cast<u16*>(&rpb);
for (size_t i = 0; i < sizeof(ReverbPB) / 2; ++i)
rpb_raw_ptr[i] = Common::swap16(rpb_base_ptr[rpb_idx * sizeof(ReverbPB) / 2 + i]);
u32 rpb_addr = m_reverb_pb_base_addr + rpb_idx * sizeof(ReverbPB);
memory.CopyFromEmuSwapped(reinterpret_cast<u16*>(&rpb), rpb_addr, sizeof(ReverbPB));
if (!rpb.enabled)
continue;
@ -1101,7 +1095,6 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
u16 mram_buffer_idx = m_reverb_pb_frames_count[rpb_idx];
u32 mram_addr = rpb.GetCircularBufferBase() + mram_buffer_idx * 0x50 * sizeof(s16);
s16* mram_ptr = (s16*)HLEMemory_Get_Pointer(memory, mram_addr);
if (!post_rendering)
{
@ -1111,8 +1104,7 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
for (u16 i = 0; i < 8; ++i)
buffer[i] = (*last8_samples_buffers[rpb_idx])[i];
for (u16 i = 0; i < 0x50; ++i)
buffer[8 + i] = Common::swap16(mram_ptr[i]);
memory.CopyFromEmuSwapped(&buffer[8], mram_addr, 0x50 * sizeof(s16));
for (u16 i = 0; i < 8; ++i)
(*last8_samples_buffers[rpb_idx])[i] = buffer[0x50 + i];
@ -1161,8 +1153,7 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
MixingBuffer* buffer = reverb_buffers[rpb_idx];
// Upload the reverb data to RAM.
for (auto sample : *buffer)
*mram_ptr++ = Common::swap16(sample);
memory.CopyToEmuSwapped(mram_addr, buffer->data(), sizeof(*buffer));
mram_buffer_idx = (mram_buffer_idx + 1) % rpb.circular_buffer_size;
m_reverb_pb_frames_count[rpb_idx] = mram_buffer_idx;
@ -1427,15 +1418,10 @@ void ZeldaAudioRenderer::FinalizeFrame()
ApplyVolumeInPlace_4_12(&m_buf_front_right, m_output_volume);
auto& memory = m_system.GetMemory();
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)
{
ram_left_buffer[i] = Common::swap16(m_buf_front_left[i]);
ram_right_buffer[i] = Common::swap16(m_buf_front_right[i]);
}
m_output_lbuf_addr += sizeof(u16) * (u32)m_buf_front_left.size();
m_output_rbuf_addr += sizeof(u16) * (u32)m_buf_front_right.size();
memory.CopyToEmuSwapped(m_output_lbuf_addr, m_buf_front_left.data(), sizeof(m_buf_front_left));
memory.CopyToEmuSwapped(m_output_rbuf_addr, m_buf_front_right.data(), sizeof(m_buf_front_right));
m_output_lbuf_addr += sizeof(m_buf_front_left);
m_output_rbuf_addr += sizeof(m_buf_front_right);
// TODO: Some more Dolby mixing.
@ -1448,16 +1434,14 @@ void ZeldaAudioRenderer::FetchVPB(u16 voice_id, VPB* vpb)
{
auto& memory = m_system.GetMemory();
u16* vpb_words = (u16*)vpb;
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
// 0xC0). The whole 0x40-0x80 part is gone. Handle that by moving things
// around.
size_t vpb_size = (m_flags & TINY_VPB) ? 0x80 : 0xC0;
u32 vpb_size = ((m_flags & TINY_VPB) ? 0x80 : 0xC0) * sizeof(u16);
size_t base_idx = voice_id * vpb_size;
for (size_t i = 0; i < vpb_size; ++i)
vpb_words[i] = Common::swap16(ram_vpbs[base_idx + i]);
u32 base_idx = voice_id * vpb_size;
memory.CopyFromEmuSwapped(vpb_words, m_vpb_base_addr + base_idx, vpb_size);
if (m_flags & TINY_VPB)
vpb->Uncompress();
@ -1467,17 +1451,15 @@ void ZeldaAudioRenderer::StoreVPB(u16 voice_id, VPB* vpb)
{
auto& memory = m_system.GetMemory();
u16* vpb_words = (u16*)vpb;
u16* ram_vpbs = (u16*)HLEMemory_Get_Pointer(memory, m_vpb_base_addr);
size_t vpb_size = (m_flags & TINY_VPB) ? 0x80 : 0xC0;
size_t base_idx = voice_id * vpb_size;
u32 vpb_size = ((m_flags & TINY_VPB) ? 0x80 : 0xC0) * sizeof(u16);
u32 base_idx = voice_id * vpb_size;
if (m_flags & TINY_VPB)
vpb->Compress();
// Only the first 0x80 words are transferred back - the rest is read-only.
for (size_t i = 0; i < vpb_size - 0x40; ++i)
ram_vpbs[base_idx + i] = Common::swap16(vpb_words[i]);
memory.CopyToEmuSwapped(m_vpb_base_addr + base_idx, vpb_words, vpb_size - 0x80);
}
void ZeldaAudioRenderer::LoadInputSamples(MixingBuffer* buffer, VPB* vpb)
@ -1649,12 +1631,21 @@ void ZeldaAudioRenderer::Resample(VPB* vpb, const s16* src, MixingBuffer* dst)
vpb->current_pos_frac = pos & 0xFFF;
}
void* ZeldaAudioRenderer::GetARAMPtr(u32 offset) const
static u8* GetARAMPointerForRange(const Core::System& system, u32 aram_base_addr, u32 offset,
size_t size)
{
if (m_system.IsWii())
return HLEMemory_Get_Pointer(m_system.GetMemory(), m_aram_base_addr + offset);
if (system.IsWii())
{
const auto& memory = system.GetMemory();
return memory.GetPointerForRange(aram_base_addr + offset, size);
}
else
return reinterpret_cast<u8*>(m_system.GetDSP().GetARAMPtr()) + offset;
{
const auto& dsp = system.GetDSP();
if (offset >= dsp.GetARAMSize() || size > dsp.GetARAMSize() - offset)
return nullptr;
return system.GetDSP().GetARAMPtr() + offset;
}
}
template <typename T>
@ -1691,8 +1682,9 @@ void ZeldaAudioRenderer::DownloadPCMSamplesFromARAM(s16* dst, VPB* vpb, u16 requ
vpb->SetCurrentARAMAddr(vpb->GetBaseAddress() + vpb->GetCurrentPosition() * sizeof(T));
}
T* src_ptr = (T*)GetARAMPtr(vpb->GetCurrentARAMAddr());
u16 samples_to_download = std::min(vpb->GetRemainingLength(), (u32)requested_samples_count);
T* src_ptr = reinterpret_cast<T*>(GetARAMPointerForRange(
m_system, m_aram_base_addr, vpb->GetCurrentARAMAddr(), samples_to_download * sizeof(T)));
for (u16 i = 0; i < samples_to_download; ++i)
*dst++ = Common::FromBigEndian<T>(*src_ptr++) << (16 - 8 * sizeof(T));
@ -1826,7 +1818,8 @@ void ZeldaAudioRenderer::DownloadAFCSamplesFromARAM(s16* dst, VPB* vpb, u16 requ
void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
{
u32 addr = vpb->GetCurrentARAMAddr();
u8* src = (u8*)GetARAMPtr(addr);
u8* src = (u8*)GetARAMPointerForRange(m_system, m_aram_base_addr, addr,
block_count * vpb->samples_source_type);
vpb->SetCurrentARAMAddr(addr + (u32)block_count * vpb->samples_source_type);
for (size_t b = 0; b < block_count; ++b)
@ -1883,39 +1876,39 @@ void ZeldaAudioRenderer::DownloadRawSamplesFromMRAM(s16* dst, VPB* vpb, u16 requ
{
auto& memory = m_system.GetMemory();
u32 addr = vpb->GetBaseAddress() + vpb->current_position_h * sizeof(u16);
s16* src_ptr = (s16*)HLEMemory_Get_Pointer(memory, addr);
if (requested_samples_count > vpb->GetRemainingLength())
u32 remaining_length = vpb->GetRemainingLength();
if (requested_samples_count > remaining_length)
{
s16 last_sample = 0;
for (u16 i = 0; i < vpb->GetRemainingLength(); ++i)
*dst++ = last_sample = Common::swap16(*src_ptr++);
for (u16 i = vpb->GetRemainingLength(); i < requested_samples_count; ++i)
if (remaining_length != 0)
{
memory.CopyFromEmuSwapped(dst, addr, remaining_length * sizeof(s16));
last_sample = dst[remaining_length - 1];
}
for (u16 i = remaining_length; i < requested_samples_count; ++i)
*dst++ = last_sample;
vpb->current_position_h += vpb->GetRemainingLength();
vpb->current_position_h += remaining_length;
vpb->SetRemainingLength(0);
vpb->done = true;
}
else
{
vpb->SetRemainingLength(vpb->GetRemainingLength() - requested_samples_count);
vpb->SetRemainingLength(remaining_length - requested_samples_count);
vpb->samples_before_loop = vpb->loop_start_position_h - vpb->current_position_h;
if (requested_samples_count <= vpb->samples_before_loop)
{
for (u16 i = 0; i < requested_samples_count; ++i)
*dst++ = Common::swap16(*src_ptr++);
memory.CopyFromEmuSwapped(dst, addr, requested_samples_count * sizeof(s16));
vpb->current_position_h += requested_samples_count;
}
else
{
for (u16 i = 0; i < vpb->samples_before_loop; ++i)
*dst++ = Common::swap16(*src_ptr++);
memory.CopyFromEmuSwapped(dst, addr, vpb->samples_before_loop * sizeof(s16));
vpb->SetBaseAddress(vpb->GetLoopAddress());
src_ptr = (s16*)HLEMemory_Get_Pointer(memory, vpb->GetLoopAddress());
for (u16 i = vpb->samples_before_loop; i < requested_samples_count; ++i)
*dst++ = Common::swap16(*src_ptr++);
vpb->current_position_h = requested_samples_count - vpb->samples_before_loop;
memory.CopyFromEmuSwapped(dst + vpb->samples_before_loop, vpb->GetLoopAddress(),
vpb->current_position_h * sizeof(s16));
}
}
}

View File

@ -168,7 +168,6 @@ private:
// On the Wii, base address of the MRAM or ExRAM region replacing ARAM.
u32 m_aram_base_addr = 0;
void* GetARAMPtr(u32 offset) const;
// Downloads PCM encoded samples from ARAM. Handles looping and other
// parameters appropriately.

View File

@ -555,6 +555,13 @@ u64 MemoryManager::Read_U64(u32 address) const
return Common::swap64(value);
}
u32 MemoryManager::Read_U32_Swap(u32 address) const
{
u32 value = 0;
CopyFromEmu(&value, address, sizeof(value));
return value;
}
void MemoryManager::Write_U8(u8 value, u32 address)
{
CopyToEmu(address, &value, sizeof(value));

View File

@ -123,6 +123,7 @@ public:
u16 Read_U16(u32 address) const;
u32 Read_U32(u32 address) const;
u64 Read_U64(u32 address) const;
u32 Read_U32_Swap(u32 address) const;
void Write_U8(u8 var, u32 address);
void Write_U16(u16 var, u32 address);
void Write_U32(u32 var, u32 address);