From ddd4a07112cbcc6bebf5123cbfa5bf3d7c2aca00 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 10 Sep 2024 22:50:05 +0200 Subject: [PATCH] Share commo DMA related code for use with SPU --- include/PSX/File/file_processor_helper.hpp | 49 +++++++++++++++++++ .../internal-include/GPU/gpu_internal.hpp | 14 +++--- .../internal-include/SPU/spu_internal.hpp | 8 +-- .../src/File/Processor/tim_processor.cpp | 43 ++-------------- .../src/File/Processor/vag_processor.cpp | 2 + src/Library/src/GPU/gpu.cpp | 8 ++- 6 files changed, 70 insertions(+), 54 deletions(-) diff --git a/include/PSX/File/file_processor_helper.hpp b/include/PSX/File/file_processor_helper.hpp index 26e8fb57..facc5af2 100644 --- a/include/PSX/File/file_processor_helper.hpp +++ b/include/PSX/File/file_processor_helper.hpp @@ -1,6 +1,7 @@ #pragma once #include "Processor/file_processor.hpp" #include "cd_file_types.hpp" +#include namespace JabyEngine { namespace FileProcessor { @@ -18,6 +19,54 @@ namespace JabyEngine { config.process_routine = reinterpret_cast(process_routine); return process_routine(config, state); } + + namespace DMA { + using words_t = size_t; + + struct WordsReady { + uint32_t words_to_use; + bool is_last; + + static constexpr WordsReady calculate(const State::Configuration& config, words_t words_left) { + const auto config_data_words = (config.data_bytes/sizeof(uint32_t)); + const auto words_to_use = (config_data_words > words_left) ? words_left : config_data_words; + + return { + .words_to_use = words_to_use, + .is_last = words_to_use == words_left + }; + } + }; + + template + static words_t send_words(words_t words_to_send, bool send_all) { + auto blocks_to_send = words_to_send/16; + while(blocks_to_send > 0) { + const auto block_send = (blocks_to_send > UI16_MAX) ? UI16_MAX : blocks_to_send; + + // Send data! + T::wait(); + T::Receive::start(blocks_to_send); + blocks_to_send -= block_send; + } + + if(send_all) { + const auto last_words_to_send = (words_to_send & 0b1111); + if(last_words_to_send > 0) { + T::wait(); + T::Receive::start(1, last_words_to_send); + } + + T::wait(); + T::end(); + return words_to_send; + } + + else { + return (words_to_send & ~0b1111); + } + } + } } } } \ No newline at end of file diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 43f1ac3e..f497734f 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -65,10 +65,10 @@ namespace JabyEngine { GPU_IO::GP1.write(GPU_IO::Command::ResetCMDBufer()); } - namespace DMA { + struct DMA { #ifdef __SUPPORT_PS3__ // The PS3 doesn't autoincrement the GPU MADR register so we have to do it - extern uintptr_t MADR; + static uintptr_t MADR; #endif // __SUPPORT_PS3__ static void wait() { @@ -79,7 +79,7 @@ namespace JabyEngine { reset_cmd_buffer(); } - namespace Receive { + struct Receive { static void prepare() { GPU_IO::GP1.write(GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU)); reset_cmd_buffer(); @@ -87,7 +87,7 @@ namespace JabyEngine { static void set_src(uintptr_t adr) { #ifdef __SUPPORT_PS3__ - MADR = adr; + DMA::MADR = adr; #else DMA_IO::GPU.set_adr(adr); #endif // __SUPPORT_PS3__ @@ -105,13 +105,13 @@ namespace JabyEngine { #ifdef __SUPPORT_PS3__ DMA_IO::GPU.set_adr(MADR); - MADR += (blockCount * wordsPerBlock) << 2; + DMA::MADR += (blockCount * wordsPerBlock) << 2; #endif // __SUPPORT_PS3__ DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPUReceive()); } - } - } + }; + }; } } } \ No newline at end of file diff --git a/src/Library/internal-include/SPU/spu_internal.hpp b/src/Library/internal-include/SPU/spu_internal.hpp index b1bbdec0..21726d8a 100644 --- a/src/Library/internal-include/SPU/spu_internal.hpp +++ b/src/Library/internal-include/SPU/spu_internal.hpp @@ -5,7 +5,7 @@ namespace JabyEngine { namespace SPU { namespace internal { - namespace DMA { + struct DMA { static void wait() { DMA_IO::SPU.wait(); } @@ -14,7 +14,7 @@ namespace JabyEngine { SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::Stop); } - namespace Receive { + struct Receive { static void prepare() { SPU_IO::DataTransferControl.write(SPU_IO::DataTransferControl::NormalTransferMode()); SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::Stop); @@ -36,8 +36,8 @@ namespace JabyEngine { DMA_IO::SPU.block_ctrl.write(DMA_IO::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); DMA_IO::SPU.channel_ctrl.write(DMA_IO::CHCHR::StartSPUReceive()); } - } - } + }; + }; } } } diff --git a/src/Library/src/File/Processor/tim_processor.cpp b/src/Library/src/File/Processor/tim_processor.cpp index 4376faac..f19e3e18 100644 --- a/src/Library/src/File/Processor/tim_processor.cpp +++ b/src/Library/src/File/Processor/tim_processor.cpp @@ -1,7 +1,6 @@ #include "../../../internal-include/GPU/gpu_internal.hpp" #include #include -#include #include namespace JabyEngine { @@ -63,44 +62,12 @@ namespace JabyEngine { } static Progress parse_data(State::Configuration& config, SimpleTIMState& state) { - const auto config_data_words = (config.data_bytes/sizeof(uint32_t)); - const auto words_to_use = (config_data_words > state.words_left) ? state.words_left : config_data_words; - bool is_last = (words_to_use == state.words_left); - auto block_count = (words_to_use >> 4); + const auto [words_to_use, is_last] = Helper::DMA::WordsReady::calculate(config, state.words_left); + const auto words_used = Helper::DMA::send_words(words_to_use, is_last); - while(block_count > 0) { - const auto block_send = (block_count > UI16_MAX) ? UI16_MAX : block_count; - - // Send data! - GPU::internal::DMA::wait(); - GPU::internal::DMA::Receive::start(block_send); - block_count -= block_send; - } - - if(is_last) { - // Send words - const auto last_words = (words_to_use & 0b1111); - if(last_words > 0) { - GPU::internal::DMA::wait(); - GPU::internal::DMA::Receive::start(1, last_words); - } - - GPU::internal::DMA::wait(); - GPU::internal::DMA::end(); - - state.words_left = 0; - config.processed(words_to_use*sizeof(uint32_t)); - - return Progress::Done; - } - - else { - const auto words_used = (words_to_use & ~0b1111); - - state.words_left -= words_used; - config.processed(words_used*sizeof(uint32_t)); - return Progress::InProgress; - } + state.words_left -= words_used; + config.processed(words_used*sizeof(uint32_t)); + return is_last ? Progress::Done : Progress::InProgress; } static Progress switch_state_parse_data(State::Configuration& config, SimpleTIMState& state) { diff --git a/src/Library/src/File/Processor/vag_processor.cpp b/src/Library/src/File/Processor/vag_processor.cpp index 9c0e77a2..5734538d 100644 --- a/src/Library/src/File/Processor/vag_processor.cpp +++ b/src/Library/src/File/Processor/vag_processor.cpp @@ -41,6 +41,8 @@ namespace JabyEngine { static Progress parse_sample(State::Configuration& config, VAGState& state) { // Load balancer? + + return Progress::Error; } diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index f4215500..30feeaf0 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -8,11 +8,9 @@ namespace JabyEngine { uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 namespace internal { - namespace DMA { - #ifdef __SUPPORT_PS3__ - uintptr_t MADR = 0; - #endif // __SUPPORT_PS3__ - } + #ifdef __SUPPORT_PS3__ + uintptr_t DMA :: MADR = 0; + #endif // __SUPPORT_PS3__ static SysCall::InterruptVerifierResult interrupt_verifier(); static void interrupt_handler(uint32_t);