mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
cpu/e132xs: Moved interrupt check to the beginning of instruction execution.
* Fixes interrupts not being serviced while tracing. * Further improves recompiler performance. * Fixes recompiler interrupt check function calling itself recursively. * Also added debugger exception hook calls to interpreter and recompiler.
This commit is contained in:
parent
add2015ce3
commit
213e1b5857
@ -37,7 +37,6 @@
|
||||
- What actually happens on trying to load memory to PC or SR?
|
||||
- Verify register wrapping with sregf/dregf on hardware
|
||||
- Tracing doesn't work properly
|
||||
Interrupts are not serviced while tracing
|
||||
DRC does not generate trace exceptions on branch or return
|
||||
- Interpreter does not implement privilege check on setting L flag
|
||||
- DRC does not update ILC and P on some privilege error exceptions
|
||||
@ -159,7 +158,7 @@ e116t_device::e116t_device(const machine_config &mconfig, const char *tag, devic
|
||||
//-------------------------------------------------
|
||||
|
||||
e116xt_device::e116xt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: hyperstone_device(mconfig, tag, owner, clock, E116XT, 16, 16, address_map_constructor(FUNC(e116t_device::e116_8k_iram_map), this))
|
||||
: hyperstone_device(mconfig, tag, owner, clock, E116XT, 16, 16, address_map_constructor(FUNC(e116xt_device::e116_8k_iram_map), this))
|
||||
{
|
||||
}
|
||||
|
||||
@ -750,8 +749,11 @@ void hyperstone_device::execute_int(uint32_t addr)
|
||||
}
|
||||
|
||||
/* TODO: mask Parity Error and Extended Overflow exceptions */
|
||||
void hyperstone_device::execute_exception(uint32_t addr)
|
||||
void hyperstone_device::execute_exception(uint8_t trapno)
|
||||
{
|
||||
debugger_exception_hook(int(unsigned(trapno)));
|
||||
|
||||
const uint32_t addr = get_trap_addr(trapno);
|
||||
const uint8_t reg = GET_FP + GET_FL;
|
||||
SET_ILC(m_instruction_length);
|
||||
const uint32_t oldSR = SR;
|
||||
@ -830,161 +832,100 @@ void hyperstone_device::execute_software()
|
||||
template <hyperstone_device::is_timer TIMER>
|
||||
void hyperstone_device::check_interrupts()
|
||||
{
|
||||
/* Interrupt-Lock flag isn't set */
|
||||
if (GET_L || m_core->intblock > 0)
|
||||
// Interrupt-Lock flag isn't set
|
||||
if (GET_L)
|
||||
return;
|
||||
|
||||
/* quick exit if nothing */
|
||||
// quick exit if nothing
|
||||
if (TIMER == NO_TIMER && (ISR & 0x7f) == 0)
|
||||
return;
|
||||
|
||||
if (TIMER == NO_TIMER)
|
||||
// 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)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT4, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
return;
|
||||
}
|
||||
standard_irq_callback(IRQ_IO3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO3));
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00300000)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO3));
|
||||
return;
|
||||
}
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
|
||||
/* timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt */
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00300000)
|
||||
{
|
||||
m_core->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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT1));
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT1 is priority 7; state is in bit 0 of ISR; FCR bit 28 inhibits interrupt */
|
||||
if (INT1_LINE_STATE && (FCR & 0x10000000) == 0x00000000)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT1));
|
||||
return;
|
||||
}
|
||||
// timer int might be priority 8 if FCR bits 20-21 == 2; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00200000)
|
||||
{
|
||||
m_core->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 (TIMER && (FCR & 0x00b00000) == 0x00200000)
|
||||
{
|
||||
m_core->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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT2));
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT2 is priority 9; state is in bit 1 of ISR; FCR bit 29 inhibits interrupt */
|
||||
if (INT2_LINE_STATE && (FCR & 0x20000000) == 0x00000000)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT2));
|
||||
return;
|
||||
}
|
||||
// timer int might be priority 10 if FCR bits 20-21 == 1; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00100000)
|
||||
{
|
||||
m_core->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 (TIMER && (FCR & 0x00b00000) == 0x00100000)
|
||||
{
|
||||
m_core->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)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT3));
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT3 is priority 11; state is in bit 2 of ISR; FCR bit 30 inhibits interrupt */
|
||||
if (INT3_LINE_STATE && (FCR & 0x40000000) == 0x00000000)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT3, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT3));
|
||||
return;
|
||||
}
|
||||
// timer int might be priority 12 if FCR bits 20-21 == 0; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00000000)
|
||||
{
|
||||
m_core->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 (TIMER && (FCR & 0x00b00000) == 0x00000000)
|
||||
{
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
return;
|
||||
}
|
||||
// INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt
|
||||
if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT4, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_INT4));
|
||||
return;
|
||||
}
|
||||
|
||||
/* INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt */
|
||||
if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
|
||||
{
|
||||
standard_irq_callback(IRQ_INT4, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO1));
|
||||
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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO1, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
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)
|
||||
{
|
||||
standard_irq_callback(IRQ_IO2, m_core->global_regs[0]);
|
||||
execute_int(get_trap_addr(TRAPNO_IO2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1603,17 +1544,9 @@ void hyperstone_device::execute_run()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_core->intblock < 0)
|
||||
m_core->intblock = 0;
|
||||
|
||||
if (!m_instruction_length_valid)
|
||||
SET_ILC(get_instruction_length(m_pr16(PC)));
|
||||
|
||||
if (m_core->timer_int_pending)
|
||||
check_interrupts<IS_TIMER>();
|
||||
else
|
||||
check_interrupts<NO_TIMER>();
|
||||
|
||||
while (m_core->icount > 0)
|
||||
{
|
||||
#if E132XS_LOG_INTERPRETER_REGS
|
||||
@ -1622,6 +1555,15 @@ void hyperstone_device::execute_run()
|
||||
|
||||
debugger_instruction_hook(PC);
|
||||
|
||||
if (--m_core->intblock <= 0)
|
||||
{
|
||||
m_core->intblock = 0;
|
||||
if (m_core->timer_int_pending)
|
||||
check_interrupts<IS_TIMER>();
|
||||
else
|
||||
check_interrupts<NO_TIMER>();
|
||||
}
|
||||
|
||||
OP = m_pr16(PC);
|
||||
PC += 2;
|
||||
|
||||
@ -1898,19 +1840,7 @@ void hyperstone_device::execute_run()
|
||||
}
|
||||
|
||||
if (GET_T && GET_P && !m_core->delay_slot) /* Not in a Delayed Branch instructions */
|
||||
{
|
||||
uint32_t addr = get_trap_addr(TRAPNO_TRACE_EXCEPTION);
|
||||
execute_exception(addr);
|
||||
}
|
||||
|
||||
if (--m_core->intblock <= 0)
|
||||
{
|
||||
m_core->intblock = 0;
|
||||
if (m_core->timer_int_pending)
|
||||
check_interrupts<IS_TIMER>();
|
||||
else
|
||||
check_interrupts<NO_TIMER>();
|
||||
}
|
||||
execute_exception(TRAPNO_TRACE_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,27 +118,6 @@ class hyperstone_device : public cpu_device, public hyperstone_disassembler::con
|
||||
public:
|
||||
virtual ~hyperstone_device() override;
|
||||
|
||||
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();
|
||||
|
||||
void e116_16k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_4k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_8k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_16k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_4k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_8k_iram_map(address_map &map) ATTR_COLD;
|
||||
|
||||
static uint32_t imm_length(uint16_t op);
|
||||
|
||||
protected:
|
||||
// compilation boundaries -- how far back/forward does the analysis extend?
|
||||
enum : u32
|
||||
@ -277,28 +256,44 @@ protected:
|
||||
hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock,
|
||||
const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map);
|
||||
|
||||
// device-level overrides
|
||||
// device_t implementation
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_stop() override ATTR_COLD;
|
||||
|
||||
// device_execute_interface overrides
|
||||
// device_execute_interface implementation
|
||||
virtual uint32_t execute_min_cycles() const noexcept override;
|
||||
virtual uint32_t execute_max_cycles() const noexcept override;
|
||||
virtual void execute_run() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// device_memory_interface overrides
|
||||
// device_memory_interface implementation
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
// device_disasm_interface overrides
|
||||
// device_disasm_interface implementation
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
virtual u8 get_fp() const override;
|
||||
virtual bool get_h() const override;
|
||||
|
||||
// device_state_interface overrides
|
||||
// device_state_interface implementation
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
void dump_registers();
|
||||
#endif
|
||||
void update_timer_prescale();
|
||||
void compute_tr();
|
||||
void adjust_timer_interrupt();
|
||||
|
||||
void e116_16k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_4k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_8k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_16k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_4k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e132_8k_iram_map(address_map &map) ATTR_COLD;
|
||||
|
||||
static uint32_t imm_length(uint16_t op);
|
||||
|
||||
// address spaces
|
||||
const address_space_config m_program_config;
|
||||
const address_space_config m_io_config;
|
||||
@ -353,7 +348,7 @@ private:
|
||||
void hyperstone_br();
|
||||
void execute_trap(uint32_t addr);
|
||||
void execute_int(uint32_t addr);
|
||||
void execute_exception(uint32_t addr);
|
||||
void execute_exception(uint8_t trapno);
|
||||
void execute_software();
|
||||
|
||||
template <reg_bank DST_GLOBAL> uint64_t get_double_word(uint8_t dst_code, uint8_t dstf_code) const;
|
||||
@ -467,6 +462,7 @@ private:
|
||||
|
||||
/* internal compiler state */
|
||||
struct compiler_state;
|
||||
struct c_funcs;
|
||||
|
||||
void execute_run_drc();
|
||||
void flush_drc_cache();
|
||||
@ -480,7 +476,7 @@ private:
|
||||
void static_generate_interrupt_checks(drcuml_block &block, uml::code_label &label);
|
||||
void generate_interrupt_checks(drcuml_block &block, uml::code_label &labelnum, bool with_timer, int take_int, int take_timer);
|
||||
void generate_branch(drcuml_block &block, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc, bool update_cycles = true);
|
||||
void generate_update_cycles(drcuml_block &block, bool check_interrupts = true);
|
||||
void generate_update_cycles(drcuml_block &block);
|
||||
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);
|
||||
|
@ -18,6 +18,67 @@ struct hyperstone_device::compiler_state
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
C FUNCTION CALLBACKS
|
||||
***************************************************************************/
|
||||
|
||||
struct hyperstone_device::c_funcs
|
||||
{
|
||||
|
||||
static void unimplemented(void *param)
|
||||
{
|
||||
auto &that = *reinterpret_cast<hyperstone_device *>(param);
|
||||
fatalerror("PC=%08X: Unimplemented op %08X\n", that.PC, that.m_core->arg0);
|
||||
}
|
||||
|
||||
static void print(void *param)
|
||||
{
|
||||
auto &that = *reinterpret_cast<hyperstone_device *>(param);
|
||||
printf("%c: %08x\n", (char)that.m_core->arg0, that.m_core->arg1);
|
||||
}
|
||||
|
||||
static void standard_irq_callback(void *param)
|
||||
{
|
||||
auto &that = *reinterpret_cast<hyperstone_device *>(param);
|
||||
that.standard_irq_callback(that.m_core->arg0, that.m_core->global_regs[0]);
|
||||
}
|
||||
|
||||
static void debugger_exception_hook(void *param)
|
||||
{
|
||||
auto &that = *reinterpret_cast<hyperstone_device *>(param);
|
||||
that.debugger_exception_hook(int32_t(that.m_core->arg0));
|
||||
}
|
||||
|
||||
static void adjust_timer_interrupt(void *param)
|
||||
{
|
||||
reinterpret_cast<hyperstone_device *>(param)->adjust_timer_interrupt();
|
||||
}
|
||||
|
||||
static void compute_tr(void *param)
|
||||
{
|
||||
reinterpret_cast<hyperstone_device *>(param)->compute_tr();
|
||||
}
|
||||
|
||||
static void update_timer_prescale(void *param)
|
||||
{
|
||||
reinterpret_cast<hyperstone_device *>(param)->update_timer_prescale();
|
||||
}
|
||||
|
||||
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
|
||||
static void dump_registers(void *param)
|
||||
{
|
||||
reinterpret_cast<hyperstone_device *>(param)->dump_registers();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void total_cycles(void *param)
|
||||
{
|
||||
auto &that = *reinterpret_cast<hyperstone_device *>(param);
|
||||
that.m_core->numcycles = that.total_cycles();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define DRC_PC uml::mem(&m_core->global_regs[0])
|
||||
#define DRC_SR uml::mem(&m_core->global_regs[1])
|
||||
|
||||
@ -49,84 +110,6 @@ void hyperstone_device::execute_run_drc()
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
C FUNCTION CALLBACKS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
cfunc_unimplemented - handler for
|
||||
unimplemented opcdes
|
||||
-------------------------------------------------*/
|
||||
|
||||
inline void hyperstone_device::ccfunc_unimplemented()
|
||||
{
|
||||
fatalerror("PC=%08X: Unimplemented op %08X\n", PC, m_core->arg0);
|
||||
}
|
||||
|
||||
inline void hyperstone_device::ccfunc_print()
|
||||
{
|
||||
printf("%c: %08x\n", (char)m_core->arg0, m_core->arg1);
|
||||
}
|
||||
|
||||
inline void hyperstone_device::ccfunc_standard_irq_callback()
|
||||
{
|
||||
standard_irq_callback(m_core->arg0, m_core->global_regs[0]);
|
||||
}
|
||||
|
||||
static void cfunc_unimplemented(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->ccfunc_unimplemented();
|
||||
}
|
||||
|
||||
static void cfunc_adjust_timer_interrupt(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->adjust_timer_interrupt();
|
||||
}
|
||||
|
||||
static void cfunc_compute_tr(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->compute_tr();
|
||||
}
|
||||
|
||||
static void cfunc_update_timer_prescale(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->update_timer_prescale();
|
||||
}
|
||||
|
||||
static void cfunc_standard_irq_callback(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->ccfunc_standard_irq_callback();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void cfunc_print(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->ccfunc_print();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if E132XS_LOG_DRC_REGS
|
||||
static void cfunc_dump_registers(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->dump_registers();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
cfunc_total_cycles - compute the total number
|
||||
of cycles executed so far
|
||||
-------------------------------------------------*/
|
||||
|
||||
void hyperstone_device::ccfunc_total_cycles()
|
||||
{
|
||||
m_core->numcycles = total_cycles();
|
||||
}
|
||||
|
||||
static void cfunc_total_cycles(void *param)
|
||||
{
|
||||
((hyperstone_device *)param)->ccfunc_total_cycles();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
CACHE MANAGEMENT
|
||||
***************************************************************************/
|
||||
@ -278,7 +261,6 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
UML_LABEL(block, seqhead->pc | 0x80000000);
|
||||
|
||||
UML_MOV(block, I7, 0);
|
||||
UML_CALLH(block, *m_interrupt_checks);
|
||||
|
||||
/* iterate over instructions in the sequence and compile them */
|
||||
for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
|
||||
@ -350,6 +332,11 @@ void hyperstone_device::static_generate_exception(drcuml_block &block, uml::code
|
||||
UML_HANDLE(block, *m_exception);
|
||||
|
||||
UML_GETEXP(block, I0); // I0 = exception code
|
||||
if (machine().debug_flags & DEBUG_FLAG_ENABLED)
|
||||
{
|
||||
UML_MOV(block, mem(&m_core->arg0), I0); // let the debugger know
|
||||
UML_CALLC(block, &c_funcs::debugger_exception_hook, this);
|
||||
}
|
||||
generate_get_trap_addr(block, label, uml::I0); // I0 = target PC
|
||||
|
||||
UML_MOV(block, I4, DRC_SR); // I4 = old SR
|
||||
@ -392,8 +379,6 @@ void hyperstone_device::static_generate_interrupt_checks(drcuml_block &block, um
|
||||
const int dispatch_int = label++;
|
||||
const int done_int = label++;
|
||||
|
||||
UML_CMP(block, mem(&m_core->intblock), 0);
|
||||
UML_JMPc(block, uml::COND_G, done_int);
|
||||
UML_TEST(block, DRC_SR, L_MASK);
|
||||
UML_JMPc(block, uml::COND_NZ, done_int);
|
||||
|
||||
@ -413,7 +398,7 @@ void hyperstone_device::static_generate_interrupt_checks(drcuml_block &block, um
|
||||
UML_JMP(block, done_int);
|
||||
|
||||
UML_LABEL(block, take_int);
|
||||
UML_CALLC(block, cfunc_standard_irq_callback, this);
|
||||
UML_CALLC(block, &c_funcs::standard_irq_callback, this);
|
||||
UML_JMP(block, dispatch_int);
|
||||
|
||||
UML_LABEL(block, take_timer);
|
||||
@ -638,17 +623,8 @@ void hyperstone_device::generate_interrupt_checks(drcuml_block &block, uml::code
|
||||
an exception if out
|
||||
-------------------------------------------------*/
|
||||
|
||||
void hyperstone_device::generate_update_cycles(drcuml_block &block, bool check_interrupts)
|
||||
void hyperstone_device::generate_update_cycles(drcuml_block &block)
|
||||
{
|
||||
// clobbers I0
|
||||
|
||||
UML_SUB(block, I0, mem(&m_core->intblock), 1);
|
||||
UML_MOVc(block, uml::COND_S, I0, 0);
|
||||
UML_MOV(block, mem(&m_core->intblock), I0);
|
||||
|
||||
if (check_interrupts)
|
||||
UML_CALLH(block, *m_interrupt_checks);
|
||||
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I7);
|
||||
UML_MOV(block, I7, 0);
|
||||
UML_CALLHc(block, uml::COND_LE, *m_out_of_cycles);
|
||||
@ -754,7 +730,7 @@ void hyperstone_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc,
|
||||
|
||||
void hyperstone_device::generate_branch(drcuml_block &block, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc, bool update_cycles)
|
||||
{
|
||||
// clobbers I0, I1, I2, I3 and I4 if update_cycles is true
|
||||
// clobbers I0 and I1 if mode is BRANCH_TARGET_DYNAMIC
|
||||
|
||||
if (desc)
|
||||
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
@ -792,7 +768,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
|
||||
UML_MAPVAR(block, MAPVAR_PC, expc);
|
||||
|
||||
#if E132XS_LOG_DRC_REGS
|
||||
UML_CALLC(block, cfunc_dump_registers, this);
|
||||
UML_CALLC(block, &c_funcs::dump_registers, this);
|
||||
#endif
|
||||
|
||||
// if we are debugging, call the debugger
|
||||
@ -802,6 +778,12 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
|
||||
UML_DEBUG(block, desc->pc);
|
||||
}
|
||||
|
||||
// check for pending interrupts
|
||||
UML_SUB(block, I0, mem(&m_core->intblock), 1);
|
||||
UML_MOVc(block, uml::COND_S, I0, 0);
|
||||
UML_MOV(block, mem(&m_core->intblock), I0);
|
||||
UML_CALLHc(block, uml::COND_LE, *m_interrupt_checks);
|
||||
|
||||
if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
// compile the instruction
|
||||
@ -809,7 +791,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
|
||||
{
|
||||
UML_MOV(block, DRC_PC, desc->pc);
|
||||
UML_MOV(block, mem(&m_core->arg0), desc->opptr.w[0]);
|
||||
UML_CALLC(block, cfunc_unimplemented, this);
|
||||
UML_CALLC(block, &c_funcs::unimplemented, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,10 +157,10 @@ void hyperstone_device::generate_set_global_register(drcuml_block &block, compil
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
UML_TEST(block, I5, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_NZ, skip_compute_tr);
|
||||
UML_CALLC(block, cfunc_compute_tr, this);
|
||||
UML_CALLC(block, cfunc_update_timer_prescale, this);
|
||||
UML_CALLC(block, &c_funcs::compute_tr, this);
|
||||
UML_CALLC(block, &c_funcs::update_timer_prescale, this);
|
||||
UML_LABEL(block, skip_compute_tr);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
}
|
||||
else if (dst_code == TCR_REGISTER)
|
||||
{
|
||||
@ -169,16 +169,16 @@ void hyperstone_device::generate_set_global_register(drcuml_block &block, compil
|
||||
UML_CMP(block, I6, I5);
|
||||
UML_JMPc(block, uml::COND_E, done);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else if (dst_code == TR_REGISTER)
|
||||
{
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
UML_MOV(block, mem(&m_core->tr_base_value), I5);
|
||||
UML_CALLC(block, cfunc_total_cycles, this);
|
||||
UML_CALLC(block, &c_funcs::total_cycles, this);
|
||||
UML_DMOV(block, mem(&m_core->tr_base_cycles), mem(&m_core->numcycles));
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
}
|
||||
else if (dst_code == ISR_REGISTER)
|
||||
{
|
||||
@ -191,7 +191,7 @@ void hyperstone_device::generate_set_global_register(drcuml_block &block, compil
|
||||
UML_XOR(block, I6, I6, I5);
|
||||
UML_TEST(block, I6, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_Z, skip_adjust_timer);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
UML_LABEL(block, skip_adjust_timer);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
}
|
||||
@ -291,10 +291,10 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||
UML_TEST(block, src, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_NZ, skip_compute_tr);
|
||||
UML_CALLC(block, cfunc_compute_tr, this);
|
||||
UML_CALLC(block, cfunc_update_timer_prescale, this);
|
||||
UML_CALLC(block, &c_funcs::compute_tr, this);
|
||||
UML_CALLC(block, &c_funcs::update_timer_prescale, this);
|
||||
UML_LABEL(block, skip_compute_tr);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
}
|
||||
break;
|
||||
case TCR_REGISTER: // G22 Timer Compare Register
|
||||
@ -304,16 +304,16 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
||||
UML_CMP(block, I6, src);
|
||||
UML_JMPc(block, uml::COND_E, done);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
break;
|
||||
case TR_REGISTER: // G23 Timer Register
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||
UML_MOV(block, mem(&m_core->tr_base_value), src);
|
||||
UML_CALLC(block, cfunc_total_cycles, this);
|
||||
UML_CALLC(block, &c_funcs::total_cycles, this);
|
||||
UML_DMOV(block, mem(&m_core->tr_base_cycles), mem(&m_core->numcycles));
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
break;
|
||||
case ISR_REGISTER: // G25 Input Status Register (read-only)
|
||||
break;
|
||||
@ -324,7 +324,7 @@ void hyperstone_device::generate_set_global_register_high(drcuml_block &block, c
|
||||
UML_XOR(block, I6, I6, src);
|
||||
UML_TEST(block, I6, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_Z, skip_adjust_timer);
|
||||
UML_CALLC(block, cfunc_adjust_timer_interrupt, this);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
UML_LABEL(block, skip_adjust_timer);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), src);
|
||||
}
|
||||
@ -387,7 +387,19 @@ void hyperstone_device::generate_set_dst(drcuml_block &block, compiler_state &co
|
||||
if (code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
if (src.is_int_register() && (desc->targetpc == BRANCH_TARGET_DYNAMIC))
|
||||
{
|
||||
UML_AND(block, src, src, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, src, desc);
|
||||
}
|
||||
else if (src.is_immediate() && (desc->targetpc == BRANCH_TARGET_DYNAMIC))
|
||||
{
|
||||
generate_branch(block, compiler.m_mode, src.immediate() & ~uint32_t(1), desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -489,7 +501,7 @@ void hyperstone_device::generate_trap_exception_or_int(drcuml_block &block, uml:
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I4, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
UML_MOV(block, DRC_PC, I0); // branch to exception handler
|
||||
generate_branch(block, 1, DRC_PC, nullptr, true); // T cleared and S set - mode will always be 1
|
||||
generate_branch(block, 1, uml::I0, nullptr, true); // T cleared and S set - mode will always be 1
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_int(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t addr)
|
||||
@ -581,7 +593,7 @@ void hyperstone_device::generate_software(drcuml_block &block, compiler_state &c
|
||||
UML_ROLINS(block, I0, I4, FP_SHIFT, FP_MASK); // SET_FP(reg)
|
||||
UML_MOV(block, DRC_SR, I0);
|
||||
|
||||
generate_branch(block, compiler.m_mode & 0x1, desc->targetpc, desc); // T cleared - only keep S in bit zero of mode
|
||||
generate_branch(block, compiler.m_mode & 0x1, uml::I5, desc); // T cleared - only keep S in bit zero of mode
|
||||
}
|
||||
|
||||
|
||||
@ -1138,7 +1150,7 @@ void hyperstone_device::generate_get_global_register(drcuml_block &block, compil
|
||||
UML_CMP(block, mem(&m_core->icount), I2);
|
||||
UML_MOVc(block, uml::COND_BE, I2, 0);
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I2);
|
||||
UML_CALLC(block, cfunc_compute_tr, this);
|
||||
UML_CALLC(block, &c_funcs::compute_tr, this);
|
||||
UML_MOV(block, I5, mem(&m_core->tr_result));
|
||||
UML_JMP(block, done);
|
||||
|
||||
@ -1207,7 +1219,8 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
UML_AND(block, I5, I5, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I5, desc);
|
||||
}
|
||||
UML_JMP(block, done);
|
||||
|
||||
@ -1637,7 +1650,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
generate_branch(block, compiler.m_mode, src & ~uint32_t(1), desc);
|
||||
}
|
||||
UML_JMP(block, done);
|
||||
|
||||
@ -2584,7 +2597,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2603,7 +2619,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2624,8 +2643,11 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
if (SRC_GLOBAL)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == 0)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2651,7 +2673,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2668,7 +2693,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2701,7 +2729,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == 0)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2720,7 +2751,10 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, desc);
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler.m_mode, uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4029,11 +4063,12 @@ void hyperstone_device::generate_call(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLINS(block, DRC_SR, 6, FL_SHIFT, FL_MASK);
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
|
||||
UML_ADD(block, DRC_PC, I2, extra_s & ~1);
|
||||
UML_ADD(block, I2, I2, extra_s & ~uint32_t(1));
|
||||
UML_MOV(block, DRC_PC, I2);
|
||||
|
||||
UML_MOV(block, mem(&m_core->intblock), 2);
|
||||
|
||||
generate_branch(block, compiler.m_mode, desc->targetpc, nullptr);
|
||||
generate_branch(block, compiler.m_mode, uml::I2, nullptr);
|
||||
//TODO: add interrupt locks, errors, ....
|
||||
}
|
||||
|
||||
|
@ -37,13 +37,13 @@ void hyperstone_device::hyperstone_chk()
|
||||
if (SRC_GLOBAL && (src_code == SR_REGISTER))
|
||||
{
|
||||
if (dreg == 0)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
|
||||
if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (dreg >= sreg) : (dreg > sreg))
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
@ -81,7 +81,7 @@ void hyperstone_device::hyperstone_movd()
|
||||
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))
|
||||
execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
|
||||
execute_exception(TRAPNO_PRIVILEGE_ERROR);
|
||||
|
||||
for (int difference = util::sext(GET_FP - ((SP & 0x1fc) >> 2), 7); difference < 0; difference++)
|
||||
{
|
||||
@ -157,7 +157,7 @@ void hyperstone_device::hyperstone_divsu()
|
||||
//Z -> undefined
|
||||
//N -> undefined
|
||||
SR |= V_MASK;
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -214,7 +214,7 @@ void hyperstone_device::hyperstone_xm()
|
||||
if (sub_type < 4)
|
||||
{
|
||||
if ((SRC_GLOBAL && ((src_code == PC_REGISTER)) ? (sreg >= extra_u) : (sreg > extra_u)))
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
@ -304,7 +304,7 @@ void hyperstone_device::hyperstone_sums()
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
if ((SR & V_MASK) && src_code != SR_REGISTER)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -347,7 +347,7 @@ void hyperstone_device::hyperstone_mov()
|
||||
SR &= ~H_MASK;
|
||||
if (DST_GLOBAL && h && !(SR & S_MASK))
|
||||
{
|
||||
execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
|
||||
execute_exception(TRAPNO_PRIVILEGE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -449,7 +449,7 @@ void hyperstone_device::hyperstone_adds()
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -667,7 +667,7 @@ void hyperstone_device::hyperstone_subs()
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -802,7 +802,7 @@ void hyperstone_device::hyperstone_negs()
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
if (GET_V)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -854,7 +854,7 @@ void hyperstone_device::hyperstone_movi()
|
||||
SR &= ~H_MASK;
|
||||
if (DST_GLOBAL && h && !(SR & S_MASK))
|
||||
{
|
||||
execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
|
||||
execute_exception(TRAPNO_PRIVILEGE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -981,7 +981,7 @@ void hyperstone_device::hyperstone_addsi()
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
execute_exception(TRAPNO_RANGE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@ -2559,7 +2559,7 @@ void hyperstone_device::hyperstone_frame()
|
||||
while (difference < 0);
|
||||
|
||||
if (tmp_flag)
|
||||
execute_exception(get_trap_addr(TRAPNO_FRAME_ERROR));
|
||||
execute_exception(TRAPNO_FRAME_ERROR);
|
||||
}
|
||||
|
||||
// TODO: More than 1 cycle!
|
||||
|
Loading…
Reference in New Issue
Block a user