From 90d694c29bc15738395f68d95721284537f75346 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Wed, 28 Jul 2021 17:48:19 +0700 Subject: [PATCH] ns32082: implement program flow trace support --- src/devices/cpu/ns32000/ns32000.cpp | 8 +++--- src/devices/cpu/ns32000/ns32000.h | 2 +- src/devices/cpu/ns32000/ns32000dasm.cpp | 2 +- src/devices/cpu/ns32000/slave.h | 2 +- src/devices/machine/ns32082.cpp | 34 +++++++++++++++++++++++-- src/devices/machine/ns32082.h | 4 ++- 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp index f69ce67b846..230673d28d5 100644 --- a/src/devices/cpu/ns32000/ns32000.cpp +++ b/src/devices/cpu/ns32000/ns32000.cpp @@ -240,11 +240,11 @@ template void ns32000_device::state_string_export(device_stat * * Underlying handlers further subdivide accesses by device bus width. */ -template template T ns32000_device::mem_read(unsigned st, u32 address, bool user) +template template T ns32000_device::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 template void ns32000_device::mem_write( */ template template T ns32000_device::fetch(unsigned &bytes) { - T const data = mem_read(m_sequential ? ST_SIF : ST_NIF, m_pc + bytes); + T const data = mem_read(m_sequential ? ST_SIF : ST_NIF, m_pc + bytes, false, bytes == 0); bytes += sizeof(T); m_sequential = true; @@ -3341,7 +3341,7 @@ template device_memory_interface::space_config_vector ns32000_device template bool ns32000_device::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 std::unique_ptr ns32000_device::create_disassembler() diff --git a/src/devices/cpu/ns32000/ns32000.h b/src/devices/cpu/ns32000/ns32000.h index 39230e0ac73..366af79bc84 100644 --- a/src/devices/cpu/ns32000/ns32000.h +++ b/src/devices/cpu/ns32000/ns32000.h @@ -119,7 +119,7 @@ protected: }; // memory accessors - template T mem_read(unsigned st, u32 address, bool user = false); + template T mem_read(unsigned st, u32 address, bool user = false, bool pfs = false); template void mem_write(unsigned st, u32 address, T data, bool user = false); // instruction fetch/decode helpers diff --git a/src/devices/cpu/ns32000/ns32000dasm.cpp b/src/devices/cpu/ns32000/ns32000dasm.cpp index 5547dff1b5d..9676329157f 100644 --- a/src/devices/cpu/ns32000/ns32000dasm.cpp +++ b/src/devices/cpu/ns32000/ns32000dasm.cpp @@ -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; diff --git a/src/devices/cpu/ns32000/slave.h b/src/devices/cpu/ns32000/slave.h index 3a29683087e..c3e27ad7f90 100644 --- a/src/devices/cpu/ns32000/slave.h +++ b/src/devices/cpu/ns32000/slave.h @@ -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 diff --git a/src/devices/machine/ns32082.cpp b/src/devices/machine/ns32082.cpp index 57beccb4075..e5835401745 100644 --- a/src/devices/machine/ns32082.cpp +++ b/src/devices/machine/ns32082.cpp @@ -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; diff --git a/src/devices/machine/ns32082.h b/src/devices/machine/ns32082.h index f59fae34d68..4818c41bcb5 100644 --- a/src/devices/machine/ns32082.h +++ b/src/devices/machine/ns32082.h @@ -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];