1 // license:BSD-3-Clause
2 // copyright-holders:Barry Rodewald
3 /*
4  * The Music Machine - MIDI and sampling expansion
5  * by Ram Electronics
6  */
7 
8 #include "emu.h"
9 #include "musicmachine.h"
10 
11 #include "bus/midi/midi.h"
12 #include "machine/clock.h"
13 #include "speaker.h"
14 
15 //**************************************************************************
16 //  DEVICE DEFINITIONS
17 //**************************************************************************
18 
19 DEFINE_DEVICE_TYPE(CPC_MUSICMACHINE, cpc_musicmachine_device, "cpcmusic", "The Music Machine")
20 
21 
device_add_mconfig(machine_config & config)22 void cpc_musicmachine_device::device_add_mconfig(machine_config &config)
23 {
24 	ACIA6850(config, m_acia).txd_handler().set("mdout", FUNC(midi_port_device::write_txd));
25 	m_acia->irq_handler().set(DEVICE_SELF_OWNER, FUNC(cpc_expansion_slot_device::nmi_w));
26 	MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
27 	MIDI_PORT(config, "mdout", midiout_slot, "midiout");
28 	clock_device &acia_clock(CLOCK(config, "acia_clock", 31250*16));
29 	acia_clock.signal_handler().set(FUNC(cpc_musicmachine_device::write_acia_clock));
30 
31 	SPEAKER(config, "speaker").front_center();
32 	ZN429E(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.2);
33 
34 	// no pass-through
35 }
36 
37 //**************************************************************************
38 //  LIVE DEVICE
39 //**************************************************************************
40 
cpc_musicmachine_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)41 cpc_musicmachine_device::cpc_musicmachine_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
42 	device_t(mconfig, CPC_MUSICMACHINE, tag, owner, clock),
43 	device_cpc_expansion_card_interface(mconfig, *this),
44 	m_slot(nullptr),
45 	m_acia(*this,"acia"),
46 	m_dac(*this,"dac"),
47 	m_irq_select(false)
48 {
49 }
50 
51 //-------------------------------------------------
52 //  device_start - device-specific startup
53 //-------------------------------------------------
54 
device_start()55 void cpc_musicmachine_device::device_start()
56 {
57 	m_slot = dynamic_cast<cpc_expansion_slot_device *>(owner());
58 	address_space &space = m_slot->cpu().space(AS_IO);
59 
60 	space.install_write_handler(0xf8e8,0xf8e8, write8smo_delegate(*this, FUNC(cpc_musicmachine_device::irqsel_w)));
61 	space.install_readwrite_handler(0xf8ec,0xf8ef, read8sm_delegate(*this, FUNC(cpc_musicmachine_device::acia_r)), write8sm_delegate(*this, FUNC(cpc_musicmachine_device::acia_w)));
62 	space.install_write_handler(0xf8f0,0xf8f0, write8smo_delegate(*this, FUNC(cpc_musicmachine_device::dac_w)));
63 	// 0xf8f4 - ADC read8_delegate
64 	// 0xf8f8 - ADC start
65 }
66 
67 //-------------------------------------------------
68 //  device_reset - device-specific reset
69 //-------------------------------------------------
70 
device_reset()71 void cpc_musicmachine_device::device_reset()
72 {
73 	// TODO
74 }
75 
dac_w(uint8_t data)76 void cpc_musicmachine_device::dac_w(uint8_t data)
77 {
78 	m_dac->write(data);
79 }
80 
acia_r(offs_t offset)81 uint8_t cpc_musicmachine_device::acia_r(offs_t offset)
82 {
83 	uint8_t ret = 0;
84 
85 	switch(offset)
86 	{
87 		case 2:
88 			ret = m_acia->status_r();
89 			break;
90 		case 3:
91 			ret = m_acia->data_r();
92 			break;
93 	}
94 
95 	return ret;
96 }
97 
acia_w(offs_t offset,uint8_t data)98 void cpc_musicmachine_device::acia_w(offs_t offset, uint8_t data)
99 {
100 	switch(offset)
101 	{
102 		case 0:
103 			m_acia->control_w(data);
104 			break;
105 		case 1:
106 			m_acia->data_w(data);
107 			break;
108 	}
109 }
110 
irqsel_w(uint8_t data)111 void cpc_musicmachine_device::irqsel_w(uint8_t data)
112 {
113 	if(data == 0x01)
114 		m_irq_select = true;
115 	else
116 		m_irq_select = false;
117 }
118 
WRITE_LINE_MEMBER(cpc_musicmachine_device::irq_w)119 WRITE_LINE_MEMBER(cpc_musicmachine_device::irq_w)
120 {
121 	if(m_irq_select)
122 		m_slot->nmi_w(state);
123 }
124 
125