summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2010-05-24 12:13:13 +0000
committer Couriersud <couriersud@users.noreply.github.com>2010-05-24 12:13:13 +0000
commit37f35e51c1d9bc9695383c23547d75e42e748959 (patch)
tree99a48f7d7ad28f405def740302e98fc3c719fad1
parent4093adacbc1cc7df8cc1dc2cd231daf0d90eb3d8 (diff)
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]
-rw-r--r--src/emu/sound/tms5220.c36
-rw-r--r--src/emu/sound/tms5220.h3
-rw-r--r--src/mame/drivers/looping.c3
-rw-r--r--src/mame/drivers/zaccaria.c22
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 */