mc68681: Fixed generation of spurious interrupts, and provide ASSERT/CLEAR states to the IRQ callback. [R. Belmont]

This commit is contained in:
R. Belmont 2012-05-19 17:25:12 +00:00
parent 724bcae310
commit df357d0025
9 changed files with 67 additions and 28 deletions

View File

@ -3,6 +3,7 @@
Written by Mariusz Wojcieszek
Updated by Jonathan Gevaryahu AKA Lord Nightmare
Improved interrupt handling by R. Belmont
*/
#include "emu.h"
@ -230,9 +231,17 @@ static void duart68681_update_interrupts(duart68681_state *duart68681)
if ( duart68681->duart_config->irq_handler )
{
LOG(( "68681: Interrupt line active (IMR & ISR = %02X)\n", (duart68681->ISR & duart68681->IMR) ));
duart68681->duart_config->irq_handler( duart68681->device, duart68681->IVR );
duart68681->duart_config->irq_handler( duart68681->device, ASSERT_LINE, duart68681->IVR );
}
}
else
{
if ( duart68681->duart_config->irq_handler )
{
LOG(( "68681: Interrupt line not active (IMR & ISR = %02X)\n", (duart68681->ISR & duart68681->IMR) ));
duart68681->duart_config->irq_handler( duart68681->device, CLEAR_LINE, duart68681->IVR );
}
}
};
static TIMER_CALLBACK( duart_timer_callback )
@ -336,7 +345,7 @@ static void duart68681_write_CR(duart68681_state *duart68681, int ch, UINT8 data
else
duart68681->ISR &= ~INT_TXRDYB;
duart68681->channel[ch].tx_timer->adjust(attotime::never, ch);
break;
break;
case 4: /* Reset Error Status */
duart68681->channel[ch].SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR | STATUS_OVERRUN_ERROR);
break;
@ -355,7 +364,6 @@ static void duart68681_write_CR(duart68681_state *duart68681, int ch, UINT8 data
LOG(( "68681: Unhandled command (%x) in CR%d\n", (data >> 4) & 0x07, ch ));
break;
}
duart68681_update_interrupts(duart68681);
if (BIT(data, 0)) {
duart68681->channel[ch].rx_enabled = 1;
@ -384,6 +392,7 @@ static void duart68681_write_CR(duart68681_state *duart68681, int ch, UINT8 data
duart68681->ISR &= ~INT_TXRDYB;
}
duart68681_update_interrupts(duart68681);
};
static UINT8 duart68681_read_rx_fifo(duart68681_state *duart68681, int ch)
@ -613,7 +622,15 @@ WRITE8_DEVICE_HANDLER(duart68681_w)
break;
case 0x06: /* Timer, CLK/1 */ // Timer modes start without reading address 0xe, as per the Freescale 68681 manual
{
attotime rate = attotime::from_hz(2*device->clock()/(2*16*duart68681->CTR.w.l));
attotime rate;
if (duart68681->CTR.w.l > 0)
{
rate = attotime::from_hz(2*device->clock()/(2*16*duart68681->CTR.w.l));
}
else
{
rate = attotime::from_hz(2*device->clock()/(2*16*0x10000));
}
duart68681->duart_timer->adjust(rate, 0, rate);
}
break;
@ -621,14 +638,30 @@ WRITE8_DEVICE_HANDLER(duart68681_w)
{
//double hz;
//attotime rate = attotime::from_hz(duart68681->clock) * (16*duart68681->CTR.w.l);
attotime rate = attotime::from_hz(2*device->clock()/(2*16*16*duart68681->CTR.w.l));
//hz = ATTOSECONDS_TO_HZ(rate.attoseconds);
// workaround for maygay1b locking up MAME
if ((2*device->clock()/(2*16*16*duart68681->CTR.w.l)) == 0)
attotime rate;
if (duart68681->CTR.w.l > 0)
{
rate = attotime::from_hz(1);
rate = attotime::from_hz(2*device->clock()/(2*16*16*duart68681->CTR.w.l));
// workaround for maygay1b locking up MAME
if ((2*device->clock()/(2*16*16*duart68681->CTR.w.l)) == 0)
{
rate = attotime::from_hz(1);
}
}
else
{
if (2*device->clock()/(2*16*16*0x10000) == 0)
{
rate = attotime::from_hz(1);
}
else
{
rate = attotime::from_hz(2*device->clock()/(2*16*16*0x10000));
}
}
//hz = ATTOSECONDS_TO_HZ(rate.attoseconds);
duart68681->duart_timer->adjust(rate, 0, rate);
}

View File

@ -6,7 +6,7 @@
typedef struct _duart68681_config duart68681_config;
struct _duart68681_config
{
void (*irq_handler)(device_t *device, UINT8 vector);
void (*irq_handler)(device_t *device, int state, UINT8 vector);
void (*tx_callback)(device_t *device, int channel, UINT8 data);
UINT8 (*input_port_read)(device_t *device);
void (*output_port_write)(device_t *device, UINT8 data);

View File

@ -265,10 +265,10 @@ if (!screen.machine().input().code_pressed(KEYCODE_O)) // debug: toggle window
***************************************************************************/
static void duart_irq_handler( device_t *device, UINT8 vector )
static void duart_irq_handler( device_t *device, int state, UINT8 vector )
{
adp_state *state = device->machine().driver_data<adp_state>();
device_set_input_line_and_vector(state->m_maincpu, 4, HOLD_LINE, vector);
adp_state *adp = device->machine().driver_data<adp_state>();
device_set_input_line_and_vector(adp->m_maincpu, 4, state, vector);
}
static void duart_tx( device_t *device, int channel, UINT8 data )

View File

@ -654,17 +654,20 @@ static const ymz280b_interface ymz280b_config =
void bfm_sc4_duart_irq_handler(device_t *device, UINT8 vector)
void bfm_sc4_duart_irq_handler(device_t *device, int state, UINT8 vector)
{
// triggers after reel tests on luckb, at the start on dnd...
// not sure this is right, causes some games to crash
logerror("bfm_sc4_duart_irq_handler\n");
m68307_licr2_interrupt((legacy_cpu_device*)device->machine().device("maincpu"));
if (state == ASSERT_LINE)
{
m68307_licr2_interrupt((legacy_cpu_device*)device->machine().device("maincpu"));
}
};
void bfm_sc4_duart_tx(device_t *device, int channel, UINT8 data)
{
logerror("bfm_sc4_duart_irq_handler\n");
logerror("bfm_sc4_duart_tx\n");
};
@ -706,10 +709,13 @@ static const duart68681_config bfm_sc4_duart68681_config =
void m68307_duart_irq_handler(device_t *device, UINT8 vector)
void m68307_duart_irq_handler(device_t *device, int state, UINT8 vector)
{
logerror("m68307_duart_irq_handler\n");
m68307_serial_interrupt((legacy_cpu_device*)device->machine().device("maincpu"), vector);
if (state == ASSERT_LINE)
{
m68307_serial_interrupt((legacy_cpu_device*)device->machine().device("maincpu"), vector);
}
};
void m68307_duart_tx(device_t *device, int channel, UINT8 data)

View File

@ -541,9 +541,9 @@ static MACHINE_RESET( m1 )
///////////////////////////////////////////////////////////////////////////
static void duart_irq_handler(device_t *device, UINT8 state)
static void duart_irq_handler(device_t *device, int state, UINT8 vector)
{
cputag_set_input_line(device->machine(), "maincpu", M6809_IRQ_LINE, state?ASSERT_LINE:CLEAR_LINE);
cputag_set_input_line(device->machine(), "maincpu", M6809_IRQ_LINE, state);
LOG(("6809 irq%d \n",state));
}

View File

@ -926,9 +926,9 @@ INPUT_PORTS_END
***************************************************************************/
static void duart_irq_handler(device_t *device, UINT8 vector)
static void duart_irq_handler(device_t *device, int state, UINT8 vector)
{
cputag_set_input_line_and_vector(device->machine(), "maincpu", 5, ASSERT_LINE, vector);
cputag_set_input_line_and_vector(device->machine(), "maincpu", 5, state, vector);
// cputag_set_input_line(device->machine(), "maincpu", 5, state ? ASSERT_LINE : CLEAR_LINE);
};

View File

@ -196,9 +196,9 @@ static WRITE16_DEVICE_HANDLER( tmaster_oki_bank_w )
***************************************************************************/
static void duart_irq_handler(device_t *device, UINT8 vector)
static void duart_irq_handler(device_t *device, int state, UINT8 vector)
{
cputag_set_input_line_and_vector(device->machine(), "maincpu", 4, HOLD_LINE, vector);
cputag_set_input_line_and_vector(device->machine(), "maincpu", 4, state, vector);
};
static void duart_tx(device_t *device, int channel, UINT8 data)

View File

@ -123,7 +123,7 @@ typedef struct _micro3d_vtx_
void micro3d_duart_irq_handler(device_t *device, UINT8 vector);
void micro3d_duart_irq_handler(device_t *device, int state, UINT8 vector);
UINT8 micro3d_duart_input_r(device_t *device);
void micro3d_duart_output_w(device_t *device, UINT8 data);
void micro3d_duart_tx(device_t *device, int channel, UINT8 data);

View File

@ -29,9 +29,9 @@
*
*************************************/
void micro3d_duart_irq_handler(device_t *device, UINT8 vector)
void micro3d_duart_irq_handler(device_t *device, int state, UINT8 vector)
{
cputag_set_input_line_and_vector(device->machine(), "maincpu", 3, HOLD_LINE, vector);
cputag_set_input_line_and_vector(device->machine(), "maincpu", 3, state, vector);
};
void micro3d_duart_tx(device_t *device, int channel, UINT8 data)