From 6897e4a8be23c9dc15388cbd161da5d3d75129a4 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:55:50 -0500 Subject: [PATCH] rework card read timings --- src/NDS.cpp | 4 +++- src/NDSCart.cpp | 63 ++++++++++++++++++++++++++++++++++++++----------- src/NDSCart.h | 10 +++++--- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/NDS.cpp b/src/NDS.cpp index 5a68b865..a5618d6f 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1712,7 +1712,8 @@ u32 NDS::RunFrame() } //printf("MAIN LOOP: 9 %lli %08X %08llX %i 7 %lli %08X %08llX %i %i %08X\n", ARM9Timestamp>>ARM9ClockShift, ARM9.PC, ARM9.CurInstr, (u8)ARM9.MRTrack.Type, ARM7Timestamp, ARM7.R[15], ARM7.CurInstr, (u8)ARM7.MRTrack.Type, IME[1], IE[1]); - + + NDSCartSlot.ROMPrepareData(); RunTimers(0); GPU.GPU3D.Run(); @@ -1751,6 +1752,7 @@ u32 NDS::RunFrame() } RunTimers(1); + NDSCartSlot.ROMPrepareData(); if (!MainRAMHandle()) break; } diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 29518540..3388933f 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -37,8 +37,7 @@ namespace NDSCart enum { - ROMTransfer_PrepareData = 0, - ROMTransfer_End + ROMTransfer_End = 0 }; // SRAM TODO: emulate write delays??? @@ -1443,7 +1442,6 @@ NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr&& rom) n { NDS.RegisterEventFuncs(Event_ROMTransfer, this, { - MakeEventThunk(NDSCartSlot, ROMPrepareData), MakeEventThunk(NDSCartSlot, ROMEndTransfer) }); NDS.RegisterEventFuncs(Event_ROMSPITransfer, this, {MakeEventThunk(NDSCartSlot, SPITransferDone)}); @@ -1799,7 +1797,10 @@ void NDSCartSlot::ResetCart() noexcept TransferDir = 0; memset(TransferCmd.data(), 0, sizeof(TransferCmd)); TransferCmd[0] = 0xFF; - LastRomTransferTime = 0; + ROMTransferTime[0] = 0; + ROMTransferTime[1] = 0; + QueueIRQ = false; + ScheduledIRQ = false; if (Cart) Cart->Reset(); } @@ -1816,8 +1817,14 @@ void NDSCartSlot::ROMEndTransfer(u32 param) noexcept Cart->ROMCommandFinish(TransferCmd.data(), TransferData.data(), TransferLen); } -void NDSCartSlot::ROMPrepareData(u32 param) noexcept +void NDSCartSlot::ROMPrepareData() noexcept { + u64 curts; + if (NDS.CurCPU) curts = NDS.ARM7Timestamp; + else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift; + + if (curts < ROMTransferTime[0]) return; + if (TransferDir == 0) { if (TransferPos >= TransferLen) @@ -1828,6 +1835,8 @@ void NDSCartSlot::ROMPrepareData(u32 param) noexcept TransferPos += 4; } + ROMTransferTime[0] = -1; + ROMCnt |= (1<<23); if (NDS.ExMemCnt[0] & (1<<11)) @@ -1836,6 +1845,12 @@ void NDSCartSlot::ROMPrepareData(u32 param) noexcept NDS.CheckDMAs(0, 0x05); } +u32 NDSCartSlot::GetROMCnt() noexcept +{ + ROMPrepareData(); + return ROMCnt; +} + void NDSCartSlot::WriteROMCnt(u32 val) noexcept { u32 xferstart = (val & ~ROMCnt) & (1<<31); @@ -1922,10 +1937,18 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept if (datasize == 0) NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0); else - NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMTransfer_PrepareData, 0); + { + u64 curts; + if (NDS.CurCPU) curts = NDS.ARM7Timestamp; + else curts = ((std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift); - if (NDS.CurCPU) LastRomTransferTime = NDS.ARM7Timestamp + xfercycle*(cmddelay+4); - else LastRomTransferTime = ((std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift) + (xfercycle*(cmddelay+4)); + ROMTransferTime[0] = (xfercycle*(cmddelay+4)) + curts; + + if ((TransferPos + 4) < TransferLen) + ROMTransferTime[1] = (xfercycle*(cmddelay+8)) + curts; + else + ROMTransferTime[1] = -1; + } } void NDSCartSlot::AdvanceROMTransfer() noexcept @@ -1938,7 +1961,7 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept u32 delay = 4; if (!(ROMCnt & (1<<30))) { - if (!(TransferPos & 0x1FF)) + if (!((TransferPos+4) & 0x1FF)) delay += ((ROMCnt >> 16) & 0x3F); } @@ -1946,13 +1969,13 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept if (NDS.CurCPU) curts = NDS.ARM7Timestamp; else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift; - s64 nexttransfer = (xfercycle*delay) - (curts - LastRomTransferTime); + ROMTransferTime[0] = ROMTransferTime[1]; - if (nexttransfer < 1) nexttransfer = 1; // CHECKME: the value of 1 here was kinda just a guess? it seems right though. + if ((TransferPos + 4) < TransferLen) + ROMTransferTime[1] = (xfercycle*delay) + curts; + else + ROMTransferTime[1] = -1; - NDS.ScheduleEvent(Event_ROMTransfer, false, nexttransfer, ROMTransfer_PrepareData, 0); - - LastRomTransferTime = curts; } else ROMEndTransfer(0); @@ -1961,6 +1984,12 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept u32 NDSCartSlot::ReadROMData() noexcept { if (ROMCnt & (1<<30)) return 0; + + u64 curts; + if (NDS.CurCPU) curts = NDS.ARM7Timestamp; + else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift; + + ROMPrepareData(); if (ROMCnt & (1<<23)) { @@ -1974,6 +2003,12 @@ void NDSCartSlot::WriteROMData(u32 val) noexcept { if (!(ROMCnt & (1<<30))) return; + u64 curts; + if (NDS.CurCPU) curts = NDS.ARM7Timestamp; + else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<> NDS.ARM9ClockShift; + + ROMPrepareData(); + ROMData = val; if (ROMCnt & (1<<23)) diff --git a/src/NDSCart.h b/src/NDSCart.h index c84aec90..7ee03252 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -410,13 +410,16 @@ public: void WriteROMCnt(u32 val) noexcept; [[nodiscard]] u8 ReadSPIData() const noexcept; void WriteSPIData(u8 val) noexcept; + void ROMPrepareData() noexcept; [[nodiscard]] u8 GetROMCommand(u8 index) const noexcept { return ROMCommand[index]; } void SetROMCommand(u8 index, u8 val) noexcept { ROMCommand[index] = val; } - [[nodiscard]] u32 GetROMCnt() const noexcept { return ROMCnt; } + [[nodiscard]] u32 GetROMCnt() noexcept; + [[nodiscard]] u16 GetSPICnt() const noexcept { return SPICnt; } void SetSPICnt(u16 val) noexcept { SPICnt = val; } + private: friend class CartCommon; melonDS::NDS& NDS; @@ -426,6 +429,8 @@ private: u8 SPIData = 0; u32 SPIDataPos = 0; bool SPIHold = false; + bool QueueIRQ; + bool ScheduledIRQ; u32 ROMData = 0; @@ -442,7 +447,7 @@ private: u64 Key2_X = 0; u64 Key2_Y = 0; - u64 LastRomTransferTime; + u64 ROMTransferTime[2]; void Key1_Encrypt(u32* data) const noexcept; void Key1_Decrypt(u32* data) const noexcept; @@ -451,7 +456,6 @@ private: void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod) noexcept; void Key2_Encrypt(const u8* data, u32 len) noexcept; void ROMEndTransfer(u32 param) noexcept; - void ROMPrepareData(u32 param) noexcept; void AdvanceROMTransfer() noexcept; void SPITransferDone(u32 param) noexcept; };