aboutsummaryrefslogtreecommitdiff
path: root/src/ARMInterpreter_LoadStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARMInterpreter_LoadStore.cpp')
-rw-r--r--src/ARMInterpreter_LoadStore.cpp216
1 files changed, 145 insertions, 71 deletions
diff --git a/src/ARMInterpreter_LoadStore.cpp b/src/ARMInterpreter_LoadStore.cpp
index adb44a9..5a1b88d 100644
--- a/src/ARMInterpreter_LoadStore.cpp
+++ b/src/ARMInterpreter_LoadStore.cpp
@@ -63,28 +63,35 @@ namespace ARMInterpreter
#define A_STR \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
- if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
+ if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->AddCycles_CD();
+// TODO: user mode (bit21)
#define A_STR_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->DataWrite32(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \
- cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
+ cpu->DataWrite32(addr, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->AddCycles_CD();
#define A_STRB \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->DataWrite8(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
- if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset;
+ if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->AddCycles_CD();
+// TODO: user mode (bit21)
#define A_STRB_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->DataWrite8(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \
- cpu->R[(cpu->CurInstr>>16) & 0xF] += offset;
+ cpu->DataWrite8(addr, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->AddCycles_CD();
#define A_LDR \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- u32 val = cpu->DataRead32(offset); val = ROR(val, ((offset&0x3)<<3)); \
+ u32 val; cpu->DataRead32(offset, &val); \
+ val = ROR(val, ((offset&0x3)<<3)); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->Cycles += 1; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) \
{ \
if (cpu->Num==1) val &= ~0x1; \
@@ -95,11 +102,13 @@ namespace ARMInterpreter
cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
}
+// TODO: user mode
#define A_LDR_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- u32 val = cpu->DataRead32(addr, cpu->CurInstr & (1<<21)); val = ROR(val, ((addr&0x3)<<3)); \
+ u32 val; cpu->DataRead32(addr, &val); \
+ val = ROR(val, ((addr&0x3)<<3)); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->Cycles += 1; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) \
{ \
if (cpu->Num==1) val &= ~0x1; \
@@ -112,17 +121,18 @@ namespace ARMInterpreter
#define A_LDRB \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- u32 val = cpu->DataRead8(offset); \
+ u32 val; cpu->DataRead8(offset, &val); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->Cycles += 1; \
+ cpu->AddCycles_CDI(); \
cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \
+// TODO: user mode
#define A_LDRB_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- u32 val = cpu->DataRead8(addr, cpu->CurInstr & (1<<21)); \
+ u32 val; cpu->DataRead8(addr, &val); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->Cycles += 1; \
+ cpu->AddCycles_CDI(); \
cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \
@@ -211,11 +221,13 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->DataWrite16(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->AddCycles_CD();
#define A_STRH_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->DataWrite16(addr, cpu->R[(cpu->CurInstr>>12) & 0xF]); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->AddCycles_CD();
// TODO: CHECK LDRD/STRD TIMINGS!!
@@ -223,69 +235,85 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
if (cpu->Num != 0) return; \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->Cycles += 1; \
u32 r = (cpu->CurInstr>>12) & 0xF; \
- cpu->R[r ] = cpu->DataRead32(offset ); \
- cpu->R[r+1] = cpu->DataRead32(offset+4); \
+ if (r&1) { r--; printf("!! MISALIGNED LDRD_POST %d\n", r); } \
+ cpu->DataRead32 (offset , &cpu->R[r ]); \
+ cpu->DataRead32S(offset+4, &cpu->R[r+1]); \
+ cpu->AddCycles_CDI();
#define A_LDRD_POST \
if (cpu->Num != 0) return; \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->Cycles += 1; \
u32 r = (cpu->CurInstr>>12) & 0xF; \
- cpu->R[r ] = cpu->DataRead32(addr ); \
- cpu->R[r+1] = cpu->DataRead32(addr+4); \
+ if (r&1) { r--; printf("!! MISALIGNED LDRD_POST %d\n", r); } \
+ cpu->DataRead32 (addr , &cpu->R[r ]); \
+ cpu->DataRead32S(addr+4, &cpu->R[r+1]); \
+ cpu->AddCycles_CDI();
#define A_STRD \
if (cpu->Num != 0) return; \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
u32 r = (cpu->CurInstr>>12) & 0xF; \
- cpu->DataWrite32(offset , cpu->R[r ]); \
- cpu->DataWrite32(offset+4, cpu->R[r+1]); \
+ if (r&1) { r--; printf("!! MISALIGNED LDRD_POST %d\n", r); } \
+ cpu->DataWrite32 (offset , cpu->R[r ]); \
+ cpu->DataWrite32S(offset+4, cpu->R[r+1]); \
+ cpu->AddCycles_CD();
#define A_STRD_POST \
if (cpu->Num != 0) return; \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
u32 r = (cpu->CurInstr>>12) & 0xF; \
- cpu->DataWrite32(offset , cpu->R[r ]); \
- cpu->DataWrite32(offset+4, cpu->R[r+1]); \
+ if (r&1) { r--; printf("!! MISALIGNED LDRD_POST %d\n", r); } \
+ cpu->DataWrite32 (offset , cpu->R[r ]); \
+ cpu->DataWrite32S(offset+4, cpu->R[r+1]); \
+ cpu->AddCycles_CD();
#define A_LDRH \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->DataRead16(offset); \
+ cpu->DataRead16(offset, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \
#define A_LDRH_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->DataRead16(addr); \
+ cpu->DataRead16(addr, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \
#define A_LDRSB \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->DataRead8(offset); \
+ cpu->DataRead8(offset, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->R[(cpu->CurInstr>>12) & 0xF]; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \
#define A_LDRSB_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->DataRead8(addr); \
+ cpu->DataRead8(addr, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->R[(cpu->CurInstr>>12) & 0xF]; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \
#define A_LDRSH \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->DataRead16(offset); \
+ cpu->DataRead16(offset, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->R[(cpu->CurInstr>>12) & 0xF]; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \
#define A_LDRSH_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->DataRead16(addr); \
+ cpu->DataRead16(addr, &cpu->R[(cpu->CurInstr>>12) & 0xF]); \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->R[(cpu->CurInstr>>12) & 0xF]; \
+ cpu->AddCycles_CDI(); \
if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \
@@ -328,12 +356,15 @@ void A_SWP(ARM* cpu)
u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
u32 rm = cpu->R[cpu->CurInstr & 0xF];
- u32 val = cpu->DataRead32(base);
+ u32 val;
+ cpu->DataRead32(base, &val);
cpu->R[(cpu->CurInstr >> 12) & 0xF] = ROR(val, 8*(base&0x3));
+ u32 numD = cpu->DataCycles;
cpu->DataWrite32(base, rm);
+ cpu->DataCycles += numD;
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
void A_SWPB(ARM* cpu)
@@ -341,11 +372,13 @@ void A_SWPB(ARM* cpu)
u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
u32 rm = cpu->R[cpu->CurInstr & 0xF] & 0xFF;
- cpu->R[(cpu->CurInstr >> 12) & 0xF] = cpu->DataRead8(base);
+ cpu->DataRead8(base, &cpu->R[(cpu->CurInstr >> 12) & 0xF]);
+ u32 numD = cpu->DataCycles;
cpu->DataWrite8(base, rm);
+ cpu->DataCycles += numD;
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
@@ -356,6 +389,7 @@ void A_LDM(ARM* cpu)
u32 base = cpu->R[baseid];
u32 wbbase;
u32 preinc = (cpu->CurInstr & (1<<24));
+ bool first = true;
if (!(cpu->CurInstr & (1<<23)))
{
@@ -374,8 +408,6 @@ void A_LDM(ARM* cpu)
preinc = !preinc;
}
- cpu->Cycles += 1;
-
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10);
@@ -384,15 +416,19 @@ void A_LDM(ARM* cpu)
if (cpu->CurInstr & (1<<i))
{
if (preinc) base += 4;
- cpu->R[i] = cpu->DataRead32(base);
+ if (first) cpu->DataRead32 (base, &cpu->R[i]);
+ else cpu->DataRead32S(base, &cpu->R[i]);
+ first = false;
if (!preinc) base += 4;
}
}
if (cpu->CurInstr & (1<<15))
{
+ u32 pc;
if (preinc) base += 4;
- u32 pc = cpu->DataRead32(base);
+ if (first) cpu->DataRead32 (base, &pc);
+ else cpu->DataRead32S(base, &pc);
if (!preinc) base += 4;
if (cpu->Num == 1)
@@ -422,6 +458,8 @@ void A_LDM(ARM* cpu)
else
cpu->R[baseid] = wbbase;
}
+
+ cpu->AddCycles_CDI();
}
void A_STM(ARM* cpu)
@@ -430,6 +468,7 @@ void A_STM(ARM* cpu)
u32 base = cpu->R[baseid];
u32 oldbase = base;
u32 preinc = (cpu->CurInstr & (1<<24));
+ bool first = true;
if (!(cpu->CurInstr & (1<<23)))
{
@@ -466,12 +505,14 @@ void A_STM(ARM* cpu)
if (i == baseid && !isbanked)
{
if ((cpu->Num == 0) || (!(cpu->CurInstr & ((1<<i)-1))))
- cpu->DataWrite32(base, oldbase);
+ first ? cpu->DataWrite32(base, oldbase) : cpu->DataWrite32S(base, oldbase);
else
- cpu->DataWrite32(base, base); // checkme
+ first ? cpu->DataWrite32(base, base) : cpu->DataWrite32S(base, base); // checkme
}
else
- cpu->DataWrite32(base, cpu->R[i]);
+ first ? cpu->DataWrite32(base, cpu->R[i]) : cpu->DataWrite32S(base, cpu->R[i]);
+
+ first = false;
if (!preinc) base += 4;
}
@@ -482,6 +523,8 @@ void A_STM(ARM* cpu)
if ((cpu->CurInstr & (1<<23)) && (cpu->CurInstr & (1<<21)))
cpu->R[baseid] = base;
+
+ cpu->AddCycles_CD();
}
@@ -494,9 +537,9 @@ void A_STM(ARM* cpu)
void T_LDR_PCREL(ARM* cpu)
{
u32 addr = (cpu->R[15] & ~0x2) + ((cpu->CurInstr & 0xFF) << 2);
- cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->DataRead32(addr);
+ cpu->DataRead32(addr, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
@@ -504,30 +547,35 @@ 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();
}
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();
}
void T_LDR_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- u32 val = cpu->DataRead32(addr);
+ u32 val;
+ cpu->DataRead32(addr, &val);
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3));
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
void T_LDRB_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead8(addr);
+ cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 0x7]);
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
@@ -535,30 +583,34 @@ 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();
}
void T_LDRSB_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)cpu->DataRead8(addr);
+ cpu->DataRead8(addr, &cpu->R[cpu->CurInstr & 0x7]);
+ cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)cpu->R[cpu->CurInstr & 0x7];
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
void T_LDRH_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead16(addr);
+ cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]);
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
void T_LDRSH_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)cpu->DataRead16(addr);
+ cpu->DataRead16(addr, &cpu->R[cpu->CurInstr & 0x7]);
+ cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)cpu->R[cpu->CurInstr & 0x7];
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
@@ -568,6 +620,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();
}
void T_LDR_IMM(ARM* cpu)
@@ -575,9 +628,10 @@ void T_LDR_IMM(ARM* cpu)
u32 offset = (cpu->CurInstr >> 4) & 0x7C;
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
- u32 val = cpu->DataRead32(offset);
+ u32 val;
+ cpu->DataRead32(offset, &val);
cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3));
- cpu->Cycles += 1;
+ cpu->AddCycles_CDI();
}
void T_STRB_IMM(ARM* cpu)
@@ -586,6 +640,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();
}
void T_LDRB_IMM(ARM* cpu)
@@ -593,8 +648,8 @@ void T_LDRB_IMM(ARM* cpu)
u32 offset = (cpu->CurInstr >> 6) & 0x1F;
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead8(offset);
- cpu->Cycles += 1;
+ cpu->DataRead8(offset, &cpu->R[cpu->CurInstr & 0x7]);
+ cpu->AddCycles_CDI();
}
@@ -604,6 +659,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();
}
void T_LDRH_IMM(ARM* cpu)
@@ -611,8 +667,8 @@ void T_LDRH_IMM(ARM* cpu)
u32 offset = (cpu->CurInstr >> 5) & 0x3E;
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead16(offset);
- cpu->Cycles += 1;
+ cpu->DataRead16(offset, &cpu->R[cpu->CurInstr & 0x7]);
+ cpu->AddCycles_CDI();
}
@@ -622,6 +678,7 @@ void T_STR_SPREL(ARM* cpu)
offset += cpu->R[13];
cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]);
+ cpu->AddCycles_CD();
}
void T_LDR_SPREL(ARM* cpu)
@@ -629,14 +686,15 @@ void T_LDR_SPREL(ARM* cpu)
u32 offset = (cpu->CurInstr << 2) & 0x3FC;
offset += cpu->R[13];
- cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->DataRead32(offset);
- cpu->Cycles += 1;
+ cpu->DataRead32(offset, &cpu->R[(cpu->CurInstr >> 8) & 0x7]);
+ cpu->AddCycles_CDI();
}
void T_PUSH(ARM* cpu)
{
int nregs = 0;
+ bool first = true;
for (int i = 0; i < 8; i++)
{
@@ -655,77 +713,93 @@ void T_PUSH(ARM* cpu)
{
if (cpu->CurInstr & (1<<i))
{
- cpu->DataWrite32(base, cpu->R[i]);
+ if (first) cpu->DataWrite32 (base, cpu->R[i]);
+ else cpu->DataWrite32S(base, cpu->R[i]);
+ first = false;
base += 4;
}
}
if (cpu->CurInstr & (1<<8))
{
- cpu->DataWrite32(base, cpu->R[14]);
+ if (first) cpu->DataWrite32 (base, cpu->R[14]);
+ else cpu->DataWrite32S(base, cpu->R[14]);
}
+
+ cpu->AddCycles_CD();
}
void T_POP(ARM* cpu)
{
u32 base = cpu->R[13];
-
- cpu->Cycles += 1;
+ bool first = true;
for (int i = 0; i < 8; i++)
{
if (cpu->CurInstr & (1<<i))
{
- cpu->R[i] = cpu->DataRead32(base);
+ if (first) cpu->DataRead32 (base, &cpu->R[i]);
+ else cpu->DataRead32S(base, &cpu->R[i]);
+ first = false;
base += 4;
}
}
if (cpu->CurInstr & (1<<8))
{
- u32 pc = cpu->DataRead32(base);
+ u32 pc;
+ if (first) cpu->DataRead32 (base, &pc);
+ else cpu->DataRead32S(base, &pc);
if (cpu->Num==1) pc |= 0x1;
cpu->JumpTo(pc);
base += 4;
}
cpu->R[13] = base;
+ cpu->AddCycles_CDI();
}
void T_STMIA(ARM* cpu)
{
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
+ bool first = true;
for (int i = 0; i < 8; i++)
{
if (cpu->CurInstr & (1<<i))
{
- cpu->DataWrite32(base, cpu->R[i]);
+ if (first) cpu->DataWrite32 (base, cpu->R[i]);
+ else cpu->DataWrite32S(base, cpu->R[i]);
+ first = false;
base += 4;
}
}
// TODO: check "Rb included in Rlist" case
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
+ cpu->AddCycles_CD();
}
void T_LDMIA(ARM* cpu)
{
u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7];
-
- cpu->Cycles += 1;
+ bool first = true;
for (int i = 0; i < 8; i++)
{
if (cpu->CurInstr & (1<<i))
{
- cpu->R[i] = cpu->DataRead32(base);
+ if (first) cpu->DataRead32 (base, &cpu->R[i]);
+ else cpu->DataRead32S(base, &cpu->R[i]);
+ first = false;
base += 4;
}
}
if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7))))
cpu->R[(cpu->CurInstr >> 8) & 0x7] = base;
+
+ cpu->AddCycles_CDI();
}