mirror of
https://github.com/holub/mame
synced 2025-06-07 13:23:50 +03:00
romp: various improvements
* implement multiply/divide step instructions * privileged instruction exceptions * corrected borrow flag logic
This commit is contained in:
parent
cda4ab6526
commit
749acfe07f
@ -9,8 +9,7 @@
|
|||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - mmu/iocc exceptions
|
* - mmu/iocc exceptions
|
||||||
* - unimplemented instructions (multiply, divide, wait)
|
* - unimplemented instructions (wait)
|
||||||
* - timer/counter
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -327,19 +326,27 @@ void romp_device::execute_run()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xd0: // lps: load program status
|
case 0xd0: // lps: load program status
|
||||||
if (m_branch_state != BRANCH)
|
if (!(m_scr[ICS] & ICS_US))
|
||||||
{
|
{
|
||||||
m_branch_target = m_mem.read_dword(r3 + s16(i) + 0);
|
if (m_branch_state != BRANCH)
|
||||||
m_branch_state = BRANCH;
|
{
|
||||||
m_scr[ICS] = m_mem.read_word(r3 + s16(i) + 4);
|
m_branch_target = m_mem.read_dword(r3 + s16(i) + 0);
|
||||||
m_scr[CS] = m_mem.read_word(r3 + s16(i) + 6);
|
m_branch_state = BRANCH;
|
||||||
m_scr[MPCS] &= ~0xffff;
|
m_scr[ICS] = m_mem.read_word(r3 + s16(i) + 4);
|
||||||
// TODO: defer interrupt enable
|
m_scr[CS] = m_mem.read_word(r3 + s16(i) + 6);
|
||||||
|
if (m_scr[MPCS] & MCS_ALL)
|
||||||
|
m_scr[MPCS] &= ~MCS_ALL;
|
||||||
|
else
|
||||||
|
m_scr[MPCS] &= ~PCS_ALL;
|
||||||
|
// TODO: defer interrupt enable
|
||||||
|
|
||||||
m_icount -= 15;
|
m_icount -= 15;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
program_check(PCS_PCK | PCS_IOC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
program_check(PCS_PCK | PCS_IOC);
|
program_check(PCS_PCK | PCS_PIE);
|
||||||
break;
|
break;
|
||||||
case 0xd1: // aei: add extended immediate
|
case 0xd1: // aei: add extended immediate
|
||||||
flags_add(m_gpr[R3], s32(s16(i)) + bool(m_scr[CS] & CS_C));
|
flags_add(m_gpr[R3], s32(s16(i)) + bool(m_scr[CS] & CS_C));
|
||||||
@ -456,10 +463,15 @@ void romp_device::execute_run()
|
|||||||
m_icount -= 3;
|
m_icount -= 3;
|
||||||
break;
|
break;
|
||||||
case 0x96: // mfs: move from scr
|
case 0x96: // mfs: move from scr
|
||||||
if (R2 == IAR)
|
if (!(m_scr[ICS] & ICS_US) || R2 == MQ || R2 == CS)
|
||||||
m_gpr[R3] = updated_iar;
|
{
|
||||||
|
if (R2 == IAR)
|
||||||
|
m_gpr[R3] = updated_iar;
|
||||||
|
else
|
||||||
|
m_gpr[R3] = m_scr[R2];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_gpr[R3] = m_scr[R2];
|
program_check(PCS_PCK | PCS_PIE);
|
||||||
m_icount--;
|
m_icount--;
|
||||||
break;
|
break;
|
||||||
case 0x97: // setsb: set scr bit
|
case 0x97: // setsb: set scr bit
|
||||||
@ -588,8 +600,30 @@ void romp_device::execute_run()
|
|||||||
m_icount -= 2;
|
m_icount -= 2;
|
||||||
break;
|
break;
|
||||||
case 0xb6: // d: divide step
|
case 0xb6: // d: divide step
|
||||||
// m_icount -= 2;
|
{
|
||||||
fatalerror("divide step (%s)\n", machine().describe_context());
|
s64 sum = (s64(s32(m_gpr[R2])) << 1) | (m_scr[MQ] >> 31);
|
||||||
|
|
||||||
|
if (BIT(m_gpr[R2], 31) == BIT(m_gpr[R3], 31))
|
||||||
|
sum -= s32(m_gpr[R3]);
|
||||||
|
else
|
||||||
|
sum += s32(m_gpr[R3]);
|
||||||
|
|
||||||
|
// update remainder
|
||||||
|
m_gpr[R2] = sum;
|
||||||
|
|
||||||
|
// update quotient
|
||||||
|
m_scr[MQ] <<= 1;
|
||||||
|
if (BIT(sum, 32) == BIT(m_gpr[R3], 31))
|
||||||
|
{
|
||||||
|
m_scr[MQ] |= 1;
|
||||||
|
m_scr[CS] |= CS_C;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overflow test
|
||||||
|
if (BIT(sum, 32) == BIT(m_gpr[R2], 31))
|
||||||
|
m_scr[CS] |= CS_O;
|
||||||
|
}
|
||||||
|
m_icount -= 2;
|
||||||
break;
|
break;
|
||||||
case 0xb8: // sr: shift right
|
case 0xb8: // sr: shift right
|
||||||
m_gpr[R2] >>= (m_gpr[R3] & 63);
|
m_gpr[R2] >>= (m_gpr[R3] & 63);
|
||||||
@ -670,8 +704,40 @@ void romp_device::execute_run()
|
|||||||
flags_log(m_gpr[R2]);
|
flags_log(m_gpr[R2]);
|
||||||
break;
|
break;
|
||||||
case 0xe6: // m: multiply step
|
case 0xe6: // m: multiply step
|
||||||
// m_icount -= 3;
|
{
|
||||||
fatalerror("multiply step (%s)\n", machine().describe_context());
|
s64 sum = s32(m_gpr[R2]);
|
||||||
|
|
||||||
|
if (m_scr[CS] & CS_C)
|
||||||
|
{
|
||||||
|
// no carry
|
||||||
|
switch (m_scr[MQ] & 3)
|
||||||
|
{
|
||||||
|
case 1: sum += s32(m_gpr[R3]); break;
|
||||||
|
case 2: sum -= s64(s32(m_gpr[R3])) * 2; break;
|
||||||
|
case 3: sum -= s32(m_gpr[R3]); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// carry
|
||||||
|
switch (m_scr[MQ] & 3)
|
||||||
|
{
|
||||||
|
case 0: sum += s32(m_gpr[R3]); break;
|
||||||
|
case 1: sum += s64(s32(m_gpr[R3])) * 2; break;
|
||||||
|
case 2: sum -= s32(m_gpr[R3]); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update carry flag
|
||||||
|
if (m_scr[MQ] & 2)
|
||||||
|
m_scr[CS] &= ~CS_C;
|
||||||
|
else
|
||||||
|
m_scr[CS] |= CS_C;
|
||||||
|
|
||||||
|
m_scr[MQ] = (sum << 30) | (m_scr[MQ] >> 2);
|
||||||
|
m_gpr[R2] = sum >> 2;
|
||||||
|
}
|
||||||
|
m_icount -= 3;
|
||||||
break;
|
break;
|
||||||
case 0xe7: // x: exclusive or
|
case 0xe7: // x: exclusive or
|
||||||
m_gpr[R2] ^= m_gpr[R3];
|
m_gpr[R2] ^= m_gpr[R3];
|
||||||
@ -744,17 +810,23 @@ void romp_device::execute_run()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: // wait: wait
|
case 0xf0: // wait: wait
|
||||||
// if (m_branch_state == BRANCH)
|
if (!(m_scr[ICS] & ICS_US))
|
||||||
// program_check(PCS_PCK | PCS_IOC);
|
{
|
||||||
fatalerror("wait (%s)\n", machine().describe_context());
|
if (m_branch_state != BRANCH)
|
||||||
|
fatalerror("wait (%s)\n", machine().describe_context());
|
||||||
|
else
|
||||||
|
program_check(PCS_PCK | PCS_IOC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
program_check(PCS_PCK | PCS_PIE);
|
||||||
break;
|
break;
|
||||||
case 0xf1: // ae: add extended
|
case 0xf1: // ae: add extended
|
||||||
flags_add(m_gpr[R2], m_gpr[R3] + bool(m_scr[CS] & CS_C));
|
flags_add(m_gpr[R2], m_gpr[R3] + bool(m_scr[CS] & CS_C));
|
||||||
m_gpr[R2] += m_gpr[R3] + bool(m_scr[CS] & CS_C);
|
m_gpr[R2] += m_gpr[R3] + bool(m_scr[CS] & CS_C);
|
||||||
break;
|
break;
|
||||||
case 0xf2: // se: subtract extended
|
case 0xf2: // se: subtract extended
|
||||||
flags_sub(m_gpr[R2], m_gpr[R3] + bool(m_scr[CS] & CS_C));
|
flags_add(m_gpr[R2], ~m_gpr[R3] + bool(m_scr[CS] & CS_C));
|
||||||
m_gpr[R2] -= m_gpr[R3] + bool(m_scr[CS] & CS_C);
|
m_gpr[R2] += ~m_gpr[R3] + bool(m_scr[CS] & CS_C);
|
||||||
break;
|
break;
|
||||||
case 0xf3: // ca16: compute address 16-bit
|
case 0xf3: // ca16: compute address 16-bit
|
||||||
m_gpr[R2] = (m_gpr[R3] & 0xffff'0000U) | (u16(m_gpr[R2]) + u16(m_gpr[R3]));
|
m_gpr[R2] = (m_gpr[R3] & 0xffff'0000U) | (u16(m_gpr[R2]) + u16(m_gpr[R3]));
|
||||||
@ -830,17 +902,22 @@ void romp_device::set_scr(unsigned scr, u32 data)
|
|||||||
|
|
||||||
LOG("set_scr %s data 0x%08x (%s)\n", scr_names[scr], data, machine().describe_context());
|
LOG("set_scr %s data 0x%08x (%s)\n", scr_names[scr], data, machine().describe_context());
|
||||||
|
|
||||||
switch (scr)
|
if (!(m_scr[ICS] & ICS_US) || scr == MQ || scr == CS)
|
||||||
{
|
{
|
||||||
case ICS:
|
switch (scr)
|
||||||
space(bool(data & ICS_TM)).cache(m_mem);
|
{
|
||||||
break;
|
case ICS:
|
||||||
|
space(bool(data & ICS_TM)).cache(m_mem);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scr[scr] = data;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
m_scr[scr] = data;
|
program_check(PCS_PCK | PCS_PIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void romp_device::execute_set_input(int irqline, int state)
|
void romp_device::execute_set_input(int irqline, int state)
|
||||||
@ -925,7 +1002,7 @@ void romp_device::flags_sub(u32 const op1, u32 const op2)
|
|||||||
{
|
{
|
||||||
u32 const result = op1 - op2;
|
u32 const result = op1 - op2;
|
||||||
|
|
||||||
m_scr[CS] &= ~(CS_L | CS_E | CS_G | CS_C | CS_O);
|
m_scr[CS] &= ~(CS_L | CS_E | CS_G | CS_O);
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
m_scr[CS] |= CS_E;
|
m_scr[CS] |= CS_E;
|
||||||
@ -935,8 +1012,10 @@ void romp_device::flags_sub(u32 const op1, u32 const op2)
|
|||||||
else
|
else
|
||||||
m_scr[CS] |= CS_G;
|
m_scr[CS] |= CS_G;
|
||||||
|
|
||||||
// carry
|
// borrow
|
||||||
if ((!BIT(op2, 31) && BIT(op1, 31)) || (BIT(result, 31) && (!BIT(op2, 31) || BIT(op1, 31))))
|
if ((!BIT(op2, 31) && BIT(op1, 31)) || (BIT(result, 31) && (!BIT(op2, 31) || BIT(op1, 31))))
|
||||||
|
m_scr[CS] &= ~CS_C;
|
||||||
|
else
|
||||||
m_scr[CS] |= CS_C;
|
m_scr[CS] |= CS_C;
|
||||||
|
|
||||||
// overflow
|
// overflow
|
||||||
|
Loading…
Reference in New Issue
Block a user