es5506.cpp fixes: [Christian Brunschen]

- Fixed readback of global registers when the current page was in a certain range
- Real h/w does run the voice for a zero-length loop and the synths rely on it

These changes fix the playback of "Transwaves" on the VFX and SD-series synths.
This commit is contained in:
arbee 2016-10-15 21:53:04 -04:00
parent 20d755e3e1
commit 7892a9536d
2 changed files with 30 additions and 22 deletions

View File

@ -1096,9 +1096,15 @@ void es5505_device::generate_samples(INT32 **outputs, int offset, int samples)
es550x_voice *voice = &m_voice[v];
UINT16 *base = m_region_base[voice->control >> 14];
// This special case does not appear to match the behaviour observed in the es5505 in
// actual Ensoniq synthesizers: those, it turns out, do set loop start and end to the
// same value, and expect the voice to keep running. Examples can be found among the
// transwaves on the VFX / SD-1 series of synthesizers.
#if 0
/* special case: if end == start, stop the voice */
if (voice->start == voice->end)
voice->control |= CONTROL_STOP0;
#endif
int voice_channel = (voice->control & CONTROL_CAMASK) >> 10;
int channel = voice_channel % m_channels;
@ -2165,6 +2171,16 @@ inline UINT16 es5505_device::reg_read_test(es550x_voice *voice, offs_t offset)
result = m_read_port_cb(0);
break;
/* The following are global, and thus accessible form all pages */
case 0x0d: /* ACT */
result = m_active_voices;
break;
case 0x0e: /* IRQV */
result = m_irqv;
update_internal_irq_state();
break;
case 0x0f: /* PAGE */
result = m_current_page;
break;

View File

@ -100,7 +100,7 @@
62 = DATA INCREMENT
63 = DATA DECREMENT
VFX / VFX-SD / SD-1 analog values:
VFX / VFX-SD / SD-1 analog values: all values are 10 bits, left-justified within 16 bits.
0 = Pitch Bend
1 = Patch Select
2 = Mod Wheel
@ -243,28 +243,17 @@ SLOT_INTERFACE_END
IRQ_CALLBACK_MEMBER(esq5505_state::maincpu_irq_acknowledge_callback)
{
// We immediately update the interrupt presented to the CPU, so that it doesn't
// end up retrying the same interrupt over and over. We then return the appropriate vector.
int vector = 0;
switch(irqline) {
case 1:
otis_irq_state = 0;
vector = M68K_INT_ACK_AUTOVECTOR;
break;
return M68K_INT_ACK_AUTOVECTOR;
case 2:
dmac_irq_state = 0;
vector = dmac_irq_vector;
break;
return dmac_irq_vector;
case 3:
duart_irq_state = 0;
vector = duart_irq_vector;
break;
return duart_irq_vector;
default:
logerror("\nUnexpected IRQ ACK Callback: IRQ %d\n", irqline);
return 0;
}
update_irq_to_maincpu();
return vector;
}
void esq5505_state::machine_start()
@ -283,13 +272,13 @@ void esq5505_state::machine_reset()
floppy_connector *con = machine().device<floppy_connector>("wd1772:0");
floppy_image_device *floppy = con ? con->get_device() : nullptr;
// Default analog values:
m_analog_values[0] = 0x7fff; // pitch mod: start in the center
// Default analog values: all values are 10 bits, left-justified within 16 bits.
m_analog_values[0] = 0x7fc0; // pitch mod: start in the center
m_analog_values[1] = 0x0000; // patch select: nothing pressed.
m_analog_values[2] = 0x0000; // mod wheel: at the bottom, no modulation
m_analog_values[3] = 0xcccc; // data entry: somewhere in the middle
m_analog_values[4] = 0xffff; // control voltage / pedal: full on.
m_analog_values[5] = 0xffff; // Volume control: full on.
m_analog_values[2] = 0xffc0; // mod wheel: at the bottom, no modulation
m_analog_values[3] = 0xccc0; // data entry: somewhere in the middle
m_analog_values[4] = 0xffc0; // control voltage / pedal: full on.
m_analog_values[5] = 0xffc0; // Volume control: full on.
m_analog_values[6] = 0x7fc0; // Battery voltage: something reasonable.
m_analog_values[7] = 0x5540; // vRef to check battery.
@ -316,7 +305,7 @@ void esq5505_state::machine_reset()
}
void esq5505_state::update_irq_to_maincpu() {
//printf("\nupdating IRQ state: have OTIS=%d, DMAC=%d, DUART=%d\n", otis_irq_state, dmac_irq_state, duart_irq_state);
// printf("updating IRQ state: have OTIS=%d, DMAC=%d, DUART=%d\n", otis_irq_state, dmac_irq_state, duart_irq_state);
if (duart_irq_state) {
m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
@ -526,6 +515,7 @@ WRITE8_MEMBER(esq5505_state::dma_end)
dmac_irq_state = 0;
}
// printf("IRQ update from DMAC: have OTIS=%d, DMAC=%d, DUART=%d\n", otis_irq_state, dmac_irq_state, duart_irq_state);
update_irq_to_maincpu();
}
@ -977,7 +967,9 @@ DRIVER_INIT_MEMBER(esq5505_state,sq1)
{
DRIVER_INIT_CALL(common);
m_system_type = SQ1;
#if KEYBOARD_HACK
shift = 60;
#endif
}
DRIVER_INIT_MEMBER(esq5505_state,denib)