Core: Implements test-driven corrections (1 of 5)

This commit is contained in:
Gabriel Correia 2024-06-28 13:20:52 -03:00
parent 61b6374a80
commit 44a554fe02
15 changed files with 61 additions and 70 deletions

View File

@ -42,8 +42,8 @@ namespace cosmic {
using FileStat = struct stat;
DescriptorRaii() : hld(-1) {}
DescriptorRaii(i32 fd, bool isManaged = false)
: hld(fd), closeAtDestroy(!isManaged) {
DescriptorRaii(i32 fd, bool isManaged = false) :
hld(fd), closeAtDestroy(!isManaged) {
if (fd != invFile)
fstat(hld, &lastState);
}

View File

@ -136,16 +136,16 @@ namespace cosmic::ee {
cacheIndex = (mem >> 6) & 0x3f;
cacheBank = dataCache;
}
Wrapper<CopCacheLine> roCache{cacheBank[cacheIndex]};
const auto firstWayLayer{roCache->tags[0]};
const auto secondWayLayer{roCache->tags[1]};
CopCacheLine& roCache{cacheBank[cacheIndex]};
const auto firstWayLayer{roCache.tags[0]};
const auto secondWayLayer{roCache.tags[1]};
std::array<Wrapper<u8*>, 2> maps{
Wrapper(virtMap[firstWayLayer >> 12]),
Wrapper(virtMap[secondWayLayer >> 12])
std::array<u8*, 2> maps{
virtMap[firstWayLayer >> 12],
virtMap[secondWayLayer >> 12]
};
const auto firstLrf{roCache->lrf[0]};
const auto secondLrf{roCache->lrf[1]};
const auto firstLrf{roCache.lrf[0]};
const auto secondLrf{roCache.lrf[1]};
for (u32 layers{}; layers < 2; layers++) {
if (maps[0] == virtMap[mem >> 12] && layers == 0 ? firstLrf : secondLrf)
@ -156,15 +156,15 @@ namespace cosmic::ee {
way == 0 ? firstWayLayer & dirtyBit : secondWayLayer & dirtyBit)};
if (write && mode == Data && isDirty) {
auto wrBack{(*maps[way]) + (mem & 0xfc0)};
BitCast<u64*>(wrBack)[0] = roCache->ways[way].large[0];
BitCast<u64*>(wrBack)[1] = roCache->ways[way].large[1];
BitCast<u64*>(wrBack)[2] = roCache->ways[way].large[2];
BitCast<u64*>(wrBack)[3] = roCache->ways[way].large[3];
BitCast<u64*>(wrBack)[4] = roCache->ways[way].large[4];
BitCast<u64*>(wrBack)[5] = roCache->ways[way].large[5];
BitCast<u64*>(wrBack)[6] = roCache->ways[way].large[6];
BitCast<u64*>(wrBack)[7] = roCache->ways[way].large[7];
auto wrBack{maps[way] + (mem & 0xfc0)};
BitCast<u64*>(wrBack)[0] = roCache.ways[way].large[0];
BitCast<u64*>(wrBack)[1] = roCache.ways[way].large[1];
BitCast<u64*>(wrBack)[2] = roCache.ways[way].large[2];
BitCast<u64*>(wrBack)[3] = roCache.ways[way].large[3];
BitCast<u64*>(wrBack)[4] = roCache.ways[way].large[4];
BitCast<u64*>(wrBack)[5] = roCache.ways[way].large[5];
BitCast<u64*>(wrBack)[6] = roCache.ways[way].large[6];
BitCast<u64*>(wrBack)[7] = roCache.ways[way].large[7];
}
if (write) {
// If we are writing to the cache, the dirty bit must be set

View File

@ -3,18 +3,16 @@
namespace cosmic::ee {
EeIntC::EeIntC(std::shared_ptr<EeMipsCore>& mips, std::shared_ptr<vm::Scheduler>& sq) :
ee(mips),
sched(sq) {
ee(mips), sched(sq) {
intcStat = {};
intcMask = {};
check0Id = sched->createSchedTick(true,
[this](u64 unused0, bool unused1) {
int0Check();
});
}
void EeIntC::resetEeInterrupt() {
intcStat = {};
intcMask = {};
check0Id = sched->createSchedTick(true, [this](u64 unused0, bool unused1) {
int0Check();
});
}
void EeIntC::raiseIrq(u8 id) {
@ -25,6 +23,5 @@ namespace cosmic::ee {
sched->placeTickedTask(check0Id, 0x8, {}, true);
}
void EeIntC::int0Check() {
}
}

View File

@ -59,8 +59,7 @@ namespace cosmic::gs {
}
}
void GifBridge::update(u32 cycles) {
if (!maskedPath3() &&
!queueGetSize()) {
if (!maskedPath3() && !queueGetSize()) {
requestDmac(Gif);
}
while (isPathActivated(Gif) && !maskedPath3() &&

View File

@ -67,7 +67,7 @@ namespace cosmic::gs {
break;
default:
// For some reason, the title Ridge Racer V uses the value 11 as a alias for the value 1
ranges::for_each(gswAddrAlias, [&](auto& path) {
ranges::for_each(gswAddrAlias, [&](const auto& path) {
if (path.gameCase == addr) {
gsWrite(path.rCase, data);
}

View File

@ -9,9 +9,8 @@ namespace cosmic::gs {
struct GsPayloadDataPacket {
GsPayloadDataPacket() = default;
GsPayloadDataPacket(u64 bufferSize)
: downloadBuffer(bufferSize)
{}
GsPayloadDataPacket(u64 bufferSize) :
downloadBuffer(bufferSize) {}
u32 qw128Count;
os::MappedMemory<os::vec> downloadBuffer;
u32 indexAddr;

View File

@ -15,12 +15,12 @@ namespace cosmic::iop {
switch (copId) {
case 12: {
std::bitset<8 * 4> bin{};
bin[0x00] = status.iec;
bin[0x01] = status.kuc;
bin[0x02] = status.iep;
bin[0x04] = status.kup;
bin[0x03] = status.ieo;
bin[0x05] = status.kuo;
bin[0] = status.iec;
bin[1] = status.kuc;
bin[2] = status.iep;
bin[3] = status.kup;
bin[4] = status.ieo;
bin[5] = status.kuo;
bin[0x10] = status.isC;
bin[0x16] = status.bev;

View File

@ -33,7 +33,7 @@ namespace cosmic::iop {
void IoMipsCore::takeBranchIf(bool take, i32 pcAddr) {
if (!take && !onBranch)
return;
i64 calcPc{static_cast<i64>(ioPc) + pcAddr};
auto calcPc{static_cast<i64>(ioPc) + pcAddr};
waitPc = static_cast<u32>(calcPc);
if (waitPc & 0x3) {
throw AppErr("Next IOP PC {:#x}: lowest 3 bits couldn't be set", waitPc);

View File

@ -23,29 +23,29 @@ namespace cosmic::iop {
void IopDma::pulseSpu2Chain() {
// When true, it means that we will write into the SPU2 device
bool write2Spu;
auto spu2ch{Wrapper(channels[IopSpu2])};
auto& spu2ch{channels[IopSpu2]};
std::array<u32, 2> packet{};
write2Spu = spu2ch->status.isFrom2Device;
write2Spu = spu2ch.status.isFrom2Device;
if (spu2ch->cyclesDelay) {
spu2ch->cyclesDelay--;
if (spu2ch.cyclesDelay) {
spu2ch.cyclesDelay--;
return;
}
if (spu2ch->cyclesDelay <= 0) {
if (spu2ch.cyclesDelay <= 0) {
if (write2Spu) {
packet[0] = ioDmaRead<u32>(spu2ch->addr);
packet[0] = ioDmaRead<u32>(spu2ch.addr);
spu2->writeDmaData(packet[0]);
} else {
packet[1] = spu2->requestDmaData();
ioDmaWrite<u32>(spu2ch->addr, packet[1]);
ioDmaWrite<u32>(spu2ch.addr, packet[1]);
}
spu2ch->size--;
spu2ch->addr += sizeof(u32);
spu2ch->cyclesDelay = 3;
spu2ch.size--;
spu2ch.addr += sizeof(u32);
spu2ch.cyclesDelay = 3;
}
if (!spu2ch->size) {
spu2ch->wordCount = 0;
if (!spu2ch.size) {
spu2ch.wordCount = 0;
}
}
}

View File

@ -59,7 +59,7 @@ namespace cosmic::iop {
}
u32 IopIntC::readICtrl() {
// Global interrupt disable
const u32 ic{ctrl};
const auto ic{ctrl};
ctrl ^= ctrl;
iopCheck();
return ic;

View File

@ -8,8 +8,8 @@ namespace cosmic::iop {
class IoMipsCore;
class IopIntC {
public:
IopIntC(std::shared_ptr<IoMipsCore>& mips)
: iop(mips) {}
IopIntC(std::shared_ptr<IoMipsCore>& mips) :
iop(mips) {}
void iopCheck();
void resetInterrupt();

View File

@ -72,15 +72,15 @@ namespace cosmic::mio {
u32 countOfQw{};
for (; hasOwner && highCycles > 0; ) {
auto owner{Wrapper(channels.at(hasOwner.getId()))};
auto& owner{channels.at(hasOwner.getId())};
// "Owner" is the privileged channel that will use the available clock pulses at the moment
switch (owner->index) {
switch (owner.index) {
case Vif0:
countOfQw = feedVif0Pipe(*owner).first; break;
countOfQw = feedVif0Pipe(owner).first; break;
}
highCycles -= std::max(countOfQw, static_cast<u32>(1));
if (owner->isScratch)
if (owner.isScratch)
highCycles -= 0xc;
if (!hasOwner)
@ -99,14 +99,12 @@ namespace cosmic::mio {
}
if ((address >> 16 & 0x1000) != 0x1000) {
throw MioErr("(DMA): Reading from an invalid address, unreachable address {}", address);
}
if (cid == invCid) {
} else if (cid == invCid) {
throw MioErr("No channel selected, very serious error...");
}
// For specific channels like: SifX, IpuX, SprX
if ((address >> 4 & 0x400) == 0x400)
cid++;
which = address & 0xff;
if ((address >> 12 & 0xe000) != 0xe000) {
if (which == 0x10)

View File

@ -9,7 +9,7 @@ namespace cosmic::mio {
VirtualPointer virtAddress{};
if (address >= 0x1fc00000 && address < 0x20000000 && isMips) {
virtAddress = directPointer(address, dev);
virtAddress = directPointer(address, dev);
}
if (dev == IopDev) {
if (address < 0x00200000)

View File

@ -70,9 +70,7 @@ namespace cosmic::os {
biosPath;
OsVariable<java::JniBool> turboMode, dumpImage;
OsVariable<java::JniInteger> schedAffinity,
eeMode;
OsVariable<java::JniInteger> schedAffinity, eeMode;
private:
[[maybe_unused]] JavaVM* androidRuntime{};
};

View File

@ -51,10 +51,6 @@ namespace cosmic::vm {
mips->cop2 = std::make_unique<vu::MacroModeCop2>(vus);
mips->timer = std::make_unique<ee::EeTimers>(scheduler, intc);
states->dumpImage.addListener([&]{
dumpMemoryAtClash = *states->dumpImage;
});
user->success("VM loaded successfully");
}
@ -104,12 +100,16 @@ namespace cosmic::vm {
vu01->vpu0Cop2.resetVu();
vu01->vpu1Dlo.resetVu();
states->dumpImage.addListener([&]{
dumpMemoryAtClash = *states->dumpImage;
});
iop->resetIop();
ioDma->resetIoDma();
sound->resetSound();
#if !defined(NDEBUG)
// Memory is assumed to be random content by a early moment before tbe 1ft boot stage,
// Memory is assumed to be random content by an early moment before tbe 1ft boot stage,
// but for debugging purposes, we will cleanup everything from now (at least the EE memory)
iop->iopMem->controller->mapped->iopSoftClean();
iop->iopMem->controller->mapped->sndSoftClean();