// license:BSD-3-Clause // copyright-holders:R. Belmont /*************************************************************************** a1bus.h - Apple I expansion slot and card emulation ***************************************************************************/ #ifndef MAME_BUS_A1BUS_A1BUS_H #define MAME_BUS_A1BUS_A1BUS_H #pragma once //************************************************************************** // TYPE DEFINITIONS //************************************************************************** class a1bus_device; class device_a1bus_card_interface; class a1bus_slot_device : public device_t, public device_single_card_slot_interface { public: // construction/destruction template a1bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&a1bus_tag, U &&opts, const char *dflt) : a1bus_slot_device(mconfig, tag, owner, clock) { option_reset(); opts(*this); set_default_option(dflt); set_fixed(false); m_a1bus.set_tag(std::forward(a1bus_tag)); } a1bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: a1bus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; // configuration required_device m_a1bus; }; // device type definition DECLARE_DEVICE_TYPE(A1BUS_SLOT, a1bus_slot_device) // ======================> a1bus_device class a1bus_device : public device_t { public: // construction/destruction a1bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // inline configuration template void set_space(T &&tag, int spacenum) { m_space.set_tag(std::forward(tag), spacenum); } auto out_irq_callback() { return m_out_irq_cb.bind(); } auto out_nmi_callback() { return m_out_nmi_cb.bind(); } void add_a1bus_card(device_a1bus_card_interface *card); device_a1bus_card_interface *get_a1bus_card(); void set_irq_line(int state); void set_nmi_line(int state); void install_device(offs_t start, offs_t end, read8sm_delegate rhandler, write8sm_delegate whandler); void install_bank(offs_t start, offs_t end, const char *tag, uint8_t *data); DECLARE_WRITE_LINE_MEMBER( irq_w ); DECLARE_WRITE_LINE_MEMBER( nmi_w ); protected: a1bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; // internal state required_address_space m_space; devcb_write_line m_out_irq_cb; devcb_write_line m_out_nmi_cb; device_a1bus_card_interface *m_device; }; // device type definition DECLARE_DEVICE_TYPE(A1BUS, a1bus_device) // ======================> device_a1bus_card_interface // class representing interface-specific live a1bus card class device_a1bus_card_interface : public device_interface { friend class a1bus_device; public: // construction/destruction virtual ~device_a1bus_card_interface(); device_a1bus_card_interface *next() const { return m_next; } // inline configuration void set_a1bus(a1bus_device *a1bus, const char *slottag) { m_a1bus = a1bus; m_a1bus_slottag = slottag; } template void set_onboard(T &&a1bus) { m_a1bus_finder.set_tag(std::forward(a1bus)); m_a1bus_slottag = device().tag(); } protected: void raise_slot_irq() { m_a1bus->set_irq_line(ASSERT_LINE); } void lower_slot_irq() { m_a1bus->set_irq_line(CLEAR_LINE); } void raise_slot_nmi() { m_a1bus->set_nmi_line(ASSERT_LINE); } void lower_slot_nmi() { m_a1bus->set_nmi_line(CLEAR_LINE); } void install_device(offs_t start, offs_t end, read8sm_delegate rhandler, write8sm_delegate whandler); void install_bank(offs_t start, offs_t end, const char *tag, uint8_t *data); device_a1bus_card_interface(const machine_config &mconfig, device_t &device); virtual void interface_validity_check(validity_checker &valid) const override; virtual void interface_pre_start() override; private: optional_device m_a1bus_finder; a1bus_device *m_a1bus; const char *m_a1bus_slottag; device_a1bus_card_interface *m_next; }; #endif // MAME_BUS_A1BUS_A1BUS_H