From 32682aa2f09411d9cfde703249123ca7e19c3ac4 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 22 Sep 2023 18:52:31 +0200 Subject: [PATCH] Support CD IO and start removing old IOPort --- include/PSX/System/IOPorts/cd_io.hpp | 159 ++++++++++-------- include/PSX/System/IOPorts/gpu_io.hpp | 3 + include/PSX/System/IOPorts/ioport.hpp | 130 -------------- .../internal-include/CD/cd_internal.hpp | 10 +- src/Library/src/CD/cd.cpp | 12 +- 5 files changed, 101 insertions(+), 213 deletions(-) diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index f981aaac..bfe80a71 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -31,7 +31,7 @@ namespace JabyEngine { static constexpr uint8_t Max = 0xFF; }; - __declare_io_type(Mode, uint8_t, + __new_declare_io_value(Mode, uint8_t) { static constexpr auto DoubleSpeed = Bit(7); static constexpr auto SingleSpeed = !DoubleSpeed; static constexpr auto XADPCM = Bit(6); @@ -41,9 +41,13 @@ namespace JabyEngine { static constexpr auto AudioPlayIRQ = Bit(2); static constexpr auto AutoPauseTrack = Bit(1); static constexpr auto CDDA = Bit(0); - ); - __declare_io_type(IndexStatus, uint8_t, + operator uint8_t() const { + return this->raw; + } + }; + + __new_declare_io_value(IndexStatus, uint8_t) { static constexpr auto PortIndex = BitRange::from_to(0, 1); static constexpr auto HasXAFifoData = Bit(2); static constexpr auto IsParameterFifoEmpty = Bit(3); @@ -51,30 +55,31 @@ namespace JabyEngine { static constexpr auto HasResponseFifoData = Bit(5); static constexpr auto HasDataFifoData = Bit(6); static constexpr auto IsTransmissionBusy = Bit(7); - ); + }; - __declare_io_type(InterruptEnable, uint8_t, + __new_declare_io_value(InterruptEnable, uint8_t) { 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_v InterruptFlag_v; + }; + using InterruptFlag = InterruptEnable; - __declare_io_type(Request, uint8_t, + + __new_declare_io_value(Request, uint8_t) { static constexpr auto WantCommandStartIRQ = Bit(5); static constexpr auto WantData = Bit(7); - void want_data() { - this->raw_value = static_cast(Self::WantData); + static Request want_data() { + return Request{static_cast(Request::WantData)}; } - void reset() { - this->raw_value = 0; + static Request reset() { + return Request{0}; } - ); + }; - __declare_io_type(SoundMapCoding, uint8_t, + __new_declare_io_value(SoundMapCoding, uint8_t) { static constexpr auto Stereo = Bit(0); static constexpr auto Mono = !Stereo; static constexpr auto SampleRate_18900hz = Bit(2); @@ -82,23 +87,33 @@ namespace JabyEngine { static constexpr auto BitsPerSample8 = Bit(4); static constexpr auto BitsPerSample4 = !BitsPerSample8; static constexpr auto Emphasis = Bit(6); - ); + }; - __declare_io_type(AudioVolumeApply, uint8_t, + __new_declare_io_value(AudioVolumeApply, uint8_t) { static constexpr auto Mute = Bit(0); static constexpr auto ApplyChanges = Bit(5); - ); + }; - __declare_io_type(ResponseFifo, uint8_t,); - __declare_io_type(CommandFifo, uint8_t,); - __declare_io_type(DataFifo, uint8_t,); - __declare_io_type(DataFifo16, uint16_t,); - __declare_io_type(ParameterFifo, uint8_t,); - __declare_io_type(SoundMapDataOut, uint8_t,); - __declare_io_type(LeftCD2LeftSPU, CDDAVolume::Type,); - __declare_io_type(LeftCD2RightSPU, CDDAVolume::Type,); - __declare_io_type(RightCD2RightSPU,CDDAVolume::Type,); - __declare_io_type(RightCD2LeftSPU, CDDAVolume::Type,); + __new_declare_io_value(ResponseFifo, uint8_t) { + }; + __new_declare_io_value(CommandFifo, uint8_t) { + }; + __new_declare_io_value(DataFifo, uint8_t) { + }; + __new_declare_io_value(DataFifo16, uint16_t) { + }; + __new_declare_io_value(ParameterFifo, uint8_t) { + }; + __new_declare_io_value(SoundMapDataOut, uint8_t) { + }; + __new_declare_io_value(LeftCD2LeftSPU, CDDAVolume::Type) { + }; + __new_declare_io_value(LeftCD2RightSPU, CDDAVolume::Type) { + }; + __new_declare_io_value(RightCD2RightSPU, CDDAVolume::Type) { + }; + __new_declare_io_value(RightCD2LeftSPU, CDDAVolume::Type) { + }; struct Interrupt { enum Type : uint8_t { @@ -110,24 +125,24 @@ namespace JabyEngine { DiskError = 5 }; - static void enable(InterruptEnable_v& port) { - port.set(InterruptEnable_t::InterruptTypValue.range_max()); + static void enable(New::IOPort& port) { + port.write(port.read().set2(InterruptEnable::InterruptTypValue.range_max())); } - static void enable_extended(InterruptEnable_v& port) { - port = InterruptEnable_t::from(InterruptEnable_t::InterruptTypValue.range_max(), InterruptEnable_t::UnknownIRQ, InterruptEnable_t::CommandStartIRQ); + static void enable_extended(New::IOPort& port) { + port.write(InterruptEnable::from(InterruptEnable::InterruptTypValue.range_max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)); } - static Type get_type(const InterruptFlag_v& port) { - return static_cast(port.get(InterruptFlag_v::InterruptTypValue)); + static Type get_type(const New::IOPort& port) { + return static_cast(port.read().get2(InterruptFlag::InterruptTypValue)); } - static void ack(InterruptFlag_v& port) { - port.set(InterruptFlag_v::InterruptTypValue.range_max()); + static void ack(New::IOPort& port) { + port.write(port.read().set2(InterruptFlag::InterruptTypValue.range_max())); } - static void ack_extended(InterruptFlag_v& port) { - port = InterruptFlag_v::from(InterruptFlag_v::InterruptTypValue.range_max(), InterruptEnable_v::UnknownIRQ, InterruptEnable_v::CommandStartIRQ); + static void ack_extended(New::IOPort& port) { + port.write(InterruptFlag::from(InterruptFlag::InterruptTypValue.range_max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)); } }; @@ -149,71 +164,71 @@ namespace JabyEngine { static constexpr auto IORegister2Adr = 0x1F801802; static constexpr auto IORegister3Adr = 0x1F801803; - __declare_new_io_port(IndexStatus, 0x1F801800); + __new_declare_io_port(, IndexStatus, 0x1F801800); - #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) + //#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_new_const_io_port(ResponseFifo, IORegister1Adr); - __declare_new_io_port(CommandFifo, IORegister1Adr); + __new_declare_io_port(inline const, ResponseFifo, IORegister1Adr); + __new_declare_io_port(inline, CommandFifo, IORegister1Adr); - __declare_new_const_io_port(DataFifo, IORegister2Adr); - __declare_new_const_io_port(DataFifo16, IORegister2Adr); - __declare_new_io_port(ParameterFifo, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo16, IORegister2Adr); + __new_declare_io_port(inline, ParameterFifo, IORegister2Adr); - __declare_new_const_io_port(InterruptEnable, IORegister3Adr); - __declare_new_io_port(Request, IORegister3Adr); + __new_declare_io_port(inline const, InterruptEnable, IORegister3Adr); + __new_declare_io_port(inline, Request, IORegister3Adr); static void change_to() { - IndexStatus = Index::Index0; + IndexStatus.write({Index::Index0}); } }; struct PortIndex1 { - __declare_new_const_io_port(ResponseFifo, IORegister1Adr); - __declare_new_io_port(SoundMapDataOut, IORegister1Adr); + __new_declare_io_port(inline const, ResponseFifo, IORegister1Adr); + __new_declare_io_port(inline, SoundMapDataOut, IORegister1Adr); - __declare_new_const_io_port(DataFifo, IORegister2Adr); - __declare_new_const_io_port(DataFifo16, IORegister2Adr); - __declare_new_io_port(InterruptEnable, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo16, IORegister2Adr); + __new_declare_io_port(inline, InterruptEnable, IORegister2Adr); - __declare_new_io_port(InterruptFlag, IORegister3Adr); + __new_declare_io_port_w_type(inline, struct InterruptEnable, InterruptFlag, IORegister3Adr); static void change_to() { - IndexStatus = Index::Index1; - } + IndexStatus.write({Index::Index1}); + } }; struct PortIndex2 { - __declare_new_const_io_port(ResponseFifo, IORegister1Adr); - __declare_new_io_port(SoundMapCoding, IORegister1Adr); + __new_declare_io_port(inline const, ResponseFifo, IORegister1Adr); + __new_declare_io_port(inline, SoundMapCoding, IORegister1Adr); - __declare_new_const_io_port(DataFifo, IORegister2Adr); - __declare_new_const_io_port(DataFifo16, IORegister2Adr); - __declare_new_io_port(LeftCD2LeftSPU, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo16, IORegister2Adr); + __new_declare_io_port(inline, LeftCD2LeftSPU, IORegister2Adr); - __declare_new_const_io_port(InterruptEnable, IORegister3Adr); - __declare_new_io_port(LeftCD2RightSPU, IORegister3Adr); + __new_declare_io_port(inline const, InterruptEnable, IORegister3Adr); + __new_declare_io_port(inline, LeftCD2RightSPU, IORegister3Adr); static void change_to() { - IndexStatus = Index::Index2; + IndexStatus.write({Index::Index2}); } }; struct PortIndex3 { - __declare_new_const_io_port(ResponseFifo, IORegister1Adr); - __declare_new_io_port(RightCD2RightSPU, IORegister1Adr); + __new_declare_io_port(inline const, ResponseFifo, IORegister1Adr); + __new_declare_io_port(inline, RightCD2RightSPU, IORegister1Adr); - __declare_new_const_io_port(DataFifo, IORegister2Adr); - __declare_new_const_io_port(DataFifo16, IORegister2Adr); - __declare_new_io_port(RightCD2LeftSPU, IORegister1Adr); + __new_declare_io_port(inline const, DataFifo, IORegister2Adr); + __new_declare_io_port(inline const, DataFifo16, IORegister2Adr); + __new_declare_io_port(inline, RightCD2LeftSPU, IORegister1Adr); - __declare_new_const_io_port(InterruptFlag, IORegister3Adr); - __declare_new_io_port(AudioVolumeApply, IORegister3Adr); + __new_declare_io_port_w_type(inline const, struct InterruptEnable, InterruptFlag, IORegister3Adr); + __new_declare_io_port(inline, AudioVolumeApply, IORegister3Adr); static void change_to() { - IndexStatus = Index::Index3; + IndexStatus.write({Index::Index3}); } }; diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index 728ac44e..fb65fbed 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -185,6 +185,9 @@ namespace JabyEngine { } }; + __new_declare_io_value(GPUREAD, uint32_t) { + }; + __new_declare_io_value(GPUSTAT, uint32_t) { static constexpr auto DrawingOddLinesInterlaced = Bit(31); static constexpr auto DMADirectionValue = BitRange::from_to(29, 30); diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index f8745a53..4e9687ba 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -110,22 +110,6 @@ namespace JabyEngine { #define __new_declare_io_port_array(cv, name, size, adr) __new_declare_array_at(cv, struct name, name, size, adr) } - namespace IOPort { - struct IOValueType { - template - struct Normal { - typedef T Value; - typedef T UnderlyingValue; - }; - - template - struct Volatile { - typedef volatile T Value; - typedef T UnderlyingValue; - }; - }; - } - namespace IOAdress { constexpr uintptr_t patch_adr(uintptr_t adr) { constexpr uintptr_t Mask = 0xF0000000; @@ -134,119 +118,5 @@ namespace JabyEngine { return (Base + (adr & ~Mask)); } } - - #define __declare_new_named_io_port(type, name, adr) \ - static inline auto& name = *reinterpret_cast(IOAdress::patch_adr(adr)) - - #define __declare_new_io_port(name, adr) \ - __declare_new_named_io_port(name, name, adr) - - #define __declare_new_const_io_port(name, adr) \ - __declare_new_named_io_port(const name, name, adr) - - #define __declare_new_io_port_array(name, adr, size) \ - static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) - - // We need this construct to ensure the types end up being a POD - Inheritance doesn't qualify for a POD - #define __declare_io_type(name, type, ...) \ - template typename T> \ - struct name##_io_base { \ - typedef T::UnderlyingValue UnderlyingValue; \ - typedef name##_io_base Self; \ - \ - T::Value raw_value = 0; \ - \ - __VA_ARGS__ \ - \ - template \ - static constexpr Self from(const ARGS&...args) { \ - return Self().set_va(args...); \ - } \ - \ - constexpr Self& set(Bit bit) { \ - this->raw_value = bit::set(this->raw_value, bit); \ - return *this; \ - } \ - \ - constexpr Self& set(ClearBit bit) { \ - this->raw_value = bit::set(this->raw_value, bit); \ - return *this; \ - } \ - \ - constexpr Self& set(BitRange bits, UnderlyingValue value) { \ - this->raw_value = bit::value::set_normalized(this->raw_value, bits, value); \ - return *this; \ - } \ - \ - template \ - constexpr Self& set(const BitRange::RangeValuePair& value) { \ - this->raw_value = bit::value::set_normalized(this->raw_value, value); \ - return *this; \ - } \ - \ - template \ - constexpr Self& set_va(const S& head) { \ - return this->set(head); \ - } \ - \ - template \ - constexpr Self& set_va(const S& head, const ARGS&...tail) { \ - return this->set(head).set_va(tail...); \ - } \ - \ - constexpr UnderlyingValue get(BitRange bits) const { \ - return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ - } \ - \ - constexpr Self& clear(Bit bit) { \ - this->raw_value = bit::clear(this->raw_value, bit); \ - return *this; \ - } \ - \ - constexpr bool is_set(Bit bit) const { \ - return bit::is_set(this->raw_value, bit); \ - } \ - \ - constexpr void operator=(UnderlyingValue value) { \ - this->raw_value = value; \ - } \ - \ - constexpr operator UnderlyingValue() const { \ - return this->raw_value; \ - } \ - }; \ - \ - typedef name##_io_base name##_v; \ - typedef name##_io_base name##_t - - #pragma pack(push, 1) - struct ubus32_t { - __declare_io_type(uint16_t, uint16_t,); - uint16_t_v low; - uint16_t_v high; - - constexpr ubus32_t(uint32_t value) : low{0}, high{0} { - *this = value; - } - - constexpr void write(uint32_t value) { - *this = value; - } - - constexpr operator uint32_t() const { - const uint32_t high = this->high; - const uint32_t low = this->low; - - return ((high << 16) | low); - } - - constexpr ubus32_t& operator=(uint32_t value) { - this->low = (value & 0xFFFF); - this->high = (value >> 16); - - return *this; - } - }; - #pragma pack(pop) } #endif //!__JABYENGINE_IOPORT_HPP__ \ No newline at end of file diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index aad04e32..7d9d7af2 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -15,11 +15,11 @@ namespace JabyEngine { } template - static void send(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { - while(CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::IsTransmissionBusy)); + static void send(New::IOPort& cmd_fifo, New::IOPort& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { + while(CD_IO::IndexStatus.read().is_set2(CD_IO::IndexStatus::IsTransmissionBusy)); - ((parameter_fifo = args),...); - cmd_fifo = cmd.id; + ((parameter_fifo.write(CD_IO::ParameterFifo{args})),...); + cmd_fifo.write(CD_IO::CommandFifo{cmd.id}); cmd_interrupt_bit = bit::set(0, cmd.complete_irq); } @@ -29,7 +29,7 @@ namespace JabyEngine { } template - static void send_wait(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { + static void send_wait(New::IOPort& cmd_fifo, New::IOPort& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { send(cmd_fifo, parameter_fifo, cmd, args...); wait_completed(); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 7a95d5ce..913c364d 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -6,7 +6,7 @@ namespace JabyEngine { namespace CD { namespace internal { - static constexpr auto DataSectorMode = CD_IO::Mode_t::from(CD_IO::Mode_t::DoubleSpeed, CD_IO::Mode_t::DataSector); + static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); static InterruptVerifierResult interrupt_verifier(); static void interrupt_handler(uint32_t); @@ -40,7 +40,7 @@ namespace JabyEngine { static void read_sector_dma(CD_IO::DataSector& sector) { static const auto WaitSectorReady = []() { - while(!CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::HasDataFifoData)); + while(!CD_IO::IndexStatus.read().is_set2(CD_IO::IndexStatus::HasDataFifoData)); }; static const auto ReadSector = [](uint32_t* dst) { @@ -50,7 +50,7 @@ namespace JabyEngine { DMA_IO::CDROM.wait(); - CD_IO::PortIndex0::Request.reset(); + CD_IO::PortIndex0::Request.write(CD_IO::Request::reset()); }; WaitSectorReady(); @@ -59,7 +59,7 @@ namespace JabyEngine { static void read_sector_to(CD_IO::DataSector& sector) { CD_IO::PortIndex0::change_to(); - CD_IO::PortIndex0::Request.want_data(); + CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data()); // We only support DMA rn read_sector_dma(sector); @@ -79,7 +79,7 @@ namespace JabyEngine { } static void interrupt_handler(uint32_t) { - const uint8_t old_status = CD_IO::IndexStatus; + const auto old_status = CD_IO::IndexStatus.read(); CD_IO::PortIndex1::change_to(); const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); @@ -112,7 +112,7 @@ namespace JabyEngine { } // No masking required because we can only write bit 0 - 2 - CD_IO::IndexStatus = old_status; + CD_IO::IndexStatus.write(old_status); Interrupt::ack_irq(Interrupt::CDROM); __syscall_ReturnFromException(); }