From a4426ad5d2f4e070b7e83a80d4ed337ef58a911d Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 6 Sep 2024 18:32:09 +0100 Subject: [PATCH] Save state --- include/PSX/SPU/spu.hpp | 4 +- .../System/IOPorts/IOValues/spu_io_values.hpp | 29 ++++++++++++ include/PSX/System/IOPorts/ioport.hpp | 26 +++++++++++ include/PSX/System/IOPorts/spu_io.hpp | 45 +++++++++---------- readme.md | 11 ++++- .../internal-include/GPU/gpu_internal.hpp | 4 +- .../internal-include/SPU/spu_internal.hpp | 41 +++++++++++++++++ .../src/File/Processor/vag_processor.cpp | 15 +++++-- 8 files changed, 143 insertions(+), 32 deletions(-) create mode 100644 include/PSX/System/IOPorts/IOValues/spu_io_values.hpp diff --git a/include/PSX/SPU/spu.hpp b/include/PSX/SPU/spu.hpp index f18f2f63..ab92464e 100644 --- a/include/PSX/SPU/spu.hpp +++ b/include/PSX/SPU/spu.hpp @@ -3,8 +3,8 @@ namespace JabyEngine { namespace SPU { - using SRAM_Adr = uint16_t; - + using SRAM_Adr = SPU_IO::SRAM_Adr; + struct Voice { size_t get_id() const { return reinterpret_cast(this); diff --git a/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp b/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp new file mode 100644 index 00000000..91491b61 --- /dev/null +++ b/include/PSX/System/IOPorts/IOValues/spu_io_values.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "../ioport.hpp" + +namespace JabyEngine { + namespace SPU_IO_Values { + __declare_io_value(ControlRegister, uint16_t) { + enum RAMTransferMode { + Stop = 0, + ManualWrite = 1, + DMAWrite = 2, + DMARead = 3 + }; + + static constexpr auto Enable = Bit(15); + static constexpr auto Unmute = Bit(14); + static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13); + static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9); + static constexpr auto ReverbMasterEnable = Bit(7); + static constexpr auto IRQ9Enable = Bit(6); + static constexpr auto TransferMode = BitRange::from_to(4, 5); + static constexpr auto ExternalAudioReverb = Bit(3); + static constexpr auto CDAudioReverb = Bit(2); + static constexpr auto ExternalAudioEnable = Bit(1); + static constexpr auto CDAudioEnable = Bit(0); + }; + + using SRAM_Adr = uint16_t; + } +} \ No newline at end of file diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 5ae35ff9..c8bc09bd 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -74,8 +74,33 @@ namespace JabyEngine { } }; + template + struct IOPortX { + using Value = S; + + S read() const { + return S{*const_cast(reinterpret_cast(this))}; + } + + void write(S value) { + *const_cast(reinterpret_cast(this)) = value.raw; + } + }; + + template + struct IOPortX { + T read() const { + return *const_cast(reinterpret_cast(this)); + } + + void write(T value) { + *const_cast(reinterpret_cast(this)) = value; + } + }; + template struct IOPort { + using Value = T; T value; T read() const { @@ -89,6 +114,7 @@ namespace JabyEngine { template<> struct IOPort { + using Value = ubus32_t; ubus32_t value; ubus32_t read() const { diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index bc7cac38..737c378c 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -1,9 +1,11 @@ #pragma once -#include "ioport.hpp" +#include "IOValues/spu_io_values.hpp" #include namespace JabyEngine { namespace SPU_IO { + using namespace SPU_IO_Values; + namespace MemoryMap { static constexpr uintptr_t ADPCM = 0x01000; } @@ -30,6 +32,9 @@ namespace JabyEngine { typedef uint8_t Step; __declare_io_value(DataTransferControl, uint16_t) { + static constexpr DataTransferControl NormalTransferMode() { + return DataTransferControl{0x0004}; + } }; __declare_io_value(SimpleVolume, int16_t) { @@ -101,27 +106,6 @@ namespace JabyEngine { }; #pragma pack(pop) - __declare_io_value(ControlRegister, uint16_t) { - enum RAMTransferMode { - Stop = 0, - ManualWrite = 1, - DMAWrite = 2, - DMARead = 3 - }; - - static constexpr auto Enable = Bit(15); - static constexpr auto Unmute = Bit(14); - static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13); - static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9); - static constexpr auto ReverbMasterEnable = Bit(7); - static constexpr auto IRQ9Enable = Bit(6); - static constexpr auto TransferMode = BitRange::from_to(4, 5); - static constexpr auto ExternalAudioReverb = Bit(3); - static constexpr auto CDAudioReverb = Bit(2); - static constexpr auto ExternalAudioEnable = Bit(1); - static constexpr auto CDAudioEnable = Bit(0); - }; - __declare_io_value(PMON, uint16_t) { static constexpr auto EnableBits = BitRange::from_to(1, 23); }; @@ -170,7 +154,22 @@ namespace JabyEngine { return {static_cast(static_cast(I16_MAX)*fraction)}; } - __declare_io_port(, ControlRegister, 0x1F801DAA); + struct SRAMTransferAddressIO : public IOPortX {}; + + struct ControlRegisterIO : public IOPortX { + using TransferMode = Value::RAMTransferMode; + + void set_transfer_mode(TransferMode mode) { + this->write(this->read().set(ControlRegister::TransferMode.with(mode))); + while(this->read().get(ControlRegister::TransferMode) != mode); + } + }; + + // TODO: The new way? v Parse with a Macro? + static auto& ControlRegister = *reinterpret_cast(0x1F801DAA); + static auto& SRAMTransferAdr = *reinterpret_cast(0x1F801DA6); + + //__declare_io_port(, ControlRegister, 0x1F801DAA); __declare_io_port(, DataTransferControl, 0x1F801DAC); __declare_io_port(, PMON, 0x1F801D90); __declare_io_port(, NON, 0x1F801D94); diff --git a/readme.md b/readme.md index e8ce7758..e2659b0c 100644 --- a/readme.md +++ b/readme.md @@ -9,11 +9,18 @@ - [ ] Emulator - [ ] Real Hardware -# Todo +# TODO - [ ] Ko-fi supporter list - [ ] Support more GTE - [X] Easy serial code swap - [X] Support .subst files to be substituted with environment variables - [X] Support pop-fe - [ ] PS3 PKG generation tool? -- [ ] PS3 runtime detection? \ No newline at end of file +- [ ] PS3 runtime detection? +- [ ] Move DMA code to public include for custom loading of files? + - [ ] Maybe make it an interface with SPU/GPU as a specification...? + - [ ] Could be empty classes that the linker maps to 0 or somewhere + - [ ] Could be a all static struct (I like that better; We are not Nicolas Noble) + - [ ] Redo the IO ports again...? +- [ ] Support better file loading with threads + - [ ] Loading Screen with GPU IO? (Does DMA and IO work together?) \ 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 dfdbcfcd..43f1ac3e 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -72,7 +72,7 @@ namespace JabyEngine { #endif // __SUPPORT_PS3__ static void wait() { - ::JabyEngine::DMA_IO::GPU.wait(); + DMA_IO::GPU.wait(); } static void end() { @@ -101,7 +101,7 @@ namespace JabyEngine { } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { - typedef DMA_IO::BCR::SyncMode1 SyncMode1; + using SyncMode1 = DMA_IO::BCR::SyncMode1; #ifdef __SUPPORT_PS3__ DMA_IO::GPU.set_adr(MADR); diff --git a/src/Library/internal-include/SPU/spu_internal.hpp b/src/Library/internal-include/SPU/spu_internal.hpp index 77e81455..d47508fb 100644 --- a/src/Library/internal-include/SPU/spu_internal.hpp +++ b/src/Library/internal-include/SPU/spu_internal.hpp @@ -1,2 +1,43 @@ #pragma once +#include +#include +namespace JabyEngine { + namespace SPU { + namespace internal { + namespace DMA { + static void wait() { + DMA_IO::SPU.wait(); + } + + static void end() { + SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::Stop); + } + + namespace Receive { + static void prepare() { + SPU_IO::DataTransferControl.write(SPU_IO::DataTransferControl::NormalTransferMode()); + SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::Stop); + SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::DMAWrite); + } + + static void set_src(SPU::SRAM_Adr adr) { + DMA_IO::SPU.set_adr(adr); + } + + static void set_dst(SPU::SRAM_Adr adr) { + SPU_IO::SRAMTransferAdr.write(adr); + } + + // Not adjusted yet + static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { + using SyncMode1 = DMA_IO::BCR::SyncMode1; + + 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/vag_processor.cpp b/src/Library/src/File/Processor/vag_processor.cpp index 2a5a023c..66eaa616 100644 --- a/src/Library/src/File/Processor/vag_processor.cpp +++ b/src/Library/src/File/Processor/vag_processor.cpp @@ -1,3 +1,4 @@ +#include "../../../internal-include/SPU/spu_internal.hpp" #include #include #include @@ -38,15 +39,23 @@ namespace JabyEngine { } }; + static Progress parse_sample(State::Configuration& config, VAGState& state) { + // Load balancer? + + } + static Progress parse_header(State::Configuration& config, VAGState& state) { if(config.data_bytes >= sizeof(VAGHeader)) { const auto& header = *reinterpret_cast(config.data_adr); state.bytes_left = header.get_sample_size(); - state.adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), state.bytes_left); + state.adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), state.bytes_left); + + SPU::internal::DMA::Receive::prepare(); + SPU::internal::DMA::Receive::set_dst(state.adr); - // TODO: Parse samples - return Progress::Error; + config.processed(sizeof(VAGHeader)); + return Helper::exchange_and_execute_process_function(parse_sample, config, state); } return Progress::InProgress;