mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
New NOT WORKING machines
======================== Yamaha PSR-60 PortaSound [R. Belmont, JKN0, d-tech]
This commit is contained in:
parent
a20cc89e13
commit
3b6f5c69f6
@ -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",
|
||||
|
164
src/mame/drivers/ympsr60.cpp
Normal file
164
src/mame/drivers/ympsr60.cpp
Normal file
@ -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<z80_device> m_maincpu;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<acia6850_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)
|
Loading…
Reference in New Issue
Block a user