mirror of
https://github.com/holub/mame
synced 2025-05-28 16:43:04 +03:00
-e132xs: Added subs to drc, fixes hidnctch fatalerror when selecting a difference, nw
This commit is contained in:
parent
483d1f49b2
commit
62aef15114
@ -179,10 +179,11 @@ protected:
|
||||
IS_SET = 1
|
||||
};
|
||||
|
||||
enum trap_or_int
|
||||
enum trap_exception_or_int
|
||||
{
|
||||
IS_TRAP = 0,
|
||||
IS_INT = 1
|
||||
IS_INT = 1,
|
||||
IS_EXCEPTION = 2
|
||||
};
|
||||
|
||||
enum is_timer
|
||||
@ -474,7 +475,7 @@ private:
|
||||
void generate_get_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <trap_or_int IS_INT> void generate_trap_or_int(drcuml_block *block);
|
||||
template <trap_exception_or_int TYPE> void generate_trap_exception_or_int(drcuml_block *block);
|
||||
void generate_int(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr);
|
||||
void generate_exception(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr);
|
||||
void generate_software(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
@ -573,7 +573,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO3);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO3);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io3);
|
||||
|
||||
int skip_int1 = labelnum++;
|
||||
@ -584,7 +584,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT1);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT1);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int1);
|
||||
|
||||
int skip_int2 = labelnum++;
|
||||
@ -595,7 +595,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT2);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT2);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int2);
|
||||
|
||||
int skip_int3 = labelnum++;
|
||||
@ -606,7 +606,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT3);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT3);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int3);
|
||||
|
||||
int skip_int4 = labelnum++;
|
||||
@ -617,7 +617,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT4);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT4);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int4);
|
||||
|
||||
int skip_io1 = labelnum++;
|
||||
@ -629,7 +629,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO1);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO1);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io1);
|
||||
|
||||
int skip_io2 = labelnum++;
|
||||
@ -641,7 +641,7 @@ void hyperstone_device::generate_interrupt_checks_no_timer(drcuml_block *block,
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO2);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO2);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io2);
|
||||
}
|
||||
|
||||
@ -656,7 +656,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO3);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO3);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io3);
|
||||
|
||||
int skip_timer_pri6 = labelnum++;
|
||||
@ -664,7 +664,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
UML_JMPc(block, uml::COND_NE, skip_timer_pri6);
|
||||
UML_MOV(block, mem(&m_timer_int_pending), 0);
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_TIMER);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_timer_pri6);
|
||||
|
||||
int skip_int1 = labelnum++;
|
||||
@ -675,7 +675,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT1);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT1);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int1);
|
||||
|
||||
int skip_timer_pri8 = labelnum++;
|
||||
@ -683,7 +683,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
UML_JMPc(block, uml::COND_NE, skip_timer_pri8);
|
||||
UML_MOV(block, mem(&m_timer_int_pending), 0);
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_TIMER);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_timer_pri8);
|
||||
|
||||
int skip_int2 = labelnum++;
|
||||
@ -694,7 +694,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT2);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT2);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int2);
|
||||
|
||||
int skip_timer_pri10 = labelnum++;
|
||||
@ -702,7 +702,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
UML_JMPc(block, uml::COND_NE, skip_timer_pri10);
|
||||
UML_MOV(block, mem(&m_timer_int_pending), 0);
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_TIMER);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_timer_pri10);
|
||||
|
||||
int skip_int3 = labelnum++;
|
||||
@ -713,7 +713,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT3);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT3);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int3);
|
||||
|
||||
int skip_timer_pri12 = labelnum++;
|
||||
@ -721,7 +721,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
UML_JMPc(block, uml::COND_NE, skip_timer_pri12);
|
||||
UML_MOV(block, mem(&m_timer_int_pending), 0);
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_TIMER);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_timer_pri12);
|
||||
|
||||
int skip_int4 = labelnum++;
|
||||
@ -732,7 +732,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_INT4);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_INT4);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_int4);
|
||||
|
||||
int skip_io1 = labelnum++;
|
||||
@ -744,7 +744,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO1);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO1);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io1);
|
||||
|
||||
int skip_io2 = labelnum++;
|
||||
@ -756,7 +756,7 @@ void hyperstone_device::generate_interrupt_checks_with_timer(drcuml_block *block
|
||||
generate_get_trap_addr(block, labelnum, TRAPNO_IO2);
|
||||
UML_MOV(block, mem(&m_drc_arg0), IRQ_IO2);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
generate_trap_or_int<IS_INT>(block);
|
||||
generate_trap_exception_or_int<IS_INT>(block);
|
||||
UML_LABEL(block, skip_io2);
|
||||
}
|
||||
|
||||
|
@ -241,8 +241,8 @@ void hyperstone_device::generate_set_global_register(drcuml_block *block, compil
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
|
||||
template <hyperstone_device::trap_or_int IS_INT>
|
||||
void hyperstone_device::generate_trap_or_int(drcuml_block *block)
|
||||
template <hyperstone_device::trap_exception_or_int TYPE>
|
||||
void hyperstone_device::generate_trap_exception_or_int(drcuml_block *block)
|
||||
{
|
||||
UML_ADD(block, I7, I7, mem(&m_clock_cycles_2));
|
||||
|
||||
@ -254,7 +254,7 @@ void hyperstone_device::generate_trap_or_int(drcuml_block *block)
|
||||
UML_MOVc(block, uml::COND_Z, I2, 16);
|
||||
UML_ADD(block, I3, I1, I2);
|
||||
|
||||
if (IS_INT)
|
||||
if (TYPE != IS_TRAP)
|
||||
UML_ROLINS(block, DRC_SR, 2, 21, 0x01e00000);
|
||||
else
|
||||
UML_ROLINS(block, DRC_SR, 6, 21, 0x01e00000);
|
||||
@ -269,7 +269,7 @@ void hyperstone_device::generate_trap_or_int(drcuml_block *block)
|
||||
UML_STORE(block, (void *)m_local_regs, I3, I4, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~(M_MASK | T_MASK));
|
||||
if (IS_INT)
|
||||
if (TYPE == IS_INT)
|
||||
UML_OR(block, DRC_SR, DRC_SR, (L_MASK | S_MASK | I_MASK));
|
||||
else
|
||||
UML_OR(block, DRC_SR, DRC_SR, (L_MASK | S_MASK));
|
||||
@ -1342,14 +1342,21 @@ void hyperstone_device::generate_sub(drcuml_block *block, compiler_state *compil
|
||||
|
||||
if (DST_GLOBAL)
|
||||
{
|
||||
UML_MOV(block, I4, dst_code);
|
||||
UML_MOV(block, I5, I2);
|
||||
generate_set_global_register(block, compiler, desc);
|
||||
|
||||
if (dst_code == PC_REGISTER)
|
||||
if (dst_code < 2)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, desc->targetpc);
|
||||
UML_MOV(block, I4, dst_code);
|
||||
UML_MOV(block, I5, I2);
|
||||
generate_set_global_register(block, compiler, desc);
|
||||
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, desc->targetpc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_STORE(block, (void *)m_global_regs, dst_code, I2, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1364,9 +1371,88 @@ void hyperstone_device::generate_sub(drcuml_block *block, compiler_state *compil
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
||||
void hyperstone_device::generate_subs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
printf("Unimplemented: generate_subs (%08x)\n", desc->pc);
|
||||
fflush(stdout);
|
||||
fatalerror(" ");
|
||||
UML_MOV(block, I7, mem(&m_clock_cycles_1));
|
||||
|
||||
uint16_t op = desc->opptr.w[0];
|
||||
const uint32_t src_code = op & 0xf;
|
||||
const uint32_t dst_code = (op & 0xf0) >> 4;
|
||||
|
||||
generate_check_delay_pc(block, compiler, desc);
|
||||
|
||||
if (!SRC_GLOBAL || !DST_GLOBAL)
|
||||
UML_ROLAND(block, I3, DRC_SR, 7, 0x7f);
|
||||
|
||||
if (SRC_GLOBAL)
|
||||
{
|
||||
if (src_code == SR_REGISTER)
|
||||
UML_AND(block, I0, DRC_SR, 1);
|
||||
else
|
||||
UML_LOAD(block, I0, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
if (DST_GLOBAL)
|
||||
{
|
||||
UML_LOAD(block, I1, (void *)m_global_regs, dst_code, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, dst_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
UML_DSEXT(block, I0, I0, SIZE_DWORD);
|
||||
UML_DSEXT(block, I1, I1, SIZE_DWORD);
|
||||
UML_DSUB(block, I2, I1, I0);
|
||||
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~(V_MASK | Z_MASK | N_MASK));
|
||||
|
||||
UML_XOR(block, I4, I1, I2);
|
||||
UML_XOR(block, I5, I0, I1);
|
||||
UML_AND(block, I4, I4, I5);
|
||||
UML_ROLINS(block, DRC_SR, I4, 4, V_MASK);
|
||||
|
||||
UML_TEST(block, I2, ~0);
|
||||
UML_SETc(block, uml::COND_Z, I4);
|
||||
UML_ROLINS(block, DRC_SR, I4, Z_SHIFT, Z_MASK);
|
||||
UML_ROLINS(block, DRC_SR, I2, 3, N_MASK);
|
||||
|
||||
if (DST_GLOBAL)
|
||||
{
|
||||
if (dst_code < 2)
|
||||
{
|
||||
UML_MOV(block, I4, dst_code);
|
||||
UML_MOV(block, I5, I2);
|
||||
generate_set_global_register(block, compiler, desc);
|
||||
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
generate_branch(block, desc->targetpc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_STORE(block, (void *)m_global_regs, dst_code, I2, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I4, I3, dst_code);
|
||||
UML_AND(block, I5, I4, 0x3f);
|
||||
UML_STORE(block, (void *)m_local_regs, I5, I2, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
int no_exception = compiler->m_labelnum++;
|
||||
UML_TEST(block, DRC_SR, V_MASK);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
generate_trap_exception_or_int<IS_EXCEPTION>(block);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
|
||||
@ -4800,7 +4886,7 @@ void hyperstone_device::generate_trap_op(drcuml_block *block, compiler_state *co
|
||||
UML_JMPc(block, uml::COND_NZ, skip_trap);
|
||||
|
||||
generate_get_trap_addr(block, compiler->m_labelnum, trapno);
|
||||
generate_trap_or_int<IS_TRAP>(block);
|
||||
generate_trap_exception_or_int<IS_TRAP>(block);
|
||||
|
||||
UML_LABEL(block, skip_trap);
|
||||
}
|
||||
|
@ -644,22 +644,18 @@ void hyperstone_device::hyperstone_subs()
|
||||
|
||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
//#ifdef SETCARRYS
|
||||
// SR |= (tmp & 0x100000000) >> 32;
|
||||
//#endif
|
||||
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
|
||||
|
||||
const int32_t res = dreg - sreg;
|
||||
dreg -= sreg;
|
||||
|
||||
if (res == 0)
|
||||
if (dreg == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(res);
|
||||
SR |= SIGN_TO_N(dreg);
|
||||
|
||||
if (DST_GLOBAL)
|
||||
set_global_register(dst_code, res);
|
||||
set_global_register(dst_code, dreg);
|
||||
else
|
||||
m_local_regs[dst_code] = res;
|
||||
m_local_regs[dst_code] = dreg;
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user