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