diff --git a/src/mips/common/syscalls/syscalls.h b/src/mips/common/syscalls/syscalls.h index f2dc1ebc8..fac71dc8a 100644 --- a/src/mips/common/syscalls/syscalls.h +++ b/src/mips/common/syscalls/syscalls.h @@ -36,6 +36,7 @@ SOFTWARE. struct JmpBuf; +#ifndef PS1_PC_PORT static __attribute__((always_inline)) int enterCriticalSection() { register int n asm("a0") = 1; register int r asm("v0"); @@ -598,3 +599,4 @@ static __attribute__((always_inline)) int syscall_getDeviceStatus() { __asm__ volatile("" : "=r"(n) : "r"(n)); return ((int (*)())0xc0)(); } +#endif // #ifdef PS1_PC_PORT diff --git a/src/mips/psyqo/advancedpad.hh b/src/mips/psyqo/advancedpad.hh index 29212ae7b..d443e3810 100644 --- a/src/mips/psyqo/advancedpad.hh +++ b/src/mips/psyqo/advancedpad.hh @@ -215,8 +215,10 @@ class AdvancedPad { }; void busyLoop(unsigned delay) { +#ifndef PS1_PC_PORT unsigned cycles = 0; while (++cycles < delay) asm(""); +#endif }; void configurePort(uint8_t port); diff --git a/src/mips/psyqo/fragment-concept.hh b/src/mips/psyqo/fragment-concept.hh index c240affb1..cfd5f5f33 100644 --- a/src/mips/psyqo/fragment-concept.hh +++ b/src/mips/psyqo/fragment-concept.hh @@ -49,10 +49,12 @@ struct has_explicit_copy_constructor< template concept Fragment = requires(Frag frag) { +#ifndef PS1_PC_PORT { (alignof(Frag) & 3) == 0 }; { (sizeof(Frag) & 3) == 0 }; { (sizeof(frag.head)) == 4 }; { ((offsetof(Frag, head)) & 3) == 0 }; +#endif // Can't seem to make this work with variadic templated constructors // { has_explicit_copy_constructor() } -> std::convertible_to; { frag.getActualFragmentSize() } -> std::convertible_to; diff --git a/src/mips/psyqo/fragments.hh b/src/mips/psyqo/fragments.hh index 44a5df6d1..bb8be102c 100644 --- a/src/mips/psyqo/fragments.hh +++ b/src/mips/psyqo/fragments.hh @@ -63,17 +63,50 @@ namespace Fragments { * @tparam T The primitive type. */ +struct ChainEntryPS1; +struct ChainEntryPC; + +#ifdef PS1_PC_PORT +using ChainEntry = ChainEntryPC; +#else +using ChainEntry = ChainEntryPS1; +#endif + +struct ChainEntryPC { + ChainEntry* next; + unsigned size; + void setEndMarker() { + next = nullptr; + size = 0; + } + void set(ChainEntry* next_, unsigned size_) { + next = next_; + size = size_; + } +}; + +struct ChainEntryPS1 { + uintptr_t head; + void setEndMarker() { + head = 0xffffff; + } + void set(ChainEntryPS1* next, unsigned size) { + head = (size << 24) | (next->head & 0xffffff); + } +}; + template -struct SimpleFragment { +struct SimpleFragment : ChainEntry { constexpr size_t maxSize() const { return 1; } template SimpleFragment(Args &&...args) : primitive(eastl::forward(args)...) { +#ifndef PS1_PC_PORT static_assert(sizeof(*this) == (sizeof(uint32_t) + sizeof(Prim)), "Spurious padding in simple fragment"); +#endif } explicit SimpleFragment(const SimpleFragment &) = default; typedef Prim FragmentBaseType; constexpr size_t getActualFragmentSize() const { return sizeof(Prim) / sizeof(uint32_t); } - uint32_t head; Prim primitive; }; @@ -89,18 +122,19 @@ struct SimpleFragment { */ template -struct FixedFragment { +struct FixedFragment : ChainEntry { constexpr size_t maxSize() const { return N; } FixedFragment() { - static_assert(sizeof(*this) == (sizeof(unsigned) + sizeof(uint32_t) + sizeof(Prim) * N), +#ifndef PS1_PC_PORT + static_assert(sizeof(*this) == (sizeof(unsigned) + sizeof(uintptr_t) + sizeof(Prim) * N), "Spurious padding in fixed fragment"); +#endif } explicit FixedFragment(const FixedFragment &) = default; typedef Prim FragmentBaseType; size_t getActualFragmentSize() const { return (sizeof(Prim) * count) / sizeof(uint32_t); } - unsigned count = N; - uint32_t head; eastl::array primitives; + unsigned count = N; }; /** @@ -118,19 +152,20 @@ struct FixedFragment { */ template -struct FixedFragmentWithPrologue { +struct FixedFragmentWithPrologue : ChainEntry { constexpr size_t maxSize() const { return N; } FixedFragmentWithPrologue() { - static_assert(sizeof(*this) == (sizeof(unsigned) + sizeof(uint32_t) + sizeof(P) + sizeof(Prim) * N), +#ifndef PS1_PC_PORT + static_assert(sizeof(*this) == (sizeof(unsigned) + sizeof(uintptr_t) + sizeof(P) + sizeof(Prim) * N), "Spurious padding in fixed fragment"); +#endif } explicit FixedFragmentWithPrologue(const FixedFragmentWithPrologue &) = default; typedef Prim FragmentBaseType; size_t getActualFragmentSize() const { return (sizeof(P) + sizeof(Prim) * count) / sizeof(uint32_t); } - unsigned count = N; - uint32_t head; P prologue; eastl::array primitives; + unsigned count = N; }; } // namespace Fragments diff --git a/src/mips/psyqo/gpu.hh b/src/mips/psyqo/gpu.hh index 99dea7d72..1a32d1d97 100644 --- a/src/mips/psyqo/gpu.hh +++ b/src/mips/psyqo/gpu.hh @@ -228,7 +228,7 @@ class GPU { */ template void sendFragment(const Frag &fragment) { - sendFragment(&fragment.head + 1, fragment.getActualFragmentSize()); + sendFragment(reinterpret_cast(&fragment.head + 1), fragment.getActualFragmentSize()); } /** @@ -243,7 +243,8 @@ class GPU { template void sendFragment(const Frag &fragment, eastl::function &&callback, DMA::DmaCallback dmaCallback = DMA::FROM_MAIN_LOOP) { - sendFragment(&fragment.head + 1, fragment.getActualFragmentSize(), eastl::move(callback), dmaCallback); + sendFragment(reinterpret_cast(&fragment.head + 1), fragment.getActualFragmentSize(), + eastl::move(callback), dmaCallback); } /** @@ -354,8 +355,8 @@ class GPU { */ template void chain(OrderingTable &table) { - chain(&table.m_table[N], &table.m_table[0], 0); - scheduleOTC(&table.m_table[N], N + 1); + chain(&table.m_table[N].head, &table.m_table[0].head, 0); + scheduleOTC(&table.m_table[N].head, N + 1); } /** @@ -535,8 +536,8 @@ class GPU { DMA::DmaCallback dmaCallback); void scheduleNormalDMA(uintptr_t data, size_t count); void scheduleChainedDMA(uintptr_t head); - void chain(uint32_t *first, uint32_t *last, size_t count); - void scheduleOTC(uint32_t *start, uint32_t count); + void chain(uintptr_t *first, uintptr_t *last, size_t count); + void scheduleOTC(uintptr_t *start, uint32_t count); void checkOTCAndTriggerCallback(); void prepareForTakeover(); @@ -548,8 +549,8 @@ class GPU { uint32_t m_frameCount = 0; uint32_t m_previousFrameCount = 0; unsigned m_parity = 0; - uint32_t *m_chainHead = nullptr; - uint32_t *m_chainTail = nullptr; + uintptr_t *m_chainHead = nullptr; + uintptr_t *m_chainTail = nullptr; size_t m_chainTailCount = 0; enum { CHAIN_IDLE, CHAIN_TRANSFERRING, CHAIN_TRANSFERRED } m_chainStatus = CHAIN_IDLE; struct Timer { @@ -562,11 +563,11 @@ class GPU { }; eastl::fixed_list m_timers; struct ScheduledOTC { - uint32_t *start; + uintptr_t *start; uint32_t count; }; eastl::fixed_list m_OTCs[2]; - uint32_t *m_chainNext = nullptr; + uintptr_t *m_chainNext = nullptr; uint16_t m_lastHSyncCounter = 0; bool m_interlaced = false; diff --git a/src/mips/psyqo/gte-kernels.hh b/src/mips/psyqo/gte-kernels.hh index 95eaee1c5..16662baba 100644 --- a/src/mips/psyqo/gte-kernels.hh +++ b/src/mips/psyqo/gte-kernels.hh @@ -55,49 +55,75 @@ enum LM : unsigned { Unlimited, Limited }; // RTPS - Perspective Transformation (single) // pers(([rt]·[v0]) >> 12 + [tr]) -> sxy2 // 14 cycles -static inline void rtps() { asm volatile("cop2 0x0180001"); } +static inline void rtps() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0180001"); +#endif +} // RTPT - Perspective Transformation (triple) // pers(([rt]·[v0]) >> 12 + [tr]) -> sxy0 // pers(([rt]·[v1]) >> 12 + [tr]) -> sxy1 // pers(([rt]·[v2]) >> 12 + [tr]) -> sxy2 // 22 cycles -static inline void rtpt() { asm volatile("cop2 0x0280030"); } +static inline void rtpt() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0280030"); +#endif +} // Depth Queuing // DCPL - Depth Cue Color light // (1 - dp)·[rgb·sv] + dp·[fc] -> rgb, lv, sv // 8 cycles -static inline void dpcl() { asm volatile("cop2 0x0680029"); } +static inline void dpcl() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0680029"); +#endif +} // DPCS - Depth Cueing (single) // (1 - dp)·[rgb] + dp·[fc] -> rgb, lv, sv // 8 cycles -static inline void dpcs() { asm volatile("cop2 0x0780010"); } +static inline void dpcs() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0780010"); +#endif +} // DPCT - Depth Cueing (triple) // (1 - dp)·[rgb0] + dp·[fc] -> rgb0, lv, sv // (1 - dp)·[rgb1] + dp·[fc] -> rgb1, lv, sv // (1 - dp)·[rgb2] + dp·[fc] -> rgb2, lv, sv // 17 cycles -static inline void dpct() { asm volatile("cop2 0x0f8002a"); } +static inline void dpct() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0f8002a"); +#endif +} // INTPL - Interpolation of a vector and far color // (1 - dp)·[sv] + dp·[fc] -> rgb2, lv, sv // 8 cycles -static inline void intpl() { asm volatile("cop2 0x0980011"); } +static inline void intpl() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0980011"); +#endif +} // Termwise Vector Square // [sv.x² >> 12, sv.y² >> 12, sv.z² >> 12] -> lv, sv // 5 cycles template static inline void sqr() { +#ifndef PS1_PC_PORT if constexpr (sf == Shifted) { asm volatile("cop2 0x0a80428"); } else { asm volatile("cop2 0x0a00428"); } +#endif } // Light Source Calculations @@ -106,7 +132,11 @@ static inline void sqr() { // limit(([ll]·[v0]) >> 12) -> sv // limit(([lc]·[sv]) >> 12) + [bk] -> rgb2 // 14 cycles -static inline void ncs() { asm volatile("cop2 0x0c8041e"); } +static inline void ncs() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0c8041e"); +#endif +} // NCT - Normal color (triple) // limit(([ll]·[v0]) >> 12) -> sv @@ -116,14 +146,22 @@ static inline void ncs() { asm volatile("cop2 0x0c8041e"); } // limit(([ll]·[v2]) >> 12) -> sv // limit(([lc]·[sv]) >> 12) + [bk] -> rgb2 // 30 cycles -static inline void nct() { asm volatile("cop2 0x0d80420"); } +static inline void nct() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0d80420"); +#endif +} // NCDS - Normal color depth cue (single vector) // limit(([ll]·[v0]) >> 12) -> sv // limit(([lc]·[sv]) >> 12) + [bk] -> sv // (1 - dp)·[rgb·sv] + dp·[fc] -> rgb2 // 19 cycles -static inline void ncds() { asm volatile("cop2 0x0e80413"); } +static inline void ncds() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0e80413"); +#endif +} // NCDT - Normal color depth cue (triple vectors) // limit(([ll]·[v0]) >> 12) -> sv @@ -136,14 +174,22 @@ static inline void ncds() { asm volatile("cop2 0x0e80413"); } // limit(([lc]·[sv]) >> 12) + [bk] -> sv // (1 - dp)·[rgb·sv] + dp·[fc] -> rgb2 // 44 cycles -static inline void ncdt() { asm volatile("cop2 0x0f80416"); } +static inline void ncdt() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0f80416"); +#endif +} // NCCS - Normal Color Color (single vector) // limit(([ll]·[v0]) >> 12) -> sv // limit(([lc]·[sv]) >> 12) + [bk] -> sv // [rgb·sv] -> rgb2 // 17 cycles -static inline void nccs() { asm volatile("cop2 0x0108041b"); } +static inline void nccs() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0108041b"); +#endif +} // NCCT - Normal Color Color (triple vector) // limit(([ll]·[v0]) >> 12) -> sv @@ -156,19 +202,31 @@ static inline void nccs() { asm volatile("cop2 0x0108041b"); } // limit(([lc]·[sv]) >> 12) + [bk] -> sv // [rgb·sv] -> rgb2 // 39 cycles -static inline void ncct() { asm volatile("cop2 0x0118043f"); } +static inline void ncct() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0118043f"); +#endif +} // Color Depth Que // limit(([lc]·[sv]) >> 12) + [bk] -> sv // (1 - dp)·[rgb·sv] + dp·[fc] -> rgb2 // 13 cycles -static inline void cdp() { asm volatile("cop2 0x01280414"); } +static inline void cdp() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x01280414"); +#endif +} // Color Color // limit(([lc]·[sv]) >> 12) + [bk] -> sv // [rgb·sv] -> rgb2 // 11 cycles -static inline void cc() { asm volatile("cop2 0x0138041c"); } +static inline void cc() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0138041c"); +#endif +} // NCLIP - Normal clipping // sx0*sy1 + sx1*sy2 + sx2*sy0 - sx0*sy2 - sx1*sy0 - sx2*sy1 -> opz @@ -176,19 +234,31 @@ static inline void cc() { asm volatile("cop2 0x0138041c"); } // [sx1 - sx0, sy1 - sy0] // [sx2 - sx0, sy2 - sy0] // 8 cycles -static inline void nclip() { asm volatile("cop2 0x01400006"); } +static inline void nclip() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x01400006"); +#endif +} // Z Average // AVSZ3 - Average of three Z values (for Triangles) // zsf3 * (sz0 + sz1 + sz2) -> otz // 5 cycles -static inline void avsz3() { asm volatile("cop2 0x0158002d"); } +static inline void avsz3() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0158002d"); +#endif +} // AVSZ4 - Average of four Z values (for Quads) // zsf4 * (sz0 + sz1 + sz2 + sz4) -> otz // 6 cycles -static inline void avsz4() { asm volatile("cop2 0x0168002e"); } +static inline void avsz4() { +#ifndef PS1_PC_PORT + asm volatile("cop2 0x0168002e"); +#endif +} // Cross Product (improperly named Outer Product in Sony's lingo) // rt.22 * ir3 - rt.33 * ir2 -> ir1 @@ -197,11 +267,13 @@ static inline void avsz4() { asm volatile("cop2 0x0168002e"); } // 6 cycles template static inline void cp() { +#ifndef PS1_PC_PORT if constexpr (sf == Shifted) { asm volatile("cop2 0x0178000c"); } else { asm volatile("cop2 0x0170000c"); } +#endif } // General Interpolation @@ -211,11 +283,13 @@ static inline void cp() { // 5 cycles template static inline void gpf() { +#ifndef PS1_PC_PORT if constexpr (sf == Shifted) { asm volatile("cop2 0x0198003d"); } else { asm volatile("cop2 0x0190003d"); } +#endif } // General purpose interpolation with base @@ -223,11 +297,13 @@ static inline void gpf() { // 5 cycles template static inline void gpl() { +#ifndef PS1_PC_PORT if constexpr (sf == Shifted) { asm volatile("cop2 0x01a8003e"); } else { asm volatile("cop2 0x01a0003e"); } +#endif } // All of the MVMVA operations take 8 cycles to complete. @@ -247,9 +323,11 @@ enum class TV : unsigned { TR, BK, FC, Zero }; // Multiply vector by matrix and add vector template void mvmva() { +#ifndef PS1_PC_PORT constexpr uint32_t op = (4 << 20) | (sf << 19) | (uint32_t(mx) << 17) | (uint32_t(v) << 15) | (uint32_t(cv) << 13) | (lm << 10) | 18; asm volatile("cop2 %0" : : "i"(op)); +#endif } // Coordinate Conversion, Light Source Calculations diff --git a/src/mips/psyqo/gte-registers.hh b/src/mips/psyqo/gte-registers.hh index b210559e1..20e787d74 100644 --- a/src/mips/psyqo/gte-registers.hh +++ b/src/mips/psyqo/gte-registers.hh @@ -161,6 +161,7 @@ enum Safety { */ template static inline void clear() { +#ifndef PS1_PC_PORT if constexpr (reg < Register::R11R12) { asm volatile("mtc2 $0, $%0" ::"i"(static_cast(reg))); } else if constexpr (reg >= Register::R11R12) { @@ -169,6 +170,7 @@ static inline void clear() { if constexpr (safety == Safe) { asm volatile("nop; nop"); } +#endif } /** @@ -180,6 +182,7 @@ static inline void clear() { */ template static inline void write(uint32_t value) { +#ifndef PS1_PC_PORT if (__builtin_constant_p(value) && (value == 0)) { clear(); } else { @@ -192,6 +195,7 @@ static inline void write(uint32_t value) { asm volatile("nop; nop"); } } +#endif } /** @@ -340,6 +344,7 @@ static inline void writeUnsafe(const Vec2& in) { */ template static inline void write(const uint32_t* ptr) { +#ifndef PS1_PC_PORT static_assert(reg < Register::R11R12, "Unable to write to register from memory directly"); if constexpr (reg < Register::R11R12) { asm volatile("lwc2 $%1, 0(%0)" ::"r"(ptr), "i"(static_cast(reg))); @@ -348,6 +353,7 @@ static inline void write(const uint32_t* ptr) { if constexpr (safety == Safe) { asm volatile("nop; nop"); } +#endif } /** @@ -359,6 +365,7 @@ static inline void write(const uint32_t* ptr) { */ template static inline uint32_t readRaw() { +#ifndef PS1_PC_PORT uint32_t value; if constexpr (reg < Register::R11R12) { if constexpr (safety == Safe) { @@ -374,6 +381,9 @@ static inline uint32_t readRaw() { } } return value; +#else + return 0; +#endif } /** @@ -384,10 +394,12 @@ static inline uint32_t readRaw() { */ template static inline void read(uint32_t* ptr) { +#ifndef PS1_PC_PORT static_assert(reg < Register::R11R12, "Unable to read from register to memory directly"); if constexpr (reg < Register::R11R12) { asm volatile("swc2 $%2, 0(%1)" : "=m"(*ptr) : "r"(ptr), "i"(static_cast(reg))); } +#endif } /** @@ -399,8 +411,12 @@ static inline void read(uint32_t* ptr) { */ template static inline PackedVec3 readSafe() { +#ifndef PS1_PC_PORT static_assert(valid, "Unable to read pseudo register as vector"); __builtin_unreachable(); +#else + return {}; +#endif } /** @@ -412,20 +428,28 @@ static inline PackedVec3 readSafe() { */ template static inline PackedVec3 readUnsafe() { +#ifndef PS1_PC_PORT static_assert(valid, "Unable to read pseudo register as vector"); __builtin_unreachable(); +#else + return {}; +#endif } template [[deprecated("Use the reference version instead")]] static inline void read(Vec3* ptr) { +#ifndef PS1_PC_PORT static_assert(valid, "Unable to read pseudo register as vector"); __builtin_unreachable(); +#endif } template static inline void read(Vec3& vec) { +#ifndef PS1_PC_PORT static_assert(valid, "Unable to read pseudo register as vector"); __builtin_unreachable(); +#endif } // The following are template specializations for the various GTE registers. diff --git a/src/mips/psyqo/kernel.hh b/src/mips/psyqo/kernel.hh index 3db18cdc1..a8e1dbe6d 100644 --- a/src/mips/psyqo/kernel.hh +++ b/src/mips/psyqo/kernel.hh @@ -54,12 +54,20 @@ static constexpr bool debugMode = true; namespace Internal { static inline uint32_t getCop0Status() { +#ifndef PS1_PC_PORT uint32_t r; asm("mfc0 %0, $12 ; nop" : "=r"(r)); return r; +#else + return 0; +#endif } -static inline void setCop0Status(uint32_t r) { asm("mtc0 %0, $12 ; nop" : : "r"(r)); } +static inline void setCop0Status(uint32_t r) { +#ifndef PS1_PC_PORT + asm("mtc0 %0, $12 ; nop" : : "r"(r)); +#endif +} [[noreturn]] void abort(const char* msg, std::source_location location = std::source_location::current()); [[noreturn]] void abort(); @@ -72,14 +80,22 @@ static inline void setCop0Status(uint32_t r) { asm("mtc0 %0, $12 ; nop" : : "r"( * @details This function is technically equivalent to `enterCriticalSection`. * @return false if the critical section was already entered, true otherwise. */ -static inline void fastEnterCriticalSection() { asm volatile("mtc0 %0, $12 ; nop ; nop" : : "r"(0x40000000)); } +static inline void fastEnterCriticalSection() { +#ifndef PS1_PC_PORT + asm volatile("mtc0 %0, $12 ; nop ; nop" : : "r"(0x40000000)); +#endif +} /** * @brief A faster version of `leaveCriticalSection`. * * @details This function is technically equivalent to `leaveCriticalSection`. */ -static inline void fastLeaveCriticalSection() { asm volatile("mtc0 %0, $12" : : "r"(0x40000401)); } +static inline void fastLeaveCriticalSection() { +#ifndef PS1_PC_PORT + asm volatile("mtc0 %0, $12" : : "r"(0x40000401)); +#endif +} enum class DMA : unsigned { MDECin, diff --git a/src/mips/psyqo/ordering-table.hh b/src/mips/psyqo/ordering-table.hh index b64415f6d..995223d40 100644 --- a/src/mips/psyqo/ordering-table.hh +++ b/src/mips/psyqo/ordering-table.hh @@ -30,6 +30,7 @@ SOFTWARE. #include #include "psyqo/fragment-concept.hh" +#include "psyqo/fragments.hh" #include "psyqo/shared.hh" namespace psyqo { @@ -37,8 +38,8 @@ namespace psyqo { class GPU; class OrderingTableBase { - protected: - static void clear(uint32_t* table, size_t size); + public: + static void clear(psyqo::Fragments::ChainEntry* table, size_t size); }; /** @@ -56,7 +57,7 @@ class OrderingTableBase { * the more precise the sorting will be, but the more memory will be used. */ template -class OrderingTable : private OrderingTableBase { +class OrderingTable : public OrderingTableBase { public: OrderingTable() { clear(); } @@ -84,17 +85,22 @@ class OrderingTable : private OrderingTableBase { template void insert(Frag& frag, int32_t z) { // TODO: cater for big packets - uint32_t* table = m_table + 1; - uint32_t* head = &frag.head; + auto* table = m_table + 1; if constexpr (safety == Safe::Yes) { z = eastl::clamp(z, int32_t(0), int32_t(N - 1)); } - *head = (frag.getActualFragmentSize() << 24) | table[z]; - table[z] = reinterpret_cast(head) & 0xffffff; +#ifdef PS1_PC_PORT + frag.set(table[z].next, frag.getActualFragmentSize()); + table[z].set(&frag, 0); +#else + frag.set(&table[z], frag.getActualFragmentSize()); + table[z].head = reinterpret_cast(&frag) & 0xffffff; +#endif } + // NOTE: can't use from other classes (PCGPU) otherwise + psyqo::Fragments::ChainEntry m_table[N + 1]; private: - uint32_t m_table[N + 1]; friend class GPU; }; diff --git a/src/mips/psyqo/src/gpu.cpp b/src/mips/psyqo/src/gpu.cpp index 2ccb89285..d4e96c2f9 100644 --- a/src/mips/psyqo/src/gpu.cpp +++ b/src/mips/psyqo/src/gpu.cpp @@ -148,7 +148,7 @@ void psyqo::GPU::initialize(const psyqo::GPU::Configuration &config) { if (count > (c_chainThreshold / 4)) { // next one still too big head &= 0xffffff; - m_chainNext = head == 0xffffff ? nullptr : reinterpret_cast(head & 0x7fffff); + m_chainNext = head == 0xffffff ? nullptr : reinterpret_cast(head & 0x7fffff); scheduleNormalDMA(reinterpret_cast(chainNext) + 4, count); } else { // next one is small enough @@ -164,12 +164,12 @@ void psyqo::GPU::initialize(const psyqo::GPU::Configuration &config) { // Did we get interrupted in the middle of a chain? // It means we linked a node too big for the DMA engine to handle, // so we need to send it manually - uint32_t *next = reinterpret_cast(madr | 0x80000000); + uintptr_t *next = reinterpret_cast(madr | 0x80000000); uint32_t head = *next; uint32_t count = head >> 24; head &= 0xffffff; if (head != 0xffffff) { - m_chainNext = reinterpret_cast(head & 0x7fffff); + m_chainNext = reinterpret_cast(head & 0x7fffff); } scheduleNormalDMA(madr + 4, count); return; @@ -422,7 +422,7 @@ void psyqo::GPU::scheduleNormalDMA(uintptr_t data, size_t count) { DMA_CTRL[DMA_GPU].CHCR = 0x01000201; } -void psyqo::GPU::chain(uint32_t *first, uint32_t *last, size_t count) { +void psyqo::GPU::chain(uintptr_t *first, uintptr_t *last, size_t count) { Kernel::assert(count < 256, "Fragment too big to be chained"); if (!m_chainHead) { m_chainHead = first; @@ -464,7 +464,7 @@ void psyqo::GPU::sendChain(eastl::function &&callback, DMA::DmaCallback uint32_t count = head >> 24; head &= 0xffffff; if (count > (c_chainThreshold / 4)) { - m_chainNext = head == 0xffffff ? nullptr : reinterpret_cast(head & 0x7fffff); + m_chainNext = head == 0xffffff ? nullptr : reinterpret_cast(head & 0x7fffff); scheduleNormalDMA(ptr + 4, count); } else { scheduleChainedDMA(ptr); @@ -579,7 +579,7 @@ void psyqo::GPU::pumpCallbacks() { m_lastHSyncCounter = hsyncCounter; } -void psyqo::GPU::scheduleOTC(uint32_t *start, uint32_t count) { m_OTCs[m_parity].emplace_back(start, count); } +void psyqo::GPU::scheduleOTC(uintptr_t *start, uint32_t count) { m_OTCs[m_parity].emplace_back(start, count); } extern uint16_t psyqoExceptionHandlerAdjustFrameCount[]; diff --git a/src/mips/psyqo/src/ordering-table.cpp b/src/mips/psyqo/src/ordering-table.cpp index 107e15449..d40e0f144 100644 --- a/src/mips/psyqo/src/ordering-table.cpp +++ b/src/mips/psyqo/src/ordering-table.cpp @@ -26,9 +26,10 @@ SOFTWARE. #include "psyqo/ordering-table.hh" -void psyqo::OrderingTableBase::clear(uint32_t* table, size_t size) { - table[0] = 0xffffff; +void psyqo::OrderingTableBase::clear(psyqo::Fragments::ChainEntry* table, size_t size) +{ + table[0].setEndMarker(); for (size_t i = 1; i <= size; i++) { - table[i] = reinterpret_cast(&table[i - 1]) & 0xffffff; + table[i].set(&table[i - 1], 0); } }