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; return m_aram.ptr;
} }
u32 DSPManager::GetARAMSize() const
{
return m_aram.size;
}
} // end of namespace DSP } // end of namespace DSP

View File

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

View File

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

View File

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

View File

@ -21,6 +21,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/AXStructs.h" #include "Core/HW/DSPHLE/UCodes/AXStructs.h"
#include "Core/HW/Memmap.h"
#define AX_GC #define AX_GC
#include "Core/HW/DSPHLE/UCodes/AXVoice.h" #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(); 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(memory, addr); int* ptr = reinterpret_cast<int*>(memory.GetPointerForRange(addr, 3 * 5 * 32 * sizeof(int)));
u16 volume = volumes[i]; u16 volume = volumes[i];
for (u32 j = 0; j < 3; ++j) 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(); auto& memory = m_dsphle->GetSystem().GetMemory();
if (write_addr) if (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) {
*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 // Then, we read the new temp from the CPU and add to our current
// temp. // 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) 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)
@ -534,21 +539,19 @@ void AXUCode::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr)
void AXUCode::UploadLRS(u32 dst_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]); memory.CopyToEmuSwapped(dst_addr, samples, 5 * 32 * sizeof(int));
buffers[1][i] = Common::swap32(m_samples_main_right[i]); dst_addr += 5 * 32 * sizeof(int);
buffers[2][i] = Common::swap32(m_samples_main_surround[i]);
} }
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(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) for (u32 i = 0; i < 5 * 32; ++i)
{ {
int samp = (int)Common::swap32(*ptr++); 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 // apply the selected ramp
auto& memory = m_dsphle->GetSystem().GetMemory(); 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) for (u32 i = 0; i < 32 * millis; ++i)
{ {
u16 coef = Common::swap16(*ramp++); 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) 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(); 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 // 32 samples per ms, 5 ms, 2 channels
short buffer[5 * 32 * 2]; 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); 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) void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
{ {
// Upload AUXB L/R // Upload AUXB L/R
auto& memory = m_dsphle->GetSystem().GetMemory(); auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, ul_addr); memory.CopyToEmuSwapped(ul_addr, m_samples_auxB_left, sizeof(m_samples_auxB_left));
for (auto& sample : m_samples_auxB_left) memory.CopyToEmuSwapped(ul_addr + sizeof(m_samples_auxB_left), m_samples_auxB_right,
*ptr++ = Common::swap32(sample); sizeof(m_samples_auxB_right));
for (auto& sample : m_samples_auxB_right)
*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(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) for (u32 i = 0; i < 5 * 32; ++i)
{ {
int samp = Common::swap32(*ptr++); int samp = Common::swap32(*ptr++);
@ -659,7 +657,7 @@ void AXUCode::MixAUXBLR(u32 ul_addr, u32 dl_addr)
void AXUCode::SetOppositeLR(u32 src_addr) void AXUCode::SetOppositeLR(u32 src_addr)
{ {
auto& memory = m_dsphle->GetSystem().GetMemory(); 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) for (u32 i = 0; i < 5 * 32; ++i)
{ {
int inp = Common::swap32(*ptr++); 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, 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) 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 // Upload AUXA LRS
auto& memory = m_dsphle->GetSystem().GetMemory(); auto& memory = m_dsphle->GetSystem().GetMemory();
int* ptr = (int*)HLEMemory_Get_Pointer(memory, auxa_lrs_up); memory.CopyToEmuSwapped(auxa_lrs_up, m_samples_auxA_left, 32 * 5 * sizeof(int));
for (const auto& up_buffer : up_buffers) memory.CopyToEmuSwapped(auxa_lrs_up + 32 * 5 * sizeof(int), m_samples_auxA_right,
{ 32 * 5 * sizeof(int));
for (u32 j = 0; j < 32 * 5; ++j) memory.CopyToEmuSwapped(auxa_lrs_up + 2 * 32 * 5 * sizeof(int), m_samples_auxA_surround,
*ptr++ = Common::swap32(up_buffer[j]); 32 * 5 * sizeof(int));
}
// Upload AUXB S // Upload AUXB S
ptr = (int*)HLEMemory_Get_Pointer(memory, auxb_s_up); memory.CopyToEmuSwapped(auxb_s_up, m_samples_auxB_surround, sizeof(m_samples_auxB_surround));
for (auto& sample : m_samples_auxB_surround)
*ptr++ = Common::swap32(sample);
// Download buffers and addresses // Download buffers and addresses
const std::array<int*, 4> dl_buffers{ 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 // 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(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) 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++);
} }
@ -799,8 +788,7 @@ void AXUCode::CopyCmdList(u32 addr, u16 size)
} }
auto& memory = m_dsphle->GetSystem().GetMemory(); auto& memory = m_dsphle->GetSystem().GetMemory();
for (u32 i = 0; i < size; ++i, addr += 2) memory.CopyFromEmuSwapped(m_cmdlist, addr, size * sizeof(u16));
m_cmdlist[i] = HLEMemory_Read_U16(memory, addr);
} }
void AXUCode::Update() void AXUCode::Update()

View File

@ -17,6 +17,7 @@
#include "Core/HW/DSPHLE/UCodes/AXStructs.h" #include "Core/HW/DSPHLE/UCodes/AXStructs.h"
#include "Core/HW/DSPHLE/UCodes/AXVoice.h" #include "Core/HW/DSPHLE/UCodes/AXVoice.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h" #include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/HW/Memmap.h"
namespace DSP::HLE namespace DSP::HLE
{ {
@ -274,7 +275,7 @@ void AXWiiUCode::SetupProcessing(u32 init_addr)
void AXWiiUCode::AddToLR(u32 val_addr, bool neg) void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
{ {
auto& memory = m_dsphle->GetSystem().GetMemory(); 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) for (int i = 0; i < 32 * 3; ++i)
{ {
int val = (int)Common::swap32(*ptr++); int val = (int)Common::swap32(*ptr++);
@ -289,7 +290,7 @@ void AXWiiUCode::AddToLR(u32 val_addr, bool neg)
void AXWiiUCode::AddSubToLR(u32 val_addr) void AXWiiUCode::AddSubToLR(u32 val_addr)
{ {
auto& memory = m_dsphle->GetSystem().GetMemory(); 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) for (int i = 0; i < 32 * 3; ++i)
{ {
int val = (int)Common::swap32(*ptr++); 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(); auto& memory = m_dsphle->GetSystem().GetMemory();
if (write_addr) if (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) memory.CopyToEmuSwapped(write_addr, buffer, 3 * 32 * sizeof(int));
*ptr++ = Common::swap32(buffer[j]); write_addr += 3 * 32 * sizeof(int);
} }
} }
// 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(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 (auto& main_buffer : main_buffers)
{ {
for (u32 j = 0; j < 3 * 32; ++j) 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; int* auxc_buffer = aux_id ? m_samples_auxC_surround : m_samples_auxC_right;
auto& memory = m_dsphle->GetSystem().GetMemory(); auto& memory = m_dsphle->GetSystem().GetMemory();
int* upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[0]); memory.CopyToEmuSwapped(addresses[0], aux_left, 96 * sizeof(int));
for (u32 i = 0; i < 96; ++i) memory.CopyToEmuSwapped(addresses[0] + 96 * sizeof(int), aux_right, 96 * sizeof(int));
*upload_ptr++ = Common::swap32(aux_left[i]); memory.CopyToEmuSwapped(addresses[0] + 2 * 96 * sizeof(int), aux_surround, 96 * sizeof(int));
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]);
upload_ptr = (int*)HLEMemory_Get_Pointer(memory, addresses[1]); memory.CopyToEmuSwapped(addresses[1], auxc_buffer, 96 * sizeof(int));
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(auxc_buffer[i]);
u16 volume_ramp[96]; u16 volume_ramp[96];
GenerateVolumeRamp(volume_ramp, m_last_aux_volumes[aux_id], volume, 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}; 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(memory, addresses[2 + mix_i]); memory.CopyFromEmuSwapped(aux_left, addresses[2 + mix_i], 96 * sizeof(int));
for (u32 i = 0; i < 96; ++i)
aux_left[i] = Common::swap32(dl_ptr[i]);
for (u32 i = 0; i < 96; ++i) 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()); GenerateVolumeRamp(volume_ramp.data(), m_last_main_volume, volume, volume_ramp.size());
m_last_main_volume = volume; 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(); 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) if (upload_auxc)
{ {
surround_addr += sizeof(upload_buffer); memory.CopyToEmuSwapped(surround_addr + 3 * 32 * sizeof(int), m_samples_auxC_left,
for (size_t i = 0; i < upload_buffer.size(); ++i) 3 * 32 * sizeof(int));
upload_buffer[i] = Common::swap32(m_samples_auxC_left[i]);
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.
@ -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]); 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); m_mail_handler.PushMail(DSP_SYNC, true);
} }
@ -644,7 +630,7 @@ void AXWiiUCode::OutputWMSamples(u32* addresses)
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(memory, addresses[i]); u16* out = reinterpret_cast<u16*>(memory.GetPointerForRange(addresses[i], 3 * 6 * sizeof(s16)));
for (u32 j = 0; j < 3 * 6; ++j) for (u32 j = 0; j < 3 * 6; ++j)
{ {
s16 sample = ClampS16(in[j]); s16 sample = ClampS16(in[j]);

View File

@ -11,6 +11,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/HW/Memmap.h"
#include "Core/System.h" #include "Core/System.h"
namespace DSP::HLE namespace DSP::HLE
@ -18,23 +19,23 @@ namespace DSP::HLE
void ProcessGBACrypto(Memory::MemoryManager& memory, 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(memory, address); const u32 challenge = memory.Read_U32_Swap(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(memory, address + 4); const u32 logo_palette = memory.Read_U32(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(memory, address + 8); const u32 logo_speed_32 = memory.Read_U32(address + 8);
// Length of JoyBoot program to upload // 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 // 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) // 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(memory, dest_addr, key); memory.Write_U32(key, dest_addr);
// Pack palette parameters // Pack palette parameters
u16 palette_speed_coded; 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) // 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(memory, dest_addr + 4, t3); memory.Write_U32(t3, dest_addr + 4);
// Done! // Done!
DEBUG_LOG_FMT(DSPHLE, DEBUG_LOG_FMT(DSPHLE,

View File

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

View File

@ -34,95 +34,6 @@
namespace DSP::HLE 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) UCodeInterface::UCodeInterface(DSPHLE* dsphle, u32 crc)
: m_mail_handler(dsphle->AccessMailHandler()), m_dsphle(dsphle), m_crc(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; m_upload_setup_in_progress = false;
auto& memory = m_dsphle->GetSystem().GetMemory(); auto& memory = m_dsphle->GetSystem().GetMemory();
const u32 ector_crc = Common::HashEctor( const u8* pointer =
static_cast<u8*>(HLEMemory_Get_Pointer(memory, m_next_ucode.iram_mram_addr)), memory.GetPointerForRange(m_next_ucode.iram_mram_addr, m_next_ucode.iram_size);
m_next_ucode.iram_size); const u32 ector_crc = Common::HashEctor(pointer, m_next_ucode.iram_size);
if (Config::Get(Config::MAIN_DUMP_UCODE)) 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); DumpDSPCode(pointer, m_next_ucode.iram_size, ector_crc);
}
DEBUG_LOG_FMT(DSPHLE, "PrepareBootUCode {:#010x}", ector_crc); DEBUG_LOG_FMT(DSPHLE, "PrepareBootUCode {:#010x}", ector_crc);
DEBUG_LOG_FMT(DSPHLE, "DRAM -> MRAM: src {:04x} dst {:08x} size {:04x}", 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_INIT_AUDIO_SYSTEM 0x00000001
#define UCODE_NULL 0xFFFFFFFF #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 class UCodeInterface
{ {
public: public:

View File

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

View File

@ -555,6 +555,13 @@ u64 MemoryManager::Read_U64(u32 address) const
return Common::swap64(value); 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) void MemoryManager::Write_U8(u8 value, u32 address)
{ {
CopyToEmu(address, &value, sizeof(value)); CopyToEmu(address, &value, sizeof(value));

View File

@ -123,6 +123,7 @@ public:
u16 Read_U16(u32 address) const; u16 Read_U16(u32 address) const;
u32 Read_U32(u32 address) const; u32 Read_U32(u32 address) const;
u64 Read_U64(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_U8(u8 var, u32 address);
void Write_U16(u16 var, u32 address); void Write_U16(u16 var, u32 address);
void Write_U32(u32 var, u32 address); void Write_U32(u32 var, u32 address);