summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/machine/netlist.cpp34
-rw-r--r--src/emu/debug/debugcpu.cpp4
-rw-r--r--src/emu/debug/dvstate.cpp6
-rw-r--r--src/emu/distate.cpp206
-rw-r--r--src/emu/distate.h154
5 files changed, 201 insertions, 203 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index f4692a29547..0744b67d87d 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -1238,35 +1238,6 @@ netlist_mame_cpu_device::netlist_mame_cpu_device(const machine_config &mconfig,
}
-// Fixes overflow error in device_pseudo_state_register
-template<>
-class device_pseudo_state_register<double> : public device_state_entry
-{
-public:
- typedef typename std::function<double ()> getter_func;
- typedef typename std::function<void (double)> setter_func;
-
- // construction/destruction
- device_pseudo_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
- : device_state_entry(index, symbol, sizeof(double), ~u64(0), DSF_FLOATING_POINT, dev),
- m_getter(std::move(getter)),
- m_setter(std::move(setter))
- {
- }
-
-protected:
- // device_state_entry overrides
- virtual u64 entry_value() const override { return u64(m_getter()); }
- virtual void entry_set_value(u64 value) const override { m_setter(double(value)); }
- virtual double entry_dvalue() const override { return m_getter(); }
- virtual void entry_set_dvalue(double value) const override { m_setter(value); }
-
-private:
- getter_func m_getter; // function to retrieve the data
- setter_func m_setter; // function to store the data
-};
-
-
void netlist_mame_cpu_device::device_start()
{
LOGDEVCALLS("device_start entry\n");
@@ -1299,12 +1270,11 @@ void netlist_mame_cpu_device::device_start()
else
{
auto nl = downcast<netlist::analog_net_t *>(n.get());
- state_add(std::make_unique<device_pseudo_state_register<double>>(
+ state_add<double>(
index++,
name.c_str(),
[nl]() { return nl->Q_Analog(); },
- [nl](double data) { nl->set_Q_Analog(data); },
- this));
+ [nl](double data) { nl->set_Q_Analog(data); });
}
}
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index afdef1362d1..6dacf7acee1 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -513,8 +513,8 @@ device_debug::device_debug(device_t &device)
strmakelower(tempstr.assign(entry->symbol()));
m_symtable->add(
tempstr.c_str(),
- std::bind(&device_state_interface::state_int, m_state, entry->index()),
- entry->writeable() ? std::bind(&device_state_interface::set_state_int, m_state, entry->index(), _1) : symbol_table::setter_func(nullptr),
+ std::bind(&device_state_entry::value, entry.get()),
+ entry->writeable() ? std::bind(&device_state_entry::set_value, entry.get(), _1) : symbol_table::setter_func(nullptr),
entry->format_string());
}
}
diff --git a/src/emu/debug/dvstate.cpp b/src/emu/debug/dvstate.cpp
index 13c019be4d5..594d8fdad39 100644
--- a/src/emu/debug/dvstate.cpp
+++ b/src/emu/debug/dvstate.cpp
@@ -147,7 +147,9 @@ void debug_view_state::recompute()
}
// add a flags entry: flags:xxxxxxxx
- m_state_list.emplace_back(STATE_GENFLAGS, "flags", source.m_stateintf->state_string_max_length(STATE_GENFLAGS));
+ const device_state_entry *flags = source.m_stateintf->state_find_entry(STATE_GENFLAGS);
+ if (flags != nullptr)
+ m_state_list.emplace_back(STATE_GENFLAGS, "flags", flags->max_length());
// add a divider entry
m_state_list.emplace_back(REG_DIVIDER, "", 0);
@@ -158,7 +160,7 @@ void debug_view_state::recompute()
if (entry->divider())
m_state_list.emplace_back(REG_DIVIDER, "", 0);
else if (entry->visible())
- m_state_list.emplace_back(entry->index(), entry->symbol(), source.m_stateintf->state_string_max_length(entry->index()));
+ m_state_list.emplace_back(entry->index(), entry->symbol(), entry->max_length());
}
// count the entries and determine the maximum tag and value sizes
diff --git a/src/emu/distate.cpp b/src/emu/distate.cpp
index 770a19292c9..ae8ba0b0e63 100644
--- a/src/emu/distate.cpp
+++ b/src/emu/distate.cpp
@@ -139,6 +139,36 @@ void device_state_entry::format_from_mask()
//-------------------------------------------------
+// value - return the current value as a u64
+//-------------------------------------------------
+
+u64 device_state_entry::value() const
+{
+ // call the exporter before we do anything
+ if ((m_flags & DSF_EXPORT) != 0)
+ m_device_state->state_export(*this);
+
+ // pick up the value
+ return entry_value() & m_datamask;
+}
+
+
+//-------------------------------------------------
+// dvalue - return the current value as a double
+//-------------------------------------------------
+
+double device_state_entry::dvalue() const
+{
+ // call the exporter before we do anything
+ if ((m_flags & DSF_EXPORT) != 0)
+ m_device_state->state_export(*this);
+
+ // pick up the value
+ return entry_dvalue();
+}
+
+
+//-------------------------------------------------
// entry_baseptr - return a pointer to where the
// data lives (if applicable)
//-------------------------------------------------
@@ -178,7 +208,7 @@ double device_state_entry::entry_dvalue() const
std::string device_state_entry::format(const char *string, bool maxout) const
{
std::string dest;
- u64 result = value();
+ u64 result = entry_value() & m_datamask;
// parse the format
bool leadzero = false;
@@ -360,6 +390,37 @@ std::string device_state_entry::format(const char *string, bool maxout) const
//-------------------------------------------------
+// to_string - return the value of the given
+// piece of indexed state as a string
+//-------------------------------------------------
+
+std::string device_state_entry::to_string() const
+{
+ // get the custom string if needed
+ std::string custom;
+ if ((m_flags & DSF_CUSTOM_STRING) != 0)
+ m_device_state->state_string_export(*this, custom);
+ else if ((m_flags & DSF_FLOATING_POINT) != 0)
+ custom = string_format("%-12G", entry_dvalue());
+
+ // ask the entry to format itself
+ return format(custom.c_str());
+}
+
+
+//-------------------------------------------------
+// max_length - return the maximum length of the
+// given state as a string
+//-------------------------------------------------
+
+int device_state_entry::max_length() const
+{
+ // ask the entry to format itself maximally
+ return format("", true).length();
+}
+
+
+//-------------------------------------------------
// set_value - set the value from a u64
//-------------------------------------------------
@@ -376,6 +437,10 @@ void device_state_entry::set_value(u64 value) const
// store the value
entry_set_value(value);
+
+ // call the importer to finish up
+ if ((m_flags & DSF_IMPORT) != 0)
+ m_device_state->state_import(*this);
}
@@ -389,6 +454,10 @@ void device_state_entry::set_dvalue(double value) const
// store the value
entry_set_dvalue(value);
+
+ // call the importer to finish up
+ if ((m_flags & DSF_IMPORT) != 0)
+ m_device_state->state_import(*this);
}
@@ -411,16 +480,6 @@ void device_state_entry::entry_set_dvalue(double value) const
}
-//-------------------------------------------------
-// set_value - set the value from a string
-//-------------------------------------------------
-
-void device_state_entry::set_value(const char *string) const
-{
- // not implemented
-}
-
-
//**************************************************************************
// DEVICE STATE INTERFACE
@@ -450,110 +509,6 @@ device_state_interface::~device_state_interface()
//-------------------------------------------------
-// state_int - return the value of the given piece
-// of indexed state as a u64
-//-------------------------------------------------
-
-u64 device_state_interface::state_int(int index)
-{
- // nullptr or out-of-range entry returns 0
- const device_state_entry *entry = state_find_entry(index);
- if (entry == nullptr)
- return 0;
-
- // call the exporter before we do anything
- if (entry->needs_export())
- state_export(*entry);
-
- // pick up the value
- return entry->value();
-}
-
-
-//-------------------------------------------------
-// state_string - return the value of the given
-// pieces of indexed state as a string
-//-------------------------------------------------
-
-std::string device_state_interface::state_string(int index) const
-{
- // nullptr or out-of-range entry returns bogus string
- const device_state_entry *entry = state_find_entry(index);
- if (entry == nullptr)
- return std::string("???");
-
- // get the custom string if needed
- std::string custom;
- if (entry->needs_custom_string())
- state_string_export(*entry, custom);
- else if (entry->is_float())
- custom = string_format("%-12G", entry->dvalue());
-
- // ask the entry to format itself
- return entry->format(custom.c_str());
-}
-
-
-//-------------------------------------------------
-// state_string_max_length - return the maximum
-// length of the given state string
-//-------------------------------------------------
-
-int device_state_interface::state_string_max_length(int index)
-{
- // nullptr or out-of-range entry returns bogus string
- const device_state_entry *entry = state_find_entry(index);
- if (entry == nullptr)
- return 3;
-
- // ask the entry to format itself maximally
- return entry->format("", true).length();
-}
-
-
-//-------------------------------------------------
-// set_state_int - set the value of the given
-// piece of indexed state from a u64
-//-------------------------------------------------
-
-void device_state_interface::set_state_int(int index, u64 value)
-{
- // nullptr or out-of-range entry is a no-op
- const device_state_entry *entry = state_find_entry(index);
- if (entry == nullptr)
- return;
-
- // set the value
- entry->set_value(value);
-
- // call the importer to finish up
- if (entry->needs_import())
- state_import(*entry);
-}
-
-
-//-------------------------------------------------
-// set_state - set the value of the given piece
-// of indexed state from a string
-//-------------------------------------------------
-
-void device_state_interface::set_state_string(int index, const char *string)
-{
- // nullptr or out-of-range entry is a no-op
- const device_state_entry *entry = state_find_entry(index);
- if (entry == nullptr)
- return;
-
- // set the value
- entry->set_value(string);
-
- // call the importer to finish up
- if (entry->needs_import())
- state_import(*entry);
-}
-
-
-//-------------------------------------------------
// state_add - add a new piece of indexed state
//-------------------------------------------------
@@ -626,24 +581,3 @@ void device_state_interface::interface_post_start()
if (m_state_list.size() == 0)
throw emu_fatalerror("No state registered for device '%s' that supports it!", device().tag());
}
-
-
-//-------------------------------------------------
-// state_find_entry - return a pointer to the
-// state entry for the given index
-//-------------------------------------------------
-
-const device_state_entry *device_state_interface::state_find_entry(int index) const
-{
- // use fast lookup if possible
- if (index >= FAST_STATE_MIN && index <= FAST_STATE_MAX)
- return m_fast_state[index - FAST_STATE_MIN];
-
- // otherwise, scan the first
- for (auto &entry : m_state_list)
- if (entry->m_index == index)
- return entry.get();
-
- // handle failure by returning nullptr
- return nullptr;
-}
diff --git a/src/emu/distate.h b/src/emu/distate.h
index 5951a0143d4..5ab34a24cf9 100644
--- a/src/emu/distate.h
+++ b/src/emu/distate.h
@@ -43,7 +43,6 @@ enum
// class describing a single item of exposed device state
class device_state_entry
{
- friend class device_state_interface;
public:
// construction/destruction
device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, u8 flags, device_state_interface *dev);
@@ -73,6 +72,18 @@ public:
device_state_interface *parent_state() const {return m_device_state;}
const std::string &format_string() const { return m_format; }
+ // return the current value
+ u64 value() const;
+ double dvalue() const;
+
+ // return the current value as a string
+ std::string to_string() const;
+ int max_length() const;
+
+ // set the current value
+ void set_value(u64 value) const;
+ void set_dvalue(double value) const;
+
protected:
// device state flags
static constexpr u8 DSF_NOSHOW = 0x01; // don't display this entry in the registers view
@@ -84,22 +95,6 @@ protected:
static constexpr u8 DSF_READONLY = 0x40; // set if this entry does not permit writes
static constexpr u8 DSF_FLOATING_POINT = 0x80; // set if this entry represents a floating-point value
- // helpers
- bool needs_custom_string() const { return ((m_flags & DSF_CUSTOM_STRING) != 0); }
- void format_from_mask();
-
- // return the current value -- only for our friends who handle export
- bool needs_export() const { return ((m_flags & DSF_EXPORT) != 0); }
- u64 value() const { return entry_value() & m_datamask; }
- double dvalue() const { return entry_dvalue(); }
- std::string format(const char *string, bool maxout = false) const;
-
- // set the current value -- only for our friends who handle import
- bool needs_import() const { return ((m_flags & DSF_IMPORT) != 0); }
- void set_value(u64 value) const;
- void set_dvalue(double value) const;
- void set_value(const char *string) const;
-
// overrides
virtual void *entry_baseptr() const;
virtual u64 entry_value() const;
@@ -107,6 +102,11 @@ protected:
virtual double entry_dvalue() const;
virtual void entry_set_dvalue(double value) const;
+private:
+ // helpers
+ void format_from_mask();
+ std::string format(const char *string, bool maxout = false) const;
+
// statics
static const u64 k_decimal_divisor[20]; // divisors for outputting decimal values
@@ -195,18 +195,47 @@ private:
};
-// ======================> device_state_register
+// ======================> device_latched_functional_state_register
// class template representing a state register of a specific width
template<class ItemType>
-class device_pseudo_state_register : public device_state_entry
+class device_latched_functional_state_register : public device_state_entry
+{
+public:
+ typedef typename std::function<void (ItemType)> setter_func;
+
+ // construction/destruction
+ device_latched_functional_state_register(int index, const char *symbol, ItemType &data, setter_func &&setter, device_state_interface *dev)
+ : device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), 0, dev),
+ m_data(data),
+ m_setter(std::move(setter))
+ {
+ }
+
+protected:
+ // device_state_entry overrides
+ virtual void *entry_baseptr() const override { return &m_data; }
+ virtual u64 entry_value() const override { return m_data; }
+ virtual void entry_set_value(u64 value) const override { m_setter(value); }
+
+private:
+ ItemType & m_data; // reference to where the data lives
+ setter_func m_setter; // function to store the data
+};
+
+
+// ======================> device_functional_state_register
+
+// class template representing a state register of a specific width
+template<class ItemType>
+class device_functional_state_register : public device_state_entry
{
public:
typedef typename std::function<ItemType ()> getter_func;
typedef typename std::function<void (ItemType)> setter_func;
// construction/destruction
- device_pseudo_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
+ device_functional_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
: device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), 0, dev),
m_getter(std::move(getter)),
m_setter(std::move(setter))
@@ -223,12 +252,41 @@ private:
setter_func m_setter; // function to store the data
};
+template<>
+class device_functional_state_register<double> : public device_state_entry
+{
+public:
+ typedef typename std::function<double ()> getter_func;
+ typedef typename std::function<void (double)> setter_func;
+
+ // construction/destruction
+ device_functional_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
+ : device_state_entry(index, symbol, sizeof(double), ~u64(0), DSF_FLOATING_POINT, dev),
+ m_getter(std::move(getter)),
+ m_setter(std::move(setter))
+ {
+ }
+
+protected:
+ // device_state_entry overrides
+ virtual u64 entry_value() const override { return u64(m_getter()); }
+ virtual void entry_set_value(u64 value) const override { m_setter(double(value)); }
+ virtual double entry_dvalue() const override { return m_getter(); }
+ virtual void entry_set_dvalue(double value) const override { m_setter(value); }
+
+private:
+ getter_func m_getter; // function to retrieve the data
+ setter_func m_setter; // function to store the data
+};
+
// ======================> device_state_interface
// class representing interface-specific live state
class device_state_interface : public device_interface
{
+ friend class device_state_entry;
+
public:
// construction/destruction
device_state_interface(const machine_config &mconfig, device_t &device);
@@ -238,17 +296,15 @@ public:
const std::vector<std::unique_ptr<device_state_entry>> &state_entries() const { return m_state_list; }
// state getters
- u64 state_int(int index);
- std::string state_string(int index) const;
- int state_string_max_length(int index);
+ u64 state_int(int index) { const device_state_entry *entry = state_find_entry(index); return (entry == nullptr) ? 0 : entry->value(); }
+ std::string state_string(int index) const { const device_state_entry *entry = state_find_entry(index); return (entry == nullptr) ? std::string("???") : entry->to_string(); }
offs_t pc() { return state_int(STATE_GENPC); }
offs_t pcbase() { return state_int(STATE_GENPCBASE); }
offs_t sp() { return state_int(STATE_GENSP); }
u64 flags() { return state_int(STATE_GENFLAGS); }
// state setters
- void set_state_int(int index, u64 value);
- void set_state_string(int index, const char *string);
+ void set_state_int(int index, u64 value) { const device_state_entry *entry = state_find_entry(index); if (entry != nullptr) entry->set_value(value); }
void set_pc(offs_t pc) { set_state_int(STATE_GENPC, pc); }
// find the entry for a given index
@@ -267,19 +323,29 @@ public: // protected eventually
return state_add(std::make_unique<device_state_register<ItemType>>(index, symbol, data, this));
}
- // add a new state pseudo-register item (template argument must be explicit)
+ // add a new state register item using functional setter
+ template<class ItemType> device_state_entry &state_add(int index, const char *symbol, ItemType &data,
+ typename device_latched_functional_state_register<ItemType>::setter_func &&setter)
+ {
+ assert(symbol != nullptr);
+ return state_add(std::make_unique<device_latched_functional_state_register<ItemType>>(index, symbol, data, std::move(setter), this));
+ }
+
+ // add a new state register item using functional getter and setter (template argument must be explicit)
template<class ItemType> device_state_entry &state_add(int index, const char *symbol,
- typename device_pseudo_state_register<ItemType>::getter_func &&getter,
- typename device_pseudo_state_register<ItemType>::setter_func &&setter)
+ typename device_functional_state_register<ItemType>::getter_func &&getter,
+ typename device_functional_state_register<ItemType>::setter_func &&setter)
{
assert(symbol != nullptr);
- return state_add(std::make_unique<device_pseudo_state_register<ItemType>>(index, symbol, std::move(getter), std::move(setter), this));
+ return state_add(std::make_unique<device_functional_state_register<ItemType>>(index, symbol, std::move(getter), std::move(setter), this));
}
+
+ // add a new read-only state register item using functional getter (template argument must be explicit)
template<class ItemType> device_state_entry &state_add(int index, const char *symbol,
- typename device_pseudo_state_register<ItemType>::getter_func &&getter)
+ typename device_functional_state_register<ItemType>::getter_func &&getter)
{
assert(symbol != nullptr);
- return state_add(std::make_unique<device_pseudo_state_register<ItemType>>(index, symbol, std::move(getter), [](ItemType){}, this)).readonly();
+ return state_add(std::make_unique<device_functional_state_register<ItemType>>(index, symbol, std::move(getter), [](ItemType){}, this)).readonly();
}
device_state_entry &state_add(std::unique_ptr<device_state_entry> &&entry);
@@ -310,4 +376,30 @@ protected:
// iterator
typedef device_interface_iterator<device_state_interface> state_interface_iterator;
+
+
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
+
+//-------------------------------------------------
+// state_find_entry - return a pointer to the
+// state entry for the given index
+//-------------------------------------------------
+
+inline const device_state_entry *device_state_interface::state_find_entry(int index) const
+{
+ // use fast lookup if possible
+ if (index >= FAST_STATE_MIN && index <= FAST_STATE_MAX)
+ return m_fast_state[index - FAST_STATE_MIN];
+
+ // otherwise, scan the first
+ for (auto &entry : m_state_list)
+ if (entry->index() == index)
+ return entry.get();
+
+ // handle failure by returning nullptr
+ return nullptr;
+}
+
#endif /* MAME_EMU_DISTATE_H */