Explicitly allow floating point values for state registers

Note that the internal debugger's expression interpreter is not set up to handle floating point values at all, so they remain disabled there.
This commit is contained in:
AJR 2017-10-13 07:24:43 -04:00
parent f2dac42df3
commit c6b2edfa89
7 changed files with 91 additions and 98 deletions

View File

@ -150,7 +150,6 @@ void clipper_device::device_start()
state_add(CLIPPER_R14, "r14", m_r[14]);
state_add(CLIPPER_R15, "r15", m_r[15]);
#ifdef STATE_REGISTER_DOUBLE
state_add(CLIPPER_F0, "f0", m_f[0]);
state_add(CLIPPER_F1, "f1", m_f[1]);
state_add(CLIPPER_F2, "f2", m_f[2]);
@ -172,7 +171,6 @@ void clipper_device::device_start()
state_add(CLIPPER_F14, "f14", m_f[14]);
state_add(CLIPPER_F15, "f15", m_f[15]);
}
#endif
}
void clipper_device::device_reset()

View File

@ -212,12 +212,10 @@ void dsp32c_device::device_start()
state_add(DSP32_PIN, "PIN", m_pin).mask(0xffffff);
state_add(DSP32_POUT, "POUT", m_pout).mask(0xffffff);
state_add(DSP32_IVTP, "IVTP", m_ivtp).mask(0xffffff);
#ifdef STATE_REGISTER_DOUBLE
state_add(DSP32_A0, "A0", m_a[0]).formatstr("%8s");
state_add(DSP32_A1, "A1", m_a[1]).formatstr("%8s");
state_add(DSP32_A2, "A2", m_a[2]).formatstr("%8s");
state_add(DSP32_A3, "A3", m_a[3]).formatstr("%8s");
#endif
state_add(DSP32_DAUC, "DAUC", m_r[26]).mask(0xff);
state_add(DSP32_PAR, "PAR", m_par);
state_add(DSP32_PDR, "PDR", m_pdr);

View File

@ -799,90 +799,14 @@ void ppc_device::device_start()
state_add(PPC_TBL, "TBL", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add(PPC_DEC, "DEC", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add(PPC_SR0, "SR0", m_core->sr[0]).formatstr("%08X");
state_add(PPC_SR1, "SR1", m_core->sr[1]).formatstr("%08X");
state_add(PPC_SR2, "SR2", m_core->sr[2]).formatstr("%08X");
state_add(PPC_SR3, "SR3", m_core->sr[3]).formatstr("%08X");
state_add(PPC_SR4, "SR4", m_core->sr[4]).formatstr("%08X");
state_add(PPC_SR5, "SR5", m_core->sr[5]).formatstr("%08X");
state_add(PPC_SR6, "SR6", m_core->sr[6]).formatstr("%08X");
state_add(PPC_SR7, "SR7", m_core->sr[7]).formatstr("%08X");
state_add(PPC_SR8, "SR8", m_core->sr[8]).formatstr("%08X");
state_add(PPC_SR9, "SR9", m_core->sr[9]).formatstr("%08X");
state_add(PPC_SR10, "SR10", m_core->sr[10]).formatstr("%08X");
state_add(PPC_SR11, "SR11", m_core->sr[11]).formatstr("%08X");
state_add(PPC_SR12, "SR12", m_core->sr[12]).formatstr("%08X");
state_add(PPC_SR13, "SR13", m_core->sr[13]).formatstr("%08X");
state_add(PPC_SR14, "SR14", m_core->sr[14]).formatstr("%08X");
state_add(PPC_SR15, "SR15", m_core->sr[15]).formatstr("%08X");
for (int regnum = 0; regnum < 16; regnum++)
state_add(PPC_SR0 + regnum, string_format("SR%d", regnum).c_str(), m_core->sr[regnum]).formatstr("%08X");
state_add(PPC_R0, "R0", m_core->r[0]).formatstr("%08X");
state_add(PPC_R1, "R1", m_core->r[1]).formatstr("%08X");
state_add(PPC_R2, "R2", m_core->r[2]).formatstr("%08X");
state_add(PPC_R3, "R3", m_core->r[3]).formatstr("%08X");
state_add(PPC_R4, "R4", m_core->r[4]).formatstr("%08X");
state_add(PPC_R5, "R5", m_core->r[5]).formatstr("%08X");
state_add(PPC_R6, "R6", m_core->r[6]).formatstr("%08X");
state_add(PPC_R7, "R7", m_core->r[7]).formatstr("%08X");
state_add(PPC_R8, "R8", m_core->r[8]).formatstr("%08X");
state_add(PPC_R9, "R9", m_core->r[9]).formatstr("%08X");
state_add(PPC_R10, "R10", m_core->r[10]).formatstr("%08X");
state_add(PPC_R11, "R11", m_core->r[11]).formatstr("%08X");
state_add(PPC_R12, "R12", m_core->r[12]).formatstr("%08X");
state_add(PPC_R13, "R13", m_core->r[13]).formatstr("%08X");
state_add(PPC_R14, "R14", m_core->r[14]).formatstr("%08X");
state_add(PPC_R15, "R15", m_core->r[15]).formatstr("%08X");
state_add(PPC_R16, "R16", m_core->r[16]).formatstr("%08X");
state_add(PPC_R17, "R17", m_core->r[17]).formatstr("%08X");
state_add(PPC_R18, "R18", m_core->r[18]).formatstr("%08X");
state_add(PPC_R19, "R19", m_core->r[19]).formatstr("%08X");
state_add(PPC_R20, "R20", m_core->r[20]).formatstr("%08X");
state_add(PPC_R21, "R21", m_core->r[21]).formatstr("%08X");
state_add(PPC_R22, "R22", m_core->r[22]).formatstr("%08X");
state_add(PPC_R23, "R23", m_core->r[23]).formatstr("%08X");
state_add(PPC_R24, "R24", m_core->r[24]).formatstr("%08X");
state_add(PPC_R25, "R25", m_core->r[25]).formatstr("%08X");
state_add(PPC_R26, "R26", m_core->r[26]).formatstr("%08X");
state_add(PPC_R27, "R27", m_core->r[27]).formatstr("%08X");
state_add(PPC_R28, "R28", m_core->r[28]).formatstr("%08X");
state_add(PPC_R29, "R29", m_core->r[29]).formatstr("%08X");
state_add(PPC_R30, "R30", m_core->r[30]).formatstr("%08X");
state_add(PPC_R31, "R31", m_core->r[31]).formatstr("%08X");
for (int regnum = 0; regnum < 32; regnum++)
state_add(PPC_R0 + regnum, string_format("R%d", regnum).c_str(), m_core->r[regnum]).formatstr("%08X");
#ifdef STATE_REGISTER_DOUBLE
state_add(PPC_F0, "F0", m_core->f[0]).formatstr("%12s");
state_add(PPC_F1, "F1", m_core->f[1]).formatstr("%12s");
state_add(PPC_F2, "F2", m_core->f[2]).formatstr("%12s");
state_add(PPC_F3, "F3", m_core->f[3]).formatstr("%12s");
state_add(PPC_F4, "F4", m_core->f[4]).formatstr("%12s");
state_add(PPC_F5, "F5", m_core->f[5]).formatstr("%12s");
state_add(PPC_F6, "F6", m_core->f[6]).formatstr("%12s");
state_add(PPC_F7, "F7", m_core->f[7]).formatstr("%12s");
state_add(PPC_F8, "F8", m_core->f[8]).formatstr("%12s");
state_add(PPC_F9, "F9", m_core->f[9]).formatstr("%12s");
state_add(PPC_F10, "F10", m_core->f[10]).formatstr("%12s");
state_add(PPC_F11, "F11", m_core->f[11]).formatstr("%12s");
state_add(PPC_F12, "F12", m_core->f[12]).formatstr("%12s");
state_add(PPC_F13, "F13", m_core->f[13]).formatstr("%12s");
state_add(PPC_F14, "F14", m_core->f[14]).formatstr("%12s");
state_add(PPC_F15, "F15", m_core->f[15]).formatstr("%12s");
state_add(PPC_F16, "F16", m_core->f[16]).formatstr("%12s");
state_add(PPC_F17, "F17", m_core->f[17]).formatstr("%12s");
state_add(PPC_F18, "F18", m_core->f[18]).formatstr("%12s");
state_add(PPC_F19, "F19", m_core->f[19]).formatstr("%12s");
state_add(PPC_F20, "F20", m_core->f[20]).formatstr("%12s");
state_add(PPC_F21, "F21", m_core->f[21]).formatstr("%12s");
state_add(PPC_F22, "F22", m_core->f[22]).formatstr("%12s");
state_add(PPC_F23, "F23", m_core->f[23]).formatstr("%12s");
state_add(PPC_F24, "F24", m_core->f[24]).formatstr("%12s");
state_add(PPC_F25, "F25", m_core->f[25]).formatstr("%12s");
state_add(PPC_F26, "F26", m_core->f[26]).formatstr("%12s");
state_add(PPC_F27, "F27", m_core->f[27]).formatstr("%12s");
state_add(PPC_F28, "F28", m_core->f[28]).formatstr("%12s");
state_add(PPC_F29, "F29", m_core->f[29]).formatstr("%12s");
state_add(PPC_F30, "F30", m_core->f[30]).formatstr("%12s");
state_add(PPC_F31, "F31", m_core->f[31]).formatstr("%12s");
#endif
for (int regnum = 0; regnum < 32; regnum++)
state_add(PPC_F0 + regnum, string_format("F%d", regnum).c_str(), m_core->f[regnum]).formatstr("%12s");
state_add(PPC_FPSCR, "FPSCR", m_core->fpscr).formatstr("%08X");
state_add(STATE_GENPC, "GENPC", m_core->pc).noshow();

View File

@ -1021,10 +1021,7 @@ void netlist_mame_cpu_device::device_start()
}
else
{
#ifdef STATE_REGISTER_DOUBLE
// This attempts to register state variables of type nl_double (double), which is currently not supported
state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
#endif
state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr());
}
}

View File

@ -1559,8 +1559,12 @@ device_debug::device_debug(device_t &device)
std::string tempstr;
for (const auto &entry : m_state->state_entries())
{
strmakelower(tempstr.assign(entry->symbol()));
m_symtable.add(tempstr.c_str(), (void *)(uintptr_t)entry->index(), get_state, entry->writeable() ? set_state : nullptr, entry->format_string());
// TODO: floating point registers
if (!entry->is_float())
{
strmakelower(tempstr.assign(entry->symbol()));
m_symtable.add(tempstr.c_str(), (void *)(uintptr_t)entry->index(), get_state, entry->writeable() ? set_state : nullptr, entry->format_string());
}
}
}

View File

@ -49,17 +49,17 @@ const u64 device_state_entry::k_decimal_divisor[] =
// device_state_entry - constructor
//-------------------------------------------------
device_state_entry::device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, device_state_interface *dev)
device_state_entry::device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, u8 flags, device_state_interface *dev)
: m_device_state(dev),
m_index(index),
m_datamask(sizemask),
m_datasize(size),
m_flags(0),
m_flags(flags),
m_symbol(symbol),
m_default_format(true),
m_sizemask(sizemask)
{
assert(size == 1 || size == 2 || size == 4 || size == 8);
assert(size == 1 || size == 2 || size == 4 || size == 8 || (flags & DSF_FLOATING_POINT) != 0);
format_from_mask();
@ -113,6 +113,12 @@ void device_state_entry::format_from_mask()
if (!m_default_format)
return;
if (is_float())
{
m_format = "%12s";
return;
}
// make up a format based on the mask
int width = 0;
for (u64 tempmask = m_datamask; tempmask != 0; tempmask >>= 4)
@ -142,6 +148,17 @@ u64 device_state_entry::entry_value() const
}
//-------------------------------------------------
// entry_dvalue - return the current value as a
// double
//-------------------------------------------------
double device_state_entry::entry_dvalue() const
{
return 0.0;
}
//-------------------------------------------------
// format - return the value of the given
// pieces of indexed state as a string
@ -351,6 +368,19 @@ void device_state_entry::set_value(u64 value) const
}
//-------------------------------------------------
// set_dvalue - set the value from a double
//-------------------------------------------------
void device_state_entry::set_dvalue(double value) const
{
assert((m_flags & DSF_READONLY) == 0);
// store the value
entry_set_dvalue(value);
}
//-------------------------------------------------
// entry_set_value - set the value from a u64
//-------------------------------------------------
@ -360,6 +390,16 @@ void device_state_entry::entry_set_value(u64 value) const
}
//-------------------------------------------------
// entry_set_dvalue - set the value from a double
//-------------------------------------------------
void device_state_entry::entry_set_dvalue(double value) const
{
set_value(u64(value));
}
//-------------------------------------------------
// set_value - set the value from a string
//-------------------------------------------------
@ -435,6 +475,8 @@ std::string device_state_interface::state_string(int index) const
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());

View File

@ -46,7 +46,7 @@ class device_state_entry
friend class device_state_interface;
public:
// construction/destruction
device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, device_state_interface *dev);
device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, u8 flags, device_state_interface *dev);
device_state_entry(int index, device_state_interface *dev);
public:
@ -67,6 +67,7 @@ public:
bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); }
bool writeable() const { return ((m_flags & DSF_READONLY) == 0); }
bool divider() const { return m_flags & DSF_DIVIDER; }
bool is_float() const { return m_flags & DSF_FLOATING_POINT; }
device_state_interface *parent_state() const {return m_device_state;}
const std::string &format_string() const { return m_format; }
@ -79,6 +80,7 @@ protected:
static constexpr u8 DSF_CUSTOM_STRING = 0x10; // set if the format has a custom string
static constexpr u8 DSF_DIVIDER = 0x20; // set if this is a divider entry
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); }
@ -87,17 +89,21 @@ protected:
// 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;
virtual void entry_set_value(u64 value) const;
virtual double entry_dvalue() const;
virtual void entry_set_dvalue(double value) const;
// statics
static const u64 k_decimal_divisor[20]; // divisors for outputting decimal values
@ -124,7 +130,7 @@ class device_state_register : public device_state_entry
public:
// construction/destruction
device_state_register(int index, const char *symbol, ItemType &data, device_state_interface *dev)
: device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), dev),
: device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), 0, dev),
m_data(data)
{
static_assert(std::is_integral<ItemType>().value, "Registration of non-integer types is not currently supported");
@ -140,6 +146,30 @@ private:
ItemType & m_data; // reference to where the data lives
};
// class template representing a floating-point state register
template<>
class device_state_register<double> : public device_state_entry
{
public:
// construction/destruction
device_state_register(int index, const char *symbol, double &data, device_state_interface *dev)
: device_state_entry(index, symbol, sizeof(double), ~u64(0), DSF_FLOATING_POINT, dev),
m_data(data)
{
}
protected:
// device_state_entry overrides
virtual void *entry_baseptr() const override { return &m_data; }
virtual u64 entry_value() const override { return u64(m_data); }
virtual void entry_set_value(u64 value) const override { m_data = double(value); }
virtual double entry_dvalue() const override { return m_data; }
virtual void entry_set_dvalue(double value) const override { m_data = value; }
private:
double & m_data; // reference to where the data lives
};
// ======================> device_state_register
@ -153,7 +183,7 @@ public:
// 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(ItemType), std::numeric_limits<ItemType>::max(), 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))
{