summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/ics2115.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/ics2115.cpp')
-rw-r--r--src/devices/sound/ics2115.cpp53
1 files changed, 25 insertions, 28 deletions
diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp
index 0afc0787ed0..f38b31e6c86 100644
--- a/src/devices/sound/ics2115.cpp
+++ b/src/devices/sound/ics2115.cpp
@@ -59,12 +59,10 @@ void ics2115_device::device_start()
space(0).cache(m_cache);
- m_timer[0].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_0),this), this);
- m_timer[1].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_1),this), this);
+ m_timer[0].timer = timer_alloc(FUNC(ics2115_device::timer_cb_0), this);
+ m_timer[1].timer = timer_alloc(FUNC(ics2115_device::timer_cb_1), this);
m_stream = stream_alloc(0, 2, clock() / (32 * 32));
- m_irq_cb.resolve_safe();
-
//Exact formula as per patent 5809466
//This seems to give the ok fit but it is not good enough.
/*double maxvol = ((1 << volume_bits) - 1) * pow(2., (double)1/0x100);
@@ -434,8 +432,8 @@ int ics2115_device::fill_output(ics2115_voice& voice, std::vector<write_stream_v
{
constexpr int RAMP_SHIFT = 6;
const u32 volacc = (voice.vol.acc >> 14) & 0xfff;
- const u16 vlefti = volacc - m_panlaw[255 - voice.vol.pan]; // left index from acc - pan law
- const u16 vrighti = volacc - m_panlaw[voice.vol.pan]; // right index from acc - pan law
+ const s16 vlefti = volacc - m_panlaw[255 - voice.vol.pan]; // left index from acc - pan law
+ const s16 vrighti = volacc - m_panlaw[voice.vol.pan]; // right index from acc - pan law
//check negative values so no cracks, is it a hardware feature ?
const u16 vleft = vlefti > 0 ? (m_volume[vlefti] * voice.state.ramp >> RAMP_SHIFT) : 0;
const u16 vright = vrighti > 0 ? (m_volume[vrighti] * voice.state.ramp >> RAMP_SHIFT) : 0;
@@ -448,10 +446,9 @@ int ics2115_device::fill_output(ics2115_voice& voice, std::vector<write_stream_v
s32 sample = get_sample(voice);
//15-bit volume + (5-bit worth of 32 channel sum) + 16-bit samples = 4-bit extra
+ //if (voice.playing())
if (!m_vmode || voice.playing())
{
- /*if (voice.playing())
- {*/
outputs[0].add_int(i, (sample * vleft) >> (5 + volume_bits), 32768);
outputs[1].add_int(i, (sample * vright) >> (5 + volume_bits), 32768);
}
@@ -618,7 +615,8 @@ u16 ics2115_device::reg_read()
ret = m_active_osc;
break;
- case 0x0f:{// [osc] Interrupt source/oscillator
+ case 0x0f: // [osc] Interrupt source/oscillator
+ {
ret = 0xff;
for (int i = 0; i <= m_active_osc; i++)
{
@@ -643,7 +641,8 @@ u16 ics2115_device::reg_read()
}
}
ret <<= 8;
- break;}
+ break;
+ }
case 0x10: // [osc] Oscillator Control
ret = voice.osc.ctl << 8;
@@ -1079,41 +1078,39 @@ void ics2115_device::recalc_irq()
//Suspect
bool irq = (m_irq_pending & m_irq_enabled);
for (int i = 0; (!irq) && (i < 32); i++)
- irq |= m_voice[i].vol_ctrl.bitflags.irq_pending && m_voice[i].osc_conf.bitflags.irq_pending;
+ irq |= m_voice[i].vol_ctrl.bitflags.irq_pending && m_voice[i].osc_conf.bitflags.irq_pending;
m_irq_on = irq;
- if (!m_irq_cb.isnull())
- m_irq_cb(irq ? ASSERT_LINE : CLEAR_LINE);
+ m_irq_cb(irq ? ASSERT_LINE : CLEAR_LINE);
}
TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_0 )
{
- m_irq_pending |= 1 << 0;
- recalc_irq();
+ if (!(m_irq_pending & (1 << 0)))
+ {
+ m_irq_pending |= 1 << 0;
+ recalc_irq();
+ }
}
TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_1 )
{
- m_irq_pending |= 1 << 1;
- recalc_irq();
+ if (!(m_irq_pending & (1 << 1)))
+ {
+ m_irq_pending |= 1 << 1;
+ recalc_irq();
+ }
}
void ics2115_device::recalc_timer(int timer)
{
- //Old regression-based formula (minus constant)
- //u64 period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60;
-
- //New formula based on O.Galibert's reverse engineering of ICS2115 card firmware
- // TODO : Related to input clock?
u64 period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1);
- period = (period << (4 + (m_timer[timer].scale >> 5)))*78125/2646;
+ period = period << (4 + (m_timer[timer].scale >> 5));
if (m_timer[timer].period != period)
{
+ attotime tp = attotime::from_ticks(period, clock());
+ logerror("Timer %d period %dns (%dHz)\n", timer, int(tp.as_double()*1e9), int(1/tp.as_double()));
m_timer[timer].period = period;
- // Adjust the timer lengths
- if (period) // Reset the length
- m_timer[timer].timer->adjust(attotime::from_nsec(period), 0, attotime::from_nsec(period));
- else // Kill the timer if length == 0
- m_timer[timer].timer->adjust(attotime::never);
+ m_timer[timer].timer->adjust(tp, 0, tp);
}
}