Save state

This commit is contained in:
jaby 2024-09-06 18:32:09 +01:00
parent 0dcd2b71a6
commit a4426ad5d2
8 changed files with 143 additions and 32 deletions

View File

@ -3,7 +3,7 @@
namespace JabyEngine {
namespace SPU {
using SRAM_Adr = uint16_t;
using SRAM_Adr = SPU_IO::SRAM_Adr;
struct Voice {
size_t get_id() const {

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>
struct IOPort {
using Value = T;
T value;
T read() const {
@ -89,6 +114,7 @@ namespace JabyEngine {
template<>
struct IOPort<ubus32_t> {
using Value = ubus32_t;
ubus32_t value;
ubus32_t read() const {

View File

@ -1,9 +1,11 @@
#pragma once
#include "ioport.hpp"
#include "IOValues/spu_io_values.hpp"
#include <limits.hpp>
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<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(, PMON, 0x1F801D90);
__declare_io_port(, NON, 0x1F801D94);

View File

@ -9,7 +9,7 @@
- [ ] Emulator
- [ ] Real Hardware
# Todo
# TODO
- [ ] Ko-fi supporter list
- [ ] Support more GTE
- [X] Easy serial code swap
@ -17,3 +17,10 @@
- [X] Support pop-fe
- [ ] PS3 PKG generation tool?
- [ ] 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__
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);

View File

@ -1,2 +1,43 @@
#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/File/file_processor_helper.hpp>
#include <PSX/SPU/spu.hpp>
@ -38,6 +39,11 @@ 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<const VAGHeader*>(config.data_adr);
@ -45,8 +51,11 @@ namespace JabyEngine {
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);
// TODO: Parse samples
return Progress::Error;
SPU::internal::DMA::Receive::prepare();
SPU::internal::DMA::Receive::set_dst(state.adr);
config.processed(sizeof(VAGHeader));
return Helper::exchange_and_execute_process_function(parse_sample, config, state);
}
return Progress::InProgress;