1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont
3 /***************************************************************************
4 
5   nubus.h - NuBus bus and card emulation
6 
7   by R. Belmont, based heavily on Miodrag Milanovic's ISA8/16 implementation
8 
9 ***************************************************************************/
10 
11 #ifndef MAME_BUS_NUBUS_NUBUS_H
12 #define MAME_BUS_NUBUS_NUBUS_H
13 
14 #pragma once
15 
16 
17 //**************************************************************************
18 //  TYPE DEFINITIONS
19 //**************************************************************************
20 
21 class nubus_device;
22 
23 // ======================> device_nubus_card_interface
24 
25 // class representing interface-specific live nubus card
26 class device_nubus_card_interface : public device_interface
27 {
28 	friend class nubus_device;
29 	template <class ElementType> friend class simple_list;
30 public:
31 	// construction/destruction
32 	virtual ~device_nubus_card_interface();
33 
next()34 	device_nubus_card_interface *next() const { return m_next; }
35 
36 	void set_nubus_device();
37 
38 	// helper functions for card devices
39 	void install_declaration_rom(device_t *dev, const char *romregion, bool mirror_all_mb = false, bool reverse_rom = false);
40 	void install_bank(offs_t start, offs_t end, const char *tag, uint8_t *data);
41 
get_slotspace()42 	uint32_t get_slotspace() { return 0xf0000000 | (m_slot<<24); }
get_super_slotspace()43 	uint32_t get_super_slotspace() { return m_slot<<28; }
44 
45 	void raise_slot_irq();
46 	void lower_slot_irq();
47 
48 	// inline configuration
set_nubus_tag(nubus_device * nubus,const char * slottag)49 	void set_nubus_tag(nubus_device *nubus, const char *slottag) { m_nubus = nubus; m_nubus_slottag = slottag; }
50 
51 protected:
52 	device_nubus_card_interface(const machine_config &mconfig, device_t &device);
53 	virtual void interface_pre_start() override;
54 
slotno()55 	int slotno() const { assert(m_nubus); return m_slot; }
nubus()56 	nubus_device &nubus() { assert(m_nubus); return *m_nubus; }
57 
58 private:
59 	nubus_device *m_nubus;
60 	const char *m_nubus_slottag;
61 	int m_slot;
62 	std::vector<uint8_t> m_declaration_rom;
63 	device_nubus_card_interface *m_next;
64 };
65 
66 class nubus_slot_device : public device_t, public device_single_card_slot_interface<device_nubus_card_interface>
67 {
68 public:
69 	// construction/destruction
70 	template <typename T, typename U>
nubus_slot_device(const machine_config & mconfig,T && tag,device_t * owner,const char * nbtag,U && opts,const char * dflt)71 	nubus_slot_device(const machine_config &mconfig, T &&tag, device_t *owner, const char *nbtag, U &&opts, const char *dflt)
72 		: nubus_slot_device(mconfig, tag, owner, (uint32_t)0)
73 	{
74 		option_reset();
75 		opts(*this);
76 		set_default_option(dflt);
77 		set_nubus_slot(std::forward<T>(nbtag), tag);
78 	}
79 
80 	nubus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
81 
82 	// inline configuration
83 	template <typename T>
set_nubus_slot(T && tag,const char * slottag)84 	void set_nubus_slot(T &&tag, const char *slottag)
85 	{
86 		m_nubus.set_tag(std::forward<T>(tag));
87 		m_nubus_slottag = slottag;
88 	}
89 
90 protected:
91 	nubus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
92 
93 	// device-level overrides
94 	virtual void device_resolve_objects() override;
95 	virtual void device_start() override;
96 
97 	// configuration
98 	required_device<nubus_device> m_nubus;
99 	const char *m_nubus_slottag;
100 };
101 
102 // device type definition
DECLARE_DEVICE_TYPE(NUBUS_SLOT,nubus_slot_device)103 DECLARE_DEVICE_TYPE(NUBUS_SLOT, nubus_slot_device)
104 
105 
106 class device_nubus_card_interface;
107 // ======================> nubus_device
108 class nubus_device : public device_t
109 {
110 public:
111 	// construction/destruction
112 	nubus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
113 	~nubus_device() { m_device_list.detach_all(); }
114 
115 	// inline configuration
116 	template <typename T> void set_space(T &&tag, int spacenum) { m_space.set_tag(std::forward<T>(tag), spacenum); }
117 	auto out_irq9_callback() { return m_out_irq9_cb.bind(); }
118 	auto out_irqa_callback() { return m_out_irqa_cb.bind(); }
119 	auto out_irqb_callback() { return m_out_irqb_cb.bind(); }
120 	auto out_irqc_callback() { return m_out_irqc_cb.bind(); }
121 	auto out_irqd_callback() { return m_out_irqd_cb.bind(); }
122 	auto out_irqe_callback() { return m_out_irqe_cb.bind(); }
123 
124 	void add_nubus_card(device_nubus_card_interface *card);
125 	template<typename R, typename W> void install_device(offs_t start, offs_t end, R rhandler, W whandler, uint32_t mask=0xffffffff);
126 	void install_readonly_device(offs_t start, offs_t end, read32_delegate rhandler, uint32_t mask=0xffffffff);
127 	void install_writeonly_device(offs_t start, offs_t end, write32_delegate whandler, uint32_t mask=0xffffffff);
128 	void install_bank(offs_t start, offs_t end, const char *tag, uint8_t *data);
129 	void set_irq_line(int slot, int state);
130 
131 	DECLARE_WRITE_LINE_MEMBER( irq9_w );
132 	DECLARE_WRITE_LINE_MEMBER( irqa_w );
133 	DECLARE_WRITE_LINE_MEMBER( irqb_w );
134 	DECLARE_WRITE_LINE_MEMBER( irqc_w );
135 	DECLARE_WRITE_LINE_MEMBER( irqd_w );
136 	DECLARE_WRITE_LINE_MEMBER( irqe_w );
137 
138 protected:
139 	nubus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
140 
141 	// device-level overrides
142 	virtual void device_resolve_objects() override;
143 	virtual void device_start() override;
144 
145 	// internal state
146 	required_address_space m_space;
147 
148 	devcb_write_line    m_out_irq9_cb;
149 	devcb_write_line    m_out_irqa_cb;
150 	devcb_write_line    m_out_irqb_cb;
151 	devcb_write_line    m_out_irqc_cb;
152 	devcb_write_line    m_out_irqd_cb;
153 	devcb_write_line    m_out_irqe_cb;
154 
155 	simple_list<device_nubus_card_interface> m_device_list;
156 };
157 
raise_slot_irq()158 inline void device_nubus_card_interface::raise_slot_irq()
159 {
160 	nubus().set_irq_line(m_slot, ASSERT_LINE);
161 }
162 
lower_slot_irq()163 inline void device_nubus_card_interface::lower_slot_irq()
164 {
165 	nubus().set_irq_line(m_slot, CLEAR_LINE);
166 }
167 
168 
169 // device type definition
170 DECLARE_DEVICE_TYPE(NUBUS, nubus_device)
171 
172 #endif  // MAME_BUS_NUBUS_NUBUS_H
173