// license:BSD-3-Clause // copyright-holders:Curt Coder /********************************************************************** Apricot keyboard emulation *********************************************************************/ #include "emu.h" #include "apricotkb.h" //************************************************************************** // MACROS / CONSTANTS //************************************************************************** #define UPD7507C_TAG "ic2" //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** DEFINE_DEVICE_TYPE(APRICOT_KEYBOARD, apricot_keyboard_device, "aprikb", "Apricot Keyboard") //------------------------------------------------- // ROM( apricot_keyboard ) //------------------------------------------------- ROM_START( apricot_keyboard ) ROM_REGION( 0x800, UPD7507C_TAG, 0 ) ROM_LOAD( "keyboard controller upd7507c.ic2", 0x000, 0x800, NO_DUMP ) ROM_END //------------------------------------------------- // rom_region - device-specific ROM region //------------------------------------------------- const tiny_rom_entry *apricot_keyboard_device::device_rom_region() const { return ROM_NAME( apricot_keyboard ); } //------------------------------------------------- // ADDRESS_MAP( kb_io ) //------------------------------------------------- #ifdef UPD7507_EMULATED void apricot_keyboard_device::apricot_keyboard_io(address_map &map) { map(0x00, 0x00).r(FUNC(apricot_keyboard_device::kb_lo_r)); map(0x01, 0x01).r(FUNC(apricot_keyboard_device::kb_hi_r)); map(0x03, 0x03).w(FUNC(apricot_keyboard_device::kb_p3_w)); map(0x04, 0x04).w(FUNC(apricot_keyboard_device::kb_y0_w)); map(0x05, 0x05).w(FUNC(apricot_keyboard_device::kb_y4_w)); map(0x06, 0x06).rw(FUNC(apricot_keyboard_device::kb_p6_r), FUNC(apricot_keyboard_device::kb_yc_w)); map(0x07, 0x07).w(FUNC(apricot_keyboard_device::kb_y8_w)); } #endif //------------------------------------------------- // device_add_mconfig - add device configuration //------------------------------------------------- void apricot_keyboard_device::device_add_mconfig(machine_config &config) { #ifdef UPD7507_EMULATED upd7507_device &upd(UPD7507(config, UPD7507C_TAG, XTAL(32'768))); upd.set_addrmap(AS_IO, &apricot_keyboard_device::apricot_keyboard_io); #endif } //------------------------------------------------- // INPUT_PORTS( apricot_keyboard ) //------------------------------------------------- INPUT_PORTS_START( apricot_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 ) PORT_START("Y12") 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("MODIFIERS") PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) INPUT_PORTS_END //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- ioport_constructor apricot_keyboard_device::device_input_ports() const { return INPUT_PORTS_NAME( apricot_keyboard ); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // apricot_keyboard_device - constructor //------------------------------------------------- apricot_keyboard_device::apricot_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, APRICOT_KEYBOARD, tag, owner, clock), m_write_txd(*this), m_y(*this, "Y%u", 0), m_modifiers(*this, "MODIFIERS") { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void apricot_keyboard_device::device_start() { // resolve callbacks m_write_txd.resolve_safe(); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void apricot_keyboard_device::device_reset() { } //------------------------------------------------- // read_keyboard - //------------------------------------------------- uint8_t apricot_keyboard_device::read_keyboard() { uint8_t data = 0xff; for (int i = 0; i < 13; i++) { if (!BIT(m_kb_y, i)) data &= m_y[i]->read(); } return data; } //------------------------------------------------- // kb_lo_r - //------------------------------------------------- READ8_MEMBER( apricot_keyboard_device::kb_lo_r ) { return read_keyboard() & 0x0f; } //------------------------------------------------- // kb_hi_r - //------------------------------------------------- READ8_MEMBER( apricot_keyboard_device::kb_hi_r ) { return read_keyboard() >> 4; } //------------------------------------------------- // kb_p6_r - //------------------------------------------------- READ8_MEMBER( apricot_keyboard_device::kb_p6_r ) { /* bit description P60 P61 SHIFT P62 CONTROL */ uint8_t modifiers = m_modifiers->read(); return modifiers << 1; } //------------------------------------------------- // kb_p3_w - //------------------------------------------------- WRITE8_MEMBER( apricot_keyboard_device::kb_p3_w ) { // bit 1 controls the IR LEDs } //------------------------------------------------- // kb_y0_w - //------------------------------------------------- WRITE8_MEMBER( apricot_keyboard_device::kb_y0_w ) { m_kb_y = (m_kb_y & 0xfff0) | (data & 0x0f); } //------------------------------------------------- // kb_y4_w - //------------------------------------------------- WRITE8_MEMBER( apricot_keyboard_device::kb_y4_w ) { m_kb_y = (m_kb_y & 0xff0f) | ((data & 0x0f) << 4); } //------------------------------------------------- // kb_y8_w - //------------------------------------------------- WRITE8_MEMBER( apricot_keyboard_device::kb_y8_w ) { m_kb_y = (m_kb_y & 0xf0ff) | ((data & 0x0f) << 8); } //------------------------------------------------- // kb_yc_w - //------------------------------------------------- WRITE8_MEMBER( apricot_keyboard_device::kb_yc_w ) { m_kb_y = (m_kb_y & 0xf0ff) | ((data & 0x0f) << 12); }