"immediate mode" dma start should be delayed 1 cycle
This commit is contained in:
parent
22f1b4d90c
commit
65e2f64695
11
src/ARM.h
11
src/ARM.h
|
@ -739,35 +739,46 @@ public:
|
||||||
void JumpTo_4();
|
void JumpTo_4();
|
||||||
void CodeRead32_2();
|
void CodeRead32_2();
|
||||||
void CodeRead32_3();
|
void CodeRead32_3();
|
||||||
|
void CodeRead32_4();
|
||||||
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 DRead8_4();
|
||||||
|
void DRead8_5();
|
||||||
void DCacheFin16();
|
void DCacheFin16();
|
||||||
void DRead16_2();
|
void DRead16_2();
|
||||||
void DRead16_3();
|
void DRead16_3();
|
||||||
void DRead16_4();
|
void DRead16_4();
|
||||||
|
void DRead16_5();
|
||||||
void DCacheFin32();
|
void DCacheFin32();
|
||||||
void DRead32_2();
|
void DRead32_2();
|
||||||
void DRead32_3();
|
void DRead32_3();
|
||||||
void DRead32_4();
|
void DRead32_4();
|
||||||
|
void DRead32_5();
|
||||||
void DRead32S_2();
|
void DRead32S_2();
|
||||||
void DRead32S_3();
|
void DRead32S_3();
|
||||||
void DRead32S_4();
|
void DRead32S_4();
|
||||||
|
void DRead32S_5A();
|
||||||
|
void DRead32S_5B();
|
||||||
void DWrite8_2();
|
void DWrite8_2();
|
||||||
void DWrite8_3();
|
void DWrite8_3();
|
||||||
void DWrite8_4();
|
void DWrite8_4();
|
||||||
|
void DWrite8_5();
|
||||||
void DWrite16_2();
|
void DWrite16_2();
|
||||||
void DWrite16_3();
|
void DWrite16_3();
|
||||||
void DWrite16_4();
|
void DWrite16_4();
|
||||||
|
void DWrite16_5();
|
||||||
void DWrite32_2();
|
void DWrite32_2();
|
||||||
void DWrite32_3();
|
void DWrite32_3();
|
||||||
void DWrite32_4();
|
void DWrite32_4();
|
||||||
|
void DWrite32_5();
|
||||||
void DWrite32S_2();
|
void DWrite32S_2();
|
||||||
void DWrite32S_3();
|
void DWrite32S_3();
|
||||||
void DWrite32S_4();
|
void DWrite32S_4();
|
||||||
|
void DWrite32S_5A();
|
||||||
|
void DWrite32S_5B();
|
||||||
void WBCheck_2();
|
void WBCheck_2();
|
||||||
void ICachePrefetch_2();
|
void ICachePrefetch_2();
|
||||||
void DCacheLookup_2();
|
void DCacheLookup_2();
|
||||||
|
|
285
src/CP15.cpp
285
src/CP15.cpp
|
@ -2242,13 +2242,13 @@ void ARMv5::CodeRead32_3()
|
||||||
|
|
||||||
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
u8 cycles = MemTimings[addr >> 14][1];
|
|
||||||
|
|
||||||
if ((addr >> 24) == 0x02)
|
if ((addr >> 24) == 0x02)
|
||||||
{
|
{
|
||||||
FetchAddr[16] = addr;
|
FetchAddr[16] = addr;
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MRCodeFetch | MR32;
|
MRTrack.Var = MRCodeFetch | MR32;
|
||||||
|
|
||||||
|
QueueFunction(DelayedQueue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2256,18 +2256,28 @@ void ARMv5::CodeRead32_3()
|
||||||
|| (Store && (NDS.ARM9Regions[addr>>14] == DataRegion))) //check the actual store
|
|| (Store && (NDS.ARM9Regions[addr>>14] == DataRegion))) //check the actual store
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
NDS.ARM9Timestamp += cycles;
|
QueueFunction(&ARMv5::CodeRead32_4);
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
|
|
||||||
RetVal = BusRead32(addr);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::CodeRead32_4()
|
||||||
|
{
|
||||||
|
u32 addr = FetchAddr[16];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
u8 cycles = MemTimings[addr >> 14][1];
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += cycles;
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
Store = false;
|
Store = false;
|
||||||
DataRegion = Mem9_Null;
|
DataRegion = Mem9_Null;
|
||||||
|
|
||||||
|
RetVal = BusRead32(addr);
|
||||||
QueueFunction(DelayedQueue);
|
QueueFunction(DelayedQueue);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2393,18 +2403,31 @@ void ARMv5::DRead8_4()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
QueueFunction(&ARMv5::DRead8_5);
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
*val = BusRead8(addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead8_5()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
*val = BusRead8(addr);
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv5::DCacheFin16()
|
void ARMv5::DCacheFin16()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
@ -2517,18 +2540,31 @@ void ARMv5::DRead16_4()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
QueueFunction(&ARMv5::DRead16_5);
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
*val = BusRead16(addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead16_5()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
*val = BusRead16(addr);
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv5::DCacheFin32()
|
void ARMv5::DCacheFin32()
|
||||||
{
|
{
|
||||||
u8 reg = __builtin_ctz(LDRRegs);
|
u8 reg = __builtin_ctz(LDRRegs);
|
||||||
|
@ -2639,19 +2675,34 @@ void ARMv5::DRead32_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MR32;
|
MRTrack.Var = MR32;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
LDRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
|
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
QueueFunction(&ARMv5::DRead32_5);
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
*val = BusRead32(addr);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead32_5()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
*val = BusRead32(addr);
|
||||||
LDRRegs &= ~1<<reg;
|
LDRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2751,18 +2802,16 @@ void ARMv5::DRead32S_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MR32 | MRSequential;
|
MRTrack.Var = MR32 | MRSequential;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
LDRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr>>14][2];
|
|
||||||
DataCycles = MemTimings[addr>>14][2];
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
QueueFunction(&ARMv5::DRead32S_5A);
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
*val = BusRead32(addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // ns
|
else // ns
|
||||||
|
@ -2774,20 +2823,53 @@ void ARMv5::DRead32S_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MR32;
|
MRTrack.Var = MR32;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
LDRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
|
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
|
||||||
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
QueueFunction(&ARMv5::DRead32S_5B);
|
||||||
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
*val = BusRead32(addr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead32S_5A()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr>>14][2];
|
||||||
|
DataCycles = MemTimings[addr>>14][2];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
*val = BusRead32(addr);
|
||||||
|
LDRRegs &= ~1<<reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DRead32S_5B()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
*val = BusRead32(addr);
|
||||||
LDRRegs &= ~1<<reg;
|
LDRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2898,16 +2980,28 @@ void ARMv5::DWrite8_4()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
QueueFunction(&ARMv5::DWrite8_5);
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
BusWrite8(addr, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite8_5()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u8 val = STRVal[reg];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
BusWrite8(addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
bool ARMv5::DataWrite16(u32 addr, u16 val, u8 reg)
|
bool ARMv5::DataWrite16(u32 addr, u16 val, u8 reg)
|
||||||
{
|
{
|
||||||
// Data Aborts
|
// Data Aborts
|
||||||
|
@ -3017,16 +3111,28 @@ void ARMv5::DWrite16_4()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
QueueFunction(&ARMv5::DWrite16_5);
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
BusWrite16(addr, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite16_5()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u16 val = STRVal[reg];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
BusWrite16(addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
bool ARMv5::DataWrite32(u32 addr, u32 val, u8 reg)
|
bool ARMv5::DataWrite32(u32 addr, u32 val, u8 reg)
|
||||||
{
|
{
|
||||||
// Data Aborts
|
// Data Aborts
|
||||||
|
@ -3139,17 +3245,31 @@ void ARMv5::DWrite32_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MRWrite | MR32;
|
MRTrack.Var = MRWrite | MR32;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
STRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
|
QueueFunction(&ARMv5::DWrite32_5);
|
||||||
DataCycles = 3<<NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
BusWrite32(addr, val);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite32_5()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 val = STRVal[reg];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
|
||||||
|
DataCycles = 3<<NDS.ARM9ClockShift;
|
||||||
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
BusWrite32(addr, val);
|
||||||
STRRegs &= ~1<<reg;
|
STRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3255,15 +3375,12 @@ void ARMv5::DWrite32S_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MRWrite | MR32 | MRSequential;
|
MRTrack.Var = MRWrite | MR32 | MRSequential;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
STRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr>>14][2];
|
QueueFunction(&ARMv5::DWrite32S_5A);
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
BusWrite32(addr, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // ns
|
else // ns
|
||||||
|
@ -3275,18 +3392,50 @@ void ARMv5::DWrite32S_4()
|
||||||
MRTrack.Type = MainRAMType::Fetch;
|
MRTrack.Type = MainRAMType::Fetch;
|
||||||
MRTrack.Var = MRWrite | MR32;
|
MRTrack.Var = MRWrite | MR32;
|
||||||
MRTrack.Progress = reg;
|
MRTrack.Progress = reg;
|
||||||
|
|
||||||
|
STRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
|
QueueFunction(&ARMv5::DWrite32S_5B);
|
||||||
DataCycles = 3 << NDS.ARM9ClockShift;
|
|
||||||
DataRegion = NDS.ARM9Regions[addr>>14];
|
|
||||||
|
|
||||||
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
|
||||||
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
|
||||||
BusWrite32(addr, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite32S_5A()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 val = STRVal[reg];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr>>14][2];
|
||||||
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
BusWrite32(addr, val);
|
||||||
|
STRRegs &= ~1<<reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::DWrite32S_5B()
|
||||||
|
{
|
||||||
|
u8 reg = __builtin_ctz(STRRegs);
|
||||||
|
u32 addr = FetchAddr[reg];
|
||||||
|
u32 val = STRVal[reg];
|
||||||
|
|
||||||
|
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
|
||||||
|
DataCycles = 3 << NDS.ARM9ClockShift;
|
||||||
|
DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
|
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
|
||||||
|
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
BusWrite32(addr, val);
|
||||||
STRRegs &= ~1<<reg;
|
STRRegs &= ~1<<reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/DMA.cpp
21
src/DMA.cpp
|
@ -146,7 +146,10 @@ void DMA::WriteCnt(u32 val)
|
||||||
StartMode = ((Cnt >> 28) & 0x3) | 0x10;
|
StartMode = ((Cnt >> 28) & 0x3) | 0x10;
|
||||||
|
|
||||||
if ((StartMode & 0x7) == 0)
|
if ((StartMode & 0x7) == 0)
|
||||||
Start();
|
{
|
||||||
|
NDS.DMAsQueued[NDS.DMAQueuePtr++] = (CPU*4)+Num;
|
||||||
|
if (!(NDS.SchedListMask & (1<<Event_DMA))) NDS.ScheduleEvent(Event_DMA, false, 1, 0, 0);
|
||||||
|
}
|
||||||
else if (StartMode == 0x07)
|
else if (StartMode == 0x07)
|
||||||
NDS.GPU.GPU3D.CheckFIFODMA();
|
NDS.GPU.GPU3D.CheckFIFODMA();
|
||||||
|
|
||||||
|
@ -212,6 +215,18 @@ void DMA::Start()
|
||||||
InProgress = true;
|
InProgress = true;
|
||||||
NDS.StopCPU(CPU, 1<<Num);
|
NDS.StopCPU(CPU, 1<<Num);
|
||||||
|
|
||||||
|
if (CPU == 0)
|
||||||
|
{
|
||||||
|
u64 ts;
|
||||||
|
/*if (StartMode == 0x00)
|
||||||
|
{
|
||||||
|
ts = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
}
|
||||||
|
else*/ ts = NDS.SysTimestamp << NDS.ARM9ClockShift;
|
||||||
|
|
||||||
|
if (NDS.DMA9Timestamp < ts) NDS.DMA9Timestamp = ts;
|
||||||
|
}
|
||||||
|
|
||||||
if (Num == 0) NDS.DMAs[(CPU*4)+1].ResetBurst();
|
if (Num == 0) NDS.DMAs[(CPU*4)+1].ResetBurst();
|
||||||
if (Num <= 1) NDS.DMAs[(CPU*4)+2].ResetBurst();
|
if (Num <= 1) NDS.DMAs[(CPU*4)+2].ResetBurst();
|
||||||
if (Num <= 2) NDS.DMAs[(CPU*4)+3].ResetBurst();
|
if (Num <= 2) NDS.DMAs[(CPU*4)+3].ResetBurst();
|
||||||
|
@ -587,8 +602,8 @@ u32 DMA::UnitTimings7_32(int burststart)
|
||||||
|
|
||||||
void DMA::Run9()
|
void DMA::Run9()
|
||||||
{
|
{
|
||||||
NDS.DMA9Timestamp = std::max(NDS.DMA9Timestamp, NDS.ARM9Timestamp);
|
//NDS.DMA9Timestamp = std::max(NDS.DMA9Timestamp, NDS.SysTimestamp << NDS.ARM9ClockShift);
|
||||||
NDS.DMA9Timestamp = (NDS.DMA9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
//NDS.DMA9Timestamp = (NDS.DMA9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) return;
|
if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) return;
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ public:
|
||||||
|
|
||||||
void ResetBurst()
|
void ResetBurst()
|
||||||
{
|
{
|
||||||
if (Running > 0) Running = (CPU ? 2 : 3);
|
if (Running > 0) Running = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 SrcAddr {};
|
u32 SrcAddr {};
|
||||||
|
|
16
src/NDS.cpp
16
src/NDS.cpp
|
@ -124,6 +124,7 @@ NDS::NDS(NDSArgs&& args, int type, void* userdata) noexcept :
|
||||||
{
|
{
|
||||||
RegisterEventFuncs(Event_Div, this, {MakeEventThunk(NDS, DivDone)});
|
RegisterEventFuncs(Event_Div, this, {MakeEventThunk(NDS, DivDone)});
|
||||||
RegisterEventFuncs(Event_Sqrt, this, {MakeEventThunk(NDS, SqrtDone)});
|
RegisterEventFuncs(Event_Sqrt, this, {MakeEventThunk(NDS, SqrtDone)});
|
||||||
|
RegisterEventFuncs(Event_DMA, this, {MakeEventThunk(NDS, QueueDMAs)});
|
||||||
|
|
||||||
MainRAM = JIT.Memory.GetMainRAM();
|
MainRAM = JIT.Memory.GetMainRAM();
|
||||||
SharedWRAM = JIT.Memory.GetSharedWRAM();
|
SharedWRAM = JIT.Memory.GetSharedWRAM();
|
||||||
|
@ -134,6 +135,7 @@ NDS::~NDS() noexcept
|
||||||
{
|
{
|
||||||
UnregisterEventFuncs(Event_Div);
|
UnregisterEventFuncs(Event_Div);
|
||||||
UnregisterEventFuncs(Event_Sqrt);
|
UnregisterEventFuncs(Event_Sqrt);
|
||||||
|
UnregisterEventFuncs(Event_DMA);
|
||||||
// The destructor for each component is automatically called by the compiler
|
// The destructor for each component is automatically called by the compiler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,6 +550,9 @@ void NDS::Reset()
|
||||||
KeyCnt[1] = 0;
|
KeyCnt[1] = 0;
|
||||||
RCnt = 0;
|
RCnt = 0;
|
||||||
|
|
||||||
|
memset(DMAsQueued, 0, sizeof(DMAsQueued));
|
||||||
|
DMAQueuePtr = 0;
|
||||||
|
|
||||||
GPU.Reset();
|
GPU.Reset();
|
||||||
NDSCartSlot.Reset();
|
NDSCartSlot.Reset();
|
||||||
GBACartSlot.Reset();
|
GBACartSlot.Reset();
|
||||||
|
@ -1818,8 +1823,8 @@ u32 NDS::RunFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDSCartSlot.ROMPrepareData();
|
|
||||||
RunSystem(target);
|
RunSystem(target);
|
||||||
|
NDSCartSlot.ROMPrepareData();
|
||||||
|
|
||||||
if (CPUStop & CPUStop_Sleep)
|
if (CPUStop & CPUStop_Sleep)
|
||||||
{
|
{
|
||||||
|
@ -2526,6 +2531,15 @@ void NDS::StopDMAs(u32 cpu, u32 mode)
|
||||||
DMAs[cpu+3].StopIfNeeded(mode);
|
DMAs[cpu+3].StopIfNeeded(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NDS::QueueDMAs(u32 param)
|
||||||
|
{
|
||||||
|
DMAs[DMAsQueued[0]].Start();
|
||||||
|
for(int i = 0; i < 7; i++) DMAsQueued[i] = DMAsQueued[i+1];
|
||||||
|
DMAQueuePtr--;
|
||||||
|
|
||||||
|
if (DMAQueuePtr != 0) ScheduleEvent(Event_DMA, false, 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NDS::DivDone(u32 param)
|
void NDS::DivDone(u32 param)
|
||||||
|
|
|
@ -64,6 +64,7 @@ enum
|
||||||
Event_SPITransfer,
|
Event_SPITransfer,
|
||||||
Event_Div,
|
Event_Div,
|
||||||
Event_Sqrt,
|
Event_Sqrt,
|
||||||
|
Event_DMA,
|
||||||
|
|
||||||
// DSi
|
// DSi
|
||||||
Event_DSi_SDMMCTransfer,
|
Event_DSi_SDMMCTransfer,
|
||||||
|
@ -244,6 +245,7 @@ public: // TODO: Encapsulate the rest of these members
|
||||||
int ConsoleType;
|
int ConsoleType;
|
||||||
int CurCPU;
|
int CurCPU;
|
||||||
|
|
||||||
|
u32 SchedListMask;
|
||||||
SchedEvent SchedList[Event_MAX] {};
|
SchedEvent SchedList[Event_MAX] {};
|
||||||
u8 ARM9MemTimings[0x40000][8];
|
u8 ARM9MemTimings[0x40000][8];
|
||||||
u32 ARM9Regions[0x40000];
|
u32 ARM9Regions[0x40000];
|
||||||
|
@ -259,6 +261,7 @@ public: // TODO: Encapsulate the rest of these members
|
||||||
u64 ARM7Timestamp, ARM7Target;
|
u64 ARM7Timestamp, ARM7Target;
|
||||||
u64 MainRAMTimestamp, MainRAMBurstStart;
|
u64 MainRAMTimestamp, MainRAMBurstStart;
|
||||||
u64 A9ContentionTS; bool ConTSLock;
|
u64 A9ContentionTS; bool ConTSLock;
|
||||||
|
u64 SysTimestamp;
|
||||||
u32 ARM9ClockShift;
|
u32 ARM9ClockShift;
|
||||||
|
|
||||||
u32 IME[2];
|
u32 IME[2];
|
||||||
|
@ -277,6 +280,8 @@ public: // TODO: Encapsulate the rest of these members
|
||||||
alignas(u32) u8 ROMSeed1[2*8];
|
alignas(u32) u8 ROMSeed1[2*8];
|
||||||
|
|
||||||
u32 DMAReadHold[2];
|
u32 DMAReadHold[2];
|
||||||
|
u8 DMAsQueued[8];
|
||||||
|
u8 DMAQueuePtr;
|
||||||
bool MainRAMBork; // if a main ram read burst starts in the last 6 bytes of a 32 byte block, and then crosses the 32 byte boundary, the burst forcibly restarts
|
bool MainRAMBork; // if a main ram read burst starts in the last 6 bytes of a 32 byte block, and then crosses the 32 byte boundary, the burst forcibly restarts
|
||||||
bool MainRAMLastAccess; // 0 == ARM9 | 1 == ARM7
|
bool MainRAMLastAccess; // 0 == ARM9 | 1 == ARM7
|
||||||
bool DMALastWasMainRAM;
|
bool DMALastWasMainRAM;
|
||||||
|
@ -506,8 +511,6 @@ public: // TODO: Encapsulate the rest of these members
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitTimings();
|
void InitTimings();
|
||||||
u32 SchedListMask;
|
|
||||||
u64 SysTimestamp;
|
|
||||||
u8 WRAMCnt;
|
u8 WRAMCnt;
|
||||||
u8 PostFlag9;
|
u8 PostFlag9;
|
||||||
u8 PostFlag7;
|
u8 PostFlag7;
|
||||||
|
@ -542,6 +545,7 @@ private:
|
||||||
void HandleTimerOverflow(u32 tid);
|
void HandleTimerOverflow(u32 tid);
|
||||||
u16 TimerGetCounter(u32 timer);
|
u16 TimerGetCounter(u32 timer);
|
||||||
void TimerStart(u32 id, u16 cnt);
|
void TimerStart(u32 id, u16 cnt);
|
||||||
|
void QueueDMAs(u32 param);
|
||||||
void StartDiv();
|
void StartDiv();
|
||||||
void DivDone(u32 param);
|
void DivDone(u32 param);
|
||||||
void SqrtDone(u32 param);
|
void SqrtDone(u32 param);
|
||||||
|
|
|
@ -1983,10 +1983,6 @@ u32 NDSCartSlot::ReadROMData() noexcept
|
||||||
{
|
{
|
||||||
if (ROMCnt & (1<<30)) return 0;
|
if (ROMCnt & (1<<30)) return 0;
|
||||||
|
|
||||||
u64 curts;
|
|
||||||
if (NDS.ExMemCnt[0] & (1<<11)) curts = NDS.ARM7Timestamp;
|
|
||||||
else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-1)) >> NDS.ARM9ClockShift;
|
|
||||||
|
|
||||||
ROMPrepareData();
|
ROMPrepareData();
|
||||||
|
|
||||||
if (ROMCnt & (1<<23))
|
if (ROMCnt & (1<<23))
|
||||||
|
@ -2001,10 +1997,6 @@ void NDSCartSlot::WriteROMData(u32 val) noexcept
|
||||||
{
|
{
|
||||||
if (!(ROMCnt & (1<<30))) return;
|
if (!(ROMCnt & (1<<30))) return;
|
||||||
|
|
||||||
u64 curts;
|
|
||||||
if (NDS.ExMemCnt[0] & (1<<11)) curts = NDS.ARM7Timestamp;
|
|
||||||
else curts = (std::max(NDS.ARM9Timestamp, NDS.DMA9Timestamp) + ((1<<NDS.ARM9ClockShift)-1)) >> NDS.ARM9ClockShift;
|
|
||||||
|
|
||||||
ROMPrepareData();
|
ROMPrepareData();
|
||||||
|
|
||||||
ROMData = val;
|
ROMData = val;
|
||||||
|
|
Loading…
Reference in New Issue