mb86235: fix PR updates (nw)

This commit is contained in:
Ville Linde 2016-12-18 22:52:40 +02:00
parent c7b853d689
commit 4dceca5389
3 changed files with 81 additions and 39 deletions

View File

@ -24,12 +24,14 @@ class mb86235_frontend;
#define OP_USERFLAG_FIFOOUT1 0x4
#define OP_USERFLAG_REPEAT 0x8
#define OP_USERFLAG_REPEATED_OP 0x10
#define OP_USERFLAG_ALU_PRP_UPDATE 0x100
#define OP_USERFLAG_MUL_PRP_UPDATE 0x200
#define OP_USERFLAG_XFER_PRP_UPDATE 0x400
#define OP_USERFLAG_ALU_PWP_UPDATE 0x800
#define OP_USERFLAG_MUL_PWP_UPDATE 0x1000
#define OP_USERFLAG_XFER_PWP_UPDATE 0x2000
#define OP_USERFLAG_PR_MASK 0x300
#define OP_USERFLAG_PR_INC 0x100
#define OP_USERFLAG_PR_DEC 0x200
#define OP_USERFLAG_PR_ZERO 0x300
#define OP_USERFLAG_PW_MASK 0xc00
#define OP_USERFLAG_PW_INC 0x400
#define OP_USERFLAG_PW_DEC 0x800
#define OP_USERFLAG_PW_ZERO 0xc00
class mb86235_device : public cpu_device

View File

@ -18,7 +18,6 @@
/*
TODO:
- check jump condition before parallel ALU/MUL (flags!)
- PR update after all operations (double update at 0x26)
*/
@ -673,12 +672,6 @@ void mb86235_device::generate_reg_read(drcuml_block *block, compiler_state *comp
case 0x30: // PR
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
if (!(desc->userflags & OP_USERFLAG_ALU_PRP_UPDATE) && !(desc->userflags & OP_USERFLAG_MUL_PRP_UPDATE)) // alu/mul have priority on PRP update
{
UML_ADD(block, PRP, PRP, 1);
UML_CMP(block, PRP, 24);
UML_MOVc(block, COND_GE, PRP, 0);
}
break;
case 0x31: // FI
@ -736,12 +729,6 @@ void mb86235_device::generate_reg_write(drcuml_block *block, compiler_state *com
case 0x30: // PR
UML_STORE(block, m_core->pr, PWP, src, SIZE_DWORD, SCALE_x4);
if (!(desc->userflags & OP_USERFLAG_ALU_PWP_UPDATE) && !(desc->userflags & OP_USERFLAG_MUL_PWP_UPDATE)) // alu/mul have priority on PWP update
{
UML_ADD(block, PWP, PWP, 1);
UML_CMP(block, PWP, 24);
UML_MOVc(block, COND_GE, PWP, 0);
}
break;
case 0x34: // PDR
@ -966,6 +953,47 @@ bool mb86235_device::generate_opcode(drcuml_block *block, compiler_state *compil
return false;
}
// update PR and PW if needed
if ((desc->userflags & OP_USERFLAG_PR_MASK) != 0)
{
switch ((desc->userflags & OP_USERFLAG_PR_MASK) >> 8)
{
case 1: // PR++
UML_ADD(block, PRP, PRP, 1);
UML_CMP(block, PRP, 24);
UML_MOVc(block, COND_GE, PRP, 0);
break;
case 2: // PR--
UML_SUB(block, PRP, PRP, 1);
UML_CMP(block, PRP, 0);
UML_MOVc(block, COND_L, PRP, 23);
break;
case 3: // PR#0
UML_MOV(block, PRP, 0);
break;
}
}
if ((desc->userflags & OP_USERFLAG_PW_MASK) != 0)
{
switch ((desc->userflags & OP_USERFLAG_PW_MASK) >> 10)
{
case 1: // PW++
UML_ADD(block, PWP, PWP, 1);
UML_CMP(block, PWP, 24);
UML_MOVc(block, COND_GE, PWP, 0);
break;
case 2: // PW--
UML_SUB(block, PWP, PWP, 1);
UML_CMP(block, PWP, 0);
UML_MOVc(block, COND_L, PWP, 23);
break;
case 3: // PW#0
UML_MOV(block, PWP, 0);
break;
}
}
// handle repeat
if (desc->userflags & OP_USERFLAG_REPEATED_OP)
{
@ -1007,26 +1035,10 @@ void mb86235_device::generate_alumul_input(drcuml_block *block, compiler_state *
break;
case 0x10: // PR
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
UML_ADD(block, PWP, PWP, 1);
UML_CMP(block, PWP, 24);
UML_MOVc(block, COND_GE, PWP, 0);
break;
case 0x11: // PR++
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
UML_ADD(block, PRP, PRP, 1);
UML_CMP(block, PRP, 24);
UML_MOVc(block, COND_GE, PRP, 0);
break;
case 0x12: // PR--
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
UML_SUB(block, PRP, PRP, 1);
UML_CMP(block, PRP, 0);
UML_MOVc(block, COND_L, PRP, 23);
break;
case 0x13: // PR#0
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
UML_MOV(block, PRP, 0);
break;
case 0x18: // 0 / -1.0E+0

View File

@ -138,10 +138,19 @@ void mb86235_frontend::describe_alu_input(opcode_desc &desc, int reg)
break;
case 0x10: // PR
break;
case 0x11: // PR++
desc.userflags &= ~OP_USERFLAG_PR_MASK;
desc.userflags |= OP_USERFLAG_PR_INC;
break;
case 0x12: // PR--
desc.userflags &= ~OP_USERFLAG_PR_MASK;
desc.userflags |= OP_USERFLAG_PR_DEC;
break;
case 0x13: // PR#0
desc.userflags |= OP_USERFLAG_ALU_PRP_UPDATE;
desc.userflags &= ~OP_USERFLAG_PR_MASK;
desc.userflags |= OP_USERFLAG_PR_ZERO;
break;
@ -163,10 +172,25 @@ void mb86235_frontend::describe_mul_input(opcode_desc &desc, int reg)
break;
case 0x10: // PR
break;
case 0x11: // PR++
if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
{
desc.userflags |= OP_USERFLAG_PR_INC;
}
break;
case 0x12: // PR--
if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
{
desc.userflags |= OP_USERFLAG_PR_DEC;
}
break;
case 0x13: // PR#0
desc.userflags |= OP_USERFLAG_MUL_PRP_UPDATE;
if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
{
desc.userflags |= OP_USERFLAG_PR_ZERO;
}
break;
default:
@ -248,7 +272,10 @@ void mb86235_frontend::describe_reg_read(opcode_desc &desc, int reg)
break;
case 0x30: // PR
desc.userflags |= OP_USERFLAG_XFER_PRP_UPDATE;
if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU and MUL PR updates have higher priority
{
desc.userflags |= OP_USERFLAG_PR_INC;
}
break;
}
}
@ -304,7 +331,8 @@ void mb86235_frontend::describe_reg_write(opcode_desc &desc, int reg)
break;
case 0x30: // PR
desc.userflags |= OP_USERFLAG_XFER_PWP_UPDATE;
desc.userflags &= ~OP_USERFLAG_PW_MASK;
desc.userflags |= OP_USERFLAG_PW_INC;
break;
}
}