stopped div 0x80000000, 0xffffffff from causing an overflow exception. All loads cancel an outstanding load to the same register, not just lwl/lwr [smf]

This commit is contained in:
smf- 2013-10-06 23:53:03 +00:00
parent c7a59beb3e
commit 84cd73c9ea

View File

@ -1183,12 +1183,12 @@ void psxcpu_device::multiplier_update()
break; break;
case MULTIPLIER_OPERATION_DIV: case MULTIPLIER_OPERATION_DIV:
if( m_multiplier_operand2 != 0 ) if( m_multiplier_operand1 == 0x80000000 && m_multiplier_operand2 == 0xffffffff)
{ {
m_lo = (INT32)m_multiplier_operand1 / (INT32)m_multiplier_operand2; m_hi = 0x00000000;
m_hi = (INT32)m_multiplier_operand1 % (INT32)m_multiplier_operand2; m_lo = 0x80000000;
} }
else else if( m_multiplier_operand2 == 0 )
{ {
if( (INT32)m_multiplier_operand1 < 0 ) if( (INT32)m_multiplier_operand1 < 0 )
{ {
@ -1201,19 +1201,24 @@ void psxcpu_device::multiplier_update()
m_hi = m_multiplier_operand1; m_hi = m_multiplier_operand1;
} }
else
{
m_lo = (INT32)m_multiplier_operand1 / (INT32)m_multiplier_operand2;
m_hi = (INT32)m_multiplier_operand1 % (INT32)m_multiplier_operand2;
}
break; break;
case MULTIPLIER_OPERATION_DIVU: case MULTIPLIER_OPERATION_DIVU:
if( m_multiplier_operand2 != 0 ) if( m_multiplier_operand2 == 0 )
{
m_lo = m_multiplier_operand1 / m_multiplier_operand2;
m_hi = m_multiplier_operand1 % m_multiplier_operand2;
}
else
{ {
m_lo = 0xffffffff; m_lo = 0xffffffff;
m_hi = m_multiplier_operand1; m_hi = m_multiplier_operand1;
} }
else
{
m_lo = m_multiplier_operand1 / m_multiplier_operand2;
m_hi = m_multiplier_operand1 % m_multiplier_operand2;
}
break; break;
} }
@ -1512,6 +1517,12 @@ void psxcpu_device::load( UINT32 reg, UINT32 value )
void psxcpu_device::delayed_load( UINT32 reg, UINT32 value ) void psxcpu_device::delayed_load( UINT32 reg, UINT32 value )
{ {
if( m_delayr == reg )
{
m_delayr = 0;
m_delayv = 0;
}
advance_pc(); advance_pc();
m_delayr = reg; m_delayr = reg;
@ -2052,12 +2063,7 @@ UINT32 psxcpu_device::get_register_from_pipeline( int reg )
{ {
if( m_delayr == reg ) if( m_delayr == reg )
{ {
UINT32 data = m_delayv; return m_delayv;
m_delayr = 0;
m_delayv = 0;
return data;
} }
return m_r[ reg ]; return m_r[ reg ];