Save state

This commit is contained in:
Björn Gaier 2024-09-06 18:32:09 +01:00
parent 740396296e
commit e7b9033f52
8 changed files with 143 additions and 32 deletions

View File

@ -3,8 +3,8 @@
namespace JabyEngine { namespace JabyEngine {
namespace SPU { namespace SPU {
using SRAM_Adr = uint16_t; using SRAM_Adr = SPU_IO::SRAM_Adr;
struct Voice { struct Voice {
size_t get_id() const { size_t get_id() const {
return reinterpret_cast<size_t>(this); return reinterpret_cast<size_t>(this);

View File

@ -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;
}
}

View File

@ -74,8 +74,33 @@ namespace JabyEngine {
} }
}; };
template<typename S, typename T = S::UnderlyingType>
struct IOPortX {
using Value = S;
S read() const {
return S{*const_cast<const volatile T*>(reinterpret_cast<const T*>(this))};
}
void write(S value) {
*const_cast<volatile T*>(reinterpret_cast<T*>(this)) = value.raw;
}
};
template<typename T>
struct IOPortX<T, T> {
T read() const {
return *const_cast<const volatile T*>(reinterpret_cast<const T*>(this));
}
void write(T value) {
*const_cast<volatile T*>(reinterpret_cast<T*>(this)) = value;
}
};
template<typename T> template<typename T>
struct IOPort { struct IOPort {
using Value = T;
T value; T value;
T read() const { T read() const {
@ -89,6 +114,7 @@ namespace JabyEngine {
template<> template<>
struct IOPort<ubus32_t> { struct IOPort<ubus32_t> {
using Value = ubus32_t;
ubus32_t value; ubus32_t value;
ubus32_t read() const { ubus32_t read() const {

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#include "ioport.hpp" #include "IOValues/spu_io_values.hpp"
#include <limits.hpp> #include <limits.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace SPU_IO { namespace SPU_IO {
using namespace SPU_IO_Values;
namespace MemoryMap { namespace MemoryMap {
static constexpr uintptr_t ADPCM = 0x01000; static constexpr uintptr_t ADPCM = 0x01000;
} }
@ -30,6 +32,9 @@ namespace JabyEngine {
typedef uint8_t Step; typedef uint8_t Step;
__declare_io_value(DataTransferControl, uint16_t) { __declare_io_value(DataTransferControl, uint16_t) {
static constexpr DataTransferControl NormalTransferMode() {
return DataTransferControl{0x0004};
}
}; };
__declare_io_value(SimpleVolume, int16_t) { __declare_io_value(SimpleVolume, int16_t) {
@ -101,27 +106,6 @@ namespace JabyEngine {
}; };
#pragma pack(pop) #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) { __declare_io_value(PMON, uint16_t) {
static constexpr auto EnableBits = BitRange::from_to(1, 23); static constexpr auto EnableBits = BitRange::from_to(1, 23);
}; };
@ -170,7 +154,22 @@ namespace JabyEngine {
return {static_cast<int16_t>(static_cast<long double>(I16_MAX)*fraction)}; return {static_cast<int16_t>(static_cast<long double>(I16_MAX)*fraction)};
} }
__declare_io_port(, ControlRegister, 0x1F801DAA); struct SRAMTransferAddressIO : public IOPortX<SRAM_Adr, SRAM_Adr> {};
struct ControlRegisterIO : public IOPortX<SPU_IO_Values::ControlRegister> {
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<ControlRegisterIO*>(0x1F801DAA);
static auto& SRAMTransferAdr = *reinterpret_cast<SRAMTransferAddressIO*>(0x1F801DA6);
//__declare_io_port(, ControlRegister, 0x1F801DAA);
__declare_io_port(, DataTransferControl, 0x1F801DAC); __declare_io_port(, DataTransferControl, 0x1F801DAC);
__declare_io_port(, PMON, 0x1F801D90); __declare_io_port(, PMON, 0x1F801D90);
__declare_io_port(, NON, 0x1F801D94); __declare_io_port(, NON, 0x1F801D94);

View File

@ -9,11 +9,18 @@
- [ ] Emulator - [ ] Emulator
- [ ] Real Hardware - [ ] Real Hardware
# Todo # TODO
- [ ] Ko-fi supporter list - [ ] Ko-fi supporter list
- [ ] Support more GTE - [ ] Support more GTE
- [X] Easy serial code swap - [X] Easy serial code swap
- [X] Support .subst files to be substituted with environment variables - [X] Support .subst files to be substituted with environment variables
- [X] Support pop-fe - [X] Support pop-fe
- [ ] PS3 PKG generation tool? - [ ] PS3 PKG generation tool?
- [ ] PS3 runtime detection? - [ ] 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?)

View File

@ -72,7 +72,7 @@ namespace JabyEngine {
#endif // __SUPPORT_PS3__ #endif // __SUPPORT_PS3__
static void wait() { static void wait() {
::JabyEngine::DMA_IO::GPU.wait(); DMA_IO::GPU.wait();
} }
static void end() { static void end() {
@ -101,7 +101,7 @@ namespace JabyEngine {
} }
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { 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__ #ifdef __SUPPORT_PS3__
DMA_IO::GPU.set_adr(MADR); DMA_IO::GPU.set_adr(MADR);

View File

@ -1,2 +1,43 @@
#pragma once #pragma once
#include <PSX/System/IOPorts/dma_io.hpp>
#include <PSX/SPU/spu.hpp>
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());
}
}
}
}
}
}

View File

@ -1,3 +1,4 @@
#include "../../../internal-include/SPU/spu_internal.hpp"
#include <PSX/Auxiliary/big_endian.hpp> #include <PSX/Auxiliary/big_endian.hpp>
#include <PSX/File/file_processor_helper.hpp> #include <PSX/File/file_processor_helper.hpp>
#include <PSX/SPU/spu.hpp> #include <PSX/SPU/spu.hpp>
@ -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) { static Progress parse_header(State::Configuration& config, VAGState& state) {
if(config.data_bytes >= sizeof(VAGHeader)) { if(config.data_bytes >= sizeof(VAGHeader)) {
const auto& header = *reinterpret_cast<const VAGHeader*>(config.data_adr); const auto& header = *reinterpret_cast<const VAGHeader*>(config.data_adr);
state.bytes_left = header.get_sample_size(); 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 config.processed(sizeof(VAGHeader));
return Progress::Error; return Helper::exchange_and_execute_process_function(parse_sample, config, state);
} }
return Progress::InProgress; return Progress::InProgress;