diff options
Diffstat (limited to 'src/emu/distate.cpp')
-rw-r--r-- | src/emu/distate.cpp | 239 |
1 files changed, 81 insertions, 158 deletions
diff --git a/src/emu/distate.cpp b/src/emu/distate.cpp index 2dcf4301ac4..76ede23dfe2 100644 --- a/src/emu/distate.cpp +++ b/src/emu/distate.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /*************************************************************************** - distate.c + distate.cpp Device state interfaces. @@ -56,8 +56,7 @@ device_state_entry::device_state_entry(int index, const char *symbol, u8 size, u m_datasize(size), m_flags(flags), m_symbol(symbol), - m_default_format(true), - m_sizemask(sizemask) + m_default_format(true) { assert(size == 1 || size == 2 || size == 4 || size == 8 || (flags & DSF_FLOATING_POINT) != 0); @@ -66,8 +65,6 @@ device_state_entry::device_state_entry(int index, const char *symbol, u8 size, u // override well-known symbols if (index == STATE_GENPCBASE) m_symbol.assign("CURPC"); - else if (index == STATE_GENSP) - m_symbol.assign("CURSP"); else if (index == STATE_GENFLAGS) m_symbol.assign("CURFLAGS"); } @@ -79,8 +76,7 @@ device_state_entry::device_state_entry(int index, device_state_interface *dev) m_datasize(0), m_flags(DSF_DIVIDER | DSF_READONLY), m_symbol(), - m_default_format(true), - m_sizemask(0) + m_default_format(true) { } @@ -105,7 +101,7 @@ device_state_entry &device_state_entry::formatstr(const char *_format) // set the DSF_CUSTOM_STRING flag by formatting with a nullptr string m_flags &= ~DSF_CUSTOM_STRING; - format(nullptr); + format(nullptr, 0); return *this; } @@ -130,15 +126,43 @@ void device_state_entry::format_from_mask() // make up a format based on the mask if (m_datamask == 0) - throw emu_fatalerror("%s state entry requires a nonzero mask\n", m_symbol.c_str()); - int width = 0; - for (u64 tempmask = m_datamask; tempmask != 0; tempmask >>= 4) - width++; + throw emu_fatalerror("%s state entry requires a nonzero mask\n", m_symbol); + int width = (63 - count_leading_zeros_64(m_datamask)) / 4 + 1; m_format = string_format("%%0%dX", width); } //------------------------------------------------- +// 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) //------------------------------------------------- @@ -175,12 +199,10 @@ double device_state_entry::entry_dvalue() const // pieces of indexed state as a string //------------------------------------------------- -std::string device_state_entry::format(const char *string, bool maxout) const +std::string device_state_entry::format(const char *string, u64 result, bool maxout) const { - std::string dest; - u64 result = value(); - // parse the format + std::string dest; bool leadzero = false; bool percent = false; bool explicitsign = false; @@ -303,18 +325,18 @@ std::string device_state_entry::format(const char *string, bool maxout) const width--; } // fall through to unsigned case - + [[fallthrough]]; // u outputs as unsigned decimal case 'u': if (width == 0) throw emu_fatalerror("Width required for %%u formats\n"); hitnonzero = false; - while (leadzero && width > ARRAY_LENGTH(k_decimal_divisor)) + while (leadzero && width > std::size(k_decimal_divisor)) { dest.append(" "); width--; } - for (int digitnum = ARRAY_LENGTH(k_decimal_divisor) - 1; digitnum >= 0; digitnum--) + for (int digitnum = std::size(k_decimal_divisor) - 1; digitnum >= 0; digitnum--) { int digit = (result >= k_decimal_divisor[digitnum]) ? (result / k_decimal_divisor[digitnum]) % 10 : 0; if (digit != 0) @@ -360,6 +382,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(), value()); +} + + +//------------------------------------------------- +// 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("", 0, true).length(); +} + + +//------------------------------------------------- // set_value - set the value from a u64 //------------------------------------------------- @@ -376,6 +429,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 +446,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 +472,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 @@ -434,9 +485,6 @@ device_state_interface::device_state_interface(const machine_config &mconfig, de : device_interface(device, "state") { memset(m_fast_state, 0, sizeof(m_fast_state)); - - // configure the fast accessor - device.interfaces().m_state = this; } @@ -450,110 +498,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 //------------------------------------------------- @@ -624,26 +568,5 @@ void device_state_interface::interface_post_start() { // make sure we got something during startup if (m_state_list.size() == 0) - throw emu_fatalerror("No state registered for device '%s' that supports it!", m_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; + throw emu_fatalerror("No state registered for device '%s' that supports it!", device().tag()); } |