mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
ns32082: implement program flow trace support
This commit is contained in:
parent
e16435f2ab
commit
90d694c29b
@ -240,11 +240,11 @@ template <int Width> void ns32000_device<Width>::state_string_export(device_stat
|
||||
*
|
||||
* Underlying handlers further subdivide accesses by device bus width.
|
||||
*/
|
||||
template <int Width> template<typename T> T ns32000_device<Width>::mem_read(unsigned st, u32 address, bool user)
|
||||
template <int Width> template<typename T> T ns32000_device<Width>::mem_read(unsigned st, u32 address, bool user, bool pfs)
|
||||
{
|
||||
u32 physical = address;
|
||||
ns32000_mmu_interface::translate_result tr = m_mmu ?
|
||||
m_mmu->translate(m_bus[st].space(), st, physical, (m_psr & PSR_U) || user, false) : ns32000_mmu_interface::COMPLETE;
|
||||
m_mmu->translate(m_bus[st].space(), st, physical, (m_psr & PSR_U) || user, false, pfs) : ns32000_mmu_interface::COMPLETE;
|
||||
|
||||
if (tr == ns32000_mmu_interface::COMPLETE)
|
||||
{
|
||||
@ -404,7 +404,7 @@ template <int Width> template<typename T> void ns32000_device<Width>::mem_write(
|
||||
*/
|
||||
template <int Width> template<typename T> T ns32000_device<Width>::fetch(unsigned &bytes)
|
||||
{
|
||||
T const data = mem_read<T>(m_sequential ? ST_SIF : ST_NIF, m_pc + bytes);
|
||||
T const data = mem_read<T>(m_sequential ? ST_SIF : ST_NIF, m_pc + bytes, false, bytes == 0);
|
||||
|
||||
bytes += sizeof(T);
|
||||
m_sequential = true;
|
||||
@ -3341,7 +3341,7 @@ template <int Width> device_memory_interface::space_config_vector ns32000_device
|
||||
|
||||
template <int Width> bool ns32000_device<Width>::memory_translate(int spacenum, int intention, offs_t &address)
|
||||
{
|
||||
return !m_mmu || m_mmu->translate(space(spacenum), spacenum, address, intention & TRANSLATE_USER_MASK, intention & TRANSLATE_WRITE, intention & TRANSLATE_DEBUG_MASK) == ns32000_mmu_interface::COMPLETE;
|
||||
return !m_mmu || m_mmu->translate(space(spacenum), spacenum, address, intention & TRANSLATE_USER_MASK, intention & TRANSLATE_WRITE, false, intention & TRANSLATE_DEBUG_MASK) == ns32000_mmu_interface::COMPLETE;
|
||||
}
|
||||
|
||||
template <int Width> std::unique_ptr<util::disasm_interface> ns32000_device<Width>::create_disassembler()
|
||||
|
@ -119,7 +119,7 @@ protected:
|
||||
};
|
||||
|
||||
// memory accessors
|
||||
template <typename T> T mem_read(unsigned st, u32 address, bool user = false);
|
||||
template <typename T> T mem_read(unsigned st, u32 address, bool user = false, bool pfs = false);
|
||||
template <typename T> void mem_write(unsigned st, u32 address, T data, bool user = false);
|
||||
|
||||
// instruction fetch/decode helpers
|
||||
|
@ -543,7 +543,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
|
||||
case 0x1e:
|
||||
// format 14: xxxx xsss s0oo ooii 0001 1110
|
||||
{
|
||||
char const *const mmureg[] = { "BPR0", "BPR1", "", "", "", "", "", "", "", "", "MSR", "BCNT", "PTB0", "PTB1", "", "EIA" };
|
||||
char const *const mmureg[] = { "BPR0", "BPR1", "", "", "PF0", "PF1", "", "", "SC", "", "MSR", "BCNT", "PTB0", "PTB1", "", "EIA" };
|
||||
|
||||
u16 const opword = opcodes.r16(pc + bytes); bytes += 2;
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
}
|
||||
|
||||
enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
|
||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool debug = false) = 0;
|
||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool debug = false) = 0;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_NS32000_SLAVE_H
|
||||
|
@ -44,6 +44,9 @@ enum reg_mask : unsigned
|
||||
{
|
||||
BPR0 = 0x0, // breakpoint register 0
|
||||
BPR1 = 0x1, // breakpoint register 1
|
||||
PF0 = 0x4, // program flow register 0 (removed at rev L)
|
||||
PF1 = 0x5, // program flow register 1 (removed at rev L)
|
||||
SC = 0x8, // sequential count register (removed at rev L)
|
||||
MSR = 0xa, // memory management status register
|
||||
BCNT = 0xb, // breakpoint counter register
|
||||
PTB0 = 0xc, // page table base register 0
|
||||
@ -69,9 +72,12 @@ enum msr_mask : u32
|
||||
MSR_BEN = 0x00100000, // breakpoint enable
|
||||
MSR_UB = 0x00200000, // user-only breakpointing
|
||||
MSR_AI = 0x00400000, // abort/interrupt
|
||||
MSR_FT = 0x00800000, // flow trace (removed at rev L)
|
||||
MSR_UT = 0x01000000, // user trace (removed at rev L)
|
||||
MSR_NT = 0x02000000, // nonsequential trace (removed at rev L)
|
||||
|
||||
MSR_ERC = 0x00000007,
|
||||
MSR_WM = 0x007f0000,
|
||||
MSR_WM = 0x03ff0000,
|
||||
};
|
||||
|
||||
enum msr_tet_mask : u32
|
||||
@ -143,6 +149,8 @@ ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, d
|
||||
: device_t(mconfig, NS32082, tag, owner, clock)
|
||||
, ns32000_mmu_interface(mconfig, *this)
|
||||
, m_bpr{}
|
||||
, m_pf{}
|
||||
, m_sc(0)
|
||||
, m_msr(0)
|
||||
, m_bcnt(0)
|
||||
, m_ptb{}
|
||||
@ -153,6 +161,8 @@ ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, d
|
||||
void ns32082_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_bpr));
|
||||
save_item(NAME(m_pf));
|
||||
save_item(NAME(m_sc));
|
||||
save_item(NAME(m_msr));
|
||||
save_item(NAME(m_bcnt));
|
||||
save_item(NAME(m_ptb));
|
||||
@ -331,6 +341,9 @@ void ns32082_device::execute()
|
||||
{
|
||||
case BPR0: m_bpr[0] = m_op[0].value & u32(0xfcffffff); break;
|
||||
case BPR1: m_bpr[1] = m_op[0].value & u32(0xf8ffffff); break;
|
||||
case PF0: m_pf[0] = m_op[0].value & u32(0x00ffffff); break;
|
||||
case PF1: m_pf[1] = m_op[0].value & u32(0x00ffffff); break;
|
||||
case SC: m_sc = m_op[0].value; break;
|
||||
case MSR: set_msr(m_op[0].value); break;
|
||||
case BCNT: m_bcnt = m_op[0].value & u32(0x00ffffff); break;
|
||||
case PTB0: m_ptb[0] = m_op[0].value & u32(0xfffffc00); break;
|
||||
@ -347,6 +360,9 @@ void ns32082_device::execute()
|
||||
{
|
||||
case BPR0: m_op[2].value = m_bpr[0]; break;
|
||||
case BPR1: m_op[2].value = m_bpr[1]; break;
|
||||
case PF0: m_op[2].value = m_pf[0]; break;
|
||||
case PF1: m_op[2].value = m_pf[1]; break;
|
||||
case SC: m_op[2].value = m_sc; break;
|
||||
case MSR: m_op[2].value = m_msr; break;
|
||||
case BCNT: m_op[2].value = m_bcnt; break;
|
||||
case PTB0: m_op[2].value = m_ptb[0]; break;
|
||||
@ -384,8 +400,22 @@ void ns32082_device::set_msr(u32 data)
|
||||
m_msr = (m_msr & ~MSR_WM) | (data & MSR_WM);
|
||||
}
|
||||
|
||||
ns32082_device::translate_result ns32082_device::translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool debug)
|
||||
ns32082_device::translate_result ns32082_device::translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs, bool debug)
|
||||
{
|
||||
// update program flow trace state
|
||||
if (pfs && (m_msr & MSR_FT))
|
||||
{
|
||||
if (st == ST_NIF)
|
||||
{
|
||||
m_pf[1] = m_pf[0];
|
||||
m_pf[0] = address;
|
||||
|
||||
m_sc = m_sc << 16;
|
||||
}
|
||||
|
||||
m_sc++;
|
||||
}
|
||||
|
||||
// check translation required
|
||||
if ((!(m_msr & MSR_TU) && user) || (!(m_msr & MSR_TS) && !user))
|
||||
return COMPLETE;
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
virtual void write_id(u16 data) override;
|
||||
virtual void write_op(u16 data) override;
|
||||
|
||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool debug = false) override;
|
||||
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool debug = false) override;
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
@ -38,6 +38,8 @@ protected:
|
||||
private:
|
||||
// registers
|
||||
u32 m_bpr[2];
|
||||
u32 m_pf[2];
|
||||
u32 m_sc;
|
||||
u32 m_msr;
|
||||
u32 m_bcnt;
|
||||
u32 m_ptb[2];
|
||||
|
Loading…
Reference in New Issue
Block a user