diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-01-30 18:36:11 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-01-30 18:36:11 +0100 |
commit | 6f3b0498dbfb4f264f406901a774078fbe0eca6e (patch) | |
tree | 59f2c52b38ecff6c1d5cddbec3870851fac167ab | |
parent | 296212ac49f1edabccde826138f8f720ef9beef5 (diff) |
start refactoring shit: more accurate timing and way of counting cycles.
-rw-r--r-- | ARM.cpp | 145 | ||||
-rw-r--r-- | ARM.h | 91 | ||||
-rw-r--r-- | ARMInterpreter.cpp | 42 | ||||
-rw-r--r-- | ARMInterpreter.h | 6 | ||||
-rw-r--r-- | ARMInterpreter_ALU.cpp | 280 | ||||
-rw-r--r-- | ARMInterpreter_ALU.h | 150 | ||||
-rw-r--r-- | ARMInterpreter_Branch.cpp | 46 | ||||
-rw-r--r-- | ARMInterpreter_Branch.h | 22 | ||||
-rw-r--r-- | ARMInterpreter_LoadStore.cpp | 300 | ||||
-rw-r--r-- | ARMInterpreter_LoadStore.h | 78 | ||||
-rw-r--r-- | CP15.cpp | 2 | ||||
-rw-r--r-- | GPU.cpp | 29 | ||||
-rw-r--r-- | NDS.cpp | 1 | ||||
-rw-r--r-- | NDS.h | 18 | ||||
-rw-r--r-- | SPI.cpp | 6 | ||||
-rw-r--r-- | main.cpp | 1 | ||||
-rw-r--r-- | melonDS.depend | 32 |
17 files changed, 645 insertions, 604 deletions
@@ -47,6 +47,97 @@ ARM::ARM(u32 num) { // well uh Num = num; + + for (int i = 0; i < 16; i++) + { + Waitstates[0][i] = 1; + Waitstates[1][i] = 1; + Waitstates[2][i] = 1; + Waitstates[3][i] = 1; + } + + if (!num) + { + // ARM9 + Waitstates[0][0x2] = 1; // main RAM timing, assuming cache hit + Waitstates[0][0x3] = 4; + Waitstates[0][0x4] = 4; + Waitstates[0][0x5] = 5; + Waitstates[0][0x6] = 5; + Waitstates[0][0x7] = 4; + Waitstates[0][0x8] = 19; + Waitstates[0][0x9] = 19; + Waitstates[0][0xF] = 4; + + Waitstates[1][0x2] = 1; + Waitstates[1][0x3] = 8; + Waitstates[1][0x4] = 8; + Waitstates[1][0x5] = 10; + Waitstates[1][0x6] = 10; + Waitstates[1][0x7] = 8; + Waitstates[1][0x8] = 38; + Waitstates[1][0x9] = 38; + Waitstates[1][0xF] = 8; + + Waitstates[2][0x2] = 1; + Waitstates[2][0x3] = 2; + Waitstates[2][0x4] = 2; + Waitstates[2][0x5] = 2; + Waitstates[2][0x6] = 2; + Waitstates[2][0x7] = 2; + Waitstates[2][0x8] = 12; + Waitstates[2][0x9] = 12; + Waitstates[2][0xA] = 20; + Waitstates[2][0xF] = 2; + + Waitstates[3][0x2] = 1; + Waitstates[3][0x3] = 2; + Waitstates[3][0x4] = 2; + Waitstates[3][0x5] = 4; + Waitstates[3][0x6] = 4; + Waitstates[3][0x7] = 2; + Waitstates[3][0x8] = 24; + Waitstates[3][0x9] = 24; + Waitstates[3][0xA] = 20; + Waitstates[3][0xF] = 2; + } + else + { + // ARM7 + Waitstates[0][0x0] = 1; + Waitstates[0][0x2] = 1; + Waitstates[0][0x3] = 1; + Waitstates[0][0x4] = 1; + Waitstates[0][0x6] = 1; + Waitstates[0][0x8] = 6; + Waitstates[0][0x9] = 6; + + Waitstates[1][0x0] = 1; + Waitstates[1][0x2] = 2; + Waitstates[1][0x3] = 1; + Waitstates[1][0x4] = 1; + Waitstates[1][0x6] = 2; + Waitstates[1][0x8] = 12; + Waitstates[1][0x9] = 12; + + Waitstates[2][0x0] = 1; + Waitstates[2][0x2] = 1; + Waitstates[2][0x3] = 1; + Waitstates[2][0x4] = 1; + Waitstates[2][0x6] = 1; + Waitstates[2][0x8] = 6; + Waitstates[2][0x9] = 6; + Waitstates[2][0xA] = 10; + + Waitstates[3][0x0] = 1; + Waitstates[3][0x2] = 2; + Waitstates[3][0x3] = 1; + Waitstates[3][0x4] = 1; + Waitstates[3][0x6] = 2; + Waitstates[3][0x8] = 12; + Waitstates[3][0x9] = 12; + Waitstates[3][0xA] = 10; + } } ARM::~ARM() @@ -83,21 +174,23 @@ void ARM::JumpTo(u32 addr, bool restorecpsr) if (addr == 0x02000800) { printf("!!!!!!!! %08X\n", R[15]); - printf("%08X %08X %08X %08X\n", Read32(0x02000000), Read32(0x0200000C), Read32(0x02000800), Read32(0x02000804)); + //printf("%08X %08X %08X %08X\n", Read32(0x02000000), Read32(0x0200000C), Read32(0x02000800), Read32(0x02000804)); } if (addr & 0x1) { addr &= ~0x1; R[15] = addr+2; - NextInstr = Read16(addr); + NextInstr[0] = CodeRead16(addr); + NextInstr[1] = CodeRead16(addr+2); CPSR |= 0x20; } else { addr &= ~0x3; R[15] = addr+4; - NextInstr = Read32(addr); + NextInstr[0] = CodeRead32(addr); + NextInstr[1] = CodeRead32(addr+4); CPSR &= ~0x20; } } @@ -227,67 +320,65 @@ void ARM::TriggerIRQ() JumpTo(ExceptionBase + 0x18); } -s32 ARM::Execute(s32 cycles) +s32 ARM::Execute(s32 cyclestorun) { if (Halted) { if (NDS::HaltInterrupted(Num)) Halted = 0; else - return cycles; + { + Cycles = cyclestorun; + return Cycles; + } } - s32 cyclesrun = 0; + Cycles = 0; u32 addr = R[15] - (CPSR&0x20 ? 4:8); u32 cpsr = CPSR; - while (cyclesrun < cycles) + while (Cycles < cyclestorun) { //if(Num==1)printf("%08X %08X\n", R[15] - (CPSR&0x20 ? 4:8), NextInstr); if (CPSR & 0x20) // THUMB { // prefetch - CurInstr = NextInstr; - NextInstr = Read16(R[15]); - //cyclesrun += MemWaitstate(0, R[15]); R[15] += 2; - - Cycles = cyclesrun; + CurInstr = NextInstr[0]; + NextInstr[0] = NextInstr[1]; + NextInstr[1] = CodeRead16(R[15]); // actually execute u32 icode = (CurInstr >> 6); - cyclesrun += ARMInterpreter::THUMBInstrTable[icode](this); + ARMInterpreter::THUMBInstrTable[icode](this); } else { // prefetch - CurInstr = NextInstr; - NextInstr = Read32(R[15]); - //cyclesrun += MemWaitstate(1, R[15]); R[15] += 4; - - Cycles = cyclesrun; + CurInstr = NextInstr[0]; + NextInstr[0] = NextInstr[1]; + NextInstr[1] = CodeRead32(R[15]); // actually execute if (CheckCondition(CurInstr >> 28)) { u32 icode = ((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0); - cyclesrun += ARMInterpreter::ARMInstrTable[icode](this); + ARMInterpreter::ARMInstrTable[icode](this); } else if ((CurInstr & 0xFE000000) == 0xFA000000) { - cyclesrun += ARMInterpreter::A_BLX_IMM(this); - } - else - { - // not executing it. oh well - cyclesrun += 1; // 1S. todo: check + ARMInterpreter::A_BLX_IMM(this); } } // TODO optimize this shit!!! - if (Halted) return cycles; + if (Halted) + { + Cycles = cyclestorun; + return Cycles; + } if (NDS::HaltInterrupted(Num)) { if (NDS::IME[Num]&1) @@ -299,5 +390,5 @@ s32 ARM::Execute(s32 cycles) cpsr = CPSR; } - return cyclesrun; + return Cycles; } @@ -81,42 +81,86 @@ public: void TriggerIRQ(); - u8 Read8(u32 addr, u32 forceuser=0) + u16 CodeRead16(u32 addr) { + u16 val; + // TODO eventually: on ARM9, THUMB opcodes are prefetched with 32bit reads if (!Num) { // TODO: PU shit - return NDS::ARM9Read8(addr); + val = NDS::ARM9Read16(addr); } else - return NDS::ARM7Read8(addr); + val = NDS::ARM7Read16(addr); + + Cycles += Waitstates[0][(addr>>24)&0xF]; + return val; } - u16 Read16(u32 addr, u32 forceuser=0) + u32 CodeRead32(u32 addr) { + u32 val; + if (!Num) + { + // TODO: PU shit + val = NDS::ARM9Read32(addr); + } + else + val = NDS::ARM7Read32(addr); + + Cycles += Waitstates[1][(addr>>24)&0xF]; + return val; + } + + + u8 DataRead8(u32 addr, u32 forceuser=0) + { + u8 val; + if (!Num) + { + // TODO: PU shit + val = NDS::ARM9Read8(addr); + } + else + val = NDS::ARM7Read8(addr); + + Cycles += Waitstates[3][(addr>>24)&0xF]; + return val; + } + + u16 DataRead16(u32 addr, u32 forceuser=0) + { + u16 val; addr &= ~1; if (!Num) { // TODO: PU shit - return NDS::ARM9Read16(addr); + val = NDS::ARM9Read16(addr); } else - return NDS::ARM7Read16(addr); + val = NDS::ARM7Read16(addr); + + Cycles += Waitstates[2][(addr>>24)&0xF]; + return val; } - u32 Read32(u32 addr, u32 forceuser=0) + u32 DataRead32(u32 addr, u32 forceuser=0) { + u32 val; addr &= ~3; if (!Num) { // TODO: PU shit - return NDS::ARM9Read32(addr); + val = NDS::ARM9Read32(addr); } else - return NDS::ARM7Read32(addr); + val = NDS::ARM7Read32(addr); + + Cycles += Waitstates[3][(addr>>24)&0xF]; + return val; } - void Write8(u32 addr, u8 val, u32 forceuser=0) + void DataWrite8(u32 addr, u8 val, u32 forceuser=0) { if (!Num) { @@ -125,9 +169,11 @@ public: } else NDS::ARM7Write8(addr, val); + + Cycles += Waitstates[3][(addr>>24)&0xF]; } - void Write16(u32 addr, u16 val, u32 forceuser=0) + void DataWrite16(u32 addr, u16 val, u32 forceuser=0) { addr &= ~1; if (!Num) @@ -137,9 +183,11 @@ public: } else NDS::ARM7Write16(addr, val); + + Cycles += Waitstates[2][(addr>>24)&0xF]; } - void Write32(u32 addr, u32 val, u32 forceuser=0) + void DataWrite32(u32 addr, u32 val, u32 forceuser=0) { addr &= ~3; if (!Num) @@ -149,23 +197,18 @@ public: } else NDS::ARM7Write32(addr, val); - } - - s32 MemWaitstate(u32 type, u32 addr) - { - // type: - // 0 = code16 - // 1 = code32 - // 2 = data16 - // 3 = data32 - - return 1; // sorry + Cycles += Waitstates[3][(addr>>24)&0xF]; } u32 Num; + // waitstates: + // 0=code16 1=code32 2=data16 3=data32 + // TODO eventually: nonsequential waitstates + s32 Waitstates[4][16]; + s32 Cycles; u32 Halted; @@ -177,7 +220,7 @@ public: u32 R_IRQ[3]; u32 R_UND[3]; u32 CurInstr; - u32 NextInstr; + u32 NextInstr[2]; u32 ExceptionBase; diff --git a/ARMInterpreter.cpp b/ARMInterpreter.cpp index 6bed690..32b3a00 100644 --- a/ARMInterpreter.cpp +++ b/ARMInterpreter.cpp @@ -29,24 +29,22 @@ namespace ARMInterpreter { -s32 A_UNK(ARM* cpu) +void A_UNK(ARM* cpu) { printf("undefined ARM%d instruction %08X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-8); for (int i = 0; i < 16; i++) printf("R%d: %08X\n", i, cpu->R[i]); NDS::Halt(); - return 0x7FFFFFFF; } -s32 T_UNK(ARM* cpu) +void T_UNK(ARM* cpu) { printf("undefined THUMB%d instruction %04X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-4); NDS::Halt(); - return 0x7FFFFFFF; } -s32 A_MSR_IMM(ARM* cpu) +void A_MSR_IMM(ARM* cpu) { u32* psr; if (cpu->CurInstr & (1<<22)) @@ -58,7 +56,7 @@ s32 A_MSR_IMM(ARM* cpu) case 0x13: psr = &cpu->R_SVC[2]; break; case 0x17: psr = &cpu->R_ABT[2]; break; case 0x1B: psr = &cpu->R_UND[2]; break; - default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1; + default: printf("bad CPU mode %08X\n", cpu->CPSR); return; } } else @@ -84,11 +82,9 @@ s32 A_MSR_IMM(ARM* cpu) if (!(cpu->CurInstr & (1<<22))) cpu->UpdateMode(oldpsr, cpu->CPSR); - - return C_S(1); } -s32 A_MSR_REG(ARM* cpu) +void A_MSR_REG(ARM* cpu) { u32* psr; if (cpu->CurInstr & (1<<22)) @@ -100,7 +96,7 @@ s32 A_MSR_REG(ARM* cpu) case 0x13: psr = &cpu->R_SVC[2]; break; case 0x17: psr = &cpu->R_ABT[2]; break; case 0x1B: psr = &cpu->R_UND[2]; break; - default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1; + default: printf("bad CPU mode %08X\n", cpu->CPSR); return; } } else @@ -126,11 +122,9 @@ s32 A_MSR_REG(ARM* cpu) if (!(cpu->CurInstr & (1<<22))) cpu->UpdateMode(oldpsr, cpu->CPSR); - - return C_S(1); } -s32 A_MRS(ARM* cpu) +void A_MRS(ARM* cpu) { u32 psr; if (cpu->CurInstr & (1<<22)) @@ -142,19 +136,17 @@ s32 A_MRS(ARM* cpu) case 0x13: psr = cpu->R_SVC[2]; break; case 0x17: psr = cpu->R_ABT[2]; break; case 0x1B: psr = cpu->R_UND[2]; break; - default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1; + default: printf("bad CPU mode %08X\n", cpu->CPSR); return; } } else psr = cpu->CPSR; cpu->R[(cpu->CurInstr>>12) & 0xF] = psr; - - return C_S(1); } -s32 A_MCR(ARM* cpu) +void A_MCR(ARM* cpu) { u32 cp = (cpu->CurInstr >> 8) & 0xF; //u32 op = (cpu->CurInstr >> 21) & 0x7; @@ -171,10 +163,10 @@ s32 A_MCR(ARM* cpu) printf("bad MCR opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9); } - return C_S(1) + 1; // TODO: checkme + cpu->Cycles += 2; // TODO: checkme } -s32 A_MRC(ARM* cpu) +void A_MRC(ARM* cpu) { u32 cp = (cpu->CurInstr >> 8) & 0xF; //u32 op = (cpu->CurInstr >> 21) & 0x7; @@ -191,12 +183,12 @@ s32 A_MRC(ARM* cpu) printf("bad MRC opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9); } - return C_S(1) + 1 + C_I(1); // TODO: checkme + cpu->Cycles += 3; // TODO: checkme } -s32 A_SVC(ARM* cpu) +void A_SVC(ARM* cpu) { u32 oldcpsr = cpu->CPSR; cpu->CPSR &= ~0xFF; @@ -206,11 +198,9 @@ s32 A_SVC(ARM* cpu) cpu->R_SVC[2] = oldcpsr; cpu->R[14] = cpu->R[15] - 4; cpu->JumpTo(cpu->ExceptionBase + 0x08); - - return C_S(2) + C_N(1); } -s32 T_SVC(ARM* cpu) +void T_SVC(ARM* cpu) { u32 oldcpsr = cpu->CPSR; cpu->CPSR &= ~0xFF; @@ -220,13 +210,11 @@ s32 T_SVC(ARM* cpu) cpu->R_SVC[2] = oldcpsr; cpu->R[14] = cpu->R[15] - 2; cpu->JumpTo(cpu->ExceptionBase + 0x08); - - return C_S(2) + C_N(1); } -#define INSTRFUNC_PROTO(x) s32 (*x)(ARM* cpu) +#define INSTRFUNC_PROTO(x) void (*x)(ARM* cpu) #include "ARM_InstrTable.h" #undef INSTRFUNC_PROTO diff --git a/ARMInterpreter.h b/ARMInterpreter.h index e6fed79..2d4c1a8 100644 --- a/ARMInterpreter.h +++ b/ARMInterpreter.h @@ -25,10 +25,10 @@ namespace ARMInterpreter { -extern s32 (*ARMInstrTable[4096])(ARM* cpu); -extern s32 (*THUMBInstrTable[1024])(ARM* cpu); +extern void (*ARMInstrTable[4096])(ARM* cpu); +extern void (*THUMBInstrTable[1024])(ARM* cpu); -s32 A_BLX_IMM(ARM* cpu); // I'm a special one look at me +void A_BLX_IMM(ARM* cpu); // I'm a special one look at me } diff --git a/ARMInterpreter_ALU.cpp b/ARMInterpreter_ALU.cpp index 702c1c8..8e897b6 100644 --- a/ARMInterpreter_ALU.cpp +++ b/ARMInterpreter_ALU.cpp @@ -139,92 +139,92 @@ namespace ARMInterpreter #define A_IMPLEMENT_ALU_OP(x,s) \ \ -s32 A_##x##_IMM(ARM* cpu) \ +void A_##x##_IMM(ARM* cpu) \ { \ A_CALC_OP2_IMM \ A_##x(0) \ } \ -s32 A_##x##_REG_LSL_IMM(ARM* cpu) \ +void A_##x##_REG_LSL_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSL_IMM) \ A_##x(0) \ } \ -s32 A_##x##_REG_LSR_IMM(ARM* cpu) \ +void A_##x##_REG_LSR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSR_IMM) \ A_##x(0) \ } \ -s32 A_##x##_REG_ASR_IMM(ARM* cpu) \ +void A_##x##_REG_ASR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ASR_IMM) \ A_##x(0) \ } \ -s32 A_##x##_REG_ROR_IMM(ARM* cpu) \ +void A_##x##_REG_ROR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ROR_IMM) \ A_##x(0) \ } \ -s32 A_##x##_REG_LSL_REG(ARM* cpu) \ +void A_##x##_REG_LSL_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSL_REG) \ A_##x(1) \ } \ -s32 A_##x##_REG_LSR_REG(ARM* cpu) \ +void A_##x##_REG_LSR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSR_REG) \ A_##x(1) \ } \ -s32 A_##x##_REG_ASR_REG(ARM* cpu) \ +void A_##x##_REG_ASR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ASR_REG) \ A_##x(1) \ } \ -s32 A_##x##_REG_ROR_REG(ARM* cpu) \ +void A_##x##_REG_ROR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ROR_REG) \ A_##x(1) \ } \ -s32 A_##x##_IMM_S(ARM* cpu) \ +void A_##x##_IMM_S(ARM* cpu) \ { \ A_CALC_OP2_IMM \ A_##x##_S(0) \ } \ -s32 A_##x##_REG_LSL_IMM_S(ARM* cpu) \ +void A_##x##_REG_LSL_IMM_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSL_IMM##s) \ A_##x##_S(0) \ } \ -s32 A_##x##_REG_LSR_IMM_S(ARM* cpu) \ +void A_##x##_REG_LSR_IMM_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSR_IMM##s) \ A_##x##_S(0) \ } \ -s32 A_##x##_REG_ASR_IMM_S(ARM* cpu) \ +void A_##x##_REG_ASR_IMM_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ASR_IMM##s) \ A_##x##_S(0) \ } \ -s32 A_##x##_REG_ROR_IMM_S(ARM* cpu) \ +void A_##x##_REG_ROR_IMM_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ROR_IMM##s) \ A_##x##_S(0) \ } \ -s32 A_##x##_REG_LSL_REG_S(ARM* cpu) \ +void A_##x##_REG_LSL_REG_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSL_REG##s) \ A_##x##_S(1) \ } \ -s32 A_##x##_REG_LSR_REG_S(ARM* cpu) \ +void A_##x##_REG_LSR_REG_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSR_REG##s) \ A_##x##_S(1) \ } \ -s32 A_##x##_REG_ASR_REG_S(ARM* cpu) \ +void A_##x##_REG_ASR_REG_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ASR_REG##s) \ A_##x##_S(1) \ } \ -s32 A_##x##_REG_ROR_REG_S(ARM* cpu) \ +void A_##x##_REG_ROR_REG_S(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ROR_REG##s) \ A_##x##_S(1) \ @@ -232,47 +232,47 @@ s32 A_##x##_REG_ROR_REG_S(ARM* cpu) \ #define A_IMPLEMENT_ALU_TEST(x,s) \ \ -s32 A_##x##_IMM(ARM* cpu) \ +void A_##x##_IMM(ARM* cpu) \ { \ A_CALC_OP2_IMM \ A_##x(0) \ } \ -s32 A_##x##_REG_LSL_IMM(ARM* cpu) \ +void A_##x##_REG_LSL_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSL_IMM##s) \ A_##x(0) \ } \ -s32 A_##x##_REG_LSR_IMM(ARM* cpu) \ +void A_##x##_REG_LSR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(LSR_IMM##s) \ A_##x(0) \ } \ -s32 A_##x##_REG_ASR_IMM(ARM* cpu) \ +void A_##x##_REG_ASR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ASR_IMM##s) \ A_##x(0) \ } \ -s32 A_##x##_REG_ROR_IMM(ARM* cpu) \ +void A_##x##_REG_ROR_IMM(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_IMM(ROR_IMM##s) \ A_##x(0) \ } \ -s32 A_##x##_REG_LSL_REG(ARM* cpu) \ +void A_##x##_REG_LSL_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSL_REG##s) \ A_##x(1) \ } \ -s32 A_##x##_REG_LSR_REG(ARM* cpu) \ +void A_##x##_REG_LSR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(LSR_REG##s) \ A_##x(1) \ } \ -s32 A_##x##_REG_ASR_REG(ARM* cpu) \ +void A_##x##_REG_ASR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ASR_REG##s) \ A_##x(1) \ } \ -s32 A_##x##_REG_ROR_REG(ARM* cpu) \ +void A_##x##_REG_ROR_REG(ARM* cpu) \ { \ A_CALC_OP2_REG_SHIFT_REG(ROR_REG##s) \ A_##x(1) \ @@ -282,15 +282,14 @@ s32 A_##x##_REG_ROR_REG(ARM* cpu) \ #define A_AND(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a & b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_AND_S(c) \ @@ -298,15 +297,14 @@ s32 A_##x##_REG_ROR_REG(ARM* cpu) \ u32 res = a & b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(AND,_S) @@ -315,15 +313,14 @@ A_IMPLEMENT_ALU_OP(AND,_S) #define A_EOR(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a ^ b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_EOR_S(c) \ @@ -331,15 +328,14 @@ A_IMPLEMENT_ALU_OP(AND,_S) u32 res = a ^ b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(EOR,_S) @@ -348,15 +344,14 @@ A_IMPLEMENT_ALU_OP(EOR,_S) #define A_SUB(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a - b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_SUB_S(c) \ @@ -366,15 +361,14 @@ A_IMPLEMENT_ALU_OP(EOR,_S) !res, \ CARRY_SUB(a, b), \ OVERFLOW_SUB(a, b, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(SUB,) @@ -383,15 +377,14 @@ A_IMPLEMENT_ALU_OP(SUB,) #define A_RSB(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = b - a; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_RSB_S(c) \ @@ -401,15 +394,14 @@ A_IMPLEMENT_ALU_OP(SUB,) !res, \ CARRY_SUB(b, a), \ OVERFLOW_SUB(b, a, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(RSB,) @@ -418,15 +410,14 @@ A_IMPLEMENT_ALU_OP(RSB,) #define A_ADD(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a + b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_ADD_S(c) \ @@ -436,15 +427,14 @@ A_IMPLEMENT_ALU_OP(RSB,) !res, \ CARRY_ADD(a, b), \ OVERFLOW_ADD(a, b, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(ADD,) @@ -453,15 +443,14 @@ A_IMPLEMENT_ALU_OP(ADD,) #define A_ADC(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a + b + (cpu->CPSR&0x20000000 ? 1:0); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_ADC_S(c) \ @@ -473,15 +462,14 @@ A_IMPLEMENT_ALU_OP(ADD,) !res, \ CARRY_ADD(a, b) | CARRY_ADD(res_tmp, carry), \ OVERFLOW_ADD(a, b, res_tmp) | OVERFLOW_ADD(res_tmp, carry, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(ADC,) @@ -490,15 +478,14 @@ A_IMPLEMENT_ALU_OP(ADC,) #define A_SBC(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a - b - (cpu->CPSR&0x20000000 ? 0:1); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_SBC_S(c) \ @@ -510,15 +497,14 @@ A_IMPLEMENT_ALU_OP(ADC,) !res, \ CARRY_SUB(a, b) & CARRY_SUB(res_tmp, carry), \ OVERFLOW_SUB(a, b, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(SBC,) @@ -527,15 +513,14 @@ A_IMPLEMENT_ALU_OP(SBC,) #define A_RSC(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = b - a - (cpu->CPSR&0x20000000 ? 0:1); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_RSC_S(c) \ @@ -547,15 +532,14 @@ A_IMPLEMENT_ALU_OP(SBC,) !res, \ CARRY_SUB(b, a) & CARRY_SUB(res_tmp, carry), \ OVERFLOW_SUB(b, a, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res)); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(RSC,) @@ -566,7 +550,7 @@ A_IMPLEMENT_ALU_OP(RSC,) u32 res = a & b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ - return C_S(1) + C_I(c); + cpu->Cycles += c; A_IMPLEMENT_ALU_TEST(TST,_S) @@ -576,7 +560,7 @@ A_IMPLEMENT_ALU_TEST(TST,_S) u32 res = a ^ b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ - return C_S(1) + C_I(c); + cpu->Cycles += c; A_IMPLEMENT_ALU_TEST(TEQ,_S) @@ -588,7 +572,7 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S) !res, \ CARRY_SUB(a, b), \ OVERFLOW_SUB(a, b, res)); \ - return C_S(1) + C_I(c); + cpu->Cycles += c; A_IMPLEMENT_ALU_TEST(CMP,) @@ -600,7 +584,7 @@ A_IMPLEMENT_ALU_TEST(CMP,) !res, \ CARRY_ADD(a, b), \ OVERFLOW_ADD(a, b, res)); \ - return C_S(1) + C_I(c); + cpu->Cycles += c; A_IMPLEMENT_ALU_TEST(CMN,) @@ -608,15 +592,14 @@ A_IMPLEMENT_ALU_TEST(CMN,) #define A_ORR(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a | b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_ORR_S(c) \ @@ -624,44 +607,41 @@ A_IMPLEMENT_ALU_TEST(CMN,) u32 res = a | b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(ORR,_S) #define A_MOV(c) \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(b); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = b; \ - return C_S(1) + C_I(c); \ } #define A_MOV_S(c) \ cpu->SetNZ(b & 0x80000000, \ !b); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(b, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = b; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(MOV,_S) @@ -670,15 +650,14 @@ A_IMPLEMENT_ALU_OP(MOV,_S) #define A_BIC(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a & ~b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } #define A_BIC_S(c) \ @@ -686,15 +665,14 @@ A_IMPLEMENT_ALU_OP(MOV,_S) u32 res = a & ~b; \ cpu->SetNZ(res & 0x80000000, \ !res); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(res, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = res; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(BIC,_S) @@ -702,37 +680,35 @@ A_IMPLEMENT_ALU_OP(BIC,_S) #define A_MVN(c) \ b = ~b; \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(b); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = b; \ - return C_S(1) + C_I(c); \ } #define A_MVN_S(c) \ b = ~b; \ cpu->SetNZ(b & 0x80000000, \ !b); \ + cpu->Cycles += c; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ cpu->JumpTo(b, true); \ - return C_S(2) + C_I(c) + C_N(1); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = b; \ - return C_S(1) + C_I(c); \ } A_IMPLEMENT_ALU_OP(MVN,_S) -s32 A_MUL(ARM* cpu) +void A_MUL(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -753,10 +729,10 @@ s32 A_MUL(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 3; else cycles = 4; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_MLA(ARM* cpu) +void A_MLA(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -778,10 +754,10 @@ s32 A_MLA(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4; else cycles = 5; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_UMULL(ARM* cpu) +void A_UMULL(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -803,10 +779,10 @@ s32 A_UMULL(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000) cycles = 4; else cycles = 5; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_UMLAL(ARM* cpu) +void A_UMLAL(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -831,10 +807,10 @@ s32 A_UMLAL(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000) cycles = 4; else cycles = 5; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_SMULL(ARM* cpu) +void A_SMULL(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -856,10 +832,10 @@ s32 A_SMULL(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4; else cycles = 5; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_SMLAL(ARM* cpu) +void A_SMLAL(ARM* cpu) { u32 rm = cpu->R[cpu->CurInstr & 0xF]; u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF]; @@ -884,12 +860,12 @@ s32 A_SMLAL(ARM* cpu) else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4; else cycles = 5; - return C_S(1) + C_I(cycles); + cpu->Cycles += cycles; } -s32 A_CLZ(ARM* cpu) +void A_CLZ(ARM* cpu) { // TODO: ARM9 only @@ -910,8 +886,6 @@ s32 A_CLZ(ARM* cpu) } cpu->R[(cpu->CurInstr >> 12) & 0xF] = res; - - return C_S(1); } @@ -920,7 +894,7 @@ s32 A_CLZ(ARM* cpu) -s32 T_LSL_IMM(ARM* cpu) +void T_LSL_IMM(ARM* cpu) { u32 op = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 s = (cpu->CurInstr >> 6) & 0x1F; @@ -928,10 +902,9 @@ s32 T_LSL_IMM(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = op; cpu->SetNZ(op & 0x80000000, !op); - return C_S(1); } -s32 T_LSR_IMM(ARM* cpu) +void T_LSR_IMM(ARM* cpu) { u32 op = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 s = (cpu->CurInstr >> 6) & 0x1F; @@ -939,10 +912,9 @@ s32 T_LSR_IMM(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = op; cpu->SetNZ(op & 0x80000000, !op); - return C_S(1); } -s32 T_ASR_IMM(ARM* cpu) +void T_ASR_IMM(ARM* cpu) { u32 op = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 s = (cpu->CurInstr >> 6) & 0x1F; @@ -950,10 +922,9 @@ s32 T_ASR_IMM(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = op; cpu->SetNZ(op & 0x80000000, !op); - return C_S(1); } -s32 T_ADD_REG_(ARM* cpu) +void T_ADD_REG_(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 6) & 0x7]; @@ -963,10 +934,9 @@ s32 T_ADD_REG_(ARM* cpu) !res, CARRY_ADD(a, b), OVERFLOW_ADD(a, b, res)); - return C_S(1); } -s32 T_SUB_REG_(ARM* cpu) +void T_SUB_REG_(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 6) & 0x7]; @@ -976,10 +946,9 @@ s32 T_SUB_REG_(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_ADD_IMM_(ARM* cpu) +void T_ADD_IMM_(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 b = (cpu->CurInstr >> 6) & 0x7; @@ -989,10 +958,9 @@ s32 T_ADD_IMM_(ARM* cpu) !res, CARRY_ADD(a, b), OVERFLOW_ADD(a, b, res)); - return C_S(1); } -s32 T_SUB_IMM_(ARM* cpu) +void T_SUB_IMM_(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 b = (cpu->CurInstr >> 6) & 0x7; @@ -1002,19 +970,17 @@ s32 T_SUB_IMM_(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_MOV_IMM(ARM* cpu) +void T_MOV_IMM(ARM* cpu) { u32 b = cpu->CurInstr & 0xFF; cpu->R[(cpu->CurInstr >> 8) & 0x7] = b; cpu->SetNZ(0, !b); - return C_S(1); } -s32 T_CMP_IMM(ARM* cpu) +void T_CMP_IMM(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 8) & 0x7]; u32 b = cpu->CurInstr & 0xFF; @@ -1023,10 +989,9 @@ s32 T_CMP_IMM(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_ADD_IMM(ARM* cpu) +void T_ADD_IMM(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 8) & 0x7]; u32 b = cpu->CurInstr & 0xFF; @@ -1036,10 +1001,9 @@ s32 T_ADD_IMM(ARM* cpu) !res, CARRY_ADD(a, b), OVERFLOW_ADD(a, b, res)); - return C_S(1); } -s32 T_SUB_IMM(ARM* cpu) +void T_SUB_IMM(ARM* cpu) { u32 a = cpu->R[(cpu->CurInstr >> 8) & 0x7]; u32 b = cpu->CurInstr & 0xFF; @@ -1049,11 +1013,10 @@ s32 T_SUB_IMM(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_AND_REG(ARM* cpu) +void T_AND_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1061,10 +1024,9 @@ s32 T_AND_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_EOR_REG(ARM* cpu) +void T_EOR_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1072,10 +1034,9 @@ s32 T_EOR_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_LSL_REG(ARM* cpu) +void T_LSL_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7] & 0xFF; @@ -1083,10 +1044,10 @@ s32 T_LSL_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = a; cpu->SetNZ(a & 0x80000000, !a); - return C_S(1) + C_I(1); + cpu->Cycles += 1; } -s32 T_LSR_REG(ARM* cpu) +void T_LSR_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7] & 0xFF; @@ -1094,10 +1055,10 @@ s32 T_LSR_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = a; cpu->SetNZ(a & 0x80000000, !a); - return C_S(1) + C_I(1); + cpu->Cycles += 1; } -s32 T_ASR_REG(ARM* cpu) +void T_ASR_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7] & 0xFF; @@ -1105,10 +1066,10 @@ s32 T_ASR_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = a; cpu->SetNZ(a & 0x80000000, !a); - return C_S(1) + C_I(1); + cpu->Cycles += 1; } -s32 T_ADC_REG(ARM* cpu) +void T_ADC_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1120,10 +1081,9 @@ s32 T_ADC_REG(ARM* cpu) !res, CARRY_ADD(a, b) | CARRY_ADD(res_tmp, carry), OVERFLOW_ADD(a, b, res_tmp) | OVERFLOW_ADD(res_tmp, carry, res)); - return C_S(1); } -s32 T_SBC_REG(ARM* cpu) +void T_SBC_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1135,10 +1095,9 @@ s32 T_SBC_REG(ARM* cpu) !res, CARRY_SUB(a, b) & CARRY_SUB(res_tmp, carry), OVERFLOW_SUB(a, b, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res)); - return C_S(1); } -s32 T_ROR_REG(ARM* cpu) +void T_ROR_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7] & 0xFF; @@ -1146,30 +1105,28 @@ s32 T_ROR_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = a; cpu->SetNZ(a & 0x80000000, !a); - return C_S(1) + C_I(1); + cpu->Cycles += 1; } -s32 T_TST_REG(ARM* cpu) +void T_TST_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 res = a & b; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_NEG_REG(ARM* cpu) +void T_NEG_REG(ARM* cpu) { u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 res = -b; cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_CMP_REG(ARM* cpu) +void T_CMP_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1178,10 +1135,9 @@ s32 T_CMP_REG(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_CMN_REG(ARM* cpu) +void T_CMN_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1190,10 +1146,9 @@ s32 T_CMN_REG(ARM* cpu) !res, CARRY_ADD(a, b), OVERFLOW_ADD(a, b, res)); - return C_S(1); } -s32 T_ORR_REG(ARM* cpu) +void T_ORR_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1201,10 +1156,9 @@ s32 T_ORR_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_MUL_REG(ARM* cpu) +void T_MUL_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1213,23 +1167,23 @@ s32 T_MUL_REG(ARM* cpu) cpu->SetNZ(res & 0x80000000, !res); - s32 cycles = C_S(1); + s32 cycles = 0; if (cpu->Num == 0) { - cycles += C_I(3); + cycles += 3; } else { cpu->SetC(0); // carry flag destroyed, they say. whatever that means... - if (a & 0xFF000000) cycles += C_I(4); - else if (a & 0x00FF0000) cycles += C_I(3); - else if (a & 0x0000FF00) cycles += C_I(2); - else cycles += C_I(1); + if (a & 0xFF000000) cycles += 4; + else if (a & 0x00FF0000) cycles += 3; + else if (a & 0x0000FF00) cycles += 2; + else cycles += 1; } - return cycles; + cpu->Cycles += cycles; } -s32 T_BIC_REG(ARM* cpu) +void T_BIC_REG(ARM* cpu) { u32 a = cpu->R[cpu->CurInstr & 0x7]; u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; @@ -1237,21 +1191,19 @@ s32 T_BIC_REG(ARM* cpu) cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_MVN_REG(ARM* cpu) +void T_MVN_REG(ARM* cpu) { u32 b = cpu->R[(cpu->CurInstr >> 3) & 0x7]; u32 res = ~b; cpu->R[cpu->CurInstr & 0x7] = res; cpu->SetNZ(res & 0x80000000, !res); - return C_S(1); } -s32 T_ADD_HIREG(ARM* cpu) +void T_ADD_HIREG(ARM* cpu) { u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); u32 rs = (cpu->CurInstr >> 3) & 0xF; @@ -1262,16 +1214,14 @@ s32 T_ADD_HIREG(ARM* cpu) if (rd == 15) { cpu->JumpTo((a + b) | 1); - return C_S(2) + C_N(1); } else { cpu->R[rd] = a + b; - return C_S(1); } } -s32 T_CMP_HIREG(ARM* cpu) +void T_CMP_HIREG(ARM* cpu) { u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); u32 rs = (cpu->CurInstr >> 3) & 0xF; @@ -1284,10 +1234,9 @@ s32 T_CMP_HIREG(ARM* cpu) !res, CARRY_SUB(a, b), OVERFLOW_SUB(a, b, res)); - return C_S(1); } -s32 T_MOV_HIREG(ARM* cpu) +void T_MOV_HIREG(ARM* cpu) { u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); u32 rs = (cpu->CurInstr >> 3) & 0xF; @@ -1295,33 +1244,29 @@ s32 T_MOV_HIREG(ARM* cpu) if (rd == 15) { cpu->JumpTo(cpu->R[rs] | 1); - return C_S(2) + C_N(1); } else { cpu->R[rd] = cpu->R[rs]; - return C_S(1); } } -s32 T_ADD_PCREL(ARM* cpu) +void T_ADD_PCREL(ARM* cpu) { u32 val = cpu->R[15] & ~2; val += ((cpu->CurInstr & 0xFF) << 2); cpu->R[(cpu->CurInstr >> 8) & 0x7] = val; - return C_S(1); } -s32 T_ADD_SPREL(ARM* cpu) +void T_ADD_SPREL(ARM* cpu) { u32 val = cpu->R[13]; val += ((cpu->CurInstr & 0xFF) << 2); cpu->R[(cpu->CurInstr >> 8) & 0x7] = val; - return C_S(1); } -s32 T_ADD_SP(ARM* cpu) +void T_ADD_SP(ARM* cpu) { u32 val = cpu->R[13]; if (cpu->CurInstr & (1<<7)) @@ -1329,7 +1274,6 @@ s32 T_ADD_SP(ARM* cpu) else val += ((cpu->CurInstr & 0x7F) << 2); cpu->R[13] = val; - return C_S(1); } diff --git a/ARMInterpreter_ALU.h b/ARMInterpreter_ALU.h index 224de04..15b9948 100644 --- a/ARMInterpreter_ALU.h +++ b/ARMInterpreter_ALU.h @@ -24,36 +24,36 @@ namespace ARMInterpreter #define A_PROTO_ALU_OP(x) \ \ -s32 A_##x##_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSL_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSR_IMM(ARM* cpu); \ -s32 A_##x##_REG_ASR_IMM(ARM* cpu); \ -s32 A_##x##_REG_ROR_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSL_REG(ARM* cpu); \ -s32 A_##x##_REG_LSR_REG(ARM* cpu); \ -s32 A_##x##_REG_ASR_REG(ARM* cpu); \ -s32 A_##x##_REG_ROR_REG(ARM* cpu); \ -s32 A_##x##_IMM_S(ARM* cpu); \ -s32 A_##x##_REG_LSL_IMM_S(ARM* cpu); \ -s32 A_##x##_REG_LSR_IMM_S(ARM* cpu); \ -s32 A_##x##_REG_ASR_IMM_S(ARM* cpu); \ -s32 A_##x##_REG_ROR_IMM_S(ARM* cpu); \ -s32 A_##x##_REG_LSL_REG_S(ARM* cpu); \ -s32 A_##x##_REG_LSR_REG_S(ARM* cpu); \ -s32 A_##x##_REG_ASR_REG_S(ARM* cpu); \ -s32 A_##x##_REG_ROR_REG_S(ARM* cpu); +void A_##x##_IMM(ARM* cpu); \ +void A_##x##_REG_LSL_IMM(ARM* cpu); \ +void A_##x##_REG_LSR_IMM(ARM* cpu); \ +void A_##x##_REG_ASR_IMM(ARM* cpu); \ +void A_##x##_REG_ROR_IMM(ARM* cpu); \ +void A_##x##_REG_LSL_REG(ARM* cpu); \ +void A_##x##_REG_LSR_REG(ARM* cpu); \ +void A_##x##_REG_ASR_REG(ARM* cpu); \ +void A_##x##_REG_ROR_REG(ARM* cpu); \ +void A_##x##_IMM_S(ARM* cpu); \ +void A_##x##_REG_LSL_IMM_S(ARM* cpu); \ +void A_##x##_REG_LSR_IMM_S(ARM* cpu); \ +void A_##x##_REG_ASR_IMM_S(ARM* cpu); \ +void A_##x##_REG_ROR_IMM_S(ARM* cpu); \ +void A_##x##_REG_LSL_REG_S(ARM* cpu); \ +void A_##x##_REG_LSR_REG_S(ARM* cpu); \ +void A_##x##_REG_ASR_REG_S(ARM* cpu); \ +void A_##x##_REG_ROR_REG_S(ARM* cpu); #define A_PROTO_ALU_TEST(x) \ \ -s32 A_##x##_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSL_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSR_IMM(ARM* cpu); \ -s32 A_##x##_REG_ASR_IMM(ARM* cpu); \ -s32 A_##x##_REG_ROR_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSL_REG(ARM* cpu); \ -s32 A_##x##_REG_LSR_REG(ARM* cpu); \ -s32 A_##x##_REG_ASR_REG(ARM* cpu); \ -s32 A_##x##_REG_ROR_REG(ARM* cpu); +void A_##x##_IMM(ARM* cpu); \ +void A_##x##_REG_LSL_IMM(ARM* cpu); \ +void A_##x##_REG_LSR_IMM(ARM* cpu); \ +void A_##x##_REG_ASR_IMM(ARM* cpu); \ +void A_##x##_REG_ROR_IMM(ARM* cpu); \ +void A_##x##_REG_LSL_REG(ARM* cpu); \ +void A_##x##_REG_LSR_REG(ARM* cpu); \ +void A_##x##_REG_ASR_REG(ARM* cpu); \ +void A_##x##_REG_ROR_REG(ARM* cpu); A_PROTO_ALU_OP(AND) A_PROTO_ALU_OP(EOR) @@ -72,54 +72,54 @@ A_PROTO_ALU_OP(MOV) A_PROTO_ALU_OP(BIC) A_PROTO_ALU_OP(MVN) -s32 A_MUL(ARM* cpu); -s32 A_MLA(ARM* cpu); -s32 A_UMULL(ARM* cpu); -s32 A_UMLAL(ARM* cpu); -s32 A_SMULL(ARM* cpu); -s32 A_SMLAL(ARM* cpu); - -s32 A_CLZ(ARM* cpu); - - -s32 T_LSL_IMM(ARM* cpu); -s32 T_LSR_IMM(ARM* cpu); -s32 T_ASR_IMM(ARM* cpu); - -s32 T_ADD_REG_(ARM* cpu); -s32 T_SUB_REG_(ARM* cpu); -s32 T_ADD_IMM_(ARM* cpu); -s32 T_SUB_IMM_(ARM* cpu); - -s32 T_MOV_IMM(ARM* cpu); -s32 T_CMP_IMM(ARM* cpu); -s32 T_ADD_IMM(ARM* cpu); -s32 T_SUB_IMM(ARM* cpu); - -s32 T_AND_REG(ARM* cpu); -s32 T_EOR_REG(ARM* cpu); -s32 T_LSL_REG(ARM* cpu); -s32 T_LSR_REG(ARM* cpu); -s32 T_ASR_REG(ARM* cpu); -s32 T_ADC_REG(ARM* cpu); -s32 T_SBC_REG(ARM* cpu); -s32 T_ROR_REG(ARM* cpu); -s32 T_TST_REG(ARM* cpu); -s32 T_NEG_REG(ARM* cpu); -s32 T_CMP_REG(ARM* cpu); -s32 T_CMN_REG(ARM* cpu); -s32 T_ORR_REG(ARM* cpu); -s32 T_MUL_REG(ARM* cpu); -s32 T_BIC_REG(ARM* cpu); -s32 T_MVN_REG(ARM* cpu); - -s32 T_ADD_HIREG(ARM* cpu); -s32 T_CMP_HIREG(ARM* cpu); -s32 T_MOV_HIREG(ARM* cpu); - -s32 T_ADD_PCREL(ARM* cpu); -s32 T_ADD_SPREL(ARM* cpu); -s32 T_ADD_SP(ARM* cpu); +void A_MUL(ARM* cpu); +void A_MLA(ARM* cpu); +void A_UMULL(ARM* cpu); +void A_UMLAL(ARM* cpu); +void A_SMULL(ARM* cpu); +void A_SMLAL(ARM* cpu); + +void A_CLZ(ARM* cpu); + + +void T_LSL_IMM(ARM* cpu); +void T_LSR_IMM(ARM* cpu); +void T_ASR_IMM(ARM* cpu); + +void T_ADD_REG_(ARM* cpu); +void T_SUB_REG_(ARM* cpu); +void T_ADD_IMM_(ARM* cpu); +void T_SUB_IMM_(ARM* cpu); + +void T_MOV_IMM(ARM* cpu); +void T_CMP_IMM(ARM* cpu); +void T_ADD_IMM(ARM* cpu); +void T_SUB_IMM(ARM* cpu); + +void T_AND_REG(ARM* cpu); +void T_EOR_REG(ARM* cpu); +void T_LSL_REG(ARM* cpu); +void T_LSR_REG(ARM* cpu); +void T_ASR_REG(ARM* cpu); +void T_ADC_REG(ARM* cpu); +void T_SBC_REG(ARM* cpu); +void T_ROR_REG(ARM* cpu); +void T_TST_REG(ARM* cpu); +void T_NEG_REG(ARM* cpu); +void T_CMP_REG(ARM* cpu); +void T_CMN_REG(ARM* cpu); +void T_ORR_REG(ARM* cpu); +void T_MUL_REG(ARM* cpu); +void T_BIC_REG(ARM* cpu); +void T_MVN_REG(ARM* cpu); + +void T_ADD_HIREG(ARM* cpu); +void T_CMP_HIREG(ARM* cpu); +void T_MOV_HIREG(ARM* cpu); + +void T_ADD_PCREL(ARM* cpu); +void T_ADD_SPREL(ARM* cpu); +void T_ADD_SP(ARM* cpu); } diff --git a/ARMInterpreter_Branch.cpp b/ARMInterpreter_Branch.cpp index efaddd3..88f316d 100644 --- a/ARMInterpreter_Branch.cpp +++ b/ARMInterpreter_Branch.cpp @@ -24,102 +24,81 @@ namespace ARMInterpreter { -s32 A_B(ARM* cpu) +void A_B(ARM* cpu) { s32 offset = (s32)(cpu->CurInstr << 8) >> 6; cpu->JumpTo(cpu->R[15] + offset); - - return C_S(2) + C_N(1); } -s32 A_BL(ARM* cpu) +void A_BL(ARM* cpu) { s32 offset = (s32)(cpu->CurInstr << 8) >> 6; cpu->R[14] = cpu->R[15] - 4; cpu->JumpTo(cpu->R[15] + offset); - - return C_S(2) + C_N(1); } -s32 A_BLX_IMM(ARM* cpu) +void A_BLX_IMM(ARM* cpu) { s32 offset = (s32)(cpu->CurInstr << 8) >> 6; if (cpu->CurInstr & 0x01000000) offset += 2; cpu->R[14] = cpu->R[15] - 4; cpu->JumpTo(cpu->R[15] + offset + 1); - - return C_S(2) + C_N(1); } -s32 A_BX(ARM* cpu) +void A_BX(ARM* cpu) { cpu->JumpTo(cpu->R[cpu->CurInstr & 0xF]); - - return C_S(2) + C_N(1); } -s32 A_BLX_REG(ARM* cpu) +void A_BLX_REG(ARM* cpu) { u32 lr = cpu->R[15] - 4; cpu->JumpTo(cpu->R[cpu->CurInstr & 0xF]); cpu->R[14] = lr; - - return C_S(2) + C_N(1); } -s32 T_BCOND(ARM* cpu) +void T_BCOND(ARM* cpu) { if (cpu->CheckCondition((cpu->CurInstr >> 8) & 0xF)) { s32 offset = (s32)(cpu->CurInstr << 24) >> 23; cpu->JumpTo(cpu->R[15] + offset + 1); - return C_S(2) + C_N(1); } - else - return C_S(1); } -s32 T_BX(ARM* cpu) +void T_BX(ARM* cpu) { cpu->JumpTo(cpu->R[(cpu->CurInstr >> 3) & 0xF]); - - return C_S(2) + C_N(1); } -s32 T_BLX_REG(ARM* cpu) +void T_BLX_REG(ARM* cpu) { if (cpu->Num==1) { printf("!! THUMB BLX_REG ON ARM7\n"); - return 1; + return; } u32 lr = cpu->R[15] - 1; cpu->JumpTo(cpu->R[(cpu->CurInstr >> 3) & 0xF]); cpu->R[14] = lr; - - return C_S(2) + C_N(1); } -s32 T_B(ARM* cpu) +void T_B(ARM* cpu) { s32 offset = (s32)((cpu->CurInstr & 0x7FF) << 21) >> 20; cpu->JumpTo(cpu->R[15] + offset + 1); - - return C_S(2) + C_N(1); } -s32 T_BL_LONG_1(ARM* cpu) +void T_BL_LONG_1(ARM* cpu) { s32 offset = (s32)((cpu->CurInstr & 0x7FF) << 21) >> 9; cpu->R[14] = cpu->R[15] + offset; - - return C_S(1); } -s32 T_BL_LONG_2(ARM* cpu) +void T_BL_LONG_2(ARM* cpu) { s32 offset = (cpu->CurInstr & 0x7FF) << 1; u32 pc = cpu->R[14] + offset; @@ -129,7 +108,6 @@ s32 T_BL_LONG_2(ARM* cpu) pc |= 1; cpu->JumpTo(pc); - return C_S(2) + C_N(1); } diff --git a/ARMInterpreter_Branch.h b/ARMInterpreter_Branch.h index 6b7989a..202f490 100644 --- a/ARMInterpreter_Branch.h +++ b/ARMInterpreter_Branch.h @@ -22,17 +22,17 @@ namespace ARMInterpreter { -s32 A_B(ARM* cpu); -s32 A_BL(ARM* cpu); -s32 A_BX(ARM* cpu); -s32 A_BLX_REG(ARM* cpu); - -s32 T_BCOND(ARM* cpu); -s32 T_BX(ARM* cpu); -s32 T_BLX_REG(ARM* cpu); -s32 T_B(ARM* cpu); -s32 T_BL_LONG_1(ARM* cpu); -s32 T_BL_LONG_2(ARM* cpu); +void A_B(ARM* cpu); +void A_BL(ARM* cpu); +void A_BX(ARM* cpu); +void A_BLX_REG(ARM* cpu); + +void T_BCOND(ARM* cpu); +void T_BX(ARM* cpu); +void T_BLX_REG(ARM* cpu); +void T_B(ARM* cpu); +void T_BL_LONG_1(ARM* cpu); +void T_BL_LONG_2(ARM* cpu); } diff --git a/ARMInterpreter_LoadStore.cpp b/ARMInterpreter_LoadStore.cpp index bc86dfb..17977dd 100644 --- a/ARMInterpreter_LoadStore.cpp +++ b/ARMInterpreter_LoadStore.cpp @@ -62,135 +62,129 @@ namespace ARMInterpreter #define A_STR \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - cpu->Write32(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ - if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ + if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; #define A_STR_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - cpu->Write32(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \ - cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(3, addr); + cpu->DataWrite32(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \ + cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; #define A_STRB \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - cpu->Write8(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ - if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite8(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ + if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; #define A_STRB_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - cpu->Write8(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \ - cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(3, addr); + cpu->DataWrite8(addr, cpu->R[(cpu->CurInstr>>12) & 0xF], cpu->CurInstr & (1<<21)); \ + cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; #define A_LDR \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - u32 val = ROR(cpu->Read32(offset), ((offset&0x3)<<3)); \ + u32 val = ROR(cpu->DataRead32(offset), ((offset&0x3)<<3)); \ if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ + cpu->Cycles += 1; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ if (cpu->Num==1) val &= ~0x1; \ cpu->JumpTo(val); \ - return C_S(2) + C_N(2) + C_I(1) + cpu->MemWaitstate(3, offset); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); \ } #define A_LDR_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - u32 val = ROR(cpu->Read32(addr, cpu->CurInstr & (1<<21)), ((addr&0x3)<<3)); \ + u32 val = ROR(cpu->DataRead32(addr, cpu->CurInstr & (1<<21)), ((addr&0x3)<<3)); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ + cpu->Cycles += 1; \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ if (cpu->Num==1) val &= ~0x1; \ cpu->JumpTo(val); \ - return C_S(2) + C_N(2) + C_I(1) + cpu->MemWaitstate(3, addr); \ } \ else \ { \ cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); \ } #define A_LDRB \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - u32 val = cpu->Read8(offset); \ + u32 val = cpu->DataRead8(offset); \ if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \ + cpu->Cycles += 1; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); #define A_LDRB_POST \ u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - u32 val = cpu->Read8(addr, cpu->CurInstr & (1<<21)); \ + u32 val = cpu->DataRead8(addr, cpu->CurInstr & (1<<21)); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ + cpu->Cycles += 1; \ cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); #define A_IMPLEMENT_WB_LDRSTR(x) \ \ -s32 A_##x##_IMM(ARM* cpu) \ +void A_##x##_IMM(ARM* cpu) \ { \ A_WB_CALC_OFFSET_IMM \ A_##x \ } \ \ -s32 A_##x##_REG_LSL(ARM* cpu) \ +void A_##x##_REG_LSL(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(LSL_IMM) \ A_##x \ } \ \ -s32 A_##x##_REG_LSR(ARM* cpu) \ +void A_##x##_REG_LSR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(LSR_IMM) \ A_##x \ } \ \ -s32 A_##x##_REG_ASR(ARM* cpu) \ +void A_##x##_REG_ASR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(ASR_IMM) \ A_##x \ } \ \ -s32 A_##x##_REG_ROR(ARM* cpu) \ +void A_##x##_REG_ROR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(ROR_IMM) \ A_##x \ } \ \ -s32 A_##x##_POST_IMM(ARM* cpu) \ +void A_##x##_POST_IMM(ARM* cpu) \ { \ A_WB_CALC_OFFSET_IMM \ A_##x##_POST \ } \ \ -s32 A_##x##_POST_REG_LSL(ARM* cpu) \ +void A_##x##_POST_REG_LSL(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(LSL_IMM) \ A_##x##_POST \ } \ \ -s32 A_##x##_POST_REG_LSR(ARM* cpu) \ +void A_##x##_POST_REG_LSR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(LSR_IMM) \ A_##x##_POST \ } \ \ -s32 A_##x##_POST_REG_ASR(ARM* cpu) \ +void A_##x##_POST_REG_ASR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(ASR_IMM) \ A_##x##_POST \ } \ \ -s32 A_##x##_POST_REG_ROR(ARM* cpu) \ +void A_##x##_POST_REG_ROR(ARM* cpu) \ { \ A_WB_CALC_OFFSET_REG(ROR_IMM) \ A_##x##_POST \ @@ -215,113 +209,102 @@ A_IMPLEMENT_WB_LDRSTR(LDRB) #define A_STRH \ offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \ - cpu->Write16(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ + cpu->DataWrite16(offset, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = 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->DataWrite16(addr, cpu->R[(cpu->CurInstr>>12) & 0xF]); \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ - return C_N(2) + cpu->MemWaitstate(2, addr); // TODO: CHECK LDRD/STRD TIMINGS!! also, ARM9-only #define A_LDRD \ 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->Read32(offset ); \ - cpu->R[r+1] = cpu->Read32(offset+4); \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); + cpu->R[r ] = cpu->DataRead32(offset ); \ + cpu->R[r+1] = cpu->DataRead32(offset+4); \ #define A_LDRD_POST \ 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->Read32(addr ); \ - cpu->R[r+1] = cpu->Read32(addr+4); \ - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); + cpu->R[r ] = cpu->DataRead32(addr ); \ + cpu->R[r+1] = cpu->DataRead32(addr+4); \ #define A_STRD \ 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->Write32(offset , cpu->R[r ]); \ - cpu->Write32(offset+4, cpu->R[r+1]); \ - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite32(offset , cpu->R[r ]); \ + cpu->DataWrite32(offset+4, cpu->R[r+1]); \ #define A_STRD_POST \ - u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \ u32 r = (cpu->CurInstr>>12) & 0xF; \ - cpu->Write32(offset , cpu->R[r ]); \ - cpu->Write32(offset+4, cpu->R[r+1]); \ - return C_N(2) + cpu->MemWaitstate(3, addr); + cpu->DataWrite32(offset , cpu->R[r ]); \ + cpu->DataWrite32(offset+4, cpu->R[r+1]); \ #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->Read16(offset); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->DataRead16(offset); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(2, offset); #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->Read16(addr); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->DataRead16(addr); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(2, addr); #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->Read8(offset); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->DataRead8(offset); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(3, offset); #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->Read8(addr); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->DataRead8(addr); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(3, addr); #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->Read16(offset); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->DataRead16(offset); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(2, offset); #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->Read16(addr); \ + cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->DataRead16(addr); \ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \ - return C_N(2) + cpu->MemWaitstate(2, addr); #define A_IMPLEMENT_HD_LDRSTR(x) \ \ -s32 A_##x##_IMM(ARM* cpu) \ +void A_##x##_IMM(ARM* cpu) \ { \ A_HD_CALC_OFFSET_IMM \ A_##x \ } \ \ -s32 A_##x##_REG(ARM* cpu) \ +void A_##x##_REG(ARM* cpu) \ { \ A_HD_CALC_OFFSET_REG \ A_##x \ } \ -s32 A_##x##_POST_IMM(ARM* cpu) \ +void A_##x##_POST_IMM(ARM* cpu) \ { \ A_HD_CALC_OFFSET_IMM \ A_##x##_POST \ } \ \ -s32 A_##x##_POST_REG(ARM* cpu) \ +void A_##x##_POST_REG(ARM* cpu) \ { \ A_HD_CALC_OFFSET_REG \ A_##x##_POST \ @@ -336,36 +319,34 @@ A_IMPLEMENT_HD_LDRSTR(LDRSH) -s32 A_SWP(ARM* cpu) +void A_SWP(ARM* cpu) { u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF]; u32 rm = cpu->R[cpu->CurInstr & 0xF]; - u32 val = cpu->Read32(base); + u32 val = cpu->DataRead32(base); cpu->R[(cpu->CurInstr >> 12) & 0xF] = ROR(val, 8*(base&0x3)); - cpu->Write32(base, rm); + cpu->DataWrite32(base, rm); - // the 1S is a code cycle. TODO - return C_S(1) + C_N(2) + C_I(1) + 2*cpu->MemWaitstate(3, base); + cpu->Cycles += 1; } -s32 A_SWPB(ARM* cpu) +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->Read8(base); + cpu->R[(cpu->CurInstr >> 12) & 0xF] = cpu->DataRead8(base); - cpu->Write8(base, rm); + cpu->DataWrite8(base, rm); - // the 1S is a code cycle. TODO - return C_S(1) + C_N(2) + C_I(1) + 2*cpu->MemWaitstate(3, base); + cpu->Cycles += 1; } -s32 A_LDM(ARM* cpu) +void A_LDM(ARM* cpu) { u32 baseid = (cpu->CurInstr >> 16) & 0xF; u32 base = cpu->R[baseid]; @@ -389,7 +370,7 @@ s32 A_LDM(ARM* cpu) preinc = !preinc; } - s32 cycles = C_N(1) + C_I(1); + cpu->Cycles += 1; if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15))) cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10); @@ -399,8 +380,7 @@ s32 A_LDM(ARM* cpu) if (cpu->CurInstr & (1<<i)) { if (preinc) base += 4; - cpu->R[i] = cpu->Read32(base); - cycles += C_S(1) + cpu->MemWaitstate(3, base); + cpu->R[i] = cpu->DataRead32(base); if (!preinc) base += 4; } } @@ -408,8 +388,7 @@ s32 A_LDM(ARM* cpu) if (cpu->CurInstr & (1<<15)) { if (preinc) base += 4; - u32 pc = cpu->Read32(base); - cycles += C_S(2) + C_N(1) + cpu->MemWaitstate(3, base); + u32 pc = cpu->DataRead32(base); if (!preinc) base += 4; if (cpu->Num == 1) @@ -439,11 +418,9 @@ s32 A_LDM(ARM* cpu) else cpu->R[baseid] = wbbase; } - - return cycles; } -s32 A_STM(ARM* cpu) +void A_STM(ARM* cpu) { u32 baseid = (cpu->CurInstr >> 16) & 0xF; u32 base = cpu->R[baseid]; @@ -452,7 +429,7 @@ s32 A_STM(ARM* cpu) if (!(cpu->CurInstr & (1<<23))) { - for (int i = 0; i < 16; i++) + for (u32 i = 0; i < 16; i++) { if (cpu->CurInstr & (1<<i)) base -= 4; @@ -464,12 +441,10 @@ s32 A_STM(ARM* cpu) preinc = !preinc; } - s32 cycles = C_N(1) + C_I(1); - if (cpu->CurInstr & (1<<22)) cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10); - for (int i = 0; i < 16; i++) + for (u32 i = 0; i < 16; i++) { if (cpu->CurInstr & (1<<i)) { @@ -478,14 +453,13 @@ s32 A_STM(ARM* cpu) if (i == baseid) { if ((cpu->Num == 0) || (!(cpu->CurInstr & (i-1)))) - cpu->Write32(base, oldbase); + cpu->DataWrite32(base, oldbase); else - cpu->Write32(base, base); // checkme + cpu->DataWrite32(base, base); // checkme } else - cpu->Write32(base, cpu->R[i]); + cpu->DataWrite32(base, cpu->R[i]); - cycles += C_S(1) + cpu->MemWaitstate(3, base); if (!preinc) base += 4; } } @@ -495,8 +469,6 @@ s32 A_STM(ARM* cpu) if ((cpu->CurInstr & (1<<23)) && (cpu->CurInstr & (1<<21))) cpu->R[baseid] = base; - - return cycles; } @@ -506,160 +478,150 @@ s32 A_STM(ARM* cpu) -s32 T_LDR_PCREL(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->Read32(addr); + cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->DataRead32(addr); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); + cpu->Cycles += 1; } -s32 T_STR_REG(ARM* cpu) +void T_STR_REG(ARM* cpu) { u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; - cpu->Write32(addr, cpu->R[cpu->CurInstr & 0x7]); - - return C_N(2) + cpu->MemWaitstate(3, addr); + cpu->DataWrite32(addr, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_STRB_REG(ARM* cpu) +void T_STRB_REG(ARM* cpu) { u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; - cpu->Write8(addr, cpu->R[cpu->CurInstr & 0x7]); - - return C_N(2) + cpu->MemWaitstate(3, addr); + cpu->DataWrite8(addr, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_LDR_REG(ARM* cpu) +void T_LDR_REG(ARM* cpu) { u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; - u32 val = cpu->Read32(addr); + u32 val = cpu->DataRead32(addr); cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3)); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); + cpu->Cycles += 1; } -s32 T_LDRB_REG(ARM* cpu) +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->Read8(addr); + cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead8(addr); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); + cpu->Cycles += 1; } -s32 T_STRH_REG(ARM* cpu) +void T_STRH_REG(ARM* cpu) { u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; - cpu->Write16(addr, cpu->R[cpu->CurInstr & 0x7]); - - return C_N(2) + cpu->MemWaitstate(2, addr); + cpu->DataWrite16(addr, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_LDRSB_REG(ARM* cpu) +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->Read8(addr); + cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)cpu->DataRead8(addr); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); + cpu->Cycles += 1; } -s32 T_LDRH_REG(ARM* cpu) +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->Read16(addr); + cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead16(addr); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, addr); + cpu->Cycles += 1; } -s32 T_LDRSH_REG(ARM* cpu) +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->Read16(addr); + cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)cpu->DataRead16(addr); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, addr); + cpu->Cycles += 1; } -s32 T_STR_IMM(ARM* cpu) +void T_STR_IMM(ARM* cpu) { u32 offset = (cpu->CurInstr >> 4) & 0x7C; offset += cpu->R[(cpu->CurInstr >> 3) & 0x7]; - cpu->Write32(offset, cpu->R[cpu->CurInstr & 0x7]); - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite32(offset, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_LDR_IMM(ARM* cpu) +void T_LDR_IMM(ARM* cpu) { u32 offset = (cpu->CurInstr >> 4) & 0x7C; offset += cpu->R[(cpu->CurInstr >> 3) & 0x7]; - u32 val = cpu->Read32(offset); + u32 val = cpu->DataRead32(offset); cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3)); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); + cpu->Cycles += 1; } -s32 T_STRB_IMM(ARM* cpu) +void T_STRB_IMM(ARM* cpu) { u32 offset = (cpu->CurInstr >> 6) & 0x1F; offset += cpu->R[(cpu->CurInstr >> 3) & 0x7]; - cpu->Write8(offset, cpu->R[cpu->CurInstr & 0x7]); - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite8(offset, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_LDRB_IMM(ARM* cpu) +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->Read8(offset); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); + cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead8(offset); + cpu->Cycles += 1; } -s32 T_STRH_IMM(ARM* cpu) +void 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); + cpu->DataWrite16(offset, cpu->R[cpu->CurInstr & 0x7]); } -s32 T_LDRH_IMM(ARM* cpu) +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->Read16(offset); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, offset); + cpu->R[cpu->CurInstr & 0x7] = cpu->DataRead16(offset); + cpu->Cycles += 1; } -s32 T_STR_SPREL(ARM* cpu) +void T_STR_SPREL(ARM* cpu) { u32 offset = (cpu->CurInstr << 2) & 0x3FC; offset += cpu->R[13]; - cpu->Write32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]); - return C_N(2) + cpu->MemWaitstate(3, offset); + cpu->DataWrite32(offset, cpu->R[(cpu->CurInstr >> 8) & 0x7]); } -s32 T_LDR_SPREL(ARM* cpu) +void T_LDR_SPREL(ARM* cpu) { u32 offset = (cpu->CurInstr << 2) & 0x3FC; offset += cpu->R[13]; - cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->Read32(offset); - return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset); + cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->DataRead32(offset); + cpu->Cycles += 1; } -s32 T_PUSH(ARM* cpu) +void T_PUSH(ARM* cpu) { int nregs = 0; @@ -676,99 +638,81 @@ s32 T_PUSH(ARM* cpu) 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); + cpu->DataWrite32(base, cpu->R[i]); base += 4; } } if (cpu->CurInstr & (1<<8)) { - cpu->Write32(base, cpu->R[14]); - cycles += C_S(1) + cpu->MemWaitstate(3, base); + cpu->DataWrite32(base, cpu->R[14]); } - - return cycles - C_S(1); } -s32 T_POP(ARM* cpu) +void T_POP(ARM* cpu) { u32 base = cpu->R[13]; - int cycles = C_N(1) + C_I(1); + cpu->Cycles += 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); + cpu->R[i] = cpu->DataRead32(base); base += 4; } } if (cpu->CurInstr & (1<<8)) { - u32 pc = cpu->Read32(base); + u32 pc = cpu->DataRead32(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; } -s32 T_STMIA(ARM* cpu) +void T_STMIA(ARM* cpu) { u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; - 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); + cpu->DataWrite32(base, cpu->R[i]); base += 4; } } // TODO: check "Rb included in Rlist" case cpu->R[(cpu->CurInstr >> 8) & 0x7] = base; - - return cycles - C_S(1); } -s32 T_LDMIA(ARM* cpu) +void T_LDMIA(ARM* cpu) { u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; - int cycles = C_N(1) + C_I(1); + cpu->Cycles += 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); + cpu->R[i] = cpu->DataRead32(base); base += 4; } } if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7)))) cpu->R[(cpu->CurInstr >> 8) & 0x7] = base; - - return cycles; } diff --git a/ARMInterpreter_LoadStore.h b/ARMInterpreter_LoadStore.h index 1c999a4..4ea0e54 100644 --- a/ARMInterpreter_LoadStore.h +++ b/ARMInterpreter_LoadStore.h @@ -24,16 +24,16 @@ namespace ARMInterpreter #define A_PROTO_WB_LDRSTR(x) \ \ -s32 A_##x##_IMM(ARM* cpu); \ -s32 A_##x##_REG_LSL(ARM* cpu); \ -s32 A_##x##_REG_LSR(ARM* cpu); \ -s32 A_##x##_REG_ASR(ARM* cpu); \ -s32 A_##x##_REG_ROR(ARM* cpu); \ -s32 A_##x##_POST_IMM(ARM* cpu); \ -s32 A_##x##_POST_REG_LSL(ARM* cpu); \ -s32 A_##x##_POST_REG_LSR(ARM* cpu); \ -s32 A_##x##_POST_REG_ASR(ARM* cpu); \ -s32 A_##x##_POST_REG_ROR(ARM* cpu); +void A_##x##_IMM(ARM* cpu); \ +void A_##x##_REG_LSL(ARM* cpu); \ +void A_##x##_REG_LSR(ARM* cpu); \ +void A_##x##_REG_ASR(ARM* cpu); \ +void A_##x##_REG_ROR(ARM* cpu); \ +void A_##x##_POST_IMM(ARM* cpu); \ +void A_##x##_POST_REG_LSL(ARM* cpu); \ +void A_##x##_POST_REG_LSR(ARM* cpu); \ +void A_##x##_POST_REG_ASR(ARM* cpu); \ +void A_##x##_POST_REG_ROR(ARM* cpu); A_PROTO_WB_LDRSTR(STR) A_PROTO_WB_LDRSTR(STRB) @@ -42,10 +42,10 @@ A_PROTO_WB_LDRSTR(LDRB) #define A_PROTO_HD_LDRSTR(x) \ \ -s32 A_##x##_IMM(ARM* cpu); \ -s32 A_##x##_REG(ARM* cpu); \ -s32 A_##x##_POST_IMM(ARM* cpu); \ -s32 A_##x##_POST_REG(ARM* cpu); +void A_##x##_IMM(ARM* cpu); \ +void A_##x##_REG(ARM* cpu); \ +void A_##x##_POST_IMM(ARM* cpu); \ +void A_##x##_POST_REG(ARM* cpu); A_PROTO_HD_LDRSTR(STRH) A_PROTO_HD_LDRSTR(LDRD) @@ -54,40 +54,40 @@ A_PROTO_HD_LDRSTR(LDRH) A_PROTO_HD_LDRSTR(LDRSB) A_PROTO_HD_LDRSTR(LDRSH) -s32 A_LDM(ARM* cpu); -s32 A_STM(ARM* cpu); +void A_LDM(ARM* cpu); +void A_STM(ARM* cpu); -s32 A_SWP(ARM* cpu); -s32 A_SWPB(ARM* cpu); +void A_SWP(ARM* cpu); +void A_SWPB(ARM* cpu); -s32 T_LDR_PCREL(ARM* cpu); +void T_LDR_PCREL(ARM* cpu); -s32 T_STR_REG(ARM* cpu); -s32 T_STRB_REG(ARM* cpu); -s32 T_LDR_REG(ARM* cpu); -s32 T_LDRB_REG(ARM* cpu); +void T_STR_REG(ARM* cpu); +void T_STRB_REG(ARM* cpu); +void T_LDR_REG(ARM* cpu); +void T_LDRB_REG(ARM* cpu); -s32 T_STRH_REG(ARM* cpu); -s32 T_LDRSB_REG(ARM* cpu); -s32 T_LDRH_REG(ARM* cpu); -s32 T_LDRSH_REG(ARM* cpu); +void T_STRH_REG(ARM* cpu); +void T_LDRSB_REG(ARM* cpu); +void T_LDRH_REG(ARM* cpu); +void T_LDRSH_REG(ARM* cpu); -s32 T_STR_IMM(ARM* cpu); -s32 T_LDR_IMM(ARM* cpu); -s32 T_STRB_IMM(ARM* cpu); -s32 T_LDRB_IMM(ARM* cpu); +void T_STR_IMM(ARM* cpu); +void T_LDR_IMM(ARM* cpu); +void T_STRB_IMM(ARM* cpu); +void T_LDRB_IMM(ARM* cpu); -s32 T_STRH_IMM(ARM* cpu); -s32 T_LDRH_IMM(ARM* cpu); +void T_STRH_IMM(ARM* cpu); +void T_LDRH_IMM(ARM* cpu); -s32 T_STR_SPREL(ARM* cpu); -s32 T_LDR_SPREL(ARM* cpu); +void T_STR_SPREL(ARM* cpu); +void T_LDR_SPREL(ARM* cpu); -s32 T_PUSH(ARM* cpu); -s32 T_POP(ARM* cpu); -s32 T_STMIA(ARM* cpu); -s32 T_LDMIA(ARM* cpu); +void T_PUSH(ARM* cpu); +void T_POP(ARM* cpu); +void T_STMIA(ARM* cpu); +void T_LDMIA(ARM* cpu); } @@ -78,6 +78,8 @@ void UpdateITCMSetting() void Write(u32 id, u32 val) { + //printf("CP15 write op %03X %08X %08X\n", id, val, NDS::ARM9->R[15]); + switch (id) { case 0x100: @@ -113,8 +113,33 @@ void Reset() } -// VRAM mapping shit. -// TODO eventually: work out priority orders in case of overlaps. there _are_ games that map overlapping banks. +// VRAM mapping notes +// +// mirroring: +// unmapped range reads zero +// LCD is mirrored every 0x100000 bytes, the gap between each mirror reads zero +// ABG: +// bank A,B,C,D,E mirror every 0x80000 bytes +// bank F,G mirror at base+0x8000, mirror every 0x80000 bytes +// AOBJ: +// bank A,B,E mirror every 0x40000 bytes +// bank F,G mirror at base+0x8000, mirror every 0x40000 bytes +// BBG: +// bank C mirrors every 0x20000 bytes +// bank H mirrors every 0x10000 bytes +// bank I mirrors at base+0x4000, mirrors every 0x10000 bytes +// BOBJ: +// bank D mirrors every 0x20000 bytes +// bank I mirrors every 0x4000 bytes +// +// untested: +// ARM7 (TODO) +// extended palette (mirroring doesn't apply) +// texture/texpal (does mirroring apply?) +// +// overlap: +// when reading: values are read from each bank and ORed together +// when writing: value is written to each bank void MapVRAM_AB(u32 bank, u8 cnt) { @@ -1901,6 +1901,7 @@ void ARM7IOWrite8(u32 addr, u8 val) return; case 0x04000301: + //printf("ARM7 HALT %02X. IME=%08X IE=%08X IF=%08X\n", val, IME[1], IE[1], IF[1]); if (val == 0x80) ARM7->Halt(1); return; } @@ -38,6 +38,22 @@ typedef struct _SchedEvent enum { + Event_ScanlineStart = 0, + + Event_Timer9_0, + Event_Timer9_1, + Event_Timer9_2, + Event_Timer9_3, + Event_Timer7_0, + Event_Timer7_1, + Event_Timer7_2, + Event_Timer7_3, + + Event_MAX +}; + +enum +{ IRQ_VBlank = 0, IRQ_HBlank, IRQ_VCount, @@ -105,6 +121,8 @@ void RunEvents(s32 cycles); // DO NOT CALL FROM ARM7!! void CompensateARM7(); +void debug(u32 p); + void Halt(); void MapSharedWRAM(u8 val); @@ -88,6 +88,12 @@ void Reset() fclose(f); + // temp: disable autoboot + /*Firmware[0x3FE64] &= 0xBF; + *(u16*)&Firmware[0x3FE72] = CRC16(&Firmware[0x3FE00], 0x70, 0xFFFF); + Firmware[0x3FF64] &= 0xBF; + *(u16*)&Firmware[0x3FF72] = CRC16(&Firmware[0x3FF00], 0x70, 0xFFFF);*/ + // verify shit printf("FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware[0x2C], 0x2A)?"GOOD":"BAD"); printf("FW: AP1 CRC16 = %s\n", VerifyCRC16(0x0000, 0x3FA00, 0xFE, 0x3FAFE)?"GOOD":"BAD"); @@ -57,6 +57,7 @@ LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam) case VK_LEFT: NDS::PressKey(5); break; case VK_RIGHT: NDS::PressKey(4); break; case 'P': NDS::PressKey(16+6); break; + case 'D': NDS::debug(0); break; } return 0; diff --git a/melonDS.depend b/melonDS.depend index 341078b..8263bde 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -1,16 +1,16 @@ # depslib dependency file v1.0 -1484954918 source:c:\documents\sources\melonds\main.cpp +1485135566 source:c:\documents\sources\melonds\main.cpp <stdio.h> <windows.h> "NDS.h" "GPU.h" -1485110344 c:\documents\sources\melonds\nds.h +1485792939 c:\documents\sources\melonds\nds.h "types.h" 1481161027 c:\documents\sources\melonds\types.h -1485133568 source:c:\documents\sources\melonds\nds.cpp +1485374133 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -24,23 +24,23 @@ "RTC.h" "Wifi.h" -1485133372 source:c:\documents\sources\melonds\arm.cpp +1485797690 source:c:\documents\sources\melonds\arm.cpp <stdio.h> "NDS.h" "ARM.h" "ARMInterpreter.h" -1481062839 c:\documents\sources\melonds\arm.h +1485797447 c:\documents\sources\melonds\arm.h "types.h" "NDS.h" 1484530962 c:\documents\sources\melonds\arm_instrtable.h -1480965273 c:\documents\sources\melonds\arminterpreter.h +1485795549 c:\documents\sources\melonds\arminterpreter.h "types.h" "ARM.h" -1484752824 source:c:\documents\sources\melonds\arminterpreter.cpp +1485797066 source:c:\documents\sources\melonds\arminterpreter.cpp <stdio.h> "NDS.h" "CP15.h" @@ -50,27 +50,27 @@ "ARMInterpreter_LoadStore.h" "ARM_InstrTable.h" -1480957205 c:\documents\sources\melonds\arminterpreter_branch.h +1485795628 c:\documents\sources\melonds\arminterpreter_branch.h -1480957179 source:c:\documents\sources\melonds\arminterpreter_branch.cpp +1485797084 source:c:\documents\sources\melonds\arminterpreter_branch.cpp <stdio.h> "ARM.h" -1481160920 c:\documents\sources\melonds\arminterpreter_alu.h +1485795628 c:\documents\sources\melonds\arminterpreter_alu.h -1484917510 source:c:\documents\sources\melonds\arminterpreter_alu.cpp +1485797076 source:c:\documents\sources\melonds\arminterpreter_alu.cpp <stdio.h> "ARM.h" -1480957165 c:\documents\sources\melonds\arminterpreter_loadstore.h +1485795628 c:\documents\sources\melonds\arminterpreter_loadstore.h -1485133521 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp +1485797600 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp <stdio.h> "ARM.h" 1481037554 c:\documents\sources\melonds\cp15.h -1484754534 source:c:\documents\sources\melonds\cp15.cpp +1485136658 source:c:\documents\sources\melonds\cp15.cpp <stdio.h> "NDS.h" "ARM.h" @@ -78,7 +78,7 @@ 1480957111 c:\documents\sources\melonds\spi.h -1484762789 source:c:\documents\sources\melonds\spi.cpp +1485137440 source:c:\documents\sources\melonds\spi.cpp <stdio.h> <string.h> "NDS.h" @@ -115,7 +115,7 @@ 1484698068 c:\documents\sources\melonds\dma.h "types.h" -1484753188 source:c:\documents\sources\melonds\gpu.cpp +1485789352 source:c:\documents\sources\melonds\gpu.cpp <stdio.h> <string.h> "NDS.h" |