DSPLLE - flags&stuff (more later)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5093 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Marko Pusljar 2010-02-21 10:35:28 +00:00
parent 2aa03f5b3b
commit 885299d985
5 changed files with 35 additions and 23 deletions

View File

@ -154,10 +154,10 @@
#define SR_OVERFLOW 0x0002
#define SR_ARITH_ZERO 0x0004
#define SR_SIGN 0x0008
#define SR_10 0x0010 // set when there there was mod/tst/cmp on accu and abs(acc?)>=0x80000000, tstaxh never modifies it
#define SR_TOP2BITS 0x0020 // if the upper 2 bits are equal
#define SR_OVER_S32 0x0010 // set when there there was mod/tst/cmp on accu and result is over s32
#define SR_TOP2BITS 0x0020 // if the upper (ac?.m/ax?.h) 2 bits are equal
#define SR_LOGIC_ZERO 0x0040
#define SR_80 0x0080 // Unknown, set by add
#define SR_80 0x0080 // Unknown, set by add, sub
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)

View File

@ -26,7 +26,7 @@
namespace DSPInterpreter {
void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10)
void Update_SR_Register64(s64 _Value, bool carry, bool overflow)
{
// TODO: recheck 0x1,0x2,even 0x80... implement...
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
@ -55,10 +55,10 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10)
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
// 0x10 - abs((u40)acc?) >= 0x80000000
if (sr10)
// 0x10
if (_Value != (s32)_Value)
{
g_dsp.r[DSP_REG_SR] |= SR_10;
g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
}
// 0x20 - Checks if top bits of m are equal, what is it good for?
@ -66,10 +66,14 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10)
{
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
}
// 0x80
{
}
}
void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10)
void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
{
// TODO: recheck 0x1,0x2,even 0x80... implement...
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
@ -98,10 +102,10 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10)
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
// 0x10 - abs((u40)acc?) >= 0x80000000
if (sr10)
// 0x10
if (overS32)
{
g_dsp.r[DSP_REG_SR] |= SR_10;
g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
}
// 0x20 - Checks if top bits of m are equal, what is it good for?
@ -109,6 +113,10 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10)
{
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
}
// 0x80
{
}
}
void Update_SR_LZ(bool value) {

View File

@ -30,8 +30,8 @@ bool CheckCondition(u8 _Condition);
int GetMultiplyModifier();
void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false, bool sr10 = false);
void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false, bool sr10 = false);
void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false, bool overS32 = false);
void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false);
void Update_SR_LZ(bool value);
inline bool isAddCarry(u64 val, u64 result) {
@ -46,9 +46,8 @@ inline bool isOverflow(s64 val1, s64 val2, s64 res) {
return ((val1 ^ res) & (val2 ^ res)) < 0;
}
inline bool isSR10(s64 acc) {
return (((u64)acc >= 0x80000000ULL) && ((u64)acc < 0xffffffff80000000ULL)) ? true : false;
//return (_abs64(acc) < 0x80000000) ? false : true; // working too - easier to understand
inline bool isOverS32(s64 acc) {
return (acc != (s32)acc) ? true : false;
}
} // namespace

View File

@ -251,6 +251,10 @@ inline void dsp_set_long_acc(int _reg, s64 val)
g_dsp.r[DSP_REG_ACH0 + _reg] = (u16)(s16)(s8)(u8)val;
}
inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40
{
return ((s64)(s8)(val >> 32))<<32 | (u32)val;
}
inline s16 dsp_get_acc_l(int _reg)
{

View File

@ -339,7 +339,7 @@ void ori(const UDSPInstruction& opc)
g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isSR10(dsp_get_long_acc(reg)));
Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
}
//-------------------------------------------------------------
@ -350,17 +350,18 @@ void ori(const UDSPInstruction& opc)
// Adds accumulator $ac(1-D) to accumulator register $acD.
void add(const UDSPInstruction& opc)
{
u8 areg = (opc.hex >> 8) & 0x1;
s64 acc0 = dsp_get_long_acc(0);
s64 acc1 = dsp_get_long_acc(1);
u8 dreg = (opc.hex >> 8) & 0x1;
s64 acc0 = dsp_get_long_acc(dreg);
s64 acc1 = dsp_get_long_acc(1 - dreg);
s64 res = acc0 + acc1;
zeroWriteBackLog();
dsp_set_long_acc(areg, res);
res = dsp_get_long_acc(areg);
Update_SR_Register64(res, false, false, isSR10(res));
dsp_set_long_acc(dreg, res);
res = dsp_get_long_acc(dreg);
Update_SR_Register64(res, isAddCarry(acc0, res), isOverflow(acc0, acc1, res));
}
// ADDP $acD