#pragma once #include "ioport.hpp" #include namespace JabyEngine { namespace SPU_IO_Values { namespace MemoryMap { static constexpr uintptr_t ADPCM = 0x01000; static constexpr uintptr_t End = 0x7FFFF; } __declare_io_struct(AD, uint16_t) { static constexpr auto AttackMode = Bit(15); static constexpr auto AttackShift = BitRange::from_to(10, 14); static constexpr auto AttackStep = BitRange::from_to(8, 9); static constexpr auto DecayShift = BitRange::from_to(4, 7); static constexpr auto SustainLevel = BitRange::from_to(0, 3); static constexpr AD none() { return AD{0}; } }; __declare_io_struct(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_struct(DataTransferControl, uint16_t) { static constexpr DataTransferControl NormalTransferMode() { return DataTransferControl{0x0004}; } }; __declare_io_struct(Echo, uint32_t) { static constexpr auto EchoBits = BitRange::from_to(0, 23); static constexpr Echo AllOff() { return Echo{0}; } }; __declare_io_struct(KeyOff, uint32_t) { static constexpr KeyOff for_specific(uint32_t id) { return KeyOff{1u << id}; } static constexpr KeyOff all() { return KeyOff{UI32_MAX}; } }; __declare_io_struct(KeyOn, uint32_t) { static constexpr KeyOn for_specific(uint32_t id) { return KeyOn{1u << id}; } static constexpr KeyOn all() { return KeyOn{UI32_MAX}; } }; __declare_io_struct(KeyStatus, uint32_t) { }; __declare_io_struct(Noise, uint16_t) { static constexpr auto NoiseBits = BitRange::from_to(0, 23); static constexpr Noise AllOff() { return Noise{0}; } }; __declare_io_struct(PitchModulation, uint32_t) { static constexpr auto EnableBits = BitRange::from_to(1, 23); static constexpr PitchModulation AllOff() { return PitchModulation{0}; } }; __declare_io_struct(SampleRate, uint16_t) { static constexpr SampleRate stop() { return SampleRate{0}; } static constexpr SampleRate from_HZ(uint32_t freq) { constexpr uint32_t Base1024Hz = static_cast((4096.0/44100.0)*1024.0); return SampleRate{static_cast((freq >> 10)*Base1024Hz)}; } static constexpr SampleRate from_HZ(double freq) { //4096 == 44100Hz constexpr double Base = (4096.0 / 44100.0); return SampleRate{static_cast((freq*Base))}; } }; __declare_io_struct(SimpleVolume, int16_t) { static constexpr auto MaxVolume = I16_MAX; static constexpr SimpleVolume mute() { return SimpleVolume{0}; } constexpr operator int16_t() const { return this->raw; } }; static constexpr SimpleVolume operator""_vol(long double fraction) { return {static_cast(static_cast(SimpleVolume::MaxVolume)*fraction)}; } __declare_io_struct(SR, uint16_t) { static constexpr auto SustainMode = Bit(31 - 16); static constexpr auto SustainDirection = Bit(30 - 16); static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16)); static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16)); static constexpr auto ReleaseMode = Bit(21 - 16); static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); static constexpr SR none() { return SR{0}; } }; __declare_io_struct(SRAMAdr, uint16_t) { static constexpr SRAMAdr null() { return SRAMAdr{0x0}; } static constexpr SRAMAdr adpcm_start() { return SRAMAdr{MemoryMap::ADPCM}; } }; __declare_io_struct(StatusRegister, uint16_t) { enum CapureBufferHalf { First = 0, Second = 1 }; static constexpr auto Unused = BitRange::from_to(12, 15); static constexpr auto CaputreBufferHalf = Bit(11); 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_struct(SweepVolume, int16_t) { struct VolumeMode { static constexpr auto MaxVolume = (I16_MAX >> 1); static constexpr auto EnableSweep = Bit(15); static constexpr auto Enable = !EnableSweep; static constexpr auto Volume = BitRange::from_to(0, 14); }; struct SweepMode { enum Mode { Linear = 0, Exponential = 1, }; enum Direction { Increase = 0, Decrease = 1, }; enum Phase { Posititve = 0, Negative = 1, }; static constexpr auto Mode = Bit(14); static constexpr auto Direction = Bit(13); static constexpr auto Phase = Bit(12); static constexpr auto Shift = BitRange::from_to(2, 6); static constexpr auto Step = BitRange::from_to(0, 1); }; static constexpr SweepVolume create(SimpleVolume volume) { return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1)); } static constexpr SweepVolume mute() { return SweepVolume{0}; } }; } }