Core: Fixes issues of unconsciousness when copying or moving objects

This commit is contained in:
Correia 2024-05-04 20:37:44 -03:00
parent e6983f3d03
commit f98d1b9301
6 changed files with 34 additions and 41 deletions

View File

@ -16,8 +16,8 @@ namespace cosmic::java {
}
}
void feedVm(JNIEnv* e) {
if ((jv = e->GetVersion()) != JNI_VERSION_1_6)
;
if ((jv = e->GetVersion()) != JNI_VERSION_1_6) {
}
if (!jvm)
e->GetJavaVM(&jvm);
gnv = e;

View File

@ -14,31 +14,28 @@ namespace cosmic::mio {
}
DmaController::DmaController() {
queued.resize(channels.size());
getStagedChannel = [&](const DmaChannelId requested) {
std::list<DmaChannel>::iterator b, e;
getStagedChannel = [&](const DmaChannelId requested) -> ChannelIterator {
ChannelIterator b, e;
b = std::begin(queued);
e = std::end(queued);
bool isValid{};
std::array<u32, 2> crc;
for (; b != e && !isValid; b++) {
std::array<DmaChannel, 9>::value_type local{};
std::array<DmaChannel, 9>::value_type staged{};
staged = *b;
local = channels[requested];
for (; b != e; b++) {
ChannelIterator::value_type
local{channels[requested]},
staged{*b};
crc[0] = cpu::check32({BitCast<u8*>(&staged), sizeof(staged)});
crc[1] = cpu::check32({BitCast<u8*>(&local), sizeof(local)});
isValid = crc[0] == crc[1];
if (crc[0] == crc[1]) {
e = b;
break;
}
}
if (isValid)
return b;
return e;
return std::ref(e);
};
std::list<DmaChannel> empty{};
queued.swap(empty);
std::list<DmaChannel> emptyDma{};
queued.swap(emptyDma);
}
void DmaController::resetMa() {
@ -92,12 +89,9 @@ namespace cosmic::mio {
highCycles = 0;
}
Ref<u32> DmaController::dmaVirtSolver(u32 address) {
u64 invCid;
u64 cid;
u8 which;
invCid = channels.size();
cid = invCid;
u64 invCid = channels.size();
u64 cid = invCid;
u8 which{};
switch (address >> 12) {
case 0x8:
@ -180,10 +174,10 @@ namespace cosmic::mio {
if (!ch->qwc)
return std::make_pair(false, 0);
u32 maxQwc{qwcPerRequest - (ch->adr >> 0x4) & 0x7};
if (maxQwc >= std::numeric_limits<u16>::max())
;
if (maxQwc >= std::numeric_limits<u16>::max()) {
}
u32 toTransfer{std::min(ch->qwc, static_cast<u16>(maxQwc))};
const u32 toTransfer{std::min(ch->qwc, static_cast<u16>(maxQwc))};
return {true, toTransfer};
}
void DmaController::disableChannel(DirectChannels channel, bool disableRequest) {
@ -203,8 +197,7 @@ namespace cosmic::mio {
hasOwner.unselect();
return;
}
std::list<DmaChannel>::iterator del;
del = getStagedChannel(static_cast<DmaChannelId>(index));
auto del{getStagedChannel(static_cast<DmaChannelId>(index))};
// Only one stream to remove? I don't understand why yet
if (del != std::end(queued)) {
queued.erase(del);

View File

@ -140,6 +140,7 @@ namespace cosmic::mio {
}
private:
std::list<DmaChannel> queued;
using ChannelIterator = std::list<DmaChannel>::iterator;
u32 intStatus;
OwnerChannel hasOwner;
i64 highCycles;
@ -149,11 +150,11 @@ namespace cosmic::mio {
void switchChannel();
void findNextChannel();
std::function<std::list<DmaChannel>::iterator(DmaChannelId)> getStagedChannel;
union {
std::array<DmaChannel, 0x9> channels;
};
std::function<ChannelIterator(DmaChannelId)> getStagedChannel;
DmaRegister priorityCtrl{0x1f8010f0}; // PCR
u32 stallAddress; // STADR
std::shared_ptr<MemoryPipe> pipe;

View File

@ -99,7 +99,6 @@ namespace cosmic::vu {
if (status.isVuExecuting) {
if (ee->getHtzCycles(true) >= clock.count)
return;
}
}
void VectorUnit::updateDeltaCycles(i64 add, bool incCount) {
@ -195,7 +194,7 @@ namespace cosmic::vu {
}
return {};
}
void VectorUnit::establishVif(u16* conTops, Ref<gs::GifBridge> gif) {
void VectorUnit::establishVif(u16 conTops[2], Ref<gs::GifBridge> gif) {
for (u8 top{}; top < 2; top++)
vifTops[top] = &conTops[top];
@ -203,8 +202,8 @@ namespace cosmic::vu {
vu1Gif = gif;
}
void VectorUnit::pushIntPipe(u8 ir, u8 fir) {
if (ir > 0xf || fir > 0xf)
;
if (ir > 0xf || fir > 0xf) {
}
intPipeline.pushInt(ir, intsRegs[ir], ir == fir);
}
void VectorUnit::startProgram(u32 addr) {

View File

@ -84,7 +84,7 @@ namespace cosmic::vu {
void softwareReset();
void pulse(u32 cycles);
// Some implementations add a cycle delay at the beginning of the program (I won't do it now;
// Some implementations add a cycle delay at the beginning of the program (I won't do it now -
// I still don't know how to solve this problem)
void startProgram(u32 addr);
void stopProgram();
@ -99,8 +99,8 @@ namespace cosmic::vu {
alignas(512) std::array<VuReg, 32> VuGPRs;
alignas(32) std::array<VuIntReg, 16> intsRegs;
void establishVif(u16* conTops, Ref<gs::GifBridge> gif);
// P register: Used by EFU to store the result; waitp could be used to stall the execution
void establishVif(u16 conTops[2], Ref<gs::GifBridge> gif);
// P register: Used by EFU to store the result - waitp could be used to stall the execution
// while EFU doesn't finish the previous calculation
VuRegUnique spI, spQ, spR, spP;
VuRegUnique

View File

@ -5,7 +5,7 @@
#include <os/neon_simd.h>
namespace cosmic::vu {
enum FifoMethodVif {
// Clean the valid bit, and if (gsValue == 0x2), clean gsData
// Clear the valid bit and delete the stored value at the specified index
FifoClean,
// Set a valid value
FifoSet,
@ -13,8 +13,8 @@ namespace cosmic::vu {
FifoLoad
};
// A vector-based FIFO; we will not delete our FIFO data, just mark it as trash.
// This will avoid vector data movement and FIFO allocation and de-allocation
// A vector-based FIFO; we will not delete our FIFO data, just mark it as trash
// This will satisfy the need to not reallocate queue data during execution
struct VifDataPack {
u32 gsData;
bool isValid;