theoretically improve dma responsiveness?
in practice seems to make no difference...
This commit is contained in:
parent
98d0a6b371
commit
22f1b4d90c
16
src/ARM.cpp
16
src/ARM.cpp
|
@ -1447,6 +1447,22 @@ void ARMv5::ForceInterlock_2()
|
||||||
NDS.ARM9Timestamp = TimestampMemory + ILForceDelay;
|
NDS.ARM9Timestamp = TimestampMemory + ILForceDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::QueueFunction(void (ARMv5::*QueueEntry)(void))
|
||||||
|
{
|
||||||
|
if ((NDS.ARM9Timestamp >= NDS.ARM9Target) || (MRTrack.Type != MainRAMType::Null))
|
||||||
|
FuncQueue[FuncQueueFill++] = QueueEntry;
|
||||||
|
else
|
||||||
|
(this->*QueueEntry)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv4::QueueFunction(void (ARMv4::*QueueEntry)(void))
|
||||||
|
{
|
||||||
|
if ((NDS.ARM7Timestamp >= NDS.ARM7Target) || (MRTrack.Type != MainRAMType::Null))
|
||||||
|
FuncQueue[FuncQueueFill++] = QueueEntry;
|
||||||
|
else
|
||||||
|
(this->*QueueEntry)();
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv4::CodeRead16(u32 addr)
|
void ARMv4::CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
if ((addr >> 24) == 0x02)
|
if ((addr >> 24) == 0x02)
|
||||||
|
|
27
src/ARM.h
27
src/ARM.h
|
@ -723,14 +723,8 @@ public:
|
||||||
* @return Value of the cp15 register
|
* @return Value of the cp15 register
|
||||||
*/
|
*/
|
||||||
u32 CP15Read(const u32 id) const;
|
u32 CP15Read(const u32 id) const;
|
||||||
|
|
||||||
inline void QueueFunction(void (ARMv5::*QueueEntry)(void))
|
void QueueFunction(void (ARMv5::*QueueEntry)(void));
|
||||||
{
|
|
||||||
if (MRTrack.Type != MainRAMType::Null)
|
|
||||||
FuncQueue[FuncQueueFill++] = QueueEntry;
|
|
||||||
else
|
|
||||||
(this->*QueueEntry)();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue Functions
|
// Queue Functions
|
||||||
void StartExecARM();
|
void StartExecARM();
|
||||||
|
@ -744,27 +738,36 @@ public:
|
||||||
void JumpTo_3C();
|
void JumpTo_3C();
|
||||||
void JumpTo_4();
|
void JumpTo_4();
|
||||||
void CodeRead32_2();
|
void CodeRead32_2();
|
||||||
|
void CodeRead32_3();
|
||||||
void ICacheLookup_2();
|
void ICacheLookup_2();
|
||||||
void DAbortHandle();
|
void DAbortHandle();
|
||||||
void DCacheFin8();
|
void DCacheFin8();
|
||||||
void DRead8_2();
|
void DRead8_2();
|
||||||
void DRead8_3();
|
void DRead8_3();
|
||||||
|
void DRead8_4();
|
||||||
void DCacheFin16();
|
void DCacheFin16();
|
||||||
void DRead16_2();
|
void DRead16_2();
|
||||||
void DRead16_3();
|
void DRead16_3();
|
||||||
|
void DRead16_4();
|
||||||
void DCacheFin32();
|
void DCacheFin32();
|
||||||
void DRead32_2();
|
void DRead32_2();
|
||||||
void DRead32_3();
|
void DRead32_3();
|
||||||
|
void DRead32_4();
|
||||||
void DRead32S_2();
|
void DRead32S_2();
|
||||||
void DRead32S_3();
|
void DRead32S_3();
|
||||||
|
void DRead32S_4();
|
||||||
void DWrite8_2();
|
void DWrite8_2();
|
||||||
void DWrite8_3();
|
void DWrite8_3();
|
||||||
|
void DWrite8_4();
|
||||||
void DWrite16_2();
|
void DWrite16_2();
|
||||||
void DWrite16_3();
|
void DWrite16_3();
|
||||||
|
void DWrite16_4();
|
||||||
void DWrite32_2();
|
void DWrite32_2();
|
||||||
void DWrite32_3();
|
void DWrite32_3();
|
||||||
|
void DWrite32_4();
|
||||||
void DWrite32S_2();
|
void DWrite32S_2();
|
||||||
void DWrite32S_3();
|
void DWrite32S_3();
|
||||||
|
void DWrite32S_4();
|
||||||
void WBCheck_2();
|
void WBCheck_2();
|
||||||
void ICachePrefetch_2();
|
void ICachePrefetch_2();
|
||||||
void DCacheLookup_2();
|
void DCacheLookup_2();
|
||||||
|
@ -933,13 +936,7 @@ public:
|
||||||
void AddCycles_CDI() override;
|
void AddCycles_CDI() override;
|
||||||
void AddCycles_CD() override;
|
void AddCycles_CD() override;
|
||||||
|
|
||||||
inline void QueueFunction(void (ARMv4::*QueueEntry)(void))
|
void QueueFunction(void (ARMv4::*QueueEntry)(void));
|
||||||
{
|
|
||||||
if (MRTrack.Type != MainRAMType::Null)
|
|
||||||
FuncQueue[FuncQueueFill++] = QueueEntry;
|
|
||||||
else
|
|
||||||
(this->*QueueEntry)();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartExecARM();
|
void StartExecARM();
|
||||||
void StartExecTHUMB();
|
void StartExecTHUMB();
|
||||||
|
|
169
src/CP15.cpp
169
src/CP15.cpp
|
@ -2213,7 +2213,13 @@ void ARMv5::CodeRead32(u32 addr)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FetchAddr[16] = addr;
|
||||||
|
QueueFunction(&ARMv5::CodeRead32_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::CodeRead32_2()
|
||||||
|
{
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
// bus reads can only overlap with dcache streaming by 6 cycles
|
// bus reads can only overlap with dcache streaming by 6 cycles
|
||||||
if (DCacheStreamPtr < 7)
|
if (DCacheStreamPtr < 7)
|
||||||
|
@ -2222,16 +2228,15 @@ void ARMv5::CodeRead32(u32 addr)
|
||||||
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PU_Map[addr>>12] & 0x30)
|
if (PU_Map[FetchAddr[16]>>12] & 0x30)
|
||||||
WriteBufferDrain();
|
WriteBufferDrain();
|
||||||
else
|
else
|
||||||
WriteBufferCheck<3>();
|
WriteBufferCheck<3>();
|
||||||
|
|
||||||
FetchAddr[16] = addr;
|
QueueFunction(&ARMv5::CodeRead32_3);
|
||||||
QueueFunction(&ARMv5::CodeRead32_2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::CodeRead32_2()
|
void ARMv5::CodeRead32_3()
|
||||||
{
|
{
|
||||||
u32 addr = FetchAddr[16];
|
u32 addr = FetchAddr[16];
|
||||||
|
|
||||||
|
@ -2346,6 +2351,15 @@ void ARMv5::DRead8_2()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QueueFunction(&ARMv5::DRead8_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead8_3()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 dummy; u32* val = (LDRFailedRegs & (1<<reg)) ? &dummy : &R[reg];
|
||||||
|
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
// checkme: does dcache trigger this?
|
// checkme: does dcache trigger this?
|
||||||
|
@ -2360,10 +2374,10 @@ void ARMv5::DRead8_2()
|
||||||
else
|
else
|
||||||
WriteBufferCheck<1>();
|
WriteBufferCheck<1>();
|
||||||
|
|
||||||
QueueFunction(&ARMv5::DRead8_3);
|
QueueFunction(&ARMv5::DRead8_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DRead8_3()
|
void ARMv5::DRead8_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -2461,6 +2475,15 @@ void ARMv5::DRead16_2()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QueueFunction(&ARMv5::DRead16_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead16_3()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 dummy; u32* val = (LDRFailedRegs & (1<<reg)) ? &dummy : &R[reg];
|
||||||
|
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
// checkme: does cache trigger this?
|
// checkme: does cache trigger this?
|
||||||
|
@ -2475,10 +2498,10 @@ void ARMv5::DRead16_2()
|
||||||
else
|
else
|
||||||
WriteBufferCheck<1>();
|
WriteBufferCheck<1>();
|
||||||
|
|
||||||
QueueFunction(&ARMv5::DRead16_3);
|
QueueFunction(&ARMv5::DRead16_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DRead16_3()
|
void ARMv5::DRead16_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -2576,7 +2599,16 @@ void ARMv5::DRead32_2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QueueFunction(&ARMv5::DRead32_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead32_3()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 dummy; u32* val = (LDRFailedRegs & (1<<reg)) ? &dummy : &R[reg];
|
||||||
|
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
// checkme: does cache trigger this?
|
// checkme: does cache trigger this?
|
||||||
|
@ -2591,10 +2623,10 @@ void ARMv5::DRead32_2()
|
||||||
else
|
else
|
||||||
WriteBufferCheck<1>();
|
WriteBufferCheck<1>();
|
||||||
|
|
||||||
QueueFunction(&ARMv5::DRead32_3);
|
QueueFunction(&ARMv5::DRead32_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DRead32_3()
|
void ARMv5::DRead32_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -2678,7 +2710,16 @@ void ARMv5::DRead32S_2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QueueFunction(&ARMv5::DRead32S_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead32S_3()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 dummy; u32* val = (LDRFailedRegs & (1<<reg)) ? &dummy : &R[reg];
|
||||||
|
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
// checkme: does cache trigger this?
|
// checkme: does cache trigger this?
|
||||||
|
@ -2693,10 +2734,10 @@ void ARMv5::DRead32S_2()
|
||||||
else
|
else
|
||||||
WriteBufferCheck<1>();
|
WriteBufferCheck<1>();
|
||||||
|
|
||||||
QueueFunction(&ARMv5::DRead32S_3);
|
QueueFunction(&ARMv5::DRead32S_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DRead32S_3()
|
void ARMv5::DRead32S_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -2815,16 +2856,6 @@ void ARMv5::DWrite8_2()
|
||||||
|
|
||||||
if (!(PU_Map[addr>>12] & (0x30)))
|
if (!(PU_Map[addr>>12] & (0x30)))
|
||||||
{
|
{
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
|
||||||
// checkme: do buffered writes trigger this?
|
|
||||||
if (ICacheStreamPtr < 7)
|
|
||||||
{
|
|
||||||
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
|
||||||
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteBufferCheck<2>();
|
|
||||||
QueueFunction(&ARMv5::DWrite8_3);
|
QueueFunction(&ARMv5::DWrite8_3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2837,6 +2868,21 @@ void ARMv5::DWrite8_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DWrite8_3()
|
void ARMv5::DWrite8_3()
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
|
// checkme: do buffered writes trigger this?
|
||||||
|
if (ICacheStreamPtr < 7)
|
||||||
|
{
|
||||||
|
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
||||||
|
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteBufferCheck<2>();
|
||||||
|
QueueFunction(&ARMv5::DWrite8_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite8_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(STRRegs);
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -2929,16 +2975,6 @@ void ARMv5::DWrite16_2()
|
||||||
|
|
||||||
if (!(PU_Map[addr>>12] & 0x30))
|
if (!(PU_Map[addr>>12] & 0x30))
|
||||||
{
|
{
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
|
||||||
// checkme: do buffered writes trigger this?
|
|
||||||
if (ICacheStreamPtr < 7)
|
|
||||||
{
|
|
||||||
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
|
||||||
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteBufferCheck<2>();
|
|
||||||
QueueFunction(&ARMv5::DWrite16_3);
|
QueueFunction(&ARMv5::DWrite16_3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2951,6 +2987,21 @@ void ARMv5::DWrite16_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DWrite16_3()
|
void ARMv5::DWrite16_3()
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
|
// checkme: do buffered writes trigger this?
|
||||||
|
if (ICacheStreamPtr < 7)
|
||||||
|
{
|
||||||
|
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
||||||
|
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteBufferCheck<2>();
|
||||||
|
QueueFunction(&ARMv5::DWrite16_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite16_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(STRRegs);
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -3048,16 +3099,6 @@ void ARMv5::DWrite32_2()
|
||||||
|
|
||||||
if (!(PU_Map[addr>>12] & 0x30))
|
if (!(PU_Map[addr>>12] & 0x30))
|
||||||
{
|
{
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
|
||||||
// checkme: do buffered writes trigger this?
|
|
||||||
if (ICacheStreamPtr < 7)
|
|
||||||
{
|
|
||||||
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
|
||||||
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteBufferCheck<2>();
|
|
||||||
QueueFunction(&ARMv5::DWrite32_3);
|
QueueFunction(&ARMv5::DWrite32_3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3071,6 +3112,21 @@ void ARMv5::DWrite32_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DWrite32_3()
|
void ARMv5::DWrite32_3()
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
|
// checkme: do buffered writes trigger this?
|
||||||
|
if (ICacheStreamPtr < 7)
|
||||||
|
{
|
||||||
|
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
||||||
|
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteBufferCheck<2>();
|
||||||
|
QueueFunction(&ARMv5::DWrite32_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite32_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(STRRegs);
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
@ -3162,15 +3218,6 @@ void ARMv5::DWrite32S_2()
|
||||||
|
|
||||||
if (!(PU_Map[addr>>12] & 0x30)) // non-bufferable
|
if (!(PU_Map[addr>>12] & 0x30)) // non-bufferable
|
||||||
{
|
{
|
||||||
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
|
||||||
// bus reads can only overlap with icache streaming by 6 cycles
|
|
||||||
// checkme: do buffered writes trigger this?
|
|
||||||
if (ICacheStreamPtr < 7)
|
|
||||||
{
|
|
||||||
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
|
||||||
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
|
||||||
}
|
|
||||||
WriteBufferCheck<2>();
|
|
||||||
QueueFunction(&ARMv5::DWrite32S_3);
|
QueueFunction(&ARMv5::DWrite32S_3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3181,6 +3228,20 @@ void ARMv5::DWrite32S_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DWrite32S_3()
|
void ARMv5::DWrite32S_3()
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
// bus reads can only overlap with icache streaming by 6 cycles
|
||||||
|
// checkme: do buffered writes trigger this?
|
||||||
|
if (ICacheStreamPtr < 7)
|
||||||
|
{
|
||||||
|
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
|
||||||
|
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
|
||||||
|
}
|
||||||
|
WriteBufferCheck<2>();
|
||||||
|
QueueFunction(&ARMv5::DWrite32S_4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite32S_4()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(STRRegs);
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
u32 addr = FetchAddr[reg];
|
u32 addr = FetchAddr[reg];
|
||||||
|
|
11
src/NDS.cpp
11
src/NDS.cpp
|
@ -792,7 +792,7 @@ void NDS::SetARM9BIOS(const std::array<u8, ARM9BIOSSize>& bios) noexcept
|
||||||
|
|
||||||
u64 NDS::NextTarget()
|
u64 NDS::NextTarget()
|
||||||
{
|
{
|
||||||
u64 minEvent = UINT64_MAX;
|
u64 minEvent = std::max(SysTimestamp+1, NDSCartSlot.ROMTransferTime[0]);
|
||||||
|
|
||||||
u32 mask = SchedListMask;
|
u32 mask = SchedListMask;
|
||||||
for (int i = 0; i < Event_MAX; i++)
|
for (int i = 0; i < Event_MAX; i++)
|
||||||
|
@ -1740,7 +1740,6 @@ u32 NDS::RunFrame()
|
||||||
u64 target = NextTarget();
|
u64 target = NextTarget();
|
||||||
|
|
||||||
ARM9Target = target << ARM9ClockShift;
|
ARM9Target = target << ARM9ClockShift;
|
||||||
//ARM7Target = target;
|
|
||||||
|
|
||||||
while (std::max(std::max(ARM9Timestamp, DMA9Timestamp), A9ContentionTS << ARM9ClockShift) < ARM9Target)
|
while (std::max(std::max(ARM9Timestamp, DMA9Timestamp), A9ContentionTS << ARM9ClockShift) < ARM9Target)
|
||||||
{
|
{
|
||||||
|
@ -1776,12 +1775,10 @@ 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();
|
||||||
|
|
||||||
//if (MainRAMHandle()) break;
|
|
||||||
MainRAMHandle();
|
MainRAMHandle();
|
||||||
|
|
||||||
target = std::max(std::max(ARM9Timestamp, DMA9Timestamp) >> ARM9ClockShift, A9ContentionTS);
|
target = std::max(std::max(ARM9Timestamp, DMA9Timestamp) >> ARM9ClockShift, A9ContentionTS);
|
||||||
|
@ -1816,12 +1813,12 @@ u32 NDS::RunFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
RunTimers(1);
|
RunTimers(1);
|
||||||
NDSCartSlot.ROMPrepareData();
|
|
||||||
|
|
||||||
if (!MainRAMHandle()) break;
|
if (!MainRAMHandle()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDSCartSlot.ROMPrepareData();
|
||||||
RunSystem(target);
|
RunSystem(target);
|
||||||
|
|
||||||
if (CPUStop & CPUStop_Sleep)
|
if (CPUStop & CPUStop_Sleep)
|
||||||
|
|
|
@ -1818,8 +1818,8 @@ void NDSCartSlot::ROMEndTransfer(u32 param) noexcept
|
||||||
void NDSCartSlot::ROMPrepareData() noexcept
|
void NDSCartSlot::ROMPrepareData() noexcept
|
||||||
{
|
{
|
||||||
u64 curts;
|
u64 curts;
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.ExMemCnt[0] & (1<<11)) 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;
|
||||||
|
|
||||||
if (curts < ROMTransferTime[0]) return;
|
if (curts < ROMTransferTime[0]) return;
|
||||||
|
|
||||||
|
@ -1937,8 +1937,8 @@ void NDSCartSlot::WriteROMCnt(u32 val) noexcept
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u64 curts;
|
u64 curts;
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.ExMemCnt[0] & (1<<11)) 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;
|
||||||
|
|
||||||
ROMTransferTime[0] = (xfercycle*(cmddelay+4)) + curts;
|
ROMTransferTime[0] = (xfercycle*(cmddelay+4)) + curts;
|
||||||
|
|
||||||
|
@ -1962,10 +1962,10 @@ void NDSCartSlot::AdvanceROMTransfer() noexcept
|
||||||
if (!((TransferPos+4) & 0x1FF))
|
if (!((TransferPos+4) & 0x1FF))
|
||||||
delay += ((ROMCnt >> 16) & 0x3F);
|
delay += ((ROMCnt >> 16) & 0x3F);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 curts;
|
u64 curts;
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.ExMemCnt[0] & (1<<11)) 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;
|
||||||
|
|
||||||
ROMTransferTime[0] = ROMTransferTime[1];
|
ROMTransferTime[0] = ROMTransferTime[1];
|
||||||
|
|
||||||
|
@ -1984,8 +1984,8 @@ u32 NDSCartSlot::ReadROMData() noexcept
|
||||||
if (ROMCnt & (1<<30)) return 0;
|
if (ROMCnt & (1<<30)) return 0;
|
||||||
|
|
||||||
u64 curts;
|
u64 curts;
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.ExMemCnt[0] & (1<<11)) 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;
|
||||||
|
|
||||||
ROMPrepareData();
|
ROMPrepareData();
|
||||||
|
|
||||||
|
@ -2000,10 +2000,10 @@ u32 NDSCartSlot::ReadROMData() noexcept
|
||||||
void NDSCartSlot::WriteROMData(u32 val) noexcept
|
void NDSCartSlot::WriteROMData(u32 val) noexcept
|
||||||
{
|
{
|
||||||
if (!(ROMCnt & (1<<30))) return;
|
if (!(ROMCnt & (1<<30))) return;
|
||||||
|
|
||||||
u64 curts;
|
u64 curts;
|
||||||
if (NDS.CurCPU) curts = NDS.ARM7Timestamp;
|
if (NDS.ExMemCnt[0] & (1<<11)) 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;
|
||||||
|
|
||||||
ROMPrepareData();
|
ROMPrepareData();
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,8 @@ public:
|
||||||
[[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; }
|
||||||
|
|
||||||
|
u64 ROMTransferTime[2];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CartCommon;
|
friend class CartCommon;
|
||||||
melonDS::NDS& NDS;
|
melonDS::NDS& NDS;
|
||||||
|
@ -445,8 +447,6 @@ private:
|
||||||
u64 Key2_X = 0;
|
u64 Key2_X = 0;
|
||||||
u64 Key2_Y = 0;
|
u64 Key2_Y = 0;
|
||||||
|
|
||||||
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;
|
||||||
void Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept;
|
void Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept;
|
||||||
|
|
Loading…
Reference in New Issue