summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/mconfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/mconfig.cpp')
-rw-r--r--src/emu/mconfig.cpp134
1 files changed, 111 insertions, 23 deletions
diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp
index e9533aff7d8..d6385c6d628 100644
--- a/src/emu/mconfig.cpp
+++ b/src/emu/mconfig.cpp
@@ -13,7 +13,9 @@
#include "screen.h"
#include <ctype.h>
+
#include <cstring>
+#include <numeric>
//**************************************************************************
@@ -37,12 +39,13 @@ private:
//-------------------------------------------------
machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
- : m_minimum_quantum(attotime::zero)
- , m_gamedrv(gamedrv)
+ : m_gamedrv(gamedrv)
, m_options(options)
, m_root_device()
, m_default_layouts([] (char const *a, char const *b) { return 0 > std::strcmp(a, b); })
, m_current_device(nullptr)
+ , m_maximum_quantums([] (char const *a, char const *b) { return 0 > std::strcmp(a, b); })
+ , m_perfect_quantum_device(nullptr, "")
{
// add the root device
device_add("root", gamedrv.type, 0);
@@ -117,6 +120,51 @@ machine_config::~machine_config()
//-------------------------------------------------
+// maximum_quantum - get smallest configured
+// maximum quantum
+//-------------------------------------------------
+
+attotime machine_config::maximum_quantum(attotime const &default_quantum) const
+{
+ return std::accumulate(
+ m_maximum_quantums.begin(),
+ m_maximum_quantums.end(),
+ default_quantum,
+ [] (attotime const &lhs, maximum_quantum_map::value_type const &rhs) { return (std::min)(lhs, rhs.second); });
+}
+
+//-------------------------------------------------
+// perfect_quantum_device - get device configured
+// for perfect quantum if any
+//-------------------------------------------------
+
+device_execute_interface *machine_config::perfect_quantum_device() const
+{
+ if (!m_perfect_quantum_device.first)
+ return nullptr;
+
+ device_t *const found(m_perfect_quantum_device.first->subdevice(m_perfect_quantum_device.second.c_str()));
+ if (!found)
+ {
+ throw emu_fatalerror(
+ "Device %s relative to %s specified for perfect interleave is not present!\n",
+ m_perfect_quantum_device.second,
+ m_perfect_quantum_device.first->tag());
+ }
+
+ device_execute_interface *result;
+ if (!found->interface(result))
+ {
+ throw emu_fatalerror("Device %s (%s) specified for perfect interleave does not implement device_execute_interface!\n",
+ found->tag(),
+ found->shortname());
+ }
+
+ return result;
+}
+
+
+//-------------------------------------------------
// set_default_layout - set layout for current
// device
//-------------------------------------------------
@@ -130,6 +178,19 @@ void machine_config::set_default_layout(internal_layout const &layout)
//-------------------------------------------------
+// set_maximum_quantum - set maximum scheduling
+// quantum for current device device
+//-------------------------------------------------
+
+void machine_config::set_maximum_quantum(attotime const &quantum)
+{
+ std::pair<maximum_quantum_map::iterator, bool> const ins(m_maximum_quantums.emplace(current_device().tag(), quantum));
+ if (!ins.second)
+ ins.first->second = quantum;
+}
+
+
+//-------------------------------------------------
// device_add - configuration helper to add a
// new device
//-------------------------------------------------
@@ -288,43 +349,70 @@ device_t &machine_config::replace_device(std::unique_ptr<device_t> &&device, dev
//-------------------------------------------------
-// device_find - configuration helper to
-// locate a device
-//-------------------------------------------------
-
-device_t *machine_config::device_find(device_t *owner, const char *tag)
-{
- // find the original device by relative tag (must exist)
- assert(owner != nullptr);
- device_t *device = owner->subdevice(tag);
- if (device == nullptr)
- throw emu_fatalerror("Unable to find device '%s'\n", tag);
-
- // return the device
- return device;
-}
-
-
-//-------------------------------------------------
// remove_references - globally remove references
// to a device about to be removed from the tree
//-------------------------------------------------
void machine_config::remove_references(device_t &device)
{
- // remove default layouts for subdevices
+ // sanity check
+ if (m_perfect_quantum_device.first == &device)
+ {
+ throw emu_fatalerror(
+ "Removing %s device %s would make the perfect quantum device target invalid\n",
+ device.shortname(),
+ device.tag());
+ }
+
+ // remove default layouts and maximum quantum settings for subdevices
char const *const tag(device.tag());
std::size_t const taglen(std::strlen(tag));
- default_layout_map::iterator it(m_default_layouts.lower_bound(tag));
- while ((m_default_layouts.end() != it) && !std::strncmp(tag, it->first, taglen))
+ for (auto it = m_default_layouts.lower_bound(tag); (m_default_layouts.end() != it) && !std::strncmp(tag, it->first, taglen); )
{
if (!it->first[taglen] || (':' == it->first[taglen]))
it = m_default_layouts.erase(it);
else
++it;
}
+ for (auto it = m_maximum_quantums.lower_bound(tag); (m_maximum_quantums.end() != it) && !std::strncmp(tag, it->first, taglen); )
+ {
+ if (!it->first[taglen] || (':' == it->first[taglen]))
+ it = m_maximum_quantums.erase(it);
+ else
+ ++it;
+ }
// iterate over all devices and remove any references
for (device_t &scan : device_iterator(root_device()))
scan.subdevices().m_tagmap.clear();
}
+
+
+//-------------------------------------------------
+// set_perfect_quantum - set device to base
+// scheduling interval on
+//-------------------------------------------------
+
+void machine_config::set_perfect_quantum(device_t &device, std::string tag)
+{
+ if (!m_current_device)
+ {
+ throw emu_fatalerror(
+ "Perfect quantum device can only be set during configuration (set to %s relative to %s)\n",
+ tag,
+ device.tag());
+ }
+
+ if (m_current_device != m_root_device.get())
+ {
+ throw emu_fatalerror(
+ "Perfect quantum device can only be set by the root device (set to %s relative to %s while configuring %s device %s)\n",
+ tag,
+ device.tag(),
+ m_current_device->shortname(),
+ m_current_device->tag());
+ }
+
+ m_perfect_quantum_device.first = &device;
+ m_perfect_quantum_device.second = std::move(tag);
+}