#pragma once #include "IOValues/spu_io_values.hpp" #include namespace JabyEngine { namespace SPU_IO { static constexpr size_t VoiceCount = 24; static constexpr size_t ReverbCount = 1; struct ControlRegisterIO : public IOPort { using TransferMode = Value::RAMTransferMode; void set_transfer_mode(TransferMode mode) { this->write(this->read().set(Value::ControlRegister::TransferMode.with(mode))); while(this->read().get(Value::ControlRegister::TransferMode) != mode); } }; using ADIO = IOPort; using DataTransferControlIO = IOPort; using EchoIO = IOPort32; using KeyOffIO = IOPort32; using KeyOnIO = IOPort32; using KeyStatusIO = IOPort32; using NoiseIO = IOPort; using PitchModulationIO = IOPort32; using SampleRateIO = IOPort; using SimpleVolumeIO = IOPort; using StatusRegisterIO = IOPort; using SRIO = IOPort; using SRAMAdrIO = IOPort; using SweepVolumeIO = IOPort; #pragma pack(push, 1) struct Voice { SweepVolumeIO volumeLeft; //Offset: 0x0 SweepVolumeIO volumeRight; //Offset: 0x2 SampleRateIO sampleRate; //Offset: 0x4; SRAMAdrIO adr; //Offset: 0x6 ADIO ad; //Offset: 0x8 SRIO sr; //Offset: 0xA SimpleVolumeIO adsr_volume; //Offset: 0xC SRAMAdrIO repeatAdr; //Offset: 0xE }; #pragma pack(pop) // Required so GCC does not create guards for the ReverbON reference #define __eon_declaration __new_declare_io_port(EchoIO, 0x1F801D98) static auto& Voice = __new_declare_io_port_array(struct Voice, VoiceCount, 0x1F801C00); static auto& PMON = __new_declare_io_port(PitchModulationIO, 0x1F801D90); static auto& NON = __new_declare_io_port(NoiseIO, 0x1F801D94); static auto& EON = __eon_declaration; static auto& SRAMTransferAdr = __new_declare_io_port(SRAMAdrIO, 0x1F801DA6); static auto& ControlRegister = __new_declare_io_port(ControlRegisterIO, 0x1F801DAA); static auto& DataTransferControl = __new_declare_io_port(DataTransferControlIO, 0x1F801DAC); static auto& StatusRegister = __new_declare_io_port(StatusRegisterIO, 0x1F801DAE); struct CDVolume { static inline auto& Left = __new_declare_io_port(SimpleVolumeIO, 0x1F801DB0); static inline auto& Right = __new_declare_io_port(SimpleVolumeIO, 0x1F801DB2); }; struct ExternalAudioInputVolume { static inline auto& Left = __new_declare_io_port(SimpleVolumeIO, 0x1F801DB4); static inline auto& Right = __new_declare_io_port(SimpleVolumeIO, 0x1F801DB6); }; struct Key { static inline auto& On = __new_declare_io_port(KeyOnIO, 0x1F801D88); static inline auto& Off = __new_declare_io_port(KeyOffIO, 0x1F801D8C); static inline auto& Status = __new_declare_io_port(KeyStatusIO, 0x1F801D9C); }; struct MainVolume { static inline auto& Left = __new_declare_io_port(SweepVolumeIO, 0x1F801D80); static inline auto& Right = __new_declare_io_port(SweepVolumeIO, 0x1F801D82); }; struct Reverb { struct Volume { static inline auto& Left = __new_declare_io_port(SimpleVolumeIO, 0x1F801D84); static inline auto& Right = __new_declare_io_port(SimpleVolumeIO, 0x1F801D86); }; static inline auto& On = __eon_declaration; static inline auto& WorkAreaAdr = __new_declare_io_port(SRAMAdrIO, 0x1F801DA2); }; } }