europc, europc2: Low-level emulation of built-in keyboard

This commit is contained in:
AJR 2022-06-04 21:10:12 -04:00
parent 8c237a7dca
commit fd82da23ef
4 changed files with 415 additions and 98 deletions

View File

@ -3390,6 +3390,8 @@ createMESSProjects(_target, _subtarget, "pc")
files {
MAME_DIR .. "src/mame/drivers/asst128.cpp",
MAME_DIR .. "src/mame/drivers/europc.cpp",
MAME_DIR .. "src/mame/machine/europc_kbd.cpp",
MAME_DIR .. "src/mame/machine/europc_kbd.h",
MAME_DIR .. "src/mame/drivers/genpc.cpp",
MAME_DIR .. "src/mame/drivers/ibmpc.cpp",
MAME_DIR .. "src/mame/drivers/ibmpcjr.cpp",

View File

@ -30,16 +30,16 @@
#include "emu.h"
#include "cpu/i86/i86.h"
#include "cpu/m6805/m68705.h"
#include "bus/isa/aga.h"
#include "bus/isa/fdc.h"
#include "bus/pc_kbd/keyboards.h"
#include "bus/pc_kbd/pc_kbdc.h"
#include "machine/europc_kbd.h"
#include "machine/genpc.h"
#include "machine/m3002.h"
#include "machine/pckeybrd.h"
#include "machine/ram.h"
#include "softlist_dev.h"
class europc_pc_state : public driver_device
{
public:
@ -47,11 +47,9 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_mb(*this, "mb"),
m_keyboard(*this, "pc_keyboard"),
m_ram(*this, RAM_TAG),
m_rtc(*this, "rtc"),
m_jim_state(0),
m_port61(0)
m_jim_state(0)
{ }
void europc(machine_config &config);
@ -63,12 +61,11 @@ public:
private:
required_device<cpu_device> m_maincpu;
required_device<pc_noppi_mb_device> m_mb;
required_device<pc_keyboard_device> m_keyboard;
required_device<ram_device> m_ram;
required_device<m3002_device> m_rtc;
void europc_pio_w(offs_t offset, uint8_t data);
uint8_t europc_pio_r(offs_t offset);
uint8_t europc_portc_r();
DECLARE_WRITE_LINE_MEMBER(reset_in_w);
void europc_jim_w(offs_t offset, uint8_t data);
uint8_t europc_jim_r(offs_t offset);
@ -77,7 +74,6 @@ private:
uint8_t m_jim_data[16];
uint8_t m_jim_state;
isa8_aga_device::mode_t m_jim_mode{};
int m_port61; // bit 0,1 must be 0 for startup; reset?
void europc_io(address_map &map);
void europc_map(address_map &map);
@ -275,43 +271,22 @@ void europc_pc_state::init_europc()
}
}
void europc_pc_state::europc_pio_w(offs_t offset, uint8_t data)
{
switch (offset)
{
case 1:
m_port61=data;
m_mb->m_pit8253->write_gate2(BIT(data, 0));
m_mb->pc_speaker_set_spkrdata(BIT(data, 1));
m_keyboard->enable(BIT(data, 6));
if(data & 0x80)
m_mb->m_pic8259->ir1_w(0);
break;
}
logerror("europc pio write %.2x %.2x\n", offset, data);
}
uint8_t europc_pc_state::europc_pio_r(offs_t offset)
uint8_t europc_pc_state::europc_portc_r()
{
int data = 0;
switch (offset)
{
case 0:
data = m_keyboard->read();
break;
case 1:
data = m_port61;
break;
case 2:
if (m_mb->pit_out2())
data |= 0x20;
break;
}
if (m_mb->pit_out2())
data |= 0x20;
return data;
}
WRITE_LINE_MEMBER(europc_pc_state::reset_in_w)
{
m_maincpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE);
if (!state)
m_mb->reset();
}
/*
layout of an uk europc
@ -367,45 +342,6 @@ static INPUT_PORTS_START( europc )
PORT_BIT( 0x01, 0x01, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( europc_keyboard )
PORT_INCLUDE(pc_keyboard)
PORT_MODIFY("pc_keyboard_2") /* IN6 */
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("` ~") PORT_CODE(KEYCODE_BACKSLASH) /* ` 29 A9 */
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_TILDE) /* \ 2B AB */
PORT_MODIFY("pc_keyboard_5") /* IN9 */
PORT_BIT ( 0x0070, 0x0000, IPT_UNUSED )
/* 0x40 non us backslash 2 not available */
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) /* F11 57 D7 */
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) /* F12 58 D8 */
PORT_START("pc_keyboard_6") /* IN10 */\
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP Enter") PORT_CODE(KEYCODE_ENTER_PAD) /* PAD Enter 60 e0 */
PORT_BIT(0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END
class europc_keyboard_device : public pc_keyboard_device
{
public:
europc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
protected:
virtual ioport_constructor device_input_ports() const override;
};
DEFINE_DEVICE_TYPE(EUROPC_KEYB, europc_keyboard_device, "europc_keyb", "EURO PC Keyboard")
europc_keyboard_device::europc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
pc_keyboard_device(mconfig, EUROPC_KEYB, tag, owner, clock)
{
m_type = KEYBOARD_TYPE::PC;
}
ioport_constructor europc_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(europc_keyboard);
}
void europc_pc_state::europc_map(address_map &map)
{
map.unmap_value_high();
@ -416,7 +352,7 @@ void europc_pc_state::europc_io(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x00ff).m(m_mb, FUNC(pc_noppi_mb_device::map));
map(0x0060, 0x0063).rw(FUNC(europc_pc_state::europc_pio_r), FUNC(europc_pc_state::europc_pio_w));
map(0x0062, 0x0062).r(FUNC(europc_pc_state::europc_portc_r));
map(0x0250, 0x025f).rw(FUNC(europc_pc_state::europc_jim_r), FUNC(europc_pc_state::europc_jim_w));
map(0x02e0, 0x02e0).r(FUNC(europc_pc_state::europc_jim2_r));
}
@ -487,15 +423,18 @@ void europc_pc_state::europc(machine_config &config)
PCNOPPI_MOTHERBOARD(config, m_mb, 0).set_cputag(m_maincpu);
m_mb->int_callback().set_inputline(m_maincpu, 0);
m_mb->nmi_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
m_mb->kbddata_callback().set("kbd", FUNC(europc_keyboard_device::kbdata_w));
m_mb->kbdclk_callback().set("kbd", FUNC(europc_keyboard_device::kbclk_w));
M6805U2(config, "kbdctrl", 16_MHz_XTAL / 4);
europc_keyboard_device &kbd(EUROPC_KEYBOARD(config, "kbd", 16_MHz_XTAL / 4));
kbd.kbdata_callback().set(m_mb, FUNC(pc_noppi_mb_device::keyboard_data_w));
kbd.kbclk_callback().set(m_mb, FUNC(pc_noppi_mb_device::keyboard_clock_w));
kbd.reset_callback().set(FUNC(europc_pc_state::reset_in_w));
ISA8_SLOT(config, "isa1", 0, "mb:isa", pc_isa8_cards, "aga", false); // FIXME: determine ISA bus clock
ISA8_SLOT(config, "isa2", 0, "mb:isa", pc_isa8_cards, "lpt", true);
ISA8_SLOT(config, "isa3", 0, "mb:isa", pc_isa8_cards, "com", true);
ISA8_SLOT(config, "isa4", 0, "mb:isa", europc_fdc, "fdc", true);
EUROPC_KEYB(config, m_keyboard);
m_keyboard->keypress().set("mb:pic8259", FUNC(pic8259_device::ir1_w));
M3002(config, m_rtc, 32.768_kHz_XTAL);
@ -520,10 +459,12 @@ void europc_pc_state::euroxt(machine_config &config)
{
europc(config);
config.device_remove("kbdctrl");
pc_kbdc_device &pc_kbdc(PC_KBDC(config.replace(), "kbd", pc_xt_keyboards, STR_KBD_IBM_PC_XT_83));
pc_kbdc.out_clock_cb().set(m_mb, FUNC(pc_noppi_mb_device::keyboard_clock_w));
pc_kbdc.out_data_cb().set(m_mb, FUNC(pc_noppi_mb_device::keyboard_data_w));
PC_KEYB(config.replace(), m_keyboard);
m_keyboard->keypress().set("mb:pic8259", FUNC(pic8259_device::ir1_w));
m_mb->kbdclk_callback().set("kbd", FUNC(pc_kbdc_device::clock_write_from_mb));
m_mb->kbddata_callback().set("kbd", FUNC(pc_kbdc_device::data_write_from_mb));
m_ram->set_default_size("768K");
@ -551,18 +492,12 @@ ROM_START( europc )
ROMX_LOAD("bios_v2.04.bin", 0x8000, 0x8000, CRC(e623967c) SHA1(5196b14018da1f3198e2950af0e6eab41425f556), ROM_BIOS(6))
ROM_SYSTEM_BIOS( 7, "v2.05", "EuroPC v2.05" )
ROMX_LOAD("bios_2.05.bin", 0x8000, 0x8000, CRC(372ceed6) SHA1(bb3d3957a22422f98be2225bdc47705bcab96f56), ROM_BIOS(7)) // v2.04 and v2.05 don't work yet, , see comment section
ROM_REGION(0x1000, "kbdctrl", 0)
ROM_LOAD("zc86115p-mc6805u2.bin", 0x0000, 0x1000, CRC(d90c1fab) SHA1(ddb7060abddee7294723833c303090de35c1e79c))
ROM_END
ROM_START( europc2 )
ROM_REGION(0x10000,"bios", 0)
// hdd bios integrated!
ROM_LOAD("europcii_bios_v3.01_500145.bin", 0x8000, 0x8000, CRC(ecca89c8) SHA1(802b89babdf0ab0a0a9c21d1234e529c8386d6fb))
ROM_REGION(0x1000, "kbdctrl", 0)
ROM_LOAD("zc86115p-mc6805u2.bin", 0x0000, 0x1000, CRC(d90c1fab) SHA1(ddb7060abddee7294723833c303090de35c1e79c))
ROM_END
ROM_START( euroxt )
@ -580,7 +515,7 @@ ROM_START( euroxt )
// BIOS ROM versions 1.02, 1.04 and 1.05 were accompanied by identical char ROM versions 50146, which in turn match the one used in /bus/isa/aga.cpp
ROM_END
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1988, europc, ibm5150, 0, europc, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO PC", MACHINE_NOT_WORKING)
COMP( 198?, europc2, ibm5150, 0, europc2, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO PC II", MACHINE_NOT_WORKING)
COMP( 198?, euroxt, ibm5150, 0, euroxt, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO XT", MACHINE_NOT_WORKING)
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1988, europc, 0, ibm5150, europc, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO PC", MACHINE_NOT_WORKING)
COMP( 198?, europc2, 0, ibm5150, europc2, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO PC II", MACHINE_NOT_WORKING)
COMP( 198?, euroxt, 0, ibm5150, euroxt, europc, europc_pc_state, init_europc, "Schneider Rdf. AG", "EURO XT", MACHINE_NOT_WORKING)

View File

@ -0,0 +1,310 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Schneider EURO PC built-in 86-key keyboard
This keyboard was produced with several different European
layouts, including of course a German QWERTZ version. Currently a
British layout is provided.
Though the clocked serial interface is basically PC/XT-compatible,
there is also a separate reset output (which is triggered at
startup or by pressing Ctrl+Alt+Backspace), and the MCU clock is
derived from the same XTAL used for the onboard FDC.
Note that the column strobes for the key matrix are fake open
drain outputs produced by manipulating DDRA and DDRC rather than
the port latches.
**********************************************************************/
#include "emu.h"
#include "europc_kbd.h"
#include "cpu/m6805/m68705.h"
//**************************************************************************
// LLE KEYBOARD DEVICE
//**************************************************************************
DEFINE_DEVICE_TYPE(EUROPC_KEYBOARD, europc_keyboard_device, "europc_kbd", "EURO PC Keyboard")
europc_keyboard_device::europc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, EUROPC_KEYBOARD, tag, owner, clock)
, m_mcu(*this, "mcu")
, m_keys(*this, "COLUMN%d", 1U)
, m_leds(*this, "led%d", 1U)
, m_kbdata_callback(*this)
, m_kbclk_callback(*this)
, m_reset_callback(*this)
, m_column_strobe(0x7fff)
, m_kbdata_in(true)
, m_kbclk_in(true)
, m_portb_out(0xff)
{
}
void europc_keyboard_device::device_resolve_objects()
{
m_kbdata_callback.resolve_safe();
m_kbclk_callback.resolve_safe();
m_reset_callback.resolve_safe();
m_leds.resolve();
}
void europc_keyboard_device::device_start()
{
save_item(NAME(m_column_strobe));
save_item(NAME(m_kbdata_in));
save_item(NAME(m_kbclk_in));
save_item(NAME(m_portb_out));
}
//**************************************************************************
// INPUT LINES
//**************************************************************************
WRITE_LINE_MEMBER(europc_keyboard_device::kbdata_w)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(europc_keyboard_device::kbdata_sync_w), this), state);
}
TIMER_CALLBACK_MEMBER(europc_keyboard_device::kbdata_sync_w)
{
if (m_kbdata_in == param)
return;
m_kbdata_in = param;
if (BIT(m_portb_out, 1))
m_kbdata_callback(param);
}
WRITE_LINE_MEMBER(europc_keyboard_device::kbclk_w)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(europc_keyboard_device::kbclk_sync_w), this), state);
}
TIMER_CALLBACK_MEMBER(europc_keyboard_device::kbclk_sync_w)
{
if (m_kbclk_in == param)
return;
m_kbclk_in = param;
if (BIT(m_portb_out, 0))
{
m_kbclk_callback(param);
m_mcu->set_input_line(M6805_IRQ_LINE, param ? CLEAR_LINE : ASSERT_LINE);
}
}
//**************************************************************************
// MCU PORTS
//**************************************************************************
void europc_keyboard_device::porta_w(offs_t offset, u8 data, u8 mem_mask)
{
data |= ~mem_mask;
m_column_strobe = (m_column_strobe & 0x7f00) | data;
}
u8 europc_keyboard_device::portb_r()
{
return 0xf0 | (m_kbdata_in ? 0x02 : 0x00) | (m_kbclk_in ? 0x01 : 0x00);
}
void europc_keyboard_device::portb_w(offs_t offset, u8 data, u8 mem_mask)
{
data |= ~mem_mask;
u8 portb_changed = std::exchange(m_portb_out, data) ^ data;
if (BIT(portb_changed, 1) && m_kbdata_in)
m_kbdata_callback(BIT(data, 1));
if (BIT(portb_changed, 0) && m_kbclk_in)
{
m_kbclk_callback(BIT(data, 0));
m_mcu->set_input_line(M6805_IRQ_LINE, BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE);
}
if (BIT(portb_changed, 4))
m_reset_callback(!BIT(data, 4)); // discrete open collector
m_leds[0] = !BIT(data, 2); // Caps Lock
m_leds[1] = !BIT(data, 3); // Num Lock
}
void europc_keyboard_device::portc_w(offs_t offset, u8 data, u8 mem_mask)
{
data |= ~mem_mask;
m_column_strobe = u16(data & 0x7f) << 8 | (m_column_strobe & 0x00ff);
}
u8 europc_keyboard_device::portd_r()
{
u8 d = 0xff;
for (int i = 0; i < 15; i++)
if (!BIT(m_column_strobe, i))
d &= m_keys[i]->read();
return d;
}
void europc_keyboard_device::device_add_mconfig(machine_config &config)
{
m6805u2_device &mcu(M6805U2(config, m_mcu, DERIVED_CLOCK(1, 1)));
mcu.set_timer_divisor(4); // determines key repeat rate; code sets this value but mask version of MCU ignores it
mcu.set_timer_external_source(false); // TIMER pin is pulled up
mcu.porta_w().set(FUNC(europc_keyboard_device::porta_w));
mcu.portb_r().set(FUNC(europc_keyboard_device::portb_r));
mcu.portb_w().set(FUNC(europc_keyboard_device::portb_w));
mcu.portc_w().set(FUNC(europc_keyboard_device::portc_w));
mcu.portd_r().set(FUNC(europc_keyboard_device::portd_r));
}
//**************************************************************************
// KEY MATRIX
//**************************************************************************
static INPUT_PORTS_START(europc_kbd)
PORT_START("COLUMN1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(0x1b) PORT_CODE(KEYCODE_ESC)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F1)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F2)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F3)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F4)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F5)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F6)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F7)
PORT_START("COLUMN2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('|') PORT_CODE(KEYCODE_TILDE)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('"') PORT_CODE(KEYCODE_2)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR(0x00a3) PORT_CODE(KEYCODE_3)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7)
PORT_START("COLUMN3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I)
PORT_START("COLUMN4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K)
PORT_START("COLUMN5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('<') PORT_CODE(KEYCODE_COMMA)
PORT_START("COLUMN6")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F8)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR('(') PORT_CODE(KEYCODE_9)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P)
PORT_START("COLUMN7")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F11)) PORT_CODE(KEYCODE_F11)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_CODE(KEYCODE_PLUS_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 2 " UTF8_DOWN) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7 Home") PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('@') PORT_CODE(KEYCODE_QUOTE)
PORT_START("COLUMN8")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad . Del") PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PORT_CODE(KEYCODE_DEL_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CODE(KEYCODE_F12)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9 Pg Up") PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad * PrtSc") PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_CODE(KEYCODE_ASTERISK)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PORT_CODE(KEYCODE_NUMLOCK)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR(')') PORT_CODE(KEYCODE_0)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON)
PORT_START("COLUMN9")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 0 Ins") PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CODE(KEYCODE_F10)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 6 " UTF8_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll Lock Break") PORT_CHAR(UCHAR_MAMEKEY(SCRLOCK)) PORT_CODE(KEYCODE_SLASH_PAD)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 1 End") PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(0x08) PORT_CODE(KEYCODE_BACKSPACE)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH)
PORT_START("COLUMN10")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_RCONTROL)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CODE(KEYCODE_F9)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3 Pg Dn") PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 8 " UTF8_UP) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 4 " UTF8_LEFT) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('#') PORT_CHAR('~') PORT_CODE(KEYCODE_BACKSLASH) // to right of quote key
PORT_START("COLUMN11")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(0x09) PORT_CODE(KEYCODE_TAB)
PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("COLUMN12")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("COLUMN13")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift Left") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("COLUMN14")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CHAR(UCHAR_MAMEKEY(LALT)) PORT_CODE(KEYCODE_LALT)
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("COLUMN15")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift Right") PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) PORT_CODE(KEYCODE_RSHIFT)
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
INPUT_PORTS_END
ioport_constructor europc_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(europc_kbd);
}
//**************************************************************************
// INTERNAL ROM
//**************************************************************************
ROM_START(europc_kbd)
ROM_REGION(0x1000, "mcu", 0)
ROM_LOAD("zc86115p-mc6805u2.bin", 0x0000, 0x1000, CRC(d90c1fab) SHA1(ddb7060abddee7294723833c303090de35c1e79c))
ROM_END
const tiny_rom_entry *europc_keyboard_device::device_rom_region() const
{
return ROM_NAME(europc_kbd);
}

View File

@ -0,0 +1,70 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#ifndef MAME_MACHINE_EUROPC_KBD_H
#define MAME_MACHINE_EUROPC_KBD_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> europc_keyboard_device
class europc_keyboard_device : public device_t
{
public:
// device type constructor
europc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// callback configuration
auto kbdata_callback() { return m_kbdata_callback.bind(); }
auto kbclk_callback() { return m_kbclk_callback.bind(); }
auto reset_callback() { return m_reset_callback.bind(); }
// line inputs
DECLARE_WRITE_LINE_MEMBER(kbdata_w);
DECLARE_WRITE_LINE_MEMBER(kbclk_w);
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
private:
TIMER_CALLBACK_MEMBER(kbdata_sync_w);
TIMER_CALLBACK_MEMBER(kbclk_sync_w);
// port handlers
void porta_w(offs_t offset, u8 data, u8 mem_mask);
u8 portb_r();
void portb_w(offs_t offset, u8 data, u8 mem_mask);
void portc_w(offs_t offset, u8 data, u8 mem_mask);
u8 portd_r();
// object finders
required_device<cpu_device> m_mcu;
required_ioport_array<15> m_keys;
output_finder<2> m_leds;
// output line callbacks
devcb_write_line m_kbdata_callback;
devcb_write_line m_kbclk_callback;
devcb_write_line m_reset_callback;
// internal state
u16 m_column_strobe;
bool m_kbdata_in;
bool m_kbclk_in;
u8 m_portb_out;
};
// device type declarations
DECLARE_DEVICE_TYPE(EUROPC_KEYBOARD, europc_keyboard_device)
#endif // MAME_MACHINE_EUROPC_KBD_H