es5503: Fix IRQ timing error introduced when I did the device conversion. [R. Belmont]

This commit is contained in:
R. Belmont 2012-09-14 03:39:57 +00:00
parent 28f35dced5
commit 5129c4f427

View File

@ -1,6 +1,6 @@
/*
ES5503 - Ensoniq ES5503 "DOC" emulator v1.0
ES5503 - Ensoniq ES5503 "DOC" emulator v2.1.1
By R. Belmont.
Copyright R. Belmont.
@ -33,6 +33,7 @@
1.0 (RB) - properly respects the input clock
2.0 (RB) - C++ conversion, more accurate oscillator IRQ timing
2.1 (RB) - Corrected phase when looping; synthLAB, Arkanoid, and Arkanoid II no longer go out of tune
2.1.1 (RB) - Fixed issue introduced in 2.0 where IRQs were delayed
*/
#include "emu.h"
@ -117,11 +118,11 @@ void es5503_device::halt_osc(int onum, int type, UINT32 *accumulator, int resshi
int mode = (pOsc->control>>1) & 3;
// if 0 found in sample data or mode is not free-run, halt this oscillator
if ((type != MODE_FREE) || (mode > 0))
if ((mode != MODE_FREE) || (type != 0))
{
pOsc->control |= 1;
}
else // preserve the relative phase of the oscillator when looping. I think.
else // preserve the relative phase of the oscillator when looping
{
UINT16 wtsize = pOsc->wtsize - 1;
UINT32 altram = (*accumulator) >> resshift;
@ -142,7 +143,7 @@ void es5503_device::halt_osc(int onum, int type, UINT32 *accumulator, int resshi
if (mode == MODE_SWAP)
{
pPartner->control &= ~1; // clear the halt bit
pPartner->accumulator = 0; // and make sure it starts from the top
pPartner->accumulator = 0; // and make sure it starts from the top (does this also need phase preservation?)
}
// IRQ enabled for this voice?
@ -249,7 +250,7 @@ void es5503_device::device_start()
// find our direct access
m_direct = &space()->direct();
rege0 = 0x80;
rege0 = 0xff;
for (osc = 0; osc < 32; osc++)
{
@ -269,12 +270,12 @@ void es5503_device::device_start()
m_stream = machine().sound().stream_alloc(*this, 0, 2, output_rate, this);
m_timer = timer_alloc(0, NULL);
m_timer->adjust(attotime::from_hz(output_rate));
m_timer->adjust(attotime::from_hz(output_rate), 0, attotime::from_hz(output_rate));
}
void es5503_device::device_reset()
{
rege0 = 0x80;
rege0 = 0xff;
for (int osc = 0; osc < 32; osc++)
{
@ -344,9 +345,14 @@ READ8_MEMBER( es5503_device::read )
{
switch (offset)
{
case 0xe0: // interrupt status
case 0xe0: // interrupt status
retval = rege0;
if (m_irq_func)
{
m_irq_func(this, 0);
}
// scan all oscillators
for (i = 0; i < oscsenabled+1; i++)
{
@ -358,12 +364,7 @@ READ8_MEMBER( es5503_device::read )
rege0 = retval | 0x80;
// and clear its flag
oscillators[i].irqpend--;
if (m_irq_func)
{
m_irq_func(this, 0);
}
oscillators[i].irqpend = 0;
break;
}
}
@ -467,7 +468,7 @@ WRITE8_MEMBER( es5503_device::write )
output_rate = (clock()/8)/(2+oscsenabled);
m_stream->set_sample_rate(output_rate);
m_timer->adjust(attotime::from_hz(output_rate));
m_timer->adjust(attotime::from_hz(output_rate), 0, attotime::from_hz(output_rate));
break;
case 0xe2: // A/D converter