mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-06-28 09:59:41 -06:00
start refactoring shit: more accurate timing and way of counting cycles.
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user