Devices can be found array-style, too

This commit is contained in:
Vas Crabb 2016-08-25 04:02:08 +10:00
parent f1eb915470
commit 0d08c04009
2 changed files with 81 additions and 52 deletions

View File

@ -23,6 +23,44 @@
// TYPE DEFINITIONS
//**************************************************************************
// ======================> array_finder_base
template <typename T, unsigned Count>
class array_finder_base
{
private:
template <unsigned... V> struct indices { };
template <unsigned C, unsigned... V> struct range : public range<C - 1, C - 1, V...> { };
template <unsigned... V> struct range<0U, V...> { typedef indices<V...> type; };
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...>)
: 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...>)
: 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];
T m_array[Count];
public:
const T &operator[](unsigned index) const { assert(index < Count); return m_array[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
@ -131,6 +169,44 @@ public:
};
// ======================> 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)
{
}
};
// 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
@ -217,7 +293,7 @@ public:
// ======================> ioport_finder
// device finder template
// ioport finder template
template<bool _Required>
class ioport_finder : public object_finder_base<ioport_port>
{
@ -242,59 +318,20 @@ public:
}
};
// optional device finder
// 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) { }
};
// required devices are similar but throw an error if they are not found
// 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) { }
};
// ======================> array_finder_base
template <typename T, unsigned Count>
class array_finder_base
{
private:
template <unsigned... V> struct indices { };
template <unsigned C, unsigned... V> struct range : public range<C - 1, C - 1, V...> { };
template <unsigned... V> struct range<0U, V...> { typedef indices<V...> type; };
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...>)
: 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...>)
: 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];
T m_array[Count];
public:
const T &operator[](unsigned index) const { assert(index < Count); return m_array[index]; }
T &operator[](unsigned index) { assert(index < Count); return m_array[index]; }
};
// ======================> ioport_array_finder
// ioport array finder template

View File

@ -385,15 +385,7 @@ public:
, m_floppy_1(*this, "wd1791:1")
, m_floppy(nullptr)
, m_wd1791(*this, "wd1791")
, m_channels{
{ *this, "cmi01a_0" },
{ *this, "cmi01a_1" },
{ *this, "cmi01a_2" },
{ *this, "cmi01a_3" },
{ *this, "cmi01a_4" },
{ *this, "cmi01a_5" },
{ *this, "cmi01a_6" },
{ *this, "cmi01a_7" } }
, m_channels(*this, "cmi01a_%u", 0)
, m_cmi10_pia_u20(*this, "cmi10_pia_u20")
, m_cmi10_pia_u21(*this, "cmi10_pia_u21")
, m_dp1(*this, "dp1")
@ -555,7 +547,7 @@ protected:
floppy_image_device *m_floppy;
required_device<fd1791_t> m_wd1791;
required_device<cmi01a_device> m_channels[8];
required_device_array<cmi01a_device, 8> m_channels;
required_device<pia6821_device> m_cmi10_pia_u20;
required_device<pia6821_device> m_cmi10_pia_u21;