mb86235: some more progress (nw)

This commit is contained in:
Ville Linde 2016-12-21 01:30:09 +02:00
parent e6155387a0
commit 667c8ea68e
5 changed files with 196 additions and 27 deletions

View File

@ -166,6 +166,7 @@ void mb86235_device::device_start()
state_add(MB86235_MB6, "MB6", m_core->mb[6]).formatstr("%08X");
state_add(MB86235_MB7, "MB7", m_core->mb[7]).formatstr("%08X");
state_add(STATE_GENPC, "GENPC", m_core->pc ).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_core->pc).noshow();
m_icountptr = &m_core->icount;
@ -261,7 +262,17 @@ bool mb86235_device::is_fifoin_full()
uint64_t mb86235_device::fifoout0_r()
{
#if ENABLE_DRC
fatalerror("fifoout0_r");
if (m_core->fifoout0.num == 0)
{
fatalerror("fifoout0_r: reading from empty fifo");
}
uint64_t data = m_core->fifoout0.data[m_core->fifoout0.rpos];
m_core->fifoout0.rpos++;
m_core->fifoout0.rpos &= FIFOOUT0_SIZE - 1;
m_core->fifoout0.num--;
return data;
#else
return 0;
#endif

View File

@ -45,7 +45,6 @@ public:
void unimplemented_op();
void unimplemented_alu();
void unimplemented_control();
void unimplemented_xfer1();
void unimplemented_double_xfer1();
void unimplemented_double_xfer2();
void pcs_overflow();

View File

@ -115,12 +115,6 @@ static void cfunc_unimplemented_control(void *param)
cpu->unimplemented_control();
}
static void cfunc_unimplemented_xfer1(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->unimplemented_xfer1();
}
static void cfunc_unimplemented_double_xfer1(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
@ -168,13 +162,6 @@ void mb86235_device::unimplemented_control()
fatalerror("MB86235: PC=%08X: Unimplemented control %02X\n", m_core->pc, cop);
}
void mb86235_device::unimplemented_xfer1()
{
uint64_t op = m_core->arg64;
printf("MB86235: PC=%08X: Unimplemented xfer1 %04X%08X\n", m_core->pc, (uint32_t)(op >> 32), (uint32_t)(op));
fatalerror("MB86235: PC=%08X: Unimplemented xfer1 %04X%08X\n", m_core->pc, (uint32_t)(op >> 32), (uint32_t)(op));
}
void mb86235_device::unimplemented_double_xfer1()
{
uint64_t op = m_core->arg64;
@ -452,6 +439,7 @@ void mb86235_device::static_generate_fifo()
block->end();
// read fifo in
// I0 = return value
block = m_drcuml->begin_block(32);
alloc_handle(m_drcuml.get(), &m_read_fifo_in, "read_fifo_in");
UML_HANDLE(block, *m_read_fifo_in);
@ -466,10 +454,16 @@ void mb86235_device::static_generate_fifo()
block->end();
// write fifo out0
// I0 = input value
block = m_drcuml->begin_block(32);
alloc_handle(m_drcuml.get(), &m_write_fifo_out0, "write_fifo_out0");
UML_HANDLE(block, *m_write_fifo_out0);
// TODO
UML_MOV(block, I1, FIFOOUT0_WPOS);
UML_STORE(block, m_core->fifoout0.data, I1, I0, SIZE_QWORD, SCALE_x8);
UML_ADD(block, I1, I1, 1);
UML_AND(block, I1, I1, FIFOOUT0_SIZE - 1);
UML_MOV(block, FIFOOUT0_WPOS, I1);
UML_ADD(block, FIFOOUT0_NUM, FIFOOUT0_NUM, 1);
UML_RET(block);
block->end();
@ -637,6 +631,9 @@ void mb86235_device::generate_ea(drcuml_block *block, compiler_state *compiler,
switch (md)
{
case 0x0: // @ARx
UML_MOV(block, I0, AR(arx));
break;
case 0x1: // @ARx++
UML_MOV(block, I0, AR(arx));
UML_ADD(block, AR(arx), AR(arx), 1);
@ -670,6 +667,11 @@ void mb86235_device::generate_reg_read(drcuml_block *block, compiler_state *comp
UML_MOV(block, dst, AR(reg & 7));
break;
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
// AB0-7
UML_MOV(block, dst, AB(reg & 7));
break;
case 0x30: // PR
UML_LOAD(block, dst, m_core->pr, PRP, SIZE_DWORD, SCALE_x4);
break;
@ -731,6 +733,11 @@ void mb86235_device::generate_reg_write(drcuml_block *block, compiler_state *com
UML_STORE(block, m_core->pr, PWP, src, SIZE_DWORD, SCALE_x4);
break;
case 0x32: // FO0
UML_MOV(block, I0, src);
UML_CALLH(block, *m_write_fifo_out0);
break;
case 0x34: // PDR
UML_MOV(block, mem(&m_core->pdr), src);
break;
@ -845,13 +852,27 @@ bool mb86235_device::generate_opcode(drcuml_block *block, compiler_state *compil
// insert FIFO OUT0 check if needed
if (fifoout0_check)
{
fatalerror("generate_opcode: fifoout0_check");
code_label not_full = compiler->labelnum++;
UML_CMP(block, FIFOOUT0_NUM, FIFOOUT0_SIZE - 1);
UML_JMPc(block, COND_L, not_full);
UML_MOV(block, mem(&m_core->icount), 0);
UML_EXH(block, *m_out_of_cycles, desc->pc);
UML_LABEL(block, not_full);
}
// insert FIFO OUT1 check if needed
if (fifoout1_check)
{
fatalerror("generate_opcode: fifoout1_check");
code_label not_full = compiler->labelnum++;
UML_CMP(block, FIFOOUT1_NUM, FIFOOUT1_SIZE - 1);
UML_JMPc(block, COND_L, not_full);
UML_MOV(block, mem(&m_core->icount), 0);
UML_EXH(block, *m_out_of_cycles, desc->pc);
UML_LABEL(block, not_full);
}
@ -1256,6 +1277,20 @@ void mb86235_device::generate_alu(drcuml_block *block, compiler_state *compiler,
UML_MOV(block, alutemp ? mem(&m_core->alutemp) : get_alu_output(io), I0);
break;
case 0x12: // SUB
generate_alumul_input(block, compiler, desc, i2, I1, false, false);
UML_SUB(block, I0, I1, get_alu1_input(i1));
if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, FLAGS_AZ);
if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, FLAGS_AN);
UML_CMP(block, I0, 0xff800000);
UML_MOVc(block, COND_L, I0, 0xff800000);
if (AV_CALC_REQUIRED) UML_MOVc(block, COND_L, FLAGS_AV, 1);
UML_CMP(block, I0, 0x007fffff);
UML_MOVc(block, COND_G, I0, 0x007fffff);
if (AV_CALC_REQUIRED) UML_MOVc(block, COND_G, FLAGS_AV, 1);
UML_MOV(block, alutemp ? mem(&m_core->alutemp) : get_alu_output(io), I0);
break;
case 0x14: // CMP
generate_alumul_input(block, compiler, desc, i2, I1, false, false);
UML_SUB(block, I0, I1, get_alu1_input(i1));
@ -1409,6 +1444,15 @@ void mb86235_device::generate_branch_target(drcuml_block *block, compiler_state
UML_MOV(block, I0, AR(reg));
break;
}
case 0x4: // Axx
{
int reg = (ef2 >> 6) & 7;
if (ef2 & 0x400)
UML_MOV(block, I0, AB(reg));
else
UML_MOV(block, I0, AA(reg));
break;
}
default:
fatalerror("generate_branch_target: type %02X at %08X", type, desc->pc);
break;
@ -1590,9 +1634,67 @@ void mb86235_device::generate_control(drcuml_block *block, compiler_state *compi
void mb86235_device::generate_xfer1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
{
UML_MOV(block, mem(&m_core->pc), desc->pc);
UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
UML_CALLC(block, cfunc_unimplemented_xfer1, this);
uint64_t opcode = desc->opptr.q[0];
int dr = (opcode >> 12) & 0x7f;
int sr = (opcode >> 19) & 0x7f;
int md = opcode & 0xf;
int ary = (opcode >> 4) & 7;
int disp5 = (opcode >> 7) & 0x1f;
int trm = (opcode >> 26) & 1;
// int dir = (opcode >> 25) & 1;
if (trm == 0)
{
if (sr == 0x58)
{
// MOV1 #imm12, DR
generate_reg_write(block, compiler, desc, dr & 0x3f, uml::parameter(opcode & 0xfff));
}
else
{
if ((sr & 0x40) == 0)
{
generate_reg_read(block, compiler, desc, sr & 0x3f, I1);
}
else
{
generate_ea(block, compiler, desc, md, sr & 7, ary, disp5);
if (sr & 0x20) // RAM-B
{
UML_SHL(block, I0, I0, 2);
UML_READ(block, I1, I0, SIZE_DWORD, SPACE_IO);
}
else // RAM-A
{
UML_CALLH(block, *m_read_abus);
}
}
if ((dr & 0x40) == 0)
{
generate_reg_write(block, compiler, desc, dr & 0x3f, I1);
}
else
{
generate_ea(block, compiler, desc, md, dr & 7, ary, disp5);
if (dr & 0x20) // RAM-B
{
UML_SHL(block, I0, I0, 2);
UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_IO);
}
else // RAM-A
{
UML_CALLH(block, *m_write_abus);
}
}
}
}
else
{
// external transfer
fatalerror("generate_xfer1 MOV1 at %08X (%08X%08X)", desc->pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
}
}
void mb86235_device::generate_double_xfer1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)

View File

@ -646,12 +646,61 @@ void mb86235_frontend::describe_ea(opcode_desc &desc, int md, int arx, int ary,
void mb86235_frontend::describe_xfer1(opcode_desc &desc)
{
uint64_t opcode = desc.opptr.q[0];
fatalerror("mb86235_frontend: describe_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
int dr = (opcode >> 12) & 0x7f;
int sr = (opcode >> 19) & 0x7f;
int md = opcode & 0xf;
int ary = (opcode >> 4) & 7;
int disp5 = (opcode >> 7) & 0x1f;
int trm = (opcode >> 26) & 1;
int dir = (opcode >> 25) & 1;
if (trm == 0)
{
if ((sr & 0x40) == 0)
{
describe_reg_read(desc, sr & 0x3f);
}
else if (sr == 0x58)
{
// MOV1 #imm12, DR
}
else
{
describe_ea(desc, md, sr & 7, ary, disp5);
desc.flags |= OPFLAG_READS_MEMORY;
}
if ((dr & 0x40) == 0)
{
describe_reg_write(desc, dr & 0x3f);
}
else
{
describe_ea(desc, md, dr & 7, ary, disp5);
desc.flags |= OPFLAG_WRITES_MEMORY;
}
}
else
{
// external transfer
if (dir == 0)
{
describe_reg_read(desc, dr & 0x3f);
desc.flags |= OPFLAG_WRITES_MEMORY;
}
else
{
describe_reg_write(desc, dr & 0x3f);
desc.flags |= OPFLAG_READS_MEMORY;
}
}
}
void mb86235_frontend::describe_double_xfer1(opcode_desc &desc)
{
uint64_t opcode = desc.opptr.q[0];
fatalerror("mb86235_frontend: describe_double_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
}
@ -733,7 +782,7 @@ void mb86235_frontend::describe_xfer3(opcode_desc &desc)
int ary = (opcode >> 4) & 7;
int md = opcode & 0xf;
switch (dr >> 4)
switch (dr >> 5)
{
case 0:
case 1: // reg

View File

@ -831,10 +831,18 @@ WRITE32_MEMBER(model2_state::copro_fifo_w)
else if (m_dsp_type == DSP_TYPE_TGPX4)
{
if (m_tgpx4->is_fifoin_full())
printf("trying to push to full fifo!\n");
// printf("push %08X at %08X\n", data, space.device().safe_pc());
m_tgpx4->fifoin_w(data);
{
/* Writing to full FIFO causes the i960 to enter wait state */
downcast<i960_cpu_device &>(space.device()).i960_stall();
/* spin the main cpu and let the TGP catch up */
space.device().execute().spin_until_time(attotime::from_usec(100));
printf("write stalled\n");
}
else
{
// printf("push %08X at %08X\n", data, space.device().safe_pc());
m_tgpx4->fifoin_w(data);
}
}
}
}