improve arm7 timings

This commit is contained in:
Jaklyy 2024-09-01 15:15:59 -04:00
parent f0bd2b9051
commit 2d081a6e02
2 changed files with 172 additions and 79 deletions

View File

@ -190,6 +190,8 @@ void ARM::Reset()
BreakReq = false;
#endif
MainRAMTimestamp = 0;
// zorp
JumpTo(ExceptionBase);
}
@ -201,6 +203,13 @@ void ARMv5::Reset()
ARM::Reset();
}
void ARMv4::Reset()
{
Nonseq = true;
ARM::Reset();
}
void ARM::DoSavestate(Savestate* file)
{
@ -377,22 +386,15 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
else addr &= ~0x1;
}
u32 oldregion = R[15] >> 23;
u32 newregion = addr >> 23;
CodeRegion = addr >> 24;
CodeCycles = addr >> 15; // cheato
if (addr & 0x1)
{
addr &= ~0x1;
R[15] = addr+2;
//if (newregion != oldregion) SetupCodeMem(addr);
Nonseq = true;
NextInstr[0] = CodeRead16(addr);
Nonseq = false;
NextInstr[1] = CodeRead16(addr+2);
Cycles += NDS.ARM7MemTimings[CodeCycles][0] + NDS.ARM7MemTimings[CodeCycles][1];
CPSR |= 0x20;
}
@ -400,12 +402,11 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
{
addr &= ~0x3;
R[15] = addr+4;
//if (newregion != oldregion) SetupCodeMem(addr);
Nonseq = true;
NextInstr[0] = CodeRead32(addr);
Nonseq = false;
NextInstr[1] = CodeRead32(addr+4);
Cycles += NDS.ARM7MemTimings[CodeCycles][2] + NDS.ARM7MemTimings[CodeCycles][3];
CPSR &= ~0x20;
}
@ -815,7 +816,7 @@ void ARMv4::Execute()
{
if ((Halted == 1 || IdleLoop) && NDS.ARM7Timestamp < NDS.ARM7Target)
{
Cycles = 0;
//Cycles = 0;
NDS.ARM7Timestamp = NDS.ARM7Target;
}
IdleLoop = 0;
@ -882,8 +883,8 @@ void ARMv4::Execute()
}*/
}
NDS.ARM7Timestamp += Cycles;
Cycles = 0;
//NDS.ARM7Timestamp += Cycles;
//Cycles = 0;
}
if (Halted == 2)
@ -1152,58 +1153,161 @@ u32 ARMv5::ReadMem(u32 addr, int size)
}
#endif
u16 ARMv4::CodeRead16(u32 addr)
{
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr>>15][Nonseq?0:1];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
return BusRead16(addr);
}
u32 ARMv4::CodeRead32(u32 addr)
{
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr>>15][Nonseq?2:3];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
return BusRead32(addr);
}
bool ARMv4::DataRead8(u32 addr, u32* val)
{
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][0];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
*val = BusRead8(addr);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
return true;
}
bool ARMv4::DataRead16(u32 addr, u32* val)
{
addr &= ~1;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][0];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
*val = BusRead16(addr);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
return true;
}
bool ARMv4::DataRead32(u32 addr, u32* val)
{
addr &= ~3;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][2];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
*val = BusRead32(addr);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
return true;
}
bool ARMv4::DataRead32S(u32 addr, u32* val)
{
addr &= ~3;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][3];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 3;
}
*val = BusRead32(addr);
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
return true;
}
bool ARMv4::DataWrite8(u32 addr, u8 val)
{
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][0];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 5;
}
BusWrite8(addr, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
return true;
}
bool ARMv4::DataWrite16(u32 addr, u16 val)
{
addr &= ~1;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][0];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 5;
}
BusWrite16(addr, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
return true;
}
@ -1211,9 +1315,20 @@ bool ARMv4::DataWrite32(u32 addr, u32 val)
{
addr &= ~3;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][2];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 5;
}
BusWrite32(addr, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
return true;
}
@ -1221,8 +1336,20 @@ bool ARMv4::DataWrite32S(u32 addr, u32 val, bool dataabort)
{
addr &= ~3;
if ((addr >> 24) == 0x02)
{
if (NDS.ARM7Timestamp < MainRAMTimestamp) NDS.ARM7Timestamp = MainRAMTimestamp;
}
NDS.ARM7Timestamp += NDS.ARM7MemTimings[addr >> 15][3];
if ((addr >> 24) == 0x02)
{
MainRAMTimestamp = NDS.ARM7Timestamp;
NDS.ARM7Timestamp -= 5;
}
BusWrite32(addr, val);
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
return true;
}
@ -1230,63 +1357,30 @@ bool ARMv4::DataWrite32S(u32 addr, u32 val, bool dataabort)
void ARMv4::AddCycles_C()
{
// code only. this code fetch is sequential.
Cycles += NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?1:3];
Nonseq = false;
}
void ARMv4::AddCycles_CI(s32 num)
{
// code+internal. results in a nonseq code fetch.
Cycles += NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2] + num;
NDS.ARM7Timestamp += num;
Nonseq = true;
}
void ARMv4::AddCycles_CDI()
{
// LDR/LDM cycles.
s32 numC = NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
s32 numD = DataCycles;
NDS.ARM7Timestamp += 1;
if ((DataRegion >> 24) == 0x02) // mainRAM
{
if (CodeRegion == 0x02)
Cycles += numC + numD;
else
{
numC++;
Cycles += std::max(numC + numD - 3, std::max(numC, numD));
}
}
else if (CodeRegion == 0x02)
{
numD++;
Cycles += std::max(numC + numD - 3, std::max(numC, numD));
}
else
{
Cycles += numC + numD + 1;
}
Nonseq = true;
}
void ARMv4::AddCycles_CD()
{
// TODO: max gain should be 5c when writing to mainRAM
s32 numC = NDS.ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
s32 numD = DataCycles;
if ((DataRegion >> 24) == 0x02)
{
if (CodeRegion == 0x02)
Cycles += numC + numD;
else
Cycles += std::max(numC + numD - 3, std::max(numC, numD));
}
else if (CodeRegion == 0x02)
{
Cycles += std::max(numC + numD - 3, std::max(numC, numD));
}
else
{
Cycles += numC + numD;
}
Nonseq = true;
}
u8 ARMv5::BusRead8(u32 addr)

View File

@ -185,6 +185,8 @@ public:
MemRegion CodeMem;
u64 MainRAMTimestamp;
#ifdef JIT_ENABLED
u32 FastBlockLookupStart, FastBlockLookupSize;
u64* FastBlockLookup;
@ -384,6 +386,8 @@ class ARMv4 : public ARM
{
public:
ARMv4(melonDS::NDS& nds, std::optional<GDBArgs> gdb, bool jit);
void Reset() override;
void FillPipeline() override;
@ -393,15 +397,10 @@ public:
template <CPUExecuteMode mode>
void Execute();
u16 CodeRead16(u32 addr)
{
return BusRead16(addr);
}
bool Nonseq;
u32 CodeRead32(u32 addr)
{
return BusRead32(addr);
}
u16 CodeRead16(u32 addr);
u32 CodeRead32(u32 addr);
bool DataRead8(u32 addr, u32* val) override;
bool DataRead16(u32 addr, u32* val) override;