diff options
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 |
commit | 1c98b515c5a10728d3d679ac7215440e55158f38 (patch) | |
tree | 0083c3d073488fa7d40e14c7fb4624bb19bff41a | |
parent | cf8060d762ffddd8dbb923e5db9d2e6f7eed49e0 (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.cpp | 11 | ||||
-rw-r--r-- | src/devices/machine/rp5h01.h | 7 | ||||
-rw-r--r-- | src/devices/video/hd44780.cpp | 15 | ||||
-rw-r--r-- | src/devices/video/hd44780.h | 3 | ||||
-rw-r--r-- | src/emu/devfind.cpp | 54 | ||||
-rw-r--r-- | src/emu/devfind.h | 782 | ||||
-rw-r--r-- | src/emu/device.cpp | 2 | ||||
-rw-r--r-- | src/emu/screen.h | 2 | ||||
-rw-r--r-- | src/mame/machine/fd1094.cpp | 31 | ||||
-rw-r--r-- | src/mame/machine/fd1094.h | 5 |
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]; |