1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     S-100 (IEEE-696/1983) bus emulation
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "s100.h"
11 
12 
13 //**************************************************************************
14 //  DEVICE DEFINITIONS
15 //**************************************************************************
16 
17 DEFINE_DEVICE_TYPE(S100_BUS,  s100_bus_device,  "s100_bus",  "S100 bus")
18 DEFINE_DEVICE_TYPE(S100_SLOT, s100_slot_device, "s100_slot", "S100 slot")
19 
20 
21 
22 //**************************************************************************
23 //  LIVE DEVICE
24 //**************************************************************************
25 
26 //-------------------------------------------------
27 //  device_s100_card_interface - constructor
28 //-------------------------------------------------
29 
device_s100_card_interface(const machine_config & mconfig,device_t & device)30 device_s100_card_interface::device_s100_card_interface(const machine_config &mconfig, device_t &device) :
31 	device_interface(device, "s100bus"),
32 	m_bus(nullptr),
33 	m_next(nullptr)
34 {
35 }
36 
interface_pre_start()37 void device_s100_card_interface::interface_pre_start()
38 {
39 	if (!m_bus)
40 		throw device_missing_dependencies();
41 }
42 
43 
44 //-------------------------------------------------
45 //  s100_slot_device - constructor
46 //-------------------------------------------------
s100_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)47 s100_slot_device::s100_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
48 	device_t(mconfig, S100_SLOT, tag, owner, clock),
49 	device_single_card_slot_interface<device_s100_card_interface>(mconfig, *this),
50 	m_bus(*this, DEVICE_SELF_OWNER)
51 {
52 }
53 
54 
55 //-------------------------------------------------
56 //  device_start - device-specific startup
57 //-------------------------------------------------
58 
device_start()59 void s100_slot_device::device_start()
60 {
61 	device_s100_card_interface *const dev = get_card_device();
62 	if (dev)
63 		m_bus->add_card(dev);
64 }
65 
66 
67 //-------------------------------------------------
68 //  s100_bus_device - constructor
69 //-------------------------------------------------
70 
s100_bus_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)71 s100_bus_device::s100_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
72 	device_t(mconfig, S100_BUS, tag, owner, clock),
73 	m_write_irq(*this),
74 	m_write_nmi(*this),
75 	m_write_vi0(*this),
76 	m_write_vi1(*this),
77 	m_write_vi2(*this),
78 	m_write_vi3(*this),
79 	m_write_vi4(*this),
80 	m_write_vi5(*this),
81 	m_write_vi6(*this),
82 	m_write_vi7(*this),
83 	m_write_dma0(*this),
84 	m_write_dma1(*this),
85 	m_write_dma2(*this),
86 	m_write_dma3(*this),
87 	m_write_rdy(*this),
88 	m_write_hold(*this),
89 	m_write_error(*this)
90 {
91 }
92 
93 
94 //-------------------------------------------------
95 //  device_start - device-specific startup
96 //-------------------------------------------------
97 
device_start()98 void s100_bus_device::device_start()
99 {
100 	// resolve callbacks
101 	m_write_irq.resolve_safe();
102 	m_write_nmi.resolve_safe();
103 	m_write_vi0.resolve_safe();
104 	m_write_vi1.resolve_safe();
105 	m_write_vi2.resolve_safe();
106 	m_write_vi3.resolve_safe();
107 	m_write_vi4.resolve_safe();
108 	m_write_vi5.resolve_safe();
109 	m_write_vi6.resolve_safe();
110 	m_write_vi7.resolve_safe();
111 	m_write_dma0.resolve_safe();
112 	m_write_dma1.resolve_safe();
113 	m_write_dma2.resolve_safe();
114 	m_write_dma3.resolve_safe();
115 	m_write_rdy.resolve_safe();
116 	m_write_hold.resolve_safe();
117 	m_write_error.resolve_safe();
118 }
119 
120 
121 //-------------------------------------------------
122 //  device_reset - device-specific reset
123 //-------------------------------------------------
124 
device_reset()125 void s100_bus_device::device_reset()
126 {
127 }
128 
129 
130 //-------------------------------------------------
131 //  add_card - add card
132 //-------------------------------------------------
133 
add_card(device_s100_card_interface * card)134 void s100_bus_device::add_card(device_s100_card_interface *card)
135 {
136 	card->m_bus = this;
137 	m_device_list.append(*card);
138 }
139 
140 
141 //-------------------------------------------------
142 //  smemr_r - memory read
143 //-------------------------------------------------
144 
smemr_r(offs_t offset)145 uint8_t s100_bus_device::smemr_r(offs_t offset)
146 {
147 	uint8_t data = 0xff;
148 
149 	device_s100_card_interface *entry = m_device_list.first();
150 
151 	while (entry)
152 	{
153 		data &= entry->s100_smemr_r(offset);
154 		entry = entry->next();
155 	}
156 
157 	return data;
158 }
159 
160 
161 //-------------------------------------------------
162 //  mwrt_w - memory write
163 //-------------------------------------------------
164 
mwrt_w(offs_t offset,uint8_t data)165 void s100_bus_device::mwrt_w(offs_t offset, uint8_t data)
166 {
167 	device_s100_card_interface *entry = m_device_list.first();
168 
169 	while (entry)
170 	{
171 		entry->s100_mwrt_w(offset, data);
172 		entry = entry->next();
173 	}
174 }
175 
176 
177 //-------------------------------------------------
178 //  sinp_r - I/O read
179 //-------------------------------------------------
180 
sinp_r(offs_t offset)181 uint8_t s100_bus_device::sinp_r(offs_t offset)
182 {
183 	uint8_t data = 0xff;
184 
185 	device_s100_card_interface *entry = m_device_list.first();
186 
187 	while (entry)
188 	{
189 		data &= entry->s100_sinp_r(offset);
190 		entry = entry->next();
191 	}
192 
193 	return data;
194 }
195 
196 
197 //-------------------------------------------------
198 //  sout_w - I/O write
199 //-------------------------------------------------
200 
sout_w(offs_t offset,uint8_t data)201 void s100_bus_device::sout_w(offs_t offset, uint8_t data)
202 {
203 	device_s100_card_interface *entry = m_device_list.first();
204 
205 	while (entry)
206 	{
207 		entry->s100_sout_w(offset, data);
208 		entry = entry->next();
209 	}
210 }
211