diff options
Diffstat (limited to 'src/ARMInterpreter_LoadStore.cpp')
-rw-r--r-- | src/ARMInterpreter_LoadStore.cpp | 216 |
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(); } |