Divider related emulation core update, Fix init and period limitation
This commit is contained in:
parent
a9a249fd4c
commit
a8258d9a1a
|
@ -17,3 +17,4 @@ android/app/build/
|
|||
android/app/.cxx/
|
||||
.vs/
|
||||
CMakeSettings.json
|
||||
CMakePresets.json
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue