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 oldregion = R[15] >> 24;
|
||||||
u32 newregion = addr >> 24;
|
u32 newregion = addr >> 24;
|
||||||
|
|
||||||
if (addr < ITCMSize) CodeRegion = Mem9_ITCM;
|
|
||||||
else CodeRegion = NDS.ARM9Regions[addr >> 14];
|
|
||||||
|
|
||||||
RegionCodeCycles = MemTimings[addr >> 12][0];
|
RegionCodeCycles = MemTimings[addr >> 12][0];
|
||||||
|
|
||||||
|
@ -644,7 +641,7 @@ void ARMv5::Execute()
|
||||||
R[15] += 2;
|
R[15] += 2;
|
||||||
CurInstr = NextInstr[0];
|
CurInstr = NextInstr[0];
|
||||||
NextInstr[0] = NextInstr[1];
|
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);
|
else NextInstr[1] = CodeRead32(R[15], false);
|
||||||
|
|
||||||
// actually execute
|
// 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()
|
void ARMv4::AddCycles_C()
|
||||||
{
|
{
|
||||||
// code only. this code fetch is sequential.
|
// code only. this code fetch is sequential.
|
||||||
|
|
45
src/ARM.h
45
src/ARM.h
|
@ -266,23 +266,41 @@ public:
|
||||||
void AddCycles_C() override
|
void AddCycles_C() override
|
||||||
{
|
{
|
||||||
// code only. always nonseq 32-bit for ARM9.
|
// code only. always nonseq 32-bit for ARM9.
|
||||||
s32 numC = CodeCycles;
|
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||||
Cycles += numC;
|
Cycles += numC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCycles_CI(s32 numI) override
|
void AddCycles_CI(s32 numI) override
|
||||||
{
|
{
|
||||||
// code+internal
|
// code+internal
|
||||||
s32 numC = CodeCycles;
|
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
|
||||||
numI += 1;
|
Cycles += numC + numI;
|
||||||
Cycles += std::max(numC, numI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCycles_CDI_LDR() override;
|
void AddCycles_CDI() override
|
||||||
void AddCycles_CDI_LDM() override;
|
{
|
||||||
void AddCycles_CDI_SWP() override { AddCycles_CD_STR(); } // uses the same behavior as str
|
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
|
||||||
void AddCycles_CD_STR() override;
|
// TODO: ITCM data fetches shouldn't be parallelized, they say
|
||||||
void AddCycles_CD_STM() override;
|
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);
|
void GetCodeMemRegion(u32 addr, MemRegion* region);
|
||||||
|
|
||||||
|
@ -396,13 +414,8 @@ public:
|
||||||
bool DataWrite32S(u32 addr, u32 val, bool dataabort = false) override;
|
bool DataWrite32S(u32 addr, u32 val, bool dataabort = false) override;
|
||||||
void AddCycles_C() override;
|
void AddCycles_C() override;
|
||||||
void AddCycles_CI(s32 num) override;
|
void AddCycles_CI(s32 num) override;
|
||||||
void AddCycles_CDI();
|
void AddCycles_CDI() override;
|
||||||
void AddCycles_CDI_LDR() override { AddCycles_CDI(); }
|
void AddCycles_CD() override;
|
||||||
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(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u8 BusRead8(u32 addr) override;
|
u8 BusRead8(u32 addr) override;
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace melonDS::ARMInterpreter
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 0xF) \
|
if (((cpu->CurInstr>>12) & 0xF) == 0xF) \
|
||||||
storeval += 4; \
|
storeval += 4; \
|
||||||
bool dataabort = !cpu->DataWrite32(offset, storeval); \
|
bool dataabort = !cpu->DataWrite32(offset, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
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) \
|
if (((cpu->CurInstr>>12) & 0xF) == 0xF) \
|
||||||
storeval += 4; \
|
storeval += 4; \
|
||||||
bool dataabort = !cpu->DataWrite32(addr, storeval); \
|
bool dataabort = !cpu->DataWrite32(addr, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ namespace melonDS::ARMInterpreter
|
||||||
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||||
bool dataabort = !cpu->DataWrite8(offset, storeval); \
|
bool dataabort = !cpu->DataWrite8(offset, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
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]; \
|
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||||
bool dataabort = !cpu->DataWrite8(addr, storeval); \
|
bool dataabort = !cpu->DataWrite8(addr, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||||
|
|
||||||
#define A_LDR \
|
#define A_LDR \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead32(offset, &val); \
|
u32 val; bool dataabort = !cpu->DataRead32(offset, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = ROR(val, ((offset&0x3)<<3)); \
|
val = ROR(val, ((offset&0x3)<<3)); \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
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); \
|
cpu->JumpTo(val); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
|
@ -121,13 +121,13 @@ namespace melonDS::ARMInterpreter
|
||||||
#define A_LDR_POST \
|
#define A_LDR_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead32(addr, &val); \
|
u32 val; bool dataabort = !cpu->DataRead32(addr, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = ROR(val, ((addr&0x3)<<3)); \
|
val = ROR(val, ((addr&0x3)<<3)); \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
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); \
|
cpu->JumpTo(val); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
|
@ -138,7 +138,7 @@ namespace melonDS::ARMInterpreter
|
||||||
#define A_LDRB \
|
#define A_LDRB \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
|
@ -148,7 +148,7 @@ namespace melonDS::ARMInterpreter
|
||||||
#define A_LDRB_POST \
|
#define A_LDRB_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
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]; \
|
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||||
bool dataabort = !cpu->DataWrite16(offset, storeval); \
|
bool dataabort = !cpu->DataWrite16(offset, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
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]; \
|
u32 storeval = cpu->R[(cpu->CurInstr>>12) & 0xF]; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) storeval+=4; \
|
||||||
bool dataabort = !cpu->DataWrite16(addr, storeval); \
|
bool dataabort = !cpu->DataWrite16(addr, storeval); \
|
||||||
cpu->AddCycles_CD_STR(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||||
|
|
||||||
|
@ -260,11 +260,11 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
||||||
if (r&1) { A_UNK(cpu); return; } \
|
if (r&1) { A_UNK(cpu); return; } \
|
||||||
if (!cpu->DataRead32 (offset , &cpu->R[r ])) {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_LDM(); 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 */ \
|
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; \
|
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;
|
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
||||||
|
|
||||||
#define A_LDRD_POST \
|
#define A_LDRD_POST \
|
||||||
|
@ -272,11 +272,11 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
u32 r = (cpu->CurInstr>>12) & 0xF; \
|
||||||
if (r&1) { A_UNK(cpu); return; } \
|
if (r&1) { A_UNK(cpu); return; } \
|
||||||
if (!cpu->DataRead32 (addr , &cpu->R[r ])) {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_LDM(); 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 */ \
|
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; \
|
else cpu->R[r+1] = val; \
|
||||||
cpu->AddCycles_CDI_LDM(); \
|
cpu->AddCycles_CDI(); \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||||
|
|
||||||
#define A_STRD \
|
#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 */ \
|
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; \
|
u32 storeval = cpu->R[r+1]; if (r == 14) storeval+=4; \
|
||||||
dataabort |= !cpu->DataWrite32S (offset+4, storeval, dataabort); /* no, i dont understand it either */ \
|
dataabort |= !cpu->DataWrite32S (offset+4, storeval, dataabort); /* no, i dont understand it either */ \
|
||||||
cpu->AddCycles_CD_STM(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
|
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]); \
|
bool dataabort = !cpu->DataWrite32(addr, cpu->R[r]); \
|
||||||
u32 storeval = cpu->R[r+1]; if (r == 14) storeval+=4; \
|
u32 storeval = cpu->R[r+1]; if (r == 14) storeval+=4; \
|
||||||
dataabort |= !cpu->DataWrite32S (addr+4, storeval, dataabort); \
|
dataabort |= !cpu->DataWrite32S (addr+4, storeval, dataabort); \
|
||||||
cpu->AddCycles_CD_STM(); \
|
cpu->AddCycles_CD(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
|
||||||
|
|
||||||
#define A_LDRH \
|
#define A_LDRH \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
||||||
|
@ -315,7 +315,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
#define A_LDRH_POST \
|
#define A_LDRH_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
else cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
|
||||||
|
@ -324,7 +324,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
#define A_LDRSB \
|
#define A_LDRSB \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
u32 val; bool dataabort = !cpu->DataRead8(offset, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = (s32)(s8)val; \
|
val = (s32)(s8)val; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
|
@ -334,7 +334,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
#define A_LDRSB_POST \
|
#define A_LDRSB_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
u32 val; bool dataabort = !cpu->DataRead8(addr, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = (s32)(s8)val; \
|
val = (s32)(s8)val; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
|
@ -344,7 +344,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
#define A_LDRSH \
|
#define A_LDRSH \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
u32 val; bool dataabort = !cpu->DataRead16(offset, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = (s32)(s16)val; \
|
val = (s32)(s16)val; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
|
@ -354,7 +354,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
#define A_LDRSH_POST \
|
#define A_LDRSH_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
u32 val; bool dataabort = !cpu->DataRead16(addr, &val); \
|
||||||
cpu->AddCycles_CDI_LDR(); \
|
cpu->AddCycles_CDI(); \
|
||||||
if (dataabort) return; \
|
if (dataabort) return; \
|
||||||
val = (s32)(s16)val; \
|
val = (s32)(s16)val; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) cpu->JumpTo8_16Bit(val); \
|
||||||
|
@ -415,7 +415,7 @@ void A_SWP(ARM* cpu)
|
||||||
}
|
}
|
||||||
cpu->DataCycles += numD;
|
cpu->DataCycles += numD;
|
||||||
}
|
}
|
||||||
cpu->AddCycles_CDI_SWP();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void A_SWPB(ARM* cpu)
|
void A_SWPB(ARM* cpu)
|
||||||
|
@ -437,7 +437,7 @@ void A_SWPB(ARM* cpu)
|
||||||
}
|
}
|
||||||
cpu->DataCycles += numD;
|
cpu->DataCycles += numD;
|
||||||
}
|
}
|
||||||
cpu->AddCycles_CDI_SWP();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ void A_LDM(ARM* cpu)
|
||||||
|
|
||||||
if (!preinc) base += 4;
|
if (!preinc) base += 4;
|
||||||
|
|
||||||
if (cpu->Num == 1)
|
if (cpu->Num == 1 || (((ARMv5*)cpu)->CP15Control & (1<<15)))
|
||||||
pc &= ~0x1;
|
pc &= ~0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ void A_LDM(ARM* cpu)
|
||||||
cpu->R[baseid] = oldbase;
|
cpu->R[baseid] = oldbase;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->AddCycles_CDI_LDM();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void A_STM(ARM* cpu)
|
void A_STM(ARM* cpu)
|
||||||
|
@ -630,7 +630,7 @@ void A_STM(ARM* cpu)
|
||||||
cpu->R[baseid] = oldbase;
|
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);
|
u32 addr = (cpu->R[15] & ~0x2) + ((cpu->CurInstr & 0xFF) << 2);
|
||||||
cpu->DataRead32(addr, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
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];
|
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||||
cpu->DataWrite32(addr, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite32(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
|
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_STRB_REG(ARM* cpu)
|
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];
|
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||||
cpu->DataWrite8(addr, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite8(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
|
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDR_REG(ARM* cpu)
|
void T_LDR_REG(ARM* cpu)
|
||||||
|
@ -673,7 +673,7 @@ void T_LDR_REG(ARM* cpu)
|
||||||
if (cpu->DataRead32(addr, &val))
|
if (cpu->DataRead32(addr, &val))
|
||||||
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3));
|
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3));
|
||||||
|
|
||||||
cpu->AddCycles_CDI_LDR();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDRB_REG(ARM* cpu)
|
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];
|
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||||
cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 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];
|
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||||
cpu->DataWrite16(addr, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite16(addr, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
|
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDRSB_REG(ARM* cpu)
|
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]))
|
if (cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 0x7]))
|
||||||
cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)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)
|
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];
|
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
|
||||||
cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]);
|
||||||
|
|
||||||
cpu->AddCycles_CDI_LDR();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDRSH_REG(ARM* cpu)
|
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]))
|
if (cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]))
|
||||||
cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)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];
|
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||||
|
|
||||||
cpu->DataWrite32(offset, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite32(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDR_IMM(ARM* cpu)
|
void T_LDR_IMM(ARM* cpu)
|
||||||
|
@ -737,7 +737,7 @@ void T_LDR_IMM(ARM* cpu)
|
||||||
u32 val;
|
u32 val;
|
||||||
if (cpu->DataRead32(offset, &val))
|
if (cpu->DataRead32(offset, &val))
|
||||||
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3));
|
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3));
|
||||||
cpu->AddCycles_CDI_LDR();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_STRB_IMM(ARM* cpu)
|
void T_STRB_IMM(ARM* cpu)
|
||||||
|
@ -746,7 +746,7 @@ void T_STRB_IMM(ARM* cpu)
|
||||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||||
|
|
||||||
cpu->DataWrite8(offset, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite8(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDRB_IMM(ARM* cpu)
|
void T_LDRB_IMM(ARM* cpu)
|
||||||
|
@ -755,7 +755,7 @@ void T_LDRB_IMM(ARM* cpu)
|
||||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||||
|
|
||||||
cpu->DataRead8(offset, &cpu->R[cpu->CurInstr & 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];
|
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||||
|
|
||||||
cpu->DataWrite16(offset, cpu->R[cpu->CurInstr & 0x7]);
|
cpu->DataWrite16(offset, cpu->R[cpu->CurInstr & 0x7]);
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDRH_IMM(ARM* cpu)
|
void T_LDRH_IMM(ARM* cpu)
|
||||||
|
@ -774,7 +774,7 @@ void T_LDRH_IMM(ARM* cpu)
|
||||||
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
|
||||||
|
|
||||||
cpu->DataRead16(offset, &cpu->R[cpu->CurInstr & 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];
|
offset += cpu->R[13];
|
||||||
|
|
||||||
cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
||||||
cpu->AddCycles_CD_STR();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDR_SPREL(ARM* cpu)
|
void T_LDR_SPREL(ARM* cpu)
|
||||||
|
@ -793,7 +793,7 @@ void T_LDR_SPREL(ARM* cpu)
|
||||||
offset += cpu->R[13];
|
offset += cpu->R[13];
|
||||||
|
|
||||||
cpu->DataRead32(offset, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
|
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;
|
cpu->R[13] = wbbase;
|
||||||
|
|
||||||
dataabort:
|
dataabort:
|
||||||
cpu->AddCycles_CD_STM();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_POP(ARM* cpu)
|
void T_POP(ARM* cpu)
|
||||||
|
@ -871,7 +871,7 @@ void T_POP(ARM* cpu)
|
||||||
{
|
{
|
||||||
goto dataabort;
|
goto dataabort;
|
||||||
}
|
}
|
||||||
if (cpu->Num==1) pc |= 0x1;
|
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) pc |= 0x1;
|
||||||
cpu->JumpTo(pc);
|
cpu->JumpTo(pc);
|
||||||
base += 4;
|
base += 4;
|
||||||
}
|
}
|
||||||
|
@ -879,7 +879,7 @@ void T_POP(ARM* cpu)
|
||||||
cpu->R[13] = base;
|
cpu->R[13] = base;
|
||||||
|
|
||||||
dataabort:
|
dataabort:
|
||||||
cpu->AddCycles_CDI_LDM();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_STMIA(ARM* cpu)
|
void T_STMIA(ARM* cpu)
|
||||||
|
@ -904,7 +904,7 @@ void T_STMIA(ARM* cpu)
|
||||||
// TODO: check "Rb included in Rlist" case
|
// TODO: check "Rb included in Rlist" case
|
||||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||||
dataabort:
|
dataabort:
|
||||||
cpu->AddCycles_CD_STM();
|
cpu->AddCycles_CD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_LDMIA(ARM* cpu)
|
void T_LDMIA(ARM* cpu)
|
||||||
|
@ -930,7 +930,7 @@ void T_LDMIA(ARM* cpu)
|
||||||
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
|
||||||
|
|
||||||
dataabort:
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
@ -846,21 +843,18 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -877,21 +871,18 @@ bool ARMv5::DataRead32(u32 addr, u32* val)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -934,7 +925,6 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_ITCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(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);
|
||||||
|
@ -942,14 +932,12 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_DTCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BusWrite8(addr, val);
|
BusWrite8(addr, val);
|
||||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +954,6 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_ITCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(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);
|
||||||
|
@ -974,14 +961,12 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_DTCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BusWrite16(addr, val);
|
BusWrite16(addr, val);
|
||||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -998,7 +983,6 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_ITCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(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);
|
||||||
|
@ -1006,14 +990,12 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataRegion = Mem9_DTCM;
|
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BusWrite32(addr, val);
|
BusWrite32(addr, val);
|
||||||
DataRegion = NDS.ARM9Regions[addr >> 14];
|
|
||||||
DataCycles = MemTimings[addr >> 12][2];
|
DataCycles = MemTimings[addr >> 12][2];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue