Add new IOPort design

This commit is contained in:
Jaby 2023-01-15 16:49:38 +01:00
parent f30ecbe46c
commit fc915a887a
15 changed files with 143 additions and 240 deletions

View File

@ -63,6 +63,7 @@ namespace JabyEngine {
template<typename T>
class ComplexBitMap {
public:
typedef T UnderlyingType;
T raw;
private:

View File

@ -11,9 +11,7 @@ namespace JabyEngine {
Index3 = 3,
};
struct __no_align IndexStatus : public ComplexBitMap<uint8_t> {
__io_port_inherit_complex_bit_map(IndexStatus);
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);
@ -21,20 +19,16 @@ namespace JabyEngine {
static constexpr auto HasResponseFifoData = Bit<uint8_t>(5);
static constexpr auto HasDataFifoData = Bit<uint8_t>(6);
static constexpr auto IsTransmissionBusy = Bit<uint8_t>(7);
};
struct __no_align InterruptEnable : public ComplexBitMap<uint8_t> {
__io_port_inherit_complex_bit_map(InterruptEnable);
} 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 __no_align Request : public ComplexBitMap<uint8_t> {
__io_port_inherit_complex_bit_map(Request);
struct Request : public ComplexBitMap<uint8_t> {
static constexpr auto WantCommandStartIRQ = Bit<uint8_t>(5);
static constexpr auto WantData = Bit<uint8_t>(7);
};
@ -63,34 +57,34 @@ namespace JabyEngine {
struct __no_align IndexTriplet {
// Replace with proper types later
union __no_align {
const IOPort<ResponseFifo> response_fifo;
IOPort<CommandFifo> command;
const IOPort<uint8_t, ResponseFifo> response_fifo;
IOPort<uint8_t, CommandFifo> command;
};
union __no_align {
const IOPort<DataFifo> data_fifo;
IOPort<ParameterFifo> parameter_fifo;
const IOPort<uint8_t, DataFifo> data_fifo;
IOPort<uint8_t, ParameterFifo> parameter_fifo;
};
union __no_align {
const IOPort<InterruptEnable> irq_enable;
IOPort<Request> request;
const IOPort<InterruptEnable::UnderlyingType, InterruptEnable> irq_enable;
IOPort<Request::UnderlyingType, Request> request;
};
const IOPort<uint16_t>& get_data_fifo_16() const {
return *reinterpret_cast<const IOPort<uint16_t>*>(&this->data_fifo);
const IOPort<uint16_t, DataFifo16>& get_data_fifo_16() const {
return *reinterpret_cast<const IOPort<uint16_t, DataFifo16>*>(&this->data_fifo);
}
};
static_assert(sizeof(IndexTriplet) == 3);
}
__declare_io_port_global(struct IndexStatus, IndexStatus, 0x1F801800);
__declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800);
namespace Helper {
template<typename S>
static S& change_to(Index idx) {
IndexStatus.write(ComplexBitMap(static_cast<uint8_t>(idx)));
IndexStatus.write({static_cast<uint8_t>(idx)});
return *reinterpret_cast<S*>(0x1F801801);
}
}

View File

@ -4,34 +4,26 @@
namespace JabyEngine {
namespace DMA_IO {
struct __no_align MADR : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(MADR);
struct MADR : public ComplexBitMap<uint32_t> {
static constexpr auto MemoryAdr = BitRange<uint32_t>::from_to(0, 23);
};
struct __no_align BCR : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(BCR);
struct BCR : public ComplexBitMap<uint32_t> {
struct __no_align SyncMode0 {
static constexpr auto NumberOfWords = BitRange<uint16_t>::from_to(0, 15);
static constexpr auto CD_OneBlock = Bit<uint16_t>(16);
};
struct __no_align SyncMode1 : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(SyncMode1);
struct SyncMode1 : public ComplexBitMap<uint32_t> {
static constexpr auto BlockSize = BitRange<uint32_t>::from_to(0, 15);
static constexpr auto BlockAmount = BitRange<uint32_t>::from_to(16, 31);
};
struct __no_align SyncMode2 {
struct SyncMode2 {
};
};
struct __no_align CHCHR : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(CHCHR);
struct CHCHR : public ComplexBitMap<uint32_t> {
enum _SyncMode {
Sync0 = 0, //Start immediately,
Sync1 = 1, //Sync blocks to DMA requests
@ -60,34 +52,34 @@ namespace JabyEngine {
static constexpr auto ToMainRAM = !FromMainRAM;
static constexpr CHCHR StartMDECin() {
return ComplexBitMap{0x01000201};
return CHCHR{0x01000201};
}
static constexpr CHCHR StartMDECout() {
return ComplexBitMap{0x01000200};
return CHCHR{0x01000200};
}
static constexpr CHCHR StartGPUReceive() {
return ComplexBitMap{0x01000201};
return CHCHR{0x01000201};
}
static constexpr CHCHR StartCDROM() {
return ComplexBitMap{0x11000000};
return CHCHR{0x11000000};
}
static constexpr CHCHR StartSPUReceive() {
return ComplexBitMap{0x01000201};
return CHCHR{0x01000201};
}
static constexpr CHCHR StartOTC() {
return ComplexBitMap{0x11000002};
return CHCHR{0x11000002};
}
};
struct __no_align Registers {
IOPort<MADR> adr;
IOPort<BCR> block_ctrl;
IOPort<CHCHR> channel_ctrl;
IOPort<MADR::UnderlyingType, MADR> adr;
IOPort<BCR::UnderlyingType, BCR> block_ctrl;
IOPort<CHCHR::UnderlyingType, CHCHR> channel_ctrl;
};
//0: Highest, 7: Lowest
@ -95,9 +87,7 @@ namespace JabyEngine {
static constexpr Priority HighestPriority = 0;
static constexpr Priority LowestPriority = 7;
struct __no_align DMAControlRegister : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(DMAControlRegister);
struct DMAControlRegister : public ComplexBitMap<uint32_t> {
static constexpr auto OTCEnable = Bit<uint32_t>(27);
static constexpr auto OTCPriority = BitRange<Priority>::from_to(24, 26);
@ -120,9 +110,7 @@ namespace JabyEngine {
static constexpr auto MDECinPriority = BitRange<Priority>::from_to(0, 2);
};
struct __no_align DMAInterruptRegister : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(DMAInterruptRegister);
struct DMAInterruptRegister : public ComplexBitMap<uint32_t> {
static constexpr auto MasterEnable = Bit<uint32_t>(31);
static constexpr auto Flags = BitRange<uint32_t>::from_to(24, 30);
static constexpr auto MasterEnableDPCR = Bit<uint32_t>(23);

View File

@ -48,15 +48,14 @@ namespace JabyEngine {
};
struct Command {
struct __no_align GP0 : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(GP0);
struct GP0 : public ComplexBitMap<uint32_t> {
static constexpr GP0 QuickFill(GPU::Color24 color) {
return ComplexBitMap{(0x02 << 24) | color.raw()};
return {(0x02 << 24) | color.raw()};
}
static constexpr GP0 CPU2VRAM_Blitting() {
return ComplexBitMap{(0b101u << 29)};
return {(0b101u << 29)};
}
static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) {
@ -64,7 +63,7 @@ namespace JabyEngine {
constexpr auto Y = BitRange<uint32_t>::from_to(10, 18);
constexpr auto X = BitRange<uint32_t>::from_to(0, 9);
return ComplexBitMap<uint32_t>::with(Command.with(code), Y.with(y), X.with(x));
return {GP0::with(Command.with(code), Y.with(y), X.with(x))};
}
static constexpr GP0 DrawAreaTopLeft(uint16_t x, uint16_t y) {
@ -76,65 +75,63 @@ namespace JabyEngine {
}
static constexpr GP0 TopLeftPosition(uint16_t x, uint16_t y) {
return ComplexBitMap{static_cast<uint32_t>((y << 16u) | x)};
return {static_cast<uint32_t>((y << 16u) | x)};
}
static constexpr GP0 WidthHeight(uint16_t w, uint16_t h) {
return ComplexBitMap{static_cast<uint32_t>((h << 16u) | w)};
return {static_cast<uint32_t>((h << 16u) | w)};
}
};
struct __no_align GP1 : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(GP1);
struct GP1 : public ComplexBitMap<uint32_t> {
static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) {
return ((cmd << 24) | value);
}
static constexpr GP1 Reset() {
return ComplexBitMap{0};
return {0};
}
static constexpr GP1 ResetCMDBufer() {
return ComplexBitMap{construct_cmd(0x01, 0)};
return {construct_cmd(0x01, 0)};
}
static constexpr GP1 SetDisplayState(DisplayState state) {
return ComplexBitMap{construct_cmd(0x03, static_cast<uint32_t>(state))};
return {construct_cmd(0x03, static_cast<uint32_t>(state))};
}
static constexpr GP1 DMADirection(DMADirection dir) {
return ComplexBitMap{construct_cmd(0x04, static_cast<uint32_t>(dir))};
return {construct_cmd(0x04, static_cast<uint32_t>(dir))};
}
static constexpr GP1 DisplayArea(uint16_t x, uint16_t y) {
constexpr auto X = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y = BitRange<uint32_t>::from_to(10, 18);
return ComplexBitMap{construct_cmd(0x05, ComplexBitMap<uint32_t>::with(X.with(x), Y.with(y)).raw)};
return {construct_cmd(0x05, ComplexBitMap<uint32_t>::with(X.with(x), Y.with(y)).raw)};
}
static constexpr GP1 HorizontalDisplayRange(uint32_t x1, uint32_t x2) {
constexpr auto X1 = BitRange<uint32_t>::from_to(0, 11);
constexpr auto X2 = BitRange<uint32_t>::from_to(12, 23);
return ComplexBitMap{construct_cmd(0x06, ComplexBitMap<uint32_t>::with(X1.with(x1), X2.with(x2)).raw)};
return {construct_cmd(0x06, ComplexBitMap<uint32_t>::with(X1.with(x1), X2.with(x2)).raw)};
}
static constexpr GP1 VerticalDisplayRange(uint32_t y1, uint32_t y2) {
constexpr auto Y1 = BitRange<uint32_t>::from_to(0, 9);
constexpr auto Y2 = BitRange<uint32_t>::from_to(10, 19);
return ComplexBitMap{construct_cmd(0x07, ComplexBitMap<uint32_t>::with(Y1.with(y1), Y2.with(y2)).raw)};
return {construct_cmd(0x07, ComplexBitMap<uint32_t>::with(Y1.with(y1), Y2.with(y2)).raw)};
}
static constexpr GP1 DisplayMode(uint32_t mode) {
return ComplexBitMap{construct_cmd(0x08, mode)};
return {construct_cmd(0x08, mode)};
}
};
};
struct __no_align GPUStatusRegister : public ComplexBitMap<uint32_t> {
struct GPUStatusRegister : public ComplexBitMap<uint32_t> {
static constexpr auto DrawingOddLinesInterlaced = Bit<uint32_t>(31);
static constexpr auto DMADirectionValue = BitRange<DMADirection>::from_to(29, 30);
static constexpr auto DMAReady = Bit<uint32_t>(28);
@ -166,7 +163,7 @@ namespace JabyEngine {
__declare_io_port_global(Command::GP0, GP0, 0x1F801810);
__declare_io_port_global(Command::GP1, GP1, 0x1F801814);
__declare_io_port_global_const(uint32_t, GPUREAD, 0x1F801810);
__declare_io_port_global_const_simple(uint32_t, GPUREAD, 0x1F801810);
__declare_io_port_global_const(GPUStatusRegister, GPUSTAT, 0x1F801814);
}
}

View File

@ -17,31 +17,29 @@ namespace JabyEngine {
static constexpr auto Controller = Bit<uint32_t>(10);
static constexpr auto LightPen = Controller;
struct __no_align Status : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(Status);
};
typedef struct Status : public ComplexBitMap<uint32_t> {
} Status_t;
struct __no_align Mask : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(Mask);
};
typedef struct Mask : public ComplexBitMap<uint32_t> {
} Mask_t;
__declare_io_port_member(struct Status, Status, 0x1F801070);
__declare_io_port_member(struct Mask, Mask, 0x1F801074);
__declare_io_port_member(Status_t, Status, 0x1F801070);
__declare_io_port_member(Mask_t, Mask, 0x1F801074);
static bool is_irq(Bit<uint32_t> irq) {
return Status.read().is_bit_set(irq);
}
static void ack_irq(Bit<uint32_t> irq) {
Status.write(Status.read().clear_bit(irq));
Status.write({Status.read().clear_bit(irq)});
}
static void disable_irq(Bit<uint32_t> irq) {
Mask.write(Mask.read().clear_bit(irq));
Mask.write({Mask.read().clear_bit(irq)});
}
static void enable_irq(Bit<uint32_t> irq) {
Mask.write(Mask.read().set_bit(irq));
Mask.write({Mask.read().set_bit(irq)});
}
};
}

View File

@ -3,94 +3,82 @@
#include "../../Auxiliary/complex_bitmap.hpp"
namespace JabyEngine {
template<typename T>
template<typename T, typename S/* = T*/>
class __no_align IOPort {
private:
T value;
volatile T value;
public:
// decltype(this) instead of IOPort<T>* lead to wrong runtime behaviour somethow...
constexpr T read() const {
return const_cast<const volatile IOPort<T>*>(this)->value;
constexpr T read_raw() const {
return this->value;
}
template<typename S>
constexpr S read(const BitRange<S>& range) const {
constexpr S read() const {
return S{this->value};
}
constexpr T read_range_value(const BitRange<T>& range) const {
return IOPort::read().get_value(range);
}
template<typename...ARGS>
constexpr void write_combined(const ARGS&... value) {
IOPort::write(T::with(value...));
constexpr void write_raw(T value) {
this->value = value;
}
template<typename S>
constexpr void write(const BitRangeValue<S>& value) {
IOPort::write(T::with(value));
constexpr void write(const S& value) {
this->value = static_cast<T>(value);
}
constexpr void write(const T& value) {
const_cast<volatile IOPort<T>*>(this)->value = value;
constexpr void write_range_value(const BitRangeValue<T>& value) {
IOPort<T, S>::write(S{S::with(value)});
}
// We keep this a POD so we will not add assignment operators anymore
// We also removed ref() to be more percise
};
struct __no_align ubus32_t {
ComplexBitMap<uint16_t> low;
ComplexBitMap<uint16_t> high;
typedef ComplexBitMap<uint16_t> Base16;
IOPort<Base16::UnderlyingType, Base16> low;
IOPort<Base16::UnderlyingType, Base16> high;
constexpr ubus32_t(uint32_t value) {
*this = value;
}
constexpr operator uint32_t() const {
return ((this->high.raw << 16) | this->low.raw);
constexpr void write(uint32_t value) {
*this = value;
}
operator uint32_t() const volatile {
return ((this->high.raw << 16) | this->low.raw);
constexpr operator uint32_t() const {
return ((this->high.read_raw() << 16) | this->low.read_raw());
}
constexpr ubus32_t& operator=(uint32_t value) {
this->low.raw = (value & 0xFFFF);
this->high.raw = (value >> 16);
this->low.write_raw(value & 0xFFFF);
this->high.write_raw(value >> 16);
return *this;
}
constexpr void operator=(uint32_t value) volatile {
this->low.raw = (value & 0xFFFF);
this->high.raw = (value >> 16);
}
};
static constexpr uintptr_t IO_Base_Mask = 0xF0000000;
static constexpr uintptr_t IO_Base_Adr = 0x10000000;
#define __declare_global_raw(cv, type, name, adr) static __always_inline cv auto& name = *reinterpret_cast<type*>(__io_port_adr(adr))
#define __io_port_adr(adr) (IO_Base_Adr + (adr & ~IO_Base_Mask))
#define __declare_io_port_global_raw(cv, type, name, adr) static __always_inline cv auto& name = *reinterpret_cast<IOPort<type>*>(__io_port_adr(adr))
#define __declare_io_port_global(type, name, adr) __declare_io_port_global_raw(, type, name, adr)
#define __declare_io_port_global_const(type, name, adr) __declare_io_port_global_raw(const, type, name, adr)
#define __declare_io_port_global_raw(cv, type, sub_type, name, adr) __declare_global_raw(cv, __collect(IOPort<type, sub_type>), name, adr)
#define __declare_io_port_member(type, name, adr) __declare_io_port_global_raw(inline, type, name, adr)
#define __declare_io_port_member_const(type, name, adr) __declare_io_port_global_raw(const inline, type, name, adr)
#define __declare_io_port_global(type, name, adr) __declare_io_port_global_raw(, type::UnderlyingType, type, name, adr)
#define __declare_io_port_global_const(type, name, adr) __declare_io_port_global_raw(const, type::UnderlyingType, type, name, adr)
#define __declare_io_port_global_simple(type, name, adr) __declare_io_port_global_raw(, type, type, name, adr)
#define __declare_io_port_global_const_simple(type, name, adr) __declare_io_port_global_raw(const, type, type, name, adr)
#define __declare_io_port_member(type, name, adr) __declare_io_port_global_raw(inline, type::UnderlyingType, type, name, adr)
#define __declare_io_port_member_const(type, name, adr) __declare_io_port_global_raw(const inline, type::UnderlyingType, type, name, adr)
#define __declare_io_port_member_simple(type, name, adr) __declare_io_port_global_raw(inline, type, type, name, adr)
#define __declare_io_port_member_const_simple(type, name, adr) __declare_io_port_global_raw(const inline, type, type, name, adr)
#define __declare_io_port_global_array(type, name, adr, size) static __always_inline auto& name = reinterpret_cast<type(&)[size]>(*reinterpret_cast<type*>((IO_Base_Adr + (adr & ~IO_Base_Mask))))
#define __declare_io_port_global_struct(type, name, adr) static __always_inline auto& name = *reinterpret_cast<type*>(__io_port_adr(adr))
#define __io_port_inherit_complex_bit_map(name) \
constexpr __always_inline name() = default; \
constexpr __always_inline name(ComplexBitMap value) : ComplexBitMap(value) { \
} \
template<typename...ARGS> \
static constexpr __always_inline name with(ARGS...args) { \
return {ComplexBitMap::with(args...)}; \
}\
template<typename T> \
constexpr void __always_inline operator=(ComplexBitMap<T> value) volatile { \
this->raw = value.raw; \
}
}
#endif //!__JABYENGINE_IOPORT_HPP__

View File

@ -27,20 +27,16 @@ namespace JabyEngine {
typedef int16_t SimpleVolume;
struct __no_align SampleRate : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(SampleRate);
struct SampleRate : public ComplexBitMap<uint16_t> {
static constexpr SampleRate from_HZ(double freq) {
//4096 == 44100Hz
constexpr double Base = (4096.0 / 44100.0);
return ComplexBitMap<uint16_t>{static_cast<uint16_t>((freq*Base))};
return {static_cast<uint16_t>((freq*Base))};
}
};
struct __no_align SweepVolume : public ComplexBitMap<int16_t> {
__io_port_inherit_complex_bit_map(SweepVolume);
struct SweepVolume : public ComplexBitMap<int16_t> {
// For Volume Mode
static constexpr auto SweepEnable = Bit<int16_t>(15);
static constexpr auto VolumeEnable = !SweepEnable;
@ -54,9 +50,7 @@ namespace JabyEngine {
static constexpr auto SweepStep = BitRange<Step>::from_to(0, 1);
};
struct __no_align SR : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(SR);
struct SR : public ComplexBitMap<uint16_t> {
static constexpr auto SustainMode = Bit<Mode>(31 - 16);
static constexpr auto SustainDirection = Bit<Direction>(30 - 16);
static constexpr auto SustainShift = BitRange<Shift>::from_to((24 - 16), (28 - 16));
@ -65,9 +59,7 @@ namespace JabyEngine {
static constexpr auto ReleaseShift = BitRange<Shift>::from_to((16 - 16), (20 - 16));
};
struct __no_align AD : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(AD);
struct AD : public ComplexBitMap<uint16_t> {
static constexpr auto AttackMode = Bit<Mode>(15);
static constexpr auto AttackShift = BitRange<Shift>::from_to(10, 14);
static constexpr auto AttackStep = BitRange<Step>::from_to(8, 9);
@ -76,19 +68,17 @@ namespace JabyEngine {
};
struct __no_align Voice {
IOPort<SweepVolume> volumeLeft; //Offset: 0x0
IOPort<SweepVolume> volumeRight; //Offset: 0x2
IOPort<SampleRate> sampleRate; //Offset: 0x4;
IOPort<uint16_t> adr; //Offset: 0x6
IOPort<AD> ad; //Offset: 0x8
IOPort<SR> sr; //Offset: 0xA
IOPort<SimpleVolume> currentVolume; //Offset: 0xC
IOPort<uint16_t> repeatAdr; //Offset: 0xE
IOPort<SweepVolume::UnderlyingType, SweepVolume> volumeLeft; //Offset: 0x0
IOPort<SweepVolume::UnderlyingType, SweepVolume> volumeRight; //Offset: 0x2
IOPort<SampleRate::UnderlyingType, SampleRate> sampleRate; //Offset: 0x4;
IOPort<uint16_t, uint16_t> adr; //Offset: 0x6
IOPort<AD::UnderlyingType, AD> ad; //Offset: 0x8
IOPort<SR::UnderlyingType, SR> sr; //Offset: 0xA
IOPort<SimpleVolume, SimpleVolume> currentVolume; //Offset: 0xC
IOPort<uint16_t, uint16_t> repeatAdr; //Offset: 0xE
};
struct __no_align ControlRegister : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(ControlRegister);
struct ControlRegister : public ComplexBitMap<uint16_t> {
enum RAMTransferMode {
Stop = 0,
ManualWrite = 1,
@ -109,30 +99,24 @@ namespace JabyEngine {
static constexpr auto CDAudioEnable = Bit<uint16_t>(0);
};
struct __no_align PitchModFlags : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(PitchModFlags);
struct PitchModFlags : public ComplexBitMap<uint16_t> {
static constexpr BitRange<uint16_t> EnableBits = BitRange<uint16_t>::from_to(1, 23);
};
struct __no_align NoiseGenerator : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(NoiseGenerator);
struct NoiseGenerator : public ComplexBitMap<uint16_t> {
static constexpr BitRange<uint16_t> NoiseBits = BitRange<uint16_t>::from_to(0, 23);
};
struct __no_align EchoOn : public ComplexBitMap<uint16_t> {
__io_port_inherit_complex_bit_map(EchoOn);
struct EchoOn : public ComplexBitMap<uint16_t> {
static constexpr BitRange<uint16_t> EchoBits = BitRange<uint16_t>::from_to(0, 23);
};
static constexpr size_t VoiceCount = 24;
struct Key {
__declare_io_port_member(ubus32_t, On, 0x1F801D88);
__declare_io_port_member(ubus32_t, Off, 0x1F801D8C);
__declare_io_port_member(ubus32_t, Status, 0x1F801D9C);
__declare_global_raw(inline, ubus32_t, On, 0x1F801D88);
__declare_global_raw(inline, ubus32_t, Off, 0x1F801D8C);
__declare_global_raw(inline, ubus32_t, Status, 0x1F801D9C);
};
struct MainVolume {
@ -141,28 +125,28 @@ namespace JabyEngine {
};
struct CDVolume {
__declare_io_port_member(SimpleVolume, Left, 0x1F801DB0);
__declare_io_port_member(SimpleVolume, Right, 0x1F801DB2);
__declare_io_port_member_simple(SimpleVolume, Left, 0x1F801DB0);
__declare_io_port_member_simple(SimpleVolume, Right, 0x1F801DB2);
};
struct ExternalAudioInputVolume {
__declare_io_port_member(SimpleVolume, Left, 0x1F801DB4);
__declare_io_port_member(SimpleVolume, Right, 0x1F801DB6);
__declare_io_port_member_simple(SimpleVolume, Left, 0x1F801DB4);
__declare_io_port_member_simple(SimpleVolume, Right, 0x1F801DB6);
};
struct Reverb {
struct Volume {
__declare_io_port_member(SimpleVolume, Left, 0x1F801D84);
__declare_io_port_member(SimpleVolume, Right, 0x1F801D86);
__declare_io_port_member_simple(SimpleVolume, Left, 0x1F801D84);
__declare_io_port_member_simple(SimpleVolume, Right, 0x1F801D86);
};
__declare_io_port_member(uint16_t, WorkAreaAdr, 0x1F801DA2);
__declare_io_port_member_simple(uint16_t, WorkAreaAdr, 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(ControlRegister, Control, 0x1F801DAA);
__declare_io_port_global_simple(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(struct Voice, Voice, 0x1F801C00, VoiceCount);
}

View File

@ -4,9 +4,7 @@
namespace JabyEngine {
namespace Timer_IO {
struct __no_align CounterMode : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(CounterMode);
struct CounterMode : public ComplexBitMap<uint32_t> {
static constexpr auto SyncEnable = Bit<uint32_t>(0);
static constexpr auto FreeRun = !SyncEnable;
static constexpr auto SyncMode = BitRange<uint32_t>::from_to(1, 2);
@ -23,22 +21,18 @@ namespace JabyEngine {
static constexpr auto IsMaxReached = Bit<uint32_t>(12);
};
struct __no_align CounterTarget : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(CounterTarget);
struct CounterTarget : public ComplexBitMap<uint32_t> {
static constexpr auto CounterTargetValue = BitRange<uint32_t>::from_to(0, 15);
};
struct __no_align CounterValue : public ComplexBitMap<uint32_t> {
__io_port_inherit_complex_bit_map(CounterValue);
struct CounterValue : public ComplexBitMap<uint32_t> {
static constexpr auto Value = BitRange<uint32_t>::from_to(0, 15);
};
struct __no_align Counter {
IOPort<CounterValue> value;
IOPort<CounterMode> mode;
IOPort<CounterTarget> target;
IOPort<CounterValue::UnderlyingType, CounterValue> value;
IOPort<CounterMode::UnderlyingType, CounterMode> mode;
IOPort<CounterTarget::UnderlyingType, CounterTarget> target;
private:
uint32_t _unused;
};

View File

@ -66,10 +66,9 @@ namespace JabyEngine {
~HighResTime() = delete;
static TimeStamp get_time_stamp() {
return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.value.read(Timer_IO::CounterValue::Value));
return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.value.read_range_value(Timer_IO::CounterValue::Value));
}
};
#endif //JABYENGINE_USE_HIGH_PERCISION_TIMER
}
#endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__

View File

@ -8,6 +8,7 @@
#define __no_inline __attribute__((noinline))
#define __always_inline __attribute__((always_inline))
#define __section(name) __attribute__((section(name)))
#define __collect(...) __VA_ARGS__
#ifdef __cplusplus
#define __constexpr constexpr

View File

@ -95,7 +95,7 @@ namespace JabyEngine {
}
static void set_src(uintptr_t adr) {
DMA_IO::GPU.adr.write(DMA_IO::MADR::MemoryAdr.with(static_cast<uint32_t>(adr)));
DMA_IO::GPU.adr.write_range_value(DMA_IO::MADR::MemoryAdr.with(static_cast<uint32_t>(adr)));
}
static void set_dst(const PositionU16& position, const SizeU16& size) {
@ -108,7 +108,7 @@ namespace JabyEngine {
static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) {
typedef DMA_IO::BCR::SyncMode1 SyncMode1;
DMA_IO::GPU.block_ctrl.write(SyncMode1::with(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount)));
DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR{SyncMode1::with(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))});
DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPUReceive());
}
}

View File

@ -10,8 +10,8 @@ namespace JabyEngine {
static void clear_main_volume() {
static constexpr auto StartVol = SPU_IO::SweepVolume::with(SPU_IO::SweepVolume::VolumeEnable, SPU_IO::SweepVolume::Volume.with(I16_MAX >> 2));
SPU_IO::MainVolume::Left.write(StartVol);
SPU_IO::MainVolume::Right.write(StartVol);
SPU_IO::MainVolume::Left.write({StartVol});
SPU_IO::MainVolume::Right.write({StartVol});
}
static void clear_cd_and_ext_audio_volume() {
@ -58,7 +58,7 @@ namespace JabyEngine {
static void setup_control_register() {
static constexpr auto SetupValue = SPU_IO::ControlRegister::with(SPU_IO::ControlRegister::Enable, SPU_IO::ControlRegister::Unmute, SPU_IO::ControlRegister::CDAudioEnable);
SPU_IO::Control.write(SetupValue);
SPU_IO::Control.write({SetupValue});
}
static void setup_data_transfer_control() {
@ -79,7 +79,7 @@ namespace JabyEngine {
}
void stop_voices() {
SPU_IO::Key::Off.write(UI32_MAX);
SPU_IO::Key::Off.write({UI32_MAX});
}
void setup() {

View File

@ -8,7 +8,7 @@ namespace JabyEngine {
namespace boot {
namespace Start {
static void enable_DMA() {
DMA_IO::DPCR.write(DMA_IO::DPCR.read() | DMA_IO::DMAControlRegister::SPUEnable | DMA_IO::DMAControlRegister::GPUEnable);
DMA_IO::DPCR.write(DMA_IO::DMAControlRegister{DMA_IO::DPCR.read() | DMA_IO::DMAControlRegister::SPUEnable | DMA_IO::DMAControlRegister::GPUEnable});
}
JabyEngine::NextRoutine setup() {

View File

@ -26,8 +26,8 @@
__syscall_SysEnqIntRP(Timer2Irq, &IRQCallback);
__syscall_ExitCriticalSection();
Counter2.target.write(CounterTarget::CounterTargetValue.with(HighResTime::TicksFor10ms));
Counter2.mode.write(Mode);
Counter2.target.write_range_value(CounterTarget::CounterTargetValue.with(HighResTime::TicksFor10ms));
Counter2.mode.write({Mode});
Interrupt::enable_irq(Interrupt::Timer2);
}

View File

@ -1,49 +1,8 @@
#include "../../include/CD/cd_internal.hpp"
#include <PSX/Auxiliary/complex_bitmap.hpp>
namespace JabyEngine {
namespace CD {
template<typename T, typename S = T>
class IOPortX {
private:
volatile T value;
public:
constexpr T read_raw() const {
return this->value;
}
constexpr S read() const {
return S{this->value};
}
constexpr void write_raw(T value) {
this->value = value;
}
constexpr void write(const S& value) {
this->value = static_cast<T>(value);
}
};
struct __no_align Wuff : public ComplexBitMap<uint32_t> {
static constexpr auto Miau = Bit<uint32_t>(0);
static constexpr auto Blubb = BitRange<uint32_t>::from_to(0, 5);
};
static __always_inline auto& Wuff = *reinterpret_cast<IOPortX<uint32_t, struct Wuff>*>(0x1F80000);
static uint32_t read(const IOPortX<uint32_t, struct Wuff>& port) {
return port.read().get_value(Wuff::Blubb);
}
namespace internal {
void setup() {
while(Wuff.read().is_bit_set(Wuff::Miau));
Wuff.write({Wuff::with(Wuff::Miau)});
}
}
}
}