basic arm9 set up
This commit is contained in:
parent
7cfc4b5849
commit
299713e412
37
src/ARM.cpp
37
src/ARM.cpp
|
@ -151,6 +151,7 @@ void ARM::Reset()
|
||||||
{
|
{
|
||||||
Cycles = 0;
|
Cycles = 0;
|
||||||
Halted = 0;
|
Halted = 0;
|
||||||
|
DataCycles = 0;
|
||||||
|
|
||||||
IRQ = 0;
|
IRQ = 0;
|
||||||
|
|
||||||
|
@ -199,6 +200,13 @@ void ARM::Reset()
|
||||||
void ARMv5::Reset()
|
void ARMv5::Reset()
|
||||||
{
|
{
|
||||||
PU_Map = PU_PrivMap;
|
PU_Map = PU_PrivMap;
|
||||||
|
|
||||||
|
TimestampActual = 0;
|
||||||
|
InterlockMem = 16;
|
||||||
|
InterlockWBCur = 16;
|
||||||
|
InterlockWBPrev = 16;
|
||||||
|
Store = false;
|
||||||
|
InterlockMask = 0;
|
||||||
|
|
||||||
ARM::Reset();
|
ARM::Reset();
|
||||||
}
|
}
|
||||||
|
@ -310,14 +318,12 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
||||||
u32 oldregion = R[15] >> 24;
|
u32 oldregion = R[15] >> 24;
|
||||||
u32 newregion = addr >> 24;
|
u32 newregion = addr >> 24;
|
||||||
|
|
||||||
RegionCodeCycles = MemTimings[addr >> 12][0];
|
|
||||||
|
|
||||||
if (addr & 0x1)
|
if (addr & 0x1)
|
||||||
{
|
{
|
||||||
addr &= ~0x1;
|
addr &= ~0x1;
|
||||||
R[15] = addr+2;
|
R[15] = addr+2;
|
||||||
|
|
||||||
if (newregion != oldregion) SetupCodeMem(addr);
|
//if (newregion != oldregion) SetupCodeMem(addr);
|
||||||
|
|
||||||
// two-opcodes-at-once fetch
|
// two-opcodes-at-once fetch
|
||||||
// doesn't matter if we put garbage in the MSbs there
|
// doesn't matter if we put garbage in the MSbs there
|
||||||
|
@ -342,7 +348,7 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
||||||
addr &= ~0x3;
|
addr &= ~0x3;
|
||||||
R[15] = addr+4;
|
R[15] = addr+4;
|
||||||
|
|
||||||
if (newregion != oldregion) SetupCodeMem(addr);
|
//if (newregion != oldregion) SetupCodeMem(addr);
|
||||||
|
|
||||||
NextInstr[0] = CodeRead32(addr, true);
|
NextInstr[0] = CodeRead32(addr, true);
|
||||||
Cycles += CodeCycles;
|
Cycles += CodeCycles;
|
||||||
|
@ -744,8 +750,8 @@ void ARMv5::Execute()
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
NDS.ARM9Timestamp += Cycles;
|
//NDS.ARM9Timestamp += Cycles;
|
||||||
Cycles = 0;
|
//Cycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Halted == 2)
|
if (Halted == 2)
|
||||||
|
@ -816,7 +822,7 @@ void ARMv4::Execute()
|
||||||
{
|
{
|
||||||
if ((Halted == 1 || IdleLoop) && NDS.ARM7Timestamp < NDS.ARM7Target)
|
if ((Halted == 1 || IdleLoop) && NDS.ARM7Timestamp < NDS.ARM7Target)
|
||||||
{
|
{
|
||||||
//Cycles = 0;
|
Cycles = 0;
|
||||||
NDS.ARM7Timestamp = NDS.ARM7Target;
|
NDS.ARM7Timestamp = NDS.ARM7Target;
|
||||||
}
|
}
|
||||||
IdleLoop = 0;
|
IdleLoop = 0;
|
||||||
|
@ -882,9 +888,6 @@ void ARMv4::Execute()
|
||||||
TriggerIRQ<mode>();
|
TriggerIRQ<mode>();
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//NDS.ARM7Timestamp += Cycles;
|
|
||||||
//Cycles = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Halted == 2)
|
if (Halted == 2)
|
||||||
|
@ -1153,6 +1156,20 @@ u32 ARMv5::ReadMem(u32 addr, int size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void ARMv5::AddCycles_CI(s32 numI)
|
||||||
|
{
|
||||||
|
NDS.ARM9Timestamp += numI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMv5::AddCycles_MW()
|
||||||
|
{
|
||||||
|
u64 TimestampActual = DataCycles + NDS.ARM9Timestamp;
|
||||||
|
s32 cycles = DataCycles - (3<<NDS.ARM9ClockShift);
|
||||||
|
|
||||||
|
if (cycles > 0) NDS.ARM9Timestamp += cycles;
|
||||||
|
}
|
||||||
|
|
||||||
u16 ARMv4::CodeRead16(u32 addr)
|
u16 ARMv4::CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
if ((addr >> 24) == 0x02)
|
if ((addr >> 24) == 0x02)
|
||||||
|
|
56
src/ARM.h
56
src/ARM.h
|
@ -265,44 +265,41 @@ public:
|
||||||
bool DataWrite16(u32 addr, u16 val) override;
|
bool DataWrite16(u32 addr, u16 val) override;
|
||||||
bool DataWrite32(u32 addr, u32 val) override;
|
bool DataWrite32(u32 addr, u32 val) override;
|
||||||
bool DataWrite32S(u32 addr, u32 val, bool dataabort = false) override;
|
bool DataWrite32S(u32 addr, u32 val, bool dataabort = false) override;
|
||||||
|
|
||||||
|
template<u8 nregs>
|
||||||
|
void ExecuteStage(u8 rn, u8 rm)
|
||||||
|
{
|
||||||
|
static_assert((nregs < 2), "too many regs");
|
||||||
|
|
||||||
|
if constexpr (nregs == 1)
|
||||||
|
{
|
||||||
|
InterlockMask = 1 << rn;
|
||||||
|
}
|
||||||
|
if constexpr (nregs == 2)
|
||||||
|
{
|
||||||
|
InterlockMask = 1 << rn | 1 << rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCycles_C();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddCycles_C() override
|
void AddCycles_C() override
|
||||||
{
|
{
|
||||||
// code only. always nonseq 32-bit for ARM9.
|
|
||||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
|
||||||
Cycles += numC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCycles_CI(s32 numI) override
|
void AddCycles_CI(s32 numI) override;
|
||||||
{
|
|
||||||
// code+internal
|
void AddCycles_MW();
|
||||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
|
||||||
Cycles += numC + numI;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddCycles_CDI() override
|
void AddCycles_CDI() override
|
||||||
{
|
{
|
||||||
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
|
AddCycles_MW();
|
||||||
// TODO: ITCM data fetches shouldn't be parallelized, they say
|
|
||||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
|
||||||
s32 numD = DataCycles;
|
|
||||||
|
|
||||||
//if (DataRegion != CodeRegion)
|
|
||||||
Cycles += std::max(numC + numD - 6, std::max(numC, numD));
|
|
||||||
//else
|
|
||||||
// Cycles += numC + numD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCycles_CD() override
|
void AddCycles_CD() override
|
||||||
{
|
{
|
||||||
// TODO: ITCM data fetches shouldn't be parallelized, they say
|
AddCycles_MW();
|
||||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
|
||||||
s32 numD = DataCycles;
|
|
||||||
|
|
||||||
//if (DataRegion != CodeRegion)
|
|
||||||
Cycles += std::max(numC + numD - 6, std::max(numC, numD));
|
|
||||||
//else
|
|
||||||
// Cycles += numC + numD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetCodeMemRegion(u32 addr, MemRegion* region);
|
void GetCodeMemRegion(u32 addr, MemRegion* region);
|
||||||
|
@ -367,6 +364,13 @@ public:
|
||||||
u8* CurICacheLine;
|
u8* CurICacheLine;
|
||||||
|
|
||||||
bool (*GetMemRegion)(u32 addr, bool write, MemRegion* region);
|
bool (*GetMemRegion)(u32 addr, bool write, MemRegion* region);
|
||||||
|
|
||||||
|
u64 TimestampActual;
|
||||||
|
u8 InterlockMem;
|
||||||
|
u8 InterlockWBCur;
|
||||||
|
u8 InterlockWBPrev;
|
||||||
|
bool Store;
|
||||||
|
u16 InterlockMask;
|
||||||
|
|
||||||
#ifdef GDBSTUB_ENABLED
|
#ifdef GDBSTUB_ENABLED
|
||||||
u32 ReadMem(u32 addr, int size) override;
|
u32 ReadMem(u32 addr, int size) override;
|
||||||
|
|
127
src/CP15.cpp
127
src/CP15.cpp
|
@ -299,13 +299,16 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)
|
||||||
u8 pu = PU_Map[i];
|
u8 pu = PU_Map[i];
|
||||||
u8* bustimings = NDS.ARM9MemTimings[i >> 2];
|
u8* bustimings = NDS.ARM9MemTimings[i >> 2];
|
||||||
|
|
||||||
|
// checkme: should these be (bus timings shifted) - 1 or ((bustimings - 1) shifted) + 1
|
||||||
|
// should the last cycle be halved...?
|
||||||
|
|
||||||
if (pu & 0x40)
|
if (pu & 0x40)
|
||||||
{
|
{
|
||||||
MemTimings[i][0] = 0xFF;//kCodeCacheTiming;
|
MemTimings[i][0] = 0xFF;//kCodeCacheTiming;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MemTimings[i][0] = bustimings[2] << NDS.ARM9ClockShift;
|
MemTimings[i][0] = ((bustimings[2] - 1) << NDS.ARM9ClockShift) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pu & 0x10)
|
if (pu & 0x10)
|
||||||
|
@ -316,9 +319,9 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MemTimings[i][1] = bustimings[0] << NDS.ARM9ClockShift;
|
MemTimings[i][1] = ((bustimings[0] - 1) << NDS.ARM9ClockShift) + 1;
|
||||||
MemTimings[i][2] = bustimings[2] << NDS.ARM9ClockShift;
|
MemTimings[i][2] = ((bustimings[2] - 1) << NDS.ARM9ClockShift) + 1;
|
||||||
MemTimings[i][3] = bustimings[3] << NDS.ARM9ClockShift;
|
MemTimings[i][3] = ((bustimings[3] - 1) << NDS.ARM9ClockShift) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,10 +787,11 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
CodeCycles = 1;
|
CodeCycles = 1;
|
||||||
|
if ((DataRegion == Mem9_ITCM) && (TimestampActual >= NDS.ARM9Timestamp)) NDS.ARM9Timestamp = TimestampActual + 1;
|
||||||
return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCycles = RegionCodeCycles;
|
CodeCycles = MemTimings[addr >> 12][0];
|
||||||
if (CodeCycles == 0xFF) // cached memory. hax
|
if (CodeCycles == 0xFF) // cached memory. hax
|
||||||
{
|
{
|
||||||
if (branch || !(addr & 0x1F))
|
if (branch || !(addr & 0x1F))
|
||||||
|
@ -798,7 +802,21 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
|
||||||
//return *(u32*)&CurICacheLine[addr & 0x1C];
|
//return *(u32*)&CurICacheLine[addr & 0x1C];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodeMem.Mem) return *(u32*)&CodeMem.Mem[addr & CodeMem.Mask];
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
|
||||||
|
if (DataRegion == Mem9_MainRAM) NDS.ARM9Timestamp += CodeCycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CodeRegion == DataRegion && Store) NDS.ARM9Timestamp += (1<<NDS.ARM9ClockShift);
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp += CodeCycles;
|
||||||
|
if (NDS.ARM9Timestamp < TimestampActual) NDS.ARM9Timestamp = TimestampActual;
|
||||||
|
|
||||||
|
//if (CodeMem.Mem) return *(u32*)&CodeMem.Mem[addr & CodeMem.Mask];
|
||||||
|
|
||||||
return BusRead32(addr);
|
return BusRead32(addr);
|
||||||
}
|
}
|
||||||
|
@ -806,6 +824,7 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
|
||||||
|
|
||||||
bool ARMv5::DataRead8(u32 addr, u32* val)
|
bool ARMv5::DataRead8(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
|
Store = false;
|
||||||
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -815,15 +834,26 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
*val = BusRead8(addr);
|
*val = BusRead8(addr);
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
|
@ -832,6 +862,7 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
|
||||||
|
|
||||||
bool ARMv5::DataRead16(u32 addr, u32* val)
|
bool ARMv5::DataRead16(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
|
Store = false;
|
||||||
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -843,15 +874,26 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
*val = BusRead16(addr);
|
*val = BusRead16(addr);
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
|
@ -860,6 +902,7 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
|
||||||
|
|
||||||
bool ARMv5::DataRead32(u32 addr, u32* val)
|
bool ARMv5::DataRead32(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
|
Store = false;
|
||||||
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -871,16 +914,27 @@ bool ARMv5::DataRead32(u32 addr, u32* val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataCycles = MemTimings[addr >> 12][2];
|
DataCycles = MemTimings[addr >> 12][2];
|
||||||
return true;
|
return true;
|
||||||
|
@ -899,23 +953,36 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataCycles += MemTimings[addr >> 12][3];
|
NDS.ARM9Timestamp += DataCycles;
|
||||||
|
DataCycles = MemTimings[addr >> 12][3];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMv5::DataWrite8(u32 addr, u8 val)
|
bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
|
Store = true;
|
||||||
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -925,6 +992,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||||
return true;
|
return true;
|
||||||
|
@ -932,10 +1000,20 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
BusWrite8(addr, val);
|
BusWrite8(addr, val);
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
|
@ -943,6 +1021,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
|
|
||||||
bool ARMv5::DataWrite16(u32 addr, u16 val)
|
bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
|
Store = true;
|
||||||
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -954,6 +1033,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||||
return true;
|
return true;
|
||||||
|
@ -961,10 +1041,20 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
BusWrite16(addr, val);
|
BusWrite16(addr, val);
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
|
@ -972,6 +1062,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
|
|
||||||
bool ARMv5::DataWrite32(u32 addr, u32 val)
|
bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
|
Store = true;
|
||||||
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
|
@ -983,6 +1074,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||||
return true;
|
return true;
|
||||||
|
@ -990,10 +1082,20 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
BusWrite32(addr, val);
|
BusWrite32(addr, val);
|
||||||
DataCycles = MemTimings[addr >> 12][2];
|
DataCycles = MemTimings[addr >> 12][2];
|
||||||
return true;
|
return true;
|
||||||
|
@ -1012,6 +1114,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val, bool dataabort)
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||||
#ifdef JIT_ENABLED
|
#ifdef JIT_ENABLED
|
||||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||||
|
@ -1021,10 +1124,20 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val, bool dataabort)
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
|
||||||
|
|
||||||
|
if ((addr >> 24) == 0x02)
|
||||||
|
{
|
||||||
|
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
|
||||||
|
DataRegion = Mem9_MainRAM;
|
||||||
|
}
|
||||||
|
else DataRegion = NDS.ARM9Regions[addr>>14];
|
||||||
|
|
||||||
BusWrite32(addr, val);
|
BusWrite32(addr, val);
|
||||||
DataCycles += MemTimings[addr >> 12][3];
|
DataCycles += MemTimings[addr >> 12][3];
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue