diff options
Diffstat (limited to 'ARMInterpreter_LoadStore.cpp')
-rw-r--r-- | ARMInterpreter_LoadStore.cpp | 100 |
1 files changed, 94 insertions, 6 deletions
diff --git a/ARMInterpreter_LoadStore.cpp b/ARMInterpreter_LoadStore.cpp index 173e417..9e69f77 100644 --- a/ARMInterpreter_LoadStore.cpp +++ b/ARMInterpreter_LoadStore.cpp @@ -196,13 +196,13 @@ A_IMPLEMENT_WB_LDRSTR(LDRB) offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->Write16(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ if (cpu->CurInstr & (1<<24)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ - return C_N(2) + cpu->MemWaitstate(3, offset); + return C_N(2) + cpu->MemWaitstate(2, offset); #define A_STRH_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->Write16(addr, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(3, addr); + return C_N(2) + cpu->MemWaitstate(2, addr); // TODO: CHECK LDRD/STRD TIMINGS!! @@ -242,13 +242,13 @@ A_IMPLEMENT_WB_LDRSTR(LDRB) offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(offset); \ if (cpu->CurInstr & (1<<24)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ - return C_N(2) + cpu->MemWaitstate(3, offset); + return C_N(2) + cpu->MemWaitstate(2, offset); #define A_LDRH_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(addr); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(3, addr); + return C_N(2) + cpu->MemWaitstate(2, addr); #define A_LDRSB \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ @@ -266,13 +266,13 @@ A_IMPLEMENT_WB_LDRSTR(LDRB) offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(offset); \ if (cpu->CurInstr & (1<<24)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ - return C_N(2) + cpu->MemWaitstate(3, offset); + return C_N(2) + cpu->MemWaitstate(2, offset); #define A_LDRSH_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(addr); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(3, addr); + return C_N(2) + cpu->MemWaitstate(2, addr); #define A_IMPLEMENT_HD_LDRSTR(x) \ @@ -356,5 +356,93 @@ s32 T_LDRB_REG(ARM* cpu) } +s32 T_STRH_IMM(ARM* cpu) +{ + u32 offset = (cpu->CurInstr >> 5) & 0x3E; + offset += cpu->R[(cpu->CurInstr >> 3) & 0x7]; + + cpu->Write16(offset, cpu->R[cpu->CurInstr & 0x7]); + return C_N(2) + cpu->MemWaitstate(2, offset); +} + +s32 T_LDRH_IMM(ARM* cpu) +{ + u32 offset = (cpu->CurInstr >> 5) & 0x3E; + offset += cpu->R[(cpu->CurInstr >> 3) & 0x7]; + + cpu->R[cpu->CurInstr & 0x7] = cpu->Read16(offset); + return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, offset); +} + + +s32 T_PUSH(ARM* cpu) +{ + int nregs = 0; + + for (int i = 0; i < 8; i++) + { + if (cpu->CurInstr & (1<<i)) + nregs++; + } + + if (cpu->CurInstr & (1<<8)) + nregs++; + + u32 base = cpu->R[13]; + base -= (nregs<<2); + cpu->R[13] = base; + + int cycles = C_N(2); + + for (int i = 0; i < 8; i++) + { + if (cpu->CurInstr & (1<<i)) + { + cpu->Write32(base, cpu->R[i]); + cycles += C_S(1) + cpu->MemWaitstate(3, base); + base += 4; + } + } + + if (cpu->CurInstr & (1<<8)) + { + cpu->Write32(base, cpu->R[14]); + cycles += C_S(1) + cpu->MemWaitstate(3, base); + } + + return cycles - C_S(1); +} + +s32 T_POP(ARM* cpu) +{ + u32 base = cpu->R[13]; + + int cycles = C_N(1) + C_I(1); + + for (int i = 0; i < 8; i++) + { + if (cpu->CurInstr & (1<<i)) + { + cpu->R[i] = cpu->Read32(base); + cycles += C_S(1) + cpu->MemWaitstate(3, base); + base += 4; + } + } + + if (cpu->CurInstr & (1<<8)) + { + u32 pc = cpu->Read32(base); + if (cpu->Num==1) pc |= 0x1; + cpu->JumpTo(pc); + cycles += C_S(2) + C_N(1) + cpu->MemWaitstate(3, base); + base += 4; + } + + cpu->R[13] = base; + + return cycles; +} + + } |