mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
-e132xs: Hyperstone DRC. [Ryan Holtz]
This commit is contained in:
parent
6c7e77189e
commit
54f5e90d9c
@ -45,7 +45,7 @@ const char *const hyperstone_disassembler::SETxx[] =
|
||||
#define SOURCEBIT(op) ((op & 0x100) >> 8)
|
||||
#define DESTBIT(op) ((op & 0x200) >> 9)
|
||||
|
||||
#define N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f))
|
||||
#define DASM_N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f))
|
||||
|
||||
void hyperstone_disassembler::LL_format(char *source, char *dest, uint16_t op)
|
||||
{
|
||||
@ -200,7 +200,7 @@ int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc
|
||||
uint16_t imm1, imm2;
|
||||
int32_t ret;
|
||||
|
||||
int n = N_VALUE(op);
|
||||
int n = DASM_N_VALUE(op);
|
||||
|
||||
if( DESTBIT(op) )
|
||||
{
|
||||
@ -287,7 +287,7 @@ uint8_t hyperstone_disassembler::Ln_format(char *dest, uint16_t op)
|
||||
{
|
||||
strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]);
|
||||
|
||||
return N_VALUE(op);
|
||||
return DASM_N_VALUE(op);
|
||||
}
|
||||
|
||||
uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op)
|
||||
@ -301,7 +301,7 @@ uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op)
|
||||
strcpy(dest, G_REG[DESTCODE(op)]);
|
||||
}
|
||||
|
||||
return N_VALUE(op);
|
||||
return DASM_N_VALUE(op);
|
||||
}
|
||||
|
||||
int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes)
|
||||
@ -796,7 +796,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
{
|
||||
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
|
||||
|
||||
if( !N_VALUE(op) )
|
||||
if( !DASM_N_VALUE(op) )
|
||||
{
|
||||
util::stream_format(stream, "ADDI %s, CZ", dest);
|
||||
}
|
||||
@ -813,7 +813,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
{
|
||||
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
|
||||
|
||||
if( !N_VALUE(op) )
|
||||
if( !DASM_N_VALUE(op) )
|
||||
{
|
||||
util::stream_format(stream, "ADDSI %s, CZ", dest);
|
||||
}
|
||||
@ -830,13 +830,13 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
{
|
||||
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
|
||||
|
||||
if( !N_VALUE(op) )
|
||||
if( !DASM_N_VALUE(op) )
|
||||
{
|
||||
util::stream_format(stream, "CMPBI %s, ANYBZ", dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( N_VALUE(op) == 31 )
|
||||
if( DASM_N_VALUE(op) == 31 )
|
||||
imm = 0x7fffffff; //bit 31 = 0, others = 1
|
||||
|
||||
util::stream_format(stream, "CMPBI %s, $%x", dest, imm);
|
||||
@ -850,7 +850,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
{
|
||||
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
|
||||
|
||||
if( N_VALUE(op) == 31 )
|
||||
if( DASM_N_VALUE(op) == 31 )
|
||||
imm = 0x7fffffff; //bit 31 = 0, others = 1
|
||||
|
||||
util::stream_format(stream, "ANDNI %s, $%x", dest, imm);
|
||||
|
@ -25,8 +25,29 @@
|
||||
#define S_BIT_CONST(val) ((val & 0x4000) >> 14)
|
||||
#define DD(val) ((val & 0x3000) >> 12)
|
||||
|
||||
#define S_BIT ((OP & 0x100) >> 8)
|
||||
#define D_BIT ((OP & 0x200) >> 9)
|
||||
#define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f))
|
||||
#define HI_N_VALUE (0x10 | (OP & 0x0f))
|
||||
#define LO_N_VALUE (OP & 0x0f)
|
||||
#define N_OP_MASK (m_op & 0x10f)
|
||||
#define DRC_HI_N_VALUE (0x10 | (op & 0x0f))
|
||||
#define DRC_LO_N_VALUE (op & 0x0f)
|
||||
#define DRC_N_OP_MASK (op & 0x10f)
|
||||
#define DST_CODE ((OP & 0xf0) >> 4)
|
||||
#define SRC_CODE (OP & 0x0f)
|
||||
#define SIGN_BIT(val) ((val & 0x80000000) >> 31)
|
||||
#define SIGN_TO_N(val) ((val & 0x80000000) >> 29)
|
||||
#define SIGN64_TO_N(val) ((val & 0x8000000000000000ULL) >> 61)
|
||||
|
||||
/* Extended DSP instructions */
|
||||
#define EHMAC 0x02a
|
||||
#define EHMACD 0x02e
|
||||
#define EHCMULD 0x046
|
||||
#define EHCMACD 0x04e
|
||||
#define EHCSUMD 0x086
|
||||
#define EHCFFTD 0x096
|
||||
#define EMUL_N 0x100
|
||||
#define EMUL 0x102
|
||||
#define EMULU 0x104
|
||||
#define EMULS 0x106
|
||||
@ -34,12 +55,6 @@
|
||||
#define EMACD 0x10e
|
||||
#define EMSUB 0x11a
|
||||
#define EMSUBD 0x11e
|
||||
#define EHMAC 0x02a
|
||||
#define EHMACD 0x02e
|
||||
#define EHCMULD 0x046
|
||||
#define EHCMACD 0x04e
|
||||
#define EHCSUMD 0x086
|
||||
#define EHCFFTD 0x096
|
||||
#define EHCFFTSD 0x296
|
||||
|
||||
/* IRQ numbers */
|
||||
|
@ -385,6 +385,33 @@ uint32_t hyperstone_device::get_emu_code_addr(uint8_t num) /* num is OP */
|
||||
0xffffff00, // MEM3
|
||||
};
|
||||
|
||||
#if E132XS_LOG_INTERPRETER_REGS
|
||||
void hyperstone_device::dump_registers()
|
||||
{
|
||||
static uint64_t total_ops = 0;
|
||||
//static uint64_t total_11094 = 0;
|
||||
total_ops++;
|
||||
if (total_ops < 389000000ULL)
|
||||
{
|
||||
//if (m_global_regs[0] == 0x11094)
|
||||
//{
|
||||
// total_11094++;
|
||||
//}
|
||||
return;
|
||||
} else if (total_ops == 389000000ULL) {
|
||||
//printf("Total non-log hits of 0x11094: %d\n", (uint32_t)total_11094);
|
||||
}
|
||||
uint8_t packed[4];
|
||||
packed[0] = (uint8_t)m_intblock;
|
||||
packed[1] = (uint8_t)(m_icount >> 16);
|
||||
packed[2] = (uint8_t)(m_icount >> 8);
|
||||
packed[3] = (uint8_t)(m_icount >> 0);
|
||||
fwrite(packed, 1, 4, m_trace_log);
|
||||
fwrite(m_global_regs, 4, 32, m_trace_log);
|
||||
fwrite(m_local_regs, 4, 64, m_trace_log);
|
||||
}
|
||||
#endif
|
||||
|
||||
void hyperstone_device::compute_tr()
|
||||
{
|
||||
uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles;
|
||||
@ -401,6 +428,7 @@ void hyperstone_device::update_timer_prescale()
|
||||
m_clock_cycles_3 = 3 << m_clck_scale;
|
||||
m_clock_cycles_4 = 4 << m_clck_scale;
|
||||
m_clock_cycles_6 = 6 << m_clck_scale;
|
||||
m_clock_cycles_36 = 36 << m_clck_scale;
|
||||
m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2;
|
||||
m_tr_base_value = m_tr_result;
|
||||
m_tr_base_cycles = total_cycles();
|
||||
@ -614,17 +642,6 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
#define S_BIT ((OP & 0x100) >> 8)
|
||||
#define D_BIT ((OP & 0x200) >> 9)
|
||||
#define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f))
|
||||
#define HI_N_VALUE (0x10 | (OP & 0x0f))
|
||||
#define LO_N_VALUE (OP & 0x0f)
|
||||
#define N_OP_MASK (m_op & 0x10f)
|
||||
#define DST_CODE ((OP & 0xf0) >> 4)
|
||||
#define SRC_CODE (OP & 0x0f)
|
||||
#define SIGN_BIT(val) ((val & 0x80000000) >> 31)
|
||||
#define SIGN_TO_N(val) ((val & 0x80000000) >> 29)
|
||||
|
||||
/*static*/ const int32_t hyperstone_device::s_immediate_values[16] =
|
||||
{
|
||||
16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000),
|
||||
@ -844,18 +861,16 @@ void hyperstone_device::execute_software()
|
||||
//since it's sure the register is in the register part of the stack,
|
||||
//set the stack address to a value above the highest address
|
||||
//that can be set by a following frame instruction
|
||||
const uint32_t stack_of_dst = (SP & ~0xff) + 64*4 + (((fp + DST_CODE) % 64) * 4); //converted to 32bits offset
|
||||
|
||||
const uint32_t oldSR = SR;
|
||||
|
||||
SET_FL(6);
|
||||
SET_FP(reg);
|
||||
const uint32_t stack_of_dst = (SP & ~0xff) + 0x100 + (((fp + DST_CODE) & 0x3f) << 2); //converted to 32bits offset
|
||||
|
||||
m_local_regs[(reg + 0) & 0x3f] = stack_of_dst;
|
||||
m_local_regs[(reg + 1) & 0x3f] = sreg;
|
||||
m_local_regs[(reg + 2) & 0x3f] = sregf;
|
||||
m_local_regs[(reg + 3) & 0x3f] = (PC & ~1) | GET_S;
|
||||
m_local_regs[(reg + 4) & 0x3f] = oldSR;
|
||||
m_local_regs[(reg + 4) & 0x3f] = SR;
|
||||
|
||||
SET_FL(6);
|
||||
SET_FP(reg);
|
||||
|
||||
SR &= ~(M_MASK | T_MASK);
|
||||
SR |= L_MASK;
|
||||
@ -878,14 +893,15 @@ void hyperstone_device::execute_software()
|
||||
7 - TIMER (trap 55)
|
||||
*/
|
||||
|
||||
#define INT1_LINE_STATE ((ISR >> 0) & 1)
|
||||
#define INT2_LINE_STATE ((ISR >> 1) & 1)
|
||||
#define INT3_LINE_STATE ((ISR >> 2) & 1)
|
||||
#define INT4_LINE_STATE ((ISR >> 3) & 1)
|
||||
#define IO1_LINE_STATE ((ISR >> 4) & 1)
|
||||
#define IO2_LINE_STATE ((ISR >> 5) & 1)
|
||||
#define IO3_LINE_STATE ((ISR >> 6) & 1)
|
||||
#define INT1_LINE_STATE (ISR & 0x01)
|
||||
#define INT2_LINE_STATE (ISR & 0x02)
|
||||
#define INT3_LINE_STATE (ISR & 0x04)
|
||||
#define INT4_LINE_STATE (ISR & 0x08)
|
||||
#define IO1_LINE_STATE (ISR & 0x10)
|
||||
#define IO2_LINE_STATE (ISR & 0x20)
|
||||
#define IO3_LINE_STATE (ISR & 0x40)
|
||||
|
||||
template <hyperstone_device::is_timer TIMER>
|
||||
void hyperstone_device::check_interrupts()
|
||||
{
|
||||
/* Interrupt-Lock flag isn't set */
|
||||
@ -893,95 +909,156 @@ void hyperstone_device::check_interrupts()
|
||||
return;
|
||||
|
||||
/* quick exit if nothing */
|
||||
if (!m_timer_int_pending && (ISR & 0x7f) == 0)
|
||||
if (TIMER == NO_TIMER && (ISR & 0x7f) == 0)
|
||||
return;
|
||||
|
||||
/* IO3 is priority 5; state is in bit 6 of ISR; FCR bit 10 enables input and FCR bit 8 inhibits interrupt */
|
||||
if (IO3_LINE_STATE && (FCR & 0x00000500) == 0x00000400)
|
||||
if (TIMER == NO_TIMER)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO3));
|
||||
standard_irq_callback(IRQ_IO3);
|
||||
return;
|
||||
/* IO3 is priority 5; state is in bit 6 of ISR; FCR bit 10 enables input and FCR bit 8 inhibits interrupt */
|
||||
if (IO3_LINE_STATE && (FCR & 0x00000500) == 0x00000400)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO3));
|
||||
standard_irq_callback(IRQ_IO3);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT1 is priority 7; state is in bit 0 of ISR; FCR bit 28 inhibits interrupt */
|
||||
if (INT1_LINE_STATE && (FCR & 0x10000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT1));
|
||||
standard_irq_callback(IRQ_INT1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT2 is priority 9; state is in bit 1 of ISR; FCR bit 29 inhibits interrupt */
|
||||
if (INT2_LINE_STATE && (FCR & 0x20000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT2));
|
||||
standard_irq_callback(IRQ_INT2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT3 is priority 11; state is in bit 2 of ISR; FCR bit 30 inhibits interrupt */
|
||||
if (INT3_LINE_STATE && (FCR & 0x40000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT3));
|
||||
standard_irq_callback(IRQ_INT3);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt */
|
||||
if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT4));
|
||||
standard_irq_callback(IRQ_INT4);
|
||||
return;
|
||||
}
|
||||
|
||||
/* IO1 is priority 14; state is in bit 4 of ISR; FCR bit 2 enables input and FCR bit 0 inhibits interrupt */
|
||||
if (IO1_LINE_STATE && (FCR & 0x00000005) == 0x00000004)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO1));
|
||||
standard_irq_callback(IRQ_IO1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* IO2 is priority 15; state is in bit 5 of ISR; FCR bit 6 enables input and FCR bit 4 inhibits interrupt */
|
||||
if (IO2_LINE_STATE && (FCR & 0x00000050) == 0x00000040)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
standard_irq_callback(IRQ_IO2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt */
|
||||
if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00300000)
|
||||
else
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
/* IO3 is priority 5; state is in bit 6 of ISR; FCR bit 10 enables input and FCR bit 8 inhibits interrupt */
|
||||
if (IO3_LINE_STATE && (FCR & 0x00000500) == 0x00000400)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO3));
|
||||
standard_irq_callback(IRQ_IO3);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT1 is priority 7; state is in bit 0 of ISR; FCR bit 28 inhibits interrupt */
|
||||
if (INT1_LINE_STATE && (FCR & 0x10000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT1));
|
||||
standard_irq_callback(IRQ_INT1);
|
||||
return;
|
||||
}
|
||||
/* timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt */
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00300000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
|
||||
/* timer int might be priority 8 if FCR bits 20-21 == 2; FCR bit 23 inhibits interrupt */
|
||||
if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00200000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
/* INT1 is priority 7; state is in bit 0 of ISR; FCR bit 28 inhibits interrupt */
|
||||
if (INT1_LINE_STATE && (FCR & 0x10000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT1));
|
||||
standard_irq_callback(IRQ_INT1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT2 is priority 9; state is in bit 1 of ISR; FCR bit 29 inhibits interrupt */
|
||||
if (INT2_LINE_STATE && (FCR & 0x20000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT2));
|
||||
standard_irq_callback(IRQ_INT2);
|
||||
return;
|
||||
}
|
||||
/* timer int might be priority 8 if FCR bits 20-21 == 2; FCR bit 23 inhibits interrupt */
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00200000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
|
||||
/* timer int might be priority 10 if FCR bits 20-21 == 1; FCR bit 23 inhibits interrupt */
|
||||
if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00100000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
/* INT2 is priority 9; state is in bit 1 of ISR; FCR bit 29 inhibits interrupt */
|
||||
if (INT2_LINE_STATE && (FCR & 0x20000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT2));
|
||||
standard_irq_callback(IRQ_INT2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT3 is priority 11; state is in bit 2 of ISR; FCR bit 30 inhibits interrupt */
|
||||
if (INT3_LINE_STATE && (FCR & 0x40000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT3));
|
||||
standard_irq_callback(IRQ_INT3);
|
||||
return;
|
||||
}
|
||||
/* timer int might be priority 10 if FCR bits 20-21 == 1; FCR bit 23 inhibits interrupt */
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00100000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
|
||||
/* timer int might be priority 12 if FCR bits 20-21 == 0; FCR bit 23 inhibits interrupt */
|
||||
if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00000000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
/* INT3 is priority 11; state is in bit 2 of ISR; FCR bit 30 inhibits interrupt */
|
||||
if (INT3_LINE_STATE && (FCR & 0x40000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT3));
|
||||
standard_irq_callback(IRQ_INT3);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt */
|
||||
if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT4));
|
||||
standard_irq_callback(IRQ_INT4);
|
||||
return;
|
||||
}
|
||||
/* timer int might be priority 12 if FCR bits 20-21 == 0; FCR bit 23 inhibits interrupt */
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00000000)
|
||||
{
|
||||
m_timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
|
||||
/* IO1 is priority 14; state is in bit 4 of ISR; FCR bit 2 enables input and FCR bit 0 inhibits interrupt */
|
||||
if (IO1_LINE_STATE && (FCR & 0x00000005) == 0x00000004)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO1));
|
||||
standard_irq_callback(IRQ_IO1);
|
||||
return;
|
||||
}
|
||||
/* INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt */
|
||||
if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_INT4));
|
||||
standard_irq_callback(IRQ_INT4);
|
||||
return;
|
||||
}
|
||||
|
||||
/* IO2 is priority 15; state is in bit 5 of ISR; FCR bit 6 enables input and FCR bit 4 inhibits interrupt */
|
||||
if (IO2_LINE_STATE && (FCR & 0x00000050) == 0x00000040)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
standard_irq_callback(IRQ_IO2);
|
||||
return;
|
||||
/* IO1 is priority 14; state is in bit 4 of ISR; FCR bit 2 enables input and FCR bit 0 inhibits interrupt */
|
||||
if (IO1_LINE_STATE && (FCR & 0x00000005) == 0x00000004)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO1));
|
||||
standard_irq_callback(IRQ_IO1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* IO2 is priority 15; state is in bit 5 of ISR; FCR bit 6 enables input and FCR bit 4 inhibits interrupt */
|
||||
if (IO2_LINE_STATE && (FCR & 0x00000050) == 0x00000040)
|
||||
{
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
standard_irq_callback(IRQ_IO2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -992,6 +1069,15 @@ void hyperstone_device::device_start()
|
||||
|
||||
void hyperstone_device::init(int scale_mask)
|
||||
{
|
||||
m_enable_drc = allow_drc();
|
||||
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
if (m_enable_drc)
|
||||
m_trace_log = fopen("e1_drc.log", "wb");
|
||||
else
|
||||
m_trace_log = fopen("e1_interpreter.log", "wb");
|
||||
#endif
|
||||
|
||||
memset(m_global_regs, 0, sizeof(uint32_t) * 32);
|
||||
memset(m_local_regs, 0, sizeof(uint32_t) * 64);
|
||||
m_op = 0;
|
||||
@ -1000,8 +1086,10 @@ void hyperstone_device::init(int scale_mask)
|
||||
m_clck_scale = 0;
|
||||
m_clock_cycles_1 = 0;
|
||||
m_clock_cycles_2 = 0;
|
||||
m_clock_cycles_3 = 0;
|
||||
m_clock_cycles_4 = 0;
|
||||
m_clock_cycles_6 = 0;
|
||||
m_clock_cycles_36 = 0;
|
||||
|
||||
m_tr_base_cycles = 0;
|
||||
m_tr_base_value = 0;
|
||||
@ -1150,6 +1238,7 @@ void hyperstone_device::init(int scale_mask)
|
||||
save_item(NAME(m_instruction_length));
|
||||
save_item(NAME(m_intblock));
|
||||
save_item(NAME(m_delay_slot));
|
||||
save_item(NAME(m_delay_slot_taken));
|
||||
save_item(NAME(m_tr_clocks_per_tick));
|
||||
save_item(NAME(m_tr_base_value));
|
||||
save_item(NAME(m_tr_base_cycles));
|
||||
@ -1158,8 +1247,10 @@ void hyperstone_device::init(int scale_mask)
|
||||
save_item(NAME(m_clock_scale_mask));
|
||||
save_item(NAME(m_clock_cycles_1));
|
||||
save_item(NAME(m_clock_cycles_2));
|
||||
save_item(NAME(m_clock_cycles_3));
|
||||
save_item(NAME(m_clock_cycles_4));
|
||||
save_item(NAME(m_clock_cycles_6));
|
||||
save_item(NAME(m_clock_cycles_36));
|
||||
|
||||
// set our instruction counter
|
||||
m_icountptr = &m_icount;
|
||||
@ -1275,6 +1366,7 @@ void hyperstone_device::device_reset()
|
||||
SET_T(0);
|
||||
SET_L(1);
|
||||
SET_S(1);
|
||||
SET_ILC(1<<19);
|
||||
|
||||
set_local_register(0, (PC & 0xfffffffe) | GET_S);
|
||||
set_local_register(1, SR);
|
||||
@ -1284,6 +1376,17 @@ void hyperstone_device::device_reset()
|
||||
|
||||
void hyperstone_device::device_stop()
|
||||
{
|
||||
if (m_drcfe != nullptr)
|
||||
{
|
||||
m_drcfe = nullptr;
|
||||
}
|
||||
if (m_drcuml != nullptr)
|
||||
{
|
||||
m_drcuml = nullptr;
|
||||
}
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
fclose(m_trace_log);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1358,6 +1461,8 @@ bool hyperstone_device::get_h() const
|
||||
|
||||
void hyperstone_device::hyperstone_trap()
|
||||
{
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
static const uint32_t conditions[16] = {
|
||||
0, 0, 0, 0, N_MASK | Z_MASK, N_MASK | Z_MASK, N_MASK, N_MASK, C_MASK | Z_MASK, C_MASK | Z_MASK, C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, 0
|
||||
};
|
||||
@ -1381,8 +1486,6 @@ void hyperstone_device::hyperstone_trap()
|
||||
if (!(SR & conditions[code]))
|
||||
execute_trap(addr);
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
|
||||
@ -1453,11 +1556,16 @@ void hyperstone_device::execute_run()
|
||||
if (m_intblock < 0)
|
||||
m_intblock = 0;
|
||||
|
||||
check_interrupts();
|
||||
if (m_timer_int_pending)
|
||||
check_interrupts<IS_TIMER>();
|
||||
else
|
||||
check_interrupts<NO_TIMER>();
|
||||
|
||||
do
|
||||
while (m_icount > 0)
|
||||
{
|
||||
uint32_t oldh = SR & 0x00000020;
|
||||
#if E132XS_LOG_INTERPRETER_REGS
|
||||
dump_registers();
|
||||
#endif
|
||||
|
||||
debugger_instruction_hook(this, PC);
|
||||
|
||||
@ -1726,9 +1834,6 @@ void hyperstone_device::execute_run()
|
||||
case 0xff: hyperstone_trap(); break;
|
||||
}
|
||||
|
||||
/* clear the H state if it was previously set */
|
||||
SR ^= oldh;
|
||||
|
||||
SET_ILC(m_instruction_length);
|
||||
|
||||
if (GET_T && GET_P && !m_delay_slot) /* Not in a Delayed Branch instructions */
|
||||
@ -1737,10 +1842,15 @@ void hyperstone_device::execute_run()
|
||||
execute_exception(addr);
|
||||
}
|
||||
|
||||
if (--m_intblock == 0)
|
||||
check_interrupts();
|
||||
|
||||
} while( m_icount > 0 );
|
||||
if (--m_intblock <= 0)
|
||||
{
|
||||
m_intblock = 0;
|
||||
if (m_timer_int_pending)
|
||||
check_interrupts<IS_TIMER>();
|
||||
else
|
||||
check_interrupts<NO_TIMER>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_TYPE(E116T, e116t_device, "e116t", "E1-16T")
|
||||
|
@ -23,6 +23,35 @@
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
/* map variables */
|
||||
#define MAPVAR_PC M0
|
||||
#define MAPVAR_CYCLES M1
|
||||
|
||||
/* compilation boundaries -- how far back/forward does the analysis extend? */
|
||||
#define COMPILE_BACKWARDS_BYTES 128
|
||||
#define COMPILE_FORWARDS_BYTES 512
|
||||
#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
|
||||
#define COMPILE_MAX_SEQUENCE 64
|
||||
|
||||
/* exit codes */
|
||||
#define EXECUTE_OUT_OF_CYCLES 0
|
||||
#define EXECUTE_MISSING_CODE 1
|
||||
#define EXECUTE_UNMAPPED_CODE 2
|
||||
#define EXECUTE_RESET_CACHE 3
|
||||
|
||||
#define E132XS_STRICT_VERIFY 0x0001 /* verify all instructions */
|
||||
|
||||
#define SINGLE_INSTRUCTION_MODE (1)
|
||||
|
||||
#define ENABLE_E132XS_DRC (1)
|
||||
|
||||
#define E132XS_LOG_DRC_REGS (0)
|
||||
#define E132XS_LOG_INTERPRETER_REGS (0)
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
@ -40,6 +69,11 @@ public:
|
||||
inline void ccfunc_unimplemented();
|
||||
inline void ccfunc_print();
|
||||
inline void ccfunc_total_cycles();
|
||||
inline void ccfunc_standard_irq_callback();
|
||||
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
void dump_registers();
|
||||
#endif
|
||||
void update_timer_prescale();
|
||||
void compute_tr();
|
||||
void adjust_timer_interrupt();
|
||||
@ -141,6 +175,18 @@ protected:
|
||||
IS_SET = 1
|
||||
};
|
||||
|
||||
enum trap_or_int
|
||||
{
|
||||
IS_TRAP = 0,
|
||||
IS_INT = 1
|
||||
};
|
||||
|
||||
enum is_timer
|
||||
{
|
||||
NO_TIMER = 0,
|
||||
IS_TIMER = 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EXCEPTION_IO2 = 48,
|
||||
@ -210,17 +256,18 @@ protected:
|
||||
|
||||
uint8_t m_clock_scale_mask;
|
||||
uint8_t m_clck_scale;
|
||||
uint8_t m_clock_cycles_1;
|
||||
uint8_t m_clock_cycles_2;
|
||||
uint8_t m_clock_cycles_3;
|
||||
uint8_t m_clock_cycles_4;
|
||||
uint8_t m_clock_cycles_6;
|
||||
uint32_t m_clock_cycles_1;
|
||||
uint32_t m_clock_cycles_2;
|
||||
uint32_t m_clock_cycles_3;
|
||||
uint32_t m_clock_cycles_4;
|
||||
uint32_t m_clock_cycles_6;
|
||||
uint32_t m_clock_cycles_36;
|
||||
|
||||
uint64_t m_tr_base_cycles;
|
||||
uint32_t m_tr_base_value;
|
||||
uint32_t m_tr_result;
|
||||
uint32_t m_tr_clocks_per_tick;
|
||||
uint8_t m_timer_int_pending;
|
||||
uint32_t m_timer_int_pending;
|
||||
emu_timer *m_timer;
|
||||
|
||||
uint64_t m_numcycles;
|
||||
@ -228,6 +275,7 @@ protected:
|
||||
uint32_t m_prev_pc;
|
||||
uint32_t m_delay_pc;
|
||||
uint32_t m_delay_slot;
|
||||
uint32_t m_delay_slot_taken;
|
||||
|
||||
uint32_t m_opcodexor;
|
||||
|
||||
@ -245,7 +293,7 @@ protected:
|
||||
|
||||
private:
|
||||
// internal functions
|
||||
void check_interrupts();
|
||||
template <hyperstone_device::is_timer TIMER> void check_interrupts();
|
||||
|
||||
void set_global_register(uint8_t code, uint32_t val);
|
||||
void set_local_register(uint8_t code, uint32_t val);
|
||||
@ -345,6 +393,165 @@ private:
|
||||
|
||||
void hyperstone_reserved();
|
||||
void hyperstone_do();
|
||||
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
FILE *m_trace_log;
|
||||
#endif
|
||||
|
||||
drc_cache m_cache;
|
||||
std::unique_ptr<drcuml_state> m_drcuml;
|
||||
std::unique_ptr<e132xs_frontend> m_drcfe;
|
||||
uint32_t m_drcoptions;
|
||||
uint8_t m_cache_dirty;
|
||||
|
||||
uml::parameter m_regmap[16];
|
||||
|
||||
uml::code_handle *m_entry;
|
||||
uml::code_handle *m_nocode;
|
||||
uml::code_handle *m_interrupt_checks;
|
||||
uml::code_handle *m_out_of_cycles;
|
||||
|
||||
uint32_t m_drc_arg0;
|
||||
uint32_t m_drc_arg1;
|
||||
uint32_t m_drc_arg2;
|
||||
uint32_t m_drc_arg3;
|
||||
uint32_t m_branch_dest;
|
||||
|
||||
uml::code_handle *m_mem_read8;
|
||||
uml::code_handle *m_mem_write8;
|
||||
uml::code_handle *m_mem_read16;
|
||||
uml::code_handle *m_mem_write16;
|
||||
uml::code_handle *m_mem_read32;
|
||||
uml::code_handle *m_mem_write32;
|
||||
uml::code_handle *m_io_read32;
|
||||
uml::code_handle *m_io_write32;
|
||||
uml::code_handle *m_exception[EXCEPTION_COUNT];
|
||||
|
||||
bool m_enable_drc;
|
||||
|
||||
/* internal compiler state */
|
||||
struct compiler_state
|
||||
{
|
||||
uint32_t m_cycles; /* accumulated cycles */
|
||||
uint8_t m_checkints; /* need to check interrupts before next instruction */
|
||||
uml::code_label m_labelnum; /* index for local labels */
|
||||
};
|
||||
|
||||
void execute_run_drc();
|
||||
void flush_drc_cache();
|
||||
void code_flush_cache();
|
||||
void code_compile_block(offs_t pc);
|
||||
//void load_fast_iregs(drcuml_block *block);
|
||||
//void save_fast_iregs(drcuml_block *block);
|
||||
void static_generate_entry_point();
|
||||
void static_generate_nocode_handler();
|
||||
void static_generate_out_of_cycles();
|
||||
void static_generate_exception(uint32_t exception, const char *name);
|
||||
void static_generate_memory_accessor(int size, int iswrite, bool isio, const char *name, uml::code_handle *&handleptr);
|
||||
void static_generate_interrupt_checks();
|
||||
void generate_interrupt_checks_no_timer(drcuml_block *block, uml::code_label &labelnum);
|
||||
void generate_interrupt_checks_with_timer(drcuml_block *block, uml::code_label &labelnum);
|
||||
void generate_branch(drcuml_block *block, uml::parameter targetpc, bool update_cycles = true);
|
||||
void generate_update_cycles(drcuml_block *block, bool check_interrupts = true);
|
||||
void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
|
||||
void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op);
|
||||
bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
void generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno);
|
||||
void generate_check_delay_pc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_ignore_immediate_s(drcuml_block *block, const opcode_desc *desc);
|
||||
void generate_decode_pcrel(drcuml_block *block, const opcode_desc *desc);
|
||||
void generate_ignore_pcrel(drcuml_block *block, const opcode_desc *desc);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_chk(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_movd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_divsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mask(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sum(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sums(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mov(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_add(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_adds(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmpb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sub(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_addc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_neg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_negs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_and(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_andn(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_or(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_andni(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_ori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_xori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N> void generate_shrdi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_shrd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_shr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shri(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N> void generate_sardi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_sard(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_sar(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_sari(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N> void generate_shldi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_shld(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_shl(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shli(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_testlz(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_rol(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_mulsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mul(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_set(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <reg_bank SRC_GLOBAL> void generate_ldwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_lddr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_ldwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_lddp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <reg_bank SRC_GLOBAL> void generate_stwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_stdr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_stwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <reg_bank SRC_GLOBAL> void generate_stdp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
template <branch_condition CONDITION, condition_set COND_SET> void generate_b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_br(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <branch_condition CONDITION, condition_set COND_SET> void generate_db(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_dbr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
void generate_frame(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
template <hyperstone_device::reg_bank SRC_GLOBAL> void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
void generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_extend(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
||||
void generate_reserved(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_do(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
1234
src/devices/cpu/e132xs/e132xsdrc.cpp
Normal file
1234
src/devices/cpu/e132xs/e132xsdrc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4977
src/devices/cpu/e132xs/e132xsdrc_ops.hxx
Normal file
4977
src/devices/cpu/e132xs/e132xsdrc_ops.hxx
Normal file
File diff suppressed because it is too large
Load Diff
1365
src/devices/cpu/e132xs/e132xsfe.cpp
Normal file
1365
src/devices/cpu/e132xs/e132xsfe.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -55,8 +55,6 @@ void hyperstone_device::hyperstone_movd()
|
||||
if (m_intblock < 1)
|
||||
m_intblock = 1;
|
||||
|
||||
m_instruction_length = 0; // undefined
|
||||
|
||||
const uint32_t new_s = SR & S_MASK;
|
||||
const uint32_t new_l = SR & L_MASK;
|
||||
if( (!old_s && new_s) || (!new_s && !old_l && new_l))
|
||||
@ -76,8 +74,8 @@ void hyperstone_device::hyperstone_movd()
|
||||
m_local_regs[(SP & 0xfc) >> 2] = READ_W(SP);
|
||||
}
|
||||
|
||||
//TODO: no 1!
|
||||
m_icount -= m_clock_cycles_1;
|
||||
//TODO: not 2!
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR
|
||||
{
|
||||
@ -160,7 +158,7 @@ void hyperstone_device::hyperstone_divsu()
|
||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)quotient;
|
||||
}
|
||||
|
||||
m_icount -= 36 << m_clck_scale;
|
||||
m_icount -= m_clock_cycles_36;
|
||||
}
|
||||
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
||||
@ -334,9 +332,12 @@ void hyperstone_device::hyperstone_cmp()
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
||||
void hyperstone_device::hyperstone_mov()
|
||||
{
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
check_delay_PC();
|
||||
|
||||
const bool h = (SR & H_MASK) != 0;
|
||||
const bool h = (SR & H_MASK) != 0;
|
||||
SR &= ~H_MASK;
|
||||
if (DST_GLOBAL && h && !(SR & S_MASK))
|
||||
{
|
||||
execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
|
||||
@ -365,8 +366,6 @@ void hyperstone_device::hyperstone_mov()
|
||||
m_local_regs[(DST_CODE + fp) & 0x3f] = sreg;
|
||||
}
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
||||
@ -545,29 +544,19 @@ void hyperstone_device::hyperstone_subc()
|
||||
const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
|
||||
|
||||
const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? 0 : m_global_regs[src_code]) : m_local_regs[src_code];
|
||||
uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
||||
const uint32_t c = GET_C;
|
||||
|
||||
const uint64_t tmp = uint64_t(dreg) - (uint64_t(sreg) + uint64_t(c));
|
||||
|
||||
uint32_t old_z = SR & Z_MASK;
|
||||
SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
if (SRC_GLOBAL && (src_code == SR_REGISTER))
|
||||
{
|
||||
const uint64_t tmp = uint64_t(dreg) - uint64_t(c);
|
||||
SR |= ((tmp ^ dreg) & dreg & 0x80000000) >> 28;
|
||||
SR |= (tmp & 0x100000000) >> 32;
|
||||
dreg -= c;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
||||
const uint64_t tmp = uint64_t(dreg) - (uint64_t(sreg) + uint64_t(c));
|
||||
//CHECK!
|
||||
const uint32_t sreg_c = sreg + c;
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg_c) & 0x80000000) >> 28;
|
||||
SR |= (tmp & 0x100000000) >> 32;
|
||||
dreg -= sreg_c;
|
||||
}
|
||||
const uint32_t sreg_c = sreg + c;
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg_c) & 0x80000000) >> 28;
|
||||
SR |= (tmp & 0x100000000) >> 32;
|
||||
dreg -= sreg + c;
|
||||
|
||||
if (old_z && dreg == 0)
|
||||
SR |= Z_MASK;
|
||||
@ -848,6 +837,8 @@ void hyperstone_device::hyperstone_cmpi()
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
|
||||
void hyperstone_device::hyperstone_movi()
|
||||
{
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
uint32_t imm;
|
||||
if (IMM_LONG)
|
||||
imm = decode_immediate_s();
|
||||
@ -857,6 +848,7 @@ void hyperstone_device::hyperstone_movi()
|
||||
imm = m_op & 0x0f;
|
||||
|
||||
const bool h = (SR & H_MASK) != 0;
|
||||
SR &= ~H_MASK;
|
||||
if (DST_GLOBAL && h && !(SR & S_MASK))
|
||||
{
|
||||
execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
|
||||
@ -885,8 +877,6 @@ void hyperstone_device::hyperstone_movi()
|
||||
m_local_regs[(DST_CODE + GET_FP) & 0x3f] = imm;
|
||||
}
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
|
||||
@ -1234,7 +1224,7 @@ void hyperstone_device::hyperstone_shrd()
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(m_local_regs[dst_code]);
|
||||
SR |= SIGN64_TO_N(val);
|
||||
|
||||
m_local_regs[dst_code] = (uint32_t)(val >> 32);
|
||||
m_local_regs[dstf_code] = (uint32_t)val;
|
||||
@ -1322,6 +1312,7 @@ void hyperstone_device::hyperstone_sard()
|
||||
SR &= ~(C_MASK | Z_MASK | N_MASK);
|
||||
|
||||
const uint32_t n = m_local_regs[src_code] & 0x1f;
|
||||
|
||||
if (n)
|
||||
{
|
||||
SR |= (val >> (n - 1)) & 1;
|
||||
@ -1338,7 +1329,7 @@ void hyperstone_device::hyperstone_sard()
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(m_local_regs[dst_code]);
|
||||
SR |= SIGN64_TO_N(val);
|
||||
|
||||
m_local_regs[dst_code] = (uint32_t)(val >> 32);
|
||||
m_local_regs[dstf_code] = (uint32_t)val;
|
||||
@ -1396,24 +1387,21 @@ void hyperstone_device::hyperstone_shldi()
|
||||
SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
|
||||
if ((HI_N || n) && ((val << (n - 1)) & 0x8000000000000000U))
|
||||
SR |= C_MASK;
|
||||
SR |= (n)?(((val<<(n-1))&0x8000000000000000ULL)?1:0):0;
|
||||
|
||||
const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff;
|
||||
const uint32_t tmp = high_order << n;
|
||||
const uint32_t tmp = high_order << n;
|
||||
uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
|
||||
|
||||
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
|
||||
SR |= V_MASK;
|
||||
|
||||
val <<= n;
|
||||
|
||||
high_order = extract_64hi(val);
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(high_order);
|
||||
SR |= SIGN64_TO_N(val);
|
||||
|
||||
m_local_regs[dst_code] = high_order;
|
||||
m_local_regs[dst_code] = extract_64hi(val);
|
||||
m_local_regs[dstf_code] = extract_64lo(val);
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
@ -1437,18 +1425,19 @@ void hyperstone_device::hyperstone_shld()
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t n = m_local_regs[src_code & 0x3f] & 0x1f;
|
||||
uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */
|
||||
uint32_t high_order = m_local_regs[dst_code];
|
||||
uint32_t low_order = m_local_regs[dstf_code];
|
||||
|
||||
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
|
||||
|
||||
uint64_t val = concat_64(high_order, low_order);
|
||||
|
||||
SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
|
||||
SR |= (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0;
|
||||
|
||||
uint32_t tmp = high_order << n;
|
||||
const uint32_t n = m_local_regs[src_code] & 0x1f;
|
||||
SR |= (n)?(((val<<(n-1))&0x8000000000000000ULL)?1:0):0;
|
||||
|
||||
const uint32_t tmp = high_order << n;
|
||||
const uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
|
||||
|
||||
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
|
||||
SR |= V_MASK;
|
||||
|
||||
@ -1456,7 +1445,7 @@ void hyperstone_device::hyperstone_shld()
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(m_local_regs[dst_code]);
|
||||
SR |= SIGN64_TO_N(val);
|
||||
|
||||
m_local_regs[dst_code] = extract_64hi(val);
|
||||
m_local_regs[dstf_code] = extract_64lo(val);
|
||||
@ -1525,14 +1514,14 @@ void hyperstone_device::hyperstone_rol()
|
||||
|
||||
#ifdef MISSIONCRAFT_FLAGS
|
||||
const uint32_t base = val;
|
||||
const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff;
|
||||
const uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
|
||||
#endif
|
||||
|
||||
if (n)
|
||||
val = (val << n) | (val >> (32 - n));
|
||||
|
||||
#ifdef MISSIONCRAFT_FLAGS
|
||||
SR &= ~(V_MASK | Z_MASK | C_MASK);
|
||||
SR &= ~(V_MASK | Z_MASK | C_MASK | N_MASK);
|
||||
if (((base & mask) && (!(val & 0x80000000))) || (((base & mask) ^ mask) && (val & 0x80000000)))
|
||||
SR |= V_MASK;
|
||||
#else
|
||||
@ -1875,7 +1864,7 @@ void hyperstone_device::hyperstone_stxx1()
|
||||
case 1: // STD.D
|
||||
{
|
||||
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
|
||||
const uint32_t sregf = ((SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
|
||||
extra_s &= ~1;
|
||||
WRITE_W(dreg + extra_s, sreg);
|
||||
WRITE_W(dreg + extra_s + 4, sregf);
|
||||
@ -1888,7 +1877,7 @@ void hyperstone_device::hyperstone_stxx1()
|
||||
case 3: // STD.IOD
|
||||
{
|
||||
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
|
||||
const uint32_t sregf = ((SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
|
||||
extra_s &= ~3;
|
||||
IO_WRITE_W(dreg + extra_s, sreg);
|
||||
IO_WRITE_W(dreg + extra_s + 4, sregf);
|
||||
@ -1974,15 +1963,12 @@ void hyperstone_device::hyperstone_stxx2()
|
||||
break;
|
||||
case 1: // STD.N
|
||||
{
|
||||
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code];
|
||||
WRITE_W(dreg, sreg);
|
||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1;
|
||||
|
||||
if(DST_GLOBAL == SRC_GLOBAL && (src_code + 1) == dst_code)
|
||||
WRITE_W(dreg + 4, sregf + (extra_s & ~1)); // because DREG == SREGF and DREG has been incremented
|
||||
else
|
||||
WRITE_W(dreg + 4, sregf);
|
||||
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sregf = (SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code];
|
||||
WRITE_W(dreg + 4, sregf);
|
||||
|
||||
m_icount -= m_clock_cycles_1; // extra cycle
|
||||
break;
|
||||
@ -2041,16 +2027,18 @@ void hyperstone_device::hyperstone_sari()
|
||||
check_delay_PC();
|
||||
|
||||
const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
||||
|
||||
const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
|
||||
uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
||||
|
||||
SR &= ~(C_MASK | Z_MASK | N_MASK);
|
||||
|
||||
if (HI_N || n)
|
||||
{
|
||||
const uint32_t sign_bit = val & 0x80000000;
|
||||
|
||||
SR |= (val >> (n - 1)) & 1;
|
||||
|
||||
uint32_t sign_bit = val & 0x80000000;
|
||||
val >>= n;
|
||||
|
||||
if (sign_bit)
|
||||
@ -2079,7 +2067,12 @@ void hyperstone_device::hyperstone_shli()
|
||||
|
||||
const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
|
||||
SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
|
||||
SR |= (HI_N || n) ? (((val << (n - 1)) & 0x80000000) ? 1 : 0) : 0;
|
||||
|
||||
if (HI_N || n)
|
||||
{
|
||||
SR |= (val & (0x80000000 >> (n - 1))) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff;
|
||||
uint32_t val2 = val << n;
|
||||
|
||||
@ -2128,12 +2121,11 @@ void hyperstone_device::hyperstone_mulsu()
|
||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = high_order;
|
||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)double_word;
|
||||
|
||||
m_icount -= m_clock_cycles_6;
|
||||
if(SIGNED == IS_SIGNED && (sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff))
|
||||
m_icount -= m_clock_cycles_4;
|
||||
m_icount += m_clock_cycles_2;
|
||||
else if(SIGNED == IS_UNSIGNED && sreg <= 0xffff && dreg <= 0xffff)
|
||||
m_icount -= m_clock_cycles_4;
|
||||
else
|
||||
m_icount -= m_clock_cycles_6;
|
||||
m_icount += m_clock_cycles_2;
|
||||
}
|
||||
|
||||
template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL>
|
||||
@ -2222,10 +2214,10 @@ void hyperstone_device::hyperstone_mul()
|
||||
|
||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = result;
|
||||
|
||||
if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff))
|
||||
m_icount -= 3 << m_clck_scale;
|
||||
else
|
||||
if (sreg < 0xffff8000 || sreg > 0x7fff || dreg < 0xffff8000 || dreg > 0x7fff)
|
||||
m_icount -= 5 << m_clck_scale;
|
||||
else
|
||||
m_icount -= 3 << m_clck_scale;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_extend()
|
||||
@ -2244,7 +2236,7 @@ void hyperstone_device::hyperstone_extend()
|
||||
{
|
||||
// signed or unsigned multiplication, single word product
|
||||
case EMUL:
|
||||
case 0x100: // used in "N" type cpu
|
||||
case EMUL_N: // used in "N" type cpu
|
||||
m_global_regs[15] = (uint32_t)(vals * vald);
|
||||
break;
|
||||
|
||||
@ -2256,13 +2248,13 @@ void hyperstone_device::hyperstone_extend()
|
||||
m_global_regs[15] = (uint32_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
// signed multiplication, double word product
|
||||
case EMULS:
|
||||
{
|
||||
const int64_t result = (int64_t)(int32_t)vals * (int64_t)(int32_t)vald;
|
||||
m_global_regs[14] = (uint32_t)(result >> 32);
|
||||
m_global_regs[15] = (uint32_t)result;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2279,6 +2271,7 @@ void hyperstone_device::hyperstone_extend()
|
||||
m_global_regs[15] = (uint32_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
// signed multiply/substract, single word product difference
|
||||
case EMSUB:
|
||||
m_global_regs[15] = (int32_t)m_global_regs[15] - ((int32_t)vals * (int32_t)vald);
|
||||
@ -2290,19 +2283,18 @@ void hyperstone_device::hyperstone_extend()
|
||||
int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) - (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald);
|
||||
m_global_regs[14] = (uint32_t)(result >> 32);
|
||||
m_global_regs[15] = (uint32_t)result;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// signed half-word multiply/add, single word product sum
|
||||
case EHMAC:
|
||||
m_global_regs[15] = (int32_t)m_global_regs[15] + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff));
|
||||
m_global_regs[15] = (int32_t)m_global_regs[15] + ((int32_t)(vald >> 16) * (int32_t)(vals >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff));
|
||||
break;
|
||||
|
||||
// signed half-word multiply/add, double word product sum
|
||||
case EHMACD:
|
||||
{
|
||||
int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff));
|
||||
int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)(vald >> 16) * (int64_t)(int32_t)(vals >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff));
|
||||
m_global_regs[14] = (uint32_t)(result >> 32);
|
||||
m_global_regs[15] = (uint32_t)result;
|
||||
break;
|
||||
@ -2310,14 +2302,14 @@ void hyperstone_device::hyperstone_extend()
|
||||
|
||||
// half-word complex multiply
|
||||
case EHCMULD:
|
||||
m_global_regs[14] = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
|
||||
m_global_regs[15] = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
|
||||
m_global_regs[14] = ((vald >> 16) * (vals >> 16 )) - ((vald & 0xffff) * (vals & 0xffff));
|
||||
m_global_regs[15] = ((vald >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * (vals >> 16 ));
|
||||
break;
|
||||
|
||||
// half-word complex multiply/add
|
||||
case EHCMACD:
|
||||
m_global_regs[14] += (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
|
||||
m_global_regs[15] += (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
|
||||
m_global_regs[14] += ((vald >> 16) * (vals >> 16 )) - ((vald & 0xffff) * (vals & 0xffff));
|
||||
m_global_regs[15] += ((vald >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * (vals >> 16 ));
|
||||
break;
|
||||
|
||||
// half-word (complex) add/substract
|
||||
@ -2326,8 +2318,8 @@ void hyperstone_device::hyperstone_extend()
|
||||
{
|
||||
const uint32_t r14 = m_global_regs[14];
|
||||
const uint32_t r15 = m_global_regs[15];
|
||||
m_global_regs[14] = (((((vals & 0xffff0000) >> 16) + r14) << 16) & 0xffff0000) | (((vals & 0xffff) + r15) & 0xffff);
|
||||
m_global_regs[15] = (((((vals & 0xffff0000) >> 16) - r14) << 16) & 0xffff0000) | (((vals & 0xffff) - r15) & 0xffff);
|
||||
m_global_regs[14] = (((vals >> 16) + r14) << 16) | (((vals & 0xffff) + r15) & 0xffff);
|
||||
m_global_regs[15] = (((vals >> 16) - r14) << 16) | (((vals & 0xffff) - r15) & 0xffff);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2358,7 +2350,7 @@ void hyperstone_device::hyperstone_extend()
|
||||
break;
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_1; //TODO: with the latency it can change
|
||||
m_icount -= m_clock_cycles_1; // TODO: with the latency it can change
|
||||
}
|
||||
|
||||
|
||||
@ -2513,7 +2505,6 @@ void hyperstone_device::hyperstone_stdp()
|
||||
const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
|
||||
const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
||||
const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code];
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const uint32_t dreg = m_local_regs[dst_code];
|
||||
@ -2522,10 +2513,9 @@ void hyperstone_device::hyperstone_stdp()
|
||||
|
||||
m_local_regs[dst_code] += 8;
|
||||
|
||||
if (SRC_GLOBAL || srcf_code != dst_code)
|
||||
WRITE_W(dreg + 4, sregf);
|
||||
else
|
||||
WRITE_W(dreg + 4, sregf + 8); // because DREG == SREGF and DREG has been incremented
|
||||
const uint32_t sregf = (SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code];
|
||||
|
||||
WRITE_W(dreg + 4, sregf);
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
@ -2543,11 +2533,13 @@ void hyperstone_device::hyperstone_db()
|
||||
m_delay_slot = 1;
|
||||
m_delay_pc = PC + offset;
|
||||
m_intblock = 3;
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2556,6 +2548,7 @@ void hyperstone_device::hyperstone_db()
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2564,10 +2557,9 @@ void hyperstone_device::hyperstone_db()
|
||||
m_delay_slot = 1;
|
||||
m_delay_pc = PC + offset;
|
||||
m_intblock = 3;
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_dbr()
|
||||
@ -2578,6 +2570,8 @@ void hyperstone_device::hyperstone_dbr()
|
||||
m_delay_slot = 1;
|
||||
m_delay_pc = PC + offset;
|
||||
m_intblock = 3;
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_frame()
|
||||
@ -2615,7 +2609,7 @@ void hyperstone_device::hyperstone_frame()
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: no 1!
|
||||
// TODO: More than 1 cycle!
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
@ -2633,6 +2627,7 @@ void hyperstone_device::hyperstone_call()
|
||||
|
||||
PC += 2;
|
||||
SET_ILC(3<<19);
|
||||
m_instruction_length = (3<<19);
|
||||
|
||||
extra_s = imm_2;
|
||||
extra_s |= ((imm_1 & 0x3fff) << 16);
|
||||
@ -2645,6 +2640,7 @@ void hyperstone_device::hyperstone_call()
|
||||
extra_s = imm_1 & 0x3fff;
|
||||
|
||||
SET_ILC(2<<19);
|
||||
m_instruction_length = (2<<19);
|
||||
|
||||
if (imm_1 & 0x4000)
|
||||
extra_s |= 0xffffc000;
|
||||
@ -2675,7 +2671,7 @@ void hyperstone_device::hyperstone_call()
|
||||
|
||||
//TODO: add interrupt locks, errors, ....
|
||||
|
||||
//TODO: no 1!
|
||||
// TODO: More than 1 cycle!
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user