Continue setup SPU

This commit is contained in:
jaby 2022-08-31 21:17:14 +02:00
parent b070dc655a
commit 48ba6a4f8b
3 changed files with 77 additions and 13 deletions

View File

@ -23,7 +23,7 @@
}
template<typename T>
static constexpr __always_inline void io_class__volatile_assign(T& dst, const T& src) {
static constexpr __always_inline void io_class__update_with(T& dst, const T& src) {
typedef decltype(dst.raw_value) DST_VALUE;
const_cast<volatile DST_VALUE&>(dst.raw_value) = src.raw_value;

View File

@ -4,6 +4,29 @@
#include <limits.h>
namespace SPU {
struct __no_align ubus32_t
{
uint16_t low;
uint16_t high;
constexpr ubus32_t() : low(0), high(0) {
}
constexpr operator uint32_t() const {
return ((this->high << 16) | this->low);
}
constexpr void operator=(uint32_t value) {
this->low = (value & 0xFFFF);
this->high = (value >> 16);
}
constexpr void operator=(ubus32_t value) volatile {
this->low = value.low;
this->high = value.high;
}
};
enum Mode {
Linear = 0,
Exponential = 1,
@ -86,9 +109,41 @@ namespace SPU {
uint32_t raw_value = 0;
};
struct __no_align KeyW {
ubus32_t raw_value;
constexpr KeyW() = default;
static constexpr KeyW All1() {
KeyW value;
value.raw_value = static_cast<uint32_t>(0xFFFFFFFF);
return value;
}
constexpr KeyW& set(size_t id) {
this->raw_value = bit::set<uint32_t>(this->raw_value, id);
return *this;
}
};
struct __no_align KeyR {
ubus32_t raw_value;
constexpr bool is_set(size_t id) const {
return bit::is_set<uint32_t>(this->raw_value, id);
}
};
struct __no_align Key {
static inline __always_inline auto& on = *reinterpret_cast<KeyW*>(0x1F801D88);
static inline __always_inline auto& off = *reinterpret_cast<KeyW*>(0x1F801D8C);
static inline __always_inline auto& state = *reinterpret_cast<KeyR*>(0x1F801D9C);
};
struct __no_align Voice {
static constexpr size_t Count = 24;
static inline __always_inline auto& Channel = reinterpret_cast<Voice(&)[Count]>(*reinterpret_cast<Voice*>(0x1f801c00));
static constexpr size_t Count = 24;
static inline __always_inline auto& Channel = reinterpret_cast<Voice(&)[Count]>(*reinterpret_cast<Voice*>(0x1f801c00));
SweepVolume volumeLeft;
SweepVolume volumeRight;

View File

@ -1,23 +1,32 @@
#include <PSX/System/IOPorts/SPU_IO.hpp>
namespace SPU {
static void clear_voice(Voice& voice) {
io_class__volatile_assign(voice.volumeLeft, SweepVolume());
io_class__volatile_assign(voice.volumeRight, SweepVolume());
static void clear_main_volume() {
static constexpr auto StartVol = SweepVolume().set_volume_mode().set_volume_percent(50.0);
io_class__volatile_assign(voice.sampleRate, SampleRate::from_HZ(0.0));
io_class__volatile_assign(voice.adsr, ADSR());
io_class__volatile_assign(voice.currentVolume, SweepVolume());
io_class__update_with(MainVolume::Left, StartVol);
io_class__update_with(MainVolume::Right, StartVol);
}
static void clear_keys() {
io_class__update_with(Key::off, KeyW::All1());
}
static void clear_voice(Voice& voice) {
io_class__update_with(voice.volumeLeft, SweepVolume());
io_class__update_with(voice.volumeRight, SweepVolume());
io_class__update_with(voice.sampleRate, SampleRate::from_HZ(0.0));
io_class__update_with(voice.adsr, ADSR());
io_class__update_with(voice.currentVolume, SweepVolume());
voice.adr = 0x200;
voice.repeatAdr = 0x200;
}
void setup() {
static constexpr auto StartVol = SweepVolume().set_volume_mode().set_volume_percent(50.0);
io_class__volatile_assign(MainVolume::Left, StartVol);
io_class__volatile_assign(MainVolume::Right, StartVol);
clear_main_volume();
clear_keys();
for(auto& voice : Voice::Channel) {
clear_voice(voice);