diff options
Diffstat (limited to 'ARM.cpp')
-rw-r--r-- | ARM.cpp | 66 |
1 files changed, 43 insertions, 23 deletions
@@ -53,12 +53,20 @@ void ARM::JumpTo(u32 addr) { // pipeline shit - // TODO: THUMB!! - if (addr&1) printf("!!! THUMB JUMP\n"); - - addr &= ~3; - NextInstr = Read32(addr); - R[15] = addr+4; + if (addr&1) + { + addr &= ~1; + NextInstr = Read16(addr); + R[15] = addr+2; + CPSR |= 0x20; + } + else + { + addr &= ~3; + NextInstr = Read32(addr); + R[15] = addr+4; + CPSR &= ~0x20; + } } void ARM::RestoreCPSR() @@ -70,27 +78,39 @@ s32 ARM::Execute(s32 cycles) { while (cycles > 0) { - // TODO THUM SHIT ASGAFDGSUHAJISGFYAUISAGY - - // prefetch - CurInstr = NextInstr; - NextInstr = Read32(R[15]); - R[15] += 4; - - // actually execute - if (CheckCondition(CurInstr >> 28)) - { - u32 icode = ((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0); - cycles -= ARMInterpreter::ARMInstrTable[icode](this); - } - else if ((CurInstr & 0xFE000000) == 0xFA000000) + if (CPSR & 0x20) // THUMB { - cycles -= ARMInterpreter::A_BLX_IMM(this); + // prefetch + CurInstr = NextInstr; + NextInstr = Read16(R[15]); + R[15] += 2; + + // actually execute + u32 icode = (CurInstr >> 6); + cycles -= ARMInterpreter::THUMBInstrTable[icode](this); } else { - // not executing it. oh well - cycles -= 1; // 1S. todo: check + // prefetch + CurInstr = NextInstr; + NextInstr = Read32(R[15]); + R[15] += 4; + + // actually execute + if (CheckCondition(CurInstr >> 28)) + { + u32 icode = ((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0); + cycles -= ARMInterpreter::ARMInstrTable[icode](this); + } + else if ((CurInstr & 0xFE000000) == 0xFA000000) + { + cycles -= ARMInterpreter::A_BLX_IMM(this); + } + else + { + // not executing it. oh well + cycles -= 1; // 1S. todo: check + } } } |