From 012cbee2c3e0facb8876b2d31808cf07652a417d Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 23 Aug 2018 00:25:21 +1000 Subject: [PATCH] Amiga keyboard overhaul: * Implement Mitsumi Amiga 500, 600, and 2000/3000/4000/CDTV keyboards * Add unlabeled keys to UK layout * Restrict available keyboards depending on system type * Note that C-A-A reset is now broken on "big box" Amigas as MAME doesn't implement it properly, and the hack providing a fake dedicated reset line has been removed 6502 MCU: fix execute loop 6500/1: implement as device with onboard peripherals Fix some bogus comments --- scripts/src/bus.lua | 4 +- scripts/src/cpu.lua | 3 + src/devices/bus/amiga/keyboard/a2000.cpp | 86 +- src/devices/bus/amiga/keyboard/a2000.h | 46 +- src/devices/bus/amiga/keyboard/a500.cpp | 504 ----------- src/devices/bus/amiga/keyboard/a500.h | 253 ------ src/devices/bus/amiga/keyboard/keyboard.cpp | 43 +- src/devices/bus/amiga/keyboard/keyboard.h | 6 +- src/devices/bus/amiga/keyboard/matrix.cpp | 53 ++ src/devices/bus/amiga/keyboard/matrix.h | 1 + src/devices/bus/amiga/keyboard/mitsumi.cpp | 887 ++++++++++++++++++++ src/devices/bus/amiga/keyboard/mitsumi.h | 55 ++ src/devices/cpu/m6502/m6500_1.cpp | 471 +++++++++++ src/devices/cpu/m6502/m6500_1.h | 110 +++ src/devices/cpu/m6502/m6502.cpp | 8 +- src/devices/cpu/m6502/m6502.h | 3 +- src/devices/cpu/m6502/m6502d.cpp | 2 +- src/devices/cpu/m6502/m6502d.h | 2 +- src/devices/cpu/m6502/m6504.cpp | 2 +- src/devices/cpu/m6502/m6504.h | 2 +- src/devices/cpu/m6502/m6507.cpp | 2 +- src/devices/cpu/m6502/m6507.h | 2 +- src/devices/cpu/m6502/m65c02.cpp | 4 +- src/devices/cpu/m6502/m65c02.h | 4 +- src/devices/cpu/m6502/m65c02d.cpp | 4 +- src/devices/cpu/m6502/m65c02d.h | 4 +- src/mame/drivers/amiga.cpp | 72 +- 27 files changed, 1774 insertions(+), 859 deletions(-) delete mode 100644 src/devices/bus/amiga/keyboard/a500.cpp delete mode 100644 src/devices/bus/amiga/keyboard/a500.h create mode 100644 src/devices/bus/amiga/keyboard/mitsumi.cpp create mode 100644 src/devices/bus/amiga/keyboard/mitsumi.h create mode 100644 src/devices/cpu/m6502/m6500_1.cpp create mode 100644 src/devices/cpu/m6502/m6500_1.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index ab7a4fb2f7b..6669b6244fd 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2988,8 +2988,8 @@ if (BUSES["AMIGA_KEYBOARD"]~=null) then MAME_DIR .. "src/devices/bus/amiga/keyboard/a1200.h", MAME_DIR .. "src/devices/bus/amiga/keyboard/a2000.cpp", MAME_DIR .. "src/devices/bus/amiga/keyboard/a2000.h", - MAME_DIR .. "src/devices/bus/amiga/keyboard/a500.cpp", - MAME_DIR .. "src/devices/bus/amiga/keyboard/a500.h", + MAME_DIR .. "src/devices/bus/amiga/keyboard/mitsumi.cpp", + MAME_DIR .. "src/devices/bus/amiga/keyboard/mitsumi.h", } end diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 878fb8e1fcb..73b5c18d837 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -1362,6 +1362,7 @@ end --@src/devices/cpu/m6502/m65c02.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/r65c02.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m65sc02.h,CPUS["M6502"] = true +--@src/devices/cpu/m6502/m6500_1.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m6504.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m6507.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m6509.h,CPUS["M6502"] = true @@ -1392,6 +1393,8 @@ if (CPUS["M6502"]~=null) then MAME_DIR .. "src/devices/cpu/m6502/m65ce02.h", MAME_DIR .. "src/devices/cpu/m6502/m65sc02.cpp", MAME_DIR .. "src/devices/cpu/m6502/m65sc02.h", + MAME_DIR .. "src/devices/cpu/m6502/m6500_1.cpp", + MAME_DIR .. "src/devices/cpu/m6502/m6500_1.h", MAME_DIR .. "src/devices/cpu/m6502/m6504.cpp", MAME_DIR .. "src/devices/cpu/m6502/m6504.h", MAME_DIR .. "src/devices/cpu/m6502/m6507.cpp", diff --git a/src/devices/bus/amiga/keyboard/a2000.cpp b/src/devices/bus/amiga/keyboard/a2000.cpp index c728c7a43ee..4cc9141947b 100644 --- a/src/devices/bus/amiga/keyboard/a2000.cpp +++ b/src/devices/bus/amiga/keyboard/a2000.cpp @@ -74,11 +74,11 @@ // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE_NS(A2000_KBD_US, bus::amiga::keyboard, a2000_kbd_us_device, "a2000kbd_us", "Amiga 2000 Keyboard (U.S./Canada)") -DEFINE_DEVICE_TYPE_NS(A2000_KBD_DE, bus::amiga::keyboard, a2000_kbd_de_device, "a2000kbd_de", "Amiga 2000 Keyboard (Germany/Austria)") -DEFINE_DEVICE_TYPE_NS(A2000_KBD_SE, bus::amiga::keyboard, a2000_kbd_se_device, "a2000kbd_se", "Amiga 2000 Keyboard (Sweden/Finland)") -DEFINE_DEVICE_TYPE_NS(A2000_KBD_DK, bus::amiga::keyboard, a2000_kbd_dk_device, "a2000kbd_dk", "Amiga 2000 Keyboard (Denmark)") -DEFINE_DEVICE_TYPE_NS(A2000_KBD_GB, bus::amiga::keyboard, a2000_kbd_gb_device, "a2000kbd_gb", "Amiga 2000 Keyboard (UK)") +DEFINE_DEVICE_TYPE_NS(A2000_KBD_G80_US, bus::amiga::keyboard, a2000_kbd_g80_us_device, "a2000kbd_g80_us", "Amiga 2000 Keyboard (Cherry - U.S./Canada)") +DEFINE_DEVICE_TYPE_NS(A2000_KBD_G80_DE, bus::amiga::keyboard, a2000_kbd_g80_de_device, "a2000kbd_g80_de", "Amiga 2000 Keyboard (Cherry - Germany/Austria)") +DEFINE_DEVICE_TYPE_NS(A2000_KBD_G80_SE, bus::amiga::keyboard, a2000_kbd_g80_se_device, "a2000kbd_g80_se", "Amiga 2000 Keyboard (Cherry - Sweden/Finland)") +DEFINE_DEVICE_TYPE_NS(A2000_KBD_G80_DK, bus::amiga::keyboard, a2000_kbd_g80_dk_device, "a2000kbd_g80_dk", "Amiga 2000 Keyboard (Cherry - Denmark)") +DEFINE_DEVICE_TYPE_NS(A2000_KBD_G80_GB, bus::amiga::keyboard, a2000_kbd_g80_gb_device, "a2000kbd_g80_gb", "Amiga 2000 Keyboard (Cherry - UK)") @@ -489,9 +489,9 @@ ROM_END // LIVE DEVICE //************************************************************************** -// ======================> a2000_kbd_device +// ======================> a2000_kbd_g80_device -a2000_kbd_device::a2000_kbd_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock) +a2000_kbd_g80_device::a2000_kbd_g80_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_amiga_keyboard_interface(mconfig, *this) , m_rows(*this, "ROW%u", 0U) @@ -503,7 +503,7 @@ a2000_kbd_device::a2000_kbd_device(machine_config const &mconfig, device_type ty { } -WRITE_LINE_MEMBER(a2000_kbd_device::kdat_w) +WRITE_LINE_MEMBER(a2000_kbd_g80_device::kdat_w) { if (bool(state) != m_host_kdat) { @@ -514,7 +514,7 @@ WRITE_LINE_MEMBER(a2000_kbd_device::kdat_w) } } -READ8_MEMBER(a2000_kbd_device::mcu_bus_r) +READ8_MEMBER(a2000_kbd_g80_device::mcu_bus_r) { // when jumpered for external ROM, offset latched by U2 is 0x60 + (row << 1) uint8_t result(0U); @@ -527,12 +527,12 @@ READ8_MEMBER(a2000_kbd_device::mcu_bus_r) return result; } -WRITE8_MEMBER(a2000_kbd_device::mcu_p1_w) +WRITE8_MEMBER(a2000_kbd_g80_device::mcu_p1_w) { m_row_drive = (m_row_drive & 0x1f00U) | uint16_t(data); } -WRITE8_MEMBER(a2000_kbd_device::mcu_p2_w) +WRITE8_MEMBER(a2000_kbd_g80_device::mcu_p2_w) { m_row_drive = (m_row_drive & 0x00ffU) | (uint16_t(data & 0x1fU) << 8); @@ -555,24 +555,24 @@ WRITE8_MEMBER(a2000_kbd_device::mcu_p2_w) } } -tiny_rom_entry const *a2000_kbd_device::device_rom_region() const +tiny_rom_entry const *a2000_kbd_g80_device::device_rom_region() const { return ROM_NAME(a2000kbd); } -void a2000_kbd_device::device_add_mconfig(machine_config &config) +void a2000_kbd_g80_device::device_add_mconfig(machine_config &config) { auto &mcu(I8039(config, "u1", 6_MHz_XTAL)); - mcu.set_addrmap(AS_PROGRAM, &a2000_kbd_device::program_map); - mcu.set_addrmap(AS_IO, &a2000_kbd_device::ext_map); - mcu.p1_out_cb().set(FUNC(a2000_kbd_device::mcu_p1_w)); - mcu.p2_out_cb().set(FUNC(a2000_kbd_device::mcu_p2_w)); - mcu.bus_in_cb().set(FUNC(a2000_kbd_device::mcu_bus_r)); + mcu.set_addrmap(AS_PROGRAM, &a2000_kbd_g80_device::program_map); + mcu.set_addrmap(AS_IO, &a2000_kbd_g80_device::ext_map); + mcu.p1_out_cb().set(FUNC(a2000_kbd_g80_device::mcu_p1_w)); + mcu.p2_out_cb().set(FUNC(a2000_kbd_g80_device::mcu_p2_w)); + mcu.bus_in_cb().set(FUNC(a2000_kbd_g80_device::mcu_bus_r)); mcu.t0_in_cb().set_constant(1); mcu.t1_in_cb().set([this] () { return m_mcu_kclk ? 1 : 0; }); } -void a2000_kbd_device::device_start() +void a2000_kbd_g80_device::device_start() { save_item(NAME(m_row_drive)); save_item(NAME(m_host_kdat)); @@ -585,83 +585,83 @@ void a2000_kbd_device::device_start() m_mcu_kclk = true; } -void a2000_kbd_device::device_reset() +void a2000_kbd_g80_device::device_reset() { } -void a2000_kbd_device::program_map(address_map &map) +void a2000_kbd_g80_device::program_map(address_map &map) { map.global_mask(0x07ff); map(0x0000, 0x07ff).rom().region("mcu", 0); } -void a2000_kbd_device::ext_map(address_map &map) +void a2000_kbd_g80_device::ext_map(address_map &map) { map.global_mask(0x00ff); - map(0x0000, 0x00ff).r(FUNC(a2000_kbd_device::mcu_bus_r)); + map(0x0000, 0x00ff).r(FUNC(a2000_kbd_g80_device::mcu_bus_r)); } -// ======================> a2000_kbd_us_device +// ======================> a2000_kbd_g80_us_device -a2000_kbd_us_device::a2000_kbd_us_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : a2000_kbd_device(mconfig, A2000_KBD_US, tag, owner, clock) +a2000_kbd_g80_us_device::a2000_kbd_g80_us_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : a2000_kbd_g80_device(mconfig, A2000_KBD_G80_US, tag, owner, clock) { } -ioport_constructor a2000_kbd_us_device::device_input_ports() const +ioport_constructor a2000_kbd_g80_us_device::device_input_ports() const { return INPUT_PORTS_NAME(a2000_us_keyboard); } -// ======================> a2000_kbd_de_device +// ======================> a2000_kbd_g80_de_device -a2000_kbd_de_device::a2000_kbd_de_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : a2000_kbd_device(mconfig, A2000_KBD_DE, tag, owner, clock) +a2000_kbd_g80_de_device::a2000_kbd_g80_de_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : a2000_kbd_g80_device(mconfig, A2000_KBD_G80_DE, tag, owner, clock) { } -ioport_constructor a2000_kbd_de_device::device_input_ports() const +ioport_constructor a2000_kbd_g80_de_device::device_input_ports() const { return INPUT_PORTS_NAME(a2000_de_keyboard); } -// ======================> a2000_kbd_se_device +// ======================> a2000_kbd_g80_se_device -a2000_kbd_se_device::a2000_kbd_se_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : a2000_kbd_device(mconfig, A2000_KBD_SE, tag, owner, clock) +a2000_kbd_g80_se_device::a2000_kbd_g80_se_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : a2000_kbd_g80_device(mconfig, A2000_KBD_G80_SE, tag, owner, clock) { } -ioport_constructor a2000_kbd_se_device::device_input_ports() const +ioport_constructor a2000_kbd_g80_se_device::device_input_ports() const { return INPUT_PORTS_NAME(a2000_se_keyboard); } -// ======================> a2000_kbd_dk_device +// ======================> a2000_kbd_g80_dk_device -a2000_kbd_dk_device::a2000_kbd_dk_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : a2000_kbd_device(mconfig, A2000_KBD_DK, tag, owner, clock) +a2000_kbd_g80_dk_device::a2000_kbd_g80_dk_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : a2000_kbd_g80_device(mconfig, A2000_KBD_G80_DK, tag, owner, clock) { } -ioport_constructor a2000_kbd_dk_device::device_input_ports() const +ioport_constructor a2000_kbd_g80_dk_device::device_input_ports() const { return INPUT_PORTS_NAME(a2000_dk_keyboard); } -// ======================> a2000_kbd_gb_device +// ======================> a2000_kbd_g80_gb_device -a2000_kbd_gb_device::a2000_kbd_gb_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : a2000_kbd_device(mconfig, A2000_KBD_GB, tag, owner, clock) +a2000_kbd_g80_gb_device::a2000_kbd_g80_gb_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : a2000_kbd_g80_device(mconfig, A2000_KBD_G80_GB, tag, owner, clock) { } -ioport_constructor a2000_kbd_gb_device::device_input_ports() const +ioport_constructor a2000_kbd_g80_gb_device::device_input_ports() const { return INPUT_PORTS_NAME(a2000_gb_keyboard); } diff --git a/src/devices/bus/amiga/keyboard/a2000.h b/src/devices/bus/amiga/keyboard/a2000.h index 001f0fb78fb..900d47c5cc2 100644 --- a/src/devices/bus/amiga/keyboard/a2000.h +++ b/src/devices/bus/amiga/keyboard/a2000.h @@ -20,9 +20,9 @@ namespace bus { namespace amiga { namespace keyboard { // TYPE DECLARATIONS //************************************************************************** -// ======================> a2000_kbd_device +// ======================> a2000_kbd_g80_device -class a2000_kbd_device : public device_t, public device_amiga_keyboard_interface +class a2000_kbd_g80_device : public device_t, public device_amiga_keyboard_interface { public: // from host @@ -30,7 +30,7 @@ public: protected: // construction/destruction - a2000_kbd_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock); // MCU I/O DECLARE_READ8_MEMBER(mcu_bus_r); @@ -54,56 +54,56 @@ private: bool m_host_kdat, m_mcu_kdat, m_mcu_kclk; }; -// ======================> a2000_kbd_us_device +// ======================> a2000_kbd_g80_us_device -class a2000_kbd_us_device : public a2000_kbd_device +class a2000_kbd_g80_us_device : public a2000_kbd_g80_device { public: - a2000_kbd_us_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_us_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); protected: virtual ioport_constructor device_input_ports() const override; }; -// ======================> a2000_kbd_de_device +// ======================> a2000_kbd_g80_de_device -class a2000_kbd_de_device : public a2000_kbd_device +class a2000_kbd_g80_de_device : public a2000_kbd_g80_device { public: - a2000_kbd_de_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_de_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); protected: virtual ioport_constructor device_input_ports() const override; }; -// ======================> a2000_kbd_se_device +// ======================> a2000_kbd_g80_se_device -class a2000_kbd_se_device : public a2000_kbd_device +class a2000_kbd_g80_se_device : public a2000_kbd_g80_device { public: - a2000_kbd_se_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_se_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); protected: virtual ioport_constructor device_input_ports() const override; }; -// ======================> a2000_kbd_dk_device +// ======================> a2000_kbd_g80_dk_device -class a2000_kbd_dk_device : public a2000_kbd_device +class a2000_kbd_g80_dk_device : public a2000_kbd_g80_device { public: - a2000_kbd_dk_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_dk_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); protected: virtual ioport_constructor device_input_ports() const override; }; -// ======================> a2000_kbd_gb_device +// ======================> a2000_kbd_g80_gb_device -class a2000_kbd_gb_device : public a2000_kbd_device +class a2000_kbd_g80_gb_device : public a2000_kbd_g80_device { public: - a2000_kbd_gb_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + a2000_kbd_g80_gb_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); protected: virtual ioport_constructor device_input_ports() const override; @@ -116,10 +116,10 @@ protected: // GLOBAL VARIABLES //************************************************************************** -DECLARE_DEVICE_TYPE_NS(A2000_KBD_US, bus::amiga::keyboard, a2000_kbd_us_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_DE, bus::amiga::keyboard, a2000_kbd_de_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_SE, bus::amiga::keyboard, a2000_kbd_se_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_DK, bus::amiga::keyboard, a2000_kbd_dk_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_GB, bus::amiga::keyboard, a2000_kbd_gb_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_US, bus::amiga::keyboard, a2000_kbd_g80_us_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DE, bus::amiga::keyboard, a2000_kbd_g80_de_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_SE, bus::amiga::keyboard, a2000_kbd_g80_se_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DK, bus::amiga::keyboard, a2000_kbd_g80_dk_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_GB, bus::amiga::keyboard, a2000_kbd_g80_gb_device) #endif // MAME_BUS_AMIGA_KEYBOARD_A2000_H diff --git a/src/devices/bus/amiga/keyboard/a500.cpp b/src/devices/bus/amiga/keyboard/a500.cpp deleted file mode 100644 index 6572205f773..00000000000 --- a/src/devices/bus/amiga/keyboard/a500.cpp +++ /dev/null @@ -1,504 +0,0 @@ -// license: GPL-2.0+ -// copyright-holders: Dirk Best -/*************************************************************************** - - Amiga 500 Keyboard - - TODO: - Move 6500/1 to its own CPU core so that it can be shared with - other systems - -***************************************************************************/ - -#include "emu.h" -#include "a500.h" -#include "matrix.h" - -#include "machine/rescap.h" - - -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - -DEFINE_DEVICE_TYPE_NS(A500_KBD_US, bus::amiga::keyboard, a500_kbd_us_device, "a500_kbd_us", "Amiga 500 Keyboard (U.S./Canada)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_DE, bus::amiga::keyboard, a500_kbd_de_device, "a500_kbd_de", "Amiga 500 Keyboard (Germany/Austria)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_FR, bus::amiga::keyboard, a500_kbd_fr_device, "a500_kbd_fr", "Amiga 500 Keyboard (France/Belgium)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_IT, bus::amiga::keyboard, a500_kbd_it_device, "a500_kbd_it", "Amiga 500 Keyboard (Italy)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_SE, bus::amiga::keyboard, a500_kbd_se_device, "a500_kbd_se", "Amiga 500 Keyboard (Sweden/Finland)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_ES, bus::amiga::keyboard, a500_kbd_es_device, "a500_kbd_es", "Amiga 500 Keyboard (Spain)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_DK, bus::amiga::keyboard, a500_kbd_dk_device, "a500_kbd_dk", "Amiga 500 Keyboard (Denmark)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_CH, bus::amiga::keyboard, a500_kbd_ch_device, "a500_kbd_ch", "Amiga 500 Keyboard (Switzerland)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_NO, bus::amiga::keyboard, a500_kbd_no_device, "a500_kbd_no", "Amiga 500 Keyboard (Norway)") -DEFINE_DEVICE_TYPE_NS(A500_KBD_GB, bus::amiga::keyboard, a500_kbd_gb_device, "a500_kbd_gb", "Amiga 500 Keyboard (UK)") - - -namespace bus { namespace amiga { namespace keyboard { - -void a500_kbd_device::mpu6500_map(address_map &map) -{ - map.global_mask(0xfff); - map(0x000, 0x03f).ram(); - map(0x080, 0x080).rw(FUNC(a500_kbd_device::port_a_r), FUNC(a500_kbd_device::port_a_w)); - map(0x081, 0x081).portr("special").w(FUNC(a500_kbd_device::port_b_w)); - map(0x082, 0x082).w(FUNC(a500_kbd_device::port_c_w)); - map(0x083, 0x083).w(FUNC(a500_kbd_device::port_d_w)); - map(0x084, 0x085).w(FUNC(a500_kbd_device::latch_w)); - map(0x086, 0x087).r(FUNC(a500_kbd_device::counter_r)); - map(0x088, 0x088).w(FUNC(a500_kbd_device::transfer_latch_w)); - map(0x089, 0x089).w(FUNC(a500_kbd_device::clear_pa0_detect)); - map(0x08a, 0x08a).w(FUNC(a500_kbd_device::clear_pa1_detect)); - map(0x08f, 0x08f).rw(FUNC(a500_kbd_device::control_r), FUNC(a500_kbd_device::control_w)); - map(0x090, 0x0ff).noprw(); - map(0x800, 0xfff).rom().region("ic1", 0); -} - -namespace { - -//------------------------------------------------- -// rom_region - device-specific ROM region -//------------------------------------------------- - -ROM_START( kbd_pcb ) - ROM_REGION(0x800, "ic1", 0) - ROM_LOAD("328191-02.ic1", 0x000, 0x800, CRC(4a3fc332) SHA1(83b21d0c8b93fc9b9b3b287fde4ec8f3badac5a2)) -ROM_END - -//------------------------------------------------- -// input_ports - device-specific input ports -//------------------------------------------------- - -INPUT_PORTS_START( a500_special ) - PORT_START("special") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LWIN) PORT_CHAR(UCHAR_MAMEKEY(LWIN)) PORT_NAME("Left Amiga") PORT_CHANGED_MEMBER(DEVICE_SELF, a500_kbd_device, check_reset, nullptr) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) PORT_NAME("Left Alt") - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Left Shift") - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Ctrl") PORT_CHANGED_MEMBER(DEVICE_SELF, a500_kbd_device, check_reset, nullptr) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RWIN) PORT_CHAR(UCHAR_MAMEKEY(RWIN)) PORT_NAME("Right Amiga") PORT_CHANGED_MEMBER(DEVICE_SELF, a500_kbd_device, check_reset, nullptr) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("Right Alt") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) PORT_NAME("Right Shift") -INPUT_PORTS_END - -INPUT_PORTS_START( a500_us_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_us) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_de_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_de) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_fr_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_fr) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_it_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_it) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_se_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_se) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_es_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_es) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_dk_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_dk) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_ch_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_ch) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_no_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_no) -INPUT_PORTS_END - -INPUT_PORTS_START( a500_gb_keyboard ) - PORT_INCLUDE(a500_special) - PORT_INCLUDE(matrix_gb) -INPUT_PORTS_END - -} // anonymous namespace - - -//------------------------------------------------- -// device_add_mconfig - add device configuration -//------------------------------------------------- - - -MACHINE_CONFIG_START(a500_kbd_device::device_add_mconfig) - MCFG_DEVICE_ADD("ic1", M6502, XTAL(3'000'000) / 2) - MCFG_DEVICE_PROGRAM_MAP(mpu6500_map) -MACHINE_CONFIG_END - -const tiny_rom_entry *a500_kbd_device::device_rom_region() const -{ - return ROM_NAME(kbd_pcb); -} - -ioport_constructor a500_kbd_us_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_us_keyboard ); } -ioport_constructor a500_kbd_de_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_de_keyboard ); } -ioport_constructor a500_kbd_fr_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_fr_keyboard ); } -ioport_constructor a500_kbd_it_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_it_keyboard ); } -ioport_constructor a500_kbd_se_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_se_keyboard ); } -ioport_constructor a500_kbd_es_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_es_keyboard ); } -ioport_constructor a500_kbd_dk_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_dk_keyboard ); } -ioport_constructor a500_kbd_ch_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_ch_keyboard ); } -ioport_constructor a500_kbd_no_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_no_keyboard ); } -ioport_constructor a500_kbd_gb_device::device_input_ports() const { return INPUT_PORTS_NAME( a500_gb_keyboard ); } - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -a500_kbd_device::a500_kbd_device( - const machine_config &mconfig, - const char *tag, - device_t *owner, - uint32_t clock, - device_type type) : - device_t(mconfig, type, tag, owner, clock), - device_amiga_keyboard_interface(mconfig, *this), - m_mpu(*this, "ic1"), - m_special(*this, "special"), - m_rows(*this, "ROW%u", 0), - m_timer(nullptr), - m_watchdog(nullptr), - m_reset(nullptr), - m_host_kdat(1), - m_mpu_kdat(1), - m_kclk(1), - m_port_c(0xff), - m_port_d(0xff), - m_latch(0xffff), - m_counter(0xffff), - m_control(0x00) -{ -} - - -a500_kbd_us_device::a500_kbd_us_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_US) -{ -} - -a500_kbd_de_device::a500_kbd_de_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_DE) -{ -} - -a500_kbd_fr_device::a500_kbd_fr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_FR) -{ -} - -a500_kbd_it_device::a500_kbd_it_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_IT) -{ -} - -a500_kbd_se_device::a500_kbd_se_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_SE) -{ -} - -a500_kbd_es_device::a500_kbd_es_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_ES) -{ -} - -a500_kbd_dk_device::a500_kbd_dk_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_DK) -{ -} - -a500_kbd_ch_device::a500_kbd_ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_CH) -{ -} - -a500_kbd_no_device::a500_kbd_no_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_NO) -{ -} - -a500_kbd_gb_device::a500_kbd_gb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - a500_kbd_device(mconfig, tag, owner, clock, A500_KBD_GB) -{ -} - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void a500_kbd_device::device_start() -{ - // allocate timers - m_timer = timer_alloc(0, nullptr); - m_watchdog = timer_alloc(1, nullptr); - m_reset = timer_alloc(2, nullptr); - - // register for save states - save_item(NAME(m_host_kdat)); - save_item(NAME(m_mpu_kdat)); - save_item(NAME(m_kclk)); - save_item(NAME(m_port_c)); - save_item(NAME(m_port_d)); - save_item(NAME(m_latch)); - save_item(NAME(m_counter)); - save_item(NAME(m_control)); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void a500_kbd_device::device_reset() -{ - // stack starts 0 - m_mpu->set_state_int(M6502_S, 0); - - m_host_kdat = 1; - m_mpu_kdat = 1; - m_kclk = 1; - m_port_c = 0xff; - m_port_d = 0xff; - m_latch = 0xffff; // not initialized by hardware - m_counter = 0xffff; // not initialized by hardware - m_control = 0x00; - - m_timer->adjust(attotime::zero, 0, attotime::from_hz(XTAL(3'000'000) / 2)); - m_watchdog->adjust(attotime::from_msec(54)); -} - -void a500_kbd_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) -{ - switch (tid) - { - // 6500/1 internal timer - case 0: - switch (m_control & 0x03) - { - // interval timer, pulse width measurement (connected to gnd here) - case 0: - case 3: - if (m_counter-- == 0) - { - // counter overflow - m_control |= COUNTER_OVERFLOW; - m_counter = m_latch; - - // generate interrupt? - update_irqs(); - } - break; - - // pulse generator - case 1: - break; - - // event counter - case 2: - break; - } - break; - - // watchdog - case 1: - m_mpu->reset(); - m_watchdog->adjust(attotime::from_msec(54)); - break; - - // keyboard reset timer - case 2: - m_host->krst_w(1); - break; - } -} - - -//************************************************************************** -// IMPLEMENTATION -//************************************************************************** - -INPUT_CHANGED_MEMBER( a500_kbd_device::check_reset ) -{ - uint8_t keys = m_special->read(); - - // ctrl-amiga-amiga pressed? - if (!BIT(keys, 6) && !BIT(keys, 3) && !BIT(keys, 2)) - { - m_host->krst_w(0); - m_reset->adjust(PERIOD_OF_555_MONOSTABLE(RES_K(47), CAP_U(10))); - } -} - -void a500_kbd_device::update_irqs() -{ - if ((m_control & PA1_INT_ENABLED) && (m_control & PA1_NEGATIVE_EDGE)) - m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); - - else if ((m_control & PA0_INT_ENABLED) && (m_control & PA0_POSITIVE_EDGE)) - m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); - - else if ((m_control & COUNTER_INT_ENABLED) && (m_control & COUNTER_OVERFLOW)) - m_mpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); - - else - m_mpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); -} - -READ8_MEMBER( a500_kbd_device::port_a_r ) -{ - uint8_t data = 0xfc; - - // kdat & kclk - data |= (m_host_kdat & m_mpu_kdat) << 0; - data |= m_kclk << 1; - - // scan port d and c rows - uint16_t const row_drive = (uint16_t(m_port_d | 0x80) << 8) | uint16_t(m_port_c); - for (unsigned i = 0; i < m_rows.size(); i++) - if (!BIT(row_drive, m_rows.size() - i - 1)) data &= m_rows[i]->read(); - - return data; -} - -WRITE8_MEMBER( a500_kbd_device::port_a_w ) -{ - // look for pa0 edge - if (m_host_kdat && !m_mpu_kdat && BIT(data, 0)) - { - m_control |= PA0_POSITIVE_EDGE; - update_irqs(); - } - - // and pa1 edge - if (m_kclk && !BIT(data, 1)) - { - m_control |= PA1_NEGATIVE_EDGE; - update_irqs(); - } - - // update with new values and output - if (m_mpu_kdat != BIT(data, 0)) - { - m_mpu_kdat = BIT(data, 0); - m_host->kdat_w(m_mpu_kdat); - } - - if (m_kclk != BIT(data, 1)) - { - m_kclk = BIT(data, 1); - m_host->kclk_w(m_kclk); - } -} - -WRITE8_MEMBER( a500_kbd_device::port_b_w ) -{ - // caps lock led - machine().output().set_value("led_kbd_caps", BIT(data, 7)); -} - -WRITE8_MEMBER( a500_kbd_device::port_c_w ) -{ - m_port_c = data; -} - -WRITE8_MEMBER( a500_kbd_device::port_d_w ) -{ - // reset watchdog on 0 -> 1 transition - if (!BIT(m_port_d, 7) && BIT(data, 7)) - m_watchdog->adjust(attotime::from_msec(54)); - - m_port_d = data; -} - -WRITE8_MEMBER( a500_kbd_device::latch_w ) -{ - if (offset == 0) - { - m_latch &= 0x00ff; - m_latch |= data << 8; - } - else - { - m_latch &= 0xff00; - m_latch |= data << 0; - } -} - -READ8_MEMBER( a500_kbd_device::counter_r ) -{ - if (!machine().side_effects_disabled()) - { - m_control &= ~COUNTER_OVERFLOW; - update_irqs(); - } - - if (offset == 0) - return m_counter >> 8; - else - return m_counter >> 0; -} - -WRITE8_MEMBER( a500_kbd_device::transfer_latch_w ) -{ - m_control &= ~COUNTER_OVERFLOW; - update_irqs(); - - m_latch &= 0x00ff; - m_latch |= data << 8; - - m_counter = m_latch; -} - -WRITE8_MEMBER( a500_kbd_device::clear_pa0_detect ) -{ - m_control &= ~PA0_POSITIVE_EDGE; - update_irqs(); -} - -WRITE8_MEMBER( a500_kbd_device::clear_pa1_detect ) -{ - m_control &= ~PA1_NEGATIVE_EDGE; - update_irqs(); -} - -READ8_MEMBER( a500_kbd_device::control_r ) -{ - return m_control; -} - -WRITE8_MEMBER( a500_kbd_device::control_w ) -{ - m_control = data; - update_irqs(); -} - -WRITE_LINE_MEMBER( a500_kbd_device::kdat_w ) -{ - // detect positive edge - if (!m_host_kdat && m_mpu_kdat && state) - { - m_control |= PA0_POSITIVE_EDGE; - update_irqs(); - } - - m_host_kdat = state; -} - -} } } // namespace bus::amiga::keyboard diff --git a/src/devices/bus/amiga/keyboard/a500.h b/src/devices/bus/amiga/keyboard/a500.h deleted file mode 100644 index f5ff92f9efb..00000000000 --- a/src/devices/bus/amiga/keyboard/a500.h +++ /dev/null @@ -1,253 +0,0 @@ -// license: GPL-2.0+ -// copyright-holders: Dirk Best -/*************************************************************************** - - Amiga 500 Keyboard - - Assembly part numbers: - - - 312502-01 U.S./Canada - - 312502-02 Germany/Austria - - 312502-03 France/Belgium - - 312502-04 Italy - - 312502-05 Sweden/Finland - - 312502-06 Spain - - 312502-07 Denmark - - 312502-08 Switzerland - - 312502-09 Norway - - 312502-12 UK - - Amiga 1000 (for reference, to be moved): - - - 327063-01 U.S./Canada - - 327063-02 UK - - 327063-03 Germany - - 327063-04 France - - 327063-05 Italy - -***************************************************************************/ - -#ifndef MAME_BUS_AMIGA_KEYBOARD_A500_H -#define MAME_BUS_AMIGA_KEYBOARD_A500_H - -#pragma once - -#include "keyboard.h" -#include "cpu/m6502/m6502.h" - - -namespace bus { namespace amiga { namespace keyboard { - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> a500_kbd_device - -class a500_kbd_device : public device_t, public device_amiga_keyboard_interface -{ -public: - - DECLARE_INPUT_CHANGED_MEMBER(check_reset); - -protected: - a500_kbd_device( - const machine_config &mconfig, - const char *tag, - device_t *owner, - uint32_t clock, - device_type type); - - // device-level overrides - virtual const tiny_rom_entry *device_rom_region() const override; - virtual void device_add_mconfig(machine_config &config) override; - 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; - - // from host - virtual DECLARE_WRITE_LINE_MEMBER(kdat_w) override; - -private: - enum - { - // counter modes - COUNTER_INTERVAL = 0x00, - COUNTER_PULSE = 0x01, - COUNTER_EVENT = 0x02, - COUNTER_PWM = 0x03, - - // interrupt enables - PA1_INT_ENABLED = 0x04, - PA0_INT_ENABLED = 0x08, - COUNTER_INT_ENABLED = 0x10, - - // status - PA1_NEGATIVE_EDGE = 0x20, - PA0_POSITIVE_EDGE = 0x40, - COUNTER_OVERFLOW = 0x80 - }; - - void update_irqs(); - - required_device m_mpu; - required_ioport m_special; - required_ioport_array<15> m_rows; - - emu_timer *m_timer; - emu_timer *m_watchdog; - emu_timer *m_reset; - - int m_host_kdat; - int m_mpu_kdat; - int m_kclk; - - uint8_t m_port_c; - uint8_t m_port_d; - uint16_t m_latch; - uint16_t m_counter; - uint8_t m_control; - - // 6500/1 internal - DECLARE_READ8_MEMBER(port_a_r); - DECLARE_WRITE8_MEMBER(port_a_w); - DECLARE_WRITE8_MEMBER(port_b_w); - DECLARE_WRITE8_MEMBER(port_c_w); - DECLARE_WRITE8_MEMBER(port_d_w); - DECLARE_WRITE8_MEMBER(latch_w); - DECLARE_READ8_MEMBER(counter_r); - DECLARE_WRITE8_MEMBER(transfer_latch_w); - DECLARE_WRITE8_MEMBER(clear_pa0_detect); - DECLARE_WRITE8_MEMBER(clear_pa1_detect); - DECLARE_READ8_MEMBER(control_r); - DECLARE_WRITE8_MEMBER(control_w); - - void mpu6500_map(address_map &map); -}; - -// ======================> a500_kbd_us_device - -class a500_kbd_us_device : public a500_kbd_device -{ -public: - a500_kbd_us_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_de_device - -class a500_kbd_de_device : public a500_kbd_device -{ -public: - a500_kbd_de_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_fr_device - -class a500_kbd_fr_device : public a500_kbd_device -{ -public: - a500_kbd_fr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_it_device - -class a500_kbd_it_device : public a500_kbd_device -{ -public: - a500_kbd_it_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_se_device - -class a500_kbd_se_device : public a500_kbd_device -{ -public: - a500_kbd_se_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_es_device - -class a500_kbd_es_device : public a500_kbd_device -{ -public: - a500_kbd_es_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_dk_device - -class a500_kbd_dk_device : public a500_kbd_device -{ -public: - a500_kbd_dk_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_ch_device - -class a500_kbd_ch_device : public a500_kbd_device -{ -public: - a500_kbd_ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_no_device - -class a500_kbd_no_device : public a500_kbd_device -{ -public: - a500_kbd_no_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -// ======================> a500_kbd_gb_device - -class a500_kbd_gb_device : public a500_kbd_device -{ -public: - a500_kbd_gb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual ioport_constructor device_input_ports() const override; -}; - -} } } // namespace bus::amiga::keyboard - - -// device type definition -DECLARE_DEVICE_TYPE_NS(A500_KBD_US, bus::amiga::keyboard, a500_kbd_us_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_DE, bus::amiga::keyboard, a500_kbd_de_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_FR, bus::amiga::keyboard, a500_kbd_fr_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_IT, bus::amiga::keyboard, a500_kbd_it_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_SE, bus::amiga::keyboard, a500_kbd_se_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_ES, bus::amiga::keyboard, a500_kbd_es_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_DK, bus::amiga::keyboard, a500_kbd_dk_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_CH, bus::amiga::keyboard, a500_kbd_ch_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_NO, bus::amiga::keyboard, a500_kbd_no_device) -DECLARE_DEVICE_TYPE_NS(A500_KBD_GB, bus::amiga::keyboard, a500_kbd_gb_device) - -#endif // MAME_BUS_AMIGA_KEYBOARD_A500_H diff --git a/src/devices/bus/amiga/keyboard/keyboard.cpp b/src/devices/bus/amiga/keyboard/keyboard.cpp index d3c3275d2ae..ec70072ce5a 100644 --- a/src/devices/bus/amiga/keyboard/keyboard.cpp +++ b/src/devices/bus/amiga/keyboard/keyboard.cpp @@ -8,9 +8,10 @@ #include "emu.h" #include "keyboard.h" -#include "a500.h" + #include "a1200.h" #include "a2000.h" +#include "mitsumi.h" //************************************************************************** @@ -106,6 +107,26 @@ device_amiga_keyboard_interface::~device_amiga_keyboard_interface() //************************************************************************** void amiga_keyboard_devices(device_slot_interface &device) +{ + device.option_add("a1200_us", A1200_KBD); // FIXME: sort this out properly when we get mask ROM dumps + device.option_add("a2000_g80_us", A2000_KBD_G80_US); + device.option_add("a2000_g80_de", A2000_KBD_G80_DE); + device.option_add("a2000_g80_se", A2000_KBD_G80_SE); + device.option_add("a2000_g80_dk", A2000_KBD_G80_DK); + device.option_add("a2000_g80_gb", A2000_KBD_G80_GB); + device.option_add("a2000_us", A2000_KBD_US); + device.option_add("a2000_de", A2000_KBD_DE); + device.option_add("a2000_fr", A2000_KBD_FR); + device.option_add("a2000_it", A2000_KBD_IT); + device.option_add("a2000_se", A2000_KBD_SE); + device.option_add("a2000_es", A2000_KBD_ES); + device.option_add("a2000_dk", A2000_KBD_DK); + device.option_add("a2000_ch", A2000_KBD_CH); + device.option_add("a2000_no", A2000_KBD_NO); + device.option_add("a2000_gb", A2000_KBD_GB); +} + +void a500_keyboard_devices(device_slot_interface &device) { device.option_add("a500_us", A500_KBD_US); device.option_add("a500_de", A500_KBD_DE); @@ -117,10 +138,18 @@ void amiga_keyboard_devices(device_slot_interface &device) device.option_add("a500_ch", A500_KBD_CH); device.option_add("a500_no", A500_KBD_NO); device.option_add("a500_gb", A500_KBD_GB); - device.option_add("a1200_us", A1200_KBD); - device.option_add("a2000_us", A2000_KBD_US); - device.option_add("a2000_de", A2000_KBD_DE); - device.option_add("a2000_se", A2000_KBD_SE); - device.option_add("a2000_dk", A2000_KBD_DK); - device.option_add("a2000_gb", A2000_KBD_GB); +} + +void a600_keyboard_devices(device_slot_interface &device) +{ + device.option_add("a600_us", A600_KBD_US); + device.option_add("a600_de", A600_KBD_DE); + device.option_add("a600_fr", A600_KBD_FR); + device.option_add("a600_it", A600_KBD_IT); + device.option_add("a600_se", A600_KBD_SE); + device.option_add("a600_es", A600_KBD_ES); + device.option_add("a600_dk", A600_KBD_DK); + device.option_add("a600_ch", A600_KBD_CH); + device.option_add("a600_no", A600_KBD_NO); + device.option_add("a600_gb", A600_KBD_GB); } diff --git a/src/devices/bus/amiga/keyboard/keyboard.h b/src/devices/bus/amiga/keyboard/keyboard.h index 5fb210afa29..496917d9d15 100644 --- a/src/devices/bus/amiga/keyboard/keyboard.h +++ b/src/devices/bus/amiga/keyboard/keyboard.h @@ -23,9 +23,9 @@ // INTERFACE CONFIGURATION MACROS //************************************************************************** -#define MCFG_AMIGA_KEYBOARD_INTERFACE_ADD(_tag, _def_slot) \ +#define MCFG_AMIGA_KEYBOARD_INTERFACE_ADD(_tag, _opts, _def_slot) \ MCFG_DEVICE_ADD(_tag, AMIGA_KEYBOARD_INTERFACE, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(amiga_keyboard_devices, _def_slot, false) + MCFG_DEVICE_SLOT_INTERFACE(_opts, _def_slot, false) #define MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(_devcb) \ downcast(*device).set_kclk_handler(DEVCB_##_devcb); @@ -99,5 +99,7 @@ DECLARE_DEVICE_TYPE(AMIGA_KEYBOARD_INTERFACE, amiga_keyboard_bus_device) // supported devices void amiga_keyboard_devices(device_slot_interface &device); +void a500_keyboard_devices(device_slot_interface &device); +void a600_keyboard_devices(device_slot_interface &device); #endif // MAME_BUS_AMIGA_KEYBOARD_H diff --git a/src/devices/bus/amiga/keyboard/matrix.cpp b/src/devices/bus/amiga/keyboard/matrix.cpp index 04b29205a0b..8a89e5a389b 100644 --- a/src/devices/bus/amiga/keyboard/matrix.cpp +++ b/src/devices/bus/amiga/keyboard/matrix.cpp @@ -775,6 +775,9 @@ INPUT_PORTS_END INPUT_PORTS_START(matrix_gb) PORT_INCLUDE(matrix_us) + PORT_MODIFY("ROW0") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH2) PORT_NAME("Left Blank") + PORT_MODIFY("ROW2") PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') PORT_CHAR(0x00b2) // ² @@ -783,6 +786,56 @@ INPUT_PORTS_START(matrix_gb) PORT_MODIFY("ROW11") PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('#') PORT_CHAR('@') PORT_CHAR('\'') PORT_CHAR('"') + + PORT_MODIFY("ROW12") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11) PORT_NAME("Right Blank") +INPUT_PORTS_END + +INPUT_PORTS_START(remove_keypad) + PORT_MODIFY("ROW0") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW1") + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW2") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW4") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW5") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW6") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW7") + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW8") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW9") + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW10") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW11") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW12") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW13") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_MODIFY("ROW14") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) INPUT_PORTS_END } } } // namespace bus::amiga::keyboard diff --git a/src/devices/bus/amiga/keyboard/matrix.h b/src/devices/bus/amiga/keyboard/matrix.h index 9bfa801f9c8..3647dd69e57 100644 --- a/src/devices/bus/amiga/keyboard/matrix.h +++ b/src/devices/bus/amiga/keyboard/matrix.h @@ -23,6 +23,7 @@ INPUT_PORTS_EXTERN(matrix_dk); INPUT_PORTS_EXTERN(matrix_ch); INPUT_PORTS_EXTERN(matrix_no); INPUT_PORTS_EXTERN(matrix_gb); +INPUT_PORTS_EXTERN(remove_keypad); } } } // namespace bus::amiga::keyboard diff --git a/src/devices/bus/amiga/keyboard/mitsumi.cpp b/src/devices/bus/amiga/keyboard/mitsumi.cpp new file mode 100644 index 00000000000..2fb57e66690 --- /dev/null +++ b/src/devices/bus/amiga/keyboard/mitsumi.cpp @@ -0,0 +1,887 @@ +// license: BSD-3-Clause +// copyright-holders: Vas Crabb +/*************************************************************************** + + mitsumi.cpp + + Fifteen rows by six columns, plus seven dedicated meta key inputs. + + Newer external keyboards and the Amiga 500 keyboard have an external + watchdog circuit built from a 74LS123. Older external keyboards and + the Amiga 600 keyboard lack this. If CNTR is tied low, the program + expects the watchdog to be present. + + Note that the Ctrl-Amiga-Amiga detection circuit is not present in + external "big box" keyboards. It's implemented in the base class + here for convenience. In the Amiga 600, it's possible for the MCU + to read or drive the input to the reset pulse generator via PA7 + (assuming R624 has a low enough resistance), but this isn't used. + + The Amiga 500 and Amiga 600 keyboards generate a reset pulse on a + dedicated line using an NE555 timer. These systems won't generate a + system reset in response to the KCLK line being held low for an + extended period. No reset warning is generated before the reset + pulse on these systems. + + The NE555 used of generating the reset pulse on Amiga 600 keyboards + also provides power-on reset, and its output is combined with a + power good signal on Rev 2C and later machines. + + Newer external keyboards have a 74HC00 in addition to the 74LS123. + The exact purpose of this chip is unknown. + + We need better photos of the Hi-Tek version of the Amiga 2000 + keyboard to identify the chips (40-pin MCU, two 14-pin DIPs, one + 8-pin DIP). + + Known Amiga 500 keyboard part numbers: + * 312502-01 U.S./Canada + * 312502-02 Germany/Austria + * 312502-03 France/Belgium + * 312502-04 Italy + * 312502-05 Sweden/Finland + * 312502-06 Spain + * 312502-07 Denmark + * 312502-08 Switzerland + * 312502-09 Norway + * 312502-12 UK + + Known Amiga 1000 keyboard part numbers: + * 327063-01 U.S./Canada + * 327063-02 UK + * 327063-03 Germany + * 327063-04 France + * 327063-05 Italy + + Known Amiga 2000 keyboard part numbers: + * 312716-02 U.S./Canada + + Known Amiga CDTV keyboard part numbers: + * 364351-01 U.S./Canada + +***************************************************************************/ + +#include "emu.h" +#include "mitsumi.h" + +#include "matrix.h" + +#include "cpu/m6502/m6500_1.h" +#include "machine/input_merger.h" +#include "machine/rescap.h" + + +namespace { + +ROM_START(keyboard_new) + ROM_REGION(0x0800, "mcu", 0) + ROM_LOAD("6570-036", 0x0000, 0x0800, CRC(4a3fc332) SHA1(83b21d0c8b93fc9b9b3b287fde4ec8f3badac5a2)) +ROM_END + + +class mitsumi_keyboard_base : public device_t, public device_amiga_keyboard_interface +{ +public: + virtual WRITE_LINE_MEMBER(kdat_w) override + { + m_kdat_in = state ? 0x01U : 0x00U; + m_mcu->pa_w(machine().dummy_space(), 0, m_meta->read()); + } + + CUSTOM_INPUT_MEMBER(kdat_r) + { + return m_kdat_in ^ 0x01U; + } + + CUSTOM_INPUT_MEMBER(cols_r) + { + ioport_value result(0xffU); + for (unsigned i = 0U; m_rows.size() > i; ++i) + { + if (!BIT(m_row_drive, m_rows.size() - 1 - i)) + result &= m_rows[i]->read(); + } + return (result >> 2) ^ 0x3fU; + } + + CUSTOM_INPUT_MEMBER(reset_r) + { + return m_reset; + } + + DECLARE_INPUT_CHANGED_MEMBER(check_reset) + { + u8 const state((m_meta->read() & 0x4cU) ? 0x00 : 0x01); + if (state != m_reset) + { + m_reset = state; + reset_changed(bool(state)); + } + } + +protected: + mitsumi_keyboard_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_amiga_keyboard_interface(mconfig, *this) + , m_mcu{ *this, "mcu" } + , m_rows{ *this, "ROW%u", 0U } + , m_meta{ *this, "META" } + { + } + + virtual tiny_rom_entry const *device_rom_region() const override + { + return ROM_NAME(keyboard_new); + } + + virtual void device_add_mconfig(machine_config &config) override + { + M6500_1(config, m_mcu, 3_MHz_XTAL); + m_mcu->pa_in_cb().set_ioport("COLS"); + m_mcu->pb_in_cb().set_ioport("META"); + m_mcu->pa_out_cb().set([this] (u8 data) { m_host->kdat_w(data); }).bit(0); + m_mcu->pa_out_cb().append([this] (u8 data) { m_host->kclk_w(data); }).bit(1); + m_mcu->pb_out_cb().set_output("led_kbd_caps").bit(7); + m_mcu->pc_out_cb().set([this] (u8 data) { m_row_drive = (m_row_drive & 0xff00U) | u16(data); }); + m_mcu->pd_out_cb().set([this] (u8 data) { m_row_drive = (m_row_drive & 0x80ffU) | (u16(data) << 8); }).mask(0x7f); + } + + virtual void device_start() override + { + save_item(NAME(m_row_drive)); + save_item(NAME(m_kdat_in)); + save_item(NAME(m_reset)); + } + + virtual void reset_changed(bool state) + { + } + + required_device m_mcu; + +private: + required_ioport_array<15> m_rows; + required_ioport m_meta; + + u16 m_row_drive = 0xffffU; + u8 m_kdat_in = 0x01; + u8 m_reset = 0x00; +}; + + +class mitsumi_watchdog_keyboard_base : public mitsumi_keyboard_base +{ +protected: + using mitsumi_keyboard_base::mitsumi_keyboard_base; + + virtual void device_add_mconfig(machine_config &config) override + { + mitsumi_keyboard_base::device_add_mconfig(config); + + m_mcu->pd_out_cb().append(FUNC(mitsumi_watchdog_keyboard_base::pd7_w)).bit(7); + } + + virtual void device_start() override + { + mitsumi_keyboard_base::device_start(); + + m_wd_timeout = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mitsumi_watchdog_keyboard_base::wd_timeout), this)); + m_wd_pulse = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mitsumi_watchdog_keyboard_base::wd_pulse), this)); + + m_pd7 = 0x01U; + + save_item(NAME(m_pd7)); + } + + virtual void device_reset() override + { + mitsumi_keyboard_base::device_reset(); + + m_mcu->cntr_w(0); + } + + virtual void watchdog_changed(bool state) + { + m_mcu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); + } + +private: + WRITE_LINE_MEMBER(pd7_w) + { + if (bool(state) != bool(m_pd7)) + { + m_pd7 = state ? 0x01U : 0x00U; + if (!state) + { + // 74LS123 with Rt = 120kΩ and Cext = 1µF + // t = K * Rt * Cext * (1 + (0.7 / Rt)) = 0.28 * 120k * 1µ * (1 + (0.7 / 120k)) ≈ 33.6ms + m_wd_timeout->adjust(attotime::from_usec(33600)); + } + } + } + + TIMER_CALLBACK_MEMBER(wd_timeout) + { + // 74LS123 with Rt = 10kΩ and Cext = 100nF + // t = K * Rt * Cext * (1 + (0.7 / Rt)) = 0.28 * 10k * 100n * (1 + (0.7 / 10k)) ≈ 280µs + m_wd_pulse->adjust(attotime::from_usec(280)); + watchdog_changed(true); + } + + TIMER_CALLBACK_MEMBER(wd_pulse) + { + watchdog_changed(false); + } + + emu_timer *m_wd_timeout = nullptr; + emu_timer *m_wd_pulse = nullptr; + + u8 m_pd7 = 0x01U; +}; + + +class a500_keyboard_base : public mitsumi_watchdog_keyboard_base +{ +protected: + a500_keyboard_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, type, tag, owner, clock) + , m_reset_merger(*this, "reset") + { + } + + virtual void device_add_mconfig(machine_config &config) override + { + mitsumi_watchdog_keyboard_base::device_add_mconfig(config); + + INPUT_MERGER_ANY_HIGH(config, m_reset_merger).output_handler().set_inputline(m_mcu, INPUT_LINE_RESET); + } + + virtual void device_start() override + { + mitsumi_watchdog_keyboard_base::device_start(); + + m_reset_pulse = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a500_keyboard_base::reset_pulse), this)); + } + + virtual void reset_changed(bool state) override + { + if (state) + { + m_host->krst_w(0); + m_reset_merger->in_w<0>(1); + m_reset_pulse->adjust(PERIOD_OF_555_MONOSTABLE(RES_K(47), CAP_U(10))); + } + } + + virtual void watchdog_changed(bool state) override + { + m_reset_merger->in_w<1>(state ? 1 : 0); + } + +private: + TIMER_CALLBACK_MEMBER(reset_pulse) + { + m_host->krst_w(1); + m_reset_merger->in_w<0>(0); + } + + required_device m_reset_merger; + + emu_timer *m_reset_pulse = nullptr; +}; + + +class a600_keyboard_base : public mitsumi_keyboard_base +{ +protected: + a600_keyboard_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) + : mitsumi_keyboard_base(mconfig, type, tag, owner, clock) + , m_reset_merger(*this, "reset") + { + } + + virtual void device_add_mconfig(machine_config &config) override + { + mitsumi_keyboard_base::device_add_mconfig(config); + + m_mcu->pa_out_cb().append(m_reset_merger, FUNC(input_merger_device::in_w<0>)).bit(7); + + INPUT_MERGER_ANY_LOW(config, m_reset_merger).output_handler().set(FUNC(a600_keyboard_base::reset_trigger)); + } + + virtual void device_start() override + { + mitsumi_keyboard_base::device_start(); + + m_reset_pulse = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a600_keyboard_base::reset_pulse), this)); + + m_reset_trigger = 0x00U; + + save_item(NAME(m_reset_trigger)); + } + + virtual void reset_changed(bool state) override + { + m_reset_merger->in_w<1>(state ? 0 : 1); + } + +private: + WRITE_LINE_MEMBER(reset_trigger) + { + if (bool(state) != bool(m_reset_trigger)) + { + m_reset_trigger = state ? 0x01U : 0x00U; + if (state) + { + m_host->krst_w(0); + m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_reset_pulse->adjust(PERIOD_OF_555_MONOSTABLE(RES_K(47), CAP_U(10))); + } + } + } + + TIMER_CALLBACK_MEMBER(reset_pulse) + { + m_host->krst_w(1); + m_mcu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + } + + required_device m_reset_merger; + + emu_timer *m_reset_pulse = nullptr; + + u8 m_reset_trigger = 0x00U; +}; + + +INPUT_PORTS_START(fullsize_cols) + PORT_START("COLS") + PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, cols_r, nullptr) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, kdat_r, nullptr) +INPUT_PORTS_END + +INPUT_PORTS_START(compact_cols) + PORT_START("COLS") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, reset_r, nullptr) + PORT_BIT(0x7c, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, cols_r, nullptr) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, kdat_r, nullptr) +INPUT_PORTS_END + +INPUT_PORTS_START(mitsumi_meta) + PORT_START("META") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LWIN) PORT_CHAR(UCHAR_MAMEKEY(LWIN)) PORT_NAME("Left Amiga") PORT_CHANGED_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, check_reset, nullptr) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) PORT_NAME("Left Alt") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Left Shift") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Ctrl") PORT_CHANGED_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, check_reset, nullptr) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RWIN) PORT_CHAR(UCHAR_MAMEKEY(RWIN)) PORT_NAME("Right Amiga") PORT_CHANGED_MEMBER(DEVICE_SELF, mitsumi_keyboard_base, check_reset, nullptr) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("Right Alt") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) PORT_NAME("Right Shift") +INPUT_PORTS_END + + +INPUT_PORTS_START(fullsize_us) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_us(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_de) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_de(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_fr) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_fr(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_it) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_it(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_se) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_se(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_es) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_es(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_dk) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_dk(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_ch) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_ch(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_no) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_no(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(fullsize_gb) + PORT_INCLUDE(fullsize_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_gb(owner, portlist, errorbuf); +INPUT_PORTS_END + + +INPUT_PORTS_START(compact_us) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_us(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_de) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_de(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_fr) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_fr(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_it) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_it(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_se) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_se(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_es) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_es(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_dk) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_dk(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_ch) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_ch(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_no) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_no(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + +INPUT_PORTS_START(compact_gb) + PORT_INCLUDE(compact_cols) + PORT_INCLUDE(mitsumi_meta) + bus::amiga::keyboard::construct_ioport_matrix_gb(owner, portlist, errorbuf); + bus::amiga::keyboard::construct_ioport_remove_keypad(owner, portlist, errorbuf); +INPUT_PORTS_END + + +class a500_keyboard_us : public a500_keyboard_base +{ +public: + a500_keyboard_us(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_US, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_us); } +}; + +class a500_keyboard_de : public a500_keyboard_base +{ +public: + a500_keyboard_de(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_DE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_de); } +}; + +class a500_keyboard_fr : public a500_keyboard_base +{ +public: + a500_keyboard_fr(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_FR, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_fr); } +}; + +class a500_keyboard_it : public a500_keyboard_base +{ +public: + a500_keyboard_it(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_IT, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_it); } +}; + +class a500_keyboard_se : public a500_keyboard_base +{ +public: + a500_keyboard_se(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_SE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_se); } +}; + +class a500_keyboard_es : public a500_keyboard_base +{ +public: + a500_keyboard_es(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_ES, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_es); } +}; + +class a500_keyboard_dk : public a500_keyboard_base +{ +public: + a500_keyboard_dk(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_DK, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_dk); } +}; + +class a500_keyboard_ch : public a500_keyboard_base +{ +public: + a500_keyboard_ch(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_CH, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_ch); } +}; + +class a500_keyboard_no : public a500_keyboard_base +{ +public: + a500_keyboard_no(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_NO, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_no); } +}; + +class a500_keyboard_gb : public a500_keyboard_base +{ +public: + a500_keyboard_gb(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a500_keyboard_base(mconfig, A500_KBD_GB, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_gb); } +}; + + +class a600_keyboard_us : public a600_keyboard_base +{ +public: + a600_keyboard_us(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_US, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_us); } +}; + +class a600_keyboard_de : public a600_keyboard_base +{ +public: + a600_keyboard_de(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_DE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_de); } +}; + +class a600_keyboard_fr : public a600_keyboard_base +{ +public: + a600_keyboard_fr(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_FR, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_fr); } +}; + +class a600_keyboard_it : public a600_keyboard_base +{ +public: + a600_keyboard_it(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_IT, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_it); } +}; + +class a600_keyboard_se : public a600_keyboard_base +{ +public: + a600_keyboard_se(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_SE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_se); } +}; + +class a600_keyboard_es : public a600_keyboard_base +{ +public: + a600_keyboard_es(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_ES, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_es); } +}; + +class a600_keyboard_dk : public a600_keyboard_base +{ +public: + a600_keyboard_dk(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_DK, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_dk); } +}; + +class a600_keyboard_ch : public a600_keyboard_base +{ +public: + a600_keyboard_ch(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_CH, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_ch); } +}; + +class a600_keyboard_no : public a600_keyboard_base +{ +public: + a600_keyboard_no(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_NO, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_no); } +}; + +class a600_keyboard_gb : public a600_keyboard_base +{ +public: + a600_keyboard_gb(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : a600_keyboard_base(mconfig, A600_KBD_GB, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_gb); } +}; + + +class a2000_keyboard_us : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_us(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_US, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_us); } +}; + +class a2000_keyboard_de : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_de(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_DE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_de); } +}; + +class a2000_keyboard_fr : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_fr(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_FR, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_fr); } +}; + +class a2000_keyboard_it : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_it(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_IT, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_it); } +}; + +class a2000_keyboard_se : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_se(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_SE, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_se); } +}; + +class a2000_keyboard_es : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_es(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_ES, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_es); } +}; + +class a2000_keyboard_dk : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_dk(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_DK, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_dk); } +}; + +class a2000_keyboard_ch : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_ch(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_CH, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_ch); } +}; + +class a2000_keyboard_no : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_no(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_NO, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_no); } +}; + +class a2000_keyboard_gb : public mitsumi_watchdog_keyboard_base +{ +public: + a2000_keyboard_gb(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_GB, tag, owner, clock) + { } + +protected: + virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_gb); } +}; + +} // anonymous namespace + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_US, device_amiga_keyboard_interface, a500_keyboard_us, "a500kbd_us", "Amiga 500 Keyboard (U.S./Canada)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_DE, device_amiga_keyboard_interface, a500_keyboard_de, "a500kbd_de", "Amiga 500 Keyboard (Germany/Austria)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_FR, device_amiga_keyboard_interface, a500_keyboard_fr, "a500kbd_fr", "Amiga 500 Keyboard (France/Belgium)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_IT, device_amiga_keyboard_interface, a500_keyboard_it, "a500kbd_it", "Amiga 500 Keyboard (Italy)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_SE, device_amiga_keyboard_interface, a500_keyboard_se, "a500kbd_se", "Amiga 500 Keyboard (Sweden/Finland)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_ES, device_amiga_keyboard_interface, a500_keyboard_es, "a500kbd_es", "Amiga 500 Keyboard (Spain)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_DK, device_amiga_keyboard_interface, a500_keyboard_dk, "a500kbd_dk", "Amiga 500 Keyboard (Denmark)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_CH, device_amiga_keyboard_interface, a500_keyboard_ch, "a500kbd_ch", "Amiga 500 Keyboard (Switzerland)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_NO, device_amiga_keyboard_interface, a500_keyboard_no, "a500kbd_no", "Amiga 500 Keyboard (Norway)") +DEFINE_DEVICE_TYPE_PRIVATE(A500_KBD_GB, device_amiga_keyboard_interface, a500_keyboard_gb, "a500kbd_gb", "Amiga 500 Keyboard (UK)") + +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_US, device_amiga_keyboard_interface, a600_keyboard_us, "a600kbd_us", "Amiga 600 Keyboard (U.S./Canada)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_DE, device_amiga_keyboard_interface, a600_keyboard_de, "a600kbd_de", "Amiga 600 Keyboard (Germany/Austria)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_FR, device_amiga_keyboard_interface, a600_keyboard_fr, "a600kbd_fr", "Amiga 600 Keyboard (France/Belgium)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_IT, device_amiga_keyboard_interface, a600_keyboard_it, "a600kbd_it", "Amiga 600 Keyboard (Italy)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_SE, device_amiga_keyboard_interface, a600_keyboard_se, "a600kbd_se", "Amiga 600 Keyboard (Sweden/Finland)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_ES, device_amiga_keyboard_interface, a600_keyboard_es, "a600kbd_es", "Amiga 600 Keyboard (Spain)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_DK, device_amiga_keyboard_interface, a600_keyboard_dk, "a600kbd_dk", "Amiga 600 Keyboard (Denmark)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_CH, device_amiga_keyboard_interface, a600_keyboard_ch, "a600kbd_ch", "Amiga 600 Keyboard (Switzerland)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_NO, device_amiga_keyboard_interface, a600_keyboard_no, "a600kbd_no", "Amiga 600 Keyboard (Norway)") +DEFINE_DEVICE_TYPE_PRIVATE(A600_KBD_GB, device_amiga_keyboard_interface, a600_keyboard_gb, "a600kbd_gb", "Amiga 600 Keyboard (UK)") + +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_US, device_amiga_keyboard_interface, a2000_keyboard_us, "a2000kbd_us", "Amiga 2000/3000/4000 Keyboard (U.S./Canada)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_DE, device_amiga_keyboard_interface, a2000_keyboard_de, "a2000kbd_de", "Amiga 2000/3000/4000 Keyboard (Germany/Austria)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_FR, device_amiga_keyboard_interface, a2000_keyboard_fr, "a2000kbd_fr", "Amiga 2000/3000/4000 Keyboard (France/Belgium)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_IT, device_amiga_keyboard_interface, a2000_keyboard_it, "a2000kbd_it", "Amiga 2000/3000/4000 Keyboard (Italy)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_SE, device_amiga_keyboard_interface, a2000_keyboard_se, "a2000kbd_se", "Amiga 2000/3000/4000 Keyboard (Sweden/Finland)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_ES, device_amiga_keyboard_interface, a2000_keyboard_es, "a2000kbd_es", "Amiga 2000/3000/4000 Keyboard (Spain)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_DK, device_amiga_keyboard_interface, a2000_keyboard_dk, "a2000kbd_dk", "Amiga 2000/3000/4000 Keyboard (Denmark)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_CH, device_amiga_keyboard_interface, a2000_keyboard_ch, "a2000kbd_ch", "Amiga 2000/3000/4000 Keyboard (Switzerland)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_NO, device_amiga_keyboard_interface, a2000_keyboard_no, "a2000kbd_no", "Amiga 2000/3000/4000 Keyboard (Norway)") +DEFINE_DEVICE_TYPE_PRIVATE(A2000_KBD_GB, device_amiga_keyboard_interface, a2000_keyboard_gb, "a2000kbd_gb", "Amiga 2000/3000/4000 Keyboard (UK)") diff --git a/src/devices/bus/amiga/keyboard/mitsumi.h b/src/devices/bus/amiga/keyboard/mitsumi.h new file mode 100644 index 00000000000..187d5ded4c5 --- /dev/null +++ b/src/devices/bus/amiga/keyboard/mitsumi.h @@ -0,0 +1,55 @@ +// license: BSD-3-Clause +// copyright-holders: Vas Crabb +/*************************************************************************** + + mitsumi.h + + Mitsumi keyboards with MOS MCU and 15-row matrix: + * A500 keyboard (watchdog, crystal, reset line) + * A600 keyboard (no keypad, no watchdog, crystal, reset line) + * A2000/A3000 keyboard (watchdog, ceramic resonator) + +***************************************************************************/ +#ifndef MAME_BUS_AMIGA_KEYBOARD_MITSUMI_H +#define MAME_BUS_AMIGA_KEYBOARD_MITSUMI_H + +#include "keyboard.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DECLARE_DEVICE_TYPE(A500_KBD_US, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_DE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_FR, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_IT, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_SE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_ES, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_DK, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_CH, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_NO, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A500_KBD_GB, device_amiga_keyboard_interface) + +DECLARE_DEVICE_TYPE(A600_KBD_US, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_DE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_FR, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_IT, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_SE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_ES, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_DK, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_CH, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_NO, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A600_KBD_GB, device_amiga_keyboard_interface) + +DECLARE_DEVICE_TYPE(A2000_KBD_US, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_DE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_FR, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_IT, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_SE, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_ES, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_DK, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_CH, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_NO, device_amiga_keyboard_interface) +DECLARE_DEVICE_TYPE(A2000_KBD_GB, device_amiga_keyboard_interface) + +#endif // MAME_BUS_AMIGA_KEYBOARD_MITSUMI_H diff --git a/src/devices/cpu/m6502/m6500_1.cpp b/src/devices/cpu/m6502/m6500_1.cpp new file mode 100644 index 00000000000..f119d0dc6a4 --- /dev/null +++ b/src/devices/cpu/m6502/m6500_1.cpp @@ -0,0 +1,471 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + m6500_1.h + + MOS Technology 6500/1, original NMOS variant with onboard peripherals: + * 6502 CPU + * 2048*8 mask ROM + * 64*8 static RAM + * Four eight-bit open drain I/O ports + * Sixteen-bit programmable counter/latch + + The onboad clock generator has mask options for an external crystal + (2MHz to 6MHz) an external TTL-compatible clock with a 300Ω pull-up + resistor (2MHz to 6MHz), or an RC oscillator with an external 47kΩ + resistor and internal capacitor (nominally 2MHz). The clock is + divided by two to generate the two-phase CPU code clock. + + There is no on-board power-on reset generator. The /RES pin must be + held low (asserted) for at least eight phase 2 clock cycles after + CPU core voltage reaches operating range and the clock stabilises. + + The RAM is fully static and has a separate power supply pin. This + allows you to assert /RES, stop the clock, and power down the CPU + core while retaining RAM contents. + + The I/O ports have active low drivers and internal passive pull-up + resistances. There is a mask option to disable the internal + pull-ups per port (i.e. per group of eight lines). Rising edges on + PA0 and falling edges on PA1 are detected and set bits in CR. This + can be triggered by external circuitry or by the output drivers + themselves. + + The sixteen-bit counter/timer counts down either on phase 2 clock or + a rising edge on CNTR. On overflow, the latch is transferred to the + counter and a bit is set in CR. The counter and latch are not + affected by reset. There are four counter modes: + * 0 - interval timer: counter is free-running at clock phase 2 rate + * 1 - pulse generator: like mode 0 but CNTR is toggled on overflow + * 2 - event counter: counter is incremented on rising CNTR edge + * 3 - pulse width measurement: like mode 0 gated by CNTR (low) + + Applying +10V to the /RES pin activates test mode, redirecting + memory fetches to port C. + +***************************************************************************/ + +#include "emu.h" +#include "m6500_1.h" + + +namespace { + +constexpr u8 CR_CMC0 = 0x01U; +constexpr u8 CR_CMC1 = 0x02U; +constexpr u8 CR_A1IE = 0x04U; +constexpr u8 CR_A0IE = 0x08U; +constexpr u8 CR_CIE = 0x10U; +constexpr u8 CR_A1ED = 0x20U; +constexpr u8 CR_A0ED = 0x40U; +constexpr u8 CR_CTRO = 0x80U; + +} // anonymous namespace + + +DEFINE_DEVICE_TYPE(M6500_1, m6500_1_device, "m6500_1", "MOS M6500/1"); + + +m6500_1_device::m6500_1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : m6502_mcu_device(mconfig, M6500_1, tag, owner, clock) + , m_port_in_cb{ { *this }, { *this }, { *this }, { *this } } + , m_port_out_cb{ { *this }, { *this }, { *this }, { *this } } + , m_cntr_out_cb{ *this } + , m_cr{ 0x00U } + , m_port_in{ 0xffU, 0xffU, 0xffU, 0xffU } + , m_port_buf{ 0xffU, 0xffU, 0xffU, 0xffU } + , m_counter_base{ 0U } + , m_counter{ 0x0000 } + , m_latch{ 0x0000 } + , m_cntr_in{ 1U } + , m_cntr_out{ 1U } + , m_ul{ 0U } + , m_ll{ 0U } + , m_uc{ 0U } + , m_lc{ 0U } +{ + program_config.m_internal_map = address_map_constructor(FUNC(m6500_1_device::memory_map), this); +} + + +WRITE8_MEMBER(m6500_1_device::pa_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<0>), this), unsigned(data)); +} + +WRITE8_MEMBER(m6500_1_device::pb_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<1>), this), unsigned(data)); +} + +WRITE8_MEMBER(m6500_1_device::pc_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<2>), this), unsigned(data)); +} + +WRITE8_MEMBER(m6500_1_device::pd_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<3>), this), unsigned(data)); +} + + +WRITE_LINE_MEMBER(m6500_1_device::cntr_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_cntr_in), this), state); +} + + +void m6500_1_device::device_resolve_objects() +{ + m6502_mcu_device::device_resolve_objects(); + + for (devcb_read8 &cb : m_port_in_cb) + cb.resolve(); + + for (devcb_write8 &cb : m_port_out_cb) + cb.resolve_safe(); + + m_cntr_out_cb.resolve_safe(); +} + +void m6500_1_device::device_start() +{ + m6502_mcu_device::device_start(); + + m_counter_base = 0U; + + state_add(M6500_1_CR, "CR", m_cr).callimport().callexport(); + state_add(M6500_1_UL, "UL", m_ul).callimport().callexport(); + state_add(M6500_1_LL, "LL", m_ll).callimport().callexport(); + state_add(M6500_1_UC, "UC", m_uc).callimport().callexport(); + state_add(M6500_1_LC, "LC", m_lc).callimport().callexport(); + + save_item(NAME(m_cr)); + save_item(NAME(m_port_in)); + save_item(NAME(m_port_buf)); + save_item(NAME(m_counter_base)); + save_item(NAME(m_counter)); + save_item(NAME(m_latch)); + save_item(NAME(m_cntr_in)); + save_item(NAME(m_cntr_out)); +} + +void m6500_1_device::device_reset() +{ + m6502_mcu_device::device_reset(); + + SP = 0x003fU; + + internal_update(); + + m_cr = 0x00U; + + for (unsigned i = 0; ARRAY_LENGTH(m_port_buf) > i; ++i) + { + if (0xffU != m_port_buf[i]) + m_port_out_cb[i](m_port_buf[i] = 0xffU); + } + + if (!m_cntr_out) + m_cntr_out_cb(m_cntr_out = 1U); + + internal_update(); + update_irq(); +} + + +u64 m6500_1_device::execute_clocks_to_cycles(u64 clocks) const +{ + return (clocks + 1) / 2; +} + +u64 m6500_1_device::execute_cycles_to_clocks(u64 cycles) const +{ + return cycles * 2; +} + + +void m6500_1_device::state_import(device_state_entry const &entry) +{ + switch (entry.index()) + { + case M6500_1_CR: + update_irq(); + if (!pulse_generator_mode() && !m_cntr_out) + m_cntr_out_cb(m_cntr_out = 1U); + internal_update(); + break; + + case M6500_1_UL: + m_latch = (m_latch & 0x00ffU) | (u16(m_ul) << 8); + break; + + case M6500_1_LL: + m_latch = (m_latch & 0xff00U) | u16(m_ll); + break; + + case M6500_1_UC: + internal_update(); + m_counter = (m_counter & 0x00ffU) | (u16(m_uc) << 8); + internal_update(); + break; + + case M6500_1_LC: + internal_update(); + m_counter = (m_counter & 0xff00U) | u16(m_lc); + internal_update(); + break; + + default: + m6502_mcu_device::state_import(entry); + } +} + +void m6500_1_device::state_export(device_state_entry const &entry) +{ + switch (entry.index()) + { + case M6500_1_CR: + internal_update(); + break; + + case M6500_1_UL: + m_ul = u8(m_latch >> 8); + break; + + case M6500_1_LL: + m_ll = u8(m_latch); + break; + + case M6500_1_UC: + internal_update(); + m_uc = u8(m_counter >> 8); + break; + + case M6500_1_LC: + internal_update(); + m_lc = u8(m_counter); + break; + + default: + m6502_mcu_device::state_export(entry); + } +} + + +void m6500_1_device::internal_update(u64 current_time) +{ + u64 event_time(0U); + add_event(event_time, update_counter(current_time)); + recompute_bcount(event_time); +} + + +READ8_MEMBER(m6500_1_device::read_control_register) +{ + internal_update(); + return m_cr; +} + +WRITE8_MEMBER(m6500_1_device::write_control_register) +{ + internal_update(); + m_cr = (m_cr & (CR_A1ED | CR_A0ED | CR_CTRO)) | (data & (CR_CMC0 | CR_CMC1 | CR_A1IE | CR_A0IE | CR_CIE)); + update_irq(); + if (!pulse_generator_mode() && !m_cntr_out) + m_cntr_out_cb(m_cntr_out = 1U); + internal_update(); +} + +void m6500_1_device::update_irq() +{ + set_input_line(M6502_IRQ_LINE, (m_cr & (m_cr << 3) & (CR_A1ED | CR_A0ED | CR_CTRO)) ? ASSERT_LINE : CLEAR_LINE); +} + + +READ8_MEMBER(m6500_1_device::read_port) +{ + if (!machine().side_effects_disabled() && m_port_in_cb[offset]) + { + u8 const prev(m_port_in[offset]); + m_port_in[offset] = m_port_in_cb[offset](space); + if (!offset) + { + u8 const diff((prev ^ m_port_in[0]) & m_port_buf[0]); + if (BIT(diff, 0) && BIT(m_port_in[0], 0)) + m_cr |= CR_A0ED; + if (BIT(diff, 1) && !BIT(m_port_in[0], 1)) + m_cr |= CR_A1ED; + update_irq(); + } + } + + return m_port_in[offset] & m_port_buf[offset]; +} + +WRITE8_MEMBER(m6500_1_device::write_port) +{ + u8 const prev(m_port_in[offset] & m_port_buf[offset]); + if (m_port_buf[offset] != data) + m_port_out_cb[offset](space, m_port_buf[offset] = data); + + if (!offset) + { + if (!machine().side_effects_disabled() && m_port_in_cb[0]) + m_port_in[0] = m_port_in_cb[0](space); + u8 const effective(m_port_in[0] & data); + u8 const diff(prev ^ effective); + if (BIT(diff, 0) && BIT(effective, 0)) + m_cr |= CR_A0ED; + if (BIT(diff, 1) && !BIT(effective, 1)) + m_cr |= CR_A1ED; + update_irq(); + } +} + +WRITE8_MEMBER(m6500_1_device::clear_edge) +{ + m_cr &= BIT(offset, 0) ? ~CR_A1ED : ~CR_A0ED; + update_irq(); +} + +template TIMER_CALLBACK_MEMBER(m6500_1_device::set_port_in) +{ + u8 const prev(m_port_in[Port]); + m_port_in[Port] = m_port_in_cb[Port] ? m_port_in_cb[Port]() : u8(u32(param)); + + if (!Port) + { + u8 const diff((prev ^ m_port_in[0]) & m_port_buf[0]); + if (BIT(diff, 0) && BIT(m_port_in[0], 0)) + m_cr |= CR_A0ED; + if (BIT(diff, 1) && !BIT(m_port_in[0], 1)) + m_cr |= CR_A1ED; + update_irq(); + } +} + + +READ8_MEMBER(m6500_1_device::read_upper_count) +{ + internal_update(); + return u8(m_counter >> 8); +} + +READ8_MEMBER(m6500_1_device::read_lower_count) +{ + internal_update(); + if (!machine().side_effects_disabled()) + { + m_cr &= ~CR_CTRO; + update_irq(); + } + + return u8(m_counter); +} + +template WRITE8_MEMBER(m6500_1_device::write_upper_latch) +{ + m_latch = (m_latch & 0x00ffU) | u16(data << 8); + if (Transfer) + { + internal_update(); + m_counter = m_latch; + m_cr &= ~CR_CTRO; + update_irq(); + internal_update(); + toggle_cntr(); + } +} + +WRITE8_MEMBER(m6500_1_device::write_lower_latch) +{ + m_latch = (m_latch & 0xff00U) | u16(data); +} + +u64 m6500_1_device::update_counter(u64 current_time) +{ + u64 elapsed(current_time - m_counter_base); + m_counter_base = current_time; + if (!should_count()) + return 0U; + + if (elapsed <= m_counter) + { + m_counter -= elapsed; + } + else + { + m_cr |= CR_CTRO; + elapsed -= m_counter + 1; + u32 const period(u32(m_latch) + 1); + u64 const events((elapsed / period) + 1); + m_counter = u16(m_latch - (elapsed % period)); + update_irq(); + if (events % 2) + toggle_cntr(); + } + + if (pulse_generator_mode() || (m_cr & CR_CIE)) + return current_time + m_counter + 1; + else + return 0U; +} + +bool m6500_1_device::should_count() const +{ + switch (m_cr & (CR_CMC0 | CR_CMC1)) + { + case 0x00U: // interval timer + case 0x01U: // pulse generator + return true; + case 0x02U: // event counter + return false; + case 0x03U: // pulse width measurement + assert(m_cntr_out); + return !m_cntr_in; + } + + // unreachable + throw false; +} + +bool m6500_1_device::pulse_generator_mode() const +{ + return (m_cr & (CR_CMC0 | CR_CMC1)) == 0x01U; +} + +TIMER_CALLBACK_MEMBER(m6500_1_device::set_cntr_in) +{ + internal_update(); + m_cntr_in = param ? 1U : 0U; + internal_update(); +} + +void m6500_1_device::toggle_cntr() +{ + if (pulse_generator_mode()) + m_cntr_out_cb(m_cntr_out = m_cntr_out ? 0U : 1U); +} + + +void m6500_1_device::memory_map(address_map &map) +{ + map.global_mask(0x0fff); // guessed + map.unmap_value_high(); // guessed + + map(0x0000, 0x003f).ram(); + + map(0x0080, 0x0083).rw(FUNC(m6500_1_device::read_port), FUNC(m6500_1_device::write_port)); + map(0x0084, 0x0084).w(FUNC(m6500_1_device::write_upper_latch)); + map(0x0085, 0x0085).w(FUNC(m6500_1_device::write_lower_latch)); + map(0x0086, 0x0086).r(FUNC(m6500_1_device::read_upper_count)); + map(0x0087, 0x0087).r(FUNC(m6500_1_device::read_lower_count)); + map(0x0088, 0x0088).w(FUNC(m6500_1_device::write_upper_latch)); + map(0x0089, 0x008a).w(FUNC(m6500_1_device::clear_edge)); + + map(0x008f, 0x008f).rw(FUNC(m6500_1_device::read_control_register), FUNC(m6500_1_device::write_control_register)); + + map(0x0800, 0x0fff).rom().region(DEVICE_SELF, 0); +} diff --git a/src/devices/cpu/m6502/m6500_1.h b/src/devices/cpu/m6502/m6500_1.h new file mode 100644 index 00000000000..8d5c8cbbebe --- /dev/null +++ b/src/devices/cpu/m6502/m6500_1.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + m6500_1.h + + MOS Technology 6500/1, original NMOS variant with onboard peripherals: + * 6502 CPU + * 2048*8 mask ROM + * 64*8 static RAM + * Four eight-bit open drain I/O ports + * Sixteen-bit programmable counter/latch + +***************************************************************************/ +#ifndef MAME_CPU_M6502_M6500_1_H +#define MAME_CPU_M6502_M6500_1_H + +#pragma once + +#include "m6502.h" + +class m6500_1_device : public m6502_mcu_device +{ +public: + m6500_1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + auto pa_in_cb() { return m_port_in_cb[0].bind(); } + auto pb_in_cb() { return m_port_in_cb[1].bind(); } + auto pc_in_cb() { return m_port_in_cb[2].bind(); } + auto pd_in_cb() { return m_port_in_cb[3].bind(); } + auto pa_out_cb() { return m_port_out_cb[0].bind(); } + auto pb_out_cb() { return m_port_out_cb[1].bind(); } + auto pc_out_cb() { return m_port_out_cb[2].bind(); } + auto pd_out_cb() { return m_port_out_cb[3].bind(); } + auto cntr_out_cb() { return m_cntr_out_cb.bind(); } + + DECLARE_READ8_MEMBER(pa_r) { return m_port_buf[0]; } + DECLARE_READ8_MEMBER(pb_r) { return m_port_buf[1]; } + DECLARE_READ8_MEMBER(pc_r) { return m_port_buf[2]; } + DECLARE_READ8_MEMBER(pd_r) { return m_port_buf[3]; } + DECLARE_WRITE8_MEMBER(pa_w); + DECLARE_WRITE8_MEMBER(pb_w); + DECLARE_WRITE8_MEMBER(pc_w); + DECLARE_WRITE8_MEMBER(pd_w); + + DECLARE_WRITE_LINE_MEMBER(cntr_w); + +protected: + enum + { + M6500_1_CR = M6502_IR + 1, + M6500_1_UL, + M6500_1_LL, + M6500_1_UC, + M6500_1_LC + }; + + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + + virtual u64 execute_clocks_to_cycles(u64 clocks) const override; + virtual u64 execute_cycles_to_clocks(u64 cycles) const override; + + virtual void state_import(device_state_entry const &entry) override; + virtual void state_export(device_state_entry const &entry) override; + + virtual void internal_update(u64 current_time) override; + using m6502_mcu_device::internal_update; + + DECLARE_READ8_MEMBER(read_control_register); + DECLARE_WRITE8_MEMBER(write_control_register); + void update_irq(); + + DECLARE_READ8_MEMBER(read_port); + DECLARE_WRITE8_MEMBER(write_port); + DECLARE_WRITE8_MEMBER(clear_edge); + template TIMER_CALLBACK_MEMBER(set_port_in); + + DECLARE_READ8_MEMBER(read_upper_count); + DECLARE_READ8_MEMBER(read_lower_count); + template DECLARE_WRITE8_MEMBER(write_upper_latch); + DECLARE_WRITE8_MEMBER(write_lower_latch); + u64 update_counter(u64 current_time); + bool should_count() const; + bool pulse_generator_mode() const; + TIMER_CALLBACK_MEMBER(set_cntr_in); + void toggle_cntr(); + + void memory_map(address_map &map); + +private: + devcb_read8 m_port_in_cb[4]; + devcb_write8 m_port_out_cb[4]; + devcb_write_line m_cntr_out_cb; + + u8 m_cr; + + u8 m_port_in[4], m_port_buf[4]; + + u64 m_counter_base; + u16 m_counter, m_latch; + u8 m_cntr_in, m_cntr_out; + + u8 m_ul, m_ll, m_uc, m_lc; +}; + +DECLARE_DEVICE_TYPE(M6500_1, m6500_1_device) + +#endif // MAME_CPU_M6502_M6500_1_H diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index 8252d617465..2249ee5be20 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -4,7 +4,7 @@ m6502.c - Mostek 6502, original NMOS variant + MOS Technology 6502, original NMOS variant ***************************************************************************/ @@ -589,9 +589,11 @@ void m6502_mcu_device::execute_run() while(icount > 0) { while(icount > bcount) { - if(inst_state < 0x10000) { + if(inst_state < 0xff00) { PPC = NPC; - debugger_instruction_hook(NPC); + inst_state = IR | inst_state_base; + if(machine().debug_flags & DEBUG_FLAG_ENABLED) + debugger_instruction_hook(NPC); } do_exec_full(); } diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h index 28527969c75..fc527ad8c5a 100644 --- a/src/devices/cpu/m6502/m6502.h +++ b/src/devices/cpu/m6502/m6502.h @@ -4,7 +4,7 @@ m6502.h - Mostek 6502, original NMOS variant + MOS Technology 6502, original NMOS variant ***************************************************************************/ @@ -275,6 +275,7 @@ class m6502_mcu_device : public m6502_device { protected: m6502_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + void internal_update() { internal_update(total_cycles()); } virtual void internal_update(uint64_t current_time) = 0; void recompute_bcount(uint64_t event_time); static void add_event(uint64_t &event_time, uint64_t new_event); diff --git a/src/devices/cpu/m6502/m6502d.cpp b/src/devices/cpu/m6502/m6502d.cpp index 7970efb524b..589aafdf3b7 100644 --- a/src/devices/cpu/m6502/m6502d.cpp +++ b/src/devices/cpu/m6502/m6502d.cpp @@ -4,7 +4,7 @@ m6502d.cpp - Mostek 6502, original NMOS variant, disassembler + MOS Technology 6502, original NMOS variant, disassembler ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m6502d.h b/src/devices/cpu/m6502/m6502d.h index 2700ee2f239..5a02dddca04 100644 --- a/src/devices/cpu/m6502/m6502d.h +++ b/src/devices/cpu/m6502/m6502d.h @@ -4,7 +4,7 @@ m6502d.h - Mostek 6502, original NMOS variant, disassembler + MOS Technology 6502, original NMOS variant, disassembler ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m6504.cpp b/src/devices/cpu/m6502/m6504.cpp index b065e36f8ce..b2c8132d3ad 100644 --- a/src/devices/cpu/m6502/m6504.cpp +++ b/src/devices/cpu/m6502/m6504.cpp @@ -4,7 +4,7 @@ m6504.c - Mostek 6502, NMOS variant with reduced address bus + MOS Technology 6502, NMOS variant with reduced address bus ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m6504.h b/src/devices/cpu/m6502/m6504.h index dda2c5f30ad..6238d510b18 100644 --- a/src/devices/cpu/m6502/m6504.h +++ b/src/devices/cpu/m6502/m6504.h @@ -4,7 +4,7 @@ m6504.h - Mostek 6502, NMOS variant with reduced address bus + MOS Technology 6502, NMOS variant with reduced address bus ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m6507.cpp b/src/devices/cpu/m6502/m6507.cpp index 2932eb2923a..ea97cf260e9 100644 --- a/src/devices/cpu/m6502/m6507.cpp +++ b/src/devices/cpu/m6502/m6507.cpp @@ -4,7 +4,7 @@ m6507.c - Mostek 6502, NMOS variant with reduced address bus + MOS Technology 6502, NMOS variant with reduced address bus ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m6507.h b/src/devices/cpu/m6502/m6507.h index 93c39a35378..350891637bc 100644 --- a/src/devices/cpu/m6502/m6507.h +++ b/src/devices/cpu/m6502/m6507.h @@ -4,7 +4,7 @@ m6507.h - Mostek 6502, NMOS variant with reduced address bus + MOS Technology 6502, NMOS variant with reduced address bus ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m65c02.cpp b/src/devices/cpu/m6502/m65c02.cpp index ab7fdf5d3a7..80df7c79921 100644 --- a/src/devices/cpu/m6502/m65c02.cpp +++ b/src/devices/cpu/m6502/m65c02.cpp @@ -4,8 +4,8 @@ m65c02.c - Mostek 6502, CMOS variant with some additional instructions (but - not the bitwise ones) + MOS Technology 6502, CMOS variant with some additional instructions + (but not the bitwise ones) ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m65c02.h b/src/devices/cpu/m6502/m65c02.h index a1e0ba553d2..b2670756943 100644 --- a/src/devices/cpu/m6502/m65c02.h +++ b/src/devices/cpu/m6502/m65c02.h @@ -4,8 +4,8 @@ m65c02.h - Mostek 6502, CMOS variant with some additional instructions (but - not the bitwise ones) + MOS Technology 6502, CMOS variant with some additional instructions + (but not the bitwise ones) ***************************************************************************/ #ifndef MAME_CPU_M6502_M65C02_H diff --git a/src/devices/cpu/m6502/m65c02d.cpp b/src/devices/cpu/m6502/m65c02d.cpp index 7a78219f129..2c7b3b81fc3 100644 --- a/src/devices/cpu/m6502/m65c02d.cpp +++ b/src/devices/cpu/m6502/m65c02d.cpp @@ -4,8 +4,8 @@ m65c02d.cpp - Mostek 6502, CMOS variant with some additional instructions (but - not the bitwise ones), disassembler + MOS Technology 6502, CMOS variant with some additional instructions + (but not the bitwise ones), disassembler ***************************************************************************/ diff --git a/src/devices/cpu/m6502/m65c02d.h b/src/devices/cpu/m6502/m65c02d.h index d9599e548bb..77b134c4b95 100644 --- a/src/devices/cpu/m6502/m65c02d.h +++ b/src/devices/cpu/m6502/m65c02d.h @@ -4,8 +4,8 @@ m65c02d.h - Mostek 6502, CMOS variant with some additional instructions (but - not the bitwise ones), disassembler + MOS Technology 6502, CMOS variant with some additional instructions + (but not the bitwise ones), disassembler ***************************************************************************/ diff --git a/src/mame/drivers/amiga.cpp b/src/mame/drivers/amiga.cpp index 8cbbaaf8e71..4eabbdab678 100644 --- a/src/mame/drivers/amiga.cpp +++ b/src/mame/drivers/amiga.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "includes/amiga.h" + #include "bus/amiga/keyboard/keyboard.h" #include "bus/amiga/zorro/zorro.h" #include "cpu/m68000/m68000.h" @@ -1437,12 +1438,6 @@ MACHINE_CONFIG_START(amiga_state::amiga_base) MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(*this, amiga_state, centronics_select_w)) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") - // keyboard - MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", "a500_us") - MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) - MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) - MCFG_AMIGA_KEYBOARD_KRST_HANDLER(WRITELINE(*this, amiga_state, kbreset_w)) - // software MCFG_SOFTWARE_LIST_ADD("wb_list", "amiga_workbench") MCFG_SOFTWARE_LIST_ADD("hardware_list", "amiga_hardware") @@ -1453,6 +1448,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a1000_state::a1000) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a2000_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(a1000_mem) @@ -1465,6 +1466,7 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a1000_state::a1000n) a1000(config); + MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_CLOCK(amiga_state::CLK_7M_NTSC) MCFG_DEVICE_REMOVE("screen") @@ -1481,6 +1483,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a2000_state::a2000) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a2000_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(a2000_mem) @@ -1506,6 +1514,7 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a2000_state::a2000n) a2000(config); + MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_CLOCK(amiga_state::CLK_7M_NTSC) MCFG_DEVICE_REMOVE("screen") @@ -1522,6 +1531,13 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a500_state::a500) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", a500_keyboard_devices, "a500_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + MCFG_AMIGA_KEYBOARD_KRST_HANDLER(WRITELINE(*this, amiga_state, kbreset_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(a500_mem) @@ -1552,6 +1568,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(cdtv_state::cdtv) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a2000_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(cdtv_mem) @@ -1623,6 +1645,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a3000_state::a3000) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a2000_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68030, XTAL(32'000'000) / 2) MCFG_DEVICE_PROGRAM_MAP(a3000_mem) @@ -1653,6 +1681,13 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a500p_state::a500p) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", a500_keyboard_devices, "a500_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + MCFG_AMIGA_KEYBOARD_KRST_HANDLER(WRITELINE(*this, amiga_state, kbreset_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(a500p_mem) @@ -1687,6 +1722,13 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a600_state::a600) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", a600_keyboard_devices, "a600_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + MCFG_AMIGA_KEYBOARD_KRST_HANDLER(WRITELINE(*this, amiga_state, kbreset_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68000, amiga_state::CLK_7M_PAL) MCFG_DEVICE_PROGRAM_MAP(a600_mem) @@ -1729,6 +1771,13 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a1200_state::a1200) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a1200_us") // FIXME: replace with Amiga 1200 devices when we have mask ROM dump + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + MCFG_AMIGA_KEYBOARD_KRST_HANDLER(WRITELINE(*this, amiga_state, kbreset_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68EC020, amiga_state::CLK_28M_PAL / 2) MCFG_DEVICE_PROGRAM_MAP(a1200_mem) @@ -1789,6 +1838,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a4000_state::a4000) amiga_base(config); + + // keyboard + MCFG_AMIGA_KEYBOARD_INTERFACE_ADD("kbd", amiga_keyboard_devices, "a2000_us") + MCFG_AMIGA_KEYBOARD_KCLK_HANDLER(WRITELINE("cia_0", mos8520_device, cnt_w)) + MCFG_AMIGA_KEYBOARD_KDAT_HANDLER(WRITELINE("cia_0", mos8520_device, sp_w)) + // main cpu MCFG_DEVICE_ADD("maincpu", M68040, XTAL(50'000'000) / 2) MCFG_DEVICE_PROGRAM_MAP(a4000_mem) @@ -1819,6 +1874,7 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a4000_state::a4000n) a4000(config); + MCFG_DEVICE_REMOVE("screen") ntsc_video(config); MCFG_DEVICE_MODIFY("screen") @@ -1863,6 +1919,7 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(cd32_state::cd32) amiga_base(config); + // main cpu MCFG_DEVICE_ADD("maincpu", M68EC020, amiga_state::CLK_28M_PAL / 2) MCFG_DEVICE_PROGRAM_MAP(cd32_mem) @@ -1900,11 +1957,11 @@ MACHINE_CONFIG_START(cd32_state::cd32) MCFG_CDROM_ADD("cdrom") MCFG_CDROM_INTERFACE("cd32_cdrom") MCFG_SOFTWARE_LIST_ADD("cd_list", "cd32") - MCFG_DEVICE_REMOVE("kbd") MACHINE_CONFIG_END MACHINE_CONFIG_START(cd32_state::cd32n) cd32(config); + MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_CLOCK(amiga_state::CLK_28M_NTSC / 2) MCFG_DEVICE_REMOVE("screen") @@ -1934,6 +1991,7 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(a4000_state::a4000tn) a4000(config); + MCFG_DEVICE_REMOVE("screen") ntsc_video(config); MCFG_DEVICE_MODIFY("screen")