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