1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4
5 Commodore SFX Sound Expander cartridge emulation
6
7 **********************************************************************/
8
9 #include "emu.h"
10 #include "sfx_sound_expander.h"
11 #include "speaker.h"
12
13
14
15 //**************************************************************************
16 // MACROS / CONSTANTS
17 //**************************************************************************
18
19 #define YM3526_TAG "ic3"
20
21
22
23 //**************************************************************************
24 // DEVICE DEFINITIONS
25 //**************************************************************************
26
27 DEFINE_DEVICE_TYPE(C64_SFX_SOUND_EXPANDER, c64_sfx_sound_expander_cartridge_device, "c64_sfxse", "C64 SFX Sound Expander cartridge")
28
29
30 //-------------------------------------------------
31 // ym3526_interface ym3526_config
32 //-------------------------------------------------
33
WRITE_LINE_MEMBER(c64_sfx_sound_expander_cartridge_device::opl_irq_w)34 WRITE_LINE_MEMBER( c64_sfx_sound_expander_cartridge_device::opl_irq_w )
35 {
36 m_slot->irq_w(state);
37 }
38
39
40 //-------------------------------------------------
41 // device_add_mconfig - add device configuration
42 //-------------------------------------------------
43
device_add_mconfig(machine_config & config)44 void c64_sfx_sound_expander_cartridge_device::device_add_mconfig(machine_config &config)
45 {
46 SPEAKER(config, "mono").front_center();
47 YM3526(config, m_opl, XTAL(3'579'545));
48 m_opl->irq_handler().set(FUNC(c64_sfx_sound_expander_cartridge_device::opl_irq_w));
49 m_opl->add_route(ALL_OUTPUTS, "mono", 0.70);
50
51 C64_EXPANSION_SLOT(config, m_exp, DERIVED_CLOCK(1, 1), c64_expansion_cards, nullptr);
52 m_exp->set_passthrough();
53 }
54
55
56 //-------------------------------------------------
57 // INPUT_PORTS( c64_sfx_sound_expander )
58 //-------------------------------------------------
59
60 static INPUT_PORTS_START( c64_sfx_sound_expander )
61 PORT_START("KB0")
62 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C2")
63 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C#2")
64 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D")
65 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D#2")
66 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E2")
67 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2")
68 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F#2")
69 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G2")
70
71 PORT_START("KB1")
72 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G#2")
73 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A3")
74 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A#3")
75 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B3")
76 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C3")
77 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C#3")
78 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D3")
79 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D#3")
80
81 PORT_START("KB2")
82 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E3")
83 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3")
84 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F#3")
85 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G3")
86 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G#3")
87 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A4")
88 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A#4")
89 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B4")
90
91 PORT_START("KB3")
92 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C4")
93 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C#4")
94 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D4")
95 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D#4")
96 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E4")
97 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4")
98 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F#4")
99 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G4")
100
101 PORT_START("KB4")
102 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G#4")
103 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A5")
104 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A#5")
105 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B5")
106 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C5")
107 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C#5")
108 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D5")
109 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D#5")
110
111 PORT_START("KB5")
112 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E5")
113 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5")
114 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F#5")
115 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G5")
116 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G#5")
117 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A6")
118 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A#6")
119 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B6")
120
121 PORT_START("KB6")
122 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C6")
123 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C#6")
124 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D6")
125 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D#6")
126 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E6")
127 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6")
128 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F#6")
129 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G6")
130
131 PORT_START("KB7")
132 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G#6")
133 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A7")
134 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A#7")
135 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B7")
136 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C7")
137 PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
138 INPUT_PORTS_END
139
140
141 //-------------------------------------------------
142 // input_ports - device-specific input ports
143 //-------------------------------------------------
144
device_input_ports() const145 ioport_constructor c64_sfx_sound_expander_cartridge_device::device_input_ports() const
146 {
147 return INPUT_PORTS_NAME( c64_sfx_sound_expander );
148 }
149
150
151
152 //**************************************************************************
153 // INLINE HELPERS
154 //**************************************************************************
155
156 //-------------------------------------------------
157 // get_offset - get passthru expansion port offset
158 //-------------------------------------------------
159
get_offset(offs_t offset,int rw)160 inline offs_t c64_sfx_sound_expander_cartridge_device::get_offset(offs_t offset, int rw)
161 {
162 // assimilate the 3 different MIDI cartridge 6850 ACIA register mappings?
163 return (offset & 0xfffc) | (rw << 1) | BIT(offset, 1);
164 }
165
166
167
168 //**************************************************************************
169 // LIVE DEVICE
170 //**************************************************************************
171
172 //-------------------------------------------------
173 // c64_sfx_sound_expander_cartridge_device - constructor
174 //-------------------------------------------------
175
c64_sfx_sound_expander_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)176 c64_sfx_sound_expander_cartridge_device::c64_sfx_sound_expander_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
177 device_t(mconfig, C64_SFX_SOUND_EXPANDER, tag, owner, clock),
178 device_c64_expansion_card_interface(mconfig, *this),
179 m_opl(*this, YM3526_TAG),
180 m_exp(*this, "exp"),
181 m_kb(*this, "KB%u", 0)
182 {
183 }
184
185
186 //-------------------------------------------------
187 // device_start - device-specific startup
188 //-------------------------------------------------
189
device_start()190 void c64_sfx_sound_expander_cartridge_device::device_start()
191 {
192 }
193
194
195 //-------------------------------------------------
196 // device_reset - device-specific reset
197 //-------------------------------------------------
198
device_reset()199 void c64_sfx_sound_expander_cartridge_device::device_reset()
200 {
201 m_opl->reset();
202 }
203
204
205 //-------------------------------------------------
206 // c64_cd_r - cartridge data read
207 //-------------------------------------------------
208
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)209 uint8_t c64_sfx_sound_expander_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
210 {
211 data = m_exp->cd_r(get_offset(offset, 1), data, sphi2, ba, roml, romh, io1, io2);
212
213 if (!io2 && sphi2)
214 {
215 if (BIT(offset, 3))
216 {
217 data = m_kb[offset & 0x07]->read();
218 }
219
220 if (BIT(offset, 5))
221 {
222 data = m_opl->read(BIT(offset, 4));
223 }
224 }
225
226 return data;
227 }
228
229
230 //-------------------------------------------------
231 // c64_cd_w - cartridge data write
232 //-------------------------------------------------
233
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)234 void c64_sfx_sound_expander_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
235 {
236 if (!io2 && sphi2)
237 {
238 m_opl->write(BIT(offset, 4), data);
239 }
240
241 m_exp->cd_w(get_offset(offset, 0), data, sphi2, ba, roml, romh, io1, io2);
242 }
243
244
245 //-------------------------------------------------
246 // c64_game_r - GAME read
247 //-------------------------------------------------
248
c64_game_r(offs_t offset,int sphi2,int ba,int rw)249 int c64_sfx_sound_expander_cartridge_device::c64_game_r(offs_t offset, int sphi2, int ba, int rw)
250 {
251 return m_exp->game_r(get_offset(offset, rw), sphi2, ba, rw, m_slot->loram(), m_slot->hiram());
252 }
253
254
255 //-------------------------------------------------
256 // c64_exrom_r - EXROM read
257 //-------------------------------------------------
258
c64_exrom_r(offs_t offset,int sphi2,int ba,int rw)259 int c64_sfx_sound_expander_cartridge_device::c64_exrom_r(offs_t offset, int sphi2, int ba, int rw)
260 {
261 return m_exp->exrom_r(get_offset(offset, rw), sphi2, ba, rw, m_slot->loram(), m_slot->hiram());
262 }
263