mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-25 07:10:00 -06:00
improve ldm timings
I believe this also applies to other loads as well, but currently untested.
This commit is contained in:
55
src/ARM.cpp
55
src/ARM.cpp
@ -302,6 +302,10 @@ 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;
|
||||||
|
|
||||||
|
if (addr < ITCMSize) CodeRegion = Mem9_ITCM;
|
||||||
|
else if ((addr & DTCMMask) == DTCMBase) CodeRegion = Mem9_DTCM;
|
||||||
|
else CodeRegion = NDS.ARM9Regions[addr >> 14];
|
||||||
|
|
||||||
RegionCodeCycles = MemTimings[addr >> 12][0];
|
RegionCodeCycles = MemTimings[addr >> 12][0];
|
||||||
|
|
||||||
@ -1255,6 +1259,57 @@ bool ARMv4::DataWrite32S(u32 addr, u32 val, bool dataabort)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ARMv5::AddCycles_CDI()
|
||||||
|
{
|
||||||
|
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
|
||||||
|
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||||
|
s32 numD = DataCycles;
|
||||||
|
|
||||||
|
// if a 32 bit bus, start 2 cycles early; else, start 4 cycles early
|
||||||
|
s32 early;
|
||||||
|
switch (DataRegion)
|
||||||
|
{
|
||||||
|
case 0: // background region; CHECKME
|
||||||
|
case Mem9_DTCM:
|
||||||
|
case Mem9_BIOS:
|
||||||
|
case Mem9_WRAM:
|
||||||
|
case Mem9_IO:
|
||||||
|
case Mem9_Pal: // CHECKME
|
||||||
|
default:
|
||||||
|
early = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mem9_OAM: // CHECKME
|
||||||
|
case Mem9_GBAROM:
|
||||||
|
case Mem9_GBARAM:
|
||||||
|
early = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mem9_MainRAM:
|
||||||
|
early = (CodeRegion == Mem9_MainRAM) ? 0 : 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mem9_VRAM: // the dsi can toggle the bus width of vram between 32 and 16 bit
|
||||||
|
early = (NDS.ConsoleType == 0 || !(((DSi&)NDS).SCFG_EXT[0] & (1<<13))) ? 4 : 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mem9_ITCM: // itcm data fetches cannot be done at the same time as a code fetch, it'll even incurr a 1 cycle penalty when executing from itcm
|
||||||
|
early = (CodeRegion == Mem9_ITCM) ? -1 : 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numD > early)
|
||||||
|
{
|
||||||
|
numC -= early;
|
||||||
|
if (numC < 0) numC = 0;
|
||||||
|
Cycles += numC + numD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cycles += numC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv4::AddCycles_C()
|
void ARMv4::AddCycles_C()
|
||||||
{
|
{
|
||||||
// code only. this code fetch is sequential.
|
// code only. this code fetch is sequential.
|
||||||
|
13
src/ARM.h
13
src/ARM.h
@ -325,18 +325,7 @@ public:
|
|||||||
Cycles += numC + numI;
|
Cycles += numC + numI;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCycles_CDI() override
|
void AddCycles_CDI() override;
|
||||||
{
|
|
||||||
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
|
|
||||||
// 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
|
||||||
{
|
{
|
||||||
|
19
src/CP15.cpp
19
src/CP15.cpp
@ -815,22 +815,23 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRegion = addr;
|
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = BusRead8(addr);
|
*val = BusRead8(addr);
|
||||||
|
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -843,24 +844,25 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRegion = addr;
|
|
||||||
|
|
||||||
addr &= ~1;
|
addr &= ~1;
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = BusRead16(addr);
|
*val = BusRead16(addr);
|
||||||
|
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -873,24 +875,25 @@ bool ARMv5::DataRead32(u32 addr, u32* val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRegion = addr;
|
|
||||||
|
|
||||||
addr &= ~3;
|
addr &= ~3;
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_ITCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
|
DataRegion = Mem9_DTCM;
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
|
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||||
DataCycles = MemTimings[addr >> 12][2];
|
DataCycles = MemTimings[addr >> 12][2];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user