ymf271: Support dynamic changes to clock frequency

This commit is contained in:
AJR 2017-06-26 09:43:18 -04:00
parent d1f6b7a719
commit b1576db62c
2 changed files with 24 additions and 12 deletions

View File

@ -1276,7 +1276,7 @@ void ymf271_device::device_timer(emu_timer &timer, device_timer_id id, int param
} }
// reload timer // reload timer
m_timA->adjust(attotime::from_hz(m_clock) * (384 * 4 * (256 - m_timerA)), 0); m_timA->adjust(clocks_to_attotime(384 * 4 * (256 - m_timerA)), 0);
break; break;
case 1: case 1:
@ -1292,7 +1292,7 @@ void ymf271_device::device_timer(emu_timer &timer, device_timer_id id, int param
} }
// reload timer // reload timer
m_timB->adjust(attotime::from_hz(m_clock) * (384 * 16 * (256 - m_timerB)), 0); m_timB->adjust(clocks_to_attotime(384 * 16 * (256 - m_timerB)), 0);
break; break;
default: default:
@ -1357,14 +1357,14 @@ void ymf271_device::ymf271_write_timer(uint8_t address, uint8_t data)
// timer A load // timer A load
if (~m_enable & data & 1) if (~m_enable & data & 1)
{ {
attotime period = attotime::from_hz(m_clock) * (384 * 4 * (256 - m_timerA)); attotime period = clocks_to_attotime(384 * 4 * (256 - m_timerA));
m_timA->adjust((data & 1) ? period : attotime::never, 0); m_timA->adjust((data & 1) ? period : attotime::never, 0);
} }
// timer B load // timer B load
if (~m_enable & data & 2) if (~m_enable & data & 2)
{ {
attotime period = attotime::from_hz(m_clock) * (384 * 16 * (256 - m_timerB)); attotime period = clocks_to_attotime(384 * 16 * (256 - m_timerB));
m_timB->adjust((data & 2) ? period : attotime::never, 0); m_timB->adjust((data & 2) ? period : attotime::never, 0);
} }
@ -1603,20 +1603,23 @@ void ymf271_device::init_tables()
double db = 0.75 * (double)i; double db = 0.75 * (double)i;
m_lut_total_level[i] = (int)(65536.0 / pow(10.0, db / 20.0)); m_lut_total_level[i] = (int)(65536.0 / pow(10.0, db / 20.0));
} }
}
void ymf271_device::calculate_clock_correction()
{
// timing may use a non-standard XTAL // timing may use a non-standard XTAL
double clock_correction = (double)(STD_CLOCK) / (double)(m_clock); double clock_correction = (clock() != 0) ? (double)(STD_CLOCK) / (double)clock() : 0.0;
for (i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
m_lut_lfo[i] = LFO_frequency_table[i] * clock_correction; m_lut_lfo[i] = LFO_frequency_table[i] * clock_correction;
} }
for (i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
// attack/release rate in number of samples // attack/release rate in number of samples
m_lut_ar[i] = (ARTime[i] * clock_correction * 44100.0) / 1000.0; m_lut_ar[i] = (ARTime[i] * clock_correction * 44100.0) / 1000.0;
} }
for (i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
// decay rate in number of samples // decay rate in number of samples
m_lut_dc[i] = (DCTime[i] * clock_correction * 44100.0) / 1000.0; m_lut_dc[i] = (DCTime[i] * clock_correction * 44100.0) / 1000.0;
@ -1701,8 +1704,6 @@ void ymf271_device::init_state()
void ymf271_device::device_start() void ymf271_device::device_start()
{ {
m_clock = clock();
m_timA = timer_alloc(0); m_timA = timer_alloc(0);
m_timB = timer_alloc(1); m_timB = timer_alloc(1);
@ -1744,6 +1745,17 @@ void ymf271_device::device_reset()
m_irq_handler(0); m_irq_handler(0);
} }
//-------------------------------------------------
// device_clock_changed - called whenever the
// clock is updated
//-------------------------------------------------
void ymf271_device::device_clock_changed()
{
m_stream->set_sample_rate(clock() / 384);
calculate_clock_correction();
}
DEFINE_DEVICE_TYPE(YMF271, ymf271_device, "ymf271", "Yamaha YMF271") DEFINE_DEVICE_TYPE(YMF271, ymf271_device, "ymf271", "Yamaha YMF271")
ymf271_device::ymf271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) ymf271_device::ymf271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@ -1759,7 +1771,6 @@ ymf271_device::ymf271_device(const machine_config &mconfig, const char *tag, dev
, m_ext_readlatch(0) , m_ext_readlatch(0)
, m_mem_base(*this, DEVICE_SELF) , m_mem_base(*this, DEVICE_SELF)
, m_mem_size(0) , m_mem_size(0)
, m_clock(0)
, m_timA(nullptr) , m_timA(nullptr)
, m_timB(nullptr) , m_timB(nullptr)
, m_stream(nullptr) , m_stream(nullptr)

View File

@ -33,6 +33,7 @@ protected:
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void device_clock_changed() override;
// sound stream update overrides // 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 sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
@ -98,6 +99,7 @@ private:
void init_state(); void init_state();
void init_tables(); void init_tables();
void calculate_clock_correction();
void calculate_step(YMF271Slot *slot); void calculate_step(YMF271Slot *slot);
void update_envelope(YMF271Slot *slot); void update_envelope(YMF271Slot *slot);
void init_envelope(YMF271Slot *slot); void init_envelope(YMF271Slot *slot);
@ -147,7 +149,6 @@ private:
optional_region_ptr<uint8_t> m_mem_base; optional_region_ptr<uint8_t> m_mem_base;
uint32_t m_mem_size; uint32_t m_mem_size;
uint32_t m_clock;
emu_timer *m_timA; emu_timer *m_timA;
emu_timer *m_timB; emu_timer *m_timB;