summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp/unspdrc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/unsp/unspdrc.cpp')
-rw-r--r--src/devices/cpu/unsp/unspdrc.cpp58
1 files changed, 26 insertions, 32 deletions
diff --git a/src/devices/cpu/unsp/unspdrc.cpp b/src/devices/cpu/unsp/unspdrc.cpp
index 6a12a58a762..32011522c2e 100644
--- a/src/devices/cpu/unsp/unspdrc.cpp
+++ b/src/devices/cpu/unsp/unspdrc.cpp
@@ -414,19 +414,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]));
@@ -455,21 +449,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]));
@@ -707,8 +714,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++;
@@ -849,24 +854,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