#ifndef __JABYENGINE_CD_IO_HPP__ #define __JABYENGINE_CD_IO_HPP__ #include "ioport.hpp" namespace JabyEngine { namespace CD_IO { enum Index { Index0 = 0, Index1 = 1, Index2 = 2, Index3 = 3, }; struct CDDAVolume { typedef uint8_t Type; static constexpr uint8_t Off = 0x0; static constexpr uint8_t Default = 0x80; static constexpr uint8_t Max = 0xFF; }; typedef struct IndexStatus : public ComplexBitMap { static constexpr auto PortIndex = BitRange::from_to(0, 1); static constexpr auto HasXAFifoData = Bit(2); static constexpr auto IsParameterFifoEmpty = Bit(3); static constexpr auto HasParameterFifoSpace = Bit(4); static constexpr auto HasResponseFifoData = Bit(5); static constexpr auto HasDataFifoData = Bit(6); static constexpr auto IsTransmissionBusy = Bit(7); } IndexStatus_t; struct InterruptEnable : public ComplexBitMap { static constexpr auto InterruptTypValue = BitRange::from_to(0, 2); static constexpr auto InterruptExtended = BitRange::from_to(0, 4); static constexpr auto UnknownIRQ = Bit(3); static constexpr auto CommandStartIRQ = Bit(4); }; typedef InterruptEnable InterruptFlag; struct Request : public ComplexBitMap { static constexpr auto WantCommandStartIRQ = Bit(5); static constexpr auto WantData = Bit(7); }; struct SoundMapCoding : public ComplexBitMap { static constexpr auto Stereo = Bit(0); static constexpr auto Mono = !Stereo; static constexpr auto SampleRate_18900hz = Bit(2); static constexpr auto SampleRate_37800hz = !SampleRate_18900hz; static constexpr auto BitsPerSample8 = Bit(4); static constexpr auto BitsPerSample4 = !BitsPerSample8; static constexpr auto Emphasis = Bit(6); }; struct AudioVolumeApply : public ComplexBitMap { static constexpr auto Mute = Bit(0); static constexpr auto ApplyChanges = Bit(5); }; struct Interrupt { static void enable(VolatileBitMapPOD& port) { port.write(InterruptEnable::InterruptTypValue.max()); } static void enable_extended(VolatileBitMapPOD& port) { port.write({InterruptEnable::with(InterruptEnable::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)}); } static uint8_t get_type(const VolatileBitMapPOD& port) { return port.read().get_value(InterruptFlag::InterruptTypValue); } static void ack(VolatileBitMapPOD& port) { port.write(InterruptFlag::InterruptTypValue.max()); } static void ack_extended(VolatileBitMapPOD& port) { port.write({InterruptFlag::with(InterruptFlag::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)}); } }; __declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800); static constexpr auto IORegister1Adr = 0x1F801801; static constexpr auto IORegister2Adr = 0x1F801802; static constexpr auto IORegister3Adr = 0x1F801803; typedef VolatilePOD ResponseFifo_t; typedef VolatilePOD CommandFifo_t; typedef VolatilePOD DataFifo_t; typedef VolatilePOD DataFifo16_t; typedef VolatilePOD ParameterFifo_t; typedef VolatilePOD SoundMapDataOut_t; typedef VolatilePOD VolumeRegister_t; typedef VolatileBitMapPOD InterruptEnableRegister_t; typedef VolatileBitMapPOD InterruptFlagRegister_t; typedef VolatileBitMapPOD RequestRegister_t; typedef VolatileBitMapPOD SoundMapCodingInfo_t; typedef VolatileBitMapPOD AudioVolumeApplyChange_t; #define __declare_index_io_port(type, name, adr) __cast_io_adr_with_type(inline, type, name, adr) #define __declare_index_io_port_const(type, name, adr) __cast_io_adr_with_type(const inline, type, name, adr) struct PortIndex0 { __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); __declare_index_io_port( CommandFifo_t, CommandFifo, IORegister1Adr); __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); __declare_index_io_port( ParameterFifo_t, ParameterFifo, IORegister2Adr); __declare_index_io_port_const(InterruptEnableRegister_t, InterruptEnableRegister, IORegister3Adr); __declare_index_io_port( RequestRegister_t, RequestRegister, IORegister3Adr); static void change_to() { IndexStatus.write({static_cast(Index::Index0)}); } }; struct PortIndex1 { __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); __declare_index_io_port( SoundMapDataOut_t, SoundMapDataOut, IORegister1Adr); __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); __declare_index_io_port( InterruptEnableRegister_t, InterruptEnableRegister, IORegister2Adr); __declare_index_io_port(InterruptFlagRegister_t, InterruptFlagRegister, IORegister3Adr); static void change_to() { IndexStatus.write({static_cast(Index::Index1)}); } }; struct PortIndex2 { __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); __declare_index_io_port( SoundMapCodingInfo_t, SoundMapCodingInfo, IORegister1Adr); __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); __declare_index_io_port( VolumeRegister_t, LeftCD2LeftSPU, IORegister2Adr); __declare_index_io_port_const(InterruptEnableRegister_t, InterruptEnableRegister, IORegister3Adr); __declare_index_io_port( VolumeRegister_t, LeftCD2RightSPU, IORegister3Adr); static void change_to() { IndexStatus.write({static_cast(Index::Index2)}); } }; struct PortIndex3 { __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); __declare_index_io_port( VolumeRegister_t, RightCD2RightSPU, IORegister1Adr); __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); __declare_index_io_port( VolumeRegister_t, RightCD2LeftSPU, IORegister1Adr); __declare_index_io_port_const(InterruptFlagRegister_t, InterruptFlagRegister, IORegister3Adr); __declare_index_io_port( AudioVolumeApplyChange_t, AudioVolumeApplyChange, IORegister3Adr); static void change_to() { IndexStatus.write({static_cast(Index::Index3)}); } }; #undef __declare_index_io_port #undef __declare_index_io_port_const } } #endif //!__JABYENGINE_CD_IO_HPP__