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 "bits.h"
|
||||
#include "MMU.h"
|
||||
#include "common.h"
|
||||
|
||||
#define CODE(i) (((i)>>25)&0x7)
|
||||
#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>
|
||||
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
|
||||
//#define EQ 0x0
|
||||
//#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
|
||||
|
|
|
@ -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,
|
||||
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 *ptr = NULL;
|
||||
|
|
|
@ -56,7 +56,32 @@ extern const u8 logo_data[156];
|
|||
|
||||
#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 *removeSpecialChars(char *s);
|
||||
|
||||
|
|
|
@ -38,38 +38,12 @@
|
|||
|
||||
#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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
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 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.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.C = CarryFrom(Rd, Rm + cpu->CPSR.bits.C);
|
||||
cpu->CPSR.bits.V = (Rd ^ Rm ^ -1) & (Rd ^ cpu->R[REG_NUM(i, 0)]) != 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -482,18 +463,25 @@ TEMPLATE static u32 FASTCALL OP_ADC_REG(const u32 i)
|
|||
//-----------------------------------------------------------------------------
|
||||
// SBC
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TEMPLATE static u32 FASTCALL OP_SBC_REG(const u32 i)
|
||||
{
|
||||
u32 Rd = cpu->R[REG_NUM(i, 0)];
|
||||
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.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.C = !BorrowFrom(Rd, Rm - !cpu->CPSR.bits.C);
|
||||
cpu->CPSR.bits.V = ((Rd ^ Rm) & (Rd ^ cpu->R[REG_NUM(i, 0)])) != 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -902,6 +890,13 @@ TEMPLATE static u32 FASTCALL OP_POP(const u32 i)
|
|||
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)
|
||||
{
|
||||
u32 adr = cpu->R[13];
|
||||
|
|
Loading…
Reference in New Issue