mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
-cpu/e132xs.cpp: Improved exception emulation:
* Fixed behaviour of exceptions in delay slots, and fixed recompiler not updating ILC and P for some exceptions. * Implemented privilege error exception on setting L in user mode for interpreter. -emu/debug, osd/modules/debugger: Added an option to show exceptionpoints in breakpoints windows.
This commit is contained in:
parent
e0ea955d1b
commit
1dca832b37
@ -237,20 +237,22 @@ files {
|
||||
MAME_DIR .. "src/emu/debug/debughlp.h",
|
||||
MAME_DIR .. "src/emu/debug/debugvw.cpp",
|
||||
MAME_DIR .. "src/emu/debug/debugvw.h",
|
||||
MAME_DIR .. "src/emu/debug/dvdisasm.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvdisasm.h",
|
||||
MAME_DIR .. "src/emu/debug/dvmemory.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvmemory.h",
|
||||
MAME_DIR .. "src/emu/debug/dvbpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvbpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvdisasm.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvdisasm.h",
|
||||
MAME_DIR .. "src/emu/debug/dvepoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvepoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvmemory.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvmemory.h",
|
||||
MAME_DIR .. "src/emu/debug/dvrpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvrpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvstate.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvstate.h",
|
||||
MAME_DIR .. "src/emu/debug/dvtext.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvtext.h",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/express.cpp",
|
||||
MAME_DIR .. "src/emu/debug/express.h",
|
||||
MAME_DIR .. "src/emu/debug/points.cpp",
|
||||
|
@ -103,6 +103,8 @@ project ("osd_" .. _OPTIONS["osd"])
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/exceptionpointsview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/exceptionpointsview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/memoryview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/memoryview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/memoryviewer.mm",
|
||||
|
@ -357,6 +357,8 @@ project ("osd_" .. _OPTIONS["osd"])
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyviewer.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/exceptionpointsview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/exceptionpointsview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.h",
|
||||
|
@ -871,7 +871,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
// LD/STHS.D/A
|
||||
util::stream_format(stream, "%sH%c.%c %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', mode, dest, source, dis & ~1);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1)));
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1)) & ~1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -888,7 +888,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
util::stream_format(stream, "%s%c.%c %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', mode, dest, source, dis & ~3);
|
||||
}
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)) & ~3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -921,23 +921,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
case 0:
|
||||
// LD/STBS.N
|
||||
util::stream_format(stream, "%sBS.N %s, %s, $%x", inst, dest, source, dis);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// LD/STBU.N
|
||||
util::stream_format(stream, "%sBU.N %s, %s, $%x", inst, dest, source, dis);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// LD/STHU.N
|
||||
// LD/STHS.N
|
||||
util::stream_format(stream, "%sH%c.N %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', dest, source, dis & ~1);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1)));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -945,8 +939,6 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
{
|
||||
// LD/STW.S
|
||||
util::stream_format(stream, "%sW.S %s, %s, $%x", inst, dest, source, dis & ~3);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
|
||||
}
|
||||
else if ((dis & 3) == 2)
|
||||
{
|
||||
@ -958,8 +950,6 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
|
||||
// LD/STW.N
|
||||
// LD/STD.N
|
||||
util::stream_format(stream, "%s%c.N %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', dest, source, dis & ~3);
|
||||
if (!dest_bit && (dest_code == PC_REGISTER))
|
||||
util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
TODO:
|
||||
- All instructions should clear the H flag (not just MOV/MOVI)
|
||||
- Fix behaviour of exceptions in delay slots
|
||||
- Fix behaviour of branches in delay slots
|
||||
- Many wrong cycle counts
|
||||
- No emulation of memory access latency and pipleline
|
||||
@ -41,9 +40,6 @@
|
||||
- Verify register wrapping with sregf/dregf on hardware
|
||||
- Tracing doesn't work properly
|
||||
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
|
||||
- Support for debugger exception points should be implemented
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
@ -489,9 +485,11 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
|
||||
return;
|
||||
case SR_REGISTER:
|
||||
{
|
||||
// FIXME: generate exception on attempt to set L from user mode const bool exception = !GET_S && !GET_L && (val & L_MASK);
|
||||
const bool privilege_error = !GET_S && !GET_L && (val & L_MASK);
|
||||
SET_LOW_SR(val); // only a RET instruction can change the full content of SR
|
||||
SR &= ~0x40; //reserved bit 6 always zero
|
||||
SR &= ~0x40; // reserved bit 6 always zero
|
||||
if (privilege_error)
|
||||
execute_exception(TRAPNO_PRIVILEGE_ERROR);
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
@ -584,8 +582,14 @@ do
|
||||
/* if PC is used in a delay instruction, the delayed PC should be used */ \
|
||||
if (m_core->delay_slot) \
|
||||
{ \
|
||||
PC = m_core->delay_pc; \
|
||||
using std::swap; \
|
||||
swap(PC, m_core->delay_pc); \
|
||||
m_core->delay_slot = 0; \
|
||||
m_core->delay_slot_taken = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
m_core->delay_slot_taken = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -761,7 +765,16 @@ void hyperstone_device::execute_exception(uint8_t trapno)
|
||||
|
||||
const uint32_t addr = get_trap_addr(trapno);
|
||||
const uint8_t reg = GET_FP + GET_FL;
|
||||
SET_ILC(m_instruction_length);
|
||||
|
||||
if (!m_core->delay_slot_taken)
|
||||
SET_ILC(m_instruction_length);
|
||||
else
|
||||
PC = m_core->delay_pc;
|
||||
|
||||
// RET does not automatically set P
|
||||
if (((m_op & 0xfef0) != 0x0400) || !(m_op & 0x010e))
|
||||
SET_P(1);
|
||||
|
||||
const uint32_t oldSR = SR;
|
||||
|
||||
SET_FL(2);
|
||||
@ -1101,9 +1114,9 @@ void hyperstone_device::device_start()
|
||||
save_item(NAME(m_core->global_regs));
|
||||
save_item(NAME(m_core->local_regs));
|
||||
save_item(NAME(m_core->trap_entry));
|
||||
save_item(NAME(m_core->delay_pc));
|
||||
save_item(NAME(m_instruction_length));
|
||||
save_item(NAME(m_core->intblock));
|
||||
save_item(NAME(m_core->delay_pc));
|
||||
save_item(NAME(m_core->delay_slot));
|
||||
save_item(NAME(m_core->delay_slot_taken));
|
||||
save_item(NAME(m_core->tr_clocks_per_tick));
|
||||
|
@ -466,16 +466,16 @@ private:
|
||||
std::pair<uint16_t, uint32_t> generate_get_d_code_dis(const opcode_desc *opcode);
|
||||
|
||||
void generate_get_global_register_high(drcuml_block &block, compiler_state &compiler, uint32_t code, uml::parameter dst);
|
||||
void generate_set_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code);
|
||||
void generate_set_global_register_low(drcuml_block &block, compiler_state &compiler, uint32_t dst_code, uml::parameter src);
|
||||
void generate_set_global_register_low(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code, uml::parameter src);
|
||||
void generate_set_global_register_high(drcuml_block &block, compiler_state &compiler, uint32_t dst_code, uml::parameter src);
|
||||
|
||||
void generate_load_operand(drcuml_block &block, compiler_state &compiler, reg_bank global, uint32_t code, uml::parameter dst, uml::parameter localidx);
|
||||
void generate_load_src_addsub(drcuml_block &block, compiler_state &compiler, reg_bank global, uint32_t code, uml::parameter dst, uml::parameter localidx, uml::parameter sr);
|
||||
uml::parameter generate_load_address_ad(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter dst, uml::parameter localidx);
|
||||
void generate_load_address_ns(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter dst, uml::parameter localidx, uint16_t d_code, uint32_t dis);
|
||||
void generate_load_address_rp(drcuml_block &block, compiler_state &compiler, uint32_t code, uml::parameter dst, uml::parameter localidx, uint32_t dis);
|
||||
void generate_load_address_rp(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t code, uml::parameter dst, uml::parameter localidx, uint32_t dis);
|
||||
void generate_add_dis(drcuml_block &block, compiler_state &compiler, uml::parameter dst, uml::parameter base, uint32_t dis, unsigned alignment);
|
||||
void generate_set_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter src, uml::parameter localidx, bool calcidx);
|
||||
void generate_set_dst(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter src, uml::parameter localidx, bool calcidx);
|
||||
void generate_update_flags_addsub(drcuml_block &block, compiler_state &compiler, uml::parameter sr);
|
||||
void generate_update_flags_addsubc(drcuml_block &block, compiler_state &compiler, uml::parameter sr);
|
||||
@ -487,7 +487,9 @@ private:
|
||||
template <trap_exception_or_int TYPE> void generate_trap_exception_or_int(drcuml_block &block, uml::code_label &label, uml::parameter trapno);
|
||||
void generate_software(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc);
|
||||
|
||||
void generate_trap_on_overflow(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uml::parameter sr);
|
||||
void generate_raise_exception(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t trapno, uml::parameter sr);
|
||||
void generate_raise_exception(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t trapno);
|
||||
void generate_exception_on_overflow(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uml::parameter sr);
|
||||
template <reg_bank DstGlobal, reg_bank SrcGlobal, typename T> void generate_logic_op(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, T &&body);
|
||||
template <reg_bank DstGlobal, typename T> void generate_logic_op_imm(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code, T &&body);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// copyright-holders:Ryan Holtz, Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "e132xs.h"
|
||||
@ -799,17 +799,19 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
|
||||
if (compiler.check_delay())
|
||||
{
|
||||
// if PC is used in a delay instruction, the delayed PC should be used
|
||||
const int nodelay = compiler.next_label();
|
||||
const int set_delay_pc = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
UML_TEST(block, mem(&m_core->delay_slot), 1);
|
||||
UML_JMPc(block, uml::COND_Z, nodelay);
|
||||
UML_TEST(block, mem(&m_core->delay_slot), ~uint32_t(0));
|
||||
UML_JMPc(block, uml::COND_NZ, set_delay_pc);
|
||||
|
||||
UML_ADD(block, DRC_PC, DRC_PC, desc->length);
|
||||
UML_MOV(block, mem(&m_core->delay_slot_taken), 0);
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, set_delay_pc);
|
||||
UML_MOV(block, DRC_PC, mem(&m_core->delay_pc));
|
||||
UML_MOV(block, mem(&m_core->delay_slot), 0);
|
||||
UML_MOV(block, mem(&m_core->delay_slot_taken), 1);
|
||||
UML_JMP(block, done);
|
||||
UML_LABEL(block, nodelay);
|
||||
UML_ADD(block, DRC_PC, DRC_PC, desc->length);
|
||||
UML_MOV(block, mem(&m_core->delay_slot_taken), 0);
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// copyright-holders:Ryan Holtz, Vas Crabb
|
||||
#ifndef MAME_CPU_E132XS_E132XSDRC_OPS_HXX
|
||||
#define MAME_CPU_E132XS_E132XSDRC_OPS_HXX
|
||||
|
||||
@ -150,101 +150,7 @@ void hyperstone_device::generate_get_global_register_high(drcuml_block &block, c
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_set_global_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code)
|
||||
{
|
||||
// TODO: this function should be refactored away
|
||||
// Expects value in I5, clobbers I6 when setting high registers
|
||||
if (dst_code < 16)
|
||||
{
|
||||
if (dst_code == 0)
|
||||
{
|
||||
UML_AND(block, DRC_PC, I5, ~1);
|
||||
}
|
||||
else if (dst_code == 1)
|
||||
{
|
||||
// TODO: privilege check on setting L in user mode
|
||||
UML_ROLINS(block, DRC_SR, I5, 0, 0x0000ffff);
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_SUB(block, mem(&m_core->icount), mem(&m_core->icount), I7);
|
||||
UML_MOV(block, I7, 0);
|
||||
|
||||
if ((dst_code <= 17) || (dst_code == BCR_REGISTER) || (dst_code == WCR_REGISTER))
|
||||
{
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
}
|
||||
else if (dst_code < BCR_REGISTER)
|
||||
{
|
||||
// SP or UB
|
||||
UML_AND(block, mem(&m_core->global_regs[dst_code]), I5, ~uint32_t(3));
|
||||
}
|
||||
else if (dst_code == TPR_REGISTER)
|
||||
{
|
||||
const int skip_compute_tr = compiler.next_label();
|
||||
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, &c_funcs::compute_tr, this);
|
||||
UML_CALLC(block, &c_funcs::update_timer_prescale, this);
|
||||
UML_LABEL(block, skip_compute_tr);
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
}
|
||||
else if (dst_code == TCR_REGISTER)
|
||||
{
|
||||
const int done = compiler.next_label();
|
||||
UML_MOV(block, I6, mem(&m_core->global_regs[dst_code]));
|
||||
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, &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, &c_funcs::total_cycles, this);
|
||||
UML_DMOV(block, mem(&m_core->tr_base_cycles), mem(&m_core->numcycles));
|
||||
UML_CALLC(block, &c_funcs::adjust_timer_interrupt, this);
|
||||
}
|
||||
else if (dst_code == ISR_REGISTER)
|
||||
{
|
||||
// ISR - read-only
|
||||
}
|
||||
else if (dst_code == FCR_REGISTER)
|
||||
{
|
||||
const int skip_adjust_timer = compiler.next_label();
|
||||
UML_MOV(block, I6, mem(&m_core->global_regs[dst_code]));
|
||||
UML_XOR(block, I6, I6, I5);
|
||||
UML_TEST(block, I6, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_Z, skip_adjust_timer);
|
||||
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);
|
||||
}
|
||||
else if (dst_code == MCR_REGISTER)
|
||||
{
|
||||
UML_ROLAND(block, I6, I5, 20, 0x7);
|
||||
UML_LOAD(block, I6, (void *)s_trap_entries, I6, SIZE_DWORD, SCALE_x4);
|
||||
UML_MOV(block, mem(&m_core->trap_entry), I6);
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// reserved register - just store the value
|
||||
UML_MOV(block, mem(&m_core->global_regs[dst_code]), I5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_set_global_register_low(drcuml_block &block, compiler_state &compiler, uint32_t dst_code, uml::parameter src)
|
||||
void hyperstone_device::generate_set_global_register_low(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t dst_code, uml::parameter src)
|
||||
{
|
||||
// clobbers I4 when setting SR
|
||||
if (dst_code == PC_REGISTER)
|
||||
@ -275,8 +181,7 @@ void hyperstone_device::generate_set_global_register_low(drcuml_block &block, co
|
||||
UML_ROLINS(block, I4, src, 0, 0x0000ffff);
|
||||
UML_AND(block, I4, I4, ~0x40); // keep reserved bit clear
|
||||
}
|
||||
UML_MOV(block, DRC_SR, I4);
|
||||
UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_PRIVILEGE_ERROR, uml::I4);
|
||||
UML_LABEL(block, no_exception);
|
||||
if (src.is_immediate())
|
||||
{
|
||||
@ -425,7 +330,7 @@ uml::parameter hyperstone_device::generate_load_address_ad(drcuml_block &block,
|
||||
else if ((code == PC_REGISTER) && ((desc->flags & OPFLAG_IN_DELAY_SLOT) || !compiler.check_delay()))
|
||||
{
|
||||
if (!compiler.pc())
|
||||
UML_EXH(block, *m_exception, TRAPNO_POINTER_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_POINTER_ERROR);
|
||||
return compiler.pc();
|
||||
}
|
||||
else
|
||||
@ -440,8 +345,11 @@ uml::parameter hyperstone_device::generate_load_address_ad(drcuml_block &block,
|
||||
UML_LOAD(block, dst, (void *)m_core->local_regs, localidx, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, dst, ~uint32_t(0));
|
||||
UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_POINTER_ERROR);
|
||||
UML_JMPc(block, uml::COND_NZ, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_POINTER_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
|
||||
return dst;
|
||||
}
|
||||
@ -474,12 +382,12 @@ void hyperstone_device::generate_load_address_ns(drcuml_block &block, compiler_s
|
||||
UML_MOV(block, mem(&m_core->global_regs[code]), dst);
|
||||
else
|
||||
UML_STORE(block, (void *)m_core->local_regs, localidx, dst, SIZE_DWORD, SCALE_x4);
|
||||
UML_EXH(block, *m_exception, TRAPNO_POINTER_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_POINTER_ERROR);
|
||||
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_load_address_rp(drcuml_block &block, compiler_state &compiler, uint32_t code, uml::parameter dst, uml::parameter localidx, uint32_t dis)
|
||||
void hyperstone_device::generate_load_address_rp(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t code, uml::parameter dst, uml::parameter localidx, uint32_t dis)
|
||||
{
|
||||
// expects frame pointer in I3 if local
|
||||
// sets I0 to masked address
|
||||
@ -488,25 +396,42 @@ void hyperstone_device::generate_load_address_rp(drcuml_block &block, compiler_s
|
||||
|
||||
generate_load_operand(block, compiler, LOCAL, code, dst, localidx);
|
||||
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, dst, ~uint32_t(0));
|
||||
UML_JMPc(block, uml::COND_NZ, no_exception);
|
||||
if (dis)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_JMPc(block, uml::COND_NZ, no_exception);
|
||||
UML_ADD(block, dst, dst, dis);
|
||||
UML_STORE(block, (void *)m_core->local_regs, localidx, dst, SIZE_DWORD, SCALE_x4);
|
||||
UML_EXH(block, *m_exception, TRAPNO_POINTER_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_POINTER_ERROR);
|
||||
}
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_POINTER_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
|
||||
UML_AND(block, I0, dst, ~uint32_t(3));
|
||||
}
|
||||
|
||||
|
||||
void hyperstone_device::generate_set_register(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter src, uml::parameter localidx, bool calcidx)
|
||||
{
|
||||
// expects frame pointer in I3 if local and calcidx is true
|
||||
// sets localidx if local and calcidx is true before storing src
|
||||
// localidx is input if local and calcidx is false
|
||||
// clobbers I4 when setting SR
|
||||
if (global)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, desc, code, src);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (calcidx)
|
||||
{
|
||||
UML_ADD(block, localidx, I3, code);
|
||||
UML_AND(block, localidx, localidx, 0x3f);
|
||||
}
|
||||
UML_STORE(block, (void *)m_core->local_regs, localidx, src, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_set_dst(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, reg_bank global, uint32_t code, uml::parameter src, uml::parameter localidx, bool calcidx)
|
||||
{
|
||||
// expects frame pointer in I3 if local and calcidx is true
|
||||
@ -515,7 +440,7 @@ void hyperstone_device::generate_set_dst(drcuml_block &block, compiler_state &co
|
||||
// clobbers I4 when setting SR
|
||||
if (global)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, code, src);
|
||||
generate_set_global_register_low(block, compiler, desc, code, src);
|
||||
if (code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
@ -646,6 +571,55 @@ void hyperstone_device::generate_update_nz_d(drcuml_block &block, compiler_state
|
||||
}
|
||||
|
||||
|
||||
void hyperstone_device::generate_raise_exception(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t trapno, uml::parameter sr)
|
||||
{
|
||||
if (desc->flags & OPFLAG_IN_DELAY_SLOT)
|
||||
{
|
||||
// definitely in delay slot - saved PC/ILC reflect delayed branch
|
||||
UML_OR(block, sr, sr, P_MASK);
|
||||
UML_MOV(block, DRC_PC, desc->pc);
|
||||
}
|
||||
else if (!compiler.check_delay())
|
||||
{
|
||||
// not in delay slot - saved PC/ILC reflect current instruction
|
||||
UML_ROLINS(block, sr, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
// possibly in delay slot
|
||||
const int set_delay_pc = compiler.next_label();
|
||||
const int done = compiler.next_label();
|
||||
UML_TEST(block, mem(&m_core->delay_slot_taken), ~uint32_t(0));
|
||||
UML_JMPc(block, uml::COND_NZ, set_delay_pc);
|
||||
|
||||
UML_ROLINS(block, sr, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, set_delay_pc);
|
||||
UML_OR(block, sr, sr, P_MASK);
|
||||
UML_MOV(block, DRC_PC, desc->pc);
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
UML_MOV(block, DRC_SR, sr);
|
||||
UML_EXH(block, *m_exception, trapno);
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_raise_exception(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t trapno)
|
||||
{
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
generate_raise_exception(block, compiler, desc, trapno, uml::I2);
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_exception_on_overflow(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uml::parameter sr)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, sr, V_MASK);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR, sr);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
|
||||
template <hyperstone_device::trap_exception_or_int TYPE>
|
||||
void hyperstone_device::generate_trap_exception_or_int(drcuml_block &block, uml::code_label &label, uml::parameter trapno)
|
||||
{
|
||||
@ -696,17 +670,6 @@ void hyperstone_device::generate_trap_exception_or_int(drcuml_block &block, uml:
|
||||
UML_HASHJMP(block, 1, I0, *m_nocode); // T cleared and S set - mode will always be 1
|
||||
}
|
||||
|
||||
void hyperstone_device::generate_trap_on_overflow(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uml::parameter sr)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, sr, V_MASK);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
UML_ROLINS(block, sr, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
UML_MOV(block, DRC_SR, sr);
|
||||
UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal, typename T>
|
||||
inline void hyperstone_device::generate_logic_op(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, T &&body)
|
||||
@ -892,9 +855,7 @@ void hyperstone_device::generate_chk(drcuml_block &block, compiler_state &compil
|
||||
}
|
||||
}
|
||||
|
||||
UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR, uml::I2);
|
||||
|
||||
if (!unconditional)
|
||||
UML_LABEL(block, done);
|
||||
@ -994,9 +955,8 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~N_MASK);
|
||||
if (DstGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, dst_code, 0);
|
||||
UML_MOV(block, I5, 0);
|
||||
generate_set_global_register(block, compiler, desc, dstf_code);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, 0);
|
||||
generate_set_global_register_low(block, compiler, desc, dstf_code, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1011,10 +971,9 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
||||
}
|
||||
else // Rd doesn't denote PC and Rs doesn't denote SR
|
||||
{
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
if (!SrcGlobal || !DstGlobal)
|
||||
{
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
}
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
@ -1023,39 +982,37 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I0, I3, src_code);
|
||||
UML_AND(block, I0, I0, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I0, SIZE_DWORD, SCALE_x4);
|
||||
UML_ADD(block, I1, I3, srcf_code);
|
||||
UML_ADD(block, I1, I3, src_code);
|
||||
UML_AND(block, I1, I1, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
UML_ADD(block, I1, I1, 1);
|
||||
UML_AND(block, I1, I1, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
|
||||
UML_OR(block, I2, I0, I1);
|
||||
UML_TEST(block, I2, ~0);
|
||||
UML_SETc(block, uml::COND_Z, I2);
|
||||
UML_ROLINS(block, DRC_SR, I2, Z_SHIFT, Z_MASK);
|
||||
|
||||
UML_TEST(block, I0, 0x80000000);
|
||||
UML_SETc(block, uml::COND_NZ, I2);
|
||||
UML_ROLINS(block, DRC_SR, I2, N_SHIFT, N_MASK);
|
||||
UML_AND(block, I2, I2, ~(Z_MASK | N_MASK));
|
||||
UML_OR(block, I4, I0, I1);
|
||||
UML_SETc(block, uml::COND_Z, I4);
|
||||
UML_ROLINS(block, I2, I4, Z_SHIFT, Z_MASK);
|
||||
UML_ROLAND(block, I4, I0, N_SHIFT + 1, N_MASK);
|
||||
UML_OR(block, I2, I2, I4);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
if (DstGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I0);
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, dstf_code);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, uml::I0);
|
||||
generate_set_global_register_low(block, compiler, desc, dstf_code, uml::I1);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, dst_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I0, SIZE_DWORD, SCALE_x4);
|
||||
UML_ADD(block, I2, I3, dstf_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I1, SIZE_DWORD, SCALE_x4);
|
||||
UML_ADD(block, I3, I3, dst_code);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I0, SIZE_DWORD, SCALE_x4);
|
||||
|
||||
UML_ADD(block, I3, I3, 1);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1138,8 +1095,7 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp
|
||||
UML_JMP(block, done);
|
||||
|
||||
UML_LABEL(block, no_result);
|
||||
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK | V_MASK, 0, ILC_MASK | P_MASK | V_MASK);
|
||||
UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
@ -1161,8 +1117,12 @@ void hyperstone_device::generate_xm(drcuml_block &block, compiler_state &compile
|
||||
if (next & 0x8000)
|
||||
extra_u = ((extra_u & 0xfff) << 16) | m_pr16(desc->pc + 4);
|
||||
|
||||
if ((SrcGlobal && (src_code == SR_REGISTER)) || (DstGlobal && (dst_code < 2)))
|
||||
if ((SrcGlobal && (src_code == SR_REGISTER)) || (DstGlobal && (dst_code <= SR_REGISTER)))
|
||||
{
|
||||
// reserved for future expansion
|
||||
osd_printf_error("Denoted PC or SR in hyperstone_xm. PC = %08X\n", desc->pc);
|
||||
return;
|
||||
}
|
||||
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
if (!SrcGlobal || !DstGlobal)
|
||||
@ -1172,22 +1132,19 @@ void hyperstone_device::generate_xm(drcuml_block &block, compiler_state &compile
|
||||
|
||||
UML_SHL(block, I0, I1, sub_type & 3);
|
||||
|
||||
// FIXME: exception before branch
|
||||
generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true);
|
||||
|
||||
if (sub_type < 4)
|
||||
{
|
||||
const int done = compiler.next_label();
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_CMP(block, I1, extra_u);
|
||||
if (SrcGlobal && (src_code == PC_REGISTER))
|
||||
UML_JMPc(block, uml::COND_B, done);
|
||||
UML_JMPc(block, uml::COND_B, no_exception);
|
||||
else
|
||||
UML_JMPc(block, uml::COND_BE, done);
|
||||
UML_JMPc(block, uml::COND_BE, no_exception);
|
||||
|
||||
UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, done);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR, uml::I2);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1283,9 +1240,22 @@ void hyperstone_device::generate_sums(drcuml_block &block, compiler_state &compi
|
||||
generate_update_flags_addsubs(block, compiler, uml::I2);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
// FIXME: exception before branch
|
||||
generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true);
|
||||
generate_trap_on_overflow(block, compiler, desc, uml::I2);
|
||||
generate_set_register(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true);
|
||||
generate_exception_on_overflow(block, compiler, desc, uml::I2);
|
||||
|
||||
if (DstGlobal && (dst_code == PC_REGISTER))
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
||||
{
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1320,16 +1290,21 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
|
||||
const uint32_t src_code = op & 0xf;
|
||||
const uint32_t dst_code = (op & 0xf0) >> 4;
|
||||
|
||||
UML_AND(block, I2, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
if (!SrcGlobal || !DstGlobal)
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (DstGlobal && compiler.user_mode())
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_PRIVILEGE_ERROR, uml::I2);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
UML_AND(block, I2, I2, ~(Z_MASK | N_MASK));
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
if (!DstGlobal || compiler.supervisor_mode())
|
||||
@ -1380,7 +1355,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I0);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, uml::I0);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
@ -1402,7 +1377,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
|
||||
else
|
||||
{
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, uml::I0);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, uml::I0);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
@ -1523,9 +1498,22 @@ void hyperstone_device::generate_adds(drcuml_block &block, compiler_state &compi
|
||||
generate_update_flags_addsubs(block, compiler, uml::I2);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
// FIXME: exception before branch
|
||||
generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, false);
|
||||
generate_trap_on_overflow(block, compiler, desc, uml::I2);
|
||||
generate_set_register(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, false);
|
||||
generate_exception_on_overflow(block, compiler, desc, uml::I2);
|
||||
|
||||
if (DstGlobal && (dst_code == PC_REGISTER))
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
||||
{
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1629,9 +1617,22 @@ void hyperstone_device::generate_subs(drcuml_block &block, compiler_state &compi
|
||||
generate_update_flags_addsubs(block, compiler, uml::I2);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
// FIXME: exception before branch
|
||||
generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, false);
|
||||
generate_trap_on_overflow(block, compiler, desc, uml::I2);
|
||||
generate_set_register(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, false);
|
||||
generate_exception_on_overflow(block, compiler, desc, uml::I2);
|
||||
|
||||
if (DstGlobal && (dst_code == PC_REGISTER))
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
||||
{
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1712,11 +1713,24 @@ void hyperstone_device::generate_negs(drcuml_block &block, compiler_state &compi
|
||||
generate_update_flags_addsubs(block, compiler, uml::I2);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
// FIXME: exception before branch
|
||||
generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true);
|
||||
generate_set_register(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true);
|
||||
|
||||
if (!SrcGlobal || (src_code != SR_REGISTER)) // negating carry cannot result in overflow
|
||||
generate_trap_on_overflow(block, compiler, desc, uml::I2);
|
||||
generate_exception_on_overflow(block, compiler, desc, uml::I2);
|
||||
|
||||
if (DstGlobal && (dst_code == PC_REGISTER))
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
||||
{
|
||||
UML_AND(block, I0, I0, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I0, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1829,14 +1843,18 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
else
|
||||
src = op & 0x0f;
|
||||
|
||||
UML_AND(block, I2, DRC_SR, ~(Z_MASK | N_MASK));
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
|
||||
if (DstGlobal && compiler.user_mode())
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_TEST(block, I2, H_MASK);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_Z, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_PRIVILEGE_ERROR, uml::I2);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
|
||||
UML_AND(block, I2, I2, ~(Z_MASK | N_MASK));
|
||||
if (!src)
|
||||
UML_OR(block, I2, I2, Z_MASK);
|
||||
else if (src & 0x80000000)
|
||||
@ -1856,7 +1874,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
UML_JMPc(block, uml::COND_NZ, highglobal);
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, src);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, src);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
@ -1877,7 +1895,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
|
||||
else
|
||||
{
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
generate_set_global_register_low(block, compiler, dst_code, src);
|
||||
generate_set_global_register_low(block, compiler, desc, dst_code, src);
|
||||
if (dst_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
|
||||
@ -2668,7 +2686,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
@ -2692,7 +2710,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
@ -2717,7 +2735,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
@ -2731,41 +2749,20 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // LDD.D/A
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
generate_set_register(block, compiler, desc, SrcGlobal, src_code, uml::I1, uml::I2, true);
|
||||
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
generate_set_register(block, compiler, desc, SrcGlobal, srcf_code, uml::I1, uml::I3, true);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, srcf_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I3, I3, srcf_code);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
break;
|
||||
|
||||
case 2: // LDW.IOD/A
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
|
||||
UML_ROLAND(block, I0, I0, 21, 0x7ffc);
|
||||
@ -2773,8 +2770,8 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == 0)
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I1, desc);
|
||||
@ -2792,37 +2789,14 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
|
||||
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
|
||||
UML_ROLAND(block, I0, I0, 21, 0x7ffc);
|
||||
UML_CALLH(block, *m_io_read32);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
if (src_code == PC_REGISTER)
|
||||
{
|
||||
UML_AND(block, I1, I1, ~uint32_t(1));
|
||||
generate_branch(block, compiler, compiler.mode(), uml::I1, desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
generate_set_register(block, compiler, desc, SrcGlobal, src_code, uml::I1, uml::I2, true);
|
||||
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_io_read32);
|
||||
generate_set_register(block, compiler, desc, SrcGlobal, srcf_code, uml::I1, uml::I3, true);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, srcf_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_ADD(block, I3, I3, srcf_code);
|
||||
UML_AND(block, I3, I3, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I1, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
if (src_code == PC_REGISTER)
|
||||
generate_branch(block, compiler, compiler.mode(), desc->targetpc, desc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2910,13 +2884,12 @@ void hyperstone_device::generate_ldxx2(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, srcf_code);
|
||||
generate_set_global_register_low(block, compiler, desc, srcf_code, uml::I1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3018,9 +2991,12 @@ void hyperstone_device::generate_stxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (sub_type == 0)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_SEXT(block, I0, I1, SIZE_BYTE);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_E, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3031,9 +3007,12 @@ void hyperstone_device::generate_stxx1(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (extra_s & 1)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_SEXT(block, I0, I1, SIZE_WORD);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_E, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3149,9 +3128,12 @@ void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (sub_type == 0)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_SEXT(block, I0, I1, SIZE_BYTE);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_E, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3169,9 +3151,12 @@ void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &comp
|
||||
|
||||
if (extra_s & 1)
|
||||
{
|
||||
const int no_exception = compiler.next_label();
|
||||
UML_SEXT(block, I0, I1, SIZE_WORD);
|
||||
UML_CMP(block, I0, I1);
|
||||
UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_RANGE_ERROR);
|
||||
UML_JMPc(block, uml::COND_E, no_exception);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR);
|
||||
UML_LABEL(block, no_exception);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3461,9 +3446,9 @@ void hyperstone_device::generate_ldwr(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I2, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I2, 0);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I3, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I3, 0);
|
||||
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
@ -3486,21 +3471,20 @@ void hyperstone_device::generate_lddr(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (!SrcGlobal && (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I2, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I2, 0);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I3, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I3, 0);
|
||||
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, src_code + 1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code + 1, uml::I1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3533,9 +3517,9 @@ void hyperstone_device::generate_ldwp(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I2, 4);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I2, 4);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I3, 4);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I3, 4);
|
||||
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
@ -3565,9 +3549,9 @@ void hyperstone_device::generate_lddp(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I2, 8);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I2, 8);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I3, 8);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I3, 8);
|
||||
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
@ -3579,13 +3563,12 @@ void hyperstone_device::generate_lddp(drcuml_block &block, compiler_state &compi
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
generate_set_global_register_low(block, compiler, src_code, uml::I1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code, uml::I1);
|
||||
|
||||
UML_ADD(block, I0, I0, 4);
|
||||
UML_CALLH(block, *m_mem_read32);
|
||||
|
||||
UML_MOV(block, I5, I1);
|
||||
generate_set_global_register(block, compiler, desc, src_code + 1);
|
||||
generate_set_global_register_low(block, compiler, desc, src_code + 1, uml::I1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3618,9 +3601,9 @@ void hyperstone_device::generate_stwr(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I2, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I2, 0);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I1, uml::I3, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I1, uml::I3, 0);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
@ -3652,9 +3635,9 @@ void hyperstone_device::generate_stdr(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I0, uml::I2, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I0, uml::I2, 0);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I1, uml::I3, 0);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I1, uml::I3, 0);
|
||||
|
||||
uml::parameter srcfp = uml::I2;
|
||||
if (SrcGlobal)
|
||||
@ -3703,9 +3686,9 @@ void hyperstone_device::generate_stwp(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I2, 4);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I2, 4);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I1, uml::I3, 4);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I1, uml::I3, 4);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
@ -3748,9 +3731,9 @@ void hyperstone_device::generate_stdp(drcuml_block &block, compiler_state &compi
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
if (SrcGlobal || (src_code != dst_code))
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I4, uml::I2, 8);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I4, uml::I2, 8);
|
||||
else
|
||||
generate_load_address_rp(block, compiler, dst_code, uml::I1, uml::I3, 8);
|
||||
generate_load_address_rp(block, compiler, desc, dst_code, uml::I1, uml::I3, 8);
|
||||
|
||||
if (SrcGlobal)
|
||||
{
|
||||
@ -3962,8 +3945,7 @@ void hyperstone_device::generate_frame(drcuml_block &block, compiler_state &comp
|
||||
|
||||
UML_TEST(block, I4, ~uint32_t(0));
|
||||
UML_JMPc(block, uml::COND_Z, done);
|
||||
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
|
||||
UML_EXH(block, *m_exception, TRAPNO_FRAME_ERROR);
|
||||
generate_raise_exception(block, compiler, desc, TRAPNO_FRAME_ERROR);
|
||||
|
||||
UML_LABEL(block, done);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "debugcpu.h"
|
||||
#include "dvbpoints.h"
|
||||
#include "dvdisasm.h"
|
||||
#include "dvepoints.h"
|
||||
#include "dvmemory.h"
|
||||
#include "dvrpoints.h"
|
||||
#include "dvstate.h"
|
||||
@ -369,6 +370,9 @@ debug_view *debug_view_manager::alloc_view(debug_view_type type, debug_view_osd_
|
||||
case DVT_REGISTER_POINTS:
|
||||
return append(new debug_view_registerpoints(machine(), osdupdate, osdprivate));
|
||||
|
||||
case DVT_EXCEPTION_POINTS:
|
||||
return append(new debug_view_exceptionpoints(machine(), osdupdate, osdprivate));
|
||||
|
||||
default:
|
||||
fatalerror("Attempt to create invalid debug view type %d\n", type);
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ enum debug_view_type
|
||||
DVT_LOG,
|
||||
DVT_BREAK_POINTS,
|
||||
DVT_WATCH_POINTS,
|
||||
DVT_REGISTER_POINTS
|
||||
DVT_REGISTER_POINTS,
|
||||
DVT_EXCEPTION_POINTS
|
||||
};
|
||||
|
||||
|
||||
|
314
src/emu/debug/dvepoints.cpp
Normal file
314
src/emu/debug/dvepoints.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrew Gardner, Vas Crabb
|
||||
/*********************************************************************
|
||||
|
||||
dvepoints.cpp
|
||||
|
||||
Exceptionpoint debugger view.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "dvepoints.h"
|
||||
|
||||
#include "debugcpu.h"
|
||||
#include "points.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
|
||||
// Sorting functors for the qsort function
|
||||
static bool cIndexAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return a->index() < b->index();
|
||||
}
|
||||
|
||||
static bool cIndexDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cIndexAscending(b, a);
|
||||
}
|
||||
|
||||
static bool cEnabledAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return !a->enabled() && b->enabled();
|
||||
}
|
||||
|
||||
static bool cEnabledDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cEnabledAscending(b, a);
|
||||
}
|
||||
|
||||
static bool cCpuAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return strcmp(a->debugInterface()->device().tag(), b->debugInterface()->device().tag()) < 0;
|
||||
}
|
||||
|
||||
static bool cCpuDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cCpuAscending(b, a);
|
||||
}
|
||||
|
||||
static bool cTypeAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return a->type() < b->type();
|
||||
}
|
||||
|
||||
static bool cTypeDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cTypeAscending(b, a);
|
||||
}
|
||||
|
||||
static bool cConditionAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return strcmp(a->condition(), b->condition()) < 0;
|
||||
}
|
||||
|
||||
static bool cConditionDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cConditionAscending(b, a);
|
||||
}
|
||||
|
||||
static bool cActionAscending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return a->action() < b->action();
|
||||
}
|
||||
|
||||
static bool cActionDescending(const debug_exceptionpoint *a, const debug_exceptionpoint *b)
|
||||
{
|
||||
return cActionAscending(b, a);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEBUG VIEW BREAK POINTS
|
||||
//**************************************************************************
|
||||
|
||||
static const int tableBreaks[] = { 5, 9, 31, 45, 63, 80 };
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// debug_view_exceptionpoints - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
debug_view_exceptionpoints::debug_view_exceptionpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate)
|
||||
: debug_view(machine, DVT_EXCEPTION_POINTS, osdupdate, osdprivate)
|
||||
, m_sortType(cIndexAscending)
|
||||
{
|
||||
// fail if no available sources
|
||||
enumerate_sources();
|
||||
if (m_source_list.empty())
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~debug_view_exceptionpoints - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
debug_view_exceptionpoints::~debug_view_exceptionpoints()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// enumerate_sources - enumerate all possible
|
||||
// sources for a disassembly view
|
||||
//-------------------------------------------------
|
||||
|
||||
void debug_view_exceptionpoints::enumerate_sources()
|
||||
{
|
||||
// start with an empty list
|
||||
m_source_list.clear();
|
||||
|
||||
// iterate over devices with disassembly interfaces
|
||||
for (device_disasm_interface &dasm : disasm_interface_enumerator(machine().root_device()))
|
||||
{
|
||||
m_source_list.emplace_back(
|
||||
std::make_unique<debug_view_source>(
|
||||
util::string_format("%s '%s'", dasm.device().name(), dasm.device().tag()),
|
||||
&dasm.device()));
|
||||
}
|
||||
|
||||
// reset the source to a known good entry
|
||||
if (!m_source_list.empty())
|
||||
set_source(*m_source_list[0]);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// view_click - handle a mouse click within the
|
||||
// current view
|
||||
//-------------------------------------------------
|
||||
|
||||
void debug_view_exceptionpoints::view_click(const int button, const debug_view_xy& pos)
|
||||
{
|
||||
bool clickedTopRow = (m_topleft.y == pos.y);
|
||||
|
||||
if (clickedTopRow)
|
||||
{
|
||||
if (pos.x < tableBreaks[0])
|
||||
m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending;
|
||||
else if (pos.x < tableBreaks[1])
|
||||
m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending;
|
||||
else if (pos.x < tableBreaks[2])
|
||||
m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending;
|
||||
else if (pos.x < tableBreaks[3])
|
||||
m_sortType = (m_sortType == &cTypeAscending) ? &cTypeDescending : &cTypeAscending;
|
||||
else if (pos.x < tableBreaks[4])
|
||||
m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending;
|
||||
else if (pos.x < tableBreaks[5])
|
||||
m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gather a sorted list of all the exceptionpoints for all the CPUs
|
||||
gather_exceptionpoints();
|
||||
|
||||
int epIndex = pos.y - 1;
|
||||
if ((epIndex >= m_buffer.size()) || (epIndex < 0))
|
||||
return;
|
||||
|
||||
// Enable / disable
|
||||
const_cast<debug_exceptionpoint &>(*m_buffer[epIndex]).setEnabled(!m_buffer[epIndex]->enabled());
|
||||
|
||||
machine().debug_view().update_all(DVT_DISASSEMBLY);
|
||||
}
|
||||
|
||||
begin_update();
|
||||
m_update_pending = true;
|
||||
end_update();
|
||||
}
|
||||
|
||||
|
||||
void debug_view_exceptionpoints::pad_ostream_to_length(std::ostream& str, int len)
|
||||
{
|
||||
auto const current = str.tellp();
|
||||
if (current < decltype(current)(len))
|
||||
str << std::setw(decltype(current)(len) - current) << "";
|
||||
}
|
||||
|
||||
|
||||
void debug_view_exceptionpoints::gather_exceptionpoints()
|
||||
{
|
||||
m_buffer.resize(0);
|
||||
for (auto &source : m_source_list)
|
||||
{
|
||||
// Collect
|
||||
device_debug &debugInterface = *source->device()->debug();
|
||||
for (const auto &epp : debugInterface.exceptionpoint_list())
|
||||
m_buffer.push_back(epp.second.get());
|
||||
}
|
||||
|
||||
// And now for the sort
|
||||
if (!m_buffer.empty())
|
||||
std::stable_sort(m_buffer.begin(), m_buffer.end(), m_sortType);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// view_update - update the contents of the
|
||||
// exceptionpoints view
|
||||
//-------------------------------------------------
|
||||
|
||||
void debug_view_exceptionpoints::view_update()
|
||||
{
|
||||
// Gather a list of all the exceptionpoints for all the CPUs
|
||||
gather_exceptionpoints();
|
||||
|
||||
// Set the view region so the scroll bars update
|
||||
m_total.x = tableBreaks[std::size(tableBreaks) - 1];
|
||||
m_total.y = m_buffer.size() + 1;
|
||||
if (m_total.y < 10)
|
||||
m_total.y = 10;
|
||||
|
||||
// Draw
|
||||
debug_view_char *dest = &m_viewdata[0];
|
||||
util::ovectorstream linebuf;
|
||||
linebuf.reserve(std::size(tableBreaks) - 1);
|
||||
|
||||
// Header
|
||||
if (m_visible.y > 0)
|
||||
{
|
||||
linebuf.clear();
|
||||
linebuf.rdbuf()->clear();
|
||||
linebuf << "ID";
|
||||
if (m_sortType == &cIndexAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cIndexDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf << "En";
|
||||
if (m_sortType == &cEnabledAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cEnabledDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf << "CPU";
|
||||
if (m_sortType == &cCpuAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cCpuDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[2]);
|
||||
linebuf << "Type";
|
||||
if (m_sortType == &cTypeAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cTypeDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[3]);
|
||||
linebuf << "Condition";
|
||||
if (m_sortType == &cConditionAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cConditionDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[4]);
|
||||
linebuf << "Action";
|
||||
if (m_sortType == &cActionAscending) linebuf.put('\\');
|
||||
else if (m_sortType == &cActionDescending) linebuf.put('/');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[5]);
|
||||
|
||||
auto const &text(linebuf.vec());
|
||||
for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
dest->byte = (i < text.size()) ? text[i] : ' ';
|
||||
dest->attrib = DCA_ANCILLARY;
|
||||
}
|
||||
}
|
||||
|
||||
for (int row = 1; row < m_visible.y; row++)
|
||||
{
|
||||
// Breakpoints
|
||||
int epi = row + m_topleft.y - 1;
|
||||
if ((epi < m_buffer.size()) && (epi >= 0))
|
||||
{
|
||||
const debug_exceptionpoint *const ep = m_buffer[epi];
|
||||
|
||||
linebuf.clear();
|
||||
linebuf.rdbuf()->clear();
|
||||
util::stream_format(linebuf, "%2X", ep->index());
|
||||
pad_ostream_to_length(linebuf, tableBreaks[0]);
|
||||
linebuf.put(ep->enabled() ? 'X' : 'O');
|
||||
pad_ostream_to_length(linebuf, tableBreaks[1]);
|
||||
linebuf << ep->debugInterface()->device().tag();
|
||||
pad_ostream_to_length(linebuf, tableBreaks[2]);
|
||||
util::stream_format(linebuf, "%X", ep->type());
|
||||
pad_ostream_to_length(linebuf, tableBreaks[3]);
|
||||
if (strcmp(ep->condition(), "1"))
|
||||
linebuf << ep->condition();
|
||||
pad_ostream_to_length(linebuf, tableBreaks[4]);
|
||||
linebuf << ep->action();
|
||||
pad_ostream_to_length(linebuf, tableBreaks[5]);
|
||||
|
||||
auto const &text(linebuf.vec());
|
||||
for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
dest->byte = (i < text.size()) ? text[i] : ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
|
||||
// Color disabled exceptionpoints red
|
||||
if ((i >= tableBreaks[0]) && (i < tableBreaks[1]) && !ep->enabled())
|
||||
dest->attrib |= DCA_CHANGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fill the remaining vertical space
|
||||
for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
|
||||
{
|
||||
dest->byte = ' ';
|
||||
dest->attrib = DCA_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
src/emu/debug/dvepoints.h
Normal file
49
src/emu/debug/dvepoints.h
Normal file
@ -0,0 +1,49 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrew Gardner, Vas Crabb
|
||||
/*********************************************************************
|
||||
|
||||
dvepoints.h
|
||||
|
||||
Exceptionpoint debugger view.
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef MAME_EMU_DEBUG_DVEPOINTS_H
|
||||
#define MAME_EMU_DEBUG_DVEPOINTS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "debugvw.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// debug view for exceptionpoints
|
||||
class debug_view_exceptionpoints : public debug_view
|
||||
{
|
||||
friend class debug_view_manager;
|
||||
|
||||
// construction/destruction
|
||||
debug_view_exceptionpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate);
|
||||
virtual ~debug_view_exceptionpoints();
|
||||
|
||||
protected:
|
||||
// view overrides
|
||||
virtual void view_update() override;
|
||||
virtual void view_click(const int button, const debug_view_xy& pos) override;
|
||||
|
||||
private:
|
||||
// internal helpers
|
||||
void enumerate_sources();
|
||||
void pad_ostream_to_length(std::ostream& str, int len);
|
||||
void gather_exceptionpoints();
|
||||
|
||||
// internal state
|
||||
bool (*m_sortType)(const debug_exceptionpoint *, const debug_exceptionpoint *);
|
||||
std::vector<const debug_exceptionpoint *> m_buffer;
|
||||
};
|
||||
|
||||
#endif // MAME_EMU_DEBUG_DVEPOINTS_H
|
23
src/osd/modules/debugger/osx/exceptionpointsview.h
Normal file
23
src/osd/modules/debugger/osx/exceptionpointsview.h
Normal file
@ -0,0 +1,23 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
//============================================================
|
||||
//
|
||||
// exceptionpointsview.h - MacOS X Cocoa debug window handling
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#import "debugosx.h"
|
||||
|
||||
#import "debugview.h"
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface MAMEExceptionpointsView : MAMEDebugView
|
||||
{
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m;
|
||||
|
||||
@end
|
27
src/osd/modules/debugger/osx/exceptionpointsview.mm
Normal file
27
src/osd/modules/debugger/osx/exceptionpointsview.mm
Normal file
@ -0,0 +1,27 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
//============================================================
|
||||
//
|
||||
// exceptionpointsview.m - MacOS X Cocoa debug window handling
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#import "exceptionpointsview.h"
|
||||
|
||||
#include "debug/debugvw.h"
|
||||
|
||||
|
||||
@implementation MAMEExceptionpointsView
|
||||
|
||||
- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
|
||||
if (!(self = [super initWithFrame:f type:DVT_EXCEPTION_POINTS machine:m wholeLineScroll:YES]))
|
||||
return nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
@ -10,6 +10,7 @@
|
||||
#import "pointsviewer.h"
|
||||
|
||||
#import "breakpointsview.h"
|
||||
#import "exceptionpointsview.h"
|
||||
#import "registerpointsview.h"
|
||||
#import "watchpointsview.h"
|
||||
|
||||
@ -19,9 +20,9 @@
|
||||
@implementation MAMEPointsViewer
|
||||
|
||||
- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c {
|
||||
MAMEDebugView *breakView, *watchView, *registerView;
|
||||
NSScrollView *breakScroll, *watchScroll, *registerScroll;
|
||||
NSTabViewItem *breakTab, *watchTab, *registerTab;
|
||||
MAMEDebugView *breakView, *watchView, *registerView, *exceptionView;
|
||||
NSScrollView *breakScroll, *watchScroll, *registerScroll, *exceptionScroll;
|
||||
NSTabViewItem *breakTab, *watchTab, *registerTab, *exceptionTab;
|
||||
NSPopUpButton *actionButton;
|
||||
NSRect subviewFrame;
|
||||
|
||||
@ -48,6 +49,9 @@
|
||||
[[[subviewButton menu] addItemWithTitle:@"All Registerpoints"
|
||||
action:NULL
|
||||
keyEquivalent:@""] setTag:2];
|
||||
[[[subviewButton menu] addItemWithTitle:@"All Exceptionpoints"
|
||||
action:NULL
|
||||
keyEquivalent:@""] setTag:3];
|
||||
[subviewButton sizeToFit];
|
||||
subviewFrame = [subviewButton frame];
|
||||
subviewFrame.origin.x = subviewFrame.size.height;
|
||||
@ -118,7 +122,23 @@
|
||||
[registerTab setView:registerScroll];
|
||||
[registerScroll release];
|
||||
|
||||
// create a tabless tabview for the two subviews
|
||||
// create the exceptionpoints view
|
||||
exceptionView = [[MAMEExceptionpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
|
||||
machine:*machine];
|
||||
exceptionScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]];
|
||||
[exceptionScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
[exceptionScroll setHasHorizontalScroller:YES];
|
||||
[exceptionScroll setHasVerticalScroller:YES];
|
||||
[exceptionScroll setAutohidesScrollers:YES];
|
||||
[exceptionScroll setBorderType:NSNoBorder];
|
||||
[exceptionScroll setDrawsBackground:NO];
|
||||
[exceptionScroll setDocumentView:exceptionView];
|
||||
[exceptionView release];
|
||||
exceptionTab = [[NSTabViewItem alloc] initWithIdentifier:@""];
|
||||
[exceptionTab setView:exceptionScroll];
|
||||
[exceptionScroll release];
|
||||
|
||||
// create a tabless tabview for the four subviews
|
||||
tabs = [[NSTabView alloc] initWithFrame:[breakScroll frame]];
|
||||
[tabs setTabViewType:NSNoTabsNoBorder];
|
||||
[tabs setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
@ -128,6 +148,8 @@
|
||||
[watchTab release];
|
||||
[tabs addTabViewItem:registerTab];
|
||||
[registerTab release];
|
||||
[tabs addTabViewItem:exceptionTab];
|
||||
[exceptionTab release];
|
||||
[[window contentView] addSubview:tabs];
|
||||
[tabs release];
|
||||
|
||||
@ -156,8 +178,14 @@
|
||||
borderType:[registerScroll borderType]
|
||||
controlSize:NSControlSizeRegular
|
||||
scrollerStyle:NSScrollerStyleOverlay];
|
||||
NSSize const desired = NSMakeSize(std::max({ breakDesired.width, watchDesired.width, registerDesired.width }),
|
||||
std::max({ breakDesired.height, watchDesired.height, registerDesired.height }));
|
||||
NSSize const exceptionDesired = [NSScrollView frameSizeForContentSize:[exceptionView maximumFrameSize]
|
||||
horizontalScrollerClass:[NSScroller class]
|
||||
verticalScrollerClass:[NSScroller class]
|
||||
borderType:[exceptionScroll borderType]
|
||||
controlSize:NSControlSizeRegular
|
||||
scrollerStyle:NSScrollerStyleOverlay];
|
||||
NSSize const desired = NSMakeSize(std::max({ breakDesired.width, watchDesired.width, registerDesired.width, exceptionDesired.width }),
|
||||
std::max({ breakDesired.height, watchDesired.height, registerDesired.height, exceptionDesired.height }));
|
||||
[self cascadeWindowWithDesiredSize:desired forView:tabs];
|
||||
|
||||
// don't forget the result
|
||||
|
@ -70,6 +70,12 @@ BreakpointsWindow::BreakpointsWindow(DebuggerQt &debugger, QWidget *parent) :
|
||||
typeRegister->setActionGroup(typeGroup);
|
||||
typeRegister->setShortcut(QKeySequence("Ctrl+3"));
|
||||
|
||||
QAction *typeException = new QAction("Exceptionpoints", this);
|
||||
typeException->setObjectName("typeexception");
|
||||
typeException->setCheckable(true);
|
||||
typeException->setActionGroup(typeGroup);
|
||||
typeException->setShortcut(QKeySequence("Ctrl+4"));
|
||||
|
||||
typeBreak->setChecked(true);
|
||||
connect(typeGroup, &QActionGroup::triggered, this, &BreakpointsWindow::typeChanged);
|
||||
|
||||
@ -116,6 +122,9 @@ void BreakpointsWindow::saveConfigurationToNode(util::xml::data_node &node)
|
||||
case DVT_REGISTER_POINTS:
|
||||
node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 2);
|
||||
break;
|
||||
case DVT_EXCEPTION_POINTS:
|
||||
node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -147,6 +156,11 @@ void BreakpointsWindow::typeChanged(QAction* changedTo)
|
||||
m_breakpointsView = new DebuggerView(DVT_REGISTER_POINTS, m_machine, this);
|
||||
setWindowTitle("Debug: All Registerpoints");
|
||||
}
|
||||
else if (changedTo->text() == "Exceptionpoints")
|
||||
{
|
||||
m_breakpointsView = new DebuggerView(DVT_EXCEPTION_POINTS, m_machine, this);
|
||||
setWindowTitle("Debug: All Exceptionpoints");
|
||||
}
|
||||
|
||||
// Re-register
|
||||
QVBoxLayout *layout = findChild<QVBoxLayout *>("vlayout");
|
||||
|
@ -110,6 +110,7 @@ protected:
|
||||
ID_SHOW_BREAKPOINTS,
|
||||
ID_SHOW_WATCHPOINTS,
|
||||
ID_SHOW_REGISTERPOINTS,
|
||||
ID_SHOW_EXCEPTIONPOINTS,
|
||||
|
||||
ID_CLEAR_LOG,
|
||||
|
||||
|
@ -36,6 +36,7 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
|
||||
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_BREAKPOINTS, TEXT("Breakpoints\tCtrl+1"));
|
||||
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_WATCHPOINTS, TEXT("Watchpoints\tCtrl+2"));
|
||||
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_REGISTERPOINTS, TEXT("Registerpoints\tCtrl+3"));
|
||||
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_EXCEPTIONPOINTS, TEXT("Exceptionpoints\tCtrl+4"));
|
||||
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
|
||||
|
||||
// compute a client rect
|
||||
@ -76,6 +77,10 @@ bool pointswin_info::handle_key(WPARAM wparam, LPARAM lparam)
|
||||
case '3':
|
||||
SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
|
||||
return true;
|
||||
|
||||
case '4':
|
||||
SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +96,7 @@ void pointswin_info::update_menu()
|
||||
CheckMenuItem(menu, ID_SHOW_BREAKPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_BREAK_POINTS ? MF_CHECKED : MF_UNCHECKED));
|
||||
CheckMenuItem(menu, ID_SHOW_WATCHPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_WATCH_POINTS ? MF_CHECKED : MF_UNCHECKED));
|
||||
CheckMenuItem(menu, ID_SHOW_REGISTERPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_REGISTER_POINTS ? MF_CHECKED : MF_UNCHECKED));
|
||||
CheckMenuItem(menu, ID_SHOW_EXCEPTIONPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_EXCEPTION_POINTS ? MF_CHECKED : MF_UNCHECKED));
|
||||
}
|
||||
|
||||
|
||||
@ -128,6 +134,15 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
|
||||
win_set_window_text_utf8(window(), "All Registerpoints");
|
||||
recompute_children();
|
||||
return true;
|
||||
|
||||
case ID_SHOW_EXCEPTIONPOINTS:
|
||||
m_views[0].reset();
|
||||
m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_EXCEPTION_POINTS));
|
||||
if (!m_views[0]->is_valid())
|
||||
m_views[0].reset();
|
||||
win_set_window_text_utf8(window(), "All Exceptionpoints");
|
||||
recompute_children();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -148,6 +163,9 @@ void pointswin_info::restore_configuration_from_node(util::xml::data_node const
|
||||
case 2:
|
||||
SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
|
||||
break;
|
||||
case 3:
|
||||
SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
debugwin_info::restore_configuration_from_node(node);
|
||||
@ -170,6 +188,9 @@ void pointswin_info::save_configuration_to_node(util::xml::data_node &node)
|
||||
case DVT_REGISTER_POINTS:
|
||||
node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 2);
|
||||
break;
|
||||
case DVT_EXCEPTION_POINTS:
|
||||
node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user