From 3b6f5c69f65da515fb13e3069de7aab29ded02bf Mon Sep 17 00:00:00 2001 From: arbee Date: Tue, 27 Apr 2021 07:42:37 -0400 Subject: New NOT WORKING machines ======================== Yamaha PSR-60 PortaSound [R. Belmont, JKN0, d-tech] --- scripts/target/mame/mess.lua | 1 + src/mame/drivers/ympsr60.cpp | 164 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 src/mame/drivers/ympsr60.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 733151e527f..419eb928c6c 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -4381,6 +4381,7 @@ files { MAME_DIR .. "src/mame/drivers/ymmu50.cpp", MAME_DIR .. "src/mame/drivers/ymmu80.cpp", MAME_DIR .. "src/mame/drivers/ymmu100.cpp", + MAME_DIR .. "src/mame/drivers/ympsr60.cpp", MAME_DIR .. "src/mame/drivers/ympsr340.cpp", MAME_DIR .. "src/mame/drivers/ymtx81z.cpp", MAME_DIR .. "src/mame/drivers/ymvl70.cpp", diff --git a/src/mame/drivers/ympsr60.cpp b/src/mame/drivers/ympsr60.cpp new file mode 100644 index 00000000000..7ae7c7f5e83 --- /dev/null +++ b/src/mame/drivers/ympsr60.cpp @@ -0,0 +1,164 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/* + Yamaha PSR-60/PSR-70 PortaSound keyboards + Preliminary driver by R. Belmont, major thanks to reverse-engineering work by JKN0 + + Documentation: https://github.com/JKN0/PSR70-reverse + More documentation: https://retroandreverse.blogspot.com/2021/01/reversing-psr-70-hardware.html + https://retroandreverse.blogspot.com/2021/01/reversing-psr-70-firmware.html + https://retroandreverse.blogspot.com/2021/01/digging-into-ym3806.html + + Service manual: https://elektrotanya.com/yamaha_psr-70_sm.pdf/download.html + + CPU: Z80 @ 6 MHz + Sound: YM3806 "OPQ" FM @ 3.58 MHz + YM2154 "RYP" sample playback chip for drums + Panel and keyboard I/O: 82C55A PPI and Yamaha IG14330 "DRVIF" + MIDI I/O: HD6350 ACIA, baud rate clock is 500 kHz + + Z80 IRQ is a wire-OR of IRQs from the OPQ, RYP4, ACIA, and DRVIF + + PPI ports: + PA0-PA5: keyboard matrix readback (PA5-PA0 for most matrix selects, where PA5 is the lowest key and PA0 is the highest) + PA6: single-use matrix readback for C1 (when PC1 is active) + PA7: cassette input + Keyboard matrix select writes: + PC1: C1 - F#1 + PC0: G1 - C2 + PB7: C#2 - F#2 + PB6: G2 - C3 + PB5: C#3 - F#3 + PB4: G3 - C4 + PB3: C#4 - F#4 + PB2: G4 - C5 + PB1: C#5 - F#5 + PB0: G5 - C6 + PC3: unused + PC4: ROM2 bank (goes to A14) + PC5: cassette output + PC6: MUTE + PC7: to "RS2" signal, IC (reset, "initial clear" in Yamaha-speak) pin on T9500 +*/ + +#include "emu.h" + +#include "cpu/z80/z80.h" +#include "machine/i8255.h" +#include "machine/6850acia.h" +#include "machine/clock.h" +#include "bus/midi/midi.h" + +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +class psr60_state : public driver_device +{ +public: + psr60_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_ppi(*this, "ppi"), + m_acia(*this, "acia"), + m_rom2bank(*this, "rom2bank") + { } + + void psr60(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + required_device m_maincpu; + required_device m_ppi; + required_device m_acia; + required_memory_bank m_rom2bank; + + void psr60_map(address_map &map); + void psr60_io_map(address_map &map); + + void ppi_pc_w(u8 data); + void recalc_irqs(); + + int m_acia_irq; + + 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(); } +}; + +void psr60_state::psr60_map(address_map &map) +{ + map(0x0000, 0x7fff).rom().region("rom1", 0); + map(0x8000, 0xbfff).bankr("rom2bank"); + // c000-c0ff: YM3806 "OPQ" FM chip + map(0xe000, 0xffff).ram(); // work RAM +} + +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)); + // 30-40: IG14330 "DRVIF" (front panel LED driver/multiplexer?) + // 80-FF: YM2154 "RYP4" (drum sample playback) +} + +void psr60_state::ppi_pc_w(u8 data) +{ + m_rom2bank->set_entry(BIT(data, 4)); +} + +void psr60_state::recalc_irqs() +{ + int irq_state = m_acia_irq; // (| OPQ, RYP4, and DRVIF interrupts eventually) + m_maincpu->set_input_line(0, irq_state); +} + +void psr60_state::machine_start() +{ + m_rom2bank->configure_entries(0, 2, memregion("rom2")->base(), 0x4000); + m_rom2bank->set_entry(0); +} + +void psr60_state::machine_reset() +{ +} + +static INPUT_PORTS_START(psr60) +INPUT_PORTS_END + +void psr60_state::psr60(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 6_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &psr60_state::psr60_map); + m_maincpu->set_addrmap(AS_IO, &psr60_state::psr60_io_map); + + I8255A(config, m_ppi, 6_MHz_XTAL); + 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) + m_acia->txd_handler().set("mdout", FUNC(midi_port_device::write_txd)); + m_acia->irq_handler().set(FUNC(psr60_state::acia_irq_w)); + + MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); + + MIDI_PORT(config, "mdout", midiout_slot, "midiout"); + + 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)); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); +} + +ROM_START( psr60 ) + ROM_REGION(0x8000, "rom1", 0) + ROM_LOAD("yamaha_psr60_pgm_ic109.bin", 0x000000, 0x008000, CRC(95604916) SHA1(811fb88fc968c58234600eb9fbf1f64e411754cd)) + + ROM_REGION(0x8000, "rom2", 0) + ROM_LOAD("yamaha_psr60_pgm_ic110.bin", 0x000000, 0x008000, CRC(39db8c74) SHA1(7750104d1e5df3357aa553ac58768dbc34051cd8)) +ROM_END + +CONS(1985, psr60, 0, 0, psr60, psr60, psr60_state, empty_init, "Yamaha", "PSR-60 PortaSound", MACHINE_NOT_WORKING) -- cgit v1.2.3