// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Fairlight CMI Music Keyboard
- CMI-10 Music Keyboard Controller
- CMI-11 Keyboard Switch Module
- CMI-12 Keyboard Display and Keypad Module
- CMI-14 Slave Keyboard Interface
****************************************************************************
The Master Keyboard
-------------------
The master keyboard has the following features:
- A serial connector for communicating with the CMI mainframe
- A connector for a slave keyboard
- A connector for the alphanumeric keyboard
- Connectors for pedal controls
- Three slider-type analog controls
- Two switch controls (one momentary, one toggle on/off)
- Two lamp indicators for the switches with software-defined
control
- A 12-character LED alphanumeric display
- A 16-switch keypad
All communications with all peripherals and controls on the master
keyboard is handled via the master keyboard's controller, and as
such there is one single serial link to the "CMI mainframe" box
itself.
***************************************************************************/
#include "emu.h"
#include "cmi_mkbd.h"
#include "cpu/m6800/m6800.h"
#include "machine/clock.h"
DEFINE_DEVICE_TYPE(CMI_MUSIC_KEYBOARD, cmi_music_keyboard_device, "cmi_mkbd", "Fairlight CMI Music Keyboard")
cmi_music_keyboard_device::cmi_music_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, CMI_MUSIC_KEYBOARD, tag, owner, clock)
, m_cmi_txd(*this)
, m_cmi_rts(*this)
, m_kbd_txd(*this)
, m_kbd_rts(*this)
, m_cpu(*this, "kbdcpu")
, m_acia_kbd(*this, "acia_kbd")
, m_acia_cmi(*this, "acia_cmi")
, m_cmi10_pia_u20(*this, "cmi10_pia_u20")
, m_cmi10_pia_u21(*this, "cmi10_pia_u21")
, m_dp1(*this, "dp1")
, m_dp2(*this, "dp2")
, m_dp3(*this, "dp3")
, m_keypad_a_port(*this, "KEYPAD_A")
, m_keypad_b_port(*this, "KEYPAD_B")
, m_analog(*this, "ANALOG")
, m_key_mux_ports{ { *this, "KEY_%u_0", 0 }, { *this, "KEY_%u_1", 0 }, { *this, "KEY_%u_2", 0 }, { *this, "KEY_%u_3", 0 } }
, m_digit(*this, "digit%u", 0U)
{
}
void cmi_music_keyboard_device::device_resolve_objects()
{
m_cmi_txd.resolve_safe();
m_cmi_rts.resolve_safe();
m_kbd_txd.resolve_safe();
m_kbd_rts.resolve_safe();
m_digit.resolve();
}
void cmi_music_keyboard_device::device_start()
{
m_cmi10_scnd_timer = timer_alloc(TIMER_CMI10_SCND);
m_cmi10_scnd_timer->adjust(attotime::from_hz(4000000 / 4 / 2048 / 2), 0, attotime::from_hz(4000000 / 4 / 2048 / 2));
m_scnd = 0;
}
void cmi_music_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_CMI10_SCND:
m_cmi10_pia_u20->ca1_w(m_scnd);
m_scnd ^= 1;
m_cmi10_pia_u21->ca1_w(m_scnd);
break;
}
}
/*
PA0-7 = BKA0-7 (display)
PB0 = DA1
PB1 = DA0
PB2 = CS2
PB3 = CU2
PB4 = CS1
PB5 = CU1
PB6 = CS0
PB7 = CU0
CB1 = /KPAD
CB2 = /DWS
*/
void cmi_music_keyboard_device::cmi10_u20_a_w(u8 data)
{
// low 7 bits connected to alphanumeric display data lines
m_dp1->data_w(data & 0x7f);
m_dp2->data_w(data & 0x7f);
m_dp3->data_w(data & 0x7f);
/*
int bk = data;
int bit = 0;
if (BIT(bk, 3))
bit = BIT(input_port_read(device->machine, "KEYPAD_A"), bk & 7);
else if (!BIT(bk, 4))
bit = BIT(input_port_read(device->machine, "KEYPAD_B"), bk & 7);
pia6821_cb1_w(m_cmi10_pia_u20, 0, !bit);
*/
}
void cmi_music_keyboard_device::cmi10_u20_b_w(u8 data)
{
}
READ_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u20_cb1_r )
{
int bk = m_cmi10_pia_u20->a_output();
int bit = 0;
if (BIT(bk, 3))
bit = BIT(m_keypad_a_port->read(), bk & 7);
else if (!BIT(bk, 4))
bit = BIT(m_keypad_b_port->read(), bk & 7);
return !bit;
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u20_cb2_w )
{
uint8_t data = m_cmi10_pia_u20->a_output() & 0x7f;
uint8_t b_port = m_cmi10_pia_u20->b_output();
int addr = (BIT(b_port, 0) << 1) | BIT(b_port, 1);
/* DP1 */
m_dp1->ce_w(BIT(b_port, 6));
m_dp1->cu_w(BIT(b_port, 7));
m_dp1->wr_w(state);
m_dp1->addr_w(addr);
m_dp1->data_w(data);
/* DP2 */
m_dp2->ce_w(BIT(b_port, 4));
m_dp2->cu_w(BIT(b_port, 5));
m_dp2->wr_w(state);
m_dp2->addr_w(addr);
m_dp2->data_w(data);
/* DP3 */
m_dp3->ce_w(BIT(b_port, 2));
m_dp3->cu_w(BIT(b_port, 3));
m_dp3->wr_w(state);
m_dp3->addr_w(addr);
m_dp3->data_w(data);
}
template <unsigned N> void cmi_music_keyboard_device::update_dp(offs_t offset, u16 data)
{
m_digit[(N << 2) | ((offset ^ 3) & 3)] = data;
}
/* Begin Conversion */
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi10_u21_cb2_w )
{
// if 0
// state = state;
}
u8 cmi_music_keyboard_device::cmi10_u21_a_r()
{
#if 0
// int thld = m_cmi10_pia_u21->ca2_output();
int sel = m_cmi10_pia_u20->a_output();
int key = sel & 7;
int mux = (sel >> 3) & 3;
u8 data = 0x38; // slave keyboard not used
for (int module = 0; module < 3; ++module)
{
// char keyname[16];
u8 keyval;
int state = 1;
if (module == 1 && mux == 2 && key == 3)
{
keyval = m_analog->read();
/* Unpressed */
if (keyval <= 0)
state = 1;
/* In flight */
#if 0
else if (keyval <= 80)
{
if (thld == 1)
state = 0;
else
state = 1;
}
/* Fully depressed */
#endif
else
state = 0;
}
data |= state << module;
}
return data;
#else
int sel = m_cmi10_pia_u20->a_output();
int key = sel & 7;
int mux = (sel >> 3) & 3;
u8 data = 0xf8; // slave keyboard not used
for (int module = 0; module < 3; ++module)
{
u8 keyval = m_key_mux_ports[mux][module]->read();
data |= BIT(keyval, key) << module;
}
/* Now do KD7 */
{
int bit = 0;
if (BIT(sel, 3))
bit = BIT(m_keypad_a_port->read(), sel & 7);
else if (!BIT(sel, 4))
bit = BIT(m_keypad_b_port->read(), sel & 7);
data |= (bit && BIT(sel, 7)) << 7;
}
return data;
#endif
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_acia_int )
{
m_kbd_acia_irq = state;
if (m_kbd_acia_irq)
m_cpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
else if (!m_cmi_acia_irq)
m_cpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_acia_int )
{
m_cmi_acia_irq = state;
if (m_cmi_acia_irq)
m_cpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
else if (!m_kbd_acia_irq)
m_cpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_txd_w )
{
m_cmi_txd(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_rts_w )
{
m_cmi_rts(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_rxd_w )
{
m_acia_cmi->write_rxd(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::cmi_cts_w )
{
m_acia_cmi->write_cts(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_txd_w )
{
m_kbd_txd(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_rts_w )
{
m_kbd_rts(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_rxd_w )
{
m_acia_kbd->write_rxd(state);
}
WRITE_LINE_MEMBER( cmi_music_keyboard_device::kbd_cts_w )
{
m_acia_kbd->write_cts(state);
}
void cmi_music_keyboard_device::muskeys_map(address_map &map)
{
map.unmap_value_high();
map(0x0080, 0x0083).rw(m_cmi10_pia_u21, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0090, 0x0093).rw(m_cmi10_pia_u20, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x00a0, 0x00a1).rw(m_acia_kbd, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0x00b0, 0x00b1).rw(m_acia_cmi, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0x4000, 0x47ff).ram();
map(0xb000, 0xb400).rom();
map(0xf000, 0xffff).rom();
}
static INPUT_PORTS_START(cmi_music_keyboard)
/* Keypad */
PORT_START("KEYPAD_A")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD)
PORT_START("KEYPAD_B")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD)
/* Master musical keyboard */
PORT_START("KEY_0_0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F0")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F0 #")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G0")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G0 #")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A1")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A1 #")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B1")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C1")
PORT_START("KEY_0_1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C1 #")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D1")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D1 #")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E1")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1 #")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G1")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G1 #")
PORT_START("KEY_0_2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2 #")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B2")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2 #")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2 #")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E2")
PORT_START("KEY_0_3")
PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("KEY_1_0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2 #")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2 #")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3 #")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B3")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3")
PORT_START("KEY_1_1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3 #")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3 #")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E3")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3 #")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4")
PORT_START("KEY_1_2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4 #")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4 #")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4 #")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4 #")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E4")
PORT_START("KEY_1_3")
PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("KEY_2_0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4 #")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4 #")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5 #")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B5")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5")
PORT_START("KEY_2_1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5 #")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5 #")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E5")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5 #")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5 #")
PORT_START("KEY_2_2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A6")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A6 #")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B6")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6")
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6 #")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D6")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D6 #")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E6")
PORT_START("KEY_2_3")
PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F6")
PORT_START("ANALOG")
PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_MINMAX(0, 128) PORT_SENSITIVITY(100) PORT_KEYDELTA(50)
INPUT_PORTS_END
ioport_constructor cmi_music_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(cmi_music_keyboard);
}
void cmi_music_keyboard_device::device_add_mconfig(machine_config &config)
{
M6802(config, m_cpu, 4_MHz_XTAL);
m_cpu->set_addrmap(AS_PROGRAM, &cmi_music_keyboard_device::muskeys_map);
PIA6821(config, m_cmi10_pia_u20);
m_cmi10_pia_u20->readcb1_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u20_cb1_r));
m_cmi10_pia_u20->writepa_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u20_a_w));
m_cmi10_pia_u20->writepb_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u20_b_w));
m_cmi10_pia_u20->cb2_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u20_cb2_w));
PIA6821(config, m_cmi10_pia_u21);
m_cmi10_pia_u21->readpa_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u21_a_r));
m_cmi10_pia_u21->cb2_handler().set(FUNC(cmi_music_keyboard_device::cmi10_u21_cb2_w));
clock_device &acia_clock(CLOCK(config, "acia_clock", 1.8432_MHz_XTAL / 12));
acia_clock.signal_handler().set(m_acia_kbd, FUNC(acia6850_device::write_rxc));
acia_clock.signal_handler().append(m_acia_kbd, FUNC(acia6850_device::write_txc));
acia_clock.signal_handler().append(m_acia_cmi, FUNC(acia6850_device::write_rxc));
acia_clock.signal_handler().append(m_acia_cmi, FUNC(acia6850_device::write_txc));
ACIA6850(config, m_acia_cmi);
m_acia_cmi->txd_handler().set(FUNC(cmi_music_keyboard_device::cmi_txd_w));
m_acia_cmi->rts_handler().set(FUNC(cmi_music_keyboard_device::cmi_rts_w));
m_acia_cmi->irq_handler().set(FUNC(cmi_music_keyboard_device::cmi_acia_int));
ACIA6850(config, m_acia_kbd);
m_acia_kbd->txd_handler().set(FUNC(cmi_music_keyboard_device::kbd_txd_w));
m_acia_kbd->rts_handler().set(FUNC(cmi_music_keyboard_device::kbd_rts_w));
m_acia_kbd->irq_handler().set(FUNC(cmi_music_keyboard_device::kbd_acia_int));
/* alpha-numeric display */
DL1416T(config, m_dp1, u32(0));
m_dp1->update().set(FUNC(cmi_music_keyboard_device::update_dp<0>));
DL1416T(config, m_dp2, u32(0));
m_dp2->update().set(FUNC(cmi_music_keyboard_device::update_dp<1>));
DL1416T(config, m_dp3, u32(0));
m_dp3->update().set(FUNC(cmi_music_keyboard_device::update_dp<2>));
}
ROM_START( cmi_mkbd )
// Both of these dumps have been trimmed to size from within a roughly 2x-bigger file.
// The actual size is known based on the format apparently used by the dumping device.
ROM_REGION( 0x10000, "kbdcpu", 0 )
ROM_LOAD( "velkeysd.bin", 0xb000, 0x0400, CRC(9b636781) SHA1(be29a72a1d6d313dafe0b63951b5e3e18ddb9a21) )
ROM_LOAD( "kbdioa.bin", 0xfc00, 0x0400, CRC(a5cbe218) SHA1(bc6784aaa5697c28eab126e20500139b8d0c1f50) )
ROM_END
const tiny_rom_entry *cmi_music_keyboard_device::device_rom_region() const
{
return ROM_NAME(cmi_mkbd);
}