From 8e9d6cc9552eb46aa1bb3f30f2a15a43784d047f Mon Sep 17 00:00:00 2001 From: Devin Acker Date: Fri, 26 Jan 2024 17:34:04 -0500 Subject: [PATCH] casio/cz230s.cpp: Added Casio CZ-230S and SZ-1. (#11969) * cpu/upd7810: Added support for internal RAM. * sound/upd934g.cpp: Corrected channel mapping for play sample command. * video/mn1252.cpp: Added Panasonic MN1252 LCD controller emulation. * casio/ra3.cpp: Added RA-5 8 KiB RAM cartridge. New working systems ---------- Casio CZ-230S [BCM, =CO=Windler, Devin Acker] Casio SZ-1 [BCM, Devin Acker] --- scripts/src/video.lua | 12 + src/devices/cpu/upd7810/upd7810.cpp | 7 +- src/devices/cpu/upd7810/upd7810.h | 1 + src/devices/cpu/upd7810/upd7810_opcodes.cpp | 5 + src/devices/sound/upd934g.cpp | 40 +- src/devices/sound/upd934g.h | 1 - src/devices/video/mn1252.cpp | 103 +++ src/devices/video/mn1252.h | 42 ++ src/mame/casio/cz230s.cpp | 694 ++++++++++++++++++++ src/mame/casio/ra3.cpp | 7 + src/mame/casio/ra3.h | 7 + src/mame/layout/cz230s.lay | 601 +++++++++++++++++ src/mame/layout/sz1.lay | 230 +++++++ src/mame/mame.lst | 4 + 14 files changed, 1729 insertions(+), 25 deletions(-) create mode 100644 src/devices/video/mn1252.cpp create mode 100644 src/devices/video/mn1252.h create mode 100644 src/mame/casio/cz230s.cpp create mode 100644 src/mame/layout/cz230s.lay create mode 100644 src/mame/layout/sz1.lay diff --git a/scripts/src/video.lua b/scripts/src/video.lua index 299ba9ba502..3e59d10ba06 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -809,6 +809,18 @@ if (VIDEOS["MOS8563"]~=null) then } end +-------------------------------------------------- +-- +--@src/devices/video/mn1252.h,VIDEOS["MN1252"] = true +-------------------------------------------------- + +if (VIDEOS["MN1252"]~=null) then + files { + MAME_DIR .. "src/devices/video/mn1252.cpp", + MAME_DIR .. "src/devices/video/mn1252.h", + } +end + -------------------------------------------------- -- --@src/devices/video/pc_vga.h,VIDEOS["PC_VGA"] = true diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index fd43adb2294..d63264d7e30 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -389,7 +389,8 @@ void upd7810_device::upd_internal_128_ram_map(address_map &map) void upd7810_device::upd_internal_256_ram_map(address_map &map) { - map(0xff00, 0xffff).ram(); + map(0xff00, 0xffff).view(m_ram_view); + m_ram_view[0](0xff00, 0xffff).ram(); } void upd7810_device::upd_internal_4096_rom_128_ram_map(address_map &map) @@ -401,7 +402,8 @@ void upd7810_device::upd_internal_4096_rom_128_ram_map(address_map &map) void upd7810_device::upd_internal_4096_rom_256_ram_map(address_map &map) { map(0x0000, 0x0fff).rom(); - map(0xff00, 0xffff).ram(); + map(0xff00, 0xffff).view(m_ram_view); + m_ram_view[0](0xff00, 0xffff).ram(); } upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map) @@ -424,6 +426,7 @@ upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, , m_pf_out_cb(*this) , m_pt_in_cb(*this, 0) // TODO: uPD7807 only , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, internal_map) + , m_ram_view(*this, "ram_view") , m_pa_pullups(0xff) , m_pb_pullups(0xff) , m_pc_pullups(0xff) diff --git a/src/devices/cpu/upd7810/upd7810.h b/src/devices/cpu/upd7810/upd7810.h index 4b6315c1fd7..d5344db0a60 100644 --- a/src/devices/cpu/upd7810/upd7810.h +++ b/src/devices/cpu/upd7810/upd7810.h @@ -236,6 +236,7 @@ protected: static const struct opcode_s s_opXX_78c06[256]; address_space_config m_program_config; + memory_view m_ram_view; PAIR m_ppc; /* previous program counter */ PAIR m_pc; /* program counter */ diff --git a/src/devices/cpu/upd7810/upd7810_opcodes.cpp b/src/devices/cpu/upd7810/upd7810_opcodes.cpp index 7df4a498fdc..32df608e867 100644 --- a/src/devices/cpu/upd7810/upd7810_opcodes.cpp +++ b/src/devices/cpu/upd7810/upd7810_opcodes.cpp @@ -1042,6 +1042,11 @@ void upd7810_device::MOV_TMM_A() void upd7810_device::MOV_MM_A() { MM = A; + + if (BIT(A, 3)) + m_ram_view.select(0); + else + m_ram_view.disable(); } /* 4d d1: 0100 1101 1101 0001 */ diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp index f3321c70d3d..1178ef0a930 100644 --- a/src/devices/sound/upd934g.cpp +++ b/src/devices/sound/upd934g.cpp @@ -9,13 +9,14 @@ TODO: - Correct MUTED and ACCENTED (currently just changes volume) - T1 input - - 8 channels? ***************************************************************************/ #include "emu.h" #include "upd934g.h" +#define VERBOSE (0) +#include "logmacro.h" //************************************************************************** // DEVICE DEFINITIONS @@ -54,13 +55,9 @@ void upd934g_device::device_start() // register for save states save_pointer(NAME(m_addr), 16); - for (unsigned i = 0; i < 4; i++) - { - save_item(NAME(m_channel[i].pos), i); - save_item(NAME(m_channel[i].playing), i); - save_item(NAME(m_channel[i].volume), i); - save_item(NAME(m_channel[i].effect), i); - } + save_item(STRUCT_MEMBER(m_channel, pos)); + save_item(STRUCT_MEMBER(m_channel, playing)); + save_item(STRUCT_MEMBER(m_channel, effect)); save_item(NAME(m_sample)); save_item(NAME(m_ready)); @@ -93,13 +90,13 @@ void upd934g_device::sound_stream_update(sound_stream &stream, std::vector(read_byte(m_channel[ch].pos)); + int16_t raw = static_cast(read_byte(m_channel[ch].pos)) * 4; // normal, muted, accented const double adjust[] = { 0, 0.7, 0.4, 1.0 }; raw *= adjust[m_channel[ch].effect]; - outputs[ch].put_int(i, raw * (m_channel[ch].volume + 1), 32768 / 64); + outputs[ch].put_int(i, raw, 32768 / 64); if (++m_channel[ch].pos >= end) { @@ -127,24 +124,23 @@ void upd934g_device::write(offs_t offset, uint8_t data) // format of data written here is: // 76------ command // --5432-- sample number - // ------10 volume? + // ------10 output channel m_sample = (data >> 2) & 0x0f; switch (data >> 6) { case 0: - logerror("CMD STORE ADDRESS sample %x\n", m_sample); + LOG("CMD STORE ADDRESS sample %x\n", m_sample); break; - case 1: - case 2: - case 3: - logerror("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, m_sample >> 1, data >> 6); - if (m_sample < 8) + case 1: // normal + case 2: // muted + case 3: // accented { - m_channel[m_sample >> 1].pos = m_addr[m_sample]; - m_channel[m_sample >> 1].playing = m_sample; - m_channel[m_sample >> 1].volume = data & 0x03; - m_channel[m_sample >> 1].effect = data >> 6; + const u8 ch = (data & 3) ^ 2; // effective order seems to be "2, 3, 0, 1" + LOG("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, ch, data >> 6); + m_channel[ch].pos = m_addr[m_sample]; + m_channel[ch].playing = m_sample; + m_channel[ch].effect = data >> 6; } break; } @@ -154,7 +150,7 @@ void upd934g_device::write(offs_t offset, uint8_t data) break; case 2: m_addr[m_sample] = (m_addr[m_sample] & 0x00ff) | (data << 8); - logerror(" sample %x address = %04x\n", m_sample, m_addr[m_sample]); + LOG(" sample %x address = %04x\n", m_sample, m_addr[m_sample]); break; case 3: m_ready = true; diff --git a/src/devices/sound/upd934g.h b/src/devices/sound/upd934g.h index 793fa71b162..2799c4d0984 100644 --- a/src/devices/sound/upd934g.h +++ b/src/devices/sound/upd934g.h @@ -45,7 +45,6 @@ private: { uint16_t pos; int playing; - int volume; int effect; } m_channel[4]; diff --git a/src/devices/video/mn1252.cpp b/src/devices/video/mn1252.cpp new file mode 100644 index 00000000000..c11b4e5378e --- /dev/null +++ b/src/devices/video/mn1252.cpp @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:Devin Acker +/*************************************************************************** + +Panasonic MN1252 LCD controller + +***************************************************************************/ + +#include "emu.h" +#include "mn1252.h" + +#include + + +DEFINE_DEVICE_TYPE(MN1252, mn1252_device, "mn1252", "Panasonic MN1252 LCD controller") + +const u8 mn1252_device::OUTPUT_DIGITS[0x40] = +{ + // bit 0..7 = segment a..h (from datasheet) + 0x00, 0x77, 0x7f, 0x39, 0x3f, 0x79, 0x71, 0x3d, + 0x76, 0x06, 0x1e, 0xf0, 0x38, 0xb7, 0xb6, 0xbf, + 0x73, 0xbf, 0xf3, 0x6d, 0x07, 0x3e, 0xa6, 0xbe, + 0xf2, 0x6e, 0x5b, 0x48, 0x0f, 0x46, 0x49, 0x44, + 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, + 0x7c, 0x58, 0x5e, 0x54, 0x5c, 0x40, 0x21, 0x0c, + 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, + 0x7f, 0x6f, 0x01, 0x36, 0x5f, 0x7b, 0x74, 0x62 +}; + +mn1252_device::mn1252_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, MN1252, tag, owner, clock) +{ +} + +/**************************************************************************/ +void mn1252_device::device_start() +{ + save_item(NAME(m_data)); + save_item(NAME(m_first_nibble)); + save_item(NAME(m_nibble_count)); + save_item(NAME(m_ce)); + save_item(NAME(m_std)); + save_item(NAME(m_output)); +} + +/**************************************************************************/ +void mn1252_device::device_reset() +{ + m_data = m_first_nibble = 0; + m_nibble_count = 0; + m_ce = m_std = 0; + + std::fill(std::begin(m_output), std::end(m_output), 0); +} + +/**************************************************************************/ +u16 mn1252_device::output(offs_t digit) const +{ + assert(digit < 6); + return m_output[digit]; +} + +/**************************************************************************/ +void mn1252_device::data_w(u8 data) +{ + m_data = data & 0xf; +} + +/**************************************************************************/ +void mn1252_device::ce_w(int state) +{ + if (!m_ce && state) + { + m_nibble_count = 0; + } + + m_ce = state; +} + +/**************************************************************************/ +void mn1252_device::std_w(int state) +{ + if (m_ce && m_std && !state && m_nibble_count < 12) + { + if (!(m_nibble_count % 2)) + { + m_first_nibble = m_data; + } + else + { + const u8 data = (m_first_nibble << 4) | m_data; + u16 output = OUTPUT_DIGITS[data & 0x3f]; + if (BIT(data, 6)) output |= 0x80; // segment h + if (BIT(data, 7)) output |= 0x100; // segment p + + m_output[m_nibble_count / 2] = output; + } + + m_nibble_count++; + } + + m_std = state; +} diff --git a/src/devices/video/mn1252.h b/src/devices/video/mn1252.h new file mode 100644 index 00000000000..f79371adfc0 --- /dev/null +++ b/src/devices/video/mn1252.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Devin Acker +/*************************************************************************** + + Panasonic MN1252 LCD controller + +***************************************************************************/ + +#ifndef MAME_VIDEO_MN1252_H +#define MAME_VIDEO_MN1252_H + +#pragma once + +class mn1252_device : public device_t +{ +public: + mn1252_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + u16 output(offs_t digit) const; + + void data_w(u8 data); + void ce_w(int state); + void std_w(int state); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + static const u8 OUTPUT_DIGITS[0x40]; + + u8 m_data; + u8 m_first_nibble; + u8 m_nibble_count; + u8 m_ce, m_std; + + u16 m_output[6]; +}; + +DECLARE_DEVICE_TYPE(MN1252, mn1252_device) + +#endif // MAME_VIDEO_MN1252_H diff --git a/src/mame/casio/cz230s.cpp b/src/mame/casio/cz230s.cpp new file mode 100644 index 00000000000..c5c83b1331e --- /dev/null +++ b/src/mame/casio/cz230s.cpp @@ -0,0 +1,694 @@ +// license: BSD-3-Clause +// copyright-holders: Devin Acker +/*************************************************************************** + Casio CZ-230S digital synthesizer and SZ-1 MIDI sequencer + + Misc. stuff: + Both of these devices have a way of loading and running external code. + - CZ-230S: + Hold "portamento speed", "value up", and "value down" together on boot. This will cause the + LCD to display "L-", as when loading from tape. At this point, the unit will try to load + $700 bytes over MIDI/serial to address $3800 and then jump to it. + - SZ-1: + While not recording or playing, pressing the Rest + Dot + Triplet buttons at the same time will + cause the firmware to check for a JMP instruction (54) at the first byte of cartridge memory + ($e000), and execute it if there is one. + + TODO: auto power off. Even after activating this, both units still continue executing as normal + (and the power switch itself is not connected to the CPU, unlike on the CZ-101/1000) + +***************************************************************************/ + +#include "emu.h" + +#include "ra3.h" + +#include "bus/midi/midiinport.h" +#include "bus/midi/midioutport.h" +#include "cpu/upd7810/upd7811.h" +#include "imagedev/cassette.h" +#include "machine/clock.h" +#include "machine/nvram.h" +#include "sound/beep.h" +#include "sound/upd933.h" +#include "sound/upd934g.h" +#include "video/mn1252.h" + +#include "screen.h" +#include "speaker.h" + +#include "cz230s.lh" +#include "sz1.lh" + +namespace { + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class cz230s_state : public driver_device +{ +public: + cz230s_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_lcdc(*this, "lcdc"), + m_cassette(*this, "cassette"), + m_pd(*this, "pd"), + m_pcm(*this, "pcm"), + m_keys(*this, "KC%u", 0U), + m_lcd_seg(*this, "%u.%u", 0U, 0U), + m_led(*this, "led%u.%u", 0U, 0U), + m_rhythm(*this, "rhythm_pos"), + m_mode(*this, "mode_pos") + { } + + void config_base(machine_config &config, u16 screen_w, u16 screen_h, bool midi_thru = true); + void cz230s(machine_config &config); + void sz1(machine_config &config); + + void keys_w(int state) { m_key_sel = state; } + void keys_mux_w(int state) { m_key_mux = state; } + template DECLARE_CUSTOM_INPUT_MEMBER(keys_row_r); + template u8 keys_analog_r(); + + DECLARE_INPUT_CHANGED_MEMBER(rhythm_w); + template DECLARE_CUSTOM_INPUT_MEMBER(rhythm_r) { return m_rhythm >> Bit; } + DECLARE_INPUT_CHANGED_MEMBER(mode_w); + DECLARE_CUSTOM_INPUT_MEMBER(mode_r) { return m_mode; } + + void cassette_w(int state); + void cassette_motor_w(int state); + DECLARE_CUSTOM_INPUT_MEMBER(cassette_r); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + void cz230s_map(address_map &map); + void cz230s_pcm_map(address_map &map); + void sz1_map(address_map &map); + + void pcm_w(offs_t offset, u8 data); + template void led_w(u8 data); + void port_a_w(u8 data); + u8 keys_r(); + + void render_w(int state); + + required_device m_maincpu; + required_device m_lcdc; + required_device m_cassette; + optional_device m_pd; + optional_device m_pcm; + + optional_ioport_array<12> m_keys; + + output_finder<6, 9> m_lcd_seg; + output_finder<2, 8> m_led; + output_finder<> m_rhythm; + output_finder<> m_mode; + + u8 m_port_a; + u8 m_key_sel; + u8 m_key_mux; + u8 m_midi_rx; +}; + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void cz230s_state::cz230s_map(address_map &map) +{ + map.unmap_value_high(); + +// map(0x0000, 0x0fff).rom(); - internal + map(0x1000, 0x1fff).w(FUNC(cz230s_state::pcm_w)); + map(0x2000, 0x3fff).ram().share("nvram"); + map(0x4000, 0x7fff).rw(m_pd, FUNC(upd933_device::read), FUNC(upd933_device::write)); + map(0x8000, 0xffff).rom().region("program", 0); +} + +/**************************************************************************/ +void cz230s_state::cz230s_pcm_map(address_map &map) +{ + map(0x0000, 0x7fff).rom(); +} + +/**************************************************************************/ +void cz230s_state::sz1_map(address_map &map) +{ + map.unmap_value_high(); + +// map(0x0000, 0x0fff).rom(); - internal + map(0x4000, 0x7fff).rom().region("program", 0); + map(0x8000, 0x9fff).mirror(0x2000).ram().share("nvram"); + map(0xc000, 0xcfff).w(FUNC(cz230s_state::led_w<0>)); + map(0xd000, 0xdfff).w(FUNC(cz230s_state::led_w<1>)); + map(0xe000, 0xffff).rw("cart", FUNC(casio_ram_cart_device::read), FUNC(casio_ram_cart_device::write)); +} + + +//************************************************************************** +// INPUT PORT DEFINITIONS +//************************************************************************** + +static INPUT_PORTS_START( cz230s ) + PORT_START("KC0") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C2") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C#2") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D2") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D#2") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("E2") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F2") + PORT_BIT(0x1c0, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Solo / Insert") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Portamento On/Off") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Bend Range / Check") + + PORT_START("KC1") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F#2") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G2") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G#2") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A2") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A#2") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("B2") + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Rhythm 1") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Rhythm 2") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Rhythm 3") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Rhythm 4") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Rhythm 5") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Preset 1") + + PORT_START("KC2") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C3") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C#3") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D3") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D#3") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("E3") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F3") + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Rhythm 6") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Rhythm 7") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Rhythm 8") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("Rhythm 9") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("Rhythm 10") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Preset 2") + + PORT_START("KC3") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F#3") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G3") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G#3") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A3") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A#3") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("B3") + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("Program") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Intro / Fill In") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Tempo Down") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Tempo Up") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Start / Stop / Record") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Synchro / Clear") + + PORT_START("KC4") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C4") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C#4") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D4") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D#4") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("E4") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F4") + PORT_BIT(0xfc0, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, rhythm_r<0>) + + PORT_START("KC5") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F#4") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G4") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G#4") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A4") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A#4") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("B4") + PORT_BIT(0xfc0, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, rhythm_r<6>) + + PORT_START("KC6") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C5") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C#5") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D5") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("D#5") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("E5") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F5") + PORT_BIT(0x3c0, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, rhythm_r<12>) + PORT_BIT(0xc00, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KC7") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("F#5") + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G5") + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("G#5") + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A5") + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("A#5") + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("B5") + PORT_BIT(0x7c0, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, mode_r) + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KC8") + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("C6") + PORT_BIT(0x03e, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("MT") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("MIDI Channel") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Portamento Speed") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Transpose") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Value Down / Save") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("Value Up / Load") + + PORT_START("KC9") + PORT_BIT(0x03f, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Tone 4") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Tone 5") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Tone 6") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Tone 7") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Tone 8") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Tone 9") + + PORT_START("KC10") + PORT_BIT(0x03f, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Tone 0") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Tone 1") + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Tone 2") + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Tone 3") + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Cancel") + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KC11") + PORT_BIT(0x03f, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Tune Down") + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Tune Up") + PORT_BIT(0x100, 0x000, IPT_OTHER ) PORT_TOGGLE PORT_NAME("MIDI Clock") + PORT_DIPSETTING(0x100, "External") + PORT_DIPSETTING(0x000, "Internal") + PORT_BIT(0x200, 0x000, IPT_OTHER ) PORT_TOGGLE PORT_NAME("MIDI") + PORT_DIPSETTING(0x200, DEF_STR(Off)) // this should be on by default + PORT_DIPSETTING(0x000, DEF_STR(On)) + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x800, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_TOGGLE PORT_NAME("Auto Power Off") + + PORT_START("RHYTHM") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (BD)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0001) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (SD)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0002) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (LT)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0004) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (HT)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0008) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (LB)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0010) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (HB)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0020) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (CH)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0040) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (Rim)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0080) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (OH)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0100) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (CB)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0200) + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (Ride)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0400) + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (Claps)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x0800) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (PD 1)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x1000) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (PD 2)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x2000) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (PD 3)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x4000) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm Sound (PD 4)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, rhythm_w, 0x8000) + + PORT_START("MODE") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Mode (Pattern Play)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, mode_w, 0x01) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Mode (Pattern Memory 4/4)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, mode_w, 0x02) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Mode (Pattern Memory 3/4)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, mode_w, 0x04) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Mode (Song Play)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, mode_w, 0x08) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Mode (Song Memory)") PORT_CHANGED_MEMBER(DEVICE_SELF, cz230s_state, mode_w, 0x10) + + PORT_START("PB") + PORT_BIT(0x0f, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, keys_w) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_READ_LINE_DEVICE_MEMBER("pd", upd933_device, rq_r) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_DEVICE_MEMBER("pd", upd933_device, cs_w) + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OUTPUT) // TODO: auto power off + + PORT_START("PC") + PORT_BIT(0x07, IP_ACTIVE_HIGH, IPT_UNUSED) // MIDI in/out/clock + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, cassette_r) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, cassette_w) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, cassette_motor_w) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, keys_mux_w) + + PORT_START("AN1") + PORT_BIT(0xff, 0x7f, IPT_PADDLE) PORT_NAME("Pitch Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) + + PORT_START("AN2") + PORT_CONFNAME(0xff, 0xff, "Battery Level") + PORT_CONFSETTING( 0x00, "Low") + PORT_CONFSETTING( 0xff, "Normal") + + PORT_START("AN3") + PORT_BIT(0xff, 0xff, IPT_POSITIONAL_H) PORT_NAME("PD Rhythm Volume") PORT_REVERSE PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + +INPUT_PORTS_END + +static INPUT_PORTS_START( sz1 ) + PORT_START("KC0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Rest") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Dot") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Triplet") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Tie") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Reverse / Save") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Forward / Load") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Play / Check") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Stop") + + PORT_START("KC1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("8th Note") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("16th Note") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("32nd Note") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN ) PORT_NAME("Tempo Down") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Real Time") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Manual") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Record") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Reset") + + PORT_START("KC2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Quarter Note") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Half Note") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Whole Note") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("Tempo Up") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Track 1") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Track 2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Track 3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Track 4") + + PORT_START("KC3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Copy") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("Insert") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Delete") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Metronome / Enter") + PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KC4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Repeat") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("MIDI") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_TOGGLE PORT_NAME("Auto Power Off") + PORT_BIT(0x20, 0x00, IPT_OTHER ) PORT_TOGGLE PORT_NAME("MIDI Clock") + PORT_DIPSETTING(0x20, "External") + PORT_DIPSETTING(0x00, "Internal") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_TOGGLE PORT_NAME("Touch Data") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Cartridge / MT") + + PORT_START("PA") + PORT_BIT(0x0f, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", mn1252_device, data_w) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", mn1252_device, ce_w) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", mn1252_device, std_w) + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, keys_row_r<7>) + + PORT_START("PB") + PORT_BIT(0x1f, IP_ACTIVE_LOW, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, keys_w) + PORT_BIT(0x60, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OUTPUT) // TODO: auto power off + + PORT_START("PC") + PORT_BIT(0x07, IP_ACTIVE_HIGH, IPT_UNUSED) // MIDI in/out/clock + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_CUSTOM_MEMBER(cz230s_state, cassette_r) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OUTPUT) PORT_WRITE_LINE_DEVICE_MEMBER("beep", beep_device, set_state) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, cassette_motor_w) + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OUTPUT) PORT_WRITE_LINE_MEMBER(cz230s_state, cassette_w) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Foot Switch") +INPUT_PORTS_END + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void cz230s_state::machine_start() +{ + m_lcd_seg.resolve(); + m_led.resolve(); + m_rhythm.resolve(); + m_mode.resolve(); + + m_rhythm = 1; + m_mode = 1; + + m_port_a = 0; + + save_item(NAME(m_port_a)); + save_item(NAME(m_key_sel)); + save_item(NAME(m_key_mux)); + save_item(NAME(m_midi_rx)); +} + +/**************************************************************************/ +void cz230s_state::machine_reset() +{ + m_key_sel = m_key_mux = 0; + m_midi_rx = 1; +} + + +/**************************************************************************/ +void cz230s_state::pcm_w(offs_t offset, u8 data) +{ + data = (BIT(offset, 0, 6) << 2) | BIT(offset, 8, 2); + m_pcm->write(offset >> 10, data); +} + +/**************************************************************************/ +template +void cz230s_state::led_w(u8 data) +{ + for (int i = 0; i < 8; i++) + m_led[Num][i] = BIT(data, i); +} + +/**************************************************************************/ +void cz230s_state::port_a_w(u8 data) +{ + m_lcdc->data_w(data & 0xf); + m_lcdc->std_w(BIT(data, 5)); + m_lcdc->ce_w(BIT(data, 6)); + + if (BIT(data, 7) && !BIT(m_port_a, 7)) + led_w<0>(~data & 0x3f); + + m_port_a = data; +} + +/**************************************************************************/ +u8 cz230s_state::keys_r() +{ + u8 data = 0x3f; + + if (m_key_sel < m_keys.size()) + { + const u16 input = m_keys[m_key_sel].read_safe(0xfff); + if (BIT(m_key_mux, 0)) + data &= (input & 0x3f); + if (BIT(m_key_mux, 1)) + data &= (input >> 6); + } + + return data; +} + +/**************************************************************************/ +template +CUSTOM_INPUT_MEMBER(cz230s_state::keys_row_r) +{ + u8 data = 0xff; + + for (int i = 0; i < 5; i++) + if (BIT(m_key_sel, i)) + data &= m_keys[i].read_safe(0xff); + + return BIT(data, Row); +} + +/**************************************************************************/ +template +u8 cz230s_state::keys_analog_r() +{ + return keys_row_r() ? 0xff : 0x00; +} + +/**************************************************************************/ +INPUT_CHANGED_MEMBER(cz230s_state::rhythm_w) +{ + if (!oldval && newval) + m_rhythm = param; +} + +/**************************************************************************/ +INPUT_CHANGED_MEMBER(cz230s_state::mode_w) +{ + if (!oldval && newval) + m_mode = param; +} + +/**************************************************************************/ +void cz230s_state::cassette_w(int state) +{ + m_cassette->output(state ? -1.0 : 1.0); +} + +/**************************************************************************/ +void cz230s_state::cassette_motor_w(int state) +{ + m_cassette->change_state(state ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); +} + +/**************************************************************************/ +CUSTOM_INPUT_MEMBER(cz230s_state::cassette_r) +{ + return m_cassette->input() > 0 ? 0 : 1; +} + +/**************************************************************************/ +void cz230s_state::render_w(int state) +{ + if (!state) + return; + + for (int digit = 0; digit < 6; digit++) + { + const u16 data = m_lcdc->output(digit); + for (int seg = 0; seg < 9; seg++) + m_lcd_seg[digit][seg] = BIT(data, seg); + } +} + + +//************************************************************************** +// MACHINE DEFINTIONS +//************************************************************************** + +void cz230s_state::config_base(machine_config &config, u16 screen_w, u16 screen_h, bool midi_thru) +{ + UPD7811(config, m_maincpu, 10_MHz_XTAL); + + CLOCK(config, "midi_clock", 2_MHz_XTAL).signal_handler().set(m_maincpu, FUNC(upd7810_device::sck_w)); + + midi_port_device &mdin(MIDI_PORT(config, "mdin", midiin_slot, "midiin")); + mdin.rxd_handler().set([this](int state) { m_midi_rx = state; }); + m_maincpu->rxd_func().set([this]() { return m_midi_rx; }); + + MIDI_PORT(config, "mdout", midiout_slot, "midiout"); + m_maincpu->txd_func().set("mdout", FUNC(midi_port_device::write_txd)); + + if (midi_thru) + { + MIDI_PORT(config, "mdthru", midiout_slot, "midiout"); + mdin.rxd_handler().append("mdthru", FUNC(midi_port_device::write_txd)); + } + + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + MN1252(config, m_lcdc); + + auto &screen = SCREEN(config, "screen", SCREEN_TYPE_SVG); + screen.set_refresh_hz(60); + screen.set_size(screen_w, screen_h); + screen.set_visarea_full(); + screen.screen_vblank().set(FUNC(cz230s_state::render_w)); + + SPEAKER(config, "speaker").front_center(); + + CASSETTE(config, m_cassette); + m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); + m_cassette->add_route(ALL_OUTPUTS, "speaker", 0.05); +} + +/**************************************************************************/ +void cz230s_state::cz230s(machine_config &config) +{ + config_base(config, 975, 205); + + m_maincpu->set_addrmap(AS_PROGRAM, &cz230s_state::cz230s_map); + m_maincpu->pa_in_cb().set(FUNC(cz230s_state::keys_r)); + m_maincpu->pa_out_cb().set(FUNC(cz230s_state::port_a_w)); + m_maincpu->pb_in_cb().set_ioport("PB"); + m_maincpu->pb_out_cb().set_ioport("PB"); + m_maincpu->pc_in_cb().set_ioport("PC"); + m_maincpu->pc_out_cb().set_ioport("PC"); + m_maincpu->an1_func().set_ioport("AN1"); + m_maincpu->an2_func().set_ioport("AN2"); + m_maincpu->an3_func().set_ioport("AN3"); + + UPD933(config, m_pd, 8.96_MHz_XTAL / 2); + m_pd->irq_cb().set_inputline(m_maincpu, UPD7810_INTF1); + m_pd->add_route(0, "speaker", 1.0); + + UPD934G(config, m_pcm, 1'280'000); + m_pcm->set_addrmap(0, &cz230s_state::cz230s_pcm_map); + m_pcm->add_route(ALL_OUTPUTS, "speaker", 0.5); + + config.set_default_layout(layout_cz230s); +} + +/**************************************************************************/ +void cz230s_state::sz1(machine_config &config) +{ + config_base(config, 938, 205, false); + + m_maincpu->set_addrmap(AS_PROGRAM, &cz230s_state::sz1_map); + m_maincpu->pa_in_cb().set_ioport("PA"); + m_maincpu->pa_out_cb().set_ioport("PA"); + m_maincpu->pb_out_cb().set_ioport("PB"); + m_maincpu->pc_in_cb().set_ioport("PC"); + m_maincpu->pc_out_cb().set_ioport("PC"); + m_maincpu->an0_func().set(FUNC(cz230s_state::keys_analog_r<0>)); + m_maincpu->an1_func().set(FUNC(cz230s_state::keys_analog_r<1>)); + m_maincpu->an2_func().set(FUNC(cz230s_state::keys_analog_r<2>)); + m_maincpu->an3_func().set(FUNC(cz230s_state::keys_analog_r<3>)); + m_maincpu->an4_func().set(FUNC(cz230s_state::keys_analog_r<4>)); + m_maincpu->an5_func().set(FUNC(cz230s_state::keys_analog_r<5>)); + m_maincpu->an6_func().set(FUNC(cz230s_state::keys_analog_r<6>)); + + CASIO_RA5(config, "cart"); + + BEEP(config, "beep", 2000).add_route(ALL_OUTPUTS, "speaker", 0.5); // TODO: verify freq + + config.set_default_layout(layout_sz1); +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START( cz230s ) + ROM_REGION(0x1000, "maincpu", 0) + ROM_LOAD("upd7811g-301.bin", 0x0000, 0x1000, CRC(506b008c) SHA1(2d91d817bd0fa4688591160e53cbc6e14acd7014)) + + ROM_REGION(0x8000, "program", 0) + ROM_LOAD("hn613256pda4.bin", 0x0000, 0x8000, CRC(f58758ec) SHA1(11e5c95e51e1c77c89682ea3db85b9457f8b6cf6)) + + ROM_REGION(0x8000, "pcm", 0) + ROM_LOAD("hn613256pct1.bin", 0x0000, 0x8000, CRC(97b9805b) SHA1(f3502a26b6a9bccb60bea11ae940619ab9960e05)) + + ROM_REGION(0x2000, "nvram", 0) + ROM_LOAD("init_ram.bin", 0x0000, 0x2000, CRC(eb756425) SHA1(3a21b45269a00d27d5943de50825edc329062c60)) + + ROM_REGION(0x7bb5, "screen", 0) + ROM_LOAD("cz230s.svg", 0x0000, 0x7bb5, CRC(e35cc3d3) SHA1(36cb369414f1e65843cd0ea318ad27f536b582be)) +ROM_END + +ROM_START( sz1 ) + ROM_REGION(0x1000, "maincpu", 0) + ROM_LOAD("upd7811g-120.bin", 0x0000, 0x1000, CRC(597ac04a) SHA1(96451a764296eaa22aaad3cba121226dcba865f4)) + + ROM_REGION(0x4000, "program", 0) + ROM_LOAD("program.bin", 0x0000, 0x4000, CRC(15f83fa5) SHA1(cb0d8d8390266f247dc7718b95bc658d1719d105)) + + ROM_REGION(0x6437, "screen", 0) + ROM_LOAD("sz1.svg", 0x0000, 0x6437, CRC(fd14625b) SHA1(069790868b382725d309fcab0148147f76ff82cc)) +ROM_END + +} // anonymous namespace + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +SYST( 1985, cz230s, 0, 0, cz230s, cz230s, cz230s_state, empty_init, "Casio", "CZ-230S", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) +SYST( 1985, sz1, 0, 0, sz1, sz1, cz230s_state, empty_init, "Casio", "SZ-1", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/casio/ra3.cpp b/src/mame/casio/ra3.cpp index a56da78426b..6d5a95b22e8 100644 --- a/src/mame/casio/ra3.cpp +++ b/src/mame/casio/ra3.cpp @@ -13,6 +13,7 @@ // device type definition DEFINE_DEVICE_TYPE(CASIO_RA3, casio_ra3_device, "casio_ra3", "Casio RA-3 RAM cartridge") +DEFINE_DEVICE_TYPE(CASIO_RA5, casio_ra5_device, "casio_ra5", "Casio RA-5 RAM cartridge") DEFINE_DEVICE_TYPE(CASIO_RA6, casio_ra6_device, "casio_ra6", "Casio RA-6 RAM cartridge") /**************************************************************************/ @@ -34,6 +35,12 @@ casio_ra3_device::casio_ra3_device(const machine_config &mconfig, const char *ta { } +/**************************************************************************/ +casio_ra5_device::casio_ra5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : casio_ram_cart_device(mconfig, CASIO_RA5, tag, owner, clock, 0x2000) +{ +} + /**************************************************************************/ casio_ra6_device::casio_ra6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : casio_ram_cart_device(mconfig, CASIO_RA6, tag, owner, clock, 0x4000) diff --git a/src/mame/casio/ra3.h b/src/mame/casio/ra3.h index e2eb6269dd3..b9ba87e8363 100644 --- a/src/mame/casio/ra3.h +++ b/src/mame/casio/ra3.h @@ -47,6 +47,12 @@ public: casio_ra3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); }; +class casio_ra5_device : public casio_ram_cart_device +{ +public: + casio_ra5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); +}; + class casio_ra6_device : public casio_ram_cart_device { public: @@ -55,6 +61,7 @@ public: // device type definition DECLARE_DEVICE_TYPE(CASIO_RA3, casio_ra3_device) +DECLARE_DEVICE_TYPE(CASIO_RA5, casio_ra5_device) DECLARE_DEVICE_TYPE(CASIO_RA6, casio_ra6_device) #endif // MAME_CASIO_RA3_H diff --git a/src/mame/layout/cz230s.lay b/src/mame/layout/cz230s.lay new file mode 100644 index 00000000000..dcb71e735e1 --- /dev/null +++ b/src/mame/layout/cz230s.lay @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/sz1.lay b/src/mame/layout/sz1.lay new file mode 100644 index 00000000000..fbb7d9f2c3e --- /dev/null +++ b/src/mame/layout/sz1.lay @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 6ad39eb9e30..710fc28a0a1 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -15916,6 +15916,10 @@ mz1 // 1986 Casio (unreleased) @source:casio/cz101.cpp cz101 // 1984 Casio +@source:casio/cz230s.cpp +cz230s // 1985 Casio +sz1 // 1985 Casio + @source:casio/fp200.cpp fp200 //