Divider related emulation core update, Fix init and period limitation

This commit is contained in:
cam900 2022-05-10 13:18:02 +09:00
parent a9a249fd4c
commit a8258d9a1a
5 changed files with 36 additions and 30 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ android/app/build/
android/app/.cxx/
.vs/
CMakeSettings.json
CMakePresets.json

View File

@ -639,7 +639,7 @@ void DivPlatformAY8910::setFlags(unsigned int flags) {
if (ay!=NULL) delete ay;
switch ((flags>>4)&3) {
case 1:
ay=new ym2149_device(rate);
ay=new ym2149_device(rate,clockSel);
sunsoft=false;
intellivision=false;
break;
@ -660,7 +660,6 @@ void DivPlatformAY8910::setFlags(unsigned int flags) {
break;
}
ay->device_start();
ay->set_clock_sel(clockSel);
stereo=(flags>>6)&1;
}

View File

@ -610,6 +610,7 @@ void DivPlatformAY8930::poke(std::vector<DivRegWrite>& wlist) {
}
void DivPlatformAY8930::setFlags(unsigned int flags) {
clockSel=(flags>>7)&1;
switch (flags&15) {
case 1:
chipClock=COLOR_PAL*2.0/5.0;
@ -657,7 +658,6 @@ void DivPlatformAY8930::setFlags(unsigned int flags) {
}
stereo=(flags>>6)&1;
clockSel=(flags>>7)&1;
}
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;
}
setFlags(flags);
ay=new ay8930_device(rate);
ay=new ay8930_device(rate,clockSel);
ay->device_start();
ay->set_clock_sel(clockSel);
ayBufLen=65536;
for (int i=0; i<3; i++) ayBuf[i]=new short[ayBufLen];
reset();

View File

@ -1061,7 +1061,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
for (int chan = 0; chan < NUM_CHANNELS; 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);
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)
{
/* 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,
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),
m_type(psg_type),
m_streams(streams),
@ -1446,12 +1446,12 @@ ay8910_device::ay8910_device(device_type type, unsigned int clock,
m_noise_out(0),
m_mode(0),
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_env_step_mul( (!(feature & PSG_HAS_EXPANDED_MODE)) && (psg_type == PSG_TYPE_AY) ? (m_step_mul << 1) : m_step_mul),
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_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_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)
{
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
// 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;
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)
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)
: ay8910_device(AY8930, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL | PSG_HAS_EXPANDED_MODE)
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, clk_sel)
{
}
ym2149_device::ym2149_device(unsigned int clock)
: ay8910_device(YM2149, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL)
ym2149_device::ym2149_device(unsigned int clock, bool clk_sel)
: ay8910_device(YM2149, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL, clk_sel)
{
}
ym3439_device::ym3439_device(unsigned int clock)
: ay8910_device(YM3439, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL)
ym3439_device::ym3439_device(unsigned int clock, bool clk_sel)
: ay8910_device(YM3439, clock, PSG_TYPE_YM, 3, 2, PSG_PIN26_IS_CLKSEL, clk_sel)
{
}

View File

@ -3,6 +3,10 @@
#ifndef MAME_SOUND_AY8910_H
#define MAME_SOUND_AY8910_H
#pragma once
#include <algorithm>
#define ALL_8910_CHANNELS -1
/* Internal resistance at Volume level 7. */
@ -89,7 +93,8 @@ public:
// configuration helpers
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; }
unsigned char data_r() { return ay8910_read_ym(); }
@ -144,7 +149,7 @@ public:
// internal interface for PSG component of YM device
// 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
void device_start();
@ -206,7 +211,7 @@ private:
void reset()
{
period = 0;
period = 1;
volume = 0;
duty = 0;
count = 0;
@ -216,7 +221,7 @@ private:
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)
@ -240,7 +245,7 @@ private:
void reset()
{
period = 0;
period = 1;
count = 0;
step = 0;
volume = 0;
@ -252,7 +257,7 @@ private:
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)
@ -295,7 +300,7 @@ private:
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 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 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))); }
// 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();
void ay8910_write_reg(int r, int v);
void build_mixer_table();
@ -370,19 +375,19 @@ public:
class ay8930_device : public ay8910_device
{
public:
ay8930_device(unsigned int clock);
ay8930_device(unsigned int clock, bool clk_sel = false);
};
class ym2149_device : public ay8910_device
{
public:
ym2149_device(unsigned int clock);
ym2149_device(unsigned int clock, bool clk_sel = false);
};
class ym3439_device : public ay8910_device
{
public:
ym3439_device(unsigned int clock);
ym3439_device(unsigned int clock, bool clk_sel = false);
};
class ymz284_device : public ay8910_device