// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************

    LVL Echo Keyboard

    Notes:
    - the Echo is a 3 octave keyboard with 37 keys, but the software seems to
      support a 5 octave keyboard.
    - keys 33, 34, 35 are polled additionally for an unknown reason, maybe an
      octave offset switch?

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

#include "emu.h"
#include "lvlecho.h"


namespace {

class bbc_lvlecho_device : public device_t, public device_bbc_userport_interface
{
public:
	bbc_lvlecho_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
		: device_t(mconfig, BBC_LVLECHO, tag, owner, clock)
		, device_bbc_userport_interface(mconfig, *this)
		, m_kbd(*this, "KEY_%u", 0)
		, m_key(0)
	{
	}

protected:
	// device_t overrides
	virtual void device_start() override ATTR_COLD;

	// optional information overrides
	virtual ioport_constructor device_input_ports() const override ATTR_COLD;

	virtual uint8_t pb_r() override
	{
		return m_kbd[m_key]->read();
	}

	virtual void pb_w(uint8_t data) override
	{
		m_key = data & 0x3f;
	}

private:
	required_ioport_array<64> m_kbd;

	uint8_t m_key;
};


//-------------------------------------------------
//  input_ports - device-specific input ports
//-------------------------------------------------

static INPUT_PORTS_START( lvlecho )
	PORT_START("KEY_0")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C2

	PORT_START("KEY_1")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_CS2

	PORT_START("KEY_2")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_D2

	PORT_START("KEY_3")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_DS2

	PORT_START("KEY_4")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_E2

	PORT_START("KEY_5")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_F2

	PORT_START("KEY_6")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_FS2

	PORT_START("KEY_7")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_G2

	PORT_START("KEY_8")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_GS2

	PORT_START("KEY_9")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_A2

	PORT_START("KEY_10")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_AS2

	PORT_START("KEY_11")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_B2

	PORT_START("KEY_12")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C3  PORT_CODE(KEYCODE_TAB)

	PORT_START("KEY_13")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_CS3 PORT_CODE(KEYCODE_1)

	PORT_START("KEY_14")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_D3  PORT_CODE(KEYCODE_Q)

	PORT_START("KEY_15")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_DS3 PORT_CODE(KEYCODE_2)

	PORT_START("KEY_16")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_E3  PORT_CODE(KEYCODE_W)

	PORT_START("KEY_17")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_F3  PORT_CODE(KEYCODE_E)

	PORT_START("KEY_18")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_FS3 PORT_CODE(KEYCODE_4)

	PORT_START("KEY_19")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_G3  PORT_CODE(KEYCODE_R)

	PORT_START("KEY_20")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_GS3 PORT_CODE(KEYCODE_5)

	PORT_START("KEY_21")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_A3  PORT_CODE(KEYCODE_T)

	PORT_START("KEY_22")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_AS3 PORT_CODE(KEYCODE_6)

	PORT_START("KEY_23")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_B3  PORT_CODE(KEYCODE_Y)

	PORT_START("KEY_24")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C4  PORT_CODE(KEYCODE_U)

	PORT_START("KEY_25")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_CS4 PORT_CODE(KEYCODE_8)

	PORT_START("KEY_26")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_D4  PORT_CODE(KEYCODE_I)

	PORT_START("KEY_27")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_DS4 PORT_CODE(KEYCODE_9)

	PORT_START("KEY_28")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_E4  PORT_CODE(KEYCODE_O)

	PORT_START("KEY_29")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_F4  PORT_CODE(KEYCODE_P)

	PORT_START("KEY_30")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_FS4 PORT_CODE(KEYCODE_A)

	PORT_START("KEY_31")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_G4  PORT_CODE(KEYCODE_Z)

	PORT_START("KEY_32")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_GS4 PORT_CODE(KEYCODE_S)

	PORT_START("KEY_33")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_A4  PORT_CODE(KEYCODE_X)

	PORT_START("KEY_34")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_AS4 PORT_CODE(KEYCODE_D)

	PORT_START("KEY_35")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_B4  PORT_CODE(KEYCODE_C)

	PORT_START("KEY_36")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C5  PORT_CODE(KEYCODE_V)

	PORT_START("KEY_37")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_CS5 PORT_CODE(KEYCODE_G)

	PORT_START("KEY_38")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_D5  PORT_CODE(KEYCODE_B)

	PORT_START("KEY_39")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_DS5 PORT_CODE(KEYCODE_H)

	PORT_START("KEY_40")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_E5  PORT_CODE(KEYCODE_N)

	PORT_START("KEY_41")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_F5  PORT_CODE(KEYCODE_M)

	PORT_START("KEY_42")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_FS5 PORT_CODE(KEYCODE_K)

	PORT_START("KEY_43")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_G5  PORT_CODE(KEYCODE_COMMA)

	PORT_START("KEY_44")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_GS5 PORT_CODE(KEYCODE_L)

	PORT_START("KEY_45")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_A5  PORT_CODE(KEYCODE_STOP)

	PORT_START("KEY_46")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_AS5 PORT_CODE(KEYCODE_COLON)

	PORT_START("KEY_47")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_B5  PORT_CODE(KEYCODE_SLASH)

	PORT_START("KEY_48")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C6  PORT_CODE(KEYCODE_RSHIFT)

	PORT_START("KEY_49")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_CS6

	PORT_START("KEY_50")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_D6

	PORT_START("KEY_51")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_DS6

	PORT_START("KEY_52")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_E6

	PORT_START("KEY_53")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_F6

	PORT_START("KEY_54")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_FS6

	PORT_START("KEY_55")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_G6

	PORT_START("KEY_56")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_GS6

	PORT_START("KEY_57")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_A6

	PORT_START("KEY_58")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_AS6

	PORT_START("KEY_59")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_B6

	PORT_START("KEY_60")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_GM_C7

	PORT_START("KEY_61")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("KEY_62")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("KEY_63")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END

ioport_constructor bbc_lvlecho_device::device_input_ports() const
{
	return INPUT_PORTS_NAME( lvlecho );
}


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

void bbc_lvlecho_device::device_start()
{
	save_item(NAME(m_key));
}

} // anonymous namespace


DEFINE_DEVICE_TYPE_PRIVATE(BBC_LVLECHO, device_bbc_userport_interface, bbc_lvlecho_device, "bbc_lvlecho", "LVL Echo Keyboard")
