mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
revert timing tweaks, finish thumb interwork code
This commit is contained in:
parent
4b703d24b5
commit
ab2a8f128f
126
src/ARM.cpp
126
src/ARM.cpp
@ -300,9 +300,6 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
||||
|
||||
u32 oldregion = R[15] >> 24;
|
||||
u32 newregion = addr >> 24;
|
||||
|
||||
if (addr < ITCMSize) CodeRegion = Mem9_ITCM;
|
||||
else CodeRegion = NDS.ARM9Regions[addr >> 14];
|
||||
|
||||
RegionCodeCycles = MemTimings[addr >> 12][0];
|
||||
|
||||
@ -644,7 +641,7 @@ void ARMv5::Execute()
|
||||
R[15] += 2;
|
||||
CurInstr = NextInstr[0];
|
||||
NextInstr[0] = NextInstr[1];
|
||||
if (R[15] & 0x2) { NextInstr[1] >>= 16; CodeCycles = 1; }
|
||||
if (R[15] & 0x2) { NextInstr[1] >>= 16; CodeCycles = 0; }
|
||||
else NextInstr[1] = CodeRead32(R[15], false);
|
||||
|
||||
// actually execute
|
||||
@ -1256,127 +1253,6 @@ bool ARMv4::DataWrite32S(u32 addr, u32 val, bool dataabort)
|
||||
}
|
||||
|
||||
|
||||
void ARMv5::AddCycles_CD_STR()
|
||||
{
|
||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||
s32 numD = DataCycles;
|
||||
|
||||
s32 early;
|
||||
if (DataRegion == Mem9_ITCM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_ITCM) ? 0 : 2;
|
||||
}
|
||||
else if (DataRegion == Mem9_DTCM)
|
||||
{
|
||||
early = 2;
|
||||
}
|
||||
else if (DataRegion == Mem9_MainRAM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_MainRAM) ? 0 : 18; // CHECKME: how early can main ram be?
|
||||
}
|
||||
else early = (DataRegion == CodeRegion) ? 4 : 6;
|
||||
|
||||
s32 code = numC - early;
|
||||
if (code < 0) code = 0;
|
||||
Cycles += std::max(code + numD, numC);
|
||||
}
|
||||
|
||||
void ARMv5::AddCycles_CD_STM()
|
||||
{
|
||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||
s32 numD = DataCycles;
|
||||
|
||||
s32 early;
|
||||
if (DataRegion == Mem9_ITCM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_ITCM) ? -1 : 0; // stm adds either: no penalty or benefit to itcm loads, or a 1 cycle penalty if executing from itcm.
|
||||
}
|
||||
else if (DataRegion == Mem9_DTCM)
|
||||
{
|
||||
early = 2;
|
||||
}
|
||||
else if (DataRegion == Mem9_MainRAM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_MainRAM) ? 0 : 18; // CHECKME: how early can main ram be?
|
||||
}
|
||||
else early = (DataRegion == CodeRegion) ? 4 : 6;
|
||||
|
||||
s32 code = numC - early;
|
||||
if (code < 0) code = 0;
|
||||
Cycles += std::max(code + numD, numC);
|
||||
}
|
||||
|
||||
void ARMv5::AddCycles_CDI_LDR()
|
||||
{
|
||||
// LDR cycles. ARM9 seems to skip the internal cycle here.
|
||||
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;
|
||||
if (DataRegion == Mem9_ITCM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_ITCM) ? 0 : 2;
|
||||
}
|
||||
else if (DataRegion == Mem9_DTCM)
|
||||
{
|
||||
early = 2;
|
||||
}
|
||||
else if (DataRegion == Mem9_MainRAM)
|
||||
{
|
||||
early = (CodeRegion == Mem9_MainRAM) ? 0 : 6;
|
||||
}
|
||||
else early = 6;
|
||||
|
||||
s32 code = numC - early;
|
||||
if (code < 0) code = 0;
|
||||
Cycles += std::max(code + numD, numC);
|
||||
}
|
||||
|
||||
void ARMv5::AddCycles_CDI_LDM()
|
||||
{
|
||||
// LDM cycles. ARM9 seems to skip the internal cycle here.
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
s32 code = numC - early;
|
||||
if (code < 0) code = 0;
|
||||
Cycles += std::max(code + numD, numC);
|
||||
}
|
||||
|
||||
void ARMv4::AddCycles_C()
|
||||
{
|
||||
// code only. this code fetch is sequential.
|
||||
|
45
src/ARM.h
45
src/ARM.h
@ -266,23 +266,41 @@ public:
|
||||
void AddCycles_C() override
|
||||
{
|
||||
// code only. always nonseq 32-bit for ARM9.
|
||||
s32 numC = CodeCycles;
|
||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||
Cycles += numC;
|
||||
}
|
||||
|
||||
void AddCycles_CI(s32 numI) override
|
||||
{
|
||||
// code+internal
|
||||
s32 numC = CodeCycles;
|
||||
numI += 1;
|
||||
Cycles += std::max(numC, numI);
|
||||
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||
Cycles += numC + numI;
|
||||
}
|
||||
|
||||
void AddCycles_CDI_LDR() override;
|
||||
void AddCycles_CDI_LDM() override;
|
||||
void AddCycles_CDI_SWP() override { AddCycles_CD_STR(); } // uses the same behavior as str
|
||||
void AddCycles_CD_STR() override;
|
||||
void AddCycles_CD_STM() 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
|
||||
{
|
||||
// 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 GetCodeMemRegion(u32 addr, MemRegion* region);
|
||||
|
||||
@ -396,13 +414,8 @@ public:
|
||||
bool DataWrite32S(u32 addr, u32 val, bool dataabort = false) override;
|
||||
void AddCycles_C() override;
|
||||
void AddCycles_CI(s32 num) override;
|
||||
void AddCycles_CDI();
|
||||
void AddCycles_CDI_LDR() override { AddCycles_CDI(); }
|
||||
void AddCycles_CDI_LDM() override { AddCycles_CDI(); }
|
||||
void AddCycles_CDI_SWP() override { AddCycles_CDI(); } // checkme?
|
||||
void AddCycles_CD();
|
||||
void AddCycles_CD_STR() override { AddCycles_CD(); }
|
||||
void AddCycles_CD_STM() override { AddCycles_CD(); }
|
||||
void AddCycles_CDI() override;
|
||||
void AddCycles_CD() override;
|
||||
|
||||
protected:
|
||||
u8 BusRead8(u32 addr) override;
|
||||
|
@ -66,7 +66,7 @@ namespace melonDS::ARMInterpreter
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 0xF) \
|
||||
storeval += 4; \
|
||||
bool dataabort = !cpu->DataWrite32(offset, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||
|
||||
@ -77,7 +77,7 @@ namespace melonDS::ARMInterpreter
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 0xF) \
|
||||
storeval += 4; \
|
||||
bool dataabort = !cpu->DataWrite32(addr, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||
|
||||
@ -86,7 +86,7 @@ namespace melonDS::ARMInterpreter
|
||||
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||
bool dataabort = !cpu->DataWrite8(offset, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||
|
||||
@ -96,20 +96,20 @@ namespace melonDS::ARMInterpreter
|
||||
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||
bool dataabort = !cpu->DataWrite8(addr, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||
|
||||
#define A_LDR \
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead32(offset, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = ROR(val, ((offset&0x3)<<3)); \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||
{ \
|
||||
if (cpu->Num==1) val &= ~0x1; \
|
||||
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) val &= ~0x1; \
|
||||
cpu->JumpTo(val); \
|
||||
} \
|
||||
else \
|
||||
@ -121,13 +121,13 @@ namespace melonDS::ARMInterpreter
|
||||
#define A_LDR_POST \
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead32(addr, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = ROR(val, ((addr&0x3)<<3)); \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||
{ \
|
||||
if (cpu->Num==1) val &= ~0x1; \
|
||||
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) val &= ~0x1; \
|
||||
cpu->JumpTo(val); \
|
||||
} \
|
||||
else \
|
||||
@ -138,7 +138,7 @@ namespace melonDS::ARMInterpreter
|
||||
#define A_LDRB \
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -148,7 +148,7 @@ namespace melonDS::ARMInterpreter
|
||||
#define A_LDRB_POST \
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -240,7 +240,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||
bool dataabort = !cpu->DataWrite16(offset, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||
|
||||
@ -249,7 +249,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||
bool dataabort = !cpu->DataWrite16(addr, storeval); \
|
||||
cpu->AddCycles_CD_STR(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||
|
||||
@ -260,11 +260,11 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
||||
if (r&1) { A_UNK(cpu); return; } \
|
||||
if (!cpu->DataRead32 (offset , &cpu->R[r ])) {cpu->AddCycles_CDI_LDM(); return;} \
|
||||
u32 val; if (!cpu->DataRead32S(offset+4, &val)) {cpu->AddCycles_CDI_LDM(); return;} \
|
||||
if (!cpu->DataRead32 (offset , &cpu->R[r ])) {cpu->AddCycles_CDI(); return;} \
|
||||
u32 val; if (!cpu->DataRead32S(offset+4, &val)) {cpu->AddCycles_CDI(); return;} \
|
||||
if (r == 14) cpu->JumpTo(((((ARMv5*)cpu)->CP15Control & (1<<15)) ? (val & ~0x1) : val), cpu->CurInstr & (1<<22)); /* restores cpsr presumably due to shared dna with ldm */ \
|
||||
else cpu->R[r+1] = val; \
|
||||
cpu->AddCycles_CDI_LDM(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||
|
||||
#define A_LDRD_POST \
|
||||
@ -272,11 +272,11 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
||||
if (r&1) { A_UNK(cpu); return; } \
|
||||
if (!cpu->DataRead32 (addr , &cpu->R[r ])) {cpu->AddCycles_CDI_LDM(); return;} \
|
||||
u32 val; if (!cpu->DataRead32S(addr+4, &val)) {cpu->AddCycles_CDI_LDM(); return;} \
|
||||
if (!cpu->DataRead32 (addr , &cpu->R[r ])) {cpu->AddCycles_CDI(); return;} \
|
||||
u32 val; if (!cpu->DataRead32S(addr+4, &val)) {cpu->AddCycles_CDI(); return;} \
|
||||
if (r == 14) cpu->JumpTo(((((ARMv5*)cpu)->CP15Control & (1<<15)) ? (val & ~0x1) : val), cpu->CurInstr & (1<<22)); /* restores cpsr presumably due to shared dna with ldm */ \
|
||||
else cpu->R[r+1] = val; \
|
||||
cpu->AddCycles_CDI_LDM(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||
|
||||
#define A_STRD \
|
||||
@ -287,7 +287,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
bool dataabort = !cpu->DataWrite32(offset, cpu->R[r]); /* yes, this data abort behavior is on purpose */ \
|
||||
u32 storeval = cpu->R[r+1]; if (r == 14) storeval+=4; \
|
||||
dataabort |= !cpu->DataWrite32S (offset+4, storeval, dataabort); /* no, i dont understand it either */ \
|
||||
cpu->AddCycles_CD_STM(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||
|
||||
@ -299,14 +299,14 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
bool dataabort = !cpu->DataWrite32(addr, cpu->R[r]); \
|
||||
u32 storeval = cpu->R[r+1]; if (r == 14) storeval+=4; \
|
||||
dataabort |= !cpu->DataWrite32S (addr+4, storeval, dataabort); \
|
||||
cpu->AddCycles_CD_STM(); \
|
||||
cpu->AddCycles_CD(); \
|
||||
if (dataabort) return; \
|
||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||
|
||||
#define A_LDRH \
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
||||
@ -315,7 +315,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
#define A_LDRH_POST \
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
||||
@ -324,7 +324,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
#define A_LDRSB \
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = (s32)(s8)val; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -334,7 +334,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
#define A_LDRSB_POST \
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = (s32)(s8)val; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -344,7 +344,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
#define A_LDRSH \
|
||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = (s32)(s16)val; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -354,7 +354,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||
#define A_LDRSH_POST \
|
||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
||||
cpu->AddCycles_CDI_LDR(); \
|
||||
cpu->AddCycles_CDI(); \
|
||||
if (dataabort) return; \
|
||||
val = (s32)(s16)val; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||
@ -415,7 +415,7 @@ void A_SWP(ARM* cpu)
|
||||
}
|
||||
cpu->DataCycles += numD;
|
||||
}
|
||||
cpu->AddCycles_CDI_SWP();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void A_SWPB(ARM* cpu)
|
||||
@ -437,7 +437,7 @@ void A_SWPB(ARM* cpu)
|
||||
}
|
||||
cpu->DataCycles += numD;
|
||||
}
|
||||
cpu->AddCycles_CDI_SWP();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -501,7 +501,7 @@ void A_LDM(ARM* cpu)
|
||||
|
||||
if (!preinc) base += 4;
|
||||
|
||||
if (cpu->Num == 1)
|
||||
if (cpu->Num == 1 || (((ARMv5*)cpu)->CP15Control & (1<<15)))
|
||||
pc &= ~0x1;
|
||||
}
|
||||
|
||||
@ -546,7 +546,7 @@ void A_LDM(ARM* cpu)
|
||||
cpu->R[baseid] = oldbase;
|
||||
}
|
||||
|
||||
cpu->AddCycles_CDI_LDM();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void A_STM(ARM* cpu)
|
||||
@ -630,7 +630,7 @@ void A_STM(ARM* cpu)
|
||||
cpu->R[baseid] = oldbase;
|
||||
}
|
||||
|
||||
cpu->AddCycles_CD_STM();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
|
||||
@ -645,7 +645,7 @@ void T_LDR_PCREL(ARM* cpu)
|
||||
u32 addr = (cpu->R[15] & ~0x2) + ((cpu->CurInstr & 0xFF) << 2);
|
||||
cpu->DataRead32(addr, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -654,7 +654,7 @@ void T_STR_REG(ARM* cpu)
|
||||
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||
cpu->DataWrite32(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_STRB_REG(ARM* cpu)
|
||||
@ -662,7 +662,7 @@ void T_STRB_REG(ARM* cpu)
|
||||
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||
cpu->DataWrite8(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDR_REG(ARM* cpu)
|
||||
@ -673,7 +673,7 @@ void T_LDR_REG(ARM* cpu)
|
||||
if (cpu->DataRead32(addr, &val))
|
||||
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3));
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void T_LDRB_REG(ARM* cpu)
|
||||
@ -681,7 +681,7 @@ void T_LDRB_REG(ARM* cpu)
|
||||
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||
cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 0x7]);
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -690,7 +690,7 @@ void T_STRH_REG(ARM* cpu)
|
||||
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||
cpu->DataWrite16(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDRSB_REG(ARM* cpu)
|
||||
@ -699,7 +699,7 @@ void T_LDRSB_REG(ARM* cpu)
|
||||
if (cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 0x7]))
|
||||
cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)cpu->R[cpu->CurInstr & 0x7];
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void T_LDRH_REG(ARM* cpu)
|
||||
@ -707,7 +707,7 @@ void T_LDRH_REG(ARM* cpu)
|
||||
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||
cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]);
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void T_LDRSH_REG(ARM* cpu)
|
||||
@ -716,7 +716,7 @@ void T_LDRSH_REG(ARM* cpu)
|
||||
if (cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]))
|
||||
cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)cpu->R[cpu->CurInstr & 0x7];
|
||||
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -726,7 +726,7 @@ void T_STR_IMM(ARM* cpu)
|
||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||
|
||||
cpu->DataWrite32(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDR_IMM(ARM* cpu)
|
||||
@ -737,7 +737,7 @@ void T_LDR_IMM(ARM* cpu)
|
||||
u32 val;
|
||||
if (cpu->DataRead32(offset, &val))
|
||||
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3));
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void T_STRB_IMM(ARM* cpu)
|
||||
@ -746,7 +746,7 @@ void T_STRB_IMM(ARM* cpu)
|
||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||
|
||||
cpu->DataWrite8(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDRB_IMM(ARM* cpu)
|
||||
@ -755,7 +755,7 @@ void T_LDRB_IMM(ARM* cpu)
|
||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||
|
||||
cpu->DataRead8(offset, &cpu->R[cpu->CurInstr & 0x7]);
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -765,7 +765,7 @@ void T_STRH_IMM(ARM* cpu)
|
||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||
|
||||
cpu->DataWrite16(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDRH_IMM(ARM* cpu)
|
||||
@ -774,7 +774,7 @@ void T_LDRH_IMM(ARM* cpu)
|
||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||
|
||||
cpu->DataRead16(offset, &cpu->R[cpu->CurInstr & 0x7]);
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -784,7 +784,7 @@ void T_STR_SPREL(ARM* cpu)
|
||||
offset += cpu->R[13];
|
||||
|
||||
cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
||||
cpu->AddCycles_CD_STR();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDR_SPREL(ARM* cpu)
|
||||
@ -793,7 +793,7 @@ void T_LDR_SPREL(ARM* cpu)
|
||||
offset += cpu->R[13];
|
||||
|
||||
cpu->DataRead32(offset, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
||||
cpu->AddCycles_CDI_LDR();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
@ -841,7 +841,7 @@ void T_PUSH(ARM* cpu)
|
||||
cpu->R[13] = wbbase;
|
||||
|
||||
dataabort:
|
||||
cpu->AddCycles_CD_STM();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_POP(ARM* cpu)
|
||||
@ -871,7 +871,7 @@ void T_POP(ARM* cpu)
|
||||
{
|
||||
goto dataabort;
|
||||
}
|
||||
if (cpu->Num==1) pc |= 0x1;
|
||||
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) pc |= 0x1;
|
||||
cpu->JumpTo(pc);
|
||||
base += 4;
|
||||
}
|
||||
@ -879,7 +879,7 @@ void T_POP(ARM* cpu)
|
||||
cpu->R[13] = base;
|
||||
|
||||
dataabort:
|
||||
cpu->AddCycles_CDI_LDM();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
void T_STMIA(ARM* cpu)
|
||||
@ -904,7 +904,7 @@ void T_STMIA(ARM* cpu)
|
||||
// TODO: check "Rb included in Rlist" case
|
||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||
dataabort:
|
||||
cpu->AddCycles_CD_STM();
|
||||
cpu->AddCycles_CD();
|
||||
}
|
||||
|
||||
void T_LDMIA(ARM* cpu)
|
||||
@ -930,7 +930,7 @@ void T_LDMIA(ARM* cpu)
|
||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||
|
||||
dataabort:
|
||||
cpu->AddCycles_CDI_LDM();
|
||||
cpu->AddCycles_CDI();
|
||||
}
|
||||
|
||||
|
||||
|
18
src/CP15.cpp
18
src/CP15.cpp
@ -815,21 +815,18 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
|
||||
*val = BusRead8(addr);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][1];
|
||||
return true;
|
||||
}
|
||||
@ -846,21 +843,18 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
|
||||
*val = BusRead16(addr);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][1];
|
||||
return true;
|
||||
}
|
||||
@ -877,21 +871,18 @@ bool ARMv5::DataRead32(u32 addr, u32* val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||
return true;
|
||||
}
|
||||
|
||||
*val = BusRead32(addr);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][2];
|
||||
return true;
|
||||
}
|
||||
@ -934,7 +925,6 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||
@ -942,14 +932,12 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
BusWrite8(addr, val);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][1];
|
||||
return true;
|
||||
}
|
||||
@ -966,7 +954,6 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||
@ -974,14 +961,12 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
BusWrite16(addr, val);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][1];
|
||||
return true;
|
||||
}
|
||||
@ -998,7 +983,6 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = Mem9_ITCM;
|
||||
DataCycles = 1;
|
||||
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
|
||||
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
|
||||
@ -1006,14 +990,12 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||
}
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
DataRegion = Mem9_DTCM;
|
||||
DataCycles = 1;
|
||||
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
BusWrite32(addr, val);
|
||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
||||
DataCycles = MemTimings[addr >> 12][2];
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user