Merge branch 'less-ambitious-timing-rework' into chemical-x

This commit is contained in:
Jaklyy 2024-10-09 17:56:10 -04:00
commit 225bd50e13
3 changed files with 425 additions and 120 deletions

View File

@ -208,6 +208,9 @@ void ARMv5::Reset()
Store = false;
InterlockMask = 0;
WBWritePointer = 16;
WBFillPointer = 0;
ARM::Reset();
}
@ -609,6 +612,7 @@ void ARMv5::Execute()
else
{
NDS.ARM9Timestamp = NDS.ARM9Target;
WriteBufferCheck();
return;
}
}
@ -742,6 +746,7 @@ void ARMv5::Execute()
//NDS.ARM9Timestamp += Cycles;
//Cycles = 0;
}
WriteBufferCheck();
if (Halted == 2)
Halted = 0;
@ -757,7 +762,7 @@ void ARMv4::Execute()
{
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
GdbCheckB();
if (Halted)
{
if (Halted == 2)

View File

@ -292,11 +292,13 @@ public:
void AddCycles_CDI() override
{
AddCycles_MW(DataCycles);
DataCycles = 0;
}
void AddCycles_CD() override
{
AddCycles_MW(DataCycles);
DataCycles = 0;
}
void GetCodeMemRegion(const u32 addr, MemRegion* region);
@ -400,6 +402,10 @@ public:
* Nothing
*/
void ICacheInvalidateAll();
void WriteBufferCheck();
void WriteBufferWrite(u32 val, u8 flag, u8 cycles, u32 addr = 0);
void WriteBufferDrain();
/**
* @brief Invalidates the instruction cacheline containing
@ -675,6 +681,13 @@ public:
bool Store;
u16 InterlockMask;
u8 WBWritePointer;
u8 WBFillPointer;
u32 WBAddr; // current working address for the write buffer
u32 storeaddr[16]; // debugging
u64 WBCycles[16]; // timestamp each write will complete
u64 WriteBufferFifo[16]; // 0-31: value | 62-63: 0 byte, 1 half, 2 word, 3 addr
#ifdef GDBSTUB_ENABLED
u32 ReadMem(u32 addr, int size) override;
void WriteMem(u32 addr, int size, u32 v) override;

View File

@ -206,13 +206,13 @@ void ARMv5::UpdatePURegion(const u32 n)
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
datacache = (PU_DataCacheable >> n) & 0x1;
datawrite = (PU_DataCacheWrite >> n) & 0x1;
}
else
{
datacache = false;
datawrite = false;
}
datawrite = (PU_DataCacheWrite >> n) & 0x1;
u32 rgn = PU_Region[n];
if (!(rgn & CP15_REGION_ENABLE))
@ -256,14 +256,14 @@ void ARMv5::UpdatePURegion(const u32 n)
if (datacache)
{
privmask |= CP15_MAP_DCACHEABLE;
usermask |= CP15_MAP_DCACHEABLE;
if (datawrite)
{
privmask |= CP15_MAP_DCACHEWRITEBACK;
usermask |= CP15_MAP_DCACHEWRITEBACK;
}
privmask |= 0x10;
usermask |= 0x10;
}
if (datawrite & 0x1)
{
privmask |= 0x20;
usermask |= 0x20;
}
if (codecache)
@ -880,7 +880,234 @@ bool ARMv5::IsAddressDCachable(const u32 addr) const
return PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_DCACHEABLE;
}
void ARMv5::CP15Write(const u32 id, const u32 val)
void ARMv5::WriteBufferCheck()
{
if (WBWritePointer == 16) return;
while (WBCycles[WBWritePointer] <= (NDS.ARM9Timestamp + DataCycles))
{
//printf("drainingwb %lli, %i %08X %i\n", WBCycles[WBWritePointer], WBWritePointer, WBAddr, WriteBufferFifo[WBWritePointer] >> 62);
switch ((u64)WriteBufferFifo[WBWritePointer] >> 62)
{
case 0: // byte
{
u8 val = WriteBufferFifo[WBWritePointer] & 0xFF;
if (WBAddr < ITCMSize)
{
*(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val;
else BusWrite8(storeaddr[WBWritePointer], val);
break;
}
case 1: // halfword
{
u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF;
if (WBAddr < ITCMSize)
{
*(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val;
else BusWrite16(storeaddr[WBWritePointer], val);
break;
}
case 2: // word
{
u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
if (WBAddr < ITCMSize)
{
*(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val;
else BusWrite32(storeaddr[WBWritePointer], val);
WBAddr += 4;
break;
}
case 3: // address update
WBAddr = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
break;
}
WBWritePointer = (WBWritePointer + 1) & 0xF;
if (WBWritePointer == WBFillPointer)
{
WBWritePointer = 16;
WBFillPointer = 0;
break;
}
}
}
void ARMv5::WriteBufferWrite(u32 val, u8 flag, u8 cycles, u32 addr)
{
WriteBufferCheck();
if (WBFillPointer == WBWritePointer)
{
//printf("forcedrainingwb %lli, %i %08X %i\n", WBCycles[WBWritePointer], WBWritePointer, WBAddr, WriteBufferFifo[WBWritePointer] >> 62);
if (NDS.ARM9Timestamp < WBCycles[WBWritePointer])
{
NDS.ARM9Timestamp = WBCycles[WBWritePointer];
DataCycles = 0; // checkme
}
switch ((u64)WriteBufferFifo[WBWritePointer] >> 62)
{
case 0: // byte
{
u8 val = WriteBufferFifo[WBWritePointer] & 0xFF;
if (WBAddr < ITCMSize)
{
*(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val;
else BusWrite8(storeaddr[WBWritePointer], val);
break;
}
case 1: // halfword
{
u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF;
if (WBAddr < ITCMSize)
{
*(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val;
else BusWrite16(storeaddr[WBWritePointer], val);
break;
}
case 2: // word
{
u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
if (WBAddr < ITCMSize)
{
*(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val;
else BusWrite32(storeaddr[WBWritePointer], val);
WBAddr += 4;
break;
}
case 3: // address update
WBAddr = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
break;
}
WBWritePointer = (WBWritePointer + 1) & 0xF;
if (WBWritePointer == WBFillPointer)
{
WBWritePointer = 16;
WBFillPointer = 0;
}
}
//printf("fillingwb %lli %i %i %08X %i\n", NDS.ARM9Timestamp, WBWritePointer, WBFillPointer, val, flag);
if (WBWritePointer == 16)
{
WBCycles[WBFillPointer] = NDS.ARM9Timestamp + DataCycles + cycles;
WBWritePointer = 0;
}
else
{
WBCycles[WBFillPointer] = WBCycles[(WBFillPointer-1) & 0xF] + cycles;
}
WriteBufferFifo[WBFillPointer] = val | (u64)flag << 62;
storeaddr[WBFillPointer] = addr;
WBFillPointer = (WBFillPointer + 1) & 0xF;
}
void ARMv5::WriteBufferDrain()
{
if (WBWritePointer == 16) return;
while (true)
{
//printf("fullydrainingwb %lli, %i %08X %i\n", WBCycles[WBWritePointer], WBWritePointer, WBAddr, WriteBufferFifo[WBWritePointer] >> 62);
if (NDS.ARM9Timestamp < WBCycles[WBWritePointer])
{
NDS.ARM9Timestamp = WBCycles[WBWritePointer];
DataCycles = 0; // checkme
}
switch (WriteBufferFifo[WBWritePointer] >> 62)
{
case 0: // byte
{
u8 val = WriteBufferFifo[WBWritePointer] & 0xFF;
if (WBAddr < ITCMSize)
{
*(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val;
else BusWrite8(storeaddr[WBWritePointer], val);
break;
}
case 1: // halfword
{
u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF;
if (WBAddr < ITCMSize)
{
*(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val;
else BusWrite16(storeaddr[WBWritePointer], val);
break;
}
case 2: // word
{
u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
if (WBAddr < ITCMSize)
{
*(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr);
#endif
}
else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val;
else BusWrite32(storeaddr[WBWritePointer], val);
WBAddr += 4;
break;
}
case 3: // address update
WBAddr = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF;
break;
}
WBWritePointer = (WBWritePointer + 1) & 0xF;
if (WBWritePointer == WBFillPointer)
{
WBWritePointer = 16;
WBFillPointer = 0;
break;
}
}
//printf("wbdrained\n");
}
void ARMv5::CP15Write(u32 id, u32 val)
{
//if(id!=0x704)printf("CP15 write op %03X %08X %08X\n", id, val, R[15]);
@ -1623,6 +1850,9 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
}
#endif
if ((PU_Map[addr>>12] & 0x30))
WriteBufferDrain();
if (addr < ITCMSize)
{
CodeCycles = 1;
@ -1688,6 +1918,9 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
}
#endif
if ((PU_Map[addr>>12] & 0x30))
WriteBufferDrain();
if (addr < ITCMSize)
{
DataCycles = 1;
@ -1748,6 +1981,8 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
}
#endif
addr &= ~1;
if ((PU_Map[addr>>12] & 0x30))
WriteBufferDrain();
if (addr < ITCMSize)
{
@ -1811,6 +2046,9 @@ bool ARMv5::DataRead32(u32 addr, u32* val)
}
#endif
if ((PU_Map[addr>>12] & 0x30))
WriteBufferDrain();
if (addr < ITCMSize)
{
DataCycles = 1;
@ -1871,6 +2109,9 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
}
#endif
if ((PU_Map[addr>>12] & 0x30))
WriteBufferDrain();
if (addr < ITCMSize)
{
DataCycles += 1;
@ -1886,8 +2127,11 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
return true;
}
NDS.ARM9Timestamp += DataCycles;
if (!(addr & 0x3FF)) return DataRead32(addr, val); // bursts cannot cross a 1kb boundary
DataCycles = MemTimings[addr >> 12][3];
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
@ -1914,7 +2158,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
DataCycles = 1;
return false;
}
#if !DISABLE_DCACHE
#ifdef JIT_ENABLED
if (!NDS.IsJITEnabled())
@ -1930,37 +2174,49 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
}
}
#endif
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
if (!(PU_Map[addr>>12] & (0x30)))
{
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
#endif
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
DataCycles = MemTimings[addr >> 12][1];
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 12][1];
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite8(addr, val);
}
else
{
DataCycles = 1;
WriteBufferWrite(addr, 3, 1);
WriteBufferWrite(val, 0, MemTimings[addr >> 12][1], addr);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite8(addr, val);
return true;
}
@ -1993,37 +2249,48 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
}
#endif
if (addr < ITCMSize)
if (!(PU_Map[addr>>12] & 0x30))
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
#endif
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
DataCycles = MemTimings[addr >> 12][1];
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 12][1];
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite16(addr, val);
}
else
{
DataCycles = 1;
WriteBufferWrite(addr, 3, 1);
WriteBufferWrite(val, 1, MemTimings[addr >> 12][1], addr);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite16(addr, val);
return true;
}
@ -2057,37 +2324,48 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
}
#endif
if (addr < ITCMSize)
if (!(PU_Map[addr>>12] & 0x30))
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
#endif
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
DataCycles = MemTimings[addr >> 12][2];
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 12][2];
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
if ((addr >> 24) == 0x02)
{
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite32(addr, val);
}
else
{
DataCycles = 1;
WriteBufferWrite(addr, 3, 1);
WriteBufferWrite(val, 2, MemTimings[addr >> 12][2], addr);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite32(addr, val);
return true;
}
@ -2119,38 +2397,47 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val)
}
#endif
if (addr < ITCMSize)
if (!(PU_Map[addr>>12] & 0x30))
{
DataCycles += 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
if (addr < ITCMSize)
{
DataCycles += 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
#endif
return true;
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles += 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
}
DataCycles += ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1)) - NDS.ARM9Timestamp);
if (!(addr & 0x3FF)) return DataWrite32(addr, val); // bursts cannot cross a 1kb boundary
if ((addr >> 24) == 0x02)
{
if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) NDS.ARM9Timestamp = MainRAMTimestamp - DataCycles;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_MainRAM;
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite32(addr, val);
DataCycles += MemTimings[addr >> 12][3];
}
if ((addr & DTCMMask) == DTCMBase)
else
{
DataCycles += 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true;
WriteBufferWrite(val, 2, MemTimings[addr >> 12][3], addr);
}
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
if ((addr >> 24) == 0x02)
{
if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) NDS.ARM9Timestamp = MainRAMTimestamp - DataCycles;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_MainRAM;
}
else DataRegion = NDS.ARM9Regions[addr>>14];
BusWrite32(addr, val);
DataCycles += MemTimings[addr >> 12][3];
return true;
}