mirror of
https://github.com/holub/mame
synced 2025-06-07 13:23:50 +03:00
ymfm: Improve OPQ behavior for timers and register access. Add YM3533 device and use that instead of YM3806.
This commit is contained in:
parent
48bde2d647
commit
9e1ed0acf4
20
3rdparty/ymfm/src/ymfm_opq.cpp
vendored
20
3rdparty/ymfm/src/ymfm_opq.cpp
vendored
@ -31,6 +31,8 @@
|
|||||||
#include "ymfm_opq.h"
|
#include "ymfm_opq.h"
|
||||||
#include "ymfm_fm.ipp"
|
#include "ymfm_fm.ipp"
|
||||||
|
|
||||||
|
#define TEMPORARY_DEBUG_PRINTS (1)
|
||||||
|
|
||||||
//
|
//
|
||||||
// OPQ (aka YM3806/YM3533)
|
// 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
|
// detune/multiple share a register based on the MSB of what is written
|
||||||
// remap the multiple values to 100-11F
|
// remap the multiple values to 100-11F
|
||||||
if ((index & 0xe0) == 0x40 && bitfield(data, 7))
|
if ((index & 0xe0) == 0x40 && bitfield(data, 7) != 0)
|
||||||
index += 0xc0;
|
index += 0xc0;
|
||||||
|
|
||||||
|
m_regdata[index] = data;
|
||||||
|
|
||||||
// handle writes to the key on index
|
// handle writes to the key on index
|
||||||
if (index == 0x05)
|
if (index == 0x05)
|
||||||
{
|
{
|
||||||
@ -425,16 +429,17 @@ uint8_t ym3806::read_status()
|
|||||||
uint8_t ym3806::read(uint32_t offset)
|
uint8_t ym3806::read(uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t result = 0xff;
|
uint8_t result = 0xff;
|
||||||
switch (offset & 1)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0: // data port (unused)
|
case 0: // status port
|
||||||
debug::log_unexpected_read_write("Unexpected read from YM3806 offset %d\n", offset & 3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // status port, YM2203 compatible
|
|
||||||
result = read_status();
|
result = read_status();
|
||||||
break;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,6 +451,7 @@ uint8_t ym3806::read(uint32_t offset)
|
|||||||
|
|
||||||
void ym3806::write(uint32_t offset, uint8_t data)
|
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
|
// write the FM register
|
||||||
m_fm.write(offset, data);
|
m_fm.write(offset, data);
|
||||||
}
|
}
|
||||||
|
21
3rdparty/ymfm/src/ymfm_opq.h
vendored
21
3rdparty/ymfm/src/ymfm_opq.h
vendored
@ -176,15 +176,15 @@ public:
|
|||||||
|
|
||||||
// system-wide registers
|
// system-wide registers
|
||||||
uint32_t timer_a_value() const { return 0; }
|
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 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 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 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 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); }
|
uint32_t lfo_rate() const { return byte(0x04, 0, 3); }
|
||||||
|
|
||||||
// per-channel registers
|
// per-channel registers
|
||||||
@ -279,6 +279,17 @@ protected:
|
|||||||
fm_engine m_fm; // core FM engine
|
fm_engine m_fm; // core FM engine
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> ym3533
|
||||||
|
|
||||||
|
class ym3533 : public ym3806
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
ym3533(ymfm_interface &intf) :
|
||||||
|
ym3806(intf) { }
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
#include "ymopq.h"
|
#include "ymopq.h"
|
||||||
|
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(YM3806, ym3806_device, "ym3806", "YM3806 OPN")
|
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
// YM3806 DEVICE
|
// YM3806 DEVICE
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
|
|
||||||
|
DEFINE_DEVICE_TYPE(YM3806, ym3806_device, "ym3806", "YM3806 OPQ")
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// ym3806_device - constructor
|
// 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)
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// license:BSD-3-Clause
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles
|
||||||
|
|
||||||
#ifndef MAME_SOUND_YM3806_H
|
#ifndef MAME_SOUND_YMOPQ_H
|
||||||
#define MAME_SOUND_YM3806_H
|
#define MAME_SOUND_YMOPQ_H
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -21,4 +21,16 @@ public:
|
|||||||
ym3806_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
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
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
Service manual: https://elektrotanya.com/yamaha_psr-70_sm.pdf/download.html
|
Service manual: https://elektrotanya.com/yamaha_psr-70_sm.pdf/download.html
|
||||||
|
|
||||||
CPU: Z80 @ 6 MHz
|
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"
|
Panel and keyboard I/O: 82C55A PPI and Yamaha IG14330 "DRVIF"
|
||||||
MIDI I/O: HD6350 ACIA, baud rate clock is 500 kHz
|
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) :
|
psr60_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||||
driver_device(mconfig, type, tag),
|
driver_device(mconfig, type, tag),
|
||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_ym3806(*this, "ym3806"),
|
m_ym3533(*this, "ym3533"),
|
||||||
m_ppi(*this, "ppi"),
|
m_ppi(*this, "ppi"),
|
||||||
m_acia(*this, "acia"),
|
m_acia(*this, "acia"),
|
||||||
m_rom2bank(*this, "rom2bank")
|
m_rom2bank(*this, "rom2bank")
|
||||||
@ -73,7 +73,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
required_device<z80_device> m_maincpu;
|
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<i8255_device> m_ppi;
|
||||||
required_device<acia6850_device> m_acia;
|
required_device<acia6850_device> m_acia;
|
||||||
required_memory_bank m_rom2bank;
|
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(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(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(0x0000, 0x7fff).rom().region("rom1", 0);
|
||||||
map(0x8000, 0xbfff).bankr("rom2bank");
|
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
|
map(0xe000, 0xffff).ram(); // work RAM
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +159,10 @@ void psr60_state::psr60(machine_config &config)
|
|||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
|
|
||||||
YM3806(config, m_ym3806, 3.579545_MHz_XTAL);
|
YM3533(config, m_ym3533, 3.579545_MHz_XTAL);
|
||||||
m_ym3806->irq_handler().set(FUNC(psr60_state::ym_irq_w));
|
m_ym3533->irq_handler().set(FUNC(psr60_state::ym_irq_w));
|
||||||
m_ym3806->add_route(0, "lspeaker", 1.0);
|
m_ym3533->add_route(0, "lspeaker", 1.0);
|
||||||
m_ym3806->add_route(1, "rspeaker", 1.0);
|
m_ym3533->add_route(1, "rspeaker", 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ROM_START( psr60 )
|
ROM_START( psr60 )
|
||||||
|
Loading…
Reference in New Issue
Block a user