core:
- a lot work on fix CPU emulation but not finished yet. Report to bugtracker if it break something.
This commit is contained in:
parent
53a76b5be5
commit
ed419e6a3a
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#define CODE(i) (((i)>>25)&0x7)
|
#define CODE(i) (((i)>>25)&0x7)
|
||||||
#define OPCODE(i) (((i)>>21)&0xF)
|
#define OPCODE(i) (((i)>>21)&0xF)
|
||||||
|
@ -54,6 +55,31 @@ inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
|
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
|
||||||
|
|
||||||
|
// ============================= CPRS flags funcs
|
||||||
|
inline bool CarryFrom(s32 left, s32 right)
|
||||||
|
{
|
||||||
|
u32 res = (0xFFFFFFFFU - (u32)left);
|
||||||
|
|
||||||
|
return ((u32)right > res);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BorrowFrom(s32 left, s32 right)
|
||||||
|
{
|
||||||
|
return ((u32)right > (u32)left);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
|
||||||
|
{
|
||||||
|
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
|
||||||
|
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
|
||||||
|
{
|
||||||
|
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
|
||||||
|
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||||
|
}
|
||||||
|
|
||||||
//zero 15-feb-2009 - these werent getting used and they were getting in my way
|
//zero 15-feb-2009 - these werent getting used and they were getting in my way
|
||||||
//#define EQ 0x0
|
//#define EQ 0x0
|
||||||
//#define NE 0x1
|
//#define NE 0x1
|
||||||
|
@ -272,4 +298,22 @@ static INLINE void NDS_makeInt(u8 proc_ID,u32 num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE char *decodeIntruction(bool thumb_mode, u32 instr)
|
||||||
|
{
|
||||||
|
char txt[20] = {0};
|
||||||
|
u32 tmp = 0;
|
||||||
|
if (thumb_mode == true)
|
||||||
|
{
|
||||||
|
tmp = (instr >> 6);
|
||||||
|
strcpy(txt, intToBin((u16)tmp)+6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp = ((instr >> 16) & 0x0FF0) | ((instr >> 4) & 0x0F);
|
||||||
|
strcpy(txt, intToBin((u32)tmp)+20);
|
||||||
|
}
|
||||||
|
return strdup(txt);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,20 +37,6 @@ const u8 logo_data[156] = {
|
||||||
0x78,0x00,0x90,0xCB,0x88,0x11,0x3A,0x94,0x65,0xC0,0x7C,0x63,0x87,0xF0,0x3C,0xAF,
|
0x78,0x00,0x90,0xCB,0x88,0x11,0x3A,0x94,0x65,0xC0,0x7C,0x63,0x87,0xF0,0x3C,0xAF,
|
||||||
0xD6,0x25,0xE4,0x8B,0x38,0x0A,0xAC,0x72,0x21,0xD4,0xF8,0x07};
|
0xD6,0x25,0xE4,0x8B,0x38,0x0A,0xAC,0x72,0x21,0xD4,0xF8,0x07};
|
||||||
|
|
||||||
u8 reverseBitsInByte(u8 x)
|
|
||||||
{
|
|
||||||
u8 h = 0;
|
|
||||||
u8 i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
h = (h << 1) + (x & 1);
|
|
||||||
x >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *trim(char *s)
|
char *trim(char *s)
|
||||||
{
|
{
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
|
|
|
@ -56,7 +56,32 @@ extern const u8 logo_data[156];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern u8 reverseBitsInByte(u8 x);
|
template<typename T>
|
||||||
|
T reverseBits(T x)
|
||||||
|
{
|
||||||
|
T h = 0;
|
||||||
|
T i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(T)*8; i++)
|
||||||
|
{
|
||||||
|
h = (h << 1) + (x & 1);
|
||||||
|
x >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char *intToBin(T val)
|
||||||
|
{
|
||||||
|
char buf[256] = {0};
|
||||||
|
for (int i = sizeof(T)*8, t = 0; i > 0; --i, t++)
|
||||||
|
{
|
||||||
|
buf[i-1] = (val & (1<<t))?'1':'0';
|
||||||
|
}
|
||||||
|
return strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
extern char *trim(char *s);
|
extern char *trim(char *s);
|
||||||
extern char *removeSpecialChars(char *s);
|
extern char *removeSpecialChars(char *s);
|
||||||
|
|
||||||
|
|
|
@ -38,38 +38,12 @@
|
||||||
|
|
||||||
#define REG_NUM(i, n) (((i)>>n)&0x7)
|
#define REG_NUM(i, n) (((i)>>n)&0x7)
|
||||||
|
|
||||||
// ============================= CPRS flags funcs
|
|
||||||
static bool CarryFrom(s32 left, s32 right)
|
|
||||||
{
|
|
||||||
u32 res = (0xFFFFFFFF - (u32)left);
|
|
||||||
|
|
||||||
return ((u32)right > res);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool BorrowFrom(s32 left, s32 right)
|
|
||||||
{
|
|
||||||
return ((u32)right > (u32)left);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
|
|
||||||
{
|
|
||||||
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
|
|
||||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
|
|
||||||
{
|
|
||||||
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
|
|
||||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Undefined instruction
|
// Undefined instruction
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEMPLATE static u32 FASTCALL OP_UND_THUMB(const u32 i)
|
TEMPLATE static u32 FASTCALL OP_UND_THUMB(const u32 i)
|
||||||
{
|
{
|
||||||
INFO("THUMB%c: Undefined instruction: 0x%08X PC=0x%08X.\n", cpu->proc_ID?'7':'9', cpu->instruction, cpu->instruct_adr);
|
INFO("THUMB%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(true, cpu->instruction), cpu->instruct_adr);
|
||||||
TRAPUNDEF(cpu);
|
TRAPUNDEF(cpu);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -469,12 +443,19 @@ TEMPLATE static u32 FASTCALL OP_ADC_REG(const u32 i)
|
||||||
u32 Rd = cpu->R[REG_NUM(i, 0)];
|
u32 Rd = cpu->R[REG_NUM(i, 0)];
|
||||||
u32 Rm = cpu->R[REG_NUM(i, 3)];
|
u32 Rm = cpu->R[REG_NUM(i, 3)];
|
||||||
|
|
||||||
cpu->R[REG_NUM(i, 0)] = Rd + Rm + cpu->CPSR.bits.C;
|
if (!cpu->CPSR.bits.C)
|
||||||
|
{
|
||||||
|
cpu->R[REG_NUM(i, 0)] = Rd + Rm;
|
||||||
|
cpu->CPSR.bits.C = cpu->R[REG_NUM(i, 0)] < Rm;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu->R[REG_NUM(i, 0)] = Rd + Rm + 1;
|
||||||
|
cpu->CPSR.bits.C = cpu->R[REG_NUM(i, 0)] <= Rm;
|
||||||
|
}
|
||||||
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
||||||
cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0);
|
cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0);
|
||||||
cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 0)], Rd, Rm + cpu->CPSR.bits.C);
|
cpu->CPSR.bits.V = (Rd ^ Rm ^ -1) & (Rd ^ cpu->R[REG_NUM(i, 0)]) != 0;
|
||||||
cpu->CPSR.bits.C = CarryFrom(Rd, Rm + cpu->CPSR.bits.C);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -482,18 +463,25 @@ TEMPLATE static u32 FASTCALL OP_ADC_REG(const u32 i)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// SBC
|
// SBC
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEMPLATE static u32 FASTCALL OP_SBC_REG(const u32 i)
|
TEMPLATE static u32 FASTCALL OP_SBC_REG(const u32 i)
|
||||||
{
|
{
|
||||||
u32 Rd = cpu->R[REG_NUM(i, 0)];
|
u32 Rd = cpu->R[REG_NUM(i, 0)];
|
||||||
u32 Rm = cpu->R[REG_NUM(i, 3)];
|
u32 Rm = cpu->R[REG_NUM(i, 3)];
|
||||||
|
|
||||||
cpu->R[REG_NUM(i, 0)] = Rd - Rm - !cpu->CPSR.bits.C;
|
if (!cpu->CPSR.bits.C)
|
||||||
|
{
|
||||||
|
cpu->R[REG_NUM(i, 0)] = Rd - Rm - 1;
|
||||||
|
cpu->CPSR.bits.C = Rd > Rm;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu->R[REG_NUM(i, 0)] = Rd - Rm;
|
||||||
|
cpu->CPSR.bits.C = Rd >= Rm;
|
||||||
|
}
|
||||||
|
|
||||||
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
||||||
cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0);
|
cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0);
|
||||||
cpu->CPSR.bits.V = OverflowFromSUB(cpu->R[REG_NUM(i, 0)], Rd, Rm - !cpu->CPSR.bits.C);
|
cpu->CPSR.bits.V = ((Rd ^ Rm) & (Rd ^ cpu->R[REG_NUM(i, 0)])) != 0;
|
||||||
cpu->CPSR.bits.C = !BorrowFrom(Rd, Rm - !cpu->CPSR.bits.C);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -902,6 +890,13 @@ TEMPLATE static u32 FASTCALL OP_POP(const u32 i)
|
||||||
return MMU_aluMemCycles<PROCNUM>(2, c);
|
return MMU_aluMemCycles<PROCNUM>(2, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In ARMv5 and above, bit[0] of the loaded value
|
||||||
|
// determines whether execution continues after this branch in ARM state or in Thumb state, as though the
|
||||||
|
// following instruction had been executed:
|
||||||
|
// BX (loaded_value)
|
||||||
|
// In T variants of ARMv4, bit[0] of the loaded value is ignored and execution continues in Thumb state, as
|
||||||
|
// though the following instruction had been executed:
|
||||||
|
// MOV PC,(loaded_value)
|
||||||
TEMPLATE static u32 FASTCALL OP_POP_PC(const u32 i)
|
TEMPLATE static u32 FASTCALL OP_POP_PC(const u32 i)
|
||||||
{
|
{
|
||||||
u32 adr = cpu->R[13];
|
u32 adr = cpu->R[13];
|
||||||
|
|
Loading…
Reference in New Issue