From 935d28a67573f4cd1333639927f19798ce953f1e Mon Sep 17 00:00:00 2001 From: Devin Acker Date: Wed, 27 Oct 2021 04:21:46 -0400 Subject: new NOT_WORKING machine (Casio CTK-2100) (#8757) * ctk2100: preliminary work * ctk2100: possible keyboard hookup * ctk2100: hook up rudimentary timers * ctk2100: add ports and hook up the LCD * ctk2100: timer tweaks, input tweaks * ctk2100: fix I/O port reads (stops constant LCD resets) * gt913: increase key polling rate (fixes ctk2100 test mode) * ctk2100: add ADCs, clean up and comment some other stuff * lpc210x: add the PL190 VIC here too while i'm at it * vic_pl192: fix clang build * unidasm: add gt913 --- scripts/src/cpu.lua | 2 + scripts/target/mame/mess.lua | 1 + src/devices/cpu/arm7/lpc210x.cpp | 29 +-- src/devices/cpu/arm7/lpc210x.h | 7 +- src/devices/cpu/arm7/upd800468.cpp | 252 +++++++++++++++++++++++++ src/devices/cpu/arm7/upd800468.h | 103 ++++++++++ src/devices/cpu/h8/gt913.cpp | 3 +- src/devices/machine/gt913_kbd.cpp | 14 +- src/devices/machine/gt913_kbd.h | 16 +- src/devices/machine/vic_pl192.cpp | 375 ++++++++++++++++++++++++++++++++----- src/devices/machine/vic_pl192.h | 99 ++++++++-- src/mame/drivers/ctk2000.cpp | 300 +++++++++++++++++++++++++++++ src/mame/drivers/ctk551.cpp | 29 +-- src/mame/mess.flt | 1 + src/tools/unidasm.cpp | 2 + 15 files changed, 1114 insertions(+), 119 deletions(-) create mode 100644 src/devices/cpu/arm7/upd800468.cpp create mode 100644 src/devices/cpu/arm7/upd800468.h create mode 100644 src/mame/drivers/ctk2000.cpp diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 9c612457313..78f18f4430a 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -160,6 +160,8 @@ if CPUS["ARM7"] then MAME_DIR .. "src/devices/cpu/arm7/arm7ops.cpp", MAME_DIR .. "src/devices/cpu/arm7/lpc210x.cpp", MAME_DIR .. "src/devices/cpu/arm7/lpc210x.h", + MAME_DIR .. "src/devices/cpu/arm7/upd800468.cpp", + MAME_DIR .. "src/devices/cpu/arm7/upd800468.h", MAME_DIR .. "src/devices/cpu/arm7/arm7core.h", MAME_DIR .. "src/devices/cpu/arm7/arm7core.hxx", MAME_DIR .. "src/devices/cpu/arm7/arm7drc.hxx", diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 580e9460a3f..0694b048902 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -2025,6 +2025,7 @@ files { MAME_DIR .. "src/mame/drivers/fp6000.cpp", MAME_DIR .. "src/mame/machine/fp6000_kbd.cpp", MAME_DIR .. "src/mame/machine/fp6000_kbd.h", + MAME_DIR .. "src/mame/drivers/ctk2000.cpp", MAME_DIR .. "src/mame/drivers/ctk551.cpp", MAME_DIR .. "src/mame/drivers/ht6000.cpp", MAME_DIR .. "src/mame/drivers/pb1000.cpp", diff --git a/src/devices/cpu/arm7/lpc210x.cpp b/src/devices/cpu/arm7/lpc210x.cpp index 9e63b5785d0..75a322f01a2 100644 --- a/src/devices/cpu/arm7/lpc210x.cpp +++ b/src/devices/cpu/arm7/lpc210x.cpp @@ -37,13 +37,14 @@ void lpc210x_device::lpc2103_map(address_map &map) map(0xE01FC100, 0xE01FC103).rw(FUNC(lpc210x_device::apbdiv_r), FUNC(lpc210x_device::apbdiv_w)); map(0xE01FC1a0, 0xE01FC1a3).rw(FUNC(lpc210x_device::scs_r), FUNC(lpc210x_device::scs_w)); - map(0xFFFFF000, 0xFFFFF2ff).rw(FUNC(lpc210x_device::vic_r), FUNC(lpc210x_device::vic_w)); // interrupt controller + map(0xfffff000, 0xffffffff).m(m_vic, FUNC(vic_pl190_device::map)); // interrupt controller } lpc210x_device::lpc210x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, LPC2103, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_LITTLE) , m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0, address_map_constructor(FUNC(lpc210x_device::lpc2103_map), this)) + , m_vic(*this, "vic") { } @@ -98,29 +99,6 @@ void lpc210x_device::device_reset() m_TxPR[1] = 0; } -/* VIC (Vectored Interrupt Controller) */ - -uint32_t lpc210x_device::vic_r(offs_t offset, uint32_t mem_mask) -{ - switch (offset*4) - { - default: - logerror("%s unhandled read from VIC offset %08x mem_mask %08x\n", machine().describe_context(), offset * 4, mem_mask); - } - - return 0x00000000; -} - - -void lpc210x_device::vic_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - switch (offset * 4) - { - default: - logerror("%s unhandled write VIC offset %02x data %08x mem_mask %08x\n", machine().describe_context(), offset * 4, data, mem_mask); - } -} - /* PIN Select block */ uint32_t lpc210x_device::pin_r(offs_t offset, uint32_t mem_mask) @@ -278,4 +256,7 @@ void lpc210x_device::write_timer(int timer, int offset, uint32_t data, uint32_t void lpc210x_device::device_add_mconfig(machine_config &config) { + PL190_VIC(config, m_vic, 0); + m_vic->out_irq_cb().set_inputline(*this, ARM7_IRQ_LINE); + m_vic->out_fiq_cb().set_inputline(*this, ARM7_FIRQ_LINE); } diff --git a/src/devices/cpu/arm7/lpc210x.h b/src/devices/cpu/arm7/lpc210x.h index c21b346a5e3..47a801a6058 100644 --- a/src/devices/cpu/arm7/lpc210x.h +++ b/src/devices/cpu/arm7/lpc210x.h @@ -8,6 +8,7 @@ #include "arm7.h" #include "arm7core.h" +#include "machine/vic_pl192.h" /*************************************************************************** DEVICE CONFIGURATION MACROS @@ -37,10 +38,6 @@ public: void write_timer(int timer, int offset, uint32_t data, uint32_t mem_mask); uint32_t read_timer(int timer, int offset, uint32_t mem_mask); - // VIC - uint32_t vic_r(offs_t offset, uint32_t mem_mask = ~0); - void vic_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - // PIN select block uint32_t pin_r(offs_t offset, uint32_t mem_mask = ~0); void pin_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); @@ -81,6 +78,8 @@ protected: private: address_space_config m_program_config; + + required_device m_vic; }; diff --git a/src/devices/cpu/arm7/upd800468.cpp b/src/devices/cpu/arm7/upd800468.cpp new file mode 100644 index 00000000000..471e16098f4 --- /dev/null +++ b/src/devices/cpu/arm7/upd800468.cpp @@ -0,0 +1,252 @@ +// license:BSD-3-Clause +// copyright-holders:Devin Acker +/*************************************************************************** + + NEC uPD800468 + ARM7TDMI core with internal peripherals and external ROM/flash + + Used in late 2000s/early 2010s Casio keyboards, like the CTK-2000 series. + +***************************************************************************/ + +#include "emu.h" +#include "upd800468.h" + +DEFINE_DEVICE_TYPE(UPD800468_TIMER, upd800468_timer_device, "upd800468_timer", "NEC uPD800468 timer") + +upd800468_timer_device::upd800468_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, UPD800468_TIMER, tag, owner, clock) + , m_irq_cb(*this) +{ +} + +u32 upd800468_timer_device::rate_r() +{ + return m_rate; +} + +void upd800468_timer_device::rate_w(u32 data) +{ + m_rate = data; +} + +u8 upd800468_timer_device::control_r() +{ + return m_control; +} + +void upd800468_timer_device::control_w(u8 data) +{ + if (BIT(data, 1) != BIT(m_control, 1)) + { + if (BIT(data, 1)) + { + attotime period = clocks_to_attotime(m_rate); + m_timer->adjust(period, 0, period); + } + else + { + m_timer->adjust(attotime::never); + m_irq_cb(0); + } + } + + if (!BIT(data, 0)) + { + m_irq_cb(0); + } + + m_control = data; +} + +void upd800468_timer_device::device_start() +{ + m_timer = timer_alloc(0); + + m_irq_cb.resolve_safe(); + + save_item(NAME(m_rate)); + save_item(NAME(m_control)); +} + +void upd800468_timer_device::device_reset() +{ + m_rate = m_control = 0; +} + +void upd800468_timer_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (BIT(m_control, 0)) + m_irq_cb(1); +} + +DEFINE_DEVICE_TYPE(UPD800468, upd800468_device, "upd800468", "NEC uPD800468") + +void upd800468_device::upd800468_map(address_map &map) +{ + map(0x00000000, 0x0000ffff).view(m_ram_view); + m_ram_view[0](0x00000000, 0x0000ffff).ram(); + + // RAM used for storing user samples (TODO: is this actually supposed to be part of the main 64kb RAM?) + map(0x1ffe8400, 0x1ffedfff).ram(); + + map(0x1fff00a0, 0x1fff00a1).r(m_kbd, FUNC(gt913_kbd_hle_device::read)).umask32(0x0000ffff); + map(0x1fff00a2, 0x1fff00a3).r(m_kbd, FUNC(gt913_kbd_hle_device::status_r)).umask32(0xffff0000); + map(0x1fff00a4, 0x1fff00a5).w(m_kbd, FUNC(gt913_kbd_hle_device::status_w)).umask32(0x0000ffff); + + map(0x1fff00c0, 0x1fff00cf).r(FUNC(upd800468_device::adc_r)); + + map(0x1fff0141, 0x1fff0141).rw(FUNC(upd800468_device::port_ddr_r<0>), FUNC(upd800468_device::port_ddr_w<0>)).umask32(0x0000ff00); + map(0x1fff0142, 0x1fff0142).rw(FUNC(upd800468_device::port_r<0>), FUNC(upd800468_device::port_w<0>)).umask32(0x00ff0000); + map(0x1fff0145, 0x1fff0145).rw(FUNC(upd800468_device::port_ddr_r<1>), FUNC(upd800468_device::port_ddr_w<1>)).umask32(0x0000ff00); + map(0x1fff0146, 0x1fff0146).rw(FUNC(upd800468_device::port_r<1>), FUNC(upd800468_device::port_w<1>)).umask32(0x00ff0000); + map(0x1fff0149, 0x1fff0149).rw(FUNC(upd800468_device::port_ddr_r<2>), FUNC(upd800468_device::port_ddr_w<2>)).umask32(0x0000ff00); + map(0x1fff014a, 0x1fff014a).rw(FUNC(upd800468_device::port_r<2>), FUNC(upd800468_device::port_w<2>)).umask32(0x00ff0000); + map(0x1fff014d, 0x1fff014d).rw(FUNC(upd800468_device::port_ddr_r<3>), FUNC(upd800468_device::port_ddr_w<3>)).umask32(0x0000ff00); + map(0x1fff014e, 0x1fff014e).rw(FUNC(upd800468_device::port_r<3>), FUNC(upd800468_device::port_w<3>)).umask32(0x00ff0000); + + map(0x2a003504, 0x2a003507).rw(m_timer[0], FUNC(upd800468_timer_device::rate_r), FUNC(upd800468_timer_device::rate_w)); + map(0x2a003508, 0x2a003508).rw(m_timer[0], FUNC(upd800468_timer_device::control_r), FUNC(upd800468_timer_device::control_w)).umask32(0x000000ff); + map(0x2a003514, 0x2a003517).rw(m_timer[1], FUNC(upd800468_timer_device::rate_r), FUNC(upd800468_timer_device::rate_w)); + map(0x2a003518, 0x2a003518).rw(m_timer[1], FUNC(upd800468_timer_device::control_r), FUNC(upd800468_timer_device::control_w)).umask32(0x000000ff); + map(0x2a003524, 0x2a003527).rw(m_timer[2], FUNC(upd800468_timer_device::rate_r), FUNC(upd800468_timer_device::rate_w)); + map(0x2a003528, 0x2a003528).rw(m_timer[2], FUNC(upd800468_timer_device::control_r), FUNC(upd800468_timer_device::control_w)).umask32(0x000000ff); + + map(0x2a003e00, 0x2a003e03).rw(FUNC(upd800468_device::ram_enable_r), FUNC(upd800468_device::ram_enable_w)); + + // keep whatever this is from spamming the error log for now + map(0x50000070, 0x50000077).noprw(); + + // TODO: USB controller at 0x50000400 + + map(0xfffff000, 0xffffffff).m(m_vic, FUNC(vic_upd800468_device::map)); +} + +upd800468_device::upd800468_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm7_cpu_device(mconfig, UPD800468, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_LITTLE) + , m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0, address_map_constructor(FUNC(upd800468_device::upd800468_map), this)) + , m_vic(*this, "vic") + , m_timer(*this, "timer%u", 0) + , m_kbd(*this, "kbd") + , m_adc_cb(*this), m_in_cb(*this), m_out_cb(*this) + , m_ram_view(*this, "ramview") +{ +} + +device_memory_interface::space_config_vector upd800468_device::memory_space_config() const +{ + return space_config_vector{ + std::make_pair(AS_PROGRAM, &m_program_config) + }; +} + +void upd800468_device::device_add_mconfig(machine_config &config) +{ + UPD800468_VIC(config, m_vic, 0); + m_vic->out_irq_cb().set_inputline(*this, ARM7_IRQ_LINE); + m_vic->out_fiq_cb().set_inputline(*this, ARM7_FIRQ_LINE); + + // this is probably not 100% accurate timing-wise + // for the ctk2100 it works ok for e.g. MIDI tempo and the auto power off interval + // it's unclear if there's supposed to be a register for setting a divider for each timer + UPD800468_TIMER(config, m_timer[0], clock() >> 3); + UPD800468_TIMER(config, m_timer[1], clock() >> 3); + UPD800468_TIMER(config, m_timer[2], clock() >> 3); + m_timer[0]->irq_cb().set(m_vic, FUNC(vic_upd800468_device::irq_w<21>)); + m_timer[1]->irq_cb().set(m_vic, FUNC(vic_upd800468_device::irq_w<22>)); + m_timer[2]->irq_cb().set(m_vic, FUNC(vic_upd800468_device::irq_w<23>)); + + // key/button controller is compatible with the one from earlier keyboards + GT913_KBD_HLE(config, m_kbd, 0); + m_kbd->irq_cb().set(m_vic, FUNC(vic_upd800468_device::irq_w<31>)); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd800468_device::device_start() +{ + arm7_cpu_device::device_start(); + + m_adc_cb.resolve_all_safe(0x000); + m_in_cb.resolve_all_safe(0x00); + m_out_cb.resolve_all_safe(); + + save_item(NAME(m_port_data)); + save_item(NAME(m_port_ddr)); + save_item(NAME(m_ram_enable)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd800468_device::device_reset() +{ + arm7_cpu_device::device_reset(); + + for (offs_t i = 0; i < 4; i++) + { + m_port_data[i] = 0; + m_port_ddr[i] = 0xff; + port_update(i); + } + + m_ram_enable = 0; + m_ram_view.disable(); +} + +u16 upd800468_device::adc_r(offs_t num) +{ + // TODO: verify strange-seeming ADC behavior + // ctk2100 reads a 10-bit value, then inverts the highest bit, and seemingly treats the result as unsigned + return m_adc_cb[num]() ^ 0x200; +} + +u8 upd800468_device::port_ddr_r(offs_t num) +{ + return m_port_ddr[num]; +} + +void upd800468_device::port_ddr_w(offs_t num, u8 data) +{ + m_port_ddr[num] = data; +// logerror("port %u ddr_w: %02x\n", num, data); + port_update(num); +} + +u8 upd800468_device::port_r(offs_t num) +{ + // port input seemingly does not use the ddr value + // (ctk2100 port 2 ddr lower 4 bits are always high, but the corresponding data bits + // are apparently expected to be bidirectional, otherwise reading LCD status fails) + return m_in_cb[num](); +} + +void upd800468_device::port_w(offs_t num, u8 data) +{ + m_port_data[num] = data; + port_update(num); +} + +void upd800468_device::port_update(offs_t num) +{ +// logerror("port %u out: %02x\n", num, m_port_data[num] & m_port_ddr[num]); + m_out_cb[num](m_port_data[num] & m_port_ddr[num]); +} + +u32 upd800468_device::ram_enable_r() +{ + return m_ram_enable; +} + +void upd800468_device::ram_enable_w(u32 data) +{ + m_ram_enable = data; + + if (BIT(m_ram_enable, 0)) + m_ram_view.select(0); + else + m_ram_view.disable(); +} diff --git a/src/devices/cpu/arm7/upd800468.h b/src/devices/cpu/arm7/upd800468.h new file mode 100644 index 00000000000..afd47d9bab9 --- /dev/null +++ b/src/devices/cpu/arm7/upd800468.h @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:Devin Acker + +#ifndef MAME_CPU_ARM7_UPD800468_H +#define MAME_CPU_ARM7_UPD800468_H + +#pragma once + +#include "arm7.h" +#include "arm7core.h" +#include "machine/gt913_kbd.h" +#include "machine/vic_pl192.h" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +class upd800468_timer_device : public device_t +{ +public: + upd800468_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto irq_cb() { return m_irq_cb.bind(); } + + u32 rate_r(); + void rate_w(u32); + + u8 control_r(); + void control_w(u8); + +protected: + 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; + +private: + devcb_write_line m_irq_cb; + + emu_timer *m_timer; + u32 m_rate; + u8 m_control; +}; + +class upd800468_device : public arm7_cpu_device +{ +public: + upd800468_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); + + void upd800468_map(address_map &map); + + template auto adc_cb() { return m_adc_cb[i].bind(); } + + template auto port_in_cb() { return m_in_cb[i].bind(); } + template auto port_out_cb() { return m_out_cb[i].bind(); } + + template u8 port_ddr_r() { return port_ddr_r(i); } + template void port_ddr_w(u8 data) { port_ddr_w(i, data); } + + template u8 port_r() { return port_r(i); } + template void port_w(u8 data) { port_w(i, data); } + + u32 ram_enable_r(); + void ram_enable_w(u32 data); + +protected: + u16 adc_r(offs_t); + + u8 port_ddr_r(offs_t); + void port_ddr_w(offs_t, u8); + + u8 port_r(offs_t); + void port_w(offs_t, u8); + void port_update(offs_t); + + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + + virtual space_config_vector memory_space_config() const override; + +private: + address_space_config m_program_config; + + required_device m_vic; + required_device_array m_timer; + required_device m_kbd; + + devcb_read16::array<8> m_adc_cb; + devcb_read8::array<4> m_in_cb; + devcb_write8::array<4> m_out_cb; + u8 m_port_ddr[4], m_port_data[4]; + + memory_view m_ram_view; + u32 m_ram_enable; +}; + +// device type +DECLARE_DEVICE_TYPE(UPD800468_TIMER, upd800468_timer_device) +DECLARE_DEVICE_TYPE(UPD800468, upd800468_device) + +#endif // MAME_CPU_ARM7_UPD800468_H diff --git a/src/devices/cpu/h8/gt913.cpp b/src/devices/cpu/h8/gt913.cpp index 5f5e8ff34cb..bc8e11f5dc5 100644 --- a/src/devices/cpu/h8/gt913.cpp +++ b/src/devices/cpu/h8/gt913.cpp @@ -89,7 +89,8 @@ void gt913_device::device_add_mconfig(machine_config &config) GT913_INTC(config, "intc"); GT913_SOUND_HLE(config, m_sound, 0); - GT913_KBD_HLE(config, m_kbd, "intc", 5); + GT913_KBD_HLE(config, m_kbd, 0); + m_kbd->irq_cb().set([this](int val) { if (val) m_intc->internal_interrupt(5); }); GT913_IO_HLE(config, m_io_hle, "intc", 6, 7); H8_SCI(config, m_sci, "intc", 8, 9, 10, 0); diff --git a/src/devices/machine/gt913_kbd.cpp b/src/devices/machine/gt913_kbd.cpp index b22197153b8..ba7a2ff521c 100644 --- a/src/devices/machine/gt913_kbd.cpp +++ b/src/devices/machine/gt913_kbd.cpp @@ -28,15 +28,15 @@ DEFINE_DEVICE_TYPE(GT913_KBD_HLE, gt913_kbd_hle_device, "gt913_kbd_hle", "Casio gt913_kbd_hle_device::gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, GT913_KBD_HLE, tag, owner, clock), - device_matrix_keyboard_interface(mconfig, *this, "KO0", "KO1", "KO2", "KO3", "KO4", "KO5", "KO6", "KO7", "KO8", "KO9", "KO10", "KO11", "KO12"), - m_intc(nullptr), m_intc_tag(nullptr), m_irq(0), - m_velocity(*this, "VELOCITY") + device_matrix_keyboard_interface(mconfig, *this, "FI0", "FI1", "FI2", "FI3", "FI4", "FI5", "FI6", "FI7", "FI8", "FI9", "FI10", "KI0", "KI1", "KI2"), + m_velocity(*this, "VELOCITY"), + m_irq_cb(*this) { } void gt913_kbd_hle_device::device_start() { - m_intc = siblingdevice(m_intc_tag); + m_irq_cb.resolve_safe(); save_item(NAME(m_status)); save_item(NAME(m_fifo)); @@ -51,7 +51,7 @@ void gt913_kbd_hle_device::device_reset() m_fifo_read = m_fifo_write = 0; reset_key_state(); - start_processing(attotime::from_hz(1200)); + start_processing(attotime::from_hz(9600)); } void gt913_kbd_hle_device::key_add(uint8_t row, uint8_t column, int state) @@ -75,7 +75,9 @@ void gt913_kbd_hle_device::update_status() m_status |= 0x8000; if (BIT(m_status, 15) && BIT(m_status, 14)) - m_intc->internal_interrupt(m_irq); + m_irq_cb(1); + else + m_irq_cb(0); } uint16_t gt913_kbd_hle_device::read() diff --git a/src/devices/machine/gt913_kbd.h b/src/devices/machine/gt913_kbd.h index 3823442ff86..3bf2ced327e 100644 --- a/src/devices/machine/gt913_kbd.h +++ b/src/devices/machine/gt913_kbd.h @@ -9,7 +9,6 @@ #pragma once -#include "cpu/h8/h8_intc.h" #include "keyboard.h" //************************************************************************** @@ -18,17 +17,13 @@ // ======================> gt913_kbd_hle_device -class gt913_kbd_hle_device : public device_t, protected device_matrix_keyboard_interface<13> +class gt913_kbd_hle_device : public device_t, protected device_matrix_keyboard_interface<14> { public: // construction/destruction gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *intc, int irq) - : gt913_kbd_hle_device(mconfig, tag, owner, 0) - { - m_intc_tag = intc; - m_irq = irq; - } + + auto irq_cb() { return m_irq_cb.bind(); } uint16_t read(); void status_w(uint16_t data); @@ -46,11 +41,10 @@ protected: void key_add(uint8_t row, uint8_t column, int state); void update_status(); private: - h8_intc_device *m_intc; - const char *m_intc_tag; - int m_irq; optional_ioport m_velocity; + devcb_write_line m_irq_cb; + uint16_t m_status; uint8_t m_fifo[16]; uint8_t m_fifo_read, m_fifo_write; diff --git a/src/devices/machine/vic_pl192.cpp b/src/devices/machine/vic_pl192.cpp index 5c37d03abee..bd7c4de4e2c 100644 --- a/src/devices/machine/vic_pl192.cpp +++ b/src/devices/machine/vic_pl192.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause -// copyright-holders:Melissa Goad +// copyright-holders:Devin Acker, Melissa Goad -// ARM PrimeCell PL192 VIC emulation +// ARM PrimeCell PL910/PL192 VIC emulation #include "emu.h" -#include "machine/bankdev.h" #include "machine/vic_pl192.h" #define LOG_GENERAL (1U << 0) @@ -12,19 +11,22 @@ #define VERBOSE (LOG_GENERAL) #include "logmacro.h" -void vic_pl192_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +DEFINE_DEVICE_TYPE(PL190_VIC, vic_pl190_device, "vic_pl190", "ARM PL190 VIC") +DEFINE_DEVICE_TYPE(UPD800468_VIC, vic_upd800468_device, "vic_upd800468", "NEC uPD800468 VIC") +DEFINE_DEVICE_TYPE(PL192_VIC, vic_pl192_device, "vic_pl192", "ARM PL192 VIC") + +void vic_pl190_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - if(u32 intrs = (raw_intr | soft_intr) & intr_en) - { - if(intrs & intr_select) m_out_fiq_func(1); - else m_out_fiq_func(0); + u32 intrs = (raw_intr | soft_intr) & intr_en; - if(intrs & ~intr_select) m_out_irq_func(1); - else m_out_irq_func(0); - } + if (intrs & intr_select) m_out_fiq_func(1); + else m_out_fiq_func(0); + + if (intrs & ~intr_select & priority_mask) m_out_irq_func(1); + else m_out_irq_func(0); } -void vic_pl192_device::set_irq_line(int irq, int state) +void vic_pl190_device::set_irq_line(int irq, int state) { u32 mask = (1 << irq); @@ -40,22 +42,173 @@ void vic_pl192_device::set_irq_line(int irq, int state) timer_set(attotime::zero, TIMER_CHECK_IRQ); } -void vic_pl192_device::map(address_map &map) +u32 vic_pl190_device::irq_status_r() +{ + return raw_intr & ~intr_select; +} + +u32 vic_pl190_device::fiq_status_r() +{ + return raw_intr & intr_select; +} + +u32 vic_pl190_device::raw_intr_r() +{ + return raw_intr; +} + +u32 vic_pl190_device::int_select_r() +{ + return intr_select; +} + +void vic_pl190_device::int_select_w(u32 data) +{ + intr_select = data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::int_enable_r() +{ + return intr_en; +} + +void vic_pl190_device::int_enable_w(u32 data) +{ + intr_en |= data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_pl190_device::int_en_clear_w(u32 data) +{ + intr_en &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::soft_int_r() +{ + return soft_intr; +} + +void vic_pl190_device::soft_int_w(u32 data) +{ + soft_intr |= data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_pl190_device::soft_int_clear_w(u32 data) +{ + soft_intr &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u8 vic_pl190_device::protection_r() +{ + return protection; +} + +void vic_pl190_device::protection_w(u8 data) { - map(0x000, 0x003).lr32([this](offs_t offset){ return raw_intr & ~intr_select; }, "irq_status"); //IRQ_STATUS - map(0x004, 0x007).lr32([this](offs_t offset){ return raw_intr & intr_select; }, "fiq_status"); //FIQ_STATUS - map(0x008, 0x00b).lr32([this](offs_t offset){ return raw_intr; }, "raw_intr"); - map(0x00c, 0x00f).lrw32(NAME([this](offs_t offset){ return intr_select; }), NAME([this](offs_t offset, u32 data){ intr_select = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x010, 0x013).lrw32(NAME([this](offs_t offset){ return intr_en; }), NAME([this](offs_t offset, u32 data){ intr_en = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x014, 0x017).lw32([this](u32 data){ intr_en &= ~data; }, "intr_en_clear"); - map(0x018, 0x01b).lrw32(NAME([this](offs_t offset){ return soft_intr; }), NAME([this](offs_t offset, u32 data){ soft_intr = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x01c, 0x01f).lw32([this](u32 data){ soft_intr &= ~data; }, "soft_intr_clear"); - map(0x020, 0x020).lrw8(NAME([this](offs_t offset){ return protection; }), NAME([this](offs_t offset, u8 data){ protection = data & 1; })).umask32(0x000000ff); - map(0x024, 0x025).lrw8(NAME([this](offs_t offset){ return sw_priority_mask; }), NAME([this](offs_t offset, u16 data){ sw_priority_mask = data; })).umask32(0x0000ffff); - map(0x028, 0x028).lrw8(NAME([this](offs_t offset){ return daisy_priority; }), NAME([this](offs_t offset, u8 data){ daisy_priority = data & 0xf; })).umask32(0x000000ff); - map(0x100, 0x17f).lrw32(NAME([this](offs_t offset){ return vectaddr[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; })); - map(0x200, 0x27f).lrw8(NAME([this](offs_t offset){ return vectprio[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectprio[(offset & 0x7c) >> 2] = data & 0xf; })); - map(0xf00, 0xf03).lrw32(NAME([this](offs_t offset){ return vicaddress; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; })); + protection = BIT(data, 0); +} + +u32 vic_pl190_device::cur_vect_addr_r() +{ + if (!machine().side_effects_disabled()) + update_vector(); + + return vicaddress; +} + +void vic_pl190_device::cur_vect_addr_w(u32 data) +{ + priority_mask = ~0; + priority = ~0; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::def_vect_addr_r() +{ + return defaddress; +} + +void vic_pl190_device::def_vect_addr_w(u32 data) +{ + defaddress = data; +} + +u32 vic_pl190_device::vect_addr_r(offs_t offset) +{ + return vectaddr[offset]; +} + +void vic_pl190_device::vect_addr_w(offs_t offset, u32 data) +{ + vectaddr[offset] = data; +} + +u32 vic_pl190_device::vect_ctl_r(offs_t offset) +{ + return vectctl[offset]; +} + +void vic_pl190_device::vect_ctl_w(offs_t offset, u32 data) +{ + vectctl[offset] = data; +} + +void vic_pl190_device::update_vector() +{ + u32 intrs = (raw_intr | soft_intr) & intr_en & ~intr_select; + u32 newmask = 0; + + for (u8 i = 0; i < std::min(priority, num_vectors); i++) + { + u8 irq = vectctl[i] & 0x1f; + + if (!BIT(vectctl[i], 5)) + { + // vector is disabled + continue; + } + else if (BIT(intrs, irq)) + { + // this interrupt is enabled and pending + // take it and update priority_mask to only allow higher priority interrupts + priority_mask = newmask; + priority = i; + vicaddress = vectaddr[i]; + return; + } + else + { + // interrupt isn't pending, but it's higher priority + // allow it to be taken later + newmask |= (1 << irq); + } + } + + // no vectored interrupt taken, use the default + priority_mask = ~0; + priority = ~0; + vicaddress = defaddress; +} + +void vic_pl190_device::map(address_map &map) +{ + map(0x000, 0x003).r(FUNC(vic_pl190_device::irq_status_r)); + map(0x004, 0x007).r(FUNC(vic_pl190_device::fiq_status_r)); + map(0x008, 0x00b).r(FUNC(vic_pl190_device::raw_intr_r)); + map(0x00c, 0x00f).rw(FUNC(vic_pl190_device::int_select_r), FUNC(vic_pl190_device::int_select_w)); + map(0x010, 0x013).rw(FUNC(vic_pl190_device::int_enable_r), FUNC(vic_pl190_device::int_enable_w)); + map(0x014, 0x017).w(FUNC(vic_pl190_device::int_en_clear_w)); + map(0x018, 0x01b).rw(FUNC(vic_pl190_device::soft_int_r), FUNC(vic_pl190_device::soft_int_w)); + map(0x01c, 0x01f).w(FUNC(vic_pl190_device::soft_int_clear_w)); + map(0x020, 0x020).rw(FUNC(vic_pl190_device::protection_r), FUNC(vic_pl190_device::protection_w)).umask32(0x000000ff); + map(0x030, 0x033).rw(FUNC(vic_pl190_device::cur_vect_addr_r), FUNC(vic_pl190_device::cur_vect_addr_w)); + map(0x034, 0x037).rw(FUNC(vic_pl190_device::def_vect_addr_r), FUNC(vic_pl190_device::def_vect_addr_w)); + map(0x100, 0x13f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x23f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); map(0xfe0, 0xfe0).lr8([this](offs_t offset){ return periph_id[0]; }, "periph_id0").umask32(0x000000ff); map(0xfe4, 0xfe4).lr8([this](offs_t offset){ return periph_id[1]; }, "periph_id1").umask32(0x000000ff); map(0xfe8, 0xfe8).lr8([this](offs_t offset){ return periph_id[2]; }, "periph_id2").umask32(0x000000ff); @@ -66,65 +219,191 @@ void vic_pl192_device::map(address_map &map) map(0xffc, 0xffc).lr8([this](offs_t offset){ return pcell_id[3]; }, "pcell_id3").umask32(0x000000ff); } -device_memory_interface::space_config_vector vic_pl192_device::memory_space_config() const +device_memory_interface::space_config_vector vic_pl190_device::memory_space_config() const { return space_config_vector{ std::make_pair(0, &m_mmio_config) }; } -void vic_pl192_device::device_resolve_objects() +void vic_pl190_device::device_resolve_objects() { // resolve callbacks m_out_irq_func.resolve_safe(); m_out_fiq_func.resolve_safe(); } -void vic_pl192_device::device_start() +void vic_pl190_device::device_start() { save_item(NAME(raw_intr)); save_item(NAME(intr_select)); save_item(NAME(intr_en)); save_item(NAME(soft_intr)); save_item(NAME(vectaddr)); + save_item(NAME(defaddress)); save_item(NAME(vicaddress)); + save_item(NAME(priority_mask)); + save_item(NAME(priority)); save_item(NAME(protection)); - save_item(NAME(sw_priority_mask)); - save_item(NAME(daisy_priority)); - save_item(NAME(vectprio)); } -void vic_pl192_device::device_reset() +void vic_pl190_device::device_reset() { - raw_intr = intr_select = intr_en = soft_intr = vicaddress = protection = 0; - sw_priority_mask = 0xffff; - daisy_priority = 0xf; + raw_intr = intr_select = intr_en = soft_intr = 0; + defaddress = vicaddress = protection = 0; - for(int i = 0; i < 32; i++) - { - vectaddr[i] = 0; - } + priority_mask = ~0; + priority = ~0; for(int i = 0; i < 32; i++) { - vectprio[i] = 0xf; + vectaddr[i] = 0; + vectctl[i] = 0; } } -DEFINE_DEVICE_TYPE(PL192_VIC, vic_pl192_device, "vic_pl192", "ARM PL192 VIC") - -vic_pl192_device::vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +vic_pl190_device::vic_pl190_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) + , num_vectors(16) + , periph_id{0x92, 0x11, 0x04, 0x00} + , pcell_id{0x0d, 0xf0, 0x05, 0xb1} , m_mmio_config("mmio", ENDIANNESS_LITTLE, 32, 32, 0) , m_out_irq_func(*this) , m_out_fiq_func(*this) - , periph_id{0x92, 0x11, 0x04, 0x00} - , pcell_id{0x0d, 0xf0, 0x05, 0xb1} { } +vic_pl190_device::vic_pl190_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : vic_pl190_device(mconfig, PL190_VIC, tag, owner, clock) +{ +} + + + + +void vic_upd800468_device::int_clear_w(u32 data) +{ + raw_intr &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_upd800468_device::map(address_map &map) +{ + vic_pl190_device::map(map); + + map(0x100, 0x17f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x27f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); + map(0x2c8, 0x2cb).w(FUNC(vic_upd800468_device::int_clear_w)); +} + +vic_upd800468_device::vic_upd800468_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : vic_pl190_device(mconfig, UPD800468_VIC, tag, owner, clock) +{ + num_vectors = 32; +} + + + + +u16 vic_pl192_device::sw_priority_r() +{ + return sw_priority_mask; +} + +void vic_pl192_device::sw_priority_w(u16 data) +{ + sw_priority_mask = data; +} + +u8 vic_pl192_device::daisy_priority_r() +{ + return daisy_priority; +} + +void vic_pl192_device::daisy_priority_w(u8 data) +{ + daisy_priority = data & 0xf; +} + +void vic_pl192_device::update_vector() +{ + u32 intrs = (raw_intr | soft_intr) & intr_en & ~intr_select; + u32 newmask = 0; + + // see if there's a higher priority active interrupt to take + for (u8 i = 0; i < num_vectors; i++) + { + u8 new_prio = vectctl[i] & 0xf; + if (BIT(sw_priority_mask, new_prio) && BIT(intrs, i) && new_prio < priority) + { + // this interrupt is enabled and pending, take it + priority = new_prio; + vicaddress = vectaddr[i]; + } + } + + // update priority_mask to only allow higher priority interrupts + for (u8 i = 0; i < num_vectors; i++) + { + u8 new_prio = vectctl[i] & 0xf; + if (BIT(sw_priority_mask, new_prio) && new_prio < priority) + { + newmask |= (1 << i); + } + } + priority_mask = newmask; +} + +void vic_pl192_device::map(address_map &map) +{ + map(0x000, 0x003).r(FUNC(vic_pl190_device::irq_status_r)); + map(0x004, 0x007).r(FUNC(vic_pl190_device::fiq_status_r)); + map(0x008, 0x00b).r(FUNC(vic_pl190_device::raw_intr_r)); + map(0x00c, 0x00f).rw(FUNC(vic_pl190_device::int_select_r), FUNC(vic_pl190_device::int_select_w)); + map(0x010, 0x013).rw(FUNC(vic_pl190_device::int_enable_r), FUNC(vic_pl190_device::int_enable_w)); + map(0x014, 0x017).w(FUNC(vic_pl190_device::int_en_clear_w)); + map(0x018, 0x01b).rw(FUNC(vic_pl190_device::soft_int_r), FUNC(vic_pl190_device::soft_int_w)); + map(0x01c, 0x01f).w(FUNC(vic_pl190_device::soft_int_clear_w)); + map(0x020, 0x020).rw(FUNC(vic_pl190_device::protection_r), FUNC(vic_pl190_device::protection_w)).umask32(0x000000ff); + map(0x024, 0x025).rw(FUNC(vic_pl192_device::sw_priority_r), FUNC(vic_pl192_device::sw_priority_w)).umask32(0x0000ffff); + map(0x028, 0x028).rw(FUNC(vic_pl192_device::daisy_priority_r), FUNC(vic_pl192_device::daisy_priority_w)).umask32(0x000000ff); + map(0x100, 0x17f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x27f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); + map(0xf00, 0xf03).rw(FUNC(vic_pl190_device::cur_vect_addr_r), FUNC(vic_pl190_device::cur_vect_addr_w)); + map(0xfe0, 0xfe0).lr8([this](offs_t offset) { return periph_id[0]; }, "periph_id0").umask32(0x000000ff); + map(0xfe4, 0xfe4).lr8([this](offs_t offset) { return periph_id[1]; }, "periph_id1").umask32(0x000000ff); + map(0xfe8, 0xfe8).lr8([this](offs_t offset) { return periph_id[2]; }, "periph_id2").umask32(0x000000ff); + map(0xfec, 0xfec).lr8([this](offs_t offset) { return periph_id[3]; }, "periph_id3").umask32(0x000000ff); + map(0xff0, 0xff0).lr8([this](offs_t offset) { return pcell_id[0]; }, "pcell_id0").umask32(0x000000ff); + map(0xff4, 0xff4).lr8([this](offs_t offset) { return pcell_id[1]; }, "pcell_id1").umask32(0x000000ff); + map(0xff8, 0xff8).lr8([this](offs_t offset) { return pcell_id[2]; }, "pcell_id2").umask32(0x000000ff); + map(0xffc, 0xffc).lr8([this](offs_t offset) { return pcell_id[3]; }, "pcell_id3").umask32(0x000000ff); +} + +void vic_pl192_device::device_start() +{ + vic_pl190_device::device_start(); + + save_item(NAME(sw_priority_mask)); + save_item(NAME(daisy_priority)); +} + +void vic_pl192_device::device_reset() +{ + vic_pl190_device::device_start(); + + sw_priority_mask = 0xffff; + daisy_priority = 0xf; + + for (int i = 0; i < 32; i++) + { + vectctl[i] = 0xf; + } +} + vic_pl192_device::vic_pl192_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : vic_pl192_device(mconfig, PL192_VIC, tag, owner, clock) + : vic_pl190_device(mconfig, PL192_VIC, tag, owner, clock) { + num_vectors = 32; } diff --git a/src/devices/machine/vic_pl192.h b/src/devices/machine/vic_pl192.h index 9936b369fb6..cb07a8854d5 100644 --- a/src/devices/machine/vic_pl192.h +++ b/src/devices/machine/vic_pl192.h @@ -1,26 +1,70 @@ // license:BSD-3-Clause -// copyright-holders:Melissa Goad +// copyright-holders:Devin Acker, Melissa Goad -// ARM PrimeCell PL192 VIC emulation +// ARM PrimeCell PL910/PL192 VIC emulation #ifndef MAME_MACHINE_VIC_PL192_H #define MAME_MACHINE_VIC_PL192_H -class vic_pl192_device : public device_t, public device_memory_interface +class vic_pl190_device : public device_t, public device_memory_interface { public: - vic_pl192_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + vic_pl190_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); auto out_irq_cb() { return m_out_irq_func.bind(); } auto out_fiq_cb() { return m_out_fiq_func.bind(); } template - DECLARE_WRITE_LINE_MEMBER( irq_w ) { set_irq_line(IRQ, state); } + DECLARE_WRITE_LINE_MEMBER(irq_w) { set_irq_line(IRQ, state); } void map(address_map &map); + u32 irq_status_r(); + u32 fiq_status_r(); + u32 raw_intr_r(); + + u32 int_select_r(); + void int_select_w(u32 data); + + u32 int_enable_r(); + void int_enable_w(u32 data); + void int_en_clear_w(u32 data); + + u32 soft_int_r(); + void soft_int_w(u32 data); + void soft_int_clear_w(u32 data); + + u8 protection_r(); + void protection_w(u8 data); + + u32 cur_vect_addr_r(); + void cur_vect_addr_w(u32 data); + + u32 def_vect_addr_r(); + void def_vect_addr_w(u32 data); + + u32 vect_addr_r(offs_t offset); + void vect_addr_w(offs_t offset, u32 data); + + u32 vect_ctl_r(offs_t offset); + void vect_ctl_w(offs_t offset, u32 data); + protected: - vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + static constexpr device_timer_id TIMER_CHECK_IRQ = 0; + + vic_pl190_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void update_vector(); + + u8 num_vectors; // number of available vectored interrupts + + u32 raw_intr, intr_select, intr_en, soft_intr; + u32 vectaddr[32], vectctl[32], defaddress, vicaddress; + int protection; + + u32 priority_mask; // mask for interrupts which can take priority over the current one + u8 priority; // priority level of the current interrupt, if any + u8 periph_id[4], pcell_id[4]; // device-level overrides virtual void device_resolve_objects() override; @@ -31,21 +75,52 @@ protected: virtual space_config_vector memory_space_config() const override; private: - static constexpr device_timer_id TIMER_CHECK_IRQ = 0; - void set_irq_line(int irq, int state); address_space_config m_mmio_config; devcb_write_line m_out_irq_func; devcb_write_line m_out_fiq_func; - u32 raw_intr, intr_select, intr_en, soft_intr, vectaddr[32], vicaddress; - int protection; +}; + +class vic_upd800468_device : public vic_pl190_device +{ +public: + vic_upd800468_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + + void map(address_map &map); + + void int_clear_w(u32 data); +}; + +class vic_pl192_device : public vic_pl190_device +{ +public: + vic_pl192_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + + void map(address_map &map); + + u16 sw_priority_r(); + void sw_priority_w(u16 data); + + u8 daisy_priority_r(); + void daisy_priority_w(u8 data); + +protected: + + virtual void update_vector() override; + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: u16 sw_priority_mask; - u8 daisy_priority, vectprio[32]; - u8 periph_id[4], pcell_id[4]; + u8 daisy_priority; }; +DECLARE_DEVICE_TYPE(PL190_VIC, vic_pl190_device) +DECLARE_DEVICE_TYPE(UPD800468_VIC, vic_upd800468_device) DECLARE_DEVICE_TYPE(PL192_VIC, vic_pl192_device) #endif // MAME_MACHINE_VIC_PL192_H diff --git a/src/mame/drivers/ctk2000.cpp b/src/mame/drivers/ctk2000.cpp new file mode 100644 index 00000000000..64aba38114c --- /dev/null +++ b/src/mame/drivers/ctk2000.cpp @@ -0,0 +1,300 @@ +// license:BSD-3-Clause +// copyright-holders:Devin Acker +/* + Casio CTK-2000 keyboard (and related models) + + - CTK-2000 (2008) + Basic 61-key model + - CTK-3000 + Adds velocity-sensitive keys and pitch wheel + - CTK-2100 (2009) + More flexible sampling feature, lesson buttons double as voice/drum pads + (based on CTK-2000, not 3000) + + Main board (M800-MDA1): + + IC1: CPU (NEC uPD800468) + Custom chip (ARM-based), built in peripheral controllers & sound generator + + LSI2: 16Mbit ROM (OKI MR27T1602L) + + Console PCB (M800-CNA): + + IC401: LCD controller (Sitronix ST7066U-0A, HD44780 compatible) + + CTK-2000 service manual with schematics, pinouts, etc.: + https://www.manualslib.com/manual/933451/Casio-Ctk-2000.html + + */ + +#include "emu.h" + +#include "cpu/arm7/upd800468.h" +#include "video/hd44780.h" +#include "emupal.h" +#include "screen.h" + +namespace { + +class ctk2000_state : public driver_device +{ +public: + ctk2000_state(machine_config const &mconfig, device_type type, char const *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_lcdc(*this, "lcdc") + { + } + + void ctk2000(machine_config &config); + + DECLARE_CUSTOM_INPUT_MEMBER(lcd_r) { return m_lcdc->db_r() >> 4; } + DECLARE_WRITE_LINE_MEMBER(lcd_w) { m_lcdc->db_w(state << 4); } + + DECLARE_WRITE_LINE_MEMBER(apo_w); + +private: + void ctk2000_map(address_map &map); + + virtual void driver_start() override; + virtual void driver_reset() override; + + HD44780_PIXEL_UPDATE(lcd_update); + void palette_init(palette_device &palette); + + required_device m_maincpu; + required_device m_lcdc; +}; + +WRITE_LINE_MEMBER(ctk2000_state::apo_w) +{ + logerror("apo_w: %x\n", state); + /* TODO: when 0, this should turn off the LCD, speakers, etc. */ +} + +HD44780_PIXEL_UPDATE(ctk2000_state::lcd_update) +{ + if (x < 6 && y < 8 && line < 2 && pos < 8) + bitmap.pix(line * 8 + y, pos * 6 + x) = state; +} + +void ctk2000_state::palette_init(palette_device &palette) +{ + palette.set_pen_color(0, rgb_t(255, 255, 255)); + palette.set_pen_color(1, rgb_t(0, 0, 0)); +} + +void ctk2000_state::ctk2000_map(address_map &map) +{ + // ROM is based at 0x18000000, but needs to be mirrored to the beginning of memory in order to boot + map(0x00000000, 0x001fffff).rom().mirror(0x18e00000); +} + +void ctk2000_state::driver_start() +{ +} + +void ctk2000_state::driver_reset() +{ +} + +void ctk2000_state::ctk2000(machine_config &config) +{ + // CPU + UPD800468(config, m_maincpu, 48'000'000); + m_maincpu->set_addrmap(AS_PROGRAM, &ctk2000_state::ctk2000_map); + m_maincpu->port_in_cb<2>().set_ioport("P2_R"); + m_maincpu->port_out_cb<2>().set_ioport("P2_W"); + m_maincpu->port_out_cb<3>().set_ioport("P3"); + // ADCs 0, 5, 6, 7 are connected to the mic input + // ADC 4 is connected to the pitch wheel (for ctk3000) + m_maincpu->adc_cb<1>().set_ioport("AIN1"); + m_maincpu->adc_cb<2>().set_ioport("AIN2"); + m_maincpu->adc_cb<3>().set_ioport("AIN3"); + + // LCD + HD44780(config, m_lcdc, 0); + m_lcdc->set_lcd_size(2, 8); + m_lcdc->set_pixel_update_cb(FUNC(ctk2000_state::lcd_update)); + + // screen (for testing only) + // TODO: the actual LCD with custom segments + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); + screen.set_refresh_hz(60); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_screen_update("lcdc", FUNC(hd44780_device::screen_update)); + screen.set_size(6 * 8, 8 * 2); + screen.set_visarea_full(); + screen.set_palette("palette"); + + PALETTE(config, "palette", FUNC(ctk2000_state::palette_init), 2); +} + +INPUT_PORTS_START(ctk2100) + PORT_START("maincpu:kbd:FI0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D2") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D2#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E2") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F2") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F2#") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2") + + PORT_START("maincpu:kbd:FI1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B2") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C3") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C3#") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3#") + + PORT_START("maincpu:kbd:FI2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E3") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G3") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G3#") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A3") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A3#") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B3") + + PORT_START("maincpu:kbd:FI3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D4") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D4#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E4") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F4") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F4#") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4") + + PORT_START("maincpu:kbd:FI4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B4") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C5") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C5#") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5#") + + PORT_START("maincpu:kbd:FI5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E5") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G5") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G5#") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A5") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A5#") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B5") + + PORT_START("maincpu:kbd:FI6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D6") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D6#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E6") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F6") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F6#") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6") + + PORT_START("maincpu:kbd:FI7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B6") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C7") + PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("maincpu:kbd:FI8") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("maincpu:kbd:FI9") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD) + + PORT_START("maincpu:kbd:FI10") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad +") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Pad 5 / Auto") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Synchro / Ending / Pause") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Accomp On/Off / Chord / Part Select") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Sampling") + + PORT_START("maincpu:kbd:KI0") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("maincpu:kbd:KI1") + // "song bank" and "tone" seem to be swapped in the schematic + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Song Bank") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tone") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tempo Up") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Set Select / Music Challenge") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Pad 4 / Next") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Play / Stop") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Metronome") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Intro / Repeat") + + PORT_START("maincpu:kbd:KI2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tempo Down") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Pad 2 / Watch") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Pad 3 / Remember") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Voice Pad 1 / Listen") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Normal / Fill In / Rewind") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Function") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Variation / Fill In / Fast Forward") + + PORT_START("P2_R") + PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ctk2000_state, lcd_r) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("P2_W") + PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(ctk2000_state, lcd_w) + PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, e_w) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(ctk2000_state, apo_w) + + PORT_START("P3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, rw_w) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, rs_w) + PORT_BIT( 0xf8, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("AIN1") + PORT_BIT( 0x3ff, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Pedal") + + PORT_START("AIN2") + PORT_CONFNAME( 0x3ff, 0x000, "Power Source" ) + PORT_CONFSETTING( 0x000, "AC Adapter" ) + PORT_CONFSETTING( 0x3ff, "Battery" ) + + PORT_START("AIN3") + PORT_BIT( 0x3ff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("AIN2", 0x3ff, EQUALS, 0) + PORT_CONFNAME( 0x3ff, 0x3ff, "Battery Level" ) PORT_CONDITION("AIN2", 0x3ff, NOTEQUALS, 0) + // values here are somewhat arbitrary - ctk2100 only checks if the value is above/below a certain threshold + PORT_CONFSETTING( 0x100, "Low" ) + PORT_CONFSETTING( 0x3ff, "Normal" ) + +INPUT_PORTS_END + +ROM_START(ctk2100) + ROM_REGION(0x200000, "maincpu", 0) + ROM_LOAD("ctk2100.ic2", 0x000000, 0x200000, CRC(daf62f81) SHA1(4edc76ea04b59090d02646d92f9fc635a43140e9)) +ROM_END + +} // anonymous namespace + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +SYST( 2009, ctk2100, 0, 0, ctk2000, ctk2100, ctk2000_state, empty_init, "Casio", "CTK-2100", MACHINE_NO_SOUND | MACHINE_NODEVICE_MICROPHONE | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/ctk551.cpp b/src/mame/drivers/ctk551.cpp index 82f2c90128c..77b0859aab8 100644 --- a/src/mame/drivers/ctk551.cpp +++ b/src/mame/drivers/ctk551.cpp @@ -180,7 +180,7 @@ void ctk551_state::ctk551(machine_config &config) } INPUT_PORTS_START(ctk551) - PORT_START("maincpu:kbd:KO0") + PORT_START("maincpu:kbd:FI0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2#") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D2") @@ -190,7 +190,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F2#") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2") - PORT_START("maincpu:kbd:KO1") + PORT_START("maincpu:kbd:FI1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2#") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2#") @@ -200,7 +200,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3#") - PORT_START("maincpu:kbd:KO2") + PORT_START("maincpu:kbd:FI2") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E3") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3#") @@ -210,7 +210,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A3#") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B3") - PORT_START("maincpu:kbd:KO3") + PORT_START("maincpu:kbd:FI3") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4#") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D4") @@ -220,7 +220,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F4#") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4") - PORT_START("maincpu:kbd:KO4") + PORT_START("maincpu:kbd:FI4") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4#") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4#") @@ -230,7 +230,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5#") - PORT_START("maincpu:kbd:KO5") + PORT_START("maincpu:kbd:FI5") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E5") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5#") @@ -240,7 +240,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A5#") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B5") - PORT_START("maincpu:kbd:KO6") + PORT_START("maincpu:kbd:FI6") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6#") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D6") @@ -250,7 +250,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F6#") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6") - PORT_START("maincpu:kbd:KO7") + PORT_START("maincpu:kbd:FI7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6#") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6#") @@ -258,7 +258,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C7") PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_START("maincpu:kbd:KO8") + PORT_START("maincpu:kbd:FI8") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) @@ -268,7 +268,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tone") - PORT_START("maincpu:kbd:KO9") + PORT_START("maincpu:kbd:FI9") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) @@ -278,7 +278,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Transpose / Tune / MIDI") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Chord Book") - PORT_START("maincpu:kbd:KO10") + PORT_START("maincpu:kbd:FI10") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) @@ -288,7 +288,7 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Start / Stop") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Sync / Fill In") - PORT_START("maincpu:kbd:KO11") + PORT_START("maincpu:kbd:KI0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right Hand On/Off") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left Hand On/Off") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Fast Forward") @@ -298,10 +298,13 @@ INPUT_PORTS_START(ctk551) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tempo Up") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Volume Up") - PORT_START("maincpu:kbd:KO12") + PORT_START("maincpu:kbd:KI1") PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ctk551_state, switch_r) + PORT_START("maincpu:kbd:KI2") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_START("maincpu:kbd:VELOCITY") PORT_BIT( 0x7f, 0x7f, IPT_POSITIONAL ) PORT_NAME("Key Velocity") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) diff --git a/src/mame/mess.flt b/src/mame/mess.flt index feccd2dc9f5..f10c87b6eb6 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -207,6 +207,7 @@ crei680.cpp crimson.cpp crvision.cpp ct486.cpp +ctk2000.cpp ctk551.cpp cvicny.cpp cxg_ch2001.cpp diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 4108b35ef42..64610c3ba21 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -56,6 +56,7 @@ using util::BIT; #include "cpu/g65816/g65816ds.h" #include "cpu/gigatron/gigatrondasm.h" #include "cpu/h6280/6280dasm.h" +#include "cpu/h8/gt913d.h" #include "cpu/h8/h8d.h" #include "cpu/h8/h8hd.h" #include "cpu/h8/h8s2000d.h" @@ -423,6 +424,7 @@ static const dasm_table_entry dasm_table[] = { "fr", be, 0, []() -> util::disasm_interface * { return new fr_disassembler; } }, { "g65816", le, 0, []() -> util::disasm_interface * { return new g65816_disassembler(&g65816_unidasm); } }, { "gigatron", be, -1, []() -> util::disasm_interface * { return new gigatron_disassembler; } }, + { "gt913", be, 0, []() -> util::disasm_interface * { return new gt913_disassembler; } }, { "h6280", le, 0, []() -> util::disasm_interface * { return new h6280_disassembler; } }, { "h8", be, 0, []() -> util::disasm_interface * { return new h8_disassembler; } }, { "h8h", be, 0, []() -> util::disasm_interface * { return new h8h_disassembler; } }, -- cgit v1.2.3