ymfm: Improve OPQ behavior for timers and register access. Add YM3533 device and use that instead of YM3806.

This commit is contained in:
Aaron Giles 2021-05-23 18:13:07 -07:00
parent 48bde2d647
commit 9e1ed0acf4
5 changed files with 72 additions and 27 deletions

View File

@ -31,6 +31,8 @@
#include "ymfm_opq.h"
#include "ymfm_fm.ipp"
#define TEMPORARY_DEBUG_PRINTS (1)
//
// OPQ (aka YM3806/YM3533)
//
@ -126,9 +128,11 @@ bool opq_registers::write(uint16_t index, uint8_t data, uint32_t &channel, uint3
// detune/multiple share a register based on the MSB of what is written
// remap the multiple values to 100-11F
if ((index & 0xe0) == 0x40 && bitfield(data, 7))
if ((index & 0xe0) == 0x40 && bitfield(data, 7) != 0)
index += 0xc0;
m_regdata[index] = data;
// handle writes to the key on index
if (index == 0x05)
{
@ -425,16 +429,17 @@ uint8_t ym3806::read_status()
uint8_t ym3806::read(uint32_t offset)
{
uint8_t result = 0xff;
switch (offset & 1)
switch (offset)
{
case 0: // data port (unused)
debug::log_unexpected_read_write("Unexpected read from YM3806 offset %d\n", offset & 3);
break;
case 1: // status port, YM2203 compatible
case 0: // status port
result = read_status();
break;
default: // unknown
debug::log_unexpected_read_write("Unexpected read from YM3806 offset %02X\n", offset);
break;
}
if (TEMPORARY_DEBUG_PRINTS && offset != 0) printf("Read %02X = %02X\n", offset, result);
return result;
}
@ -446,6 +451,7 @@ uint8_t ym3806::read(uint32_t offset)
void ym3806::write(uint32_t offset, uint8_t data)
{
if (TEMPORARY_DEBUG_PRINTS && (offset != 3 || data != 0x71)) printf("Write %02X = %02X\n", offset, data);
// write the FM register
m_fm.write(offset, data);
}

View File

@ -176,15 +176,15 @@ public:
// system-wide registers
uint32_t timer_a_value() const { return 0; }
uint32_t timer_b_value() const { return byte(0x03, 0, 8); }
uint32_t timer_b_value() const { return byte(0x03, 2, 6) | 0xc0; } // ???
uint32_t csm() const { return 0; }
uint32_t reset_timer_b() const { return byte(0x14, 5, 1); }
uint32_t reset_timer_b() const { return byte(0x03, 0, 1); } // ???
uint32_t reset_timer_a() const { return 0; }
uint32_t enable_timer_b() const { return byte(0x14, 3, 1); }
uint32_t enable_timer_b() const { return byte(0x03, 0, 1); } // ???
uint32_t enable_timer_a() const { return 0; }
uint32_t load_timer_b() const { return byte(0x14, 1, 1); }
uint32_t load_timer_b() const { return byte(0x03, 0, 1); } // ???
uint32_t load_timer_a() const { return 0; }
uint32_t lfo_enable() const { return byte(0x04, 4, 1) ^ 1; }
uint32_t lfo_enable() const { return byte(0x04, 3, 1) ^ 1; }
uint32_t lfo_rate() const { return byte(0x04, 0, 3); }
// per-channel registers
@ -279,6 +279,17 @@ protected:
fm_engine m_fm; // core FM engine
};
// ======================> ym3533
class ym3533 : public ym3806
{
public:
// constructor
ym3533(ymfm_interface &intf) :
ym3806(intf) { }
};
}

View File

@ -5,13 +5,12 @@
#include "ymopq.h"
DEFINE_DEVICE_TYPE(YM3806, ym3806_device, "ym3806", "YM3806 OPN")
//*********************************************************
// YM3806 DEVICE
//*********************************************************
DEFINE_DEVICE_TYPE(YM3806, ym3806_device, "ym3806", "YM3806 OPQ")
//-------------------------------------------------
// ym3806_device - constructor
//-------------------------------------------------
@ -20,3 +19,20 @@ ym3806_device::ym3806_device(const machine_config &mconfig, const char *tag, dev
ymfm_device_base<ymfm::ym3806>(mconfig, tag, owner, clock, YM3806)
{
}
//*********************************************************
// YM3533 DEVICE
//*********************************************************
DEFINE_DEVICE_TYPE(YM3533, ym3533_device, "ym3533", "YM3533 OPQ")
//-------------------------------------------------
// ym3533_device - constructor
//-------------------------------------------------
ym3533_device::ym3533_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
ymfm_device_base<ymfm::ym3533>(mconfig, tag, owner, clock, YM3533)
{
}

View File

@ -1,8 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
#ifndef MAME_SOUND_YM3806_H
#define MAME_SOUND_YM3806_H
#ifndef MAME_SOUND_YMOPQ_H
#define MAME_SOUND_YMOPQ_H
#pragma once
@ -21,4 +21,16 @@ public:
ym3806_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
#endif // MAME_SOUND_YM3806_H
// ======================> ym3533_device
DECLARE_DEVICE_TYPE(YM3533, ym3533_device);
class ym3533_device : public ymfm_device_base<ymfm::ym3533>
{
public:
// constructor
ym3533_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
#endif // MAME_SOUND_YMOPQ_H

View File

@ -12,7 +12,7 @@
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
Sound: YM3533 "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
@ -59,7 +59,7 @@ public:
psr60_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ym3806(*this, "ym3806"),
m_ym3533(*this, "ym3533"),
m_ppi(*this, "ppi"),
m_acia(*this, "acia"),
m_rom2bank(*this, "rom2bank")
@ -73,7 +73,7 @@ protected:
private:
required_device<z80_device> m_maincpu;
required_device<ym3806_device> m_ym3806;
required_device<ym3533_device> m_ym3533;
required_device<i8255_device> m_ppi;
required_device<acia6850_device> m_acia;
required_memory_bank m_rom2bank;
@ -89,7 +89,7 @@ private:
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(); printf("YM IRQ %d\n", state); }
WRITE_LINE_MEMBER(ym_irq_w) { m_ym_irq = state; recalc_irqs(); }
};
@ -97,7 +97,7 @@ void psr60_state::psr60_map(address_map &map)
{
map(0x0000, 0x7fff).rom().region("rom1", 0);
map(0x8000, 0xbfff).bankr("rom2bank");
map(0xc000, 0xc0ff).rw(m_ym3806, FUNC(ym3806_device::read), FUNC(ym3806_device::write));
map(0xc000, 0xc0ff).rw(m_ym3533, FUNC(ym3533_device::read), FUNC(ym3533_device::write));
map(0xe000, 0xffff).ram(); // work RAM
}
@ -159,10 +159,10 @@ void psr60_state::psr60(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
YM3806(config, m_ym3806, 3.579545_MHz_XTAL);
m_ym3806->irq_handler().set(FUNC(psr60_state::ym_irq_w));
m_ym3806->add_route(0, "lspeaker", 1.0);
m_ym3806->add_route(1, "rspeaker", 1.0);
YM3533(config, m_ym3533, 3.579545_MHz_XTAL);
m_ym3533->irq_handler().set(FUNC(psr60_state::ym_irq_w));
m_ym3533->add_route(0, "lspeaker", 1.0);
m_ym3533->add_route(1, "rspeaker", 1.0);
}
ROM_START( psr60 )