1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Passport/Syntech MIDI Interface cartridge emulation
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "midi_passport.h"
11 #include "machine/clock.h"
12 #include "bus/midi/midi.h"
13 
14 
15 
16 //**************************************************************************
17 //  MACROS/CONSTANTS
18 //**************************************************************************
19 
20 #define MC6840_TAG      "mc6840"
21 #define MC6850_TAG      "mc6850"
22 
23 
24 
25 //**************************************************************************
26 //  DEVICE DEFINITIONS
27 //**************************************************************************
28 
29 DEFINE_DEVICE_TYPE(C64_MIDI_PASSPORT, c64_passport_midi_cartridge_device, "c64_midipp", "C64 Passport MIDI")
30 
31 
32 //-------------------------------------------------
33 //  ptm6840_interface ptm_intf
34 //-------------------------------------------------
35 
WRITE_LINE_MEMBER(c64_passport_midi_cartridge_device::ptm_irq_w)36 WRITE_LINE_MEMBER( c64_passport_midi_cartridge_device::ptm_irq_w )
37 {
38 	m_ptm_irq = state;
39 
40 	m_slot->irq_w(m_ptm_irq || m_acia_irq);
41 }
42 
WRITE_LINE_MEMBER(c64_passport_midi_cartridge_device::acia_irq_w)43 WRITE_LINE_MEMBER( c64_passport_midi_cartridge_device::acia_irq_w )
44 {
45 	m_acia_irq = state;
46 
47 	m_slot->irq_w(m_ptm_irq || m_acia_irq);
48 }
49 
WRITE_LINE_MEMBER(c64_passport_midi_cartridge_device::write_acia_clock)50 WRITE_LINE_MEMBER( c64_passport_midi_cartridge_device::write_acia_clock )
51 {
52 	m_acia->write_txc(state);
53 	m_acia->write_rxc(state);
54 }
55 
56 
57 //-------------------------------------------------
58 //  device_add_mconfig - add device configuration
59 //-------------------------------------------------
60 
device_add_mconfig(machine_config & config)61 void c64_passport_midi_cartridge_device::device_add_mconfig(machine_config &config)
62 {
63 	ACIA6850(config, m_acia, 0);
64 	m_acia->txd_handler().set("mdout", FUNC(midi_port_device::write_txd));
65 	m_acia->irq_handler().set(FUNC(c64_passport_midi_cartridge_device::acia_irq_w));
66 
67 	PTM6840(config, m_ptm, 1021800);
68 	m_ptm->set_external_clocks(1021800.0f, 1021800.0f, 1021800.0f);
69 	m_ptm->irq_callback().set(FUNC(c64_passport_midi_cartridge_device::ptm_irq_w));
70 
71 	MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
72 
73 	MIDI_PORT(config, "mdout", midiout_slot, "midiout");
74 
75 	clock_device &acia_clock(CLOCK(config, "acia_clock", 31250*16)); // TODO: work out if the clock should come from the 6840
76 	acia_clock.signal_handler().set(FUNC(c64_passport_midi_cartridge_device::write_acia_clock));
77 }
78 
79 
80 
81 //**************************************************************************
82 //  LIVE DEVICE
83 //**************************************************************************
84 
85 //-------------------------------------------------
86 //  c64_passport_midi_cartridge_device - constructor
87 //-------------------------------------------------
88 
c64_passport_midi_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)89 c64_passport_midi_cartridge_device::c64_passport_midi_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
90 	device_t(mconfig, C64_MIDI_PASSPORT, tag, owner, clock),
91 	device_c64_expansion_card_interface(mconfig, *this),
92 	m_acia(*this, MC6850_TAG),
93 	m_ptm(*this, MC6840_TAG),
94 	m_ptm_irq(CLEAR_LINE),
95 	m_acia_irq(CLEAR_LINE)
96 {
97 }
98 
99 
100 //-------------------------------------------------
101 //  device_start - device-specific startup
102 //-------------------------------------------------
103 
device_start()104 void c64_passport_midi_cartridge_device::device_start()
105 {
106 	// state saving
107 	save_item(NAME(m_ptm_irq));
108 	save_item(NAME(m_acia_irq));
109 }
110 
111 
112 //-------------------------------------------------
113 //  device_reset - device-specific reset
114 //-------------------------------------------------
115 
device_reset()116 void c64_passport_midi_cartridge_device::device_reset()
117 {
118 	m_acia->reset();
119 	m_ptm->reset();
120 }
121 
122 
123 //-------------------------------------------------
124 //  c64_cd_r - cartridge data read
125 //-------------------------------------------------
126 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)127 uint8_t c64_passport_midi_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
128 {
129 	if (!io1)
130 	{
131 		switch (offset & 0xff)
132 		{
133 		case 0: case 1: case 2: case 3:
134 		case 4: case 5: case 6: case 7:
135 			data = m_ptm->read(offset & 0x07);
136 			break;
137 
138 		case 8: case 9:
139 			data = m_acia->read(offset & 0x01);
140 			break;
141 		}
142 	}
143 
144 	return data;
145 }
146 
147 
148 //-------------------------------------------------
149 //  c64_cd_w - cartridge data write
150 //-------------------------------------------------
151 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)152 void c64_passport_midi_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
153 {
154 	if (!io1)
155 	{
156 		switch (offset & 0xff)
157 		{
158 		case 0: case 1: case 2: case 3:
159 		case 4: case 5: case 6: case 7:
160 			m_ptm->write(offset & 0x07, data);
161 			break;
162 
163 		case 8: case 9:
164 			m_acia->write(offset & 0x01, data);
165 			break;
166 
167 		case 0x30:
168 			// Drum sync SET
169 			break;
170 
171 		case 0x38:
172 			// Drum sync CLEAR
173 			break;
174 		}
175 	}
176 }
177