rework card read timings
This commit is contained in:
parent
14c765d5ed
commit
6897e4a8be
|
@ -1713,6 +1713,7 @@ 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]);
|
//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);
|
RunTimers(0);
|
||||||
GPU.GPU3D.Run();
|
GPU.GPU3D.Run();
|
||||||
|
|
||||||
|
@ -1751,6 +1752,7 @@ u32 NDS::RunFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
RunTimers(1);
|
RunTimers(1);
|
||||||
|
NDSCartSlot.ROMPrepareData();
|
||||||
|
|
||||||
if (!MainRAMHandle()) break;
|
if (!MainRAMHandle()) break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,7 @@ namespace NDSCart
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ROMTransfer_PrepareData = 0,
|
ROMTransfer_End = 0
|
||||||
ROMTransfer_End
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// SRAM TODO: emulate write delays???
|
// SRAM TODO: emulate write delays???
|
||||||
|
@ -1443,7 +1442,6 @@ NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& rom) n
|
||||||
{
|
{
|
||||||
NDS.RegisterEventFuncs(Event_ROMTransfer, this,
|
NDS.RegisterEventFuncs(Event_ROMTransfer, this,
|
||||||
{
|
{
|
||||||
MakeEventThunk(NDSCartSlot, ROMPrepareData),
|
|
||||||
MakeEventThunk(NDSCartSlot, ROMEndTransfer)
|
MakeEventThunk(NDSCartSlot, ROMEndTransfer)
|
||||||
});
|
});
|
||||||
NDS.RegisterEventFuncs(Event_ROMSPITransfer, this, {MakeEventThunk(NDSCartSlot, SPITransferDone)});
|
NDS.RegisterEventFuncs(Event_ROMSPITransfer, this, {MakeEventThunk(NDSCartSlot, SPITransferDone)});
|
||||||
|
@ -1799,7 +1797,10 @@ void NDSCartSlot::ResetCart() noexcept
|
||||||
TransferDir = 0;
|
TransferDir = 0;
|
||||||
memset(TransferCmd.data(), 0, sizeof(TransferCmd));
|
memset(TransferCmd.data(), 0, sizeof(TransferCmd));
|
||||||
TransferCmd[0] = 0xFF;
|
TransferCmd[0] = 0xFF;
|
||||||
LastRomTransferTime = 0;
|
ROMTransferTime[0] = 0;
|
||||||
|
ROMTransferTime[1] = 0;
|
||||||
|
QueueIRQ = false;
|
||||||
|
ScheduledIRQ = false;
|
||||||
|
|
||||||
if (Cart) Cart->Reset();
|
if (Cart) Cart->Reset();
|
||||||
}
|
}
|
||||||
|
@ -1816,8 +1817,14 @@ void NDSCartSlot::ROMEndTransfer(u32 param) noexcept
|
||||||
Cart->ROMCommandFinish(TransferCmd.data(), TransferData.data(), TransferLen);
|
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)-1)) >> NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (curts < ROMTransferTime[0]) return;
|
||||||
|
|
||||||
if (TransferDir == 0)
|
if (TransferDir == 0)
|
||||||
{
|
{
|
||||||
if (TransferPos >= TransferLen)
|
if (TransferPos >= TransferLen)
|
||||||
|
@ -1828,6 +1835,8 @@ void NDSCartSlot::ROMPrepareData(u32 param) noexcept
|
||||||
TransferPos += 4;
|
TransferPos += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ROMTransferTime[0] = -1;
|
||||||
|
|
||||||
ROMCnt |= (1<<23);
|
ROMCnt |= (1<<23);
|
||||||
|
|
||||||
if (NDS.ExMemCnt[0] & (1<<11))
|
if (NDS.ExMemCnt[0] & (1<<11))
|
||||||
|
@ -1836,6 +1845,12 @@ void NDSCartSlot::ROMPrepareData(u32 param) noexcept
|
||||||
NDS.CheckDMAs(0, 0x05);
|
NDS.CheckDMAs(0, 0x05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 NDSCartSlot::GetROMCnt() noexcept
|
||||||
|
{
|
||||||
|
ROMPrepareData();
|
||||||
|
return ROMCnt;
|
||||||
|
}
|
||||||
|
|
||||||
void NDSCartSlot::WriteROMCnt(u32 val) noexcept
|
void NDSCartSlot::WriteROMCnt(u32 val) noexcept
|
||||||
{
|
{
|
||||||
u32 xferstart = (val & ~ROMCnt) & (1<<31);
|
u32 xferstart = (val & ~ROMCnt) & (1<<31);
|
||||||
|
@ -1922,10 +1937,18 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept
|
||||||
if (datasize == 0)
|
if (datasize == 0)
|
||||||
NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0);
|
NDS.ScheduleEvent(Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0);
|
||||||
else
|
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)-1)) >> NDS.ARM9ClockShift);
|
||||||
|
|
||||||
if (NDS.CurCPU) LastRomTransferTime = NDS.ARM7Timestamp + xfercycle*(cmddelay+4);
|
ROMTransferTime[0] = (xfercycle*(cmddelay+4)) + curts;
|
||||||
else LastRomTransferTime = ((std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-1)) >> NDS.ARM9ClockShift) + (xfercycle*(cmddelay+4));
|
|
||||||
|
if ((TransferPos + 4) < TransferLen)
|
||||||
|
ROMTransferTime[1] = (xfercycle*(cmddelay+8)) + curts;
|
||||||
|
else
|
||||||
|
ROMTransferTime[1] = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NDSCartSlot::AdvanceROMTransfer() noexcept
|
void NDSCartSlot::AdvanceROMTransfer() noexcept
|
||||||
|
@ -1938,7 +1961,7 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept
|
||||||
u32 delay = 4;
|
u32 delay = 4;
|
||||||
if (!(ROMCnt & (1<<30)))
|
if (!(ROMCnt & (1<<30)))
|
||||||
{
|
{
|
||||||
if (!(TransferPos & 0x1FF))
|
if (!((TransferPos+4) & 0x1FF))
|
||||||
delay += ((ROMCnt >> 16) & 0x3F);
|
delay += ((ROMCnt >> 16) & 0x3F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1946,13 +1969,13 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
||||||
else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-1)) >> NDS.ARM9ClockShift;
|
else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-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
|
else
|
||||||
ROMEndTransfer(0);
|
ROMEndTransfer(0);
|
||||||
|
@ -1962,6 +1985,12 @@ u32 NDSCartSlot::ReadROMData() noexcept
|
||||||
{
|
{
|
||||||
if (ROMCnt & (1<<30)) return 0;
|
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)-1)) >> NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
ROMPrepareData();
|
||||||
|
|
||||||
if (ROMCnt & (1<<23))
|
if (ROMCnt & (1<<23))
|
||||||
{
|
{
|
||||||
AdvanceROMTransfer();
|
AdvanceROMTransfer();
|
||||||
|
@ -1974,6 +2003,12 @@ void NDSCartSlot::WriteROMData(u32 val) noexcept
|
||||||
{
|
{
|
||||||
if (!(ROMCnt & (1<<30))) return;
|
if (!(ROMCnt & (1<<30))) return;
|
||||||
|
|
||||||
|
u64 curts;
|
||||||
|
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
||||||
|
else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-1)) >> NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
ROMPrepareData();
|
||||||
|
|
||||||
ROMData = val;
|
ROMData = val;
|
||||||
|
|
||||||
if (ROMCnt & (1<<23))
|
if (ROMCnt & (1<<23))
|
||||||
|
|
|
@ -410,13 +410,16 @@ public:
|
||||||
void WriteROMCnt(u32 val) noexcept;
|
void WriteROMCnt(u32 val) noexcept;
|
||||||
[[nodiscard]] u8 ReadSPIData() const noexcept;
|
[[nodiscard]] u8 ReadSPIData() const noexcept;
|
||||||
void WriteSPIData(u8 val) noexcept;
|
void WriteSPIData(u8 val) noexcept;
|
||||||
|
void ROMPrepareData() noexcept;
|
||||||
|
|
||||||
[[nodiscard]] u8 GetROMCommand(u8 index) const noexcept { return ROMCommand[index]; }
|
[[nodiscard]] u8 GetROMCommand(u8 index) const noexcept { return ROMCommand[index]; }
|
||||||
void SetROMCommand(u8 index, u8 val) noexcept { ROMCommand[index] = val; }
|
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; }
|
[[nodiscard]] u16 GetSPICnt() const noexcept { return SPICnt; }
|
||||||
void SetSPICnt(u16 val) noexcept { SPICnt = val; }
|
void SetSPICnt(u16 val) noexcept { SPICnt = val; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CartCommon;
|
friend class CartCommon;
|
||||||
melonDS::NDS& NDS;
|
melonDS::NDS& NDS;
|
||||||
|
@ -426,6 +429,8 @@ private:
|
||||||
u8 SPIData = 0;
|
u8 SPIData = 0;
|
||||||
u32 SPIDataPos = 0;
|
u32 SPIDataPos = 0;
|
||||||
bool SPIHold = false;
|
bool SPIHold = false;
|
||||||
|
bool QueueIRQ;
|
||||||
|
bool ScheduledIRQ;
|
||||||
|
|
||||||
u32 ROMData = 0;
|
u32 ROMData = 0;
|
||||||
|
|
||||||
|
@ -442,7 +447,7 @@ private:
|
||||||
u64 Key2_X = 0;
|
u64 Key2_X = 0;
|
||||||
u64 Key2_Y = 0;
|
u64 Key2_Y = 0;
|
||||||
|
|
||||||
u64 LastRomTransferTime;
|
u64 ROMTransferTime[2];
|
||||||
|
|
||||||
void Key1_Encrypt(u32* data) const noexcept;
|
void Key1_Encrypt(u32* data) const noexcept;
|
||||||
void Key1_Decrypt(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 Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod) noexcept;
|
||||||
void Key2_Encrypt(const u8* data, u32 len) noexcept;
|
void Key2_Encrypt(const u8* data, u32 len) noexcept;
|
||||||
void ROMEndTransfer(u32 param) noexcept;
|
void ROMEndTransfer(u32 param) noexcept;
|
||||||
void ROMPrepareData(u32 param) noexcept;
|
|
||||||
void AdvanceROMTransfer() noexcept;
|
void AdvanceROMTransfer() noexcept;
|
||||||
void SPITransferDone(u32 param) noexcept;
|
void SPITransferDone(u32 param) noexcept;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue