#ifndef __JABYENGINE_SPU_IO_HPP__ #define __JABYENGINE_SPU_IO_HPP__ #include "IOPort.hpp" #include namespace SPU { namespace Port { enum struct Mode { Linear = 0, Exponential = 1, }; enum struct Direction { Increase = 0, Decrease = 1, }; enum struct Phase { Posititve = 0, Negative = 1, }; //0..0x1F = Fast..Slow typedef uint8_t Shift; //0..3 = +7, +6, +5, +4 or -6, -7, -6, -5 typedef uint8_t Step; struct __no_align SampleRate : public ComplexBitMap { __io_port_inherit_complex_bit_map(SampleRate); static constexpr SampleRate from_HZ(double freq) { //4096 == 44100Hz constexpr double Base = (4096.0 / 44100.0); return ComplexBitMap(static_cast((freq*Base))); } }; struct __no_align SweepVolume : public ComplexBitMap { __io_port_inherit_complex_bit_map(SweepVolume); // For Volume Mode static constexpr Bit SweepEnable = 15; // 0 Volume Mode; 1 Sweep Mode static constexpr auto VolumeEnable = !SweepEnable; static constexpr BitRange Volume = BitRange::from_to(0, 14); // For Sweep Mode static constexpr Bit SweepMode = 14; static constexpr Bit SweepDirection = 13; static constexpr Bit SweepPhase = 12; static constexpr BitRange SweepShift = BitRange::from_to(2, 6); static constexpr BitRange SweepStep = BitRange::from_to(0, 1); }; struct __no_align SR : public ComplexBitMap { __io_port_inherit_complex_bit_map(SR); static constexpr Bit SustainMode = (31 - 16); static constexpr Bit SustainDirection = (30 - 16); static constexpr BitRange SustainShift = BitRange::from_to((24 - 16), (28 - 16)); static constexpr BitRange SustainStep = BitRange::from_to((22 - 16), (23 - 16)); static constexpr Bit ReleaseMode = (21 - 16); static constexpr BitRange ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); }; struct __no_align AD : public ComplexBitMap { __io_port_inherit_complex_bit_map(AD); static constexpr Bit AttackMode = 15; static constexpr BitRange AttackShift = BitRange::from_to(10, 14); static constexpr BitRange AttackStep = BitRange::from_to(8, 9); static constexpr BitRange DecayShift = BitRange::from_to(4, 7); static constexpr BitRange SustainLevel = BitRange::from_to(0, 3); }; struct __no_align Voice { IOPort volumeLeft; //Offset: 0x0 IOPort volumeRight; //Offset: 0x2 IOPort sampleRate; //Offset: 0x4; IOPort adr; //Offset: 0x6 IOPort ad; //Offset: 0x8 IOPort sr; //Offset: 0xA IOPort currentVolume; //Offset: 0xC IOPort repeatAdr; //Offset: 0xE }; struct __no_align ControlRegister : public ComplexBitMap { __io_port_inherit_complex_bit_map(ControlRegister); enum RAMTransferMode { Stop = 0, ManualWrite = 1, DMAWrite = 2, DMARead = 3 }; static constexpr Bit Enable = 15; static constexpr Bit Unmute = 14; static constexpr BitRange NoiseFrequcenyShift = BitRange::from_to(10, 13); static constexpr BitRange NoiseFrequcenyStep = BitRange::from_to(8, 9); static constexpr Bit ReverbMasterEnable = 7; static constexpr Bit IRQ9Enable = 6; static constexpr BitRange TransferMode = BitRange::from_to(4, 5); static constexpr Bit ExternalAudioReverb = 3; static constexpr Bit CDAudioReverb = 2; static constexpr Bit ExternalAudioEnable = 1; static constexpr Bit CDAudioEnable = 0; }; struct __no_align PitchModFlags : public ComplexBitMap { __io_port_inherit_complex_bit_map(PitchModFlags); static constexpr BitRange EnableBits = BitRange::from_to(1, 23); }; struct __no_align NoiseGenerator : public ComplexBitMap { __io_port_inherit_complex_bit_map(NoiseGenerator); static constexpr BitRange NoiseBits = BitRange::from_to(0, 23); }; struct __no_align EchoOn : public ComplexBitMap { __io_port_inherit_complex_bit_map(EchoOn); static constexpr BitRange EchoBits = BitRange::from_to(0, 23); }; static constexpr size_t VoiceCount = 24; namespace Key { __declare_io_port_global(ubus32_t, on, 0x1F801D88); __declare_io_port_global(ubus32_t, off, 0x1F801D8C); __declare_io_port_global(ubus32_t, status, 0x1F801D9C); } namespace MainVolume { __declare_io_port_global(SweepVolume, left, 0x1F801D80); __declare_io_port_global(SweepVolume, right, 0x1F801D82); } namespace CDVolume { __declare_io_port_global(int16_t, left, 0x1F801DB0); __declare_io_port_global(int16_t, right, 0x1F801DB2); } namespace ExternalAudioInputVolume { __declare_io_port_global(int16_t, left, 0x1F801DB4); __declare_io_port_global(int16_t, right, 0x1F801DB6); } namespace Reverb { namespace Volume { __declare_io_port_global(int16_t, left, 0x1F801D84); __declare_io_port_global(int16_t, right, 0x1F801D86); } __declare_io_port_global(uint16_t, work_area_adr, 0x1F801DA2); } __declare_io_port_global(ControlRegister, Control, 0x1F801DAA); __declare_io_port_global(uint16_t, DataTransferControl, 0x1F801DAC); __declare_io_port_global(PitchModFlags, PMON, 0x1F801D90); __declare_io_port_global(NoiseGenerator, NON, 0x1F801D94); __declare_io_port_global(EchoOn, EON, 0x1F801D98); __declare_io_port_global_array(Voice, Voices, 0x1F801C00, VoiceCount); } } #endif //!__JABYENGINE_SPU_IO_HPP__