/***********************************************************************************************************


 Mattel Intellivision Entertainment Computer System expansion emulation

 TODO:
   - Make paged rom emulation more accurate (according to
   http://spatula-city.org/~im14u2c/intv/tech/ecs.html
   writes to $xa5y should be available for every x and every y, i.e. we shall
   have writes to every 4K chunk of the memory map, and there shall be 16 pages
   for each)
   Current emulation is instead tailored around the minimal usage necessary to
   make the main expansion and World Series Major League Baseball happy

 ***********************************************************************************************************/


#include "emu.h"
#include "ecs.h"


//-------------------------------------------------
//  intv_ecs_device - constructor
//-------------------------------------------------

const device_type INTV_ROM_ECS = &device_creator<intv_ecs_device>;

intv_ecs_device::intv_ecs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
					: intv_rom_device(mconfig, INTV_ROM_ECS, "Intellivision ECS Expansion", tag, owner, clock, "intv_ecs", __FILE__),
					m_snd(*this, "ay8914"),
					m_subslot(*this, "subslot"),
					m_keybd(*this, "ROW"),
					m_synth(*this, "SYNTH"),
					m_cntrlsel(*this, "CNTRLSEL"),
					m_options(*this, "OPTIONS"),
					m_keypad(*this, "KEYPAD"),
					m_disc(*this, "DISC"),
					m_discx(*this, "DISCX"),
					m_discy(*this, "DISCY"),
					m_psg_porta(0),
					m_voice_enabled(false),
					m_ramd0_enabled(false),
					m_ram88_enabled(false)
{
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void intv_ecs_device::device_start()
{
	// if the ECS is mounted directly in the system, use device rom and alloc RAM
	if (m_rom == NULL)
	{
		astring region_tag;
		m_rom = memregion(region_tag.cpy(tag()).cat(":ecs"))->base();
	}
	if (!m_ram.count())
	{
		m_ram.resize(0x800);
	}

	save_item(NAME(m_bank_base));
	save_item(NAME(m_psg_porta));
}

void intv_ecs_device::device_reset()
{
	memset(m_bank_base, 0, sizeof(m_bank_base));
}

void intv_ecs_device::late_subslot_setup()
{
	switch (m_subslot->get_type())
	{
		case INTV_RAM:
			m_ramd0_enabled = true;
			break;
		case INTV_GFACT:
			m_ram88_enabled = true;
			break;
		case INTV_VOICE:
			m_voice_enabled = true;
			m_subslot->late_subslot_setup();
			break;
		case INTV_ECS:
			printf("WARNING: You cannot connect serially multiple ECS units.\n");
			printf("WARNING: Emulation will likely misbehave.\n");
			break;
		case INTV_KEYCOMP:
			printf("WARNING: You cannot connect the Keyboard component to the ECS unit.\n");
			printf("WARNING: Emulation will likely misbehave.\n");
			break;
	}
}

//-------------------------------------------------
//  MACHINE_CONFIG_FRAGMENT( sub_slot )
//-------------------------------------------------

UINT8 intv_ecs_device::intv_control_r(int hand)
{
	static const UINT8 keypad_table[] =
	{
		0xFF, 0x3F, 0x9F, 0x5F, 0xD7, 0xB7, 0x77, 0xDB,
		0xBB, 0x7B, 0xDD, 0xBD, 0x7D, 0xDE, 0xBE, 0x7E
	};

	static const UINT8 disc_table[] =
	{
		0xF3, 0xE3, 0xE7, 0xF7, 0xF6, 0xE6, 0xEE, 0xFE,
		0xFC, 0xEC, 0xED, 0xFD, 0xF9, 0xE9, 0xEB, 0xFB
	};

	static const UINT8 discyx_table[5][5] =
	{
		{ 0xE3, 0xF3, 0xFB, 0xEB, 0xE9 },
		{ 0xE7, 0xE3, 0xFB, 0xE9, 0xF9 },
		{ 0xF7, 0xF7, 0xFF, 0xFD, 0xFD },
		{ 0xF6, 0xE6, 0xFE, 0xEC, 0xED },
		{ 0xE6, 0xEE, 0xFE, 0xFC, 0xEC }
	};

	int x, y;
	UINT8 val = 0xff;

	/* keypad */
	x = m_keypad[hand]->read();
	for (y = 0; y < 16; y++)
	{
		if (x & (1 << y))
		{
			val &= keypad_table[y];
		}
	}

	switch ((m_options->read() >> hand) & 4)
	{
		case 0: /* disc == digital */
		default:

			x = m_disc[hand]->read();
			for (y = 0; y < 16; y++)
			{
				if (x & (1 << y))
				{
					val &= disc_table[y];
				}
			}
			break;

		case 4: /* disc == _fake_ analog */

			x = m_discx[hand]->read();
			y = m_discy[hand]->read();
			val &= discyx_table[y / 32][x / 32];
	}

	return val;
}

READ8_MEMBER( intv_ecs_device::ay_porta_r )
{
	if (m_cntrlsel->read() == 0)
		return intv_control_r(0);
	else
		return 0xff; // not sure what to return here, maybe it should be last output?
}

READ8_MEMBER( intv_ecs_device::ay_portb_r )
{
	switch (m_cntrlsel->read())
	{
		case 0x00: // hand controller
			return intv_control_r(1);

		case 0x01: // synthesizer keyboard
		{
			UINT8 val = 0xff;
			// return correct result if more than one bit of 0xFE is set
			for (int i = 0; i < 7; i++)
			{
				if (BIT(m_psg_porta, i))
					val &= m_synth[i]->read();
			}
			return val;
		}
		case 0x02: // ecs keyboard
		{
			UINT8 val = 0xff;
			// return correct result if more than one bit of 0xFE is set
			for (int i = 0; i < 7; i++)
			{
				if (BIT(m_psg_porta, i))
					val &= m_keybd[i]->read();
			}
			return val;
		}
		default:
			return 0xff;
	}
}

WRITE8_MEMBER( intv_ecs_device::ay_porta_w )
{
	m_psg_porta = (~data) & 0xff;
}

static MACHINE_CONFIG_FRAGMENT( sub_slot )
	MCFG_SPEAKER_STANDARD_MONO("mono_ecs")

	MCFG_SOUND_ADD("ay8914", AY8914, XTAL_3_579545MHz/2)
	MCFG_AY8910_PORT_A_READ_CB(READ8(intv_ecs_device, ay_porta_r))
	MCFG_AY8910_PORT_B_READ_CB(READ8(intv_ecs_device, ay_portb_r))
	MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(intv_ecs_device, ay_porta_w))
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono_ecs", 0.33)

	MCFG_INTV_CARTRIDGE_ADD("subslot", intv_cart, NULL)
MACHINE_CONFIG_END


machine_config_constructor intv_ecs_device::device_mconfig_additions() const
{
	return MACHINE_CONFIG_NAME( sub_slot );
}


ROM_START( ecs )
	ROM_REGION( 0x20000, "ecs", ROMREGION_ERASEFF )
	ROM_LOAD16_WORD_SWAP( "ecs_rom.20", 0x04000, 0x2000, CRC(5f9d05e5) SHA1(083a3e7405b8f8b4b8a5003ca9c31b8d824b535c))
	ROM_LOAD16_WORD_SWAP( "ecs_rom.70", 0x0e000, 0x2000, CRC(46bb1f48) SHA1(eda44a8476fdada1ae90fba0d0287611e2efa074))
	ROM_LOAD16_WORD_SWAP( "ecs_rom.e0", 0x1c000, 0x2000, CRC(c2ebcd90) SHA1(b3c14955f56c57e6f0d8fbb695771946cfcf6582))
ROM_END

const rom_entry *intv_ecs_device::device_rom_region() const
{
	return ROM_NAME( ecs );
}


static INPUT_PORTS_START( intv_ecs_kbd )
/*
 ECS matrix scanned by setting 0xFE bits to output and reading 0xFF
 ECS Keyboard Layout:
 FF\FE  Bit 7   Bit 6   Bit 5   Bit 4   Bit 3   Bit 2   Bit 1   Bit 0
 Bit 0  NC      RTN     0       ESC     P       ;       .       (left)
 Bit 1  L       O       8       9       I       K       M       ,
 Bit 2  J       U       6       7       Y       H       B       N
 Bit 3  G       T       4       5       R       F       C       V
 Bit 4  D       E       2       3       W       S       Z       X
 Bit 5  A       CTL     (right) 1       Q       (up)    (down)  (space)
 Bit 6  SHIFT   NC      NC      NC      NC      NC      NC      NC

 Shifted keys that differ from pc:
 Key        : 1 2 5 6 7 (left) (right) (up) (down)
 Shift + key: = " + - /  %      '       ^    ?
 */

	PORT_START("ROW.0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RTN")               PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0)           PORT_CHAR('0') PORT_CHAR(')') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC)     PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P)           PORT_CHAR('P') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON)   PORT_CHAR(';') PORT_CHAR(':') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP)        PORT_CHAR('.') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT)        PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR('%') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L)           PORT_CHAR('L') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O)           PORT_CHAR('O') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8)           PORT_CHAR('8') PORT_CHAR('*') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9)           PORT_CHAR('9') PORT_CHAR('(') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I)           PORT_CHAR('I') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K)           PORT_CHAR('K') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M)           PORT_CHAR('M') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA)   PORT_CHAR(',') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.2")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J)           PORT_CHAR('J') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U)           PORT_CHAR('U') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6)           PORT_CHAR('6') PORT_CHAR('-') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7)           PORT_CHAR('7') PORT_CHAR('/') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y)           PORT_CHAR('Y') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H)           PORT_CHAR('H') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B)           PORT_CHAR('B') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N)           PORT_CHAR('N') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.3")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G)           PORT_CHAR('G') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T)           PORT_CHAR('T') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4)           PORT_CHAR('4') PORT_CHAR('$') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5)           PORT_CHAR('5') PORT_CHAR('%') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R)           PORT_CHAR('R') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F)           PORT_CHAR('F') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C)           PORT_CHAR('C') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V)           PORT_CHAR('V') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.4")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D)           PORT_CHAR('D') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E)           PORT_CHAR('E') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2)           PORT_CHAR('2') PORT_CHAR('"') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3)           PORT_CHAR('3') PORT_CHAR('#') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W)           PORT_CHAR('W') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S)           PORT_CHAR('S') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z)           PORT_CHAR('Z') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X)           PORT_CHAR('X') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.5")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A)           PORT_CHAR('A') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTL") PORT_CODE(KEYCODE_RCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT)   PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR('\'') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1)           PORT_CHAR('1') PORT_CHAR('=') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q)           PORT_CHAR('Q') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP)      PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR('^') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN)        PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR('?') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE)   PORT_CHAR(' ') PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)

	PORT_START("ROW.6")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CODE(KEYCODE_LSHIFT)  PORT_CHAR(UCHAR_SHIFT_1) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x02)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END

static INPUT_PORTS_START( intv_ecs_synth )
/*
 ECS Synthesizer Layout:
 FF\FE  Bit 7   Bit 6   Bit 5   Bit 4   Bit 3   Bit 2   Bit 1   Bit 0
 Bit 0  G2      Gb2     F2      E2      Eb2     D2      Db2     C2
 Bit 1  Eb3     D3      Db3     C3      B2      Bb2     A2      Ab2
 Bit 2  B3      Bb3     A3      Ab3     G3      Gb3     F3      E3
 Bit 3  G4      Gb4     F4      E4      Eb4     D4      Db4     C4
 Bit 4  Eb5     D5      Db5     C5      B4      Bb4     A4      Ab4
 Bit 5  B5      Bb5     A5      Ab5     G5      Gb5     F5      E5
 Bit 6  C6      NC      NC      NC      NC      NC      NC      NC
 */
	PORT_START("SYNTH.0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab2")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.2")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E3")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.3")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.4")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Eb5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Db5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab4")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.5")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Bb5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ab5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gb5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E5")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)

	PORT_START("SYNTH.6")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C6")  PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x01)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END

static INPUT_PORTS_START( intv_ecs_pads )
	// First ECS Hand Controller
	PORT_START("KEYPAD.0")
	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/1") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/6") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/7") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/8") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/9") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/Clear") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/0") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P3/Enter") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3/Upper") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3/Lower-Left") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P3/Lower-Right") PORT_PLAYER(3) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )

	PORT_START("DISC.0")
	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P3/Up") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Up-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P3/Right") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Right-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Right") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P3/Down") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Down-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P3/Left") PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Left-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3/Up-Up-Left") PORT_CONDITION("OPTIONS",0x04,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)

	PORT_START("DISCX.0")
	PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("P3/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)

	PORT_START("DISCY.0")
	PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("P3/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_PLAYER(3) PORT_CONDITION("OPTIONS",0x04,EQUALS,0x04) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)

	// Second ECS Hand Controller
	PORT_START("KEYPAD.1")
	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/1") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/2") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/3") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/4") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/5") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/6") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/7") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/8") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/9") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/Clear") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/0") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("P4/Enter") PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4/Upper") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4/Lower-Left") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P4/Lower-Right") PORT_PLAYER(4) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )

	PORT_START("DISC.1")
	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("P4/Up") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Up-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("P4/Right") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Right-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Right") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("P4/Down") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Down-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("P4/Left") PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Left-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4/Up-Up-Left") PORT_CONDITION("OPTIONS",0x08,EQUALS,0x00) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)

	PORT_START("DISCX.1")
	PORT_BIT( 0xff, 0x50, IPT_AD_STICK_X ) PORT_NAME("P4/X") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_D) PORT_CODE_INC(KEYCODE_G) PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)

	PORT_START("DISCY.1")
	PORT_BIT( 0xff, 0x50, IPT_AD_STICK_Y ) PORT_NAME("P4/Y") PORT_MINMAX(0x00,0x9f) PORT_SENSITIVITY(100) PORT_KEYDELTA(0x50) PORT_CODE_DEC(KEYCODE_R) PORT_CODE_INC(KEYCODE_F) PORT_PLAYER(4) PORT_CONDITION("OPTIONS",0x08,EQUALS,0x08) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
INPUT_PORTS_END

static INPUT_PORTS_START( intv_ecs )
	PORT_INCLUDE( intv_ecs_pads )
	PORT_INCLUDE( intv_ecs_synth )
	PORT_INCLUDE( intv_ecs_kbd )

	PORT_START("OPTIONS")
	PORT_CONFNAME( 0x04, 0x00, "ECS_P3 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_CONFSETTING(    0x00, "Digital" )
	PORT_CONFSETTING(    0x04, "Analog" )
	PORT_CONFNAME( 0x08, 0x00, "ECS_P4 Disc" ) PORT_CONDITION("CNTRLSEL",0x0f,EQUALS,0x00)
	PORT_CONFSETTING(    0x00, "Digital" )
	PORT_CONFSETTING(    0x08, "Analog" )

	PORT_START("CNTRLSEL")
	PORT_CONFNAME( 0x0F, 0x02, "ECS Controller")
	PORT_CONFSETTING(  0x00, "Gamepads" )
	PORT_CONFSETTING(  0x01, "Piano" )
	PORT_CONFSETTING(  0x02, "Keyboard" )
INPUT_PORTS_END

ioport_constructor intv_ecs_device::device_input_ports() const
{
	return INPUT_PORTS_NAME( intv_ecs );
}


/*-------------------------------------------------
 Paged ROM handling
 -------------------------------------------------*/

READ16_MEMBER(intv_ecs_device::read_rom20)
{
	if (m_bank_base[2])
		return INTV_ROM16_READ(offset + 0x2000);
	else
		return 0xffff;
}

READ16_MEMBER(intv_ecs_device::read_rom70)
{
	if (m_bank_base[7])
		return 0xffff;
	else
		return INTV_ROM16_READ(offset + 0x7000);
}

READ16_MEMBER(intv_ecs_device::read_rome0)
{
	if (m_bank_base[14])
		return INTV_ROM16_READ(offset + 0xe000);
	else    // if WSMLB is loaded, it shall go here, otherwise 0xffff
		return m_subslot->read_rome0(space, offset, mem_mask);
}

READ16_MEMBER(intv_ecs_device::read_romf0)
{
	// only WSMLB should come here with bank_base = 1
	if (m_bank_base[15])
		return m_subslot->read_romf0(space, offset + 0x1000, mem_mask);
	else
		return m_subslot->read_romf0(space, offset, mem_mask);
}


/*-------------------------------------------------
 read_audio
 -------------------------------------------------*/

READ16_MEMBER(intv_ecs_device::read_ay)
{
	if (ACCESSING_BITS_0_7)
		return m_snd->read(space, offset, mem_mask);
	else
		return 0xffff;
}

/*-------------------------------------------------
 write_audio
 -------------------------------------------------*/

WRITE16_MEMBER(intv_ecs_device::write_ay)
{
	if (ACCESSING_BITS_0_7)
		return m_snd->write(space, offset, data, mem_mask);
}
