diff options
Diffstat (limited to 'src/emu/dislot.h')
-rw-r--r-- | src/emu/dislot.h | 162 |
1 files changed, 134 insertions, 28 deletions
diff --git a/src/emu/dislot.h b/src/emu/dislot.h index da6a1b0aa3d..f6e1f86fcb3 100644 --- a/src/emu/dislot.h +++ b/src/emu/dislot.h @@ -9,13 +9,10 @@ #ifndef MAME_EMU_DISLOT_H #define MAME_EMU_DISLOT_H - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// ======================> get_default_card_software_hook - class get_default_card_software_hook { // goofy "hook" to pass to device_slot_interface::get_default_card_software @@ -27,7 +24,7 @@ public: util::core_file::ptr &image_file() { return m_image_file; } // checks to see if image is of the specified "file type" (in practice, file extension) - bool is_filetype(const char *candidate_filetype) const { return !core_stricmp(m_file_type.c_str(), candidate_filetype); } + bool is_filetype(std::string_view candidate_filetype) const; // extra info from hashfile bool hashfile_extrainfo(std::string &extrainfo); @@ -42,18 +39,17 @@ private: }; -// ======================> device_slot_interface - +/// \brief Base class for configurable slot devices class device_slot_interface : public device_interface { public: class slot_option { public: - slot_option(char const *name, device_type const &devtype, bool selectable); + slot_option(char const *name, device_type devtype, bool selectable); char const *name() const { return m_name; } - device_type const &devtype() const { return m_devtype; } + device_type devtype() const { return m_devtype; } bool selectable() const { return m_selectable; } char const *default_bios() const { return m_default_bios; } std::function<void (device_t *)> const &machine_config() const { return m_machine_config; } @@ -77,20 +73,92 @@ public: u32 m_clock; }; - // construction/destruction - device_slot_interface(const machine_config &mconfig, device_t &device); virtual ~device_slot_interface(); - void set_fixed(bool fixed) { m_fixed = fixed; } - void set_default_option(const char *option) { m_default_option = option; } - void option_reset() { m_options.clear(); } - slot_option &option_add(const char *option, const device_type &devtype); - slot_option &option_add_internal(const char *option, const device_type &devtype); + /// \brief Set whether slot is fixed + /// + /// Allows a slot to be configured as fixed. Fixed slots can only + /// be configured programmatically. Options for fixed slots are not + /// user-selectable. By default, slots are not fixed. + /// \param [in] fixed True to mark the slot as fixed, or false to + /// mark it user-configurable. + /// \sa fixed + device_slot_interface &set_fixed(bool fixed) { m_fixed = fixed; return *this; } + + /// \brief Set the default option + /// + /// Set the default option the slot. The corresponding card device + /// will be loaded if no other option is selected by the user or + /// programmatically. + /// \param [in] option The name of the default option. This must be + /// correspond to an option added using #option_add or + /// #option_add_internal, or be nullptr to not load any card + /// device by default. The string is not copied and must remain + /// valid for the lifetime of the device (or until another default + /// option is configured). + /// \sa default_option + device_slot_interface &set_default_option(const char *option) { m_default_option = option; return *this; } + + /// \brief Clear options + /// + /// This removes all previously added options. + device_slot_interface &option_reset() { m_options.clear(); return *this; } + + /// \brief Add a user-selectable option + /// + /// Adds an option that may be selected by the user via the command + /// line or other configureation methods. + /// \param [in] option The name used to select the option. This + /// will also be used as the tag when instantiating the card. It + /// must be a valid device tag, and should be terse but + /// descriptive. The string is copied when the option is added. + /// \param [in] devtype Device type of the option. The device type + /// description is used in the user interface. + /// \return A reference to the added option for additional + /// configuration. + slot_option &option_add(char const *option, device_type devtype); + + /// \brief Add an internal option + /// + /// Adds an option that may only be selected programmatically. This + /// is most often used for options used for loading software. + /// \param [in] option The name used to select the option. This + /// will also be used as the tag when instantiating the card. It + /// must be a valid device tag. The string is copied when the + /// option is added. + /// \param [in] devtype Device type of the option. The device type + /// description is used in the user interface. + /// \return A reference to the added option for additional + /// configuration. + slot_option &option_add_internal(const char *option, device_type devtype); + + slot_option &option_replace(const char *option, device_type devtype); + slot_option &option_replace_internal(const char *option, device_type devtype); + void option_remove(const char *option); + void set_option_default_bios(const char *option, const char *default_bios) { config_option(option)->default_bios(default_bios); } template <typename T> void set_option_machine_config(const char *option, T &&machine_config) { config_option(option)->machine_config(std::forward<T>(machine_config)); } void set_option_device_input_defaults(const char *option, const input_device_default *default_input) { config_option(option)->input_device_defaults(default_input); } + + /// \brief Returns whether the slot is fixed + /// + /// Fixed slots can only be configured programmatically. Slots are + /// not fixed by default. + /// \return True if the slot is fixed, or false if it is + /// user-configurable. + /// \sa set_fixed bool fixed() const { return m_fixed; } + + /// \brief Returns true if the slot has user-selectable options + /// + /// Returns true if the slot is not marked as fixed and has at least + /// one user-selectable option (added using #option_add rather than + /// #option_add_internal). Returns false if the slot is marked as + /// fixed, all options are internal, or there are no options. + /// \return True if the slot has user-selectable options, or false + /// otherwise. bool has_selectable_options() const; + const char *default_option() const { return m_default_option; } const std::unordered_map<std::string, std::unique_ptr<slot_option>> &option_list() const { return m_options; } const slot_option *option(const char *name) const; @@ -98,33 +166,71 @@ public: device_t *get_card_device() const { return m_card_device; } void set_card_device(device_t *dev) { m_card_device = dev; } const char *slot_name() const { return device().tag() + 1; } - slot_option &option_set(const char *tag, const device_type &devtype) { m_default_option = tag; m_fixed = true; return option_add_internal(tag, devtype); } + slot_option &option_set(const char *tag, device_type devtype) { m_default_option = tag; m_fixed = true; return option_add_internal(tag, devtype); } protected: + device_slot_interface(machine_config const &mconfig, device_t &device); + virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD; void set_default_clock(u32 clock) { m_default_clock = clock; } private: // internal state - std::unordered_map<std::string,std::unique_ptr<slot_option>> m_options; + std::unordered_map<std::string, std::unique_ptr<slot_option>> m_options; u32 m_default_clock; - const char *m_default_option; + char const *m_default_option; bool m_fixed; device_t *m_card_device; - slot_option *config_option(const char *option); + slot_option *config_option(char const *option); }; -// iterator -typedef device_interface_iterator<device_slot_interface> slot_interface_iterator; - -// ======================> device_slot_card_interface -class device_slot_card_interface : public device_interface +/// \brief Base class for slots that accept a single card interface +/// +/// Performs basic validity checks to ensure the configured card (if +/// any) implements the required interface. +template <typename Card> +class device_single_card_slot_interface : public device_slot_interface { public: - // construction/destruction - device_slot_card_interface(const machine_config &mconfig, device_t &device); - virtual ~device_slot_card_interface(); + Card *get_card_device() const { return dynamic_cast<Card *>(device_slot_interface::get_card_device()); } + +protected: + device_single_card_slot_interface(machine_config const &mconfig, device_t &device) : + device_slot_interface(mconfig, device) + { + } + + virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD + { + device_slot_interface::interface_validity_check(valid); + device_t *const card(device_slot_interface::get_card_device()); + if (card && !dynamic_cast<Card *>(card)) + { + osd_printf_error( + "Card device %s (%s) does not implement %s\n", + card->tag(), + card->name(), + typeid(Card).name()); + } + } + + virtual void interface_pre_start() override ATTR_COLD + { + device_slot_interface::interface_pre_start(); + device_t *const card(device_slot_interface::get_card_device()); + if (card && !dynamic_cast<Card *>(card)) + { + throw emu_fatalerror( + "slot '%s' card device %s (%s) does not implement %s\n", + device().tag(), + card->tag(), + card->name(), + typeid(Card).name()); + } + } }; -#endif /* MAME_EMU_DISLOT_H */ +typedef device_interface_enumerator<device_slot_interface> slot_interface_enumerator; + +#endif // MAME_EMU_DISLOT_H |