1 // license:GPL-2.0+
2 // copyright-holders:Jonathan Edwards
3 /***************************************************************************
4 
5   bml3bus.c - Hitachi MB-6890 slot bus and card emulation
6 
7   Adapted from a2bus by Jonathan Edwards
8 
9   Pinout (/ indicates an inverted signal, ie, one that would have a bar over it
10           on a schematic diagram)
11 
12        out <-> CPU CPU <-> out
13        ----------  -----------
14        +5V <--  1   2  <-> GND
15         D0 <->  3   4  <-> D1
16         D2 <->  5   6  <-> D3
17         D4 <->  7   8  <-> D5
18         D6 <->  9  10  <-> D7
19         A0 <-> 11  12  <-> A1
20         A2 <-> 13  14  <-> A3
21         A4 <-> 15  16  <-> A5
22         A6 <-> 17  18  <-> A7
23         A8 <-> 19  20  <-> A9
24        A10 <-> 21  22  <-> A11
25        A12 <-> 23  24  <-> A13
26        A14 <-> 25  26  <-> A15
27         BA <-- 27  28  --> BS
28   /ROM-KIL --> 29  30  --> EXROM-KIL
29     R/W IN --> 31  32  --> /EX-I/O
30    R/W OUT <-- 33  34  --> VMA OUT
31          E <-- 35  36  --> Q
32       /RES <-- 37  38  <-- /NMI
33       /IRQ --> 39  40  <-- /FIRQ
34      /HALT --> 41  42  <-- /VMA CTRL
35       /DMA --> 43  44  --> /BANK-SW
36   HALT ACK <-- 45  46  <-- SOUND IN
37      16MCK <-- 47  48  <-> GND
38       2MCK <-- 49  50  <-> GND
39        -5V <-- 51  52  --> /EX-I/O2
40       -12V <-- 53  54  --> +12V
41        GND <-> 55  56  --> +5V
42 
43 ***************************************************************************/
44 
45 #include "emu.h"
46 #include "bml3bus.h"
47 
48 
49 //**************************************************************************
50 //  GLOBAL VARIABLES
51 //**************************************************************************
52 
53 DEFINE_DEVICE_TYPE(BML3BUS_SLOT, bml3bus_slot_device, "bml3bus_slot", "Hitachi MB-6890 Slot")
54 
55 //**************************************************************************
56 //  LIVE DEVICE
57 //**************************************************************************
58 
59 //-------------------------------------------------
60 //  bml3bus_slot_device - constructor
61 //-------------------------------------------------
bml3bus_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)62 bml3bus_slot_device::bml3bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
63 	bml3bus_slot_device(mconfig, BML3BUS_SLOT, tag, owner, clock)
64 {
65 }
66 
bml3bus_slot_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)67 bml3bus_slot_device::bml3bus_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
68 	device_t(mconfig, type, tag, owner, clock),
69 	device_single_card_slot_interface<device_bml3bus_card_interface>(mconfig, *this),
70 	m_bml3bus(*this, finder_base::DUMMY_TAG),
71 	m_bml3bus_slottag(nullptr)
72 {
73 }
74 
75 //-------------------------------------------------
76 //  device_start - device-specific startup
77 //-------------------------------------------------
78 
device_start()79 void bml3bus_slot_device::device_start()
80 {
81 	device_bml3bus_card_interface *const dev = get_card_device();
82 	if (dev)
83 		dev->set_bml3bus(*m_bml3bus, m_bml3bus_slottag);
84 }
85 
86 //**************************************************************************
87 //  GLOBAL VARIABLES
88 //**************************************************************************
89 
90 DEFINE_DEVICE_TYPE(BML3BUS, bml3bus_device, "bml3bus", "Hitachi MB-6890 Bus")
91 
92 //**************************************************************************
93 //  LIVE DEVICE
94 //**************************************************************************
95 
96 //-------------------------------------------------
97 //  bml3bus_device - constructor
98 //-------------------------------------------------
99 
bml3bus_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)100 bml3bus_device::bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
101 	bml3bus_device(mconfig, BML3BUS, tag, owner, clock)
102 {
103 }
104 
bml3bus_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)105 bml3bus_device::bml3bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
106 	device_t(mconfig, type, tag, owner, clock),
107 	m_space(*this, finder_base::DUMMY_TAG, -1, 8),
108 	m_out_nmi_cb(*this),
109 	m_out_irq_cb(*this),
110 	m_out_firq_cb(*this)
111 {
112 }
113 
114 //-------------------------------------------------
115 //  device_start - device-specific startup
116 //-------------------------------------------------
117 
device_start()118 void bml3bus_device::device_start()
119 {
120 	// resolve callbacks
121 	m_out_nmi_cb.resolve_safe();
122 	m_out_irq_cb.resolve_safe();
123 	m_out_firq_cb.resolve_safe();
124 
125 	// clear slots
126 	for (auto & elem : m_device_list)
127 	{
128 		elem = nullptr;
129 	}
130 }
131 
132 //-------------------------------------------------
133 //  device_reset - device-specific reset
134 //-------------------------------------------------
135 
device_reset()136 void bml3bus_device::device_reset()
137 {
138 }
139 
get_bml3bus_card(int slot)140 device_bml3bus_card_interface *bml3bus_device::get_bml3bus_card(int slot)
141 {
142 	if (slot < 0)
143 	{
144 		return nullptr;
145 	}
146 
147 	return m_device_list[slot];
148 }
149 
add_bml3bus_card(int slot,device_bml3bus_card_interface & card)150 void bml3bus_device::add_bml3bus_card(int slot, device_bml3bus_card_interface &card)
151 {
152 	m_device_list[slot] = &card;
153 }
154 
set_nmi_line(int state)155 void bml3bus_device::set_nmi_line(int state)
156 {
157 	m_out_nmi_cb(state);
158 }
159 
set_irq_line(int state)160 void bml3bus_device::set_irq_line(int state)
161 {
162 	m_out_irq_cb(state);
163 }
164 
set_firq_line(int state)165 void bml3bus_device::set_firq_line(int state)
166 {
167 	m_out_firq_cb(state);
168 }
169 
170 // interrupt request from bml3bus card
WRITE_LINE_MEMBER(bml3bus_device::nmi_w)171 WRITE_LINE_MEMBER( bml3bus_device::nmi_w ) { m_out_nmi_cb(state); }
WRITE_LINE_MEMBER(bml3bus_device::irq_w)172 WRITE_LINE_MEMBER( bml3bus_device::irq_w ) { m_out_irq_cb(state); }
WRITE_LINE_MEMBER(bml3bus_device::firq_w)173 WRITE_LINE_MEMBER( bml3bus_device::firq_w ) { m_out_firq_cb(state); }
174 
175 //**************************************************************************
176 //  DEVICE CONFIG BML3BUS CARD INTERFACE
177 //**************************************************************************
178 
179 
180 //**************************************************************************
181 //  DEVICE BML3BUS CARD INTERFACE
182 //**************************************************************************
183 
184 //-------------------------------------------------
185 //  device_bml3bus_card_interface - constructor
186 //-------------------------------------------------
187 
device_bml3bus_card_interface(const machine_config & mconfig,device_t & device)188 device_bml3bus_card_interface::device_bml3bus_card_interface(const machine_config &mconfig, device_t &device) :
189 	device_interface(device, "bml3bus"),
190 	m_bml3bus(nullptr),
191 	m_slot(0)
192 {
193 }
194 
195 
196 //-------------------------------------------------
197 //  ~device_bml3bus_card_interface - destructor
198 //-------------------------------------------------
199 
~device_bml3bus_card_interface()200 device_bml3bus_card_interface::~device_bml3bus_card_interface()
201 {
202 }
203 
interface_pre_start()204 void device_bml3bus_card_interface::interface_pre_start()
205 {
206 	if (!m_bml3bus)
207 		throw device_missing_dependencies();
208 }
209 
set_bml3bus(bml3bus_device & bus,const char * slottag)210 void device_bml3bus_card_interface::set_bml3bus(bml3bus_device &bus, const char *slottag)
211 {
212 	assert(!m_bml3bus);
213 	assert(!device().started());
214 
215 	// extract the slot number from the last digit of the slot tag
216 	int tlen = strlen(slottag);
217 	m_slot = (slottag[tlen - 1] - '1');
218 
219 	if (m_slot < 0 || m_slot >= BML3BUS_MAX_SLOTS)
220 		fatalerror("Slot %d out of range for Hitachi MB-6890 Bus\n", m_slot);
221 
222 	m_bml3bus = &bus;
223 	m_bml3bus->add_bml3bus_card(m_slot, *this);
224 }
225