cmi2x: Split off keyboards as subdevices

This commit is contained in:
AJR 2019-04-15 15:36:53 -04:00
parent abe5ff027d
commit 7e623cc886
6 changed files with 897 additions and 616 deletions

View File

@ -2167,6 +2167,10 @@ files {
MAME_DIR .. "src/mame/drivers/cmi.cpp",
MAME_DIR .. "src/mame/audio/cmi01a.cpp",
MAME_DIR .. "src/mame/audio/cmi01a.h",
MAME_DIR .. "src/mame/machine/cmi_ankbd.cpp",
MAME_DIR .. "src/mame/machine/cmi_ankbd.h",
MAME_DIR .. "src/mame/machine/cmi_mkbd.cpp",
MAME_DIR .. "src/mame/machine/cmi_mkbd.h",
}
createMESSProjects(_target, _subtarget, "force")

View File

@ -57,26 +57,6 @@
Slot 19: Floppy Disk Controller QFC-9
Slot 20: Hard Disk Controller Q-077 (Optional)
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.
Q209 Dual 6809 Central Processor Card
-------------------------------------
@ -101,15 +81,15 @@
#include "emu.h"
#include "audio/cmi01a.h"
#include "machine/cmi_ankbd.h"
#include "machine/cmi_mkbd.h"
#include "cpu/m6800/m6800.h"
#include "cpu/m6809/m6809.h"
#include "cpu/m68000/m68000.h"
#include "imagedev/floppy.h"
#include "machine/6821pia.h"
#include "machine/6840ptm.h"
#include "machine/6850acia.h"
#include "machine/7474.h"
#include "machine/clock.h"
#include "machine/i8214.h"
@ -118,8 +98,6 @@
#include "machine/msm5832.h"
#include "machine/wd_fdc.h"
#include "video/dl1416.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
@ -216,8 +194,6 @@ public:
: driver_device(mconfig, type, tag)
, m_maincpu1(*this, "maincpu1")
, m_maincpu2(*this, "maincpu2")
, m_muskeyscpu(*this, "muskeys")
, m_alphakeyscpu(*this, "alphakeys")
, m_midicpu(*this, "smptemidi")
, m_cmi07cpu(*this, "cmi07cpu")
, m_msm5832(*this, "msm5832")
@ -230,30 +206,17 @@ public:
, m_q219_ptm(*this, "q219_ptm")
, m_cmi02_pia(*this, "cmi02_pia_%u", 1U)
, m_cmi02_ptm(*this, "cmi02_ptm")
, m_ank_pia(*this, "ank_pia")
, m_acia_mkbd_kbd(*this, "acia_mkbd_kbd")
, m_acia_mkbd_cmi(*this, "acia_mkbd_cmi")
, m_cmi07_ptm(*this, "cmi07_ptm")
, m_qfc9_region(*this, "qfc9")
, m_floppy0(*this, "wd1791:0")
, m_floppy1(*this, "wd1791:1")
, m_wd1791(*this, "wd1791")
, m_channels(*this, "cmi01a_%u", 0)
, 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_screen(*this, "screen")
, m_palette(*this, "palette")
, m_ankrow_ports(*this, "ROW%u", 0)
, m_lp_x_port(*this, "LP_X")
, m_lp_y_port(*this, "LP_Y")
, m_lp_touch_port(*this, "LP_TOUCH")
, m_keypad_a_port(*this, "KEYPAD_A")
, m_keypad_b_port(*this, "KEYPAD_B")
, 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)
, m_cmi07_ram(*this, "cmi07_ram")
{
}
@ -267,7 +230,6 @@ public:
static const device_timer_id TIMER_MAP_SWITCH = 0;
static const device_timer_id TIMER_HBLANK = 1;
static const device_timer_id TIMER_JAM_TIMEOUT = 2;
static const device_timer_id TIMER_CMI10_SCND = 3;
void init_cmi2x();
@ -334,44 +296,25 @@ public:
DECLARE_WRITE_LINE_MEMBER( cmi02_ptm_irq );
DECLARE_WRITE_LINE_MEMBER( cmi02_ptm_o2 );
// Alphanumeric keyboard
DECLARE_READ8_MEMBER( ank_col_r );
DECLARE_READ_LINE_MEMBER( ank_rts_r );
// ???
DECLARE_READ8_MEMBER( cmi07_r );
DECLARE_WRITE8_MEMBER( cmi07_w );
// Music keyboard/alphanumeric display/keypad
DECLARE_WRITE8_MEMBER( cmi10_u20_a_w );
DECLARE_WRITE8_MEMBER( cmi10_u20_b_w );
DECLARE_READ_LINE_MEMBER( cmi10_u20_cb1_r );
DECLARE_WRITE_LINE_MEMBER( cmi10_u20_cb2_w );
DECLARE_WRITE_LINE_MEMBER( cmi10_u21_cb2_w );
DECLARE_READ8_MEMBER( cmi10_u21_a_r );
template <unsigned N> DECLARE_WRITE16_MEMBER( cmi_iix_update_dp );
DECLARE_WRITE_LINE_MEMBER( msm5832_irq );
DECLARE_WRITE_LINE_MEMBER( mkbd_kbd_acia_int );
DECLARE_WRITE_LINE_MEMBER( mkbd_cmi_acia_int );
DECLARE_WRITE_LINE_MEMBER( cmi07_irq );
DECLARE_WRITE_LINE_MEMBER( mkbd_acia_clock );
DECLARE_WRITE_LINE_MEMBER( q133_acia_clock );
template<int Channel> DECLARE_WRITE_LINE_MEMBER( channel_irq );
void cmi2x(machine_config &config);
void alphakeys_map(address_map &map);
void cmi07cpu_map(address_map &map);
void maincpu1_map(address_map &map);
void maincpu2_map(address_map &map);
void midicpu_map(address_map &map);
void muskeys_map(address_map &map);
protected:
required_device<mc6809e_device> m_maincpu1;
required_device<mc6809e_device> m_maincpu2;
required_device<m6802_cpu_device> m_muskeyscpu;
required_device<m6802_cpu_device> m_alphakeyscpu;
required_device<m68000_device> m_midicpu;
required_device<mc6809e_device> m_cmi07cpu;
@ -388,10 +331,6 @@ protected:
required_device_array<pia6821_device, 2> m_cmi02_pia;
required_device<ptm6840_device> m_cmi02_ptm;
required_device<pia6821_device> m_ank_pia;
required_device<acia6850_device> m_acia_mkbd_kbd;
required_device<acia6850_device> m_acia_mkbd_cmi;
required_device<ptm6840_device> m_cmi07_ptm;
required_memory_region m_qfc9_region;
@ -401,38 +340,21 @@ protected:
required_device_array<cmi01a_device, 8> m_channels;
required_device<pia6821_device> m_cmi10_pia_u20;
required_device<pia6821_device> m_cmi10_pia_u21;
required_device<dl1416_device> m_dp1;
required_device<dl1416_device> m_dp2;
required_device<dl1416_device> m_dp3;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_ioport_array<8> m_ankrow_ports;
required_ioport m_lp_x_port;
required_ioport m_lp_y_port;
required_ioport m_lp_touch_port;
required_ioport m_keypad_a_port;
required_ioport m_keypad_b_port;
required_ioport_array<3> m_key_mux_ports[4];
output_finder<12> m_digit;
required_shared_ptr<uint8_t> m_cmi07_ram;
address_space *m_cpu1space;
address_space *m_cpu2space;
private:
emu_timer *m_map_switch_timer;
emu_timer *m_hblank_timer;
emu_timer *m_cmi10_scnd_timer;
emu_timer *m_jam_timeout_timer;
uint8_t m_video_data;
@ -491,13 +413,7 @@ private:
/* CMI-07 */
uint8_t m_cmi07_ctrl;
/* CMI-10 */
uint8_t m_scnd;
/* Musical keyboard */
uint8_t m_msm5832_addr;
int m_mkbd_kbd_acia_irq;
int m_mkbd_cmi_acia_irq;
// Master card (CMI-02)
int m_cmi02_ptm_irq;
@ -778,12 +694,6 @@ void cmi_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo
m_maincpu2->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
m_jam_timeout_timer->adjust(attotime::never);
break;
case TIMER_CMI10_SCND:
m_cmi10_pia_u20->ca1_w(m_scnd);
m_scnd ^= 1;
m_cmi10_pia_u21->ca1_w(m_scnd);
break;
}
}
@ -871,28 +781,6 @@ void cmi_state::maincpu2_map(address_map &map)
map(0xfffe, 0xffff).r(FUNC(cmi_state::vector_r<1>));
}
void cmi_state::muskeys_map(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x007f).ram();
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_mkbd_kbd, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0x00b0, 0x00b1).rw(m_acia_mkbd_cmi, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0x4000, 0x47ff).ram();
map(0xb000, 0xb400).rom();
map(0xf000, 0xffff).rom();
}
void cmi_state::alphakeys_map(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x007f).ram();
map(0x4000, 0x7fff).portr("ANK_OPTIONS");
map(0x8000, 0xbfff).rw(m_ank_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xc000, 0xc3ff).rom().mirror(0x3c00);
}
void cmi_state::midicpu_map(address_map &map)
{
map(0x000000, 0x003fff).rom();
@ -921,225 +809,6 @@ static INPUT_PORTS_START( cmi2x )
PORT_START("LP_TOUCH")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME ( "Lightpen Touch" ) PORT_CODE( MOUSECODE_BUTTON1 )
/* Alphanumeric keyboard */
PORT_START("ANK_OPTIONS")
PORT_DIPNAME( 0x07, 0x00, "Speed (baud)" )
PORT_DIPSETTING( 0x00, "9600" )
PORT_DIPSETTING( 0x01, "4800" )
PORT_DIPSETTING( 0x02, "2400" )
PORT_DIPSETTING( 0x03, "1200" )
PORT_DIPSETTING( 0x04, "600" )
PORT_DIPSETTING( 0x05, "300" )
PORT_DIPSETTING( 0x06, "150" )
PORT_DIPSETTING( 0x07, "110" )
PORT_DIPNAME( 0x30, 0x20, "Parity" )
PORT_DIPSETTING( 0x00, "Even" )
PORT_DIPSETTING( 0x10, "None, bit 7 is 0" )
PORT_DIPSETTING( 0x20, "Odd" )
PORT_DIPSETTING( 0x30, "None, bit 7 is 1" )
PORT_START("ROW0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+')
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9')
PORT_START("ROW1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
PORT_START("ROW2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Set")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Add")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
PORT_START("ROW3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("LShift")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Clear")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("WTF")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
PORT_START("ROW4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=')
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Home")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
PORT_START("ROW5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return (a)")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return (b)")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
PORT_START("ROW6")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('S')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sub")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("RShift")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.')
PORT_START("ROW7")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')
/* 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")
INPUT_PORTS_END
bool cmi_state::map_is_active(int cpunum, int map, uint8_t *map_info)
@ -1253,24 +922,6 @@ WRITE_LINE_MEMBER( cmi_state::q133_acia_irq )
set_interrupt(CPU_1, IRQ_ACINT_LEVEL, state ? ASSERT_LINE : CLEAR_LINE);
}
READ8_MEMBER( cmi_state::ank_col_r )
{
int row = m_ank_pia->b_output() ^ 0xff;
switch (row)
{
case 0x01: return m_ankrow_ports[0]->read();
case 0x02: return m_ankrow_ports[1]->read();
case 0x04: return m_ankrow_ports[2]->read();
case 0x08: return m_ankrow_ports[3]->read();
case 0x10: return m_ankrow_ports[4]->read();
case 0x20: return m_ankrow_ports[5]->read();
case 0x40: return m_ankrow_ports[6]->read();
case 0x80: return m_ankrow_ports[7]->read();
default: return 0xff;
}
}
/**************************************
*
@ -1647,12 +1298,6 @@ WRITE8_MEMBER( cmi_state::shared_ram_w )
m_shared_ram[offset] = data;
}
READ_LINE_MEMBER( cmi_state::ank_rts_r )
{
// printf("ANK RTS?\n");
return 0;
}
void cmi_state::install_peripherals(int cpunum)
{
address_space *space = (cpunum == CPU_1 ? m_cpu1space : m_cpu2space);
@ -1849,169 +1494,17 @@ WRITE8_MEMBER( cmi_state::q133_1_portb_w )
m_msm5832->write_w(BIT(data, 2));
}
/*
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
*/
WRITE8_MEMBER( cmi_state::cmi10_u20_a_w )
{
// 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);
*/
}
WRITE8_MEMBER( cmi_state::cmi10_u20_b_w )
{
// connected to alphanumeric display control lines
uint8_t const addr = bitswap<2>(data, 0, 1);
m_dp1->ce_w(BIT(data, 6));
m_dp1->cu_w(BIT(data, 7));
m_dp1->addr_w(addr);
m_dp2->ce_w(BIT(data, 4));
m_dp2->cu_w(BIT(data, 5));
m_dp2->addr_w(addr);
m_dp3->ce_w(BIT(data, 2));
m_dp3->cu_w(BIT(data, 3));
m_dp3->addr_w(addr);
}
READ_LINE_MEMBER( cmi_state::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_state::cmi10_u20_cb2_w )
{
// connected to alphanumeric display write strobe
m_dp1->wr_w(state);
m_dp2->wr_w(state);
m_dp3->wr_w(state);
}
template <unsigned N> WRITE16_MEMBER( cmi_state::cmi_iix_update_dp )
{
m_digit[(N << 2) | ((offset ^ 3) & 3)] = data;
}
/* Begin Conversion */
WRITE_LINE_MEMBER( cmi_state::cmi10_u21_cb2_w )
{
// if 0
// state = state;
}
READ8_MEMBER( cmi_state::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;
uint8_t data = 0x38; // slave keyboard not used
for (int module = 0; module < 3; ++module)
{
// char keyname[16];
uint8_t keyval;
int state = 1;
if (mux == 0 && key == 3)
{
//keyval = input_port_read(device->machine, "ANALOG");
/* 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;
uint8_t data = 0xf8; // slave keyboard not used
for (int module = 0; module < 3; ++module)
{
uint8_t keyval = m_key_mux_ports[mux][module]->read();
data |= BIT(keyval, key) << module;
}
return data;
#endif
}
/*************************************
*
* 6850 ACIAs
* 6551 ACIAs
*
*************************************/
//static int kbd_to_cmi;
//static int cmi_to_kbd;
WRITE_LINE_MEMBER( cmi_state::mkbd_acia_clock )
WRITE_LINE_MEMBER( cmi_state::q133_acia_clock )
{
m_acia_mkbd_kbd->write_rxc(state);
m_acia_mkbd_kbd->write_txc(state);
m_acia_mkbd_cmi->write_rxc(state);
m_acia_mkbd_cmi->write_txc(state);
for (auto &acia : m_q133_acia)
acia->write_rxc(state);
}
@ -2023,30 +1516,6 @@ WRITE_LINE_MEMBER( cmi_state::msm5832_irq )
#endif
}
WRITE_LINE_MEMBER( cmi_state::mkbd_kbd_acia_int )
{
m_mkbd_kbd_acia_irq = state;
if (m_mkbd_kbd_acia_irq)
{
m_muskeyscpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
}
else if (!m_mkbd_cmi_acia_irq)
{
m_muskeyscpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER( cmi_state::mkbd_cmi_acia_int )
{
m_mkbd_cmi_acia_irq = state;
if (m_mkbd_cmi_acia_irq)
m_muskeyscpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
else if (!m_mkbd_kbd_acia_irq)
m_muskeyscpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
WRITE_LINE_MEMBER( cmi_state::cmi07_irq )
{
m_cmi07cpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE);
@ -2069,8 +1538,6 @@ void cmi_state::machine_reset()
m_hblank_timer->adjust(m_screen->time_until_pos(0, HBLANK_START));
m_scnd = 0;
for (int cpunum = 0; cpunum < 2; ++cpunum)
{
address_space *space = (cpunum == CPU_1 ? m_cpu1space : m_cpu2space);
@ -2093,9 +1560,6 @@ void cmi_state::machine_reset()
m_cmi07_ctrl = 0;
m_cmi07cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
m_cmi10_scnd_timer->adjust(attotime::from_hz(4000000 / 4 / 2048 / 2), 0, attotime::from_hz(4000000 / 4 / 2048 / 2));
m_scnd = 0;
m_cmi02_ptm_irq = 0;
m_m6809_bs_hack_cnt = 0;
m_m6809_bs_hack_cpu = 0;
@ -2103,19 +1567,15 @@ void cmi_state::machine_reset()
void cmi_state::machine_start()
{
m_digit.resolve();
m_q133_rom = (uint8_t *)m_q133_region->base();
// allocate timers for the built-in two channel timer
m_map_switch_timer = timer_alloc(TIMER_MAP_SWITCH);
m_hblank_timer = timer_alloc(TIMER_HBLANK);
m_cmi10_scnd_timer = timer_alloc(TIMER_CMI10_SCND);
m_jam_timeout_timer = timer_alloc(TIMER_JAM_TIMEOUT);
m_map_switch_timer->adjust(attotime::never);
m_hblank_timer->adjust(attotime::never);
m_cmi10_scnd_timer->adjust(attotime::never);
m_jam_timeout_timer->adjust(attotime::never);
/* Allocate 1kB memory mapping RAM */
@ -2170,27 +1630,12 @@ void cmi_state::cmi2x(machine_config &config)
m_maincpu2->set_irq_acknowledge_callback(FUNC(cmi_state::cpu2_interrupt_callback));
config.m_perfect_cpu_quantum = subtag("maincpu2");
M6802(config, m_muskeyscpu, 4_MHz_XTAL);
m_muskeyscpu->set_addrmap(AS_PROGRAM, &cmi_state::muskeys_map);
M6802(config, m_alphakeyscpu, 3.84_MHz_XTAL);
m_alphakeyscpu->set_addrmap(AS_PROGRAM, &cmi_state::alphakeys_map);
m_alphakeyscpu->set_periodic_int(FUNC(cmi_state::irq0_line_hold), attotime::from_hz(3.84_MHz_XTAL / 400)); // TODO: PIA controls this
M68000(config, m_midicpu, 20_MHz_XTAL / 2);
m_midicpu->set_addrmap(AS_PROGRAM, &cmi_state::midicpu_map);
MC6809E(config, m_cmi07cpu, Q209_CPU_CLOCK); // ?
m_cmi07cpu->set_addrmap(AS_PROGRAM, &cmi_state::cmi07cpu_map);
/* alpha-numeric display */
DL1416T(config, m_dp1, u32(0));
m_dp1->update().set(FUNC(cmi_state::cmi_iix_update_dp<0>));
DL1416T(config, m_dp2, u32(0));
m_dp2->update().set(FUNC(cmi_state::cmi_iix_update_dp<1>));
DL1416T(config, m_dp3, u32(0));
m_dp3->update().set(FUNC(cmi_state::cmi_iix_update_dp<2>));
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER, rgb_t::green());
m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBLANK_END, HBLANK_START, VTOTAL, VBLANK_END, VBLANK_START);
@ -2209,17 +1654,17 @@ void cmi_state::cmi2x(machine_config &config)
m_i8214[2]->int_wr_callback().set(FUNC(cmi_state::i8214_3_int_w));
m_i8214[2]->enlg_wr_callback().set(FUNC(cmi_state::i8214_3_enlg));
PIA6821(config, m_q133_pia[0], 0); // pia_q133_1_config
PIA6821(config, m_q133_pia[0]); // pia_q133_1_config
m_q133_pia[0]->readpa_handler().set(FUNC(cmi_state::q133_1_porta_r));
m_q133_pia[0]->writepa_handler().set(FUNC(cmi_state::q133_1_porta_w));
m_q133_pia[0]->writepb_handler().set(FUNC(cmi_state::q133_1_portb_w));
PIA6821(config, m_q133_pia[1], 0); // pia_q133_2_config
PIA6821(config, m_q133_pia[1]); // pia_q133_2_config
PTM6840(config, m_q133_ptm, 2000000); // ptm_q133_config
m_q133_ptm->set_external_clocks(1024, 1, 111); // Third is todo
PIA6821(config, m_q219_pia, 0); // pia_q219_config
PIA6821(config, m_q219_pia); // pia_q219_config
m_q219_pia->readpb_handler().set(FUNC(cmi_state::pia_q219_b_r));
m_q219_pia->writepa_handler().set(FUNC(cmi_state::vscroll_w));
m_q219_pia->writepb_handler().set(FUNC(cmi_state::video_attr_w));
@ -2230,17 +1675,17 @@ void cmi_state::cmi2x(machine_config &config)
m_q219_ptm->set_external_clocks(HBLANK_FREQ.dvalue(), VBLANK_FREQ.dvalue(), 1'000'000); // TODO: does the third thing come from a crystal?
m_q219_ptm->irq_callback().set(FUNC(cmi_state::ptm_q219_irq));
PIA6821(config, m_cmi02_pia[0], 0); // pia_cmi02_1_config
PIA6821(config, m_cmi02_pia[0]); // pia_cmi02_1_config
m_cmi02_pia[0]->writepb_handler().set(FUNC(cmi_state::master_tune_w));
PIA6821(config, m_cmi02_pia[1], 0); // pia_cmi02_2_config
PIA6821(config, m_cmi02_pia[1]); // pia_cmi02_2_config
PTM6840(config, m_cmi02_ptm, 2000000); // ptm_cmi02_config TODO
m_cmi02_ptm->o2_callback().set(FUNC(cmi_state::cmi02_ptm_o2));
m_cmi02_ptm->irq_callback().set(FUNC(cmi_state::cmi02_ptm_irq));
clock_device &mkbd_acia_clock(CLOCK(config, "mkbd_acia_clock", 1.8432_MHz_XTAL / 12));
mkbd_acia_clock.signal_handler().set(FUNC(cmi_state::mkbd_acia_clock));
clock_device &q133_acia_clock(CLOCK(config, "q133_acia_clock", 1.8432_MHz_XTAL / 12));
q133_acia_clock.signal_handler().set(FUNC(cmi_state::q133_acia_clock));
for (auto &acia : m_q133_acia)
MOS6551(config, acia, 1.8432_MHz_XTAL).set_xtal(1.8432_MHz_XTAL);
@ -2251,32 +1696,20 @@ void cmi_state::cmi2x(machine_config &config)
INPUT_MERGER_ANY_HIGH(config, "q133_acia_irq").output_handler().set(FUNC(cmi_state::q133_acia_irq));
ACIA6850(config, m_acia_mkbd_kbd, 1.8432_MHz_XTAL / 12); // acia_mkbd_kbd
ACIA6850(config, m_acia_mkbd_cmi, 1.8432_MHz_XTAL / 12); // acia_mkbd_cmi
PIA6821(config, m_ank_pia, 0); // pia_ank_config
m_q133_acia[0]->txd_handler().set("mkbd", FUNC(cmi_music_keyboard_device::cmi_rxd_w));
m_q133_acia[0]->rts_handler().set("mkbd", FUNC(cmi_music_keyboard_device::cmi_cts_w));
m_q133_acia[0]->txd_handler().set(m_acia_mkbd_cmi, FUNC(acia6850_device::write_rxd));
m_q133_acia[0]->rts_handler().set(m_acia_mkbd_cmi, FUNC(acia6850_device::write_cts));
// Musical keyboard
cmi_music_keyboard_device &mkbd(CMI_MUSIC_KEYBOARD(config, "mkbd"));
mkbd.cmi_txd_handler().set(m_q133_acia[0], FUNC(mos6551_device::write_rxd));
mkbd.cmi_rts_handler().set(m_q133_acia[0], FUNC(mos6551_device::write_cts));
mkbd.kbd_txd_handler().set("alphakeys", FUNC(cmi_alphanumeric_keyboard_device::rxd_w));
mkbd.kbd_rts_handler().set("alphakeys", FUNC(cmi_alphanumeric_keyboard_device::cts_w));
m_acia_mkbd_cmi->txd_handler().set("q133_acia_0", FUNC(mos6551_device::write_rxd));
m_acia_mkbd_cmi->rts_handler().set("q133_acia_0", FUNC(mos6551_device::write_cts));
m_acia_mkbd_cmi->irq_handler().set(FUNC(cmi_state::mkbd_cmi_acia_int));
m_acia_mkbd_kbd->txd_handler().set("ank_pia", FUNC(pia6821_device::cb2_w));
m_acia_mkbd_kbd->rts_handler().set("ank_pia", FUNC(pia6821_device::ca2_w));
m_acia_mkbd_kbd->irq_handler().set(FUNC(cmi_state::mkbd_kbd_acia_int));
INPUT_MERGER_ANY_HIGH(config, "irqs").output_handler().set_inputline(m_alphakeyscpu, M6802_IRQ_LINE);
m_ank_pia->readpa_handler().set(FUNC(cmi_state::ank_col_r));
m_ank_pia->readcb1_handler().set(FUNC(cmi_state::ank_rts_r));
m_ank_pia->ca2_handler().set("acia_mkbd_kbd", FUNC(acia6850_device::write_cts));
m_ank_pia->cb2_handler().set("acia_mkbd_kbd", FUNC(acia6850_device::write_rxd));
m_ank_pia->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<0>));
m_ank_pia->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<1>));
clock_device &ank_pia_clock(CLOCK(config, "ank_pia_clock", 9600));
ank_pia_clock.signal_handler().set(m_ank_pia, FUNC(pia6821_device::ca1_w));
// Alphanumeric keyboard
cmi_alphanumeric_keyboard_device &alphakeys(CMI_ALPHANUMERIC_KEYBOARD(config, "alphakeys"));
alphakeys.txd_handler().set("mkbd", FUNC(cmi_music_keyboard_device::kbd_rxd_w));
alphakeys.rts_handler().set("mkbd", FUNC(cmi_music_keyboard_device::kbd_cts_w));
PTM6840(config, m_cmi07_ptm, 2000000); // ptm_cmi07_config TODO
m_cmi07_ptm->irq_callback().set(FUNC(cmi_state::cmi07_irq));
@ -2287,17 +1720,6 @@ void cmi_state::cmi2x(machine_config &config)
FLOPPY_CONNECTOR(config, "wd1791:0", cmi2x_floppies, "8dsdd", floppy_image_device::default_floppy_formats);
FLOPPY_CONNECTOR(config, "wd1791:1", cmi2x_floppies, "8dsdd", floppy_image_device::default_floppy_formats);
/* Musical keyboard */
PIA6821(config, m_cmi10_pia_u20, 0);
m_cmi10_pia_u20->readcb1_handler().set(FUNC(cmi_state::cmi10_u20_cb1_r));
m_cmi10_pia_u20->writepa_handler().set(FUNC(cmi_state::cmi10_u20_a_w));
m_cmi10_pia_u20->writepb_handler().set(FUNC(cmi_state::cmi10_u20_b_w));
m_cmi10_pia_u20->cb2_handler().set(FUNC(cmi_state::cmi10_u20_cb2_w));
PIA6821(config, m_cmi10_pia_u21, 0);
m_cmi10_pia_u21->readpa_handler().set(FUNC(cmi_state::cmi10_u21_a_r));
m_cmi10_pia_u21->cb2_handler().set(FUNC(cmi_state::cmi10_u21_cb2_w));
SPEAKER(config, "mono").front_center();
// Channel cards
@ -2350,20 +1772,6 @@ ROM_START( cmi2x )
ROM_REGION( 0x800, "qfc9", 0 )
ROM_LOAD( "dqfc911.bin", 0x00, 0x800, CRC(5bc38db2) SHA1(bd840e19e51a336e669c40b9e18cdaf6b3c62a8a) )
/* Musical keyboard CPU */
// 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, shared with the prom
// dumps and cmikeys4.bin dump.
ROM_REGION( 0x10000, "muskeys", 0 )
ROM_LOAD( "velkeysd.bin", 0xb000, 0x0400, CRC(9b636781) SHA1(be29a72a1d6d313dafe0b63951b5e3e18ddb9a21) )
ROM_LOAD( "kbdioa.bin", 0xfc00, 0x0400, CRC(a5cbe218) SHA1(bc6784aaa5697c28eab126e20500139b8d0c1f50) )
/* Alphanumeric keyboard CPU */
// This dump has 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, shared with the prom dumps and music keys dump.
ROM_REGION( 0x10000, "alphakeys", 0 )
ROM_LOAD( "cmikeys4.bin", 0xc000, 0x400, CRC(b214fbe9) SHA1(8c404f58ba3e5a50aa42f761e966c74374e96cc9) )
// All of these PROM dumps have been trimmed to size from within a roughly 2x-bigger file.
// The actual sizes are known from the schematics and the starting address of the actual PROM data was obvious
// based on repeated data in some of the 256x4 PROMs, but it would be nice to get redumps, in the extremely

View File

@ -0,0 +1,225 @@
// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Fairlight CMI Alphanumeric Keyboard
***************************************************************************/
#include "emu.h"
#include "cmi_ankbd.h"
#include "cpu/m6800/m6800.h"
#include "machine/clock.h"
#include "machine/input_merger.h"
DEFINE_DEVICE_TYPE(CMI_ALPHANUMERIC_KEYBOARD, cmi_alphanumeric_keyboard_device, "cmi_ankbd", "Fairlight CMI Alphanumeric Keyboard")
cmi_alphanumeric_keyboard_device::cmi_alphanumeric_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, CMI_ALPHANUMERIC_KEYBOARD, tag, owner, clock)
, m_txd_handler(*this)
, m_rts_handler(*this)
, m_kbdcpu(*this, "kbdcpu")
, m_pia(*this, "pia")
, m_row_ports(*this, "ROW%u", 0)
{
}
void cmi_alphanumeric_keyboard_device::device_resolve_objects()
{
m_txd_handler.resolve_safe();
m_rts_handler.resolve_safe();
}
void cmi_alphanumeric_keyboard_device::device_start()
{
}
READ8_MEMBER( cmi_alphanumeric_keyboard_device::col_r )
{
int row = m_pia->b_output() ^ 0xff;
switch (row)
{
case 0x01: return m_row_ports[0]->read();
case 0x02: return m_row_ports[1]->read();
case 0x04: return m_row_ports[2]->read();
case 0x08: return m_row_ports[3]->read();
case 0x10: return m_row_ports[4]->read();
case 0x20: return m_row_ports[5]->read();
case 0x40: return m_row_ports[6]->read();
case 0x80: return m_row_ports[7]->read();
default: return 0xff;
}
}
READ_LINE_MEMBER( cmi_alphanumeric_keyboard_device::rts_r )
{
// printf("ANK RTS?\n");
return 0;
}
WRITE_LINE_MEMBER( cmi_alphanumeric_keyboard_device::rxd_w )
{
m_pia->cb2_w(state);
}
WRITE_LINE_MEMBER( cmi_alphanumeric_keyboard_device::cts_w )
{
m_pia->ca2_w(state);
}
WRITE_LINE_MEMBER( cmi_alphanumeric_keyboard_device::txd_w )
{
m_txd_handler(state);
}
WRITE_LINE_MEMBER( cmi_alphanumeric_keyboard_device::rts_w )
{
m_rts_handler(state);
}
void cmi_alphanumeric_keyboard_device::alphakeys_map(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x007f).ram();
map(0x4000, 0x7fff).portr("OPTIONS");
map(0x8000, 0xbfff).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0xc000, 0xc3ff).rom().mirror(0x3c00);
}
static INPUT_PORTS_START( cmi_alphanumeric_keyboard )
/* Alphanumeric keyboard */
PORT_START("OPTIONS")
PORT_DIPNAME( 0x07, 0x00, "Speed (baud)" )
PORT_DIPSETTING( 0x00, "9600" )
PORT_DIPSETTING( 0x01, "4800" )
PORT_DIPSETTING( 0x02, "2400" )
PORT_DIPSETTING( 0x03, "1200" )
PORT_DIPSETTING( 0x04, "600" )
PORT_DIPSETTING( 0x05, "300" )
PORT_DIPSETTING( 0x06, "150" )
PORT_DIPSETTING( 0x07, "110" )
PORT_DIPNAME( 0x30, 0x20, "Parity" )
PORT_DIPSETTING( 0x00, "Even" )
PORT_DIPSETTING( 0x10, "None, bit 7 is 0" )
PORT_DIPSETTING( 0x20, "Odd" )
PORT_DIPSETTING( 0x30, "None, bit 7 is 1" )
PORT_START("ROW0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+')
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9')
PORT_START("ROW1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
PORT_START("ROW2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Set")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Add")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
PORT_START("ROW3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("LShift")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Clear")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("WTF")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
PORT_START("ROW4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=')
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Home")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
PORT_START("ROW5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return (a)")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return (b)")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
PORT_START("ROW6")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('S')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sub")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("RShift")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.')
PORT_START("ROW7")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left")
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')
INPUT_PORTS_END
ioport_constructor cmi_alphanumeric_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(cmi_alphanumeric_keyboard);
}
void cmi_alphanumeric_keyboard_device::device_add_mconfig(machine_config &config)
{
M6802(config, m_kbdcpu, 3.84_MHz_XTAL);
m_kbdcpu->set_addrmap(AS_PROGRAM, &cmi_alphanumeric_keyboard_device::alphakeys_map);
INPUT_MERGER_ANY_HIGH(config, "irqs").output_handler().set_inputline(m_kbdcpu, M6802_IRQ_LINE);
PIA6821(config, m_pia); // pia_config
m_pia->readpa_handler().set(FUNC(cmi_alphanumeric_keyboard_device::col_r));
m_pia->readcb1_handler().set(FUNC(cmi_alphanumeric_keyboard_device::rts_r));
m_pia->ca2_handler().set(FUNC(cmi_alphanumeric_keyboard_device::rts_w));
m_pia->cb2_handler().set(FUNC(cmi_alphanumeric_keyboard_device::txd_w));
m_pia->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<0>));
m_pia->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<1>));
clock_device &pia_clock(CLOCK(config, "pia_clock", 3.84_MHz_XTAL / 400));
pia_clock.signal_handler().set(m_pia, FUNC(pia6821_device::ca1_w));
}
ROM_START( cmi_ankbd )
// This dump has 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( "cmikeys4.bin", 0xc000, 0x400, CRC(b214fbe9) SHA1(8c404f58ba3e5a50aa42f761e966c74374e96cc9) )
ROM_END
const tiny_rom_entry *cmi_alphanumeric_keyboard_device::device_rom_region() const
{
return ROM_NAME(cmi_ankbd);
}

View File

@ -0,0 +1,53 @@
// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Fairlight CMI Alphanumeric Keyboard
***************************************************************************/
#ifndef MAME_MACHINE_CMI_ANKBD_H
#define MAME_MACHINE_CMI_ANKBD_H 1
#pragma once
#include "machine/6821pia.h"
class cmi_alphanumeric_keyboard_device : public device_t
{
public:
cmi_alphanumeric_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
auto txd_handler() { return m_txd_handler.bind(); }
auto rts_handler() { return m_rts_handler.bind(); }
DECLARE_WRITE_LINE_MEMBER( rxd_w );
DECLARE_WRITE_LINE_MEMBER( cts_w );
protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_resolve_objects() override;
virtual void device_start() override;
private:
DECLARE_READ8_MEMBER( col_r );
DECLARE_READ_LINE_MEMBER( rts_r );
DECLARE_WRITE_LINE_MEMBER( txd_w );
DECLARE_WRITE_LINE_MEMBER( rts_w );
void alphakeys_map(address_map &map);
devcb_write_line m_txd_handler;
devcb_write_line m_rts_handler;
required_device<cpu_device> m_kbdcpu;
required_device<pia6821_device> m_pia;
required_ioport_array<8> m_row_ports;
};
DECLARE_DEVICE_TYPE(CMI_ALPHANUMERIC_KEYBOARD, cmi_alphanumeric_keyboard_device)
#endif // MAME_MACHINE_CMI_ANKBD_H

View File

@ -0,0 +1,497 @@
// 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_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
*/
WRITE8_MEMBER( cmi_music_keyboard_device::cmi10_u20_a_w )
{
// 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);
*/
}
WRITE8_MEMBER( cmi_music_keyboard_device::cmi10_u20_b_w )
{
// connected to alphanumeric display control lines
u8 const addr = bitswap<2>(data, 0, 1);
m_dp1->ce_w(BIT(data, 6));
m_dp1->cu_w(BIT(data, 7));
m_dp1->addr_w(addr);
m_dp2->ce_w(BIT(data, 4));
m_dp2->cu_w(BIT(data, 5));
m_dp2->addr_w(addr);
m_dp3->ce_w(BIT(data, 2));
m_dp3->cu_w(BIT(data, 3));
m_dp3->addr_w(addr);
}
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 )
{
// connected to alphanumeric display write strobe
m_dp1->wr_w(state);
m_dp2->wr_w(state);
m_dp3->wr_w(state);
}
template <unsigned N> WRITE16_MEMBER( cmi_music_keyboard_device::update_dp )
{
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;
}
READ8_MEMBER( 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 (mux == 0 && key == 3)
{
//keyval = input_port_read(device->machine, "ANALOG");
/* 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;
}
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(0x0000, 0x007f).ram();
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")
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);
}

View File

@ -0,0 +1,94 @@
// license:BSD-3-Clause
// copyright-holders:Phil Bennett
/***************************************************************************
Fairlight CMI Music Keyboard
***************************************************************************/
#ifndef MAME_MACHINE_CMI_MKBD_H
#define MAME_MACHINE_CMI_MKBD_H 1
#pragma once
#include "machine/6821pia.h"
#include "machine/6850acia.h"
#include "video/dl1416.h"
class cmi_music_keyboard_device : public device_t
{
static const device_timer_id TIMER_CMI10_SCND = 0;
public:
cmi_music_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
auto cmi_txd_handler() { return m_cmi_txd.bind(); }
auto cmi_rts_handler() { return m_cmi_rts.bind(); }
auto kbd_txd_handler() { return m_kbd_txd.bind(); }
auto kbd_rts_handler() { return m_kbd_rts.bind(); }
DECLARE_WRITE_LINE_MEMBER( cmi_rxd_w );
DECLARE_WRITE_LINE_MEMBER( cmi_cts_w );
DECLARE_WRITE_LINE_MEMBER( kbd_rxd_w );
DECLARE_WRITE_LINE_MEMBER( kbd_cts_w );
protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
DECLARE_WRITE8_MEMBER( cmi10_u20_a_w );
DECLARE_WRITE8_MEMBER( cmi10_u20_b_w );
DECLARE_READ_LINE_MEMBER( cmi10_u20_cb1_r );
DECLARE_WRITE_LINE_MEMBER( cmi10_u20_cb2_w );
DECLARE_WRITE_LINE_MEMBER( cmi10_u21_cb2_w );
DECLARE_READ8_MEMBER( cmi10_u21_a_r );
DECLARE_WRITE_LINE_MEMBER( kbd_acia_int );
DECLARE_WRITE_LINE_MEMBER( cmi_acia_int );
DECLARE_WRITE_LINE_MEMBER( cmi_txd_w );
DECLARE_WRITE_LINE_MEMBER( cmi_rts_w );
DECLARE_WRITE_LINE_MEMBER( kbd_txd_w );
DECLARE_WRITE_LINE_MEMBER( kbd_rts_w );
template <unsigned N> DECLARE_WRITE16_MEMBER( update_dp );
void muskeys_map(address_map &map);
devcb_write_line m_cmi_txd;
devcb_write_line m_cmi_rts;
devcb_write_line m_kbd_txd;
devcb_write_line m_kbd_rts;
required_device<cpu_device> m_cpu;
required_device<acia6850_device> m_acia_kbd;
required_device<acia6850_device> m_acia_cmi;
required_device<pia6821_device> m_cmi10_pia_u20;
required_device<pia6821_device> m_cmi10_pia_u21;
required_device<dl1416_device> m_dp1;
required_device<dl1416_device> m_dp2;
required_device<dl1416_device> m_dp3;
required_ioport m_keypad_a_port;
required_ioport m_keypad_b_port;
required_ioport_array<3> m_key_mux_ports[4];
output_finder<12> m_digit;
emu_timer *m_cmi10_scnd_timer;
int m_kbd_acia_irq;
int m_cmi_acia_irq;
u8 m_scnd;
};
DECLARE_DEVICE_TYPE(CMI_MUSIC_KEYBOARD, cmi_music_keyboard_device)
#endif // MAME_MACHINE_CMI_MKBD_H