-unsp: Fixed DIVQ operation and several Memory Bitop operations. [Ryan Holtz]

This commit is contained in:
Ryan Holtz 2020-05-21 22:13:39 +02:00
parent fb410f496a
commit ce0b942ef0
5 changed files with 26 additions and 22 deletions

View File

@ -281,6 +281,9 @@ void unsp_device::device_start()
save_item(NAME(m_core->m_bnk));
save_item(NAME(m_core->m_ine));
save_item(NAME(m_core->m_pri));
save_item(NAME(m_core->m_divq_bit));
save_item(NAME(m_core->m_divq_dividend));
save_item(NAME(m_core->m_divq_divisor));
set_icountptr(m_core->m_icount);
}
@ -328,6 +331,7 @@ void unsp_device::device_reset()
m_core->m_fiq = 0;
m_core->m_irq = 0;
m_core->m_sirq = 0;
m_core->m_divq_bit = UINT_MAX;
}
void unsp_20_device::device_reset()
@ -506,9 +510,6 @@ inline void unsp_device::execute_one(const uint16_t op)
const uint16_t opa = (op >> 9) & 7;
const uint16_t op1 = (op >> 6) & 7;
if (!op_is_divq(op))
m_core->m_divq_active = 0;
if (op0 == 0xf)
return execute_fxxx_group(op);

View File

@ -193,8 +193,10 @@ protected:
uint32_t m_ine;
uint32_t m_pri;
uint32_t m_divq_active;
uint32_t m_divq_bit;
uint32_t m_divq_dividend;
uint32_t m_divq_divisor;
uint32_t m_divq_a;
uint32_t m_arg0;
uint32_t m_arg1;

View File

@ -226,6 +226,8 @@ void unsp_20_device::execute_extended_group(uint16_t op)
uint8_t use_ds = BIT(ximm, 5);
uint8_t form = (ximm & 0x0018) >> 3;
r0 = m_core->m_r[rx];
switch (form)
{
case 0x0: // Rx, [<ds:>Ry]
@ -259,8 +261,7 @@ void unsp_20_device::execute_extended_group(uint16_t op)
break;
}
const bool write = do_basic_alu_ops(aluop, lres, r0, r1, r2, (aluop != 7) ? true : false);
if (write)
if (do_basic_alu_ops(aluop, lres, r0, r1, r2, (aluop != 7) ? true : false))
{
m_core->m_r[rx] = (uint16_t)lres;
}

View File

@ -110,7 +110,7 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
const uint8_t bitop = (op & 0x0030) >> 4;
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t offset = (op & 0x000f) >> 0;
const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint32_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
@ -172,7 +172,7 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
const uint8_t rd = (op & 0x0e00) >> 9;
const uint8_t rs = (op & 0x0007) >> 0;
const uint8_t offset = (1 << m_core->m_r[rs]);
const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint32_t addr = m_core->m_r[rd] | (get_ds() << 16);
const uint16_t orig = read16(addr);
m_core->m_r[REG_SR] &= ~UNSP_Z;
m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;

View File

@ -250,24 +250,29 @@ inline void unsp_device::execute_fxxx_100_group(uint16_t op)
void unsp_12_device::execute_divq(uint16_t op)
{
const uint16_t sign_a = m_core->m_aq;
if (m_core->m_divq_active == 0)
uint32_t orig_dividend = 0;
if (m_core->m_divq_bit == UINT_MAX)
{
m_core->m_divq_active = 1;
m_core->m_divq_bit = 15;
m_core->m_divq_dividend = (m_core->m_r[REG_R4] << 16) | m_core->m_r[REG_R3];
m_core->m_r[REG_R3] = 0;
m_core->m_divq_divisor = m_core->m_r[REG_R2];
m_core->m_divq_a = 0;
}
m_core->m_aq = BIT(m_core->m_divq_dividend, 31);
if (sign_a)
orig_dividend = m_core->m_divq_dividend;
m_core->m_aq = BIT(m_core->m_divq_a, 31);
if (m_core->m_aq)
{
m_core->m_r[REG_R3] += m_core->m_r[REG_R2];
m_core->m_divq_a += m_core->m_divq_a + BIT(m_core->m_divq_dividend, 15) + m_core->m_divq_divisor;
}
else
{
m_core->m_r[REG_R3] -= m_core->m_r[REG_R3];
m_core->m_divq_a += m_core->m_divq_a + BIT(m_core->m_divq_dividend, 15) - m_core->m_divq_divisor;
}
m_core->m_divq_dividend <<= 1;
m_core->m_divq_dividend |= m_core->m_aq ? 0 : 1;
m_core->m_divq_dividend++;
m_core->m_divq_dividend ^= BIT(m_core->m_divq_a, 31);
m_core->m_r[REG_R3] = (uint16_t)m_core->m_divq_dividend;
m_core->m_divq_bit--;
}
bool unsp_12_device::op_is_divq(const uint16_t op)
@ -550,23 +555,18 @@ void unsp_device::execute_fxxx_group(uint16_t op)
switch ((op & 0x01c0) >> 6)
{
case 0x0:
m_core->m_divq_active = 0;
return execute_fxxx_000_group(op);
case 0x1:
m_core->m_divq_active = 0;
return execute_fxxx_001_group(op);
case 0x2:
m_core->m_divq_active = 0;
return execute_fxxx_010_group(op);
case 0x3:
m_core->m_divq_active = 0;
return execute_fxxx_011_group(op);
case 0x4:
m_core->m_divq_active = 0;
return execute_fxxx_100_group(op);
case 0x5: