ym2151: Add YM2164 variant and emulate some known differences

This commit is contained in:
AJR 2020-03-04 10:07:56 -05:00
parent 245b2106b7
commit 81cccebb1f
5 changed files with 77 additions and 9 deletions

View File

@ -4,9 +4,6 @@
Yamaha SFG01/SFG05 emulation
TODO:
- Use a real YM2164 implementation for SFG05
**************************************************************************/
#include "emu.h"
@ -71,6 +68,16 @@ void msx_cart_sfg_device::device_add_mconfig(machine_config &config)
MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set("ym2148", FUNC(ym2148_device::write_rxd));
}
void msx_cart_sfg05_device::device_add_mconfig(machine_config &config)
{
msx_cart_sfg_device::device_add_mconfig(config);
YM2164(config.replace(), m_ym2151, XTAL(3'579'545));
m_ym2151->irq_handler().set(FUNC(msx_cart_sfg05_device::ym2151_irq_w));
m_ym2151->add_route(0, "lspeaker", 0.80);
m_ym2151->add_route(1, "rspeaker", 0.80);
}
ROM_START( msx_sfg01 )
ROM_REGION(0x4000, "sfg", 0)

View File

@ -31,7 +31,6 @@ protected:
IRQ_CALLBACK_MEMBER(irq_callback);
private:
DECLARE_WRITE_LINE_MEMBER(ym2151_irq_w);
DECLARE_WRITE_LINE_MEMBER(ym2148_irq_w);
@ -61,6 +60,7 @@ class msx_cart_sfg05_device : public msx_cart_sfg_device
public:
msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
};

View File

@ -5,6 +5,7 @@
#include "ym2151.h"
DEFINE_DEVICE_TYPE(YM2151, ym2151_device, "ym2151", "Yamaha YM2151 OPM")
DEFINE_DEVICE_TYPE(YM2164, ym2164_device, "ym2164", "Yamaha YM2164 OPP")
#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
@ -407,6 +408,21 @@ void ym2151_device::calculate_timers()
}
}
void ym2164_device::calculate_timers()
{
/* calculate timers' deltas */
for (int i=0; i<1024; i++)
{
/* ASG 980324: changed to compute both tim_A_tab and timer_A_time */
timer_A_time[i] = clocks_to_attotime(64 * (1024 - i));
}
for (int i=0; i<256; i++)
{
/* ASG 980324: changed to compute both tim_B_tab and timer_B_time */
timer_B_time[i] = clocks_to_attotime(2048 * (256 - i));
}
}
void ym2151_device::YM2151Operator::key_on(uint32_t key_set, uint32_t eg_cnt)
{
if (!key)
@ -910,6 +926,16 @@ void ym2151_device::write_reg(int r, int v)
}
}
void ym2164_device::write_reg(int r, int v)
{
if (r < 0x08)
logerror("%s: Writing %02X to undocumented register %d\n", machine().describe_context(), v, r);
else if (r == 0x09)
ym2151_device::write_reg(0x01, v);
else
ym2151_device::write_reg(r, v);
}
void ym2151_device::device_post_load()
{
for (int j=0; j<8; j++)
@ -1662,8 +1688,8 @@ void ym2151_device::advance()
// ym2151_device - constructor
//-------------------------------------------------
ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, YM2151, tag, owner, clock),
ym2151_device::ym2151_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock),
device_sound_interface(mconfig, *this),
m_stream(nullptr),
m_lastreg(0),
@ -1673,6 +1699,21 @@ ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, dev
{
}
ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ym2151_device(mconfig, YM2151, tag, owner, clock)
{
}
//-------------------------------------------------
// ym2164_device - constructor
//-------------------------------------------------
ym2164_device::ym2164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ym2151_device(mconfig, YM2164, tag, owner, clock)
{
}
//-------------------------------------------------
// read - read from the device

View File

@ -66,6 +66,8 @@ public:
protected:
// device-level overrides
ym2151_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@ -75,6 +77,9 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
virtual void calculate_timers();
virtual void write_reg(int r, int v);
private:
enum {
TIMER_IRQ_A_OFF,
@ -208,8 +213,11 @@ private:
emu_timer *timer_A, *timer_A_irq_off;
emu_timer *timer_B, *timer_B_irq_off;
protected:
attotime timer_A_time[1024]; /* timer A times for MAME */
attotime timer_B_time[256]; /* timer B times for MAME */
private:
int irqlinestate;
uint32_t timer_A_index; /* timer A index */
@ -250,12 +258,10 @@ private:
bool m_reset_active;
void init_tables();
void calculate_timers();
void envelope_KONKOFF(YM2151Operator * op, int v);
void set_connect(YM2151Operator *om1, int cha, int v);
void advance();
void advance_eg();
void write_reg(int r, int v);
void chan_calc(unsigned int chan);
void chan7_calc();
int op_calc(YM2151Operator * OP, unsigned int env, signed int pm);
@ -263,9 +269,23 @@ private:
void refresh_EG(YM2151Operator * op);
};
// ======================> ym2164_device
class ym2164_device : public ym2151_device
{
public:
// construction/destruction
ym2164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void calculate_timers() override;
virtual void write_reg(int r, int v) override;
};
// device type definition
DECLARE_DEVICE_TYPE(YM2151, ym2151_device)
DECLARE_DEVICE_TYPE(YM2164, ym2164_device)
#endif // MAME_SOUND_YM2151_H

View File

@ -218,7 +218,7 @@ void fb01_state::fb01(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ym2151_device &ym2164(YM2151(config, "ym2164", XTAL(4'000'000)));
ym2164_device &ym2164(YM2164(config, "ym2164", XTAL(4'000'000)));
ym2164.irq_handler().set(FUNC(fb01_state::ym2164_irq_w));
ym2164.add_route(0, "lspeaker", 1.00);
ym2164.add_route(1, "rspeaker", 1.00);