184 lines
8.6 KiB
C++
184 lines
8.6 KiB
C++
#pragma once
|
|
#include "IOValues/cd_io_values.hpp"
|
|
|
|
namespace JabyEngine {
|
|
namespace CD_IO {
|
|
using AudioVolumeApply_IO = IOPort<CD_IO_Values::AudioVolumeApply>;
|
|
using CommandFifo_IO = IOPort<CD_IO_Values::CommandFifo>;
|
|
using DataFifo_IO = IOPort<CD_IO_Values::DataFifo>;
|
|
using DataFifo16_IO = IOPort<CD_IO_Values::DataFifo16>;
|
|
using IndexStatus_IO = IOPort<CD_IO_Values::IndexStatus>;
|
|
using InterruptEnable_IO = IOPort<CD_IO_Values::InterruptEnable>;
|
|
using InterruptFlag_IO = IOPort<CD_IO_Values::InterruptFlag>;
|
|
using LeftCD2LeftSPU_IO = IOPort<CD_IO_Values::LeftCD2LeftSPU>;
|
|
using LeftCD2RightSPU_IO = IOPort<CD_IO_Values::LeftCD2RightSPU>;
|
|
using ParameterFifo_IO = IOPort<CD_IO_Values::ParameterFifo>;
|
|
using Request_IO = IOPort<CD_IO_Values::Request>;
|
|
using ResponseFifo_IO = IOPort<CD_IO_Values::ResponseFifo>;
|
|
using RightCD2LeftSPU_IO = IOPort<CD_IO_Values::RightCD2LeftSPU>;
|
|
using RightCD2RightSPU_IO = IOPort<CD_IO_Values::RightCD2RightSPU>;
|
|
using SoundMapDataOut_IO = IOPort<CD_IO_Values::SoundMapDataOut>;
|
|
using SoundMapCoding_IO = IOPort<CD_IO_Values::SoundMapCoding>;
|
|
|
|
struct DataSector {
|
|
static constexpr size_t SizeBytes = 2048;
|
|
static constexpr size_t SizeWords = (SizeBytes/sizeof(uint32_t));
|
|
|
|
uint32_t data[SizeWords];
|
|
|
|
template<typename T>
|
|
static constexpr T words_to_sectors(T size) {
|
|
return (size + static_cast<T>(DataSector::SizeWords - 1))/static_cast<T>(DataSector::SizeWords);
|
|
}
|
|
|
|
constexpr size_t hash() const {
|
|
uint32_t value = 0;
|
|
|
|
for(const auto word : this->data) {
|
|
value += word;
|
|
}
|
|
return value;
|
|
}
|
|
};
|
|
|
|
enum Index {
|
|
Index0 = 0,
|
|
Index1 = 1,
|
|
Index2 = 2,
|
|
Index3 = 3,
|
|
};
|
|
|
|
struct Interrupt {
|
|
static constexpr auto ExtendedFlags = CD_IO_Values::InterruptEnable::from(
|
|
CD_IO_Values::InterruptEnable::InterruptTypValue.range_max<uint8_t>(),
|
|
CD_IO_Values::InterruptEnable::UnknownIRQ,
|
|
CD_IO_Values::InterruptEnable::CommandStartIRQ
|
|
);
|
|
|
|
enum Type : uint8_t {
|
|
None = 0,
|
|
DataReady = 1,
|
|
Complete = 2,
|
|
Acknowledge = 3,
|
|
DataEnd = 4,
|
|
DiskError = 5
|
|
};
|
|
|
|
static void enable(InterruptEnable_IO& port) {
|
|
port.write(port.read().set(CD_IO_Values::InterruptEnable::InterruptTypValue.range_max<uint8_t>()));
|
|
}
|
|
|
|
static void enable_extended(InterruptEnable_IO& port) {
|
|
port.write(Interrupt::ExtendedFlags);
|
|
}
|
|
|
|
static Type get_type(const InterruptFlag_IO& port) {
|
|
return static_cast<Type>(port.read().get(CD_IO_Values::InterruptFlag::InterruptTypValue));
|
|
}
|
|
|
|
static void ack(InterruptFlag_IO& port) {
|
|
port.write(port.read().set(CD_IO_Values::InterruptFlag::InterruptTypValue.range_max<uint8_t>()));
|
|
}
|
|
|
|
static void ack_extended(InterruptFlag_IO& port) {
|
|
port.write(Interrupt::ExtendedFlags);
|
|
}
|
|
|
|
static void reset_parameter_fifo(InterruptFlag_IO& port) {
|
|
port.write(CD_IO_Values::InterruptFlag{0x40});
|
|
}
|
|
};
|
|
|
|
struct Command {
|
|
struct Desc {
|
|
uint8_t id;
|
|
Interrupt::Type complete_irq;
|
|
};
|
|
|
|
static constexpr Desc GetStat{0x01, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc SetLoc{0x02, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc Play{0x03, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc ReadN{0x06, Interrupt::Type::DataReady};
|
|
static constexpr Desc Pause{0x09, Interrupt::Type::Complete};
|
|
static constexpr Desc Init{0x0A, Interrupt::Type::Complete};
|
|
static constexpr Desc Demute{0x0C, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc Filter{0x0D, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc GetLocL{0x10, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc GetLocP{0x11, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc GetTD{0x14, Interrupt::Type::Acknowledge};
|
|
static constexpr Desc SeekL{0x15, Interrupt::Type::Complete};
|
|
static constexpr Desc ReadS{0x1B, Interrupt::Type::DataReady};
|
|
};
|
|
|
|
static constexpr auto IORegister1Adr = 0x1F801801;
|
|
static constexpr auto IORegister2Adr = 0x1F801802;
|
|
static constexpr auto IORegister3Adr = 0x1F801803;
|
|
|
|
static auto& IndexStatus = __declare_io_port(IndexStatus_IO, 0x1F801800);
|
|
|
|
struct PortIndex0 {
|
|
static inline const auto& ResponseFifo = __declare_io_port(ResponseFifo_IO, IORegister1Adr);
|
|
static inline auto& CommandFifo = __declare_io_port(CommandFifo_IO, IORegister1Adr);
|
|
|
|
static inline const auto& DataFifo = __declare_io_port(DataFifo_IO, IORegister2Adr);
|
|
static inline const auto& DataFifo16 = __declare_io_port(DataFifo16_IO, IORegister2Adr);
|
|
static inline auto& ParameterFifo = __declare_io_port(ParameterFifo_IO, IORegister2Adr);
|
|
|
|
static inline const auto& InterruptEnable = __declare_io_port(InterruptEnable_IO, IORegister3Adr);
|
|
static inline auto& Request = __declare_io_port(Request_IO, IORegister3Adr);
|
|
|
|
static void change_to() {
|
|
IndexStatus.write({Index::Index0});
|
|
}
|
|
};
|
|
|
|
struct PortIndex1 {
|
|
static inline const auto& ResponseFifo = __declare_io_port(ResponseFifo_IO, IORegister1Adr);
|
|
static inline auto& SoundMapDataOut = __declare_io_port(SoundMapDataOut_IO, IORegister1Adr);
|
|
|
|
static inline const auto& DataFifo = __declare_io_port(DataFifo_IO, IORegister2Adr);
|
|
static inline const auto& DataFifo16 = __declare_io_port(DataFifo16_IO, IORegister2Adr);
|
|
static inline auto& InterruptEnable = __declare_io_port(InterruptEnable_IO, IORegister2Adr);
|
|
|
|
static inline auto& InterruptFlag = __declare_io_port(InterruptFlag_IO, IORegister3Adr);
|
|
|
|
static void change_to() {
|
|
IndexStatus.write({Index::Index1});
|
|
}
|
|
};
|
|
|
|
struct PortIndex2 {
|
|
static inline const auto& ResponseFifo = __declare_io_port(ResponseFifo_IO, IORegister1Adr);
|
|
static inline auto& SoundMapCoding = __declare_io_port(SoundMapCoding_IO, IORegister1Adr);
|
|
|
|
static inline const auto& DataFifo = __declare_io_port(DataFifo_IO, IORegister2Adr);
|
|
static inline const auto& DataFifo16 = __declare_io_port(DataFifo16_IO, IORegister2Adr);
|
|
static inline auto& LeftCD2LeftSPU = __declare_io_port(LeftCD2LeftSPU_IO, IORegister2Adr);
|
|
|
|
static inline const auto& InterruptEnable = __declare_io_port(InterruptEnable_IO, IORegister3Adr);
|
|
static inline auto& LeftCD2RightSPU = __declare_io_port(LeftCD2RightSPU_IO, IORegister3Adr);
|
|
|
|
static void change_to() {
|
|
IndexStatus.write({Index::Index2});
|
|
}
|
|
};
|
|
|
|
struct PortIndex3 {
|
|
static inline const auto& ResponseFifo = __declare_io_port(ResponseFifo_IO, IORegister1Adr);
|
|
static inline auto& RightCD2RightSPU = __declare_io_port(RightCD2RightSPU_IO, IORegister1Adr);
|
|
|
|
static inline const auto& DataFifo = __declare_io_port(DataFifo_IO, IORegister2Adr);
|
|
static inline const auto& DataFifo16 = __declare_io_port(DataFifo16_IO, IORegister2Adr);
|
|
static inline auto& RightCD2LeftSPU = __declare_io_port(RightCD2LeftSPU_IO, IORegister1Adr);
|
|
|
|
static inline const auto& InterruptFlag = __declare_io_port(InterruptFlag_IO, IORegister3Adr);
|
|
static inline auto& AudioVolumeApply = __declare_io_port(AudioVolumeApply_IO, IORegister3Adr);
|
|
|
|
static void change_to() {
|
|
IndexStatus.write({Index::Index3});
|
|
}
|
|
};
|
|
}
|
|
} |