From 2098b4b1ca0ae140bef378f8ea68f6514a2ae745 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 5 Jan 2026 15:54:14 +0100 Subject: [PATCH] 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. --- Source/Core/Core/HW/DSP.cpp | 5 + Source/Core/Core/HW/DSP.h | 1 + Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp | 68 ++++++----- Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp | 99 +++++++--------- Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp | 80 ++++++------- Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp | 48 +++----- Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp | 15 +-- Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp | 12 +- Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp | 99 +--------------- Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h | 17 --- Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp | 117 +++++++++---------- Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h | 1 - Source/Core/Core/HW/Memmap.cpp | 7 ++ Source/Core/Core/HW/Memmap.h | 1 + 14 files changed, 214 insertions(+), 356 deletions(-) diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index 17672b1924d..3abea2bea8e 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -603,4 +603,9 @@ u8* DSPManager::GetARAMPtr() const return m_aram.ptr; } +u32 DSPManager::GetARAMSize() const +{ + return m_aram.size; +} + } // end of namespace DSP diff --git a/Source/Core/Core/HW/DSP.h b/Source/Core/Core/HW/DSP.h index d65116468c4..995ffec8cb9 100644 --- a/Source/Core/Core/HW/DSP.h +++ b/Source/Core/Core/HW/DSP.h @@ -97,6 +97,7 @@ public: // Debugger Helper u8* GetARAMPtr() const; + u32 GetARAMSize() const; void UpdateAudioDMA(); void UpdateDSPSlice(int cycles); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp index 973ee7e4ec9..5499ed8e453 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp @@ -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) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp index c0fe5a3a496..6e7c1fe9954 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp @@ -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 ASndUCode::ReadSampleMono8Bits() const diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index 6beeace5831..8b9a0bc6081 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -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(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(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(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( + 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(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(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 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 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(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() diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index 04dee941ca0..8d87e68d8bf 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -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(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(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( + 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 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(memory.GetPointerForRange(addresses[i], 3 * 6 * sizeof(s16))); for (u32 j = 0; j < 3 * 6; ++j) { s16 sample = ClampS16(in[j]); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp index 552f8ca8434..bd66ca38607 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp @@ -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, diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp index e971063a219..c512b206eaa 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp @@ -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(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(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); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp index 58410c06247..04e783c26b2 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp @@ -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(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}", diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h index 67841cf8115..80d056ac6ec 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h @@ -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: diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp index 70ea293cdd2..7334b5c01a7 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp @@ -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 resampling_coeffs; - for (size_t i = 0; i < 0x100; ++i) - resampling_coeffs[i] = Common::swap16(data_ptr[i]); + std::array resampling_coeffs{}; + memory.CopyFromEmuSwapped(resampling_coeffs.data(), address, sizeof(resampling_coeffs)); m_renderer.SetResamplingCoeffs(std::move(resampling_coeffs)); - std::array const_patterns; - for (size_t i = 0; i < 0x100; ++i) - const_patterns[i] = Common::swap16(data_ptr[0x100 + i]); + std::array 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 sine_table; - for (size_t i = 0; i < 0x80; ++i) - sine_table[i] = Common::swap16(data_ptr[0x200 + i]); + std::array 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 afc_coeffs; - for (size_t i = 0; i < 0x20; ++i) - afc_coeffs[i] = Common::swap16(afc_coeffs_ptr[i]); + std::array 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(&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(&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(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 @@ -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(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(*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)); } } } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h index 4ebc775ebe6..ce712519d52 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h @@ -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. diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 675e9420096..6556199a0a7 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -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)); diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h index e0708605dbf..596abfa3d69 100644 --- a/Source/Core/Core/HW/Memmap.h +++ b/Source/Core/Core/HW/Memmap.h @@ -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);