DSPLLE - SR_10 flag implemented (no idea what name should it have or how/when this is supposed to be used)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5075 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Marko Pusljar
2010-02-17 19:10:31 +00:00
parent 634f6e512e
commit 377ece3294
4 changed files with 60 additions and 34 deletions

View File

@ -154,7 +154,7 @@
#define SR_OVERFLOW 0x0002 #define SR_OVERFLOW 0x0002
#define SR_ARITH_ZERO 0x0004 #define SR_ARITH_ZERO 0x0004
#define SR_SIGN 0x0008 #define SR_SIGN 0x0008
#define SR_10 0x0010 // seem to be set by tst #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_TOP2BITS 0x0020 // if the upper 2 bits are equal
#define SR_LOGIC_ZERO 0x0040 #define SR_LOGIC_ZERO 0x0040
#define SR_80 0x0080 // Unknown, set by add #define SR_80 0x0080 // Unknown, set by add

View File

@ -26,32 +26,42 @@
namespace DSPInterpreter { namespace DSPInterpreter {
void Update_SR_Register64(s64 _Value, bool carry, bool overflow) void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10)
{ {
// TODO: Should also set 0x10 and 0x01 (also 0x02?) // TODO: recheck 0x1,0x2,even 0x80... implement...
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
if (_Value < 0) // 0x01
{
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
if (_Value == 0)
{
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
}
if (carry) if (carry)
{ {
g_dsp.r[DSP_REG_SR] |= SR_CARRY; g_dsp.r[DSP_REG_SR] |= SR_CARRY;
} }
// 0x02
if (overflow) if (overflow)
{ {
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW; g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
} }
// Checks if top bits of m are equal, what is it good for? // 0x04
if (_Value == 0)
{
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
}
// 0x08
if (_Value < 0)
{
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
// 0x10 - abs((u40)acc?) >= 0x80000000
if (sr10)
{
g_dsp.r[DSP_REG_SR] |= SR_10;
}
// 0x20 - Checks if top bits of m are equal, what is it good for?
if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000)) if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
{ {
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
@ -59,32 +69,42 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow)
} }
void Update_SR_Register16(s16 _Value, bool carry, bool overflow) void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10)
{ {
// TODO: recheck 0x1,0x2,even 0x80... implement...
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
// 0x01
if (_Value < 0)
{
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
if (_Value == 0)
{
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
}
if (carry) if (carry)
{ {
g_dsp.r[DSP_REG_SR] |= SR_CARRY; g_dsp.r[DSP_REG_SR] |= SR_CARRY;
} }
// 0x02
if (overflow) if (overflow)
{ {
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW; g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
} }
// Checks if top bits are equal, what is it good for? // 0x04
if (_Value == 0)
{
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
}
// 0x08
if (_Value < 0)
{
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
}
// 0x10 - abs((u40)acc?) >= 0x80000000
if (sr10)
{
g_dsp.r[DSP_REG_SR] |= SR_10;
}
// 0x20 - Checks if top bits of m are equal, what is it good for?
if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3)) if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
{ {
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;

View File

@ -30,8 +30,8 @@ bool CheckCondition(u8 _Condition);
int GetMultiplyModifier(); int GetMultiplyModifier();
void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false); 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); void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false, bool sr10 = false);
void Update_SR_LZ(bool value); void Update_SR_LZ(bool value);
inline bool isAddCarry(u64 val, u64 result) { inline bool isAddCarry(u64 val, u64 result) {
@ -46,6 +46,11 @@ inline bool isOverflow(s64 val1, s64 val2, s64 res) {
return ((val1 ^ res) & (val2 ^ res)) < 0; 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
}
} // namespace } // namespace
#endif // _GDSP_CONDITION_CODES_H #endif // _GDSP_CONDITION_CODES_H

View File

@ -334,12 +334,12 @@ void andi(const UDSPInstruction& opc)
// Logic OR of accumulator mid part $acD.m with immediate value I. // Logic OR of accumulator mid part $acD.m with immediate value I.
void ori(const UDSPInstruction& opc) void ori(const UDSPInstruction& opc)
{ {
u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1); u8 reg = (opc.hex >> 8) & 0x1;
u16 imm = dsp_fetch_code(); u16 imm = dsp_fetch_code();
g_dsp.r[reg] |= imm; g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
Update_SR_Register16((s16)g_dsp.r[reg]); Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isSR10(dsp_get_long_acc(reg)));
} }
//------------------------------------------------------------- //-------------------------------------------------------------
@ -358,8 +358,9 @@ void add(const UDSPInstruction& opc)
zeroWriteBackLog(); zeroWriteBackLog();
dsp_set_long_acc(areg, res); dsp_set_long_acc(areg, res);
res = dsp_get_long_acc(areg);
Update_SR_Register64(res); Update_SR_Register64(res, false, false, isSR10(res));
} }
// ADDP $acD // ADDP $acD