From 342ac0190c10ae09aee4c95f3b4f5af7d9159900 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Tue, 25 May 2021 20:27:39 -0700 Subject: psr60: Add internal layout. Hook up LEDs and buttons. --- src/mame/drivers/ympsr60.cpp | 203 ++++++++- src/mame/layout/psr60.lay | 1009 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1209 insertions(+), 3 deletions(-) create mode 100644 src/mame/layout/psr60.lay diff --git a/src/mame/drivers/ympsr60.cpp b/src/mame/drivers/ympsr60.cpp index f5c57f639e1..cf56e466270 100644 --- a/src/mame/drivers/ympsr60.cpp +++ b/src/mame/drivers/ympsr60.cpp @@ -53,6 +53,8 @@ #include "screen.h" #include "speaker.h" +#include "psr60.lh" + class psr60_state : public driver_device { public: @@ -62,7 +64,9 @@ public: m_ym3533(*this, "ym3533"), m_ppi(*this, "ppi"), m_acia(*this, "acia"), - m_rom2bank(*this, "rom2bank") + m_rom2bank(*this, "rom2bank"), + m_keyboard(*this, "P1_%u", 0), + m_drvif(*this, "DRVIF_%u", 0) { } void psr60(machine_config &config); @@ -77,20 +81,32 @@ private: required_device m_ppi; required_device m_acia; required_memory_bank m_rom2bank; + required_ioport_array<10> m_keyboard; + required_ioport_array<21> m_drvif; void psr60_map(address_map &map); void psr60_io_map(address_map &map); + u8 ppi_pa_r(); + void ppi_pb_w(u8 data); void ppi_pc_w(u8 data); void recalc_irqs(); - int m_acia_irq, m_ym_irq; + int m_acia_irq, m_ym_irq, m_drvif_irq; + u16 m_keyboard_select; + u8 m_drvif_data[2]; + u8 m_drvif_select; WRITE_LINE_MEMBER(write_acia_clock) { m_acia->write_txc(state); m_acia->write_rxc(state); } WRITE_LINE_MEMBER(acia_irq_w) { m_acia_irq = state; recalc_irqs(); } WRITE_LINE_MEMBER(ym_irq_w) { m_ym_irq = state; recalc_irqs(); } + u8 drvif_r(offs_t offset); + void drvif_w(offs_t offset, u8 data); + +public: + INPUT_CHANGED_MEMBER(drvif_changed); }; void psr60_state::psr60_map(address_map &map) @@ -106,18 +122,78 @@ void psr60_state::psr60_io_map(address_map &map) map.global_mask(0xff); // top 8 bits of the address are ignored by this hardware for I/O access map(0x10, 0x11).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); map(0x20, 0x23).rw(m_ppi, FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0x30, 0x3f).rw(FUNC(psr60_state::drvif_r), FUNC(psr60_state::drvif_w)); // 30-40: IG14330 "DRVIF" (front panel LED driver/multiplexer?) // 80-FF: YM2154 "RYP4" (drum sample playback) } +u8 psr60_state::ppi_pa_r() +{ + if (BIT(m_keyboard_select, 0)) return m_keyboard[0]->read(); + if (BIT(m_keyboard_select, 1)) return m_keyboard[1]->read(); + if (BIT(m_keyboard_select, 2)) return m_keyboard[2]->read(); + if (BIT(m_keyboard_select, 3)) return m_keyboard[3]->read(); + if (BIT(m_keyboard_select, 4)) return m_keyboard[4]->read(); + if (BIT(m_keyboard_select, 5)) return m_keyboard[5]->read(); + if (BIT(m_keyboard_select, 6)) return m_keyboard[6]->read(); + if (BIT(m_keyboard_select, 7)) return m_keyboard[7]->read(); + if (BIT(m_keyboard_select, 8)) return m_keyboard[8]->read(); + if (BIT(m_keyboard_select, 9)) return m_keyboard[9]->read(); + return 0; +} + +void psr60_state::ppi_pb_w(u8 data) +{ + m_keyboard_select = (m_keyboard_select & ~0xff) | data; +} + void psr60_state::ppi_pc_w(u8 data) { m_rom2bank->set_entry(BIT(data, 4)); + m_keyboard_select = (m_keyboard_select & ~0x300) | ((data & 3) << 8); +} + +u8 psr60_state::drvif_r(offs_t offset) +{ + if (offset == 0) + return (m_drvif_irq << 7) | 0x40; + else if (offset <= 2) + { + m_drvif_irq = 0; + recalc_irqs(); + return m_drvif_data[offset - 1]; + } + else + return 0; +} +void psr60_state::drvif_w(offs_t offset, u8 data) +{ + if (offset == 1) + m_drvif_select = data & 0x1f; + else if (offset == 2) + { + for (int bit = 0; bit < 4; bit++) + { + char name[20]; + sprintf(name, "DRVIF_%d_DP%d", m_drvif_select, bit + 1); + output().set_value(name, BIT(data, 3 - bit)); + } + } + else + printf("DRVIF: %02X = %02X\n", offset, data); +} + +INPUT_CHANGED_MEMBER(psr60_state::drvif_changed) +{ + m_drvif_irq = 1; + m_drvif_data[0] = param; + m_drvif_data[1] = m_drvif[param]->read(); + recalc_irqs(); } void psr60_state::recalc_irqs() { - int irq_state = m_acia_irq | m_ym_irq; // (|| RYP4 and DRVIF interrupts eventually) + int irq_state = m_acia_irq | m_ym_irq | m_drvif_irq; // (|| RYP4 interrupts eventually) m_maincpu->set_input_line(0, irq_state); } @@ -133,6 +209,123 @@ void psr60_state::machine_reset() } static INPUT_PORTS_START(psr60) + PORT_START("P1_9") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("Octave 0 C") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("Octave 0 C#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_NAME("Octave 0 D") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_NAME("Octave 0 D#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_NAME("Octave 0 E") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("Octave 0 F") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("Octave 0 F#") + + PORT_START("P1_8") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_NAME("Octave 0 G") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_NAME("Octave 0 G#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("Octave 0 A") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_NAME("Octave 0 A#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_NAME("Octave 0 B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_NAME("Octave 1 C") + + PORT_START("P1_7") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME("Octave 1 C#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Octave 1 D") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME("Octave 1 D#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_NAME("Octave 1 E") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_NAME("Octave 1 F") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Octave 1 F#") + + PORT_START("P1_6") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("Octave 1 G") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("Octave 1 G#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("Octave 1 A") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("Octave 1 A#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 1 B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 2 C") + + PORT_START("P1_5") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME("Octave 2 C#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Octave 2 D") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME("Octave 2 D#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_NAME("Octave 2 E") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_NAME("Octave 2 F") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Octave 2 F#") + + PORT_START("P1_4") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("Octave 2 G") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("Octave 2 G#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("Octave 2 A") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("Octave 2 A#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 2 B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 3 C") + + PORT_START("P1_3") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_NAME("Octave 3 C#") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Octave 3 D") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_NAME("Octave 3 D#") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_NAME("Octave 3 E") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_NAME("Octave 3 F") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Octave 3 F#") + + PORT_START("P1_2") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_NAME("Octave 3 G") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("Octave 3 G#") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("Octave 3 A") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_NAME("Octave 3 A#") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 3 B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_NAME("Octave 4 C") + + PORT_START("P1_1") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x7f, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("P1_0") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // cassette input + PORT_BIT( 0x7f, IP_ACTIVE_HIGH, IPT_UNUSED ) + +#define DRVIF_PORT(num, sw1, sw2, sw3, sw4) \ + PORT_START("DRVIF_" #num) \ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(sw1) PORT_CHANGED_MEMBER(DEVICE_SELF, psr60_state, drvif_changed, num) \ + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(sw2) PORT_CHANGED_MEMBER(DEVICE_SELF, psr60_state, drvif_changed, num) \ + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(sw3) PORT_CHANGED_MEMBER(DEVICE_SELF, psr60_state, drvif_changed, num) \ + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(sw4) PORT_CHANGED_MEMBER(DEVICE_SELF, psr60_state, drvif_changed, num) + + DRVIF_PORT( 0, "Pause", "Unused1.2", "Unused1.3", "Unused1.4") + DRVIF_PORT( 1, "Pitch Up", "Pitch Down", "Transposer Up", "Transposer Down") + DRVIF_PORT( 2, "Memory", "Fingered", "Single Finger", "Off") + DRVIF_PORT( 3, "Fill In 3", "Fill In 2", "Fill In 1", "Keyboard Percussion") + DRVIF_PORT( 4, "On", "Variation", "Hand Clap 2", "Hand Clap 1") + DRVIF_PORT( 5, "Pops", "Disco", "Reggae", "Big Band") + DRVIF_PORT( 6, "March/Polka", "Samba", "Salsa", "Rock'N'Roll") + DRVIF_PORT( 7, "Intro/Ending", "Start", "Unused8.3", "Stop") + DRVIF_PORT( 8, "MIDI Mode", "Unused9.2", "Unused9.3", "Unused9.4") + DRVIF_PORT( 9, "Brass 1", "Strings", "Pipe Organ", "Jazz Organ") + DRVIF_PORT(10, "Calliope", "Clarinet", "Brass & Chimes", "Brass 2") + DRVIF_PORT(11, "Unused12.1", "Unused12.2", "Unused12.3", "Unused12.4") + DRVIF_PORT(12, "Unused13.1", "Unused13.2", "Unused13.3", "Unused13.4") + DRVIF_PORT(13, "On", "To Lower", "Trio", "Duet") + DRVIF_PORT(14, "Sustain", "Stereo Symphonic", "Sustain 2", "Sustain 1") + DRVIF_PORT(15, "Trumpet", "Violin", "Piccolo", "Jazz Flute") + DRVIF_PORT(16, "Oboe", "Saxophone", "Horn", "Trombone") + DRVIF_PORT(17, "Pop Synth", "Percussion 2", "Percussion 1", "Electric Guitar") + DRVIF_PORT(18, "Bass", "SlapSynth", "Funk Synth/Blues Synth", "Off") + DRVIF_PORT(19, "Save", "Solo Record", "Orchestra Record", "Chord/Bass Record") + DRVIF_PORT(20, "Load", "Solo Play Back", "Orchestra Play Back", "Chord/Bass Play Back") + DRVIF_PORT(21, "Unused21.1", "Unused21.2", "Unused21.3", "Unused21.4") INPUT_PORTS_END void psr60_state::psr60(machine_config &config) @@ -143,6 +336,8 @@ void psr60_state::psr60(machine_config &config) m_maincpu->set_addrmap(AS_IO, &psr60_state::psr60_io_map); I8255A(config, m_ppi, 6_MHz_XTAL); + m_ppi->in_pa_callback().set(FUNC(psr60_state::ppi_pa_r)); + m_ppi->out_pb_callback().set(FUNC(psr60_state::ppi_pb_w)); m_ppi->out_pc_callback().set(FUNC(psr60_state::ppi_pc_w)); ACIA6850(config, m_acia, 500_kHz_XTAL); // actually an HD6350, differences unknown (if any) @@ -156,6 +351,8 @@ void psr60_state::psr60(machine_config &config) clock_device &acia_clock(CLOCK(config, "acia_clock", 500_kHz_XTAL)); // 31250 * 16 = 500,000 acia_clock.signal_handler().set(FUNC(psr60_state::write_acia_clock)); + config.set_default_layout(layout_psr60); + SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); diff --git a/src/mame/layout/psr60.lay b/src/mame/layout/psr60.lay new file mode 100644 index 00000000000..63e1b17822e --- /dev/null +++ b/src/mame/layout/psr60.lay @@ -0,0 +1,1009 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3