diff options
Diffstat (limited to 'src/devices/cpu/unsp/unspdrc.cpp')
-rw-r--r-- | src/devices/cpu/unsp/unspdrc.cpp | 135 |
1 files changed, 88 insertions, 47 deletions
diff --git a/src/devices/cpu/unsp/unspdrc.cpp b/src/devices/cpu/unsp/unspdrc.cpp index a34d20f8a7e..a8162b82b22 100644 --- a/src/devices/cpu/unsp/unspdrc.cpp +++ b/src/devices/cpu/unsp/unspdrc.cpp @@ -1,3 +1,4 @@ + // license:BSD-3-Clause // copyright-holders:Ryan Holtz @@ -82,6 +83,20 @@ static void ccfunc_log_write(void *param) } #endif +void unsp_device::cfunc_muls() +{ + const uint32_t op = m_core->m_arg0; + const uint16_t size = ((op >> 3) & 15) ? ((op >> 3) & 15) : 16; + const uint16_t rd = (op >> 9) & 7; + const uint16_t rs = op & 7; + execute_muls_ss(rd, rs, size); +} + +static void ccfunc_muls(void *param) +{ + ((unsp_device *)param)->cfunc_muls(); +} + /*************************************************************************** CACHE MANAGEMENT ***************************************************************************/ @@ -139,7 +154,7 @@ void unsp_device::code_compile_block(offs_t pc) const opcode_desc *seqhead, *seqlast; bool override = false; - g_profiler.start(PROFILER_DRC_COMPILE); + auto profile = g_profiler.start(PROFILER_DRC_COMPILE); /* get a description of this sequence */ const opcode_desc *desclist = m_drcfe->describe_code(pc); @@ -189,7 +204,7 @@ void unsp_device::code_compile_block(offs_t pc) } /* validate this code block if we're not pointing into ROM */ - if (m_program->get_write_ptr(seqhead->physpc) != nullptr) + if (m_program.space().get_write_ptr(seqhead->physpc) != nullptr) generate_checksum_block(block, compiler, seqhead, seqlast); /* label this instruction, if it may be jumped to locally */ @@ -215,7 +230,6 @@ void unsp_device::code_compile_block(offs_t pc) /* end the sequence */ block.end(); - g_profiler.stop(); succeeded = true; } catch (drcuml_block::abort_compilation &) @@ -399,19 +413,13 @@ void unsp_device::static_generate_trigger_fiq() alloc_handle(*m_drcuml, m_trigger_fiq, "trigger_fiq"); UML_HANDLE(block, *m_trigger_fiq); - UML_OR(block, I0, mem(&m_core->m_fiq), mem(&m_core->m_irq)); - UML_TEST(block, I0, 1); - UML_RETc(block, uml::COND_NZ); - UML_TEST(block, mem(&m_core->m_enable_fiq), 1); UML_RETc(block, uml::COND_Z); - UML_MOV(block, mem(&m_core->m_fiq), 1); + UML_TEST(block, mem(&m_core->m_fiq), 1); + UML_RETc(block, uml::COND_NZ); - UML_MOV(block, I0, mem(&m_core->m_sb)); - UML_MOV(block, I1, mem(&m_core->m_irq)); - UML_STORE(block, (void*)m_core->m_saved_sb, I1, I0, SIZE_DWORD, SCALE_x4); - UML_MOV(block, mem(&m_core->m_sb), mem(&m_core->m_saved_sb[2])); + UML_MOV(block, mem(&m_core->m_fiq), 1); UML_MOV(block, I0, mem(&m_core->m_r[REG_SP])); @@ -440,21 +448,34 @@ void unsp_device::static_generate_trigger_irq() /* begin generating */ drcuml_block &block(m_drcuml->begin_block(256)); + uml::code_label skip_ine = 1; + /* generate a hash jump via the current mode and PC */ alloc_handle(*m_drcuml, m_trigger_irq, "trigger_irq"); UML_HANDLE(block, *m_trigger_irq); - UML_OR(block, I0, mem(&m_core->m_fiq), mem(&m_core->m_irq)); - UML_TEST(block, I0, 1); + // If INE is 0 and IRQ is 1, abort + UML_XOR(block, I1, mem(&m_core->m_irq), 1); + UML_AND(block, I1, I1, mem(&m_core->m_ine)); UML_RETc(block, uml::COND_NZ); - UML_TEST(block, mem(&m_core->m_enable_irq), 1); - UML_RETc(block, uml::COND_Z); + // If INE is 0 and IRQ is 0, we have a valid IRQ + UML_TEST(block, mem(&m_core->m_ine), 1); + UML_JMPc(block, uml::COND_Z, skip_ine); + + // If INE is 1 and IRQ line is < PRI, abort + UML_CMP(block, I0, mem(&m_core->m_pri)); + UML_RETc(block, uml::COND_LE); + + // Update our current interrupt priority + UML_MOV(block, mem(&m_core->m_pri), I0); + + UML_LABEL(block, skip_ine); UML_MOV(block, mem(&m_core->m_irq), 1); - UML_MOV(block, mem(&m_core->m_saved_sb[0]), mem(&m_core->m_sb)); - UML_MOV(block, mem(&m_core->m_sb), mem(&m_core->m_saved_sb[1])); + UML_TEST(block, mem(&m_core->m_enable_irq), 1); + UML_RETc(block, uml::COND_Z); UML_MOV(block, I0, mem(&m_core->m_r[REG_SP])); UML_MOV(block, I1, mem(&m_core->m_r[REG_PC])); @@ -504,7 +525,7 @@ void unsp_device::generate_checksum_block(drcuml_block &block, compiler_state &c } /* full verification; sum up everything */ - void *memptr = m_program->get_write_ptr(seqhead->physpc); + void *memptr = m_program.space().get_write_ptr(seqhead->physpc); UML_LOAD(block, I0, memptr, 0, SIZE_WORD, SCALE_x2); uint32_t sum = seqhead->opptr.w[0]; for (int i = 1; i < seqhead->length; i++) @@ -517,7 +538,7 @@ void unsp_device::generate_checksum_block(drcuml_block &block, compiler_state &c { if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { - memptr = m_program->get_write_ptr(curdesc->physpc); + memptr = m_program.space().get_write_ptr(curdesc->physpc); UML_LOAD(block, I1, memptr, 0, SIZE_WORD, SCALE_x2); UML_ADD(block, I0, I0, I1); sum += curdesc->opptr.w[0]; @@ -589,7 +610,7 @@ void unsp_device::generate_sequence_instruction(drcuml_block &block, compiler_st UML_MAPVAR(block, MAPVAR_PC, desc->pc); /* if we are debugging, call the debugger */ - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + if (debugger_enabled()) { //save_fast_iregs(block); UML_DEBUG(block, desc->pc); @@ -634,12 +655,9 @@ void unsp_device::generate_add_lpc(drcuml_block &block, int32_t offset) void unsp_device::generate_update_nzsc(drcuml_block &block) { - UML_XOR(block, I1, I1, 0x0000ffff); - UML_SEXT(block, I1, I1, SIZE_WORD); - UML_SEXT(block, I2, I2, SIZE_WORD); - UML_CMP(block, I2, I1); - UML_SETc(block, uml::COND_L, I1); - UML_ROLINS(block, mem(&m_core->m_r[REG_SR]), I1, UNSP_S_SHIFT, UNSP_S); + UML_XOR(block, I1, I1, I2); + UML_TEST(block, I1, 0x8000); + UML_SETc(block, uml::COND_NZ, I2); UML_TEST(block, I3, 0x8000); UML_SETc(block, uml::COND_NZ, I1); @@ -648,6 +666,9 @@ void unsp_device::generate_update_nzsc(drcuml_block &block) UML_TEST(block, I3, 0x10000); UML_SETc(block, uml::COND_NZ, I1); UML_ROLINS(block, mem(&m_core->m_r[REG_SR]), I1, UNSP_C_SHIFT, UNSP_C); + UML_CMP(block, I2, I1); + UML_SETc(block, uml::COND_NE, I1); + UML_ROLINS(block, mem(&m_core->m_r[REG_SR]), I1, UNSP_S_SHIFT, UNSP_S); UML_TEST(block, I3, 0x0000ffff); UML_SETc(block, uml::COND_Z, I1); @@ -692,8 +713,6 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const uint8_t lower_op = (op1 << 4) | op0; uml::code_label skip_branch = compiler.m_labelnum++; - uml::code_label clear_fiq = compiler.m_labelnum++; - uml::code_label clear_irq = compiler.m_labelnum++; uml::code_label reti_done = compiler.m_labelnum++; uml::code_label mul_opa_nohi = compiler.m_labelnum++; uml::code_label mul_opb_nohi = compiler.m_labelnum++; @@ -769,6 +788,20 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, UML_JMPc(block, uml::COND_NZ, skip_branch); break; + case 12: // JVC + UML_ROLAND(block, I0, mem(&m_core->m_r[REG_SR]), 32-UNSP_S_SHIFT, 1); + UML_ROLAND(block, I1, mem(&m_core->m_r[REG_SR]), 32-UNSP_N_SHIFT, 1); + UML_CMP(block, I0, I1); + UML_JMPc(block, uml::COND_NE, skip_branch); + break; + + case 13: // JVS + UML_ROLAND(block, I0, mem(&m_core->m_r[REG_SR]), 32-UNSP_S_SHIFT, 1); + UML_ROLAND(block, I1, mem(&m_core->m_r[REG_SR]), 32-UNSP_N_SHIFT, 1); + UML_CMP(block, I0, I1); + UML_JMPc(block, uml::COND_E, skip_branch); + break; + case 14: // JMP UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), 4); UML_MOV(block, I0, desc->targetpc); @@ -820,24 +853,13 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, UML_AND(block, mem(&m_core->m_r[REG_SP]), I0, 0x0000ffff); UML_TEST(block, mem(&m_core->m_fiq), 1); - UML_JMPc(block, uml::COND_NZ, clear_fiq); - UML_TEST(block, mem(&m_core->m_irq), 1); - UML_JMPc(block, uml::COND_NZ, clear_irq); - UML_JMP(block, reti_done); + UML_MOVc(block, uml::COND_NZ, mem(&m_core->m_fiq), 0); + UML_JMPc(block, uml::COND_NZ, reti_done); - UML_LABEL(block, clear_fiq); - UML_MOV(block, mem(&m_core->m_fiq), 0); - UML_MOV(block, mem(&m_core->m_saved_sb[2]), mem(&m_core->m_sb)); - UML_LOAD(block, mem(&m_core->m_sb), (void*)m_core->m_saved_sb, mem(&m_core->m_irq), SIZE_DWORD, SCALE_x4); - UML_JMP(block, reti_done); - - UML_LABEL(block, clear_irq); - UML_MOV(block, mem(&m_core->m_irq), 0); - UML_MOV(block, mem(&m_core->m_saved_sb[1]), mem(&m_core->m_sb)); - UML_MOV(block, mem(&m_core->m_sb), mem(&m_core->m_saved_sb[0])); + UML_TEST(block, mem(&m_core->m_irq), 1); + UML_MOVc(block, uml::COND_NZ, mem(&m_core->m_irq), 0); UML_LABEL(block, reti_done); - UML_MOV(block, mem(&m_core->m_curirq), 0); generate_branch(block, compiler, desc); } else // pop @@ -970,6 +992,14 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, UML_MOV(block, mem(&m_core->m_enable_fiq), 1); break; + case 4: + UML_MOV(block, mem(&m_core->m_fir_move), 1); + break; + + case 5: + UML_MOV(block, mem(&m_core->m_fir_move), 0); + break; + case 8: UML_MOV(block, mem(&m_core->m_enable_irq), 0); break; @@ -991,10 +1021,21 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, break; default: + logerror("unsp drc interrupt flags %02x\n", op & 0x3f); return false; } return true; + case 0x06: + case 0x07: + if (opa == 7) + return false; + + // MULS + UML_MOV(block, mem(&m_core->m_arg0), desc->opptr.w[0]); + UML_CALLC(block, ccfunc_muls, this); + return true; + default: return false; } @@ -1116,7 +1157,7 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, case 0x01: // imm16 { UML_MOV(block, I2, mem(&m_core->m_r[opb])); - const uint16_t r1 = m_pr16(desc->pc + 1); + const uint16_t r1 = m_cache.read_word(desc->pc + 1); generate_add_lpc(block, 1); UML_MOV(block, I1, r1); break; @@ -1125,7 +1166,7 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, case 0x02: // [imm16] { UML_MOV(block, I2, mem(&m_core->m_r[opb])); - const uint16_t r1 = m_pr16(desc->pc + 1); + const uint16_t r1 = m_cache.read_word(desc->pc + 1); generate_add_lpc(block, 1); UML_MOV(block, I0, r1); if (op0 != 0x0d) @@ -1137,7 +1178,7 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, { UML_MOV(block, I1, I2); UML_MOV(block, I2, mem(&m_core->m_r[opb])); - const uint16_t r2 = m_pr16(desc->pc + 1); + const uint16_t r2 = m_cache.read_word(desc->pc + 1); generate_add_lpc(block, 1); UML_MOV(block, I0, r2); break; |