jabyengine/include/PSX/System/IOPorts/cd_io.hpp

98 lines
3.7 KiB
C++

#ifndef __JABYENGINE_CD_IO_HPP__
#define __JABYENGINE_CD_IO_HPP__
#include "ioport.hpp"
namespace JabyEngine {
namespace CD_IO {
enum struct Index {
Index0 = 0,
Index1 = 1,
Index2 = 2,
Index3 = 3,
};
typedef struct IndexStatus : public ComplexBitMap<uint8_t> {
static constexpr auto PortIndex = BitRange<Index>::from_to(0, 1);
static constexpr auto HasXAFifoData = Bit<uint8_t>(2);
static constexpr auto IsParameterFifoEmpty = Bit<uint8_t>(3);
static constexpr auto HasParameterFifoSpace = Bit<uint8_t>(4);
static constexpr auto HasResponseFifoData = Bit<uint8_t>(5);
static constexpr auto HasDataFifoData = Bit<uint8_t>(6);
static constexpr auto IsTransmissionBusy = Bit<uint8_t>(7);
} IndexStatus_t;
struct InterruptEnable : public ComplexBitMap<uint8_t> {
static constexpr auto InterruptTypValue = BitRange<uint8_t>::from_to(0, 2);
static constexpr auto UnknownIRQ = Bit<uint8_t>(3);
static constexpr auto CommandStartIRQ = Bit<uint8_t>(4);
};
typedef InterruptEnable InterruptFlag;
struct Request : public ComplexBitMap<uint8_t> {
static constexpr auto WantCommandStartIRQ = Bit<uint8_t>(5);
static constexpr auto WantData = Bit<uint8_t>(7);
};
struct Interrupt {
static void enable_all(VolatileBitMapPOD<InterruptEnable>& port) {
port.write({InterruptEnable::with(InterruptEnable::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)});
}
static uint8_t get_type(const VolatileBitMapPOD<InterruptFlag>& port) {
return port.read().get_value(InterruptFlag::InterruptTypValue);
}
static void ack(VolatileBitMapPOD<InterruptFlag>& port) {
port.write_range_value(InterruptFlag::InterruptTypValue.max());
}
};
typedef uint8_t ResponseFifo;
typedef uint8_t CommandFifo;
typedef uint8_t DataFifo;
typedef uint16_t DataFifo16;
typedef uint8_t ParameterFifo;
namespace Index0Types {
struct __no_align IndexTriplet {
// Replace with proper types later
union __no_align {
const VolatilePOD<ResponseFifo> response_fifo;
VolatilePOD<CommandFifo> command;
};
union __no_align {
const VolatilePOD<DataFifo> data_fifo;
VolatilePOD<ParameterFifo> parameter_fifo;
};
union __no_align {
const VolatileBitMapPOD<InterruptEnable> irq_enable;
VolatileBitMapPOD<Request> request;
};
const VolatilePOD<DataFifo16>& get_data_fifo_16() const {
return *reinterpret_cast<const VolatilePOD<DataFifo16>*>(&this->data_fifo);
}
};
static_assert(sizeof(IndexTriplet) == 3);
}
__declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800);
namespace Helper {
template<typename S>
static S& change_to(Index idx) {
IndexStatus.write({static_cast<uint8_t>(idx)});
return *reinterpret_cast<S*>(0x1F801801);
}
}
static Index0Types::IndexTriplet& change_to_index0() {
return Helper::change_to<Index0Types::IndexTriplet>(Index::Index0);
}
}
}
#endif //!__JABYENGINE_CD_IO_HPP__