mirror of
https://github.com/shadergz/cosmic-station.git
synced 2024-11-23 06:09:40 +00:00
Core
: Implements test-driven corrections (1 of 5)
This commit is contained in:
parent
61b6374a80
commit
44a554fe02
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
@ -59,8 +59,7 @@ namespace cosmic::gs {
|
||||
}
|
||||
}
|
||||
void GifBridge::update(u32 cycles) {
|
||||
if (!maskedPath3() &&
|
||||
!queueGetSize()) {
|
||||
if (!maskedPath3() && !queueGetSize()) {
|
||||
requestDmac(Gif);
|
||||
}
|
||||
while (isPathActivated(Gif) && !maskedPath3() &&
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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{};
|
||||
};
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user