Divider related emulation core update, Fix init and period limitation
This commit is contained in:
parent
a9a249fd4c
commit
a8258d9a1a
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ android/app/build/
|
||||||
android/app/.cxx/
|
android/app/.cxx/
|
||||||
.vs/
|
.vs/
|
||||||
CMakeSettings.json
|
CMakeSettings.json
|
||||||
|
CMakePresets.json
|
||||||
|
|
|
@ -639,7 +639,7 @@ void DivPlatformAY8910::setFlags(unsigned int flags) {
|
||||||
if (ay!=NULL) delete ay;
|
if (ay!=NULL) delete ay;
|
||||||
switch ((flags>>4)&3) {
|
switch ((flags>>4)&3) {
|
||||||
case 1:
|
case 1:
|
||||||
ay=new ym2149_device(rate);
|
ay=new ym2149_device(rate,clockSel);
|
||||||
sunsoft=false;
|
sunsoft=false;
|
||||||
intellivision=false;
|
intellivision=false;
|
||||||
break;
|
break;
|
||||||
|
@ -660,7 +660,6 @@ void DivPlatformAY8910::setFlags(unsigned int flags) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ay->device_start();
|
ay->device_start();
|
||||||
ay->set_clock_sel(clockSel);
|
|
||||||
|
|
||||||
stereo=(flags>>6)&1;
|
stereo=(flags>>6)&1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,6 +610,7 @@ void DivPlatformAY8930::poke(std::vector<DivRegWrite>& wlist) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformAY8930::setFlags(unsigned int flags) {
|
void DivPlatformAY8930::setFlags(unsigned int flags) {
|
||||||
|
clockSel=(flags>>7)&1;
|
||||||
switch (flags&15) {
|
switch (flags&15) {
|
||||||
case 1:
|
case 1:
|
||||||
chipClock=COLOR_PAL*2.0/5.0;
|
chipClock=COLOR_PAL*2.0/5.0;
|
||||||
|
@ -657,7 +658,6 @@ void DivPlatformAY8930::setFlags(unsigned int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
stereo=(flags>>6)&1;
|
stereo=(flags>>6)&1;
|
||||||
clockSel=(flags>>7)&1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformAY8930::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformAY8930::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
@ -669,9 +669,8 @@ int DivPlatformAY8930::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
oscBuf[i]=new DivDispatchOscBuffer;
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
ay=new ay8930_device(rate);
|
ay=new ay8930_device(rate,clockSel);
|
||||||
ay->device_start();
|
ay->device_start();
|
||||||
ay->set_clock_sel(clockSel);
|
|
||||||
ayBufLen=65536;
|
ayBufLen=65536;
|
||||||
for (int i=0; i<3; i++) ayBuf[i]=new short[ayBufLen];
|
for (int i=0; i<3; i++) ayBuf[i]=new short[ayBufLen];
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -1061,7 +1061,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
|
||||||
for (int chan = 0; chan < NUM_CHANNELS; chan++)
|
for (int chan = 0; chan < NUM_CHANNELS; chan++)
|
||||||
{
|
{
|
||||||
tone = &m_tone[chan];
|
tone = &m_tone[chan];
|
||||||
const int period = std::max<int>(1,tone->period) * (m_step_mul << 1);
|
const int period = tone->period * (m_step_mul << 1);
|
||||||
tone->count += is_expanded_mode() ? 32 : ((m_feature & PSG_HAS_EXPANDED_MODE) ? 1 : 2);
|
tone->count += is_expanded_mode() ? 32 : ((m_feature & PSG_HAS_EXPANDED_MODE) ? 1 : 2);
|
||||||
while (tone->count >= period)
|
while (tone->count >= period)
|
||||||
{
|
{
|
||||||
|
@ -1071,7 +1071,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int period_noise = noise_period() * m_step_mul;
|
const int period_noise = (int)(noise_period()) * m_step_mul;
|
||||||
if ((++m_count_noise) >= period_noise)
|
if ((++m_count_noise) >= period_noise)
|
||||||
{
|
{
|
||||||
/* toggle the prescaler output. Noise is no different to
|
/* toggle the prescaler output. Noise is no different to
|
||||||
|
@ -1431,7 +1431,7 @@ ay8910_device::ay8910_device(unsigned int clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
ay8910_device::ay8910_device(device_type type, unsigned int clock,
|
ay8910_device::ay8910_device(device_type type, unsigned int clock,
|
||||||
psg_type_t psg_type, int streams, int ioports, int feature)
|
psg_type_t psg_type, int streams, int ioports, int feature, bool clk_sel)
|
||||||
: chip_type(type),
|
: chip_type(type),
|
||||||
m_type(psg_type),
|
m_type(psg_type),
|
||||||
m_streams(streams),
|
m_streams(streams),
|
||||||
|
@ -1446,12 +1446,12 @@ ay8910_device::ay8910_device(device_type type, unsigned int clock,
|
||||||
m_noise_out(0),
|
m_noise_out(0),
|
||||||
m_mode(0),
|
m_mode(0),
|
||||||
m_env_step_mask((!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 0x0f : 0x1f),
|
m_env_step_mask((!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 0x0f : 0x1f),
|
||||||
m_step_mul( (feature & PSG_HAS_INTERNAL_DIVIDER) ? 2 : 1),
|
m_step_mul( ((feature & PSG_HAS_INTERNAL_DIVIDER) || ((feature & PSG_PIN26_IS_CLKSEL) && clk_sel)) ? 2 : 1),
|
||||||
m_env_step_mul( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? (m_step_mul << 1) : m_step_mul),
|
m_env_step_mul( ((feature & PSG_HAS_EXPANDED_MODE) || (psg_type == PSG_TYPE_AY)) ? (m_step_mul << 1) : m_step_mul),
|
||||||
m_zero_is_off( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 1 : 0),
|
m_zero_is_off( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? 1 : 0),
|
||||||
m_par( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param),
|
m_par( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param),
|
||||||
m_par_env( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param_env),
|
m_par_env( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? &ay8910_param : &ym2149_param_env),
|
||||||
m_flags(AY8910_LEGACY_OUTPUT),
|
m_flags(AY8910_LEGACY_OUTPUT | (((feature & PSG_PIN26_IS_CLKSEL) && clk_sel) ? YM2149_PIN26_LOW : 0)),
|
||||||
m_feature(feature)
|
m_feature(feature)
|
||||||
{
|
{
|
||||||
memset(&m_regs,0,sizeof(m_regs));
|
memset(&m_regs,0,sizeof(m_regs));
|
||||||
|
@ -1463,10 +1463,10 @@ ay8910_device::ay8910_device(device_type type, unsigned int clock,
|
||||||
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
|
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
|
||||||
|
|
||||||
// TODO : measure ay8930 volume parameters (PSG_TYPE_YM for temporary 5 bit handling)
|
// TODO : measure ay8930 volume parameters (PSG_TYPE_YM for temporary 5 bit handling)
|
||||||
set_type((m_feature & PSG_HAS_EXPANDED_MODE) ? PSG_TYPE_YM : psg_type);
|
set_type((m_feature & PSG_HAS_EXPANDED_MODE) ? PSG_TYPE_YM : psg_type, clk_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ay8910_device::set_type(psg_type_t psg_type)
|
void ay8910_device::set_type(psg_type_t psg_type, bool clk_sel)
|
||||||
{
|
{
|
||||||
m_type = psg_type;
|
m_type = psg_type;
|
||||||
if (psg_type == PSG_TYPE_AY)
|
if (psg_type == PSG_TYPE_AY)
|
||||||
|
@ -1487,6 +1487,8 @@ void ay8910_device::set_type(psg_type_t psg_type)
|
||||||
}
|
}
|
||||||
if (m_feature & PSG_HAS_EXPANDED_MODE)
|
if (m_feature & PSG_HAS_EXPANDED_MODE)
|
||||||
m_env_step_mul <<= 1;
|
m_env_step_mul <<= 1;
|
||||||
|
|
||||||
|
set_clock_sel(clk_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1515,24 +1517,24 @@ ay8914_device::ay8914_device(unsigned int clock)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ay8930_device::ay8930_device(unsigned int clock)
|
ay8930_device::ay8930_device(unsigned int clock, bool clk_sel)
|
||||||
: ay8910_device(AY8930, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL | PSG_HAS_EXPANDED_MODE)
|
: ay8910_device(AY8930, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL | PSG_HAS_EXPANDED_MODE, clk_sel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ym2149_device::ym2149_device(unsigned int clock)
|
ym2149_device::ym2149_device(unsigned int clock, bool clk_sel)
|
||||||
: ay8910_device(YM2149, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL)
|
: ay8910_device(YM2149, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL, clk_sel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ym3439_device::ym3439_device(unsigned int clock)
|
ym3439_device::ym3439_device(unsigned int clock, bool clk_sel)
|
||||||
: ay8910_device(YM3439, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL)
|
: ay8910_device(YM3439, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL, clk_sel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
#ifndef MAME_SOUND_AY8910_H
|
#ifndef MAME_SOUND_AY8910_H
|
||||||
#define MAME_SOUND_AY8910_H
|
#define MAME_SOUND_AY8910_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define ALL_8910_CHANNELS -1
|
#define ALL_8910_CHANNELS -1
|
||||||
|
|
||||||
/* Internal resistance at Volume level 7. */
|
/* Internal resistance at Volume level 7. */
|
||||||
|
@ -89,7 +93,8 @@ public:
|
||||||
|
|
||||||
// configuration helpers
|
// configuration helpers
|
||||||
void set_flags(int flags) { m_flags = flags; }
|
void set_flags(int flags) { m_flags = flags; }
|
||||||
void set_psg_type(psg_type_t psg_type) { set_type(psg_type); }
|
void set_psg_type(psg_type_t psg_type) { set_type(psg_type, m_flags & YM2149_PIN26_LOW); }
|
||||||
|
void set_psg_type(psg_type_t psg_type, bool clk_sel) { set_type(psg_type, clk_sel); }
|
||||||
void set_resistors_load(int res_load0, int res_load1, int res_load2) { m_res_load[0] = res_load0; m_res_load[1] = res_load1; m_res_load[2] = res_load2; }
|
void set_resistors_load(int res_load0, int res_load1, int res_load2) { m_res_load[0] = res_load0; m_res_load[1] = res_load1; m_res_load[2] = res_load2; }
|
||||||
|
|
||||||
unsigned char data_r() { return ay8910_read_ym(); }
|
unsigned char data_r() { return ay8910_read_ym(); }
|
||||||
|
@ -144,7 +149,7 @@ public:
|
||||||
// internal interface for PSG component of YM device
|
// internal interface for PSG component of YM device
|
||||||
// FIXME: these should be private, but vector06 accesses them directly
|
// FIXME: these should be private, but vector06 accesses them directly
|
||||||
|
|
||||||
ay8910_device(device_type type, unsigned int clock, psg_type_t psg_type, int streams, int ioports, int feature = PSG_DEFAULT);
|
ay8910_device(device_type type, unsigned int clock, psg_type_t psg_type, int streams, int ioports, int feature = PSG_DEFAULT, bool clk_sel = false);
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
void device_start();
|
void device_start();
|
||||||
|
@ -206,7 +211,7 @@ private:
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
period = 0;
|
period = 1;
|
||||||
volume = 0;
|
volume = 0;
|
||||||
duty = 0;
|
duty = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -216,7 +221,7 @@ private:
|
||||||
|
|
||||||
void set_period(unsigned char fine, unsigned char coarse)
|
void set_period(unsigned char fine, unsigned char coarse)
|
||||||
{
|
{
|
||||||
period = fine | (coarse << 8);
|
period = std::max<unsigned int>(1, fine | (coarse << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_volume(unsigned char val)
|
void set_volume(unsigned char val)
|
||||||
|
@ -240,7 +245,7 @@ private:
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
period = 0;
|
period = 1;
|
||||||
count = 0;
|
count = 0;
|
||||||
step = 0;
|
step = 0;
|
||||||
volume = 0;
|
volume = 0;
|
||||||
|
@ -252,7 +257,7 @@ private:
|
||||||
|
|
||||||
void set_period(unsigned char fine, unsigned char coarse)
|
void set_period(unsigned char fine, unsigned char coarse)
|
||||||
{
|
{
|
||||||
period = fine | (coarse << 8);
|
period = std::max<unsigned int>(1, fine | (coarse << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_shape(unsigned char shape, unsigned char mask)
|
void set_shape(unsigned char shape, unsigned char mask)
|
||||||
|
@ -295,7 +300,7 @@ private:
|
||||||
inline unsigned char get_envelope_chan(int chan) { return is_expanded_mode() ? chan : 0; }
|
inline unsigned char get_envelope_chan(int chan) { return is_expanded_mode() ? chan : 0; }
|
||||||
|
|
||||||
inline bool noise_enable(int chan) { return BIT(m_regs[AY_ENABLE], 3 + chan); }
|
inline bool noise_enable(int chan) { return BIT(m_regs[AY_ENABLE], 3 + chan); }
|
||||||
inline unsigned char noise_period() { return is_expanded_mode() ? m_regs[AY_NOISEPER] & 0xff : m_regs[AY_NOISEPER] & 0x1f; }
|
inline unsigned char noise_period() { return std::max<unsigned char>(1, is_expanded_mode() ? (m_regs[AY_NOISEPER] & 0xff) : (m_regs[AY_NOISEPER] & 0x1f)); }
|
||||||
inline unsigned char noise_output() { return is_expanded_mode() ? m_noise_out & 1 : m_rng & 1; }
|
inline unsigned char noise_output() { return is_expanded_mode() ? m_noise_out & 1 : m_rng & 1; }
|
||||||
|
|
||||||
inline bool is_expanded_mode() { return ((m_feature & PSG_HAS_EXPANDED_MODE) && ((m_mode & 0xe) == 0xa)); }
|
inline bool is_expanded_mode() { return ((m_feature & PSG_HAS_EXPANDED_MODE) && ((m_mode & 0xe) == 0xa)); }
|
||||||
|
@ -307,7 +312,7 @@ private:
|
||||||
inline bool is_clock_divided() { return ((m_feature & PSG_HAS_INTERNAL_DIVIDER) || ((m_feature & PSG_PIN26_IS_CLKSEL) && (m_flags & YM2149_PIN26_LOW))); }
|
inline bool is_clock_divided() { return ((m_feature & PSG_HAS_INTERNAL_DIVIDER) || ((m_feature & PSG_PIN26_IS_CLKSEL) && (m_flags & YM2149_PIN26_LOW))); }
|
||||||
|
|
||||||
// internal helpers
|
// internal helpers
|
||||||
void set_type(psg_type_t psg_type);
|
void set_type(psg_type_t psg_type, bool clk_sel);
|
||||||
inline float mix_3D();
|
inline float mix_3D();
|
||||||
void ay8910_write_reg(int r, int v);
|
void ay8910_write_reg(int r, int v);
|
||||||
void build_mixer_table();
|
void build_mixer_table();
|
||||||
|
@ -370,19 +375,19 @@ public:
|
||||||
class ay8930_device : public ay8910_device
|
class ay8930_device : public ay8910_device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ay8930_device(unsigned int clock);
|
ay8930_device(unsigned int clock, bool clk_sel = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ym2149_device : public ay8910_device
|
class ym2149_device : public ay8910_device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ym2149_device(unsigned int clock);
|
ym2149_device(unsigned int clock, bool clk_sel = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ym3439_device : public ay8910_device
|
class ym3439_device : public ay8910_device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ym3439_device(unsigned int clock);
|
ym3439_device(unsigned int clock, bool clk_sel = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ymz284_device : public ay8910_device
|
class ymz284_device : public ay8910_device
|
||||||
|
|
Loading…
Reference in a new issue