DMA SPU memory
This commit is contained in:
parent
2f0d972a2a
commit
efd887268b
|
@ -1,6 +1,7 @@
|
||||||
#include "../include/shared.hpp"
|
#include "../include/shared.hpp"
|
||||||
#include "include/menu.hpp"
|
#include "include/menu.hpp"
|
||||||
#include <PSX/Periphery/periphery.hpp>
|
#include <PSX/Periphery/periphery.hpp>
|
||||||
|
#include <PSX/SPU/spu.hpp>
|
||||||
|
|
||||||
namespace Menu {
|
namespace Menu {
|
||||||
using DigitalButton = Periphery::GenericController::Button;
|
using DigitalButton = Periphery::GenericController::Button;
|
||||||
|
@ -24,6 +25,7 @@ namespace Menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(controller.button.went_down(DigitalButton::Cross)) {
|
if(controller.button.went_down(DigitalButton::Cross)) {
|
||||||
|
SPU::voice[0].play();
|
||||||
this->selection_callback(this->cur_selection);
|
this->selection_callback(this->cur_selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stddef.hpp>
|
||||||
|
|
||||||
|
namespace JabyEngine {
|
||||||
|
using word_t = uint32_t;
|
||||||
|
|
||||||
|
static constexpr size_t bytes_to_words(size_t bytes) {
|
||||||
|
return bytes/sizeof(word_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t words_to_bytes(size_t words) {
|
||||||
|
return words*sizeof(word_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,22 @@ namespace JabyEngine {
|
||||||
static constexpr auto CDAudioEnable = Bit(0);
|
static constexpr auto CDAudioEnable = Bit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__declare_io_value(StatusRegister, uint16_t) {
|
||||||
|
static constexpr auto Unused = BitRange::from_to(12, 15);
|
||||||
|
static constexpr auto CaputreBufferHalf = Bit(11); // TODO: Turn into enum?; Writing to First/Second half of Capture Buffers (0=First, 1=Second)
|
||||||
|
static constexpr auto TransferBusy = Bit(10);
|
||||||
|
static constexpr auto IsDMARead = Bit(9);
|
||||||
|
static constexpr auto isDMAWrite = Bit(8);
|
||||||
|
static constexpr auto isDMA = Bit(7);
|
||||||
|
static constexpr auto isIRQ = Bit(6);
|
||||||
|
// Copies of ControlRegister
|
||||||
|
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(SRAM_Adr, uint16_t) {};
|
__declare_io_value(SRAM_Adr, uint16_t) {};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -163,8 +163,11 @@ namespace JabyEngine {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StatusRegisterIO : public IOPort<SPU_IO_Values::StatusRegister> {};
|
||||||
|
|
||||||
// TODO: The new way? v Parse with a Macro?
|
// TODO: The new way? v Parse with a Macro?
|
||||||
static auto& ControlRegister = *reinterpret_cast<ControlRegisterIO*>(0x1F801DAA);
|
static auto& ControlRegister = *reinterpret_cast<ControlRegisterIO*>(0x1F801DAA);
|
||||||
|
static auto& StatusRegister = *reinterpret_cast<StatusRegisterIO*>(0x1F801DAE);
|
||||||
static auto& SRAMTransferAdr = *reinterpret_cast<SRAMTransferAddressIO*>(0x1F801DA6);
|
static auto& SRAMTransferAdr = *reinterpret_cast<SRAMTransferAddressIO*>(0x1F801DA6);
|
||||||
|
|
||||||
//__declare_io_port(, ControlRegister, 0x1F801DAA);
|
//__declare_io_port(, ControlRegister, 0x1F801DAA);
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace JabyEngine {
|
||||||
struct DMA {
|
struct DMA {
|
||||||
static void wait() {
|
static void wait() {
|
||||||
DMA_IO::SPU.wait();
|
DMA_IO::SPU.wait();
|
||||||
|
while(SPU_IO::StatusRegister.read().is_set(SPU_IO_Values::StatusRegister::TransferBusy));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end() {
|
static void end() {
|
||||||
|
@ -16,9 +17,9 @@ namespace JabyEngine {
|
||||||
|
|
||||||
struct Receive {
|
struct Receive {
|
||||||
static void prepare() {
|
static void prepare() {
|
||||||
|
end();
|
||||||
SPU_IO::DataTransferControl.write(SPU_IO::DataTransferControl::NormalTransferMode());
|
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::Stop);
|
||||||
SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::DMAWrite);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_src(uintptr_t adr) {
|
static void set_src(uintptr_t adr) {
|
||||||
|
@ -27,9 +28,9 @@ namespace JabyEngine {
|
||||||
|
|
||||||
static void set_dst(SPU::SRAM_Adr adr) {
|
static void set_dst(SPU::SRAM_Adr adr) {
|
||||||
SPU_IO::SRAMTransferAdr.write(adr);
|
SPU_IO::SRAMTransferAdr.write(adr);
|
||||||
|
SPU_IO::ControlRegister.set_transfer_mode(SPU_IO::ControlRegister::DMAWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not adjusted yet
|
|
||||||
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) {
|
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) {
|
||||||
using SyncMode1 = DMA_IO::BCR::SyncMode1;
|
using SyncMode1 = DMA_IO::BCR::SyncMode1;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "../../../internal-include/SPU/spu_internal.hpp"
|
#include "../../../internal-include/SPU/spu_internal.hpp"
|
||||||
#include <PSX/Auxiliary/big_endian.hpp>
|
#include <PSX/Auxiliary/big_endian.hpp>
|
||||||
|
#include <PSX/Auxiliary/word_helper.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>
|
||||||
#include <stdio.hpp>
|
#include <stdio.hpp>
|
||||||
|
@ -31,32 +32,36 @@ namespace JabyEngine {
|
||||||
|
|
||||||
struct VAGState {
|
struct VAGState {
|
||||||
uint32_t voice_id;
|
uint32_t voice_id;
|
||||||
size_t bytes_left;
|
size_t words_left;
|
||||||
SPU::SRAM_Adr adr;
|
SPU::SRAM_Adr adr;
|
||||||
|
|
||||||
static constexpr VAGState create(uint32_t voice_id) {
|
static constexpr VAGState create(uint32_t voice_id) {
|
||||||
return VAGState{.voice_id = voice_id, .bytes_left = 0, .adr = 0};
|
return VAGState{.voice_id = voice_id, .words_left = 0, .adr = 0};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Progress parse_sample(State::Configuration& config, VAGState& state) {
|
static Progress parse_sample(State::Configuration& config, VAGState& state) {
|
||||||
// Load balancer?
|
const auto [words_to_use, is_last] = Helper::DMA::WordsReady::calculate(config, state.words_left);
|
||||||
|
const auto words_used = Helper::DMA::send_words<SPU::internal::DMA>(words_to_use, is_last);
|
||||||
|
|
||||||
|
state.words_left -= words_used;
|
||||||
return Progress::Error;
|
config.processed(words_used*sizeof(uint32_t));
|
||||||
|
return is_last ? Progress::Done : Progress::InProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
const auto bytes = header.get_sample_size();
|
||||||
|
|
||||||
state.bytes_left = header.get_sample_size();
|
state.words_left = bytes_to_words(bytes);
|
||||||
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()), words_to_bytes(state.words_left));
|
||||||
|
|
||||||
SPU::internal::DMA::Receive::prepare();
|
|
||||||
SPU::internal::DMA::Receive::set_dst(state.adr);
|
|
||||||
|
|
||||||
config.processed(sizeof(VAGHeader));
|
config.processed(sizeof(VAGHeader));
|
||||||
|
SPU::internal::DMA::Receive::prepare();
|
||||||
|
SPU::internal::DMA::Receive::set_dst(state.adr);
|
||||||
|
SPU::internal::DMA::Receive::set_src(reinterpret_cast<uintptr_t>(config.data_adr));
|
||||||
|
|
||||||
return Helper::exchange_and_execute_process_function(parse_sample, config, state);
|
return Helper::exchange_and_execute_process_function(parse_sample, config, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue