// license:BSD-3-Clause // copyright-holders:Curt Coder /********************************************************************** Tandy 2000 keyboard emulation *********************************************************************/ #include "tandy2kb.h" //************************************************************************** // MACROS / CONSTANTS //************************************************************************** #define I8048_TAG "m1" //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** const device_type TANDY2K_KEYBOARD = &device_creator; //------------------------------------------------- // ROM( tandy2k_keyboard ) //------------------------------------------------- ROM_START( tandy2k_keyboard ) ROM_REGION( 0x400, I8048_TAG, 0 ) ROM_LOAD( "keyboard.m1", 0x0000, 0x0400, NO_DUMP ) ROM_END //------------------------------------------------- // rom_region - device-specific ROM region //------------------------------------------------- const rom_entry *tandy2k_keyboard_device::device_rom_region() const { return ROM_NAME( tandy2k_keyboard ); } //------------------------------------------------- // ADDRESS_MAP( kb_io ) //------------------------------------------------- static ADDRESS_MAP_START( tandy2k_keyboard_io, AS_IO, 8, tandy2k_keyboard_device ) AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(kb_p1_w) AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(kb_p2_w) AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(kb_p1_r) ADDRESS_MAP_END //------------------------------------------------- // MACHINE_DRIVER( tandy2k_keyboard ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( tandy2k_keyboard ) MCFG_CPU_ADD(I8048_TAG, I8048, 1000000) // ? MCFG_CPU_IO_MAP(tandy2k_keyboard_io) MCFG_DEVICE_DISABLE() // TODO MACHINE_CONFIG_END //------------------------------------------------- // machine_config_additions - device-specific // machine configurations //------------------------------------------------- machine_config_constructor tandy2k_keyboard_device::device_mconfig_additions() const { return MACHINE_CONFIG_NAME( tandy2k_keyboard ); } //------------------------------------------------- // INPUT_PORTS( tandy2k_keyboard ) //------------------------------------------------- INPUT_PORTS_START( tandy2k_keyboard ) PORT_START("Y0") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y1") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y2") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y3") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y4") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y5") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y6") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y7") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y8") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y9") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y10") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_START("Y11") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) INPUT_PORTS_END //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- ioport_constructor tandy2k_keyboard_device::device_input_ports() const { return INPUT_PORTS_NAME( tandy2k_keyboard ); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // tandy2k_keyboard_device - constructor //------------------------------------------------- tandy2k_keyboard_device::tandy2k_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, TANDY2K_KEYBOARD, "Tandy 2000 Keyboard", tag, owner, clock, "tandy2kb", __FILE__), m_maincpu(*this, I8048_TAG), m_y0(*this, "Y0"), m_y1(*this, "Y1"), m_y2(*this, "Y2"), m_y3(*this, "Y3"), m_y4(*this, "Y4"), m_y5(*this, "Y5"), m_y6(*this, "Y6"), m_y7(*this, "Y7"), m_y8(*this, "Y8"), m_y9(*this, "Y9"), m_y10(*this, "Y10"), m_y11(*this, "Y11"), m_write_clock(*this), m_write_data(*this), m_keylatch(0xffff), m_clock(0), m_data(0) { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void tandy2k_keyboard_device::device_start() { // resolve callbacks m_write_clock.resolve_safe(); m_write_data.resolve_safe(); // state saving save_item(NAME(m_keylatch)); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void tandy2k_keyboard_device::device_reset() { } //------------------------------------------------- // power_w - //------------------------------------------------- WRITE_LINE_MEMBER( tandy2k_keyboard_device::power_w ) { // TODO } //------------------------------------------------- // reset_w - //------------------------------------------------- WRITE_LINE_MEMBER( tandy2k_keyboard_device::reset_w ) { if (!state) { device_reset(); } } //------------------------------------------------- // busy_w - //------------------------------------------------- WRITE_LINE_MEMBER( tandy2k_keyboard_device::busy_w ) { m_maincpu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); } //------------------------------------------------- // data_r - //------------------------------------------------- READ_LINE_MEMBER( tandy2k_keyboard_device::data_r ) { return m_data; } //------------------------------------------------- // kb_p1_r - //------------------------------------------------- READ8_MEMBER( tandy2k_keyboard_device::kb_p1_r ) { /* bit description 0 X0 1 X1 2 X2 3 X3 4 X4 5 X5 6 X6 7 X7 */ UINT8 data = 0xff; if (!BIT(m_keylatch, 0)) data &= m_y0->read(); if (!BIT(m_keylatch, 1)) data &= m_y1->read(); if (!BIT(m_keylatch, 2)) data &= m_y2->read(); if (!BIT(m_keylatch, 3)) data &= m_y3->read(); if (!BIT(m_keylatch, 4)) data &= m_y4->read(); if (!BIT(m_keylatch, 5)) data &= m_y5->read(); if (!BIT(m_keylatch, 6)) data &= m_y6->read(); if (!BIT(m_keylatch, 7)) data &= m_y7->read(); if (!BIT(m_keylatch, 8)) data &= m_y8->read(); if (!BIT(m_keylatch, 9)) data &= m_y9->read(); if (!BIT(m_keylatch, 10)) data &= m_y10->read(); if (!BIT(m_keylatch, 11)) data &= m_y11->read(); return ~data; } //------------------------------------------------- // kb_p1_w - //------------------------------------------------- WRITE8_MEMBER( tandy2k_keyboard_device::kb_p1_w ) { /* bit description 0 Y0 1 Y1 2 Y2 3 Y3 4 Y4 5 Y5 6 Y6 7 Y7 */ // keyboard row m_keylatch = (m_keylatch & 0xff00) | data; } //------------------------------------------------- // kb_p2_w - //------------------------------------------------- WRITE8_MEMBER( tandy2k_keyboard_device::kb_p2_w ) { /* bit description 0 Y8 1 Y9 2 Y10 3 Y11 4 LED 2 5 LED 1 6 CLOCK 7 DATA */ // keyboard row m_keylatch = ((data & 0x0f) << 8) | (m_keylatch & 0xff); // led output output_set_led_value(LED_2, !BIT(data, 4)); output_set_led_value(LED_1, !BIT(data, 5)); // keyboard clock int clock = BIT(data, 6); if (m_clock != clock) { m_clock = clock; m_write_clock(m_clock); } // keyboard data int kbddat = BIT(data, 7); if (m_data != kbddat) { m_data = kbddat; m_write_data(m_data); } }