dsplle - another small fix
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6075 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2ac8691911
commit
95b0abb737
|
@ -163,7 +163,7 @@
|
||||||
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
|
#define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so.
|
||||||
#define SR_400 0x0400 // unknown
|
#define SR_400 0x0400 // unknown
|
||||||
#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
|
#define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts
|
||||||
#define SR_1000 0x1000 // unknown
|
#define SR_ROUNDING_MODE 0x1000 // 0 - convergent rounding, 1 - twos complement rounding (source: motorola DSP56?00FM.pdf-s)
|
||||||
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
|
#define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2)
|
||||||
#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums.
|
#define SR_40_MODE_BIT 0x4000 // 0 = "16", 1 = "40" (SET16, SET40) Controls sign extension when loading mid accums.
|
||||||
#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats operands as unsigned. Tested with mulx only so far.
|
#define SR_MUL_UNSIGNED 0x8000 // 0 = normal. 1 = unsigned (CLR15, SET15) If set, treats operands as unsigned. Tested with mulx only so far.
|
||||||
|
|
|
@ -160,11 +160,6 @@ inline void dsp_op_write_reg(int reg, u16 val)
|
||||||
g_dsp.r[reg] = (u16)(s16)(s8)(u8)val;
|
g_dsp.r[reg] = (u16)(s16)(s8)(u8)val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DSP_REG_ACM0:
|
|
||||||
case DSP_REG_ACM1:
|
|
||||||
g_dsp.r[reg] = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Stack registers.
|
// Stack registers.
|
||||||
case DSP_REG_ST0:
|
case DSP_REG_ST0:
|
||||||
case DSP_REG_ST1:
|
case DSP_REG_ST1:
|
||||||
|
@ -217,7 +212,19 @@ inline s64 dsp_get_long_prod()
|
||||||
|
|
||||||
inline s64 dsp_get_long_prod_round_prodl()
|
inline s64 dsp_get_long_prod_round_prodl()
|
||||||
{
|
{
|
||||||
return (dsp_get_long_prod() + 0x7fff) & ~0xffff;
|
s64 prod = dsp_get_long_prod();
|
||||||
|
|
||||||
|
if (g_dsp.r[DSP_REG_SR] & SR_ROUNDING_MODE)
|
||||||
|
prod = (prod + 0x8000) & ~0xffff;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prod & 0x10000)
|
||||||
|
prod = (prod + 0x8000) & ~0xffff;
|
||||||
|
else
|
||||||
|
prod = (prod + 0x7fff) & ~0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For accurate emulation, this is wrong - but the real prod registers behave
|
// For accurate emulation, this is wrong - but the real prod registers behave
|
||||||
|
@ -271,6 +278,21 @@ inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40
|
||||||
return ((s64)(s8)(val >> 32))<<32 | (u32)val;
|
return ((s64)(s8)(val >> 32))<<32 | (u32)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline s64 dsp_round_long_acc(s64 val)
|
||||||
|
{
|
||||||
|
if (g_dsp.r[DSP_REG_SR] & SR_ROUNDING_MODE)
|
||||||
|
val = (val + 0x8000) & ~0xffff;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (val & 0x10000)
|
||||||
|
val = (val + 0x8000) & ~0xffff;
|
||||||
|
else
|
||||||
|
val = (val + 0x7fff) & ~0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
inline s16 dsp_get_acc_l(int _reg)
|
inline s16 dsp_get_acc_l(int _reg)
|
||||||
{
|
{
|
||||||
_assert_(_reg < 2);
|
_assert_(_reg < 2);
|
||||||
|
|
|
@ -47,8 +47,7 @@ void clr(const UDSPInstruction opc)
|
||||||
void clrl(const UDSPInstruction opc)
|
void clrl(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
|
s64 acc = dsp_round_long_acc(dsp_get_long_acc(reg));
|
||||||
s64 acc = (dsp_get_long_acc(reg) + 0x7fff) & ~0xffff;
|
|
||||||
|
|
||||||
zeroWriteBackLog();
|
zeroWriteBackLog();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue