summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Mark Garlanger <mgarlanger@users.noreply.github.com>2017-02-24 18:58:16 -0600
committer Vas Crabb <cuavas@users.noreply.github.com>2017-02-25 11:58:16 +1100
commit9533352c6bd965e680f5f20285381d551d508228 (patch)
treed30c10c3c1d271729f5dd81f80c87e1e978ce61d
parenta0aa981a6ec3bc29f71a38ab660f3645c48c7def (diff)
Fix Heath H19 keyboard (#2066)
* Fix Heath H19 keyboard * Fix how enable/disable of 25th line is handled. * Updated to use internal ROM in MM5740.
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/machine/mm5740.cpp173
-rw-r--r--src/devices/machine/mm5740.h162
-rw-r--r--src/mame/drivers/h19.cpp491
5 files changed, 655 insertions, 184 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index 8e33f586b68..5816349fa71 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -1238,6 +1238,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/mm5740.h,MACHINES["MM5740"] = true
+---------------------------------------------------
+
+if (MACHINES["MM5740"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/mm5740.cpp",
+ MAME_DIR .. "src/devices/machine/mm5740.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/kb3600.h,MACHINES["KB3600"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 9d441207bdf..ba31c0bc232 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -471,6 +471,7 @@ MACHINES["MIOT6530"] = true
MACHINES["MM58167"] = true
MACHINES["MM58274C"] = true
MACHINES["MM74C922"] = true
+MACHINES["MM5740"] = true
MACHINES["MOS6526"] = true
MACHINES["MOS6529"] = true
MACHINES["MOS6551"] = true
diff --git a/src/devices/machine/mm5740.cpp b/src/devices/machine/mm5740.cpp
new file mode 100644
index 00000000000..df8f5e43985
--- /dev/null
+++ b/src/devices/machine/mm5740.cpp
@@ -0,0 +1,173 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont, Mark Garlanger
+/**********************************************************************
+
+ National Semiconductor MM5740 Keyboard Encoder emulation
+ (Code originally based on kb3600.cpp)
+
+*********************************************************************/
+
+#include "mm5740.h"
+
+#include <algorithm>
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// devices
+const device_type MM5740 = &device_creator<mm5740_device>;
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+ROM_START( mm5740 )
+ ROM_REGION(0x1c2, "internal", 0)
+ ROM_LOAD("mm5740aac.ic1", 0x000, 0x1c2, CRC(aed404d3) SHA1(e7b9feba5f789f388d27820b5f3fa591d41b4ab1))
+ROM_END
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const tiny_rom_entry *mm5740_device::device_rom_region() const
+{
+ return ROM_NAME( mm5740 );
+}
+
+
+//-------------------------------------------------
+// mm5740_device - constructor
+//-------------------------------------------------
+
+mm5740_device::mm5740_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, MM5740, "MM5740", tag, owner, clock, "mm5740", __FILE__),
+ m_read_x({*this, *this, *this, *this, *this, *this, *this, *this, *this}),
+ m_read_shift(*this),
+ m_read_control(*this),
+ m_write_data_ready(*this),
+ m_rom(*this, "internal")
+{
+ std::fill_n(m_x_mask, 9, 0);
+}
+
+uint32_t mm5740_device::calc_effective_clock_key_debounce(uint32_t capacitance)
+{
+ // calculate key debounce based on capacitance in pF
+ uint32_t key_debounce_msec = capacitance / 125;
+ if (key_debounce_msec == 0)
+ {
+ key_debounce_msec = 1;
+ }
+
+ return 1000 / key_debounce_msec;
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mm5740_device::device_start()
+{
+ // resolve callbacks
+ for(int i = 0; i < 9; i++)
+ {
+ m_read_x[i].resolve_safe(0x3ff);
+ }
+ m_read_shift.resolve_safe(0);
+ m_read_control.resolve_safe(0);
+ m_write_data_ready.resolve_safe();
+
+ // allocate timers
+ m_scan_timer = timer_alloc();
+ m_scan_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
+
+ // state saving
+ save_item(NAME(m_b));
+ save_item(NAME(m_x_mask));
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific reset
+//-------------------------------------------------
+
+void mm5740_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+
+void mm5740_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ int ako = 0;
+
+ for (int x = 0; x < 9; x++)
+ {
+ uint16_t data = m_read_x[x]() ^ 0x3ff;
+
+ if ((data ^ m_x_mask[x]) == 0)
+ {
+ // bail early if nothing has changed.
+ continue;
+ }
+
+ for (int y = 0; y < 10; y++)
+ {
+
+ if (BIT(data, y))
+ {
+ uint8_t *rom = m_rom->base();
+ uint16_t offset = x*10 + y;
+ // Common portion
+ uint16_t common = (uint16_t) rom[offset];
+
+ offset += (((m_read_shift() ? 1: 0) + (m_read_control() ? 2: 0)) + 1) * 90;
+
+ // Unique portion based on shift/ctrl keys.
+ uint8_t uniq = rom[offset];
+
+ uint16_t b = (((common & 0x10) << 4) | ((uniq & 0x0f) << 4) | (common & 0x0f)) ^ 0x1ff;
+
+ ako = 1;
+
+ if (!BIT(m_x_mask[x], y))
+ {
+ m_x_mask[x] |= (1 << y);
+ if (m_b != b)
+ {
+ m_b = b;
+ m_write_data_ready(ASSERT_LINE);
+
+ return;
+ }
+ }
+ }
+ else // key released, unmark it from the "down" info
+ {
+ m_x_mask[x] &= ~(1 << y);
+ }
+ }
+ }
+
+ if (!ako)
+ {
+ m_write_data_ready(CLEAR_LINE);
+ m_b = -1;
+ }
+}
+
+
+//-------------------------------------------------
+// b_r -
+//-------------------------------------------------
+
+uint16_t mm5740_device::b_r()
+{
+ m_write_data_ready(CLEAR_LINE);
+ return m_b;
+}
+
diff --git a/src/devices/machine/mm5740.h b/src/devices/machine/mm5740.h
new file mode 100644
index 00000000000..8687f4d6cc9
--- /dev/null
+++ b/src/devices/machine/mm5740.h
@@ -0,0 +1,162 @@
+// license:BSD-3-Clause
+// copyright-holders: R. Belmont
+/**********************************************************************
+
+ MM5740 Keyboard Encoder emulation
+
+**********************************************************************
+ _____ _____
+ B3 1 |* \_/ | 40 B4
+ Vll 2 | | 39 B9
+ Clock 3 | | 38 B2
+ X9 4 | | 37 B1
+ X8 5 | | 36 B8
+ X7 6 | | 35 B7
+ X6 7 | | 34 B6
+ X5 8 | | 33 B5
+ X4 9 | | 32 Vss
+ X3 10 | MM5740 | 31 Y9
+ X2 11 | | 30 Y8
+ X1 12 | | 29 Y7
+ Data Strobe Output 13 | | 28 Y6
+ Data Strobe Control 14 | | 27 Y5
+ Output Enable 15 | | 26 Y4
+ Repeat 16 | | 25 Y3
+ Key Bounce Mask 17 | | 24 Y2
+ Vgg 18 | | 23 Y1
+ Control 19 | | 22 Y0
+ Shift Lock I/O 20 |_____________| 21 Shift
+
+Name Pin No. Function
+----------------------------------------------------------------------
+
+X1-X9 4-12 Output - Drives the key switch matrix.
+
+Y1-Y10 22-31 Inputs - connect to the X drive lines with
+ the key switch matrix.
+
+B1-B9 1,33-40 Tri-stated data outputs.
+
+Data Strobe Output 13 Output to indicate key pressed.
+
+Data Strobe Control 14 Input to control data strobe output pulse width.
+
+Output Enable 15 Input to control the chip's TRI-STATE output
+
+Repeat 16 Each cycle of this signal will issue
+ a new data strobe for the pressed key.
+
+Key-Bounce Mask 17 Use capacitor on this chip to provide
+ key debouncing
+
+Shift 21 Shift key pressed
+
+Control 19 Control key pressed
+
+Shift Lock I/O 20 Togglable input to signify shift (NOT caps) lock.
+
+Clock 3 A TTL compatible clock signal
+
+Vss 32 +5.0V
+
+Vll 2 Ground
+
+Vgg 18 -12V
+
+
+**********************************************************************/
+
+/* TODO:
+ Support Key-bounce mask
+ Support Repeat function
+ Support shift lock
+ Support additional internal ROMs
+*/
+
+#pragma once
+
+#ifndef MAME_DEVICE_MACHINE_MM5740_H
+#define MAME_DEVICE_MACHINE_MM5740_H
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MM5740_MATRIX_X1(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 0);
+#define MCFG_MM5740_MATRIX_X2(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 1);
+#define MCFG_MM5740_MATRIX_X3(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 2);
+#define MCFG_MM5740_MATRIX_X4(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 3);
+#define MCFG_MM5740_MATRIX_X5(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 4);
+#define MCFG_MM5740_MATRIX_X6(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 5);
+#define MCFG_MM5740_MATRIX_X7(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 6);
+#define MCFG_MM5740_MATRIX_X8(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 7);
+#define MCFG_MM5740_MATRIX_X9(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 8);
+#define MCFG_MM5740_SHIFT_CB(_cb) devcb = &mm5740_device::set_shift_cb(*device, DEVCB_##_cb);
+#define MCFG_MM5740_CONTROL_CB(_cb) devcb = &mm5740_device::set_control_cb(*device, DEVCB_##_cb);
+#define MCFG_MM5740_DATA_READY_CB(_cb) devcb = &mm5740_device::set_data_ready_cb(*device, DEVCB_##_cb);
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mm5740_device
+
+class mm5740_device : public device_t
+{
+public:
+ // construction/destruction
+ mm5740_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // public interface
+ uint16_t b_r();
+
+ template<typename Object> static devcb_base &set_x_cb(device_t &device, Object &&object, uint8_t i)
+ {
+ assert(i<9); return downcast<mm5740_device &>(device).m_read_x[i].set_callback(std::forward<Object>(object));
+ }
+ template<typename Object> static devcb_base &set_shift_cb(device_t &device, Object &&object)
+ {
+ return downcast<mm5740_device &>(device).m_read_shift.set_callback(std::forward<Object>(object));
+ }
+ template<typename Object> static devcb_base &set_control_cb(device_t &device, Object &&object)
+ {
+ return downcast<mm5740_device &>(device).m_read_control.set_callback(std::forward<Object>(object));
+ }
+ template<typename Object> static devcb_base &set_data_ready_cb(device_t &device, Object &&object)
+ {
+ return downcast<mm5740_device &>(device).m_write_data_ready.set_callback(std::forward<Object>(object));
+ }
+ static uint32_t calc_effective_clock_key_debounce(uint32_t capacitance);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+private:
+ devcb_read16 m_read_x[9];
+ devcb_read_line m_read_shift, m_read_control;
+ devcb_write_line m_write_data_ready;
+
+ required_memory_region m_rom; // Internal ROM
+
+ int m_b; // output buffer
+
+ int m_x_mask[9]; // mask of what keys are down
+
+ // timers
+ emu_timer *m_scan_timer; // keyboard scan timer
+};
+
+
+// device type definition
+extern const device_type MM5740;
+
+
+
+#endif
+
diff --git a/src/mame/drivers/h19.cpp b/src/mame/drivers/h19.cpp
index 1a3efd1a314..50d4781e4f2 100644
--- a/src/mame/drivers/h19.cpp
+++ b/src/mame/drivers/h19.cpp
@@ -2,35 +2,25 @@
// copyright-holders:Robbbert, Mark Garlanger
/***************************************************************************
- Heathkit H19
+ Heathkit H19
- 12/05/2009 Skeleton driver.
+ A smart terminal designed and manufactured by Heath Company.
- The keyboard consists of a 9x10 matrix connected to a MM5740N
- mask-programmed keyboard controller. The output of this passes
- through a rom. The MM5740N may be custom-made, in which case it
- will need to be procured and tested. There is a "default" array;
- perhaps this is used. The presence of the rom would seem to
- indicate that the default is being used. We won't know, of
- course, until the device is emulated.
+ The keyboard consists of a 9x10 matrix connected to a MM5740AAC/N
+ mask-programmed keyboard controller. The output of this passes
+ through a rom.
- Keyboard input can also come from the serial port (a 8250).
- Either device will signal an interrupt to the CPU when a key
- is pressed/sent.
+ Input can also come from the serial port (a 8250).
+ Either device will signal an interrupt to the CPU when a key
+ is pressed/data is received.
- For the moment, the "ascii keyboard" device is used for the keyboard.
+ TODO:
+ - Finish connecting up the 8250
+ - enable 8520 interrupts
+ - speed up emulation
- TODO:
- - Create device or HLE of MM5740N keyboard controller
- - Make sure correct mask programming is used for it
- - Use keyboard rom
- - Finish connecting up the 8250
- - Verify beep lengths
- - Verify ram size
- - When the internal keyboard works, get rid of the "ascii_keyboard".
-
- Bios 1 (super19) has the videoram at D800. This is not emulated.
- However, a keyclick can be heard, to assure you it does in fact work.
+ super19 version has the videoram at D800. This is not emulated.
+ However, a keyclick can be heard, to assure you it does in fact work.
****************************************************************************/
/***************************************************************************
@@ -48,17 +38,16 @@
Only address lines A5, A6, A7 are used by the U442 three-to-eight line decoder
- 1. Keyboard encoder 0x80
- 2. Keyboard status 0xA0
- 3. CRT controller 0x60
- 4. Power-up configuration (primary) 0x00
- 5. Power-up configuration (secondary) 0x20
- 6. ACE (communications) 0x40
- 7. Bell enable 0xE0
- 8. Key click enable 0xC0
-
- Decoder U442 is enabled only during an I/O read or write operation to elimnate the
- possibility of false decoding on a refresh address coming from the Z80.
+Address Description
+----------------------------------------------------
+ 0x00 Power-up configuration (primary - SW401)
+ 0x20 Power-up configuration (secondary - SW402)
+ 0x40 ACE (communications)
+ 0x60 CRT controller
+ 0x80 Keyboard encoder
+ 0xA0 Keyboard status
+ 0xC0 Key click enable
+ 0xE0 Bell enable
****************************************************************************/
@@ -67,21 +56,29 @@
#include "video/mc6845.h"
#include "sound/beep.h"
#include "machine/ins8250.h"
-#include "machine/keyboard.h"
+#include "machine/mm5740.h"
// Standard H19 used a 2.048 MHz clock
#define H19_CLOCK (XTAL_12_288MHz / 6)
+#define MC6845_CLOCK (XTAL_12_288MHz /8)
+#define INS8250_CLOCK (XTAL_12_288MHz /4)
+// Capacitor value in pF
+#define H19_KEY_DEBOUNCE_CAPACITOR 5000
+#define MM5740_CLOCK (mm5740_device::calc_effective_clock_key_debounce(H19_KEY_DEBOUNCE_CAPACITOR))
// Beep Frequency is 1 KHz
#define H19_BEEP_FRQ (H19_CLOCK / 2048)
+#define KBDC_TAG "mm5740"
+
class h19_state : public driver_device
{
public:
enum
{
- TIMER_BEEP_OFF
+ TIMER_KEY_CLICK_OFF,
+ TIMER_BELL_OFF
};
h19_state(const machine_config &mconfig, device_type type, const char *tag)
@@ -93,13 +90,20 @@ public:
, m_beep(*this, "beeper")
, m_p_videoram(*this, "videoram")
, m_p_chargen(*this, "chargen")
+ , m_mm5740(*this, KBDC_TAG)
+ , m_kbdrom(*this, "keyboard")
+ , m_kbspecial(*this, "MODIFIERS")
{
}
- DECLARE_READ8_MEMBER(h19_80_r);
- DECLARE_READ8_MEMBER(h19_a0_r);
- DECLARE_WRITE8_MEMBER(h19_c0_w);
- DECLARE_WRITE8_MEMBER(h19_kbd_put);
+ DECLARE_WRITE8_MEMBER(h19_keyclick_w);
+ DECLARE_WRITE8_MEMBER(h19_bell_w);
+ DECLARE_READ8_MEMBER(kbd_key_r);
+ DECLARE_READ8_MEMBER(kbd_flags_r);
+ DECLARE_READ_LINE_MEMBER(mm5740_shift_r);
+ DECLARE_READ_LINE_MEMBER(mm5740_control_r);
+ DECLARE_WRITE_LINE_MEMBER(mm5740_data_ready_w);
+
MC6845_UPDATE_ROW(crtc_update_row);
private:
@@ -113,182 +117,187 @@ private:
required_device<beep_device> m_beep;
required_shared_ptr<uint8_t> m_p_videoram;
required_region_ptr<u8> m_p_chargen;
+ required_device<mm5740_device> m_mm5740;
+ required_memory_region m_kbdrom;
+ required_ioport m_kbspecial;
+
+ uint8_t m_transchar;
+ bool m_strobe;
+ uint16_t translate_mm5740_b(uint16_t b);
+ bool m_keyclickactive;
+ bool m_bellactive;
};
-
void h19_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
- case TIMER_BEEP_OFF:
- m_beep->set_state(0);
+ case TIMER_KEY_CLICK_OFF:
+ m_keyclickactive = false;
+ break;
+ case TIMER_BELL_OFF:
+ m_bellactive = false;
break;
default:
assert_always(false, "Unknown id in h19_state::device_timer");
}
-}
-READ8_MEMBER( h19_state::h19_80_r )
-{
-// keyboard data
- uint8_t ret = m_term_data;
- m_term_data = 0;
- return ret;
-}
-
-READ8_MEMBER( h19_state::h19_a0_r )
-{
-// keyboard status
- m_maincpu->set_input_line(0, CLEAR_LINE);
- return 0x7f; // says that a key is ready and no modifier keys are pressed
+ if (!m_keyclickactive && !m_bellactive)
+ {
+ m_beep->set_state(0);
+ }
}
-WRITE8_MEMBER( h19_state::h19_c0_w )
-{
-/* Beeper control - a 96L02 contains 2 oneshots, one for bell and one for keyclick.
-
- offset 00-1F = keyclick
- offset 20-3F = terminal bell */
- uint8_t length = (offset & 0x20) ? 200 : 6;
- m_beep->set_state(1);
- timer_set(attotime::from_msec(length), TIMER_BEEP_OFF);
-}
static ADDRESS_MAP_START(h19_mem, AS_PROGRAM, 8, h19_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x1fff) AM_ROM
- AM_RANGE(0x2000, 0xf7ff) AM_RAM
+ AM_RANGE(0x4000, 0x4100) AM_RAM
AM_RANGE(0xf800, 0xffff) AM_RAM AM_SHARE("videoram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( h19_io, AS_IO, 8, h19_state)
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x00, 0x1F) AM_READ_PORT("S401")
- AM_RANGE(0x20, 0x3F) AM_READ_PORT("S402")
+ AM_RANGE(0x00, 0x1F) AM_READ_PORT("SW401")
+ AM_RANGE(0x20, 0x3F) AM_READ_PORT("SW402")
AM_RANGE(0x40, 0x47) AM_MIRROR(0x18) AM_DEVREADWRITE("ins8250", ins8250_device, ins8250_r, ins8250_w )
AM_RANGE(0x60, 0x60) AM_DEVWRITE("crtc", mc6845_device, address_w)
AM_RANGE(0x61, 0x61) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w)
- AM_RANGE(0x80, 0x9F) AM_READ(h19_80_r)
- AM_RANGE(0xA0, 0xBF) AM_READ(h19_a0_r)
- AM_RANGE(0xC0, 0xFF) AM_WRITE(h19_c0_w)
+ AM_RANGE(0x80, 0x9F) AM_READ(kbd_key_r)
+ AM_RANGE(0xA0, 0xBF) AM_READ(kbd_flags_r)
+ AM_RANGE(0xC0, 0xDF) AM_WRITE(h19_keyclick_w)
+ AM_RANGE(0xE0, 0xFF) AM_WRITE(h19_bell_w)
ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( h19 )
-// Port codes are omitted to prevent collision with terminal keys
PORT_START("MODIFIERS")
- // bit 0 connects to B8 of MM5740 - purpose unknown
+ // bit 0 connects to B8 of MM5740 - low if either shift key is
// bit 7 is low if a key is pressed
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift")
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_PAUSE)
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine") PORT_CODE(KEYCODE_F12) PORT_TOGGLE
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat") PORT_CODE(KEYCODE_LALT)
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F10)
PORT_START("X1")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X2")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0-pad")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dot-pad")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter-pad")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X2")
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0-pad") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dot-pad") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR('.')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter-pad") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13)
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
PORT_START("X2")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\'")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("{")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1-pad")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2-pad")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3-pad")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('.')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\'") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("{") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('{') PORT_CHAR('}')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1-pad") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2-pad") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3-pad") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
PORT_START("X3")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LF")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4-pad")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5-pad")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6-pad")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LF") PORT_CODE(KEYCODE_RWIN)
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4-pad") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5-pad") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6-pad") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
PORT_START("X4")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AccentAcute")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X1")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7-pad")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8-pad")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9-pad")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AccentAcute") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X1")
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7-pad") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8-pad") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9-pad") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
PORT_START("X5")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1)
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2)
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3)
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4)
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5)
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_F6)
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue") PORT_CODE(KEYCODE_F7)
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red") PORT_CODE(KEYCODE_F8)
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray") PORT_CODE(KEYCODE_F9)
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
PORT_START("X6")
- PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_START("X7")
- PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll") PORT_CODE(KEYCODE_LWIN)
+
PORT_START("X8")
- PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
+
PORT_START("X9")
- PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc")
- PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1")
- PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2")
- PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3")
- PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4")
- PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5")
- PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6")
- PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7")
- PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8")
- PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9")
-
- PORT_START("S401")
- PORT_DIPNAME( 0x0f, 0x03, "Baud Rate")
+ PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
+ PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
+ PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
+ PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
+ PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
+ PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
+ PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
+
+ PORT_START("SW401")
+ PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate")
PORT_DIPSETTING( 0x01, "110")
PORT_DIPSETTING( 0x02, "150")
PORT_DIPSETTING( 0x03, "300")
@@ -309,21 +318,21 @@ static INPUT_PORTS_START( h19 )
PORT_DIPNAME( 0x40, 0x00, "Parity Type")
PORT_DIPSETTING( 0x00, DEF_STR(Normal))
PORT_DIPSETTING( 0x40, "Stick")
- PORT_DIPNAME( 0x80, 0x00, "Duplex")
+ PORT_DIPNAME( 0x80, 0x80, "Duplex")
PORT_DIPSETTING( 0x00, "Half")
PORT_DIPSETTING( 0x80, "Full")
- PORT_START("S402") // stored at 40C8
+ PORT_START("SW402") // stored at 40C8
PORT_DIPNAME( 0x01, 0x00, "Cursor")
PORT_DIPSETTING( 0x00, "Underline")
PORT_DIPSETTING( 0x01, "Block")
PORT_DIPNAME( 0x02, 0x00, "Keyclick")
PORT_DIPSETTING( 0x02, DEF_STR(No))
PORT_DIPSETTING( 0x00, DEF_STR(Yes))
- PORT_DIPNAME( 0x04, 0x04, "Wrap at EOL")
+ PORT_DIPNAME( 0x04, 0x00, "Wrap at EOL")
PORT_DIPSETTING( 0x00, DEF_STR(No))
PORT_DIPSETTING( 0x04, DEF_STR(Yes))
- PORT_DIPNAME( 0x08, 0x08, "Auto LF on CR")
+ PORT_DIPNAME( 0x08, 0x00, "Auto LF on CR")
PORT_DIPSETTING( 0x00, DEF_STR(No))
PORT_DIPSETTING( 0x08, DEF_STR(Yes))
PORT_DIPNAME( 0x10, 0x00, "Auto CR on LF")
@@ -340,11 +349,120 @@ static INPUT_PORTS_START( h19 )
PORT_DIPSETTING( 0x80, "60Hz")
INPUT_PORTS_END
+// Keyboard encoder masks
+#define KB_ENCODER_KEY_VALUE_MASK 0x7F
+#define KB_ENCODER_CONTROL_KEY_MASK 0x80
+
+// Keyboard flag masks
+#define KB_STATUS_SHIFT_KEYS_MASK 0x01
+#define KB_STATUS_CAPS_LOCK_MASK 0x02
+#define KB_STATUS_BREAK_KEY_MASK 0x04
+#define KB_STATUS_ONLINE_KEY_MASK 0x08
+#define KB_STATUS_REPEAT_KEYS_MASK 0x40
+#define KB_STATUS_KEYBOARD_STROBE_MASK 0x80
+
void h19_state::machine_reset()
{
}
+
+WRITE8_MEMBER( h19_state::h19_keyclick_w )
+{
+/* Keyclick - 6 mSec */
+
+ m_beep->set_state(1);
+ m_keyclickactive = true;
+ timer_set(attotime::from_msec(6), TIMER_KEY_CLICK_OFF);
+}
+
+WRITE8_MEMBER( h19_state::h19_bell_w )
+{
+/* Bell (^G) - 200 mSec */
+
+ m_beep->set_state(1);
+ m_bellactive = true;
+ timer_set(attotime::from_msec(200), TIMER_BELL_OFF);
+}
+
+
+/***************************************************************************
+MM5740 B Mapping to the ROM address
+
+B1 -> A0 A10 = 0
+B2 -> A1 A9 = 0
+B3 -> A2 A8 = B8
+B4 -> A3 A7 = B7
+B5 -> A4 A6 = B9
+B6 -> A5 A5 = B6
+B7 -> A7 A4 = B5
+B8 -> A8 A3 = B4
+B9 -> A6 A2 = B3
+ground -> A9 A1 = B2
+ground -> A10 A0 = B1
+
+****************************************************************************/
+uint16_t h19_state::translate_mm5740_b(uint16_t b)
+{
+ return ((b & 0x100) >> 2) | ((b & 0x0c0) << 1) | (b & 0x03f);
+}
+
+READ8_MEMBER(h19_state::kbd_key_r)
+{
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
+ m_strobe = false;
+
+ // high bit is for control key pressed, this is handled in the ROM, no processing needed.
+ return m_transchar;
+}
+
+READ8_MEMBER(h19_state::kbd_flags_r)
+{
+ uint8_t rv = 0;
+ uint16_t modifiers = m_kbspecial->read();
+
+ rv = modifiers & 0xff;
+
+ // check both shifts
+ if (((modifiers & 0x020) == 0) || ((modifiers & 0x100) == 0))
+ {
+ rv |= 0x1;
+ }
+
+ // invert offline switch
+ rv ^= KB_STATUS_ONLINE_KEY_MASK;
+
+ if (!m_strobe)
+ {
+ rv |= KB_STATUS_KEYBOARD_STROBE_MASK;
+ }
+
+ return rv;
+}
+
+READ_LINE_MEMBER(h19_state::mm5740_shift_r)
+{
+ return ((m_kbspecial->read() ^ 0x120) & 0x120) ? ASSERT_LINE : CLEAR_LINE;
+}
+
+READ_LINE_MEMBER(h19_state::mm5740_control_r)
+{
+ return ((m_kbspecial->read() ^ 0x10) & 0x10) ? ASSERT_LINE: CLEAR_LINE;
+}
+
+WRITE_LINE_MEMBER(h19_state::mm5740_data_ready_w)
+{
+ if (state == ASSERT_LINE)
+ {
+ uint8_t *decode = m_kbdrom->base();
+
+ m_transchar = decode[translate_mm5740_b(m_mm5740->b_r())];
+ m_strobe = true;
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
+ }
+}
+
+
MC6845_UPDATE_ROW( h19_state::crtc_update_row )
{
const rgb_t *palette = m_palette->palette()->entry_list_raw();
@@ -399,40 +517,45 @@ static GFXDECODE_START( h19 )
GFXDECODE_ENTRY( "chargen", 0x0000, h19_charlayout, 0, 1 )
GFXDECODE_END
-WRITE8_MEMBER( h19_state::h19_kbd_put )
-{
- m_term_data = data;
- m_maincpu->set_input_line(0, HOLD_LINE);
-}
-
static MACHINE_CONFIG_START( h19, h19_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",Z80, H19_CLOCK) // From schematics
MCFG_CPU_PROGRAM_MAP(h19_mem)
MCFG_CPU_IO_MAP(h19_io)
- //MCFG_DEVICE_PERIODIC_INT_DRIVER(h19_state, irq0_line_hold, 50) // for testing, causes a keyboard scan
/* video hardware */
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
- MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_REFRESH_RATE(60) // TODO- this is adjustable by dipswitch.
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
+
MCFG_SCREEN_SIZE(640, 250)
MCFG_SCREEN_VISIBLE_AREA(0, 640 - 1, 0, 250 - 1)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", h19)
MCFG_PALETTE_ADD_MONOCHROME("palette")
- MCFG_MC6845_ADD("crtc", MC6845, "screen", XTAL_12_288MHz / 8) // clk taken from schematics
- MCFG_MC6845_SHOW_BORDER_AREA(false)
- MCFG_MC6845_CHAR_WIDTH(8) /*?*/
+ MCFG_MC6845_ADD("crtc", MC6845, "screen", MC6845_CLOCK)
+ MCFG_MC6845_SHOW_BORDER_AREA(true)
+ MCFG_MC6845_CHAR_WIDTH(8)
MCFG_MC6845_UPDATE_ROW_CB(h19_state, crtc_update_row)
MCFG_MC6845_OUT_VSYNC_CB(INPUTLINE("maincpu", INPUT_LINE_NMI)) // frame pulse
- MCFG_DEVICE_ADD("ins8250", INS8250, XTAL_12_288MHz / 4) // 3.072mhz clock which gets divided down for the various baud rates
+ MCFG_DEVICE_ADD("ins8250", INS8250, INS8250_CLOCK)
MCFG_INS8250_OUT_INT_CB(INPUTLINE("maincpu", 0)) // interrupt
- MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0)
- MCFG_GENERIC_KEYBOARD_CB(WRITE8(h19_state, h19_kbd_put))
+ MCFG_DEVICE_ADD(KBDC_TAG, MM5740, MM5740_CLOCK)
+ MCFG_MM5740_MATRIX_X1(IOPORT("X1"))
+ MCFG_MM5740_MATRIX_X2(IOPORT("X2"))
+ MCFG_MM5740_MATRIX_X3(IOPORT("X3"))
+ MCFG_MM5740_MATRIX_X4(IOPORT("X4"))
+ MCFG_MM5740_MATRIX_X5(IOPORT("X5"))
+ MCFG_MM5740_MATRIX_X6(IOPORT("X6"))
+ MCFG_MM5740_MATRIX_X7(IOPORT("X7"))
+ MCFG_MM5740_MATRIX_X8(IOPORT("X8"))
+ MCFG_MM5740_MATRIX_X9(IOPORT("X9"))
+ MCFG_MM5740_SHIFT_CB(READLINE(h19_state, mm5740_shift_r))
+ MCFG_MM5740_CONTROL_CB(READLINE(h19_state, mm5740_control_r))
+ MCFG_MM5740_DATA_READY_CB(WRITELINE(h19_state, mm5740_data_ready_w))
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -483,7 +606,7 @@ ROM_START( watz19 )
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
-COMP( 1979, h19, 0, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19", MACHINE_NOT_WORKING )
+COMP( 1979, h19, 0, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19", 0 )
/* TODO - verify the years for these third-party replacement ROMs. */
COMP( 1982, super19, h19, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19 w/ Super-19 ROM", MACHINE_NOT_WORKING )
COMP( 1982, watz19, h19, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19 w/ Watzman ROM", MACHINE_NOT_WORKING )