summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-08-25 21:34:42 +1000
committer Vas Crabb <vas@vastheman.com>2016-08-25 21:34:42 +1000
commit1c98b515c5a10728d3d679ac7215440e55158f38 (patch)
tree0083c3d073488fa7d40e14c7fb4624bb19bff41a
parentcf8060d762ffddd8dbb923e5db9d2e6f7eed49e0 (diff)
* Doxyfy a significant chunk of devfind.h
* Eliminate a lot of boilerplate code from devfind.h * Keep instantiation of templates in one place to improve build time * Remove some dangerous accessors
-rw-r--r--src/devices/machine/rp5h01.cpp11
-rw-r--r--src/devices/machine/rp5h01.h7
-rw-r--r--src/devices/video/hd44780.cpp15
-rw-r--r--src/devices/video/hd44780.h3
-rw-r--r--src/emu/devfind.cpp54
-rw-r--r--src/emu/devfind.h782
-rw-r--r--src/emu/device.cpp2
-rw-r--r--src/emu/screen.h2
-rw-r--r--src/mame/machine/fd1094.cpp31
-rw-r--r--src/mame/machine/fd1094.h5
10 files changed, 521 insertions, 391 deletions
diff --git a/src/devices/machine/rp5h01.cpp b/src/devices/machine/rp5h01.cpp
index 009757b6acf..033e2b18f4c 100644
--- a/src/devices/machine/rp5h01.cpp
+++ b/src/devices/machine/rp5h01.cpp
@@ -20,7 +20,7 @@
#include "machine/rp5h01.h"
// this is the contents of an unprogrammed PROM
-UINT8 rp5h01_device::s_initial_data[0x10] =
+UINT8 const rp5h01_device::s_initial_data[0x10] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00
@@ -34,7 +34,8 @@ const device_type RP5H01 = &device_creator<rp5h01_device>;
rp5h01_device::rp5h01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, RP5H01, "RP5H01 6/7-bit Counter", tag, owner, clock, "rp5h01", __FILE__)
- , m_data(*this, DEVICE_SELF, 0x10)
+ , m_data(nullptr)
+ , m_rom(*this, DEVICE_SELF, 0x10)
{
}
@@ -54,8 +55,10 @@ void rp5h01_device::device_config_complete()
void rp5h01_device::device_start()
{
- if (!m_data.found())
- m_data.set_target(s_initial_data, 0x10);
+ if (m_rom.found())
+ m_data = m_rom;
+ else
+ m_data = s_initial_data;
/* register for state saving */
save_item(NAME(m_counter));
diff --git a/src/devices/machine/rp5h01.h b/src/devices/machine/rp5h01.h
index c33a80a998b..e1810b181ff 100644
--- a/src/devices/machine/rp5h01.h
+++ b/src/devices/machine/rp5h01.h
@@ -36,8 +36,6 @@ enum {
class rp5h01_device : public device_t
{
- static UINT8 s_initial_data[0x10];
-
public:
rp5h01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
@@ -56,13 +54,16 @@ protected:
virtual void device_reset() override;
private:
+ static UINT8 const s_initial_data[0x10];
+
// internal state
int m_counter;
int m_counter_mode; /* test pin */
int m_enabled; /* chip enable */
int m_old_reset; /* reset pin state (level-triggered) */
int m_old_clock; /* clock pin state (level-triggered) */
- optional_region_ptr<UINT8> m_data;
+ UINT8 const *m_data;
+ optional_region_ptr<UINT8> m_rom;
};
extern const device_type RP5H01;
diff --git a/src/devices/video/hd44780.cpp b/src/devices/video/hd44780.cpp
index b793bb51089..0911ac877d8 100644
--- a/src/devices/video/hd44780.cpp
+++ b/src/devices/video/hd44780.cpp
@@ -45,16 +45,16 @@ ROM_END
// hd44780_device - constructor
//-------------------------------------------------
-hd44780_device::hd44780_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
- device_t(mconfig, HD44780, "HD44780 A00", tag, owner, clock, "hd44780_a00", __FILE__),
- m_cgrom(*this, DEVICE_SELF)
+hd44780_device::hd44780_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : hd44780_device(mconfig, HD44780, "HD44780 A00", tag, owner, clock, "hd44780_a00", __FILE__)
{
set_charset_type(CHARSET_HD44780_A00);
}
-hd44780_device::hd44780_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
- device_t(mconfig, type, name, tag, owner, clock, shortname, source),
- m_cgrom(*this, DEVICE_SELF)
+hd44780_device::hd44780_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source)
+ , m_cgrom(nullptr)
+ , m_cgrom_region(*this, DEVICE_SELF)
{
}
@@ -86,8 +86,7 @@ const tiny_rom_entry *hd44780_device::device_rom_region() const
void hd44780_device::device_start()
{
- if (!m_cgrom.found())
- m_cgrom.set_target(memregion("cgrom")->base(), 0x1000);
+ m_cgrom = m_cgrom_region.found() ? m_cgrom_region : memregion("cgrom")->base();
m_pixel_update_cb.bind_relative_to(*owner());
diff --git a/src/devices/video/hd44780.h b/src/devices/video/hd44780.h
index 2c6eec873b6..d63a64e1023 100644
--- a/src/devices/video/hd44780.h
+++ b/src/devices/video/hd44780.h
@@ -105,7 +105,8 @@ private:
bool m_busy_flag; // busy flag
UINT8 m_ddram[0x80]; // internal display data RAM
UINT8 m_cgram[0x40]; // internal chargen RAM
- optional_region_ptr<UINT8> m_cgrom; // internal chargen ROM
+ UINT8 const *m_cgrom;
+ optional_region_ptr<UINT8> m_cgrom_region; // internal chargen ROM
int m_ac; // address counter
UINT8 m_dr; // data register
UINT8 m_ir; // instruction register
diff --git a/src/emu/devfind.cpp b/src/emu/devfind.cpp
index febe71d8b3a..b7ae5ab71ce 100644
--- a/src/emu/devfind.cpp
+++ b/src/emu/devfind.cpp
@@ -12,17 +12,41 @@
//**************************************************************************
+// TEMPLATE INSTANTIATIONS
+//**************************************************************************
+
+template class object_finder_base<memory_region, false>;
+template class object_finder_base<memory_region, true>;
+template class memory_region_finder<false>;
+template class memory_region_finder<true>;
+
+template class object_finder_base<memory_bank, false>;
+template class object_finder_base<memory_bank, true>;
+template class memory_bank_finder<false>;
+template class memory_bank_finder<true>;
+
+template class object_finder_base<ioport_port, false>;
+template class object_finder_base<ioport_port, true>;
+template class ioport_finder<false>;
+template class ioport_finder<true>;
+
+
+
+//**************************************************************************
// BASE FINDER CLASS
//**************************************************************************
+constexpr char finder_base::DUMMY_TAG[];
+
+
//-------------------------------------------------
// finder_base - constructor
//-------------------------------------------------
finder_base::finder_base(device_t &base, const char *tag)
- : m_next(base.register_auto_finder(*this)),
- m_base(base),
- m_tag(tag)
+ : m_next(base.register_auto_finder(*this))
+ , m_base(base)
+ , m_tag(tag)
{
}
@@ -43,7 +67,7 @@ finder_base::~finder_base()
void *finder_base::find_memregion(UINT8 width, size_t &length, bool required) const
{
// look up the region and return nullptr if not found
- memory_region *region = m_base.memregion(m_tag);
+ memory_region *const region = m_base.memregion(m_tag);
if (region == nullptr)
{
length = 0;
@@ -60,11 +84,11 @@ void *finder_base::find_memregion(UINT8 width, size_t &length, bool required) co
}
// check the length and warn if other than specified
- size_t length_found = region->bytes() / width;
+ size_t const length_found = region->bytes() / width;
if (length != 0 && length != length_found)
{
if (required)
- osd_printf_warning("Region '%s' found but has %d bytes, not %d as requested\n", m_tag, region->bytes(), (int)length*width);
+ osd_printf_warning("Region '%s' found but has %d bytes, not %ld as requested\n", m_tag, region->bytes(), long(length*width));
length = 0;
return nullptr;
}
@@ -100,15 +124,13 @@ bool finder_base::validate_memregion(size_t bytes, bool required) const
break;
}
- if (bytes_found != 0)
+ // check the length and warn if other than specified
+ if ((bytes_found != 0) && (bytes != 0) && (bytes != bytes_found))
{
- // check the length and warn if other than specified
- if (bytes != 0 && bytes != bytes_found)
- {
- osd_printf_warning("Region '%s' found but has %d bytes, not %d as requested\n", m_tag, (int)bytes_found, (int)bytes);
- bytes_found = 0;
- }
+ osd_printf_warning("Region '%s' found but has %ld bytes, not %ld as requested\n", m_tag, long(bytes_found), long(bytes));
+ bytes_found = 0;
}
+
return report_missing(bytes_found != 0, "memory region", required);
}
@@ -145,9 +167,9 @@ void *finder_base::find_memshare(UINT8 width, size_t &bytes, bool required) cons
bool finder_base::report_missing(bool found, const char *objname, bool required) const
{
- if (required && strcmp(m_tag, FINDER_DUMMY_TAG)==0)
+ if (required && (strcmp(m_tag, DUMMY_TAG) == 0))
{
- osd_printf_error("Tag not defined for required device\n");
+ osd_printf_error("Tag not defined for required %s\n", objname);
return false;
}
@@ -156,7 +178,7 @@ bool finder_base::report_missing(bool found, const char *objname, bool required)
return true;
// otherwise, report
- std::string region_fulltag = m_base.subtag(m_tag);
+ std::string const region_fulltag = m_base.subtag(m_tag);
if (required)
osd_printf_error("Required %s '%s' not found\n", objname, region_fulltag.c_str());
else
diff --git a/src/emu/devfind.h b/src/emu/devfind.h
index ab20cd83571..663bede2c87 100644
--- a/src/emu/devfind.h
+++ b/src/emu/devfind.h
@@ -1,14 +1,12 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- devfind.h
-
- Device finding template helpers.
-
-***************************************************************************/
-
-#pragma once
+// copyright-holders:Aaron Giles, Vas Crabb
+/**
+ * \file devfind.h
+ * Object auto-discovery helpers
+ * \defgroup devfind
+ * \{
+ * Object auto-disovery helpers
+ */
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
@@ -17,16 +15,20 @@
#ifndef MAME_EMU_DEVFIND_H
#define MAME_EMU_DEVFIND_H
-#define FINDER_DUMMY_TAG "finder_dummy_tag"
+#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-// ======================> array_finder_base
-
+/// \brief Helper class to find arrays of devices, etc.
+///
+/// Useful when a machine/device has a number of similar subdevices, I/O
+/// ports, memory regions, etc. Template arguments are the element type
+/// and number of elements in the array. It's assumed that the element
+/// can be constructed with a device_t reference and a C string tag.
template <typename T, unsigned Count>
-class array_finder_base
+class object_array_finder
{
private:
template <unsigned... V> struct indices { };
@@ -35,375 +37,531 @@ private:
template <unsigned C> using index_range = typename range<C>::type;
template <typename F, unsigned... V>
- array_finder_base(device_t &base, F const &fmt, unsigned start, indices<V...>)
+ object_array_finder(device_t &base, F const &fmt, unsigned start, indices<V...>)
: m_tag{ util::string_format(fmt, start + V)... }
, m_array{ { base, m_tag[V].c_str() }... }
{
}
template <unsigned... V>
- array_finder_base(device_t &base, std::array<char const *, Count> const &tags, indices<V...>)
+ object_array_finder(device_t &base, std::array<char const *, Count> const &tags, indices<V...>)
: m_array{ { base, tags[V] }... }
{
}
-protected:
- template <typename F> array_finder_base(device_t &base, F const &fmt, unsigned start) : array_finder_base(base, fmt, start, index_range<Count>()) { }
- array_finder_base(device_t &base, std::array<char const *, Count> const &tags) : array_finder_base(base, tags, index_range<Count>()) { }
-
- std::string m_tag[Count];
+ /// \brief Generated tag names
+ ///
+ /// Finder objects do not copy the search tag supplied at
+ /// construction. Tags that are programmatically generated at
+ /// construction are stored here so they persist until resolution
+ /// time (and beyond).
+ std::string const m_tag[Count];
+
+ /// \brief The object discovery elements
+ ///
+ /// These are the actual object discovery helpers. Note that this
+ /// member must be initialised after m_tag, as it may depend on
+ /// programmatically generated tags.
T m_array[Count];
public:
+ /// \brief Construct with programmatically generated tags
+ ///
+ /// Specify a format string and starting number. A single unsigned
+ /// int format argument is supplied containing the (zero-based)
+ /// element index added to the starting number. For example if
+ /// Count = 2, ("p%u_joy", 1) expands to ("p1_joy", "p2_joy"). The
+ /// relaxed format rules used by util::string_format apply.
+ /// \param [in] base Base device to search from.
+ /// \param [in] fmt Search tag format, should expect single unsigned
+ /// int argument.
+ /// \param [in] start Number to add to element index when calculating
+ /// values for string format arguments.
+ /// \sa util::string_format
+ template <typename F> object_array_finder(device_t &base, F const &fmt, unsigned start) : object_array_finder(base, fmt, start, index_range<Count>()) { }
+
+ /// \brief Construct with free-form list of tags
+ ///
+ /// Specify arbitrary tags for objects. Useful when there is no
+ /// particular pattern to the object tags.
+ /// \param [in] base Base device to search from.
+ /// \param [in] tags Tags to search for, e.g. { "player", "dips" }.
+ object_array_finder(device_t &base, std::array<char const *, Count> const &tags) : object_array_finder(base, tags, index_range<Count>()) { }
+
+ /// \brief Element accessor (const)
+ ///
+ /// Returns a const reference to the element at the supplied index.
+ /// \param [in] index Index of desired element (zero-based).
+ /// \return Reference to element at specified index.
const T &operator[](unsigned index) const { assert(index < Count); return m_array[index]; }
- T &operator[](unsigned index) { assert(index < Count); return m_array[index]; }
+ /// \brief Element accessor (non-const)
+ ///
+ /// Returns a reference to the element at the supplied index.
+ /// \param [in] index Index of desired element (zero-based).
+ /// \return Reference to element at specified index.
+ T &operator[](unsigned index) { assert(index < Count); return m_array[index]; }
};
-// ======================> finder_base
-
-// helper class to request auto-object discovery in the constructor of a derived class
+/// \brief Base class for object discovery helpers
+///
+/// Abstract non-template base class for object auto-discovery helpers.
+/// Provides the interface that the device_t uses to manage discovery at
+/// resolution time.
class finder_base
{
- friend class device_t;
-
public:
- // construction/destruction
- finder_base(device_t &base, const char *tag);
+ /// \brief Destructor
+ ///
+ /// Destruction via base class pointer and dynmaic type behaviour
+ /// are allowed.
virtual ~finder_base();
- // getters
+ /// \brief Get next registered object discovery helper
+ ///
+ /// Implementation of basic single-linked list behaviour.
+ /// \return Pointer to the next registerd object discovery helper,
+ /// or nullptr if this is the last.
+ finder_base *next() const { return m_next; }
+
+ /// \brief Attempt discovery
+ ///
+ /// Concrete derived classes must implement this member function.
+ /// Should return false if the the object is required but not found,
+ /// or true otherwise (the report_missing member function can assist
+ /// in implementing this behaviour).
+ /// \param [in] isvalidation Pass true if this is a dry run (i.e. no
+ /// intention to actually start the device), or false otherwise.
+ /// \return False if the object is required but not found, or true
+ /// otherwise.
virtual bool findit(bool isvalidation = false) = 0;
+
+ /// \brief Get search tag
+ ///
+ /// Returns the search tag.
+ /// \return The object tag this helper will search for.
const char *finder_tag() const { return m_tag; }
- // setter for setting the object
+ /// \brief Set search tag
+ ///
+ /// Allows search tag to be changed after construction. Note that
+ /// this must be done before resolution time to take effect. Also
+ /// note that the tag is not copied.
+ /// \param [in] tag Updated search tag. This is not copied, it is
+ /// the caller's responsibility to ensure this pointer remains
+ /// valid until resolution time.
void set_tag(const char *tag) { m_tag = tag; }
+ /// \brief Dummy tag always treated as not found
+ constexpr static char DUMMY_TAG[] = "finder_dummy_tag";
+
protected:
- // helpers
+ /// \brief Designated constructor
+ ///
+ /// Construct base object discovery helper and register with device
+ /// to be invoked at resolution time.
+ /// \param [in] base Base device to search from.
+ /// \param [in] tag Object tag to search for. This is not copied,
+ /// it is the caller's responsibility to ensure this pointer
+ /// remains valid until resolution time.
+ finder_base(device_t &base, const char *tag);
+
+ /// \brief Find a memory region
+ ///
+ /// Look up memory region and check that its length and width match
+ /// desired values. Returns pointer to the base of the region if a
+ /// matching region is found, or nullptr otherwise. Prints a
+ /// message at warning level if the region is required, a region
+ /// with the requested tag is found, but it doesn't match the
+ /// desired width and length.
+ /// \param [in] width Desired region width in bytes.
+ /// \param [in,out] length On entry, the desired region length in
+ /// width units, or 0U to match any region length. Set to the
+ /// length of the region in width units if a matching region is
+ /// found, or 0U otherwise.
+ /// \param [in] required Whether warning message should be printed
+ /// if a region with matching tag of incorrect width/length is
+ /// found.
+ /// \return Base pointer of the memeroy region if a matching region
+ /// is found, or nullptr otherwise.
void *find_memregion(UINT8 width, size_t &length, bool required) const;
+
+ /// \brief Check that memory region exists
+ ///
+ /// Walks ROM regions of all devices starting from the root looking
+ /// for one with matching tag and length in bytes. Prints a warning
+ /// message if the region is required, a region iwth the requested
+ /// tag is found, but its length does not match. Calls
+ /// report_missing to print an error message if the region is
+ /// not found. Returns true if the region is required but no
+ /// matching region is found, or false otherwise.
+ /// \param [in] bytes Desired region length in bytes, or 0U to match
+ /// any length.
+ /// \param [in] required True if the region is required, or false if
+ /// it is optional.
+ /// \return True if the region is optional, or if the region is
+ /// required and a matching region is found, or false otherwise.
bool validate_memregion(size_t bytes, bool required) const;
+
+ /// \brief Find a memory share
+ ///
+ /// Look up memory share and check that its width matches desired
+ /// value. Returns pointer to base of memory share if a matching
+ /// share is found, or nullptr otherwise. Prints a message at
+ /// warning level if the memory share is required, a memory share
+ /// with the requested tag is found, but it doesn't match the
+ /// desired width.
+ /// \param [in] width Desired memory share width in bits.
+ /// \param [out] bytes Set to memoyr share length in bytes if a
+ /// matching memory share is found, otherwise left unchanged.
+ /// \param [in] required. Whether warning message should be printed
+ /// if a memory share with matching tag of incorrect width is
+ /// found.
+ /// \return Pointer to base of memory share if a matching memory
+ /// share is found, or nullptr otherwise.
void *find_memshare(UINT8 width, size_t &bytes, bool required) const;
+
+ /// \brief Log if object was not found
+ ///
+ /// Logs a message at error level if the target object is required
+ /// and the search tag is the dummy tag, or the target object is
+ /// required and not found. Logs a message at verbose level if the
+ /// object is optional and not found. Returns true if the object is
+ /// found or not required, and false otherwise.
+ /// \param [in] found Whether the target object has been found.
+ /// \param [in] objname Display name for target object type.
+ /// \param [in] required True if the object is required (validation
+ /// error if not found), or false if optional.
+ /// \return True if found or not required, false otherwise.
bool report_missing(bool found, const char *objname, bool required) const;
+ /// \brief Print a message at warning level
+ ///
+ /// Prints a message if logging is enabled at warning level or more
+ /// detailed. Uses printf semantics of the C runtime library.
+ /// \param [in] format Format string as used by printf function in
+ /// runtime library
void printf_warning(const char *format, ...) ATTR_PRINTF(2,3);
- // internal state
- finder_base *m_next;
+
+ /// \brief Pointer to next registered discovery helper
+ ///
+ /// This is a polymorphic class, so it can't be held in a standardlist
+ /// container that requires elements of the same type. Hence it
+ /// implements basic single-linked list behaviour.
+ finder_base *const m_next;
device_t &m_base;
const char *m_tag;
};
-// ======================> object_finder_base
-
-// helper class to find objects of a particular type
-template<class _ObjectClass>
+/// \brief Base class for object discovery helpers
+///
+/// Abstract template base for auto-discovery of objects of a particular
+/// type. Provides implicit cast-to-pointer and pointer member access
+/// operators. Template arguments are the type of object to discover,
+/// and whether failure to find the object is considered an error.
+/// Assumes that non-null pointer is found, and null pointer is not
+/// found.
+template <class ObjectClass, bool Required>
class object_finder_base : public finder_base
{
public:
- // construction/destruction
- object_finder_base(device_t &base, const char *tag)
- : finder_base(base, tag),
- m_target(nullptr) { }
-
- // getters for explicit fetching
- _ObjectClass *target() const { return m_target; }
+ /// \brief Get pointer to target object
+ /// \return Pointer to target object if found, or nullptr otherwise.
+ ObjectClass *target() const { return m_target; }
+
+ /// \brief Return whether target has been found
+ ///
+ /// Works on the assumption that the target object pointer will be
+ /// non-null if the target has been found, and null otherwise.
+ /// \return True if object has been found, or false otherwise.
bool found() const { return m_target != nullptr; }
- // setter for setting the object
- void set_target(_ObjectClass *target) { m_target = target; }
+ /// \brief Cast-to-pointer operator
+ ///
+ /// Allows implicit casting to a pointer to the target object.
+ /// Returns a null pointer if resolution has not been attempted or
+ // object was not found.
+ /// \return Pointer to target object if found, or nullptr otherwise.
+ operator ObjectClass *() const { return m_target; }
+
+ /// \brief Pointer member access operator
+ ///
+ /// Allows pointer-member-style access to members of the target
+ /// object. Asserts that the target object has been found.
+ /// \return Pointer to target object if found, or nullptr otherwise.
+ virtual ObjectClass *operator->() const { assert(m_target); return m_target; }
protected:
- // internal state
- _ObjectClass *m_target;
+ /// \brief Designated constructor
+ ///
+ /// Construct base, register with base device to be invoked at
+ /// resolution time, and initialise target object pointer to
+ /// nullptr.
+ /// \param [in] base Base device to search from.
+ /// \param [in] tag Object tag to search for. This is not copied,
+ /// it is the caller's responsibility to ensure this pointer
+ /// remains valid until resolution time.
+ object_finder_base(device_t &base, const char *tag) : finder_base(base, tag), m_target(nullptr) { }
+
+ /// \brief Log if object was not found
+ ///
+ /// Logs a message if the target object was not found, and returns
+ /// false if this is problematic. Calls base implementation,
+ /// supplying values for found and required parameters. See base
+ /// implementation for more detail.
+ /// \param [in] objname Display name for target object type.
+ /// \return True if found or not required, false otherwise.
+ bool report_missing(char const *objname) const { return finder_base::report_missing(found(), objname, Required); }
+
+ /// \brief Pointer to target object
+ ///
+ /// Pointer to target object, or nullptr if resolution has not been
+ /// attempted or the seach failed. Concrete derived classes must
+ /// set this in their implementation of the findit member function.
+ ObjectClass *m_target;
};
-// ======================> device_finder
-
-// device finder template
-template<class _DeviceClass, bool _Required>
-class device_finder : public object_finder_base<_DeviceClass>
+/// \brief Device finder template
+///
+/// Template arguments are the device class to find, and whether the
+/// device is required. It is a validation error if a required device
+/// is not found. If a device with matching tag is found but the class
+/// does not match, a message is printed at warning level. This class
+/// is generally not used directly, instead the optional_device and
+/// required_device helpers are used.
+/// \sa optional_device required_device
+template <class DeviceClass, bool Required>
+class device_finder : public object_finder_base<DeviceClass, Required>
{
public:
// construction/destruction
- device_finder(device_t &base, const char *tag = FINDER_DUMMY_TAG)
- : object_finder_base<_DeviceClass>(base, tag) { }
-
- // operators to make pointer use transparent
- operator _DeviceClass *() const { return object_finder_base<_DeviceClass>::m_target; }
- virtual _DeviceClass *operator->() const { assert(object_finder_base<_DeviceClass>::m_target != nullptr); return object_finder_base<_DeviceClass>::m_target; }
+ device_finder(device_t &base, const char *tag = finder_base::DUMMY_TAG) : object_finder_base<DeviceClass, Required>(base, tag) { }
// make reference use transparent as well
- operator _DeviceClass &() { assert(object_finder_base<_DeviceClass>::m_target != nullptr); return *object_finder_base<_DeviceClass>::m_target; }
+ operator DeviceClass &() { assert(this->m_target); return *this->m_target; }
// finder
virtual bool findit(bool isvalidation = false) override
{
- device_t *device = this->m_base.subdevice(this->m_tag);
- this->m_target = dynamic_cast<_DeviceClass *>(device);
- if (device != nullptr && this->m_target == nullptr)
- {
+ device_t *const device = this->m_base.subdevice(this->m_tag);
+ this->m_target = dynamic_cast<DeviceClass *>(device);
+ if (device && !this->m_target)
this->printf_warning("Device '%s' found but is of incorrect type (actual type is %s)\n", this->m_tag, device->name());
- }
- return this->report_missing(this->m_target != nullptr, "device", _Required);
- }
-};
-
-// optional device finder
-template<class _DeviceClass>
-class optional_device : public device_finder<_DeviceClass, false>
-{
-public:
- optional_device(device_t &base, const char *tag = FINDER_DUMMY_TAG) : device_finder<_DeviceClass, false>(base, tag) { }
-};
-
-// required devices are similar but throw an error if they are not found
-template<class _DeviceClass>
-class required_device : public device_finder<_DeviceClass, true>
-{
-public:
- required_device(device_t &base, const char *tag = FINDER_DUMMY_TAG) : device_finder<_DeviceClass, true>(base, tag) { }
-};
-
-// ======================> device_array_finder
-
-// device array finder template
-template <class DeviceClass, unsigned Count, bool Required>
-class device_array_finder : public array_finder_base<device_finder<DeviceClass, Required>, Count>
-{
-public:
- template <typename F>
- device_array_finder(device_t &base, F const &fmt, unsigned start)
- : array_finder_base<device_finder<DeviceClass, Required>, Count>(base, fmt, start)
- {
- }
-
- device_array_finder(device_t &base, std::array<char const *, Count> const &tags)
- : array_finder_base<device_finder<DeviceClass, Required>, Count>(base, tags)
- {
+ return this->report_missing("device");
}
};
-// optional device array finder
-template <class DeviceClass, unsigned Count>
-class optional_device_array : public device_array_finder<DeviceClass, Count, false>
-{
-public:
- template <typename F> optional_device_array(device_t &base, F const &fmt, unsigned start) : device_array_finder<DeviceClass, Count, false>(base, fmt, start) { }
- optional_device_array(device_t &base, std::array<char const *, Count> const &tags) : device_array_finder<DeviceClass, Count, false>(base, tags) { }
-};
-
-// required device array finder
-template <class DeviceClass, unsigned Count>
-class required_device_array : public device_array_finder<DeviceClass, Count, true>
-{
-public:
- template <typename F> required_device_array(device_t &base, F const &fmt, unsigned start) : device_array_finder<DeviceClass, Count, true>(base, fmt, start) { }
- required_device_array(device_t &base, std::array<char const *, Count> const &tags) : device_array_finder<DeviceClass, Count, true>(base, tags) { }
-};
-
-
-// ======================> memory_region_finder
-
-// device finder template
-template<bool _Required>
-class memory_region_finder : public object_finder_base<memory_region>
+/// \brief Optional device finder
+///
+/// Finds device with maching type and tag. If a device with matching
+/// tag is found but the type does not match, a message is printed at
+/// warning level. No error is generated if a matching device is not
+/// found (the target object pointer will be null). If you have a
+/// number of similar optional devices, consider using
+/// optional_device_array.
+/// \sa required_device optional_device_array device_finder
+template <class DeviceClass> using optional_device = device_finder<DeviceClass, false>;
+
+/// \brief Required device finder
+///
+/// Finds device with maching type and tag. If a device with matching
+/// tag is found but the type does not match, a message is printed at
+/// warning level. A validation error is generated if a matching device
+/// is not found. If you have a number of similar required devices,
+/// consider using required_device_array.
+/// \sa optional_device required_device_array device_finder
+template <class DeviceClass> using required_device = device_finder<DeviceClass, true>;
+
+template <class DeviceClass, unsigned Count, bool Required> using device_array_finder = object_array_finder<device_finder<DeviceClass, Required>, Count>;
+template <class DeviceClass, unsigned Count> using optional_device_array = device_array_finder<DeviceClass, Count, false>;
+template <class DeviceClass, unsigned Count> using required_device_array = device_array_finder<DeviceClass, Count, true>;
+
+
+/// \brief Memory region finder template
+///
+/// Template argument is whether the memory region is required. It is a
+/// validation error if a required memory region is not found. This
+/// class is generally not used directly, instead the
+/// optional_memory_region and required_memory_region helpers are used.
+/// \sa optional_memory_region required_memory_region
+template <bool Required>
+class memory_region_finder : public object_finder_base<memory_region, Required>
{
public:
// construction/destruction
- memory_region_finder(device_t &base, const char *tag = FINDER_DUMMY_TAG)
- : object_finder_base<memory_region>(base, tag) { }
-
- // operators to make pointer use transparent
- operator memory_region *() const { return m_target; }
- virtual memory_region *operator->() const { assert(m_target != nullptr); return m_target; }
+ memory_region_finder(device_t &base, const char *tag = finder_base::DUMMY_TAG) : object_finder_base<memory_region, Required>(base, tag) { }
// make reference use transparent as well
- operator memory_region &() const { assert(object_finder_base<memory_region>::m_target != nullptr); return *object_finder_base<memory_region>::m_target; }
+ operator memory_region &() const { assert(this->m_target); return *this->m_target; }
// finder
virtual bool findit(bool isvalidation = false) override
{
- if (isvalidation) return this->validate_memregion(0, _Required);
- m_target = m_base.memregion(m_tag);
- return this->report_missing(m_target != nullptr, "memory region", _Required);
+ if (isvalidation) return this->validate_memregion(0, Required);
+ this->m_target = this->m_base.memregion(this->m_tag);
+ return this->report_missing("memory region");
}
};
-// optional device finder
-class optional_memory_region : public memory_region_finder<false>
-{
-public:
- optional_memory_region(device_t &base, const char *tag = FINDER_DUMMY_TAG) : memory_region_finder<false>(base, tag) { }
-};
-
-// required devices are similar but throw an error if they are not found
-class required_memory_region : public memory_region_finder<true>
-{
-public:
- required_memory_region(device_t &base, const char *tag = FINDER_DUMMY_TAG) : memory_region_finder<true>(base, tag) { }
-};
-
-
-// ======================> memory_bank_finder
-
-// device finder template
-template<bool _Required>
-class memory_bank_finder : public object_finder_base<memory_bank>
+/// \brief Optional memory region finder
+///
+/// Finds memory region with maching tag. No error is generated if a
+/// matching memory region is not found (the target object pointer will
+/// be null). If you have a number of similar optional memory regions,
+/// consider using optional_memory_region_array.
+/// \sa required_memory_region optional_memory_region_array
+/// memory_region_finder
+using optional_memory_region = memory_region_finder<false>;
+
+/// \brief Required memory region finder
+///
+/// Finds memory region with maching tag. A validation error is
+/// generated if a matching memory region is not found. If you have a
+/// number of similar required memory regions, consider using
+/// required_memory_region_array.
+/// \sa optional_memory_region required_memory_region_array
+/// memory_region_finder
+using required_memory_region = memory_region_finder<true>;
+
+template <unsigned Count, bool Required> using memory_region_array_finder = object_array_finder<memory_region_finder<Required>, Count>;
+template <unsigned Count> using optional_memory_region_array = memory_region_array_finder<Count, false>;
+template <unsigned Count> using required_memory_region_array = memory_region_array_finder<Count, true>;
+
+extern template class object_finder_base<memory_region, false>;
+extern template class object_finder_base<memory_region, true>;
+extern template class memory_region_finder<false>;
+extern template class memory_region_finder<true>;
+
+
+/// \brief Memory bank finder template
+///
+/// Template argument is whether the memory bank is required. It is a
+/// validation error if a required memory bank is not found. This class
+/// is generally not used directly, instead the optional_memory_bank and
+/// required_memory_bank helpers are used.
+/// \sa optional_memory_bank required_memory_bank
+template <bool Required>
+class memory_bank_finder : public object_finder_base<memory_bank, Required>
{
public:
// construction/destruction
- memory_bank_finder(device_t &base, const char *tag = FINDER_DUMMY_TAG)
- : object_finder_base<memory_bank>(base, tag) { }
-
- // operators to make pointer use transparent
- operator memory_bank *() const { return m_target; }
- virtual memory_bank *operator->() const { assert(m_target != nullptr); return m_target; }
+ memory_bank_finder(device_t &base, const char *tag = finder_base::DUMMY_TAG) : object_finder_base<memory_bank, Required>(base, tag) { }
// make reference use transparent as well
- operator memory_bank &() const { assert(object_finder_base<memory_bank>::m_target != nullptr); return *object_finder_base<memory_bank>::m_target; }
+ operator memory_bank &() const { assert(this->m_target); return *this->m_target; }
// finder
virtual bool findit(bool isvalidation = false) override
{
if (isvalidation) return true;
- m_target = m_base.membank(m_tag);
- return this->report_missing(m_target != nullptr, "memory bank", _Required);
+ this->m_target = this->m_base.membank(this->m_tag);
+ return this->report_missing("memory bank");
}
};
-// optional device finder
-class optional_memory_bank : public memory_bank_finder<false>
-{
-public:
- optional_memory_bank(device_t &base, const char *tag = FINDER_DUMMY_TAG) : memory_bank_finder<false>(base, tag) { }
-};
-
-// required devices are similar but throw an error if they are not found
-class required_memory_bank : public memory_bank_finder<true>
-{
-public:
- required_memory_bank(device_t &base, const char *tag = FINDER_DUMMY_TAG) : memory_bank_finder<true>(base, tag) { }
-};
+/// \brief Optional memory bank finder
+///
+/// Finds memory bank with maching tag. No error is generated if a
+/// matching memory bank is not found (the target object pointer will
+/// be null). If you have a number of similar optional memory banks,
+/// consider using optional_memory_bank_array.
+/// \sa required_memory_bank optional_memory_bank_array
+/// memory_bank_finder
+using optional_memory_bank = memory_bank_finder<false>;
+
+/// \brief Required memory bank finder
+///
+/// Finds memory bank with maching tag. A validation error is
+/// generated if a matching memory bank is not found. If you have a
+/// number of similar required memory banks, consider using
+/// required_memory_bank_array.
+/// \sa optional_memory_bank required_memory_bank_array
+/// memory_bank_finder
+using required_memory_bank = memory_bank_finder<true>;
+
+template <unsigned Count, bool Required> using memory_bank_array_finder = object_array_finder<memory_bank_finder<Required>, Count>;
+template <unsigned Count> using optional_memory_bank_array = memory_bank_array_finder<Count, false>;
+template <unsigned Count> using required_memory_bank_array = memory_bank_array_finder<Count, true>;
+
+extern template class object_finder_base<memory_bank, false>;
+extern template class object_finder_base<memory_bank, true>;
+extern template class memory_bank_finder<false>;
+extern template class memory_bank_finder<true>;
// ======================> ioport_finder
// ioport finder template
-template<bool _Required>
-class ioport_finder : public object_finder_base<ioport_port>
+template <bool Required>
+class ioport_finder : public object_finder_base<ioport_port, Required>
{
public:
// construction/destruction
- ioport_finder(device_t &base, const char *tag = FINDER_DUMMY_TAG)
- : object_finder_base<ioport_port>(base, tag) { }
-
- // operators to make use transparent
- ioport_port &operator*() const { assert(m_target != nullptr); return *m_target; }
- virtual ioport_port *operator->() const { assert(m_target != nullptr); return m_target; }
+ ioport_finder(device_t &base, const char *tag = finder_base::DUMMY_TAG) : object_finder_base<ioport_port, Required>(base, tag) { }
// read if found, or else return a default value
- ioport_value read_safe(ioport_value defval) { return m_target != nullptr ? m_target->read() : defval; }
+ ioport_value read_safe(ioport_value defval) { return this->m_target ? this->m_target->read() : defval; }
// finder
virtual bool findit(bool isvalidation = false) override
{
if (isvalidation) return true;
- m_target = m_base.ioport(m_tag);
- return this->report_missing(m_target != nullptr, "I/O port", _Required);
+ this->m_target = this->m_base.ioport(this->m_tag);
+ return this->report_missing("I/O port");
}
};
-// optional ioport finder
-class optional_ioport : public ioport_finder<false>
-{
-public:
- optional_ioport(device_t &base, const char *tag = FINDER_DUMMY_TAG) : ioport_finder<false>(base, tag) { }
-};
+using optional_ioport = ioport_finder<false>;
+using required_ioport = ioport_finder<true>;
+template <unsigned Count, bool Required> using ioport_array_finder = object_array_finder<ioport_finder<Required>, Count>;
+template <unsigned Count> using optional_ioport_array = ioport_array_finder<Count, false>;
+template <unsigned Count> using required_ioport_array = ioport_array_finder<Count, true>;
-// required ioports are similar but throw an error if they are not found
-class required_ioport : public ioport_finder<true>
-{
-public:
- required_ioport(device_t &base, const char *tag = FINDER_DUMMY_TAG) : ioport_finder<true>(base, tag) { }
-};
-
-// ======================> ioport_array_finder
-
-// ioport array finder template
-template <unsigned Count, bool Required>
-class ioport_array_finder : public array_finder_base<ioport_finder<Required>, Count>
-{
-public:
- template <typename F>
- ioport_array_finder(device_t &base, F const &fmt, unsigned start)
- : array_finder_base<ioport_finder<Required>, Count>(base, fmt, start)
- {
- }
-
- ioport_array_finder(device_t &base, std::array<char const *, Count> const &tags)
- : array_finder_base<ioport_finder<Required>, Count>(base, tags)
- {
- }
-};
-
-// optional ioport array finder
-template <unsigned Count>
-class optional_ioport_array: public ioport_array_finder<Count, false>
-{
-public:
- template <typename F> optional_ioport_array(device_t &base, F const &fmt, unsigned start) : ioport_array_finder<Count, false>(base, fmt, start) { }
- optional_ioport_array(device_t &base, std::array<char const *, Count> const &tags) : ioport_array_finder<Count, false>(base, tags) { }
-};
-
-// required ioport array finder
-template <unsigned Count>
-class required_ioport_array: public ioport_array_finder<Count, true>
-{
-public:
- template <typename F> required_ioport_array(device_t &base, F const &fmt, unsigned start) : ioport_array_finder<Count, true>(base, fmt, start) { }
- required_ioport_array(device_t &base, std::array<char const *, Count> const &tags) : ioport_array_finder<Count, true>(base, tags) { }
-};
+extern template class object_finder_base<ioport_port, false>;
+extern template class object_finder_base<ioport_port, true>;
+extern template class ioport_finder<false>;
+extern template class ioport_finder<true>;
// ======================> region_ptr_finder
// memory region pointer finder template
-template<typename _PointerType, bool _Required>
-class region_ptr_finder : public object_finder_base<_PointerType>
+template <typename PointerType, bool Required>
+class region_ptr_finder : public object_finder_base<PointerType, Required>
{
public:
// construction/destruction
region_ptr_finder(device_t &base, const char *tag, size_t length = 0)
- : object_finder_base<_PointerType>(base, tag),
- m_length(length) { }
+ : object_finder_base<PointerType, Required>(base, tag)
+ , m_length(length)
+ {
+ }
region_ptr_finder(device_t &base, size_t length = 0)
- : object_finder_base<_PointerType>(base, FINDER_DUMMY_TAG),
- m_length(length) { }
+ : object_finder_base<PointerType, Required>(base, finder_base::DUMMY_TAG)
+ , m_length(length)
+ {
+ }
// operators to make use transparent
- operator _PointerType *() const { return this->m_target; }
- const _PointerType &operator[](int index) const { assert(index < m_length); return this->m_target[index]; }
- _PointerType &operator[](int index) { assert(index < m_length); return this->m_target[index]; }
-
- // setter for setting the object and its length
- void set_target(_PointerType *target, size_t length) { this->m_target = target; m_length = length; }
+ const PointerType &operator[](int index) const { assert(index < m_length); return this->m_target[index]; }
+ PointerType &operator[](int index) { assert(index < m_length); return this->m_target[index]; }
// getter for explicit fetching
UINT32 length() const { return m_length; }
- UINT32 bytes() const { return m_length * sizeof(_PointerType); }
+ UINT32 bytes() const { return m_length * sizeof(PointerType); }
UINT32 mask() const { return m_length - 1; } // only valid if length is known to be a power of 2
// finder
virtual bool findit(bool isvalidation = false) override
{
- if (isvalidation) return this->validate_memregion(sizeof(_PointerType) * m_length, _Required);
- this->m_target = reinterpret_cast<_PointerType *>(this->find_memregion(sizeof(_PointerType), m_length, _Required));
- return this->report_missing(this->m_target != nullptr, "memory region", _Required);
+ if (isvalidation) return this->validate_memregion(sizeof(PointerType) * m_length, Required);
+ this->m_target = reinterpret_cast<PointerType *>(this->find_memregion(sizeof(PointerType), m_length, Required));
+ return this->report_missing("memory region");
}
protected:
@@ -411,50 +569,38 @@ protected:
size_t m_length;
};
-// optional region pointer finder
-template<class _PointerType>
-class optional_region_ptr : public region_ptr_finder<_PointerType, false>
-{
-public:
- optional_region_ptr(device_t &base, const char *tag, size_t length = 0) : region_ptr_finder<_PointerType, false>(base, tag, length) { }
- optional_region_ptr(device_t &base, size_t length = 0) : region_ptr_finder<_PointerType, false>(base, FINDER_DUMMY_TAG, length) { }
-};
-
-// required region pointer finder
-template<class _PointerType>
-class required_region_ptr : public region_ptr_finder<_PointerType, true>
-{
-public:
- required_region_ptr(device_t &base, const char *tag, size_t length = 0) : region_ptr_finder<_PointerType, true>(base, tag, length) { }
- required_region_ptr(device_t &base, size_t length = 0) : region_ptr_finder<_PointerType, true>(base, FINDER_DUMMY_TAG, length) { }
-};
-
+template <typename PointerType> using optional_region_ptr = region_ptr_finder<PointerType, false>;
+template <typename PointerType> using required_region_ptr = region_ptr_finder<PointerType, true>;
+template <typename PointerType, unsigned Count, bool Required> using region_ptr_array_finder = object_array_finder<region_ptr_finder<PointerType, Required>, Count>;
+template <typename PointerType, unsigned Count> using optional_region_ptr_array = region_ptr_array_finder<PointerType, Count, false>;
+template <typename PointerType, unsigned Count> using required_region_ptr_array = region_ptr_array_finder<PointerType, Count, true>;
// ======================> shared_ptr_finder
// shared pointer finder template
-template<typename _PointerType, bool _Required>
-class shared_ptr_finder : public object_finder_base<_PointerType>
+template <typename PointerType, bool Required>
+class shared_ptr_finder : public object_finder_base<PointerType, Required>
{
public:
// construction/destruction
- shared_ptr_finder(device_t &base, const char *tag = FINDER_DUMMY_TAG, UINT8 width = sizeof(_PointerType) * 8)
- : object_finder_base<_PointerType>(base, tag),
- m_bytes(0),
- m_width(width) { }
+ shared_ptr_finder(device_t &base, const char *tag = finder_base::DUMMY_TAG, UINT8 width = sizeof(PointerType) * 8)
+ : object_finder_base<PointerType, Required>(base, tag)
+ , m_bytes(0)
+ , m_width(width)
+ {
+ }
// operators to make use transparent
- operator _PointerType *() const { return this->m_target; }
- const _PointerType &operator[](int index) const { return this->m_target[index]; }
- _PointerType &operator[](int index) { return this->m_target[index]; }
+ const PointerType &operator[](int index) const { return this->m_target[index]; }
+ PointerType &operator[](int index) { return this->m_target[index]; }
// getter for explicit fetching
UINT32 bytes() const { return m_bytes; }
- UINT32 mask() const { return m_bytes - 1; } // FIXME: wrong when sizeof(_PointerType) != 1
+ UINT32 mask() const { return m_bytes - 1; } // FIXME: wrong when sizeof(PointerType) != 1
// setter for setting the object
- void set_target(_PointerType *target, size_t bytes) { this->m_target = target; m_bytes = bytes; }
+ void set_target(PointerType *target, size_t bytes) { this->m_target = target; m_bytes = bytes; }
// dynamic allocation of a shared pointer
void allocate(UINT32 entries)
@@ -462,7 +608,7 @@ public:
assert(m_allocated.empty());
m_allocated.resize(entries);
this->m_target = &m_allocated[0];
- m_bytes = entries * sizeof(_PointerType);
+ m_bytes = entries * sizeof(PointerType);
this->m_base.save_item(this->m_allocated, this->m_tag);
}
@@ -470,70 +616,22 @@ public:
virtual bool findit(bool isvalidation = false) override
{
if (isvalidation) return true;
- this->m_target = reinterpret_cast<_PointerType *>(this->find_memshare(m_width, m_bytes, _Required));
- return this->report_missing(this->m_target != nullptr, "shared pointer", _Required);
+ this->m_target = reinterpret_cast<PointerType *>(this->find_memshare(m_width, m_bytes, Required));
+ return this->report_missing("shared pointer");
}
protected:
// internal state
size_t m_bytes;
UINT8 m_width;
- std::vector<_PointerType> m_allocated;
-};
-
-// optional shared pointer finder
-template<class _PointerType>
-class optional_shared_ptr : public shared_ptr_finder<_PointerType, false>
-{
-public:
- optional_shared_ptr(device_t &base, const char *tag = FINDER_DUMMY_TAG, UINT8 width = sizeof(_PointerType) * 8) : shared_ptr_finder<_PointerType, false>(base, tag, width) { }
-};
-
-// required shared pointer finder
-template<class _PointerType>
-class required_shared_ptr : public shared_ptr_finder<_PointerType, true>
-{
-public:
- required_shared_ptr(device_t &base, const char *tag = FINDER_DUMMY_TAG, UINT8 width = sizeof(_PointerType) * 8) : shared_ptr_finder<_PointerType, true>(base, tag, width) { }
-};
-
-
-// ======================> shared_ptr_array_finder
-
-// shared pointer array finder template
-template <typename PointerType, unsigned Count, bool Required>
-class shared_ptr_array_finder : public array_finder_base<shared_ptr_finder<PointerType, Required>, Count>
-{
-public:
- template <typename F>
- shared_ptr_array_finder(device_t &base, F const &fmt, unsigned start)
- : array_finder_base<shared_ptr_finder<PointerType, Required>, Count>(base, fmt, start)
- {
- }
-
- shared_ptr_array_finder(device_t &base, std::array<char const *, Count> const &tags)
- : array_finder_base<shared_ptr_finder<PointerType, Required>, Count>(base, tags)
- {
- }
-};
-
-// optional shared pointer array finder
-template <typename PointerType, unsigned Count>
-class optional_shared_ptr_array : public shared_ptr_array_finder<PointerType, Count, false>
-{
-public:
- template <typename F> optional_shared_ptr_array(device_t &base, F const &fmt, unsigned start) : shared_ptr_array_finder<PointerType, Count, false>(base, fmt, start) { }
- optional_shared_ptr_array(device_t &base, std::array<char const *, Count> const &tags) : shared_ptr_array_finder<PointerType, Count, false>(base, tags) { }
-};
-
-// required shared pointer array finder
-template <typename PointerType, unsigned Count>
-class required_shared_ptr_array : public shared_ptr_array_finder<PointerType, Count, true>
-{
-public:
- template <typename F> required_shared_ptr_array(device_t &base, F const &fmt, unsigned start) : shared_ptr_array_finder<PointerType, Count, true>(base, fmt, start) { }
- required_shared_ptr_array(device_t &base, std::array<char const *, Count> const &tags) : shared_ptr_array_finder<PointerType, Count, true>(base, tags) { }
+ std::vector<PointerType> m_allocated;
};
+template <typename PointerType> using optional_shared_ptr = shared_ptr_finder<PointerType, false>;
+template <typename PointerType> using required_shared_ptr = shared_ptr_finder<PointerType, true>;
+template <typename PointerType, unsigned Count, bool Required> using shared_ptr_array_finder = object_array_finder<shared_ptr_finder<PointerType, Required>, Count>;
+template <typename PointerType, unsigned Count> using optional_shared_ptr_array = shared_ptr_array_finder<PointerType, Count, false>;
+template <typename PointerType, unsigned Count> using required_shared_ptr_array = shared_ptr_array_finder<PointerType, Count, true>;
-#endif /* MAME_EMU_DEVFIND_H */
+#endif // MAME_EMU_DEVFIND_H
+/** \} */
diff --git a/src/emu/device.cpp b/src/emu/device.cpp
index 1480f30a6f1..7ad9d740a2c 100644
--- a/src/emu/device.cpp
+++ b/src/emu/device.cpp
@@ -330,7 +330,7 @@ void device_t::set_machine(running_machine &machine)
bool device_t::findit(bool isvalidation) const
{
bool allfound = true;
- for (finder_base *autodev = m_auto_finder_list; autodev != nullptr; autodev = autodev->m_next)
+ for (finder_base *autodev = m_auto_finder_list; autodev != nullptr; autodev = autodev->next())
{
if (isvalidation)
{
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 4c0d9081a48..bfdc8367e72 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -505,7 +505,7 @@ typedef device_type_iterator<&device_creator<screen_device>, screen_device> scre
#define MCFG_SCREEN_PALETTE(_palette_tag) \
screen_device::static_set_palette(*device, "^" _palette_tag);
#define MCFG_SCREEN_NO_PALETTE \
- screen_device::static_set_palette(*device, FINDER_DUMMY_TAG);
+ screen_device::static_set_palette(*device, finder_base::DUMMY_TAG);
#define MCFG_SCREEN_VIDEO_ATTRIBUTES(_flags) \
screen_device::static_set_video_attributes(*device, _flags);
#define MCFG_SCREEN_COLOR(_color) \
diff --git a/src/mame/machine/fd1094.cpp b/src/mame/machine/fd1094.cpp
index 4a37174d306..aed3905fcf5 100644
--- a/src/mame/machine/fd1094.cpp
+++ b/src/mame/machine/fd1094.cpp
@@ -553,13 +553,14 @@ UINT16 *fd1094_decryption_cache::decrypted_opcodes(UINT8 state)
fd1094_device::fd1094_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : m68000_device(mconfig, tag, owner, clock, "fd1094", __FILE__),
- m_decrypted_opcodes_bank(*this, "^fd1094_decrypted_opcodes"),
- m_state(0x00),
- m_irqmode(false),
- m_cache(*this),
- m_srcbase(*this, DEVICE_SELF),
- m_key(*this, "key")
+ : m68000_device(mconfig, tag, owner, clock, "fd1094", __FILE__)
+ , m_decrypted_opcodes_bank(*this, "^fd1094_decrypted_opcodes")
+ , m_state(0x00)
+ , m_irqmode(false)
+ , m_cache(*this)
+ , m_srcbase(nullptr)
+ , m_rom(*this, DEVICE_SELF)
+ , m_key(*this, "key")
{
// override the name after the m68000 initializes
m_name.assign("FD1094");
@@ -633,18 +634,22 @@ void fd1094_device::change_state(int newstate)
void fd1094_device::device_start()
{
+ m_srcbase = m_rom;
+ UINT32 size = m_rom.bytes();
+
// if no ROM region, see if there's a memory share with our name
- if (!m_srcbase.found())
+ if (!m_rom.found())
{
- memory_share *share = memshare(DEVICE_SELF);
- if (share != nullptr)
- m_srcbase.set_target(reinterpret_cast<UINT16 *>(share->ptr()), share->bytes() / 2);
- else
+ memory_share *const share = memshare(DEVICE_SELF);
+ if (!share)
throw emu_fatalerror("FD1094 found no data to decrypt!");
+
+ m_srcbase = reinterpret_cast<UINT16 *>(share->ptr());
+ size = share->bytes();
}
// determine length and configure our cache
- m_cache.configure(0x000000, m_srcbase.bytes(), 0x000000);
+ m_cache.configure(0x000000, size, 0x000000);
change_state(STATE_RESET);
// start the base device
diff --git a/src/mame/machine/fd1094.h b/src/mame/machine/fd1094.h
index a72fc6f5df1..5981f0640a0 100644
--- a/src/mame/machine/fd1094.h
+++ b/src/mame/machine/fd1094.h
@@ -56,7 +56,7 @@ protected:
UINT32 m_baseaddress;
UINT32 m_size;
UINT32 m_rgnoffset;
- std::vector<UINT16> m_decrypted_opcodes[256];
+ std::vector<UINT16> m_decrypted_opcodes[256];
};
@@ -110,7 +110,8 @@ protected:
bool m_irqmode;
state_change_delegate m_state_change;
fd1094_decryption_cache m_cache;
- optional_region_ptr<UINT16> m_srcbase;
+ UINT16 const *m_srcbase;
+ optional_region_ptr<UINT16> m_rom;
required_region_ptr<UINT8> m_key;
UINT8 m_masked_opcodes_lookup[2][65536/8/2];