From 37f35e51c1d9bc9695383c23547d75e42e748959 Mon Sep 17 00:00:00 2001 From: Couriersud Date: Mon, 24 May 2010 12:13:13 +0000 Subject: [PATCH] Added a readyq callback to the TMS5220 interface. This is needed to solve MT #3832. In zaccaria games, the intq and readyq are connected to pia 6821 lines ca2 and cb1 which are edge driven. Just reading readyq would miss to detect a state change if between reads readyq went 0-1-0. Updated zaccaria.c and looping.c. Fixes MT #3832. [Couriersud] --- src/emu/sound/tms5220.c | 36 ++++++++++++++++++++++++++++++++---- src/emu/sound/tms5220.h | 3 ++- src/mame/drivers/looping.c | 3 ++- src/mame/drivers/zaccaria.c | 22 ++++------------------ 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/emu/sound/tms5220.c b/src/emu/sound/tms5220.c index 13dbed3f360..034e7a0f893 100644 --- a/src/emu/sound/tms5220.c +++ b/src/emu/sound/tms5220.c @@ -238,6 +238,7 @@ struct _tms5220_state /* callbacks */ devcb_resolved_write_line irq_func; + devcb_resolved_write_line readyq_func; /* these contain data that describes the 128-bit data FIFO */ UINT8 fifo[FIFO_SIZE]; @@ -254,6 +255,7 @@ struct _tms5220_state UINT8 buffer_low; /* If 1, FIFO has less than 8 bytes in it */ UINT8 buffer_empty; /* If 1, FIFO is empty */ UINT8 irq_pin; /* state of the IRQ pin (output) */ + UINT8 ready_pin; /* state of the READY pin (output) */ /* these contain data describing the current and previous voice frames */ #define OLD_FRAME_SILENCE_FLAG (tms->old_frame_energy_idx == 0) // 1 if E=0, 0 otherwise. @@ -362,6 +364,7 @@ static void update_status_and_ints(tms5220_state *tms); static void set_interrupt_state(tms5220_state *tms, int state); static INT32 lattice_filter(tms5220_state *tms); static INT16 clip_analog(INT16 clip); +static void update_ready_state(tms5220_state *tms); static STREAM_UPDATE( tms5220_update ); void tms5220_set_variant(tms5220_state *tms, int variant) @@ -400,6 +403,7 @@ static void register_for_save_states(tms5220_state *tms) state_save_register_device_item(tms->device, 0, tms->buffer_low); state_save_register_device_item(tms->device, 0, tms->buffer_empty); state_save_register_device_item(tms->device, 0, tms->irq_pin); + state_save_register_device_item(tms->device, 0, tms->ready_pin); state_save_register_device_item(tms->device, 0, tms->old_frame_energy_idx); state_save_register_device_item(tms->device, 0, tms->old_frame_pitch_idx); @@ -560,6 +564,9 @@ static void tms5220_data_write(tms5220_state *tms, int data) static void update_status_and_ints(tms5220_state *tms) { /* update flags and set ints if needed */ + + update_ready_state(tms); + /* BL is set if neither byte 9 nor 8 of the fifo are in use; this translates to having fifo_count (which ranges from 0 bytes in use to 16 bytes used) being less than or equal to 8. Victory/Victorba depends on this. */ @@ -1378,6 +1385,23 @@ static void set_interrupt_state(tms5220_state *tms, int state) tms->irq_pin = state; } +/********************************************************************************************** + + update_ready_state -- update the ready line + +***********************************************************************************************/ + +static void update_ready_state(tms5220_state *tms) +{ + int state = tms5220_ready_read(tms); +#ifdef DEBUG_PIN_READS + logerror("ready pin set to state %d\n", state); +#endif + if (tms->readyq_func.write && state != tms->ready_pin) + devcb_call_write_line(&tms->readyq_func, !state); + tms->ready_pin = state; +} + /********************************************************************************************** @@ -1399,8 +1423,9 @@ static DEVICE_START( tms5220 ) assert_always(tms != NULL, "Error creating TMS5220 chip"); - /* resolve irq line */ + /* resolve irq and readyq line */ devcb_resolve_write_line(&tms->irq_func, &tms->intf->irq_func, device); + devcb_resolve_write_line(&tms->readyq_func, &tms->intf->readyq_func, device); /* initialize a stream */ tms->stream = stream_create(device, 0, 1, device->clock / 80, tms, tms5220_update); @@ -1459,8 +1484,9 @@ static DEVICE_RESET( tms5220 ) /* initialize the chip state */ /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if tms->buffer_empty or tms->buffer_low are 0 */ - tms->speaking_now = tms->speak_external = tms->talk_status = tms->irq_pin = 0; + tms->speaking_now = tms->speak_external = tms->talk_status = tms->irq_pin = tms->ready_pin = 0; set_interrupt_state(tms, 0); + update_ready_state(tms); tms->buffer_empty = tms->buffer_low = 1; tms->RDB_flag = FALSE; @@ -1524,6 +1550,7 @@ static TIMER_CALLBACK( io_ready_cb ) } } tms->io_ready = param; + update_ready_state(tms); } WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w ) @@ -1571,8 +1598,8 @@ WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w ) /* 100 nsec from data sheet, through 3 asynchronous gates on patent */ //timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock), tms, 0, io_ready_cb); // /READY goes inactive immediately, within one clock... for that matter, what do we even need a timer for then? tms->io_ready = 0; - /* 25 usec (16 clocks) in datasheet, but zaccaria games glitch or fail to talk if that value is used. The zaccaria glitching may be buggy game code or may be a bug with the MAME 6821 PIA code which interfaces with the tms5200, particularly its handling of updates of the CA1 and CA2 lines? */ - //timer_set(tms->device->machine, ATTOTIME_IN_USEC(100), tms, 1, io_ready_cb); + update_ready_state(tms); + /* 25 usec (16 clocks) in datasheet */ timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock/16), tms, 1, io_ready_cb); // this should take around 10-16 (closer to ~11?) cycles to complete } } @@ -1620,6 +1647,7 @@ WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w ) /* 100 nsec from data sheet, through 3 asynchronous gates on patent */ //timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock), tms, 0, io_ready_cb); // /READY goes inactive immediately, within one clock... for that matter, what do we even need a timer for then? tms->io_ready = 0; + update_ready_state(tms); timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock/16), tms, 1, io_ready_cb); // this should take around 10-16 (closer to ~15) cycles to complete for fifo writes, TODO: but actually depends on what command is written if in command mode } } diff --git a/src/emu/sound/tms5220.h b/src/emu/sound/tms5220.h index 3c5a9e69e26..1acb1d28a41 100644 --- a/src/emu/sound/tms5220.h +++ b/src/emu/sound/tms5220.h @@ -11,7 +11,8 @@ typedef struct _tms5220_interface tms5220_interface; struct _tms5220_interface { - devcb_write_line irq_func; /* IRQ callback function */ + devcb_write_line irq_func; /* IRQ callback function, active low, i.e. state=0 */ + devcb_write_line readyq_func; /* Ready callback function, active low, i.e. state=0 */ int (*read)(running_device *device, int count); /* speech ROM read callback */ void (*load_address)(running_device *device, int data); /* speech ROM load address callback */ diff --git a/src/mame/drivers/looping.c b/src/mame/drivers/looping.c index d4baf6542b7..d17af5ed4f9 100644 --- a/src/mame/drivers/looping.c +++ b/src/mame/drivers/looping.c @@ -580,7 +580,8 @@ GFXDECODE_END static const tms5220_interface tms5220_config = { - DEVCB_LINE(looping_spcint) + DEVCB_LINE(looping_spcint), // IRQ + DEVCB_NULL // READYQ }; static const ay8910_interface ay8910_config = diff --git a/src/mame/drivers/zaccaria.c b/src/mame/drivers/zaccaria.c index 73ae6ecbee1..199f38747c2 100644 --- a/src/mame/drivers/zaccaria.c +++ b/src/mame/drivers/zaccaria.c @@ -161,15 +161,6 @@ static WRITE8_DEVICE_HANDLER( zaccaria_port0b_w ) last_port0b = data; } -static INTERRUPT_GEN( zaccaria_cb1_toggle ) -{ - running_device *pia0 = devtag_get_device(device->machine, "pia0"); - static int toggle; - - pia6821_cb1_w(pia0,0, toggle & 1); - toggle ^= 1; -} - static WRITE8_DEVICE_HANDLER( zaccaria_port1b_w ) { running_device *tms = devtag_get_device(device->machine, "tms"); @@ -186,11 +177,6 @@ static WRITE8_DEVICE_HANDLER( zaccaria_port1b_w ) set_led_status(device->machine, 0,~data & 0x10); } -static READ_LINE_DEVICE_HANDLER( zaccaria_ca2_r ) -{ - return tms5220_readyq_r(device); -} - static const pia6821_interface pia_0_intf = { @@ -214,8 +200,8 @@ static const pia6821_interface pia_1_intf = DEVCB_DEVICE_HANDLER("tms", tms5220_status_r), /* port A in */ DEVCB_NULL, /* port B in */ DEVCB_NULL, /* line CA1 in */ - DEVCB_NULL, /* line CB1 in */ - DEVCB_DEVICE_LINE("tms", zaccaria_ca2_r), /* line CA2 in */ + DEVCB_NULL, //DEVCB_DEVICE_LINE("tms", tms5220_intq_r), /* line CB1 in */ + DEVCB_NULL, //DEVCB_DEVICE_LINE("tms", tms5220_readyq_r), /* line CA2 in */ DEVCB_NULL, /* line CB2 in */ DEVCB_DEVICE_HANDLER("tms", tms5220_data_w), /* port A out */ DEVCB_HANDLER(zaccaria_port1b_w), /* port B out */ @@ -541,7 +527,8 @@ static const ay8910_interface ay8910_config = static const tms5220_interface tms5220_config = { - DEVCB_DEVICE_HANDLER("pia1", pia6821_cb1_w) /* IRQ handler */ + DEVCB_DEVICE_HANDLER("pia1", pia6821_cb1_w), /* IRQ handler */ + DEVCB_DEVICE_HANDLER("pia1", pia6821_ca2_w) /* READYQ handler */ }; @@ -556,7 +543,6 @@ static MACHINE_DRIVER_START( zaccaria ) MDRV_CPU_ADD("audiocpu", M6802,XTAL_3_579545MHz) /* verified on pcb */ MDRV_CPU_PROGRAM_MAP(sound_map_1) - MDRV_CPU_PERIODIC_INT(zaccaria_cb1_toggle,(double)3580000/4096) MDRV_QUANTUM_TIME(HZ(1000000)) MDRV_CPU_ADD("audio2", M6802,XTAL_3_579545MHz) /* verified on pcb */