CVS & tms5110

CVS: 
- hook up speech cpu
- get rid of "temporary" code which hardwire ctl & pdc writes
tms5110: 
- Implement ctl port input/output for status reads.
- Input/output is switched by clocking pdc after a TALK STATUS command.
- update drivers to support new tms5110_ctl_r
This commit is contained in:
Couriersud 2009-09-18 01:09:37 +00:00
parent 5fa23d0227
commit a384977a7c
4 changed files with 83 additions and 82 deletions

View File

@ -33,6 +33,9 @@
VSS | 14 15 | M0 VSS | 14 15 | M0
+-----------------+ +-----------------+
T11: Sync for serial data out
M58817 M58817
The following connections could be derived from radar scope schematics. The following connections could be derived from radar scope schematics.
@ -85,6 +88,12 @@
#define TMS5110_IS_CD2802 TMS5110_IS_5110 #define TMS5110_IS_CD2802 TMS5110_IS_5110
#define TMS5110_IS_M58817 TMS5110_IS_5110 #define TMS5110_IS_M58817 TMS5110_IS_5110
/* States for CTL */
#define CTL_STATE_INPUT (0)
#define CTL_STATE_OUTPUT (1)
#define CTL_STATE_NEXT_OUTPUT (2)
struct tms5100_coeffs struct tms5100_coeffs
{ {
int subtype; int subtype;
@ -120,7 +129,7 @@ struct _tms5110_state
UINT8 speaking_now; UINT8 speaking_now;
UINT8 speak_delay_frames; UINT8 speak_delay_frames;
UINT8 talk_status; UINT8 talk_status;
UINT8 ignore_next_cmd; UINT8 state;
/* Rom interface */ /* Rom interface */
UINT32 address; UINT32 address;
@ -231,7 +240,7 @@ static void register_for_save_states(tms5110_state *tms)
state_save_register_device_item(tms->device, 0, tms->speaking_now); state_save_register_device_item(tms->device, 0, tms->speaking_now);
state_save_register_device_item(tms->device, 0, tms->speak_delay_frames); state_save_register_device_item(tms->device, 0, tms->speak_delay_frames);
state_save_register_device_item(tms->device, 0, tms->talk_status); state_save_register_device_item(tms->device, 0, tms->talk_status);
state_save_register_device_item(tms->device, 0, tms->ignore_next_cmd); state_save_register_device_item(tms->device, 0, tms->state);
state_save_register_device_item(tms->device, 0, tms->old_energy); state_save_register_device_item(tms->device, 0, tms->old_energy);
state_save_register_device_item(tms->device, 0, tms->old_pitch); state_save_register_device_item(tms->device, 0, tms->old_pitch);
@ -399,7 +408,7 @@ void tms5110_process(tms5110_state *tms, INT16 *buffer, unsigned int size)
/* if the old frame was a stop frame, exit and do not process any more frames */ /* if the old frame was a stop frame, exit and do not process any more frames */
if (tms->old_energy == COEFF_ENERGY_SENTINEL) if (tms->old_energy == COEFF_ENERGY_SENTINEL)
{ {
/*if (DEBUG_5110) logerror("processing frame: stop frame\n");*/ if (DEBUG_5110) logerror("processing frame: stop frame\n");
tms->target_energy = tms->current_energy = 0; tms->target_energy = tms->current_energy = 0;
tms->speaking_now = tms->talk_status = 0; tms->speaking_now = tms->talk_status = 0;
tms->interp_count = tms->sample_count = tms->pitch_count = 0; tms->interp_count = tms->sample_count = tms->pitch_count = 0;
@ -672,9 +681,17 @@ void tms5110_PDC_set(tms5110_state *tms, int data)
tms->PDC = data & 0x1; tms->PDC = data & 0x1;
if (tms->PDC == 0) /* toggling 1->0 processes command on CTL_pins */ if (tms->PDC == 0) /* toggling 1->0 processes command on CTL_pins */
{ {
if (tms->ignore_next_cmd) /* first pdc toggles output, next toggles input */
switch (tms->state)
{ {
tms->ignore_next_cmd = FALSE; case CTL_STATE_INPUT:
/* continue */
break;
case CTL_STATE_NEXT_OUTPUT:
tms->state = CTL_STATE_OUTPUT;
return;
case CTL_STATE_OUTPUT:
tms->state = CTL_STATE_INPUT;
return; return;
} }
/* the only real commands we handle now are SPEAK and RESET */ /* the only real commands we handle now are SPEAK and RESET */
@ -718,10 +735,7 @@ void tms5110_PDC_set(tms5110_state *tms, int data)
break; break;
case TMS5110_CMD_TEST_TALK: case TMS5110_CMD_TEST_TALK:
/* FIXME: status on CTL1 can only be read after this command tms->state = CTL_STATE_NEXT_OUTPUT;
* to properly do radarscope, we need a separate m58817 status read.
*/
tms->ignore_next_cmd = TRUE;
break; break;
default: default:
@ -946,6 +960,8 @@ static DEVICE_START( tms5110 )
tms->set_load_address = speech_rom_set_addr; tms->set_load_address = speech_rom_set_addr;
} }
tms->state = CTL_STATE_INPUT; /* most probably not defined */
register_for_save_states(tms); register_for_save_states(tms);
} }
@ -1060,7 +1076,7 @@ WRITE8_DEVICE_HANDLER( tms5110_pdc_w )
/****************************************************************************** /******************************************************************************
tms5110_status_r -- read status from the sound chip tms5110_ctl_r -- read status from the sound chip
bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data. bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data.
Talk Status goes active at the initiation of a SPEAK command. Talk Status goes active at the initiation of a SPEAK command.
@ -1069,9 +1085,29 @@ WRITE8_DEVICE_HANDLER( tms5110_pdc_w )
TMS5110 datasheets mention this is only available as a result of executing TMS5110 datasheets mention this is only available as a result of executing
TEST TALK command. TEST TALK command.
FIXME: data read not implemented, CTL1 only available after TALK command
******************************************************************************/ ******************************************************************************/
READ8_DEVICE_HANDLER( tms5110_status_r ) READ8_DEVICE_HANDLER( tms5110_ctl_r )
{
tms5110_state *tms = get_safe_token(device);
/* bring up to date first */
stream_update(tms->stream);
if (tms->state == CTL_STATE_OUTPUT)
{
//if (DEBUG_5110) logerror("Status read (status=%2d)\n", tms->talk_status);
return (tms->talk_status << 0); /*CTL1 = still talking ? */
}
else
{
//if (DEBUG_5110) logerror("Status read (not in output mode)\n");
return (0);
}
}
READ8_DEVICE_HANDLER( m58817_status_r )
{ {
tms5110_state *tms = get_safe_token(device); tms5110_state *tms = get_safe_token(device);
@ -1080,6 +1116,8 @@ READ8_DEVICE_HANDLER( tms5110_status_r )
return (tms->talk_status << 0); /*CTL1 = still talking ? */ return (tms->talk_status << 0); /*CTL1 = still talking ? */
} }
WRITE8_DEVICE_HANDLER( tms5110_ctl_w );
/****************************************************************************** /******************************************************************************

View File

@ -26,9 +26,12 @@ struct _tms5110_interface
}; };
WRITE8_DEVICE_HANDLER( tms5110_ctl_w ); WRITE8_DEVICE_HANDLER( tms5110_ctl_w );
READ8_DEVICE_HANDLER( tms5110_ctl_r );
WRITE8_DEVICE_HANDLER( tms5110_pdc_w ); WRITE8_DEVICE_HANDLER( tms5110_pdc_w );
READ8_DEVICE_HANDLER( tms5110_status_r ); /* m58817 status line */
READ8_DEVICE_HANDLER( m58817_status_r );
int tms5110_ready_r(const device_config *device); int tms5110_ready_r(const device_config *device);
void tms5110_set_frequency(const device_config *device, int frequency); void tms5110_set_frequency(const device_config *device, int frequency);

View File

@ -1287,7 +1287,7 @@ MACHINE_DRIVER_START( radarsc1_audio )
MDRV_LATCH8_ADD( "virtual_p1" ) /* virtual latch for port A */ MDRV_LATCH8_ADD( "virtual_p1" ) /* virtual latch for port A */
MDRV_LATCH8_INVERT( 0x80 ) /* signal is inverted */ MDRV_LATCH8_INVERT( 0x80 ) /* signal is inverted */
MDRV_LATCH8_DEVREAD(7, "ls259.6h", latch8_r, 3) MDRV_LATCH8_DEVREAD(7, "ls259.6h", latch8_r, 3)
MDRV_LATCH8_DEVREAD(6, "tms", tms5110_status_r, 0) MDRV_LATCH8_DEVREAD(6, "tms", m58817_status_r, 0)
MDRV_SOUND_ADD("tms", M58817, XTAL_640kHz) MDRV_SOUND_ADD("tms", M58817, XTAL_640kHz)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)

View File

@ -251,10 +251,11 @@ static INTERRUPT_GEN( cvs_main_cpu_interrupt )
} }
static void cvs_dac_cpu_interrupt(running_machine *machine) static void cvs_slave_cpu_interrupt(running_machine *machine, const char *cpu, int state)
{ {
cpu_set_input_line_vector(cputag_get_cpu(machine, "audiocpu"), 0, 0x03); cpu_set_input_line_vector(cputag_get_cpu(machine, cpu), 0, 0x03);
cputag_set_input_line(machine, "audiocpu", 0, HOLD_LINE); //cputag_set_input_line(machine, cpu, 0, state ? ASSERT_LINE : CLEAR_LINE);
cputag_set_input_line(machine, cpu, 0, state ? HOLD_LINE : CLEAR_LINE);
} }
@ -326,6 +327,7 @@ static WRITE8_DEVICE_HANDLER( cvs_4_bit_dac_data_w )
{ {
UINT8 dac_value; UINT8 dac_value;
//LOG(("4BIT: %02x %02x\n", offset, data));
cvs_4_bit_dac_data[offset] = data >> 7; cvs_4_bit_dac_data[offset] = data >> 7;
/* merge into D0-D3 */ /* merge into D0-D3 */
@ -346,88 +348,53 @@ static WRITE8_DEVICE_HANDLER( cvs_4_bit_dac_data_w )
* *
*************************************/ *************************************/
/* temporary code begin */
static void speech_execute_command(const device_config *tms, UINT8 command)
{
/* reset */
if (command == 0x3f)
{
tms5110_ctl_w(tms, 0, TMS5110_CMD_RESET);
tms5110_pdc_w(tms, 0,0);
tms5110_pdc_w(tms, 0,1);
tms5110_pdc_w(tms, 0,0);
tms5110_pdc_w(tms, 0,0);
tms5110_pdc_w(tms, 0,1);
tms5110_pdc_w(tms, 0,0);
tms5110_pdc_w(tms, 0,0);
tms5110_pdc_w(tms, 0,1);
tms5110_pdc_w(tms, 0,0);
speech_rom_bit_address = 0;
}
/* start */
else
{
tms5110_ctl_w(tms, 0, TMS5110_CMD_SPEAK);
tms5110_pdc_w(tms, 0, 0);
tms5110_pdc_w(tms, 0, 1);
tms5110_pdc_w(tms, 0, 0);
speech_rom_bit_address = command * 0x80 * 8;
}
}
/* temporary code end */
static WRITE8_HANDLER( cvs_speech_rom_address_lo_w ) static WRITE8_HANDLER( cvs_speech_rom_address_lo_w )
{ {
/* assuming that d0-d2 are cleared here */ /* assuming that d0-d2 are cleared here */
speech_rom_bit_address = (speech_rom_bit_address & 0xf800) | (data << 3); speech_rom_bit_address = (speech_rom_bit_address & 0xf800) | (data << 3);
LOG(("%04x : CVS: Speech Address = %04x\n", cpu_get_pc(space->cpu), speech_rom_bit_address >> 3)); LOG(("%04x : CVS: Speech Lo %02x Address = %04x\n", cpu_get_pc(space->cpu), data, speech_rom_bit_address >> 3));
} }
static WRITE8_HANDLER( cvs_speech_rom_address_hi_w ) static WRITE8_HANDLER( cvs_speech_rom_address_hi_w )
{ {
speech_rom_bit_address = (speech_rom_bit_address & 0x07ff) | (data << 11); speech_rom_bit_address = (speech_rom_bit_address & 0x07ff) | (data << 11);
} LOG(("%04x : CVS: Speech Hi %02x Address = %04x\n", cpu_get_pc(space->cpu), data, speech_rom_bit_address >> 3));
static void cvs_set_speech_command_w(const address_space *space, UINT8 data)
{
soundlatch2_w(space, 0, data & 0x7f);
if (~data & 0x40) LOG(("%04x : CVS: Speech Command W = %04x\n", cpu_get_pc(space->cpu), data & 0x7f));
} }
static READ8_HANDLER( cvs_speech_command_r ) static READ8_HANDLER( cvs_speech_command_r )
{ {
/* bit 7 is TMS status (active LO) */ /* FIXME: this was by observation on board ???
return (~tms5110_status_r(devtag_get_device(space->machine, "tms"), 0) << 7) | soundlatch2_r(space, 0); * -bit 7 is TMS status (active LO) */
return ((tms5110_ctl_r(devtag_get_device(space->machine, "tms"), 0) ^ 1) << 7)
| (soundlatch2_r(space, 0) & 0x7f);
} }
static WRITE8_DEVICE_HANDLER( cvs_tms5110_ctl_w ) static WRITE8_DEVICE_HANDLER( cvs_tms5110_ctl_w )
{ {
UINT8 ctl; UINT8 ctl;
/*
* offset 0: CS ?
*/
cvs_tms5110_ctl_data[offset] = (~data >> 7) & 0x01; cvs_tms5110_ctl_data[offset] = (~data >> 7) & 0x01;
ctl = 0 | /* CTL1 */ ctl = 0 | /* CTL1 */
(cvs_tms5110_ctl_data[1] << 1) | /* CTL2 */ (cvs_tms5110_ctl_data[1] << 1) | /* CTL2 */
0 | /* CTL4 */ (cvs_tms5110_ctl_data[2] << 2) | /* CTL4 */
(cvs_tms5110_ctl_data[0] << 3); /* CTL8 */ (cvs_tms5110_ctl_data[1] << 3); /* CTL8 */
//tms5110_ctl_w(device, ctl); LOG(("CVS: Speech CTL = %04x %02x %02x\n", ctl, offset, data));
tms5110_ctl_w(device, 0, ctl);
} }
static WRITE8_DEVICE_HANDLER( cvs_tms5110_pdc_w ) static WRITE8_DEVICE_HANDLER( cvs_tms5110_pdc_w )
{ {
//tms5110_pdc_w(device, ~data >> 7); UINT8 out = ((~data) >> 7) & 1;
LOG(("CVS: Speech PDC = %02x %02x\n", offset, out));
tms5110_pdc_w(device, 0, out);
} }
@ -464,21 +431,11 @@ static const tms5110_interface tms5100_interface =
static WRITE8_HANDLER( audio_command_w ) static WRITE8_HANDLER( audio_command_w )
{ {
LOG(("data %02x\n", data));
/* cause interrupt on audio CPU if bit 7 set */ /* cause interrupt on audio CPU if bit 7 set */
if (data & 0x80) soundlatch2_w(space, 0, data);
{
soundlatch_w(space, 0, data); soundlatch_w(space, 0, data);
cvs_dac_cpu_interrupt(space->machine); cvs_slave_cpu_interrupt(space->machine, "audiocpu", data & 0x80 ? 1 : 0);
LOG(("%04x : CVS: Audio command = %02x\n", cpu_get_pc(space->cpu), data));
}
cvs_set_speech_command_w(space, data);
/* temporary code begin */
if ((data & 0x40) == 0)
speech_execute_command(devtag_get_device(space->machine, "tms"), data & 0x03f);
/* temporary code end */
} }
@ -503,6 +460,9 @@ MACHINE_START( cvs )
start_393hz_timer(machine); start_393hz_timer(machine);
soundlatch_setclearedvalue(machine, 0xff);
soundlatch2_clear_w(NULL, 0, 0);
/* register state save */ /* register state save */
state_save_register_global_pointer(machine, cvs_color_ram, 0x400); state_save_register_global_pointer(machine, cvs_color_ram, 0x400);
state_save_register_global_pointer(machine, cvs_palette_ram, 0x10); state_save_register_global_pointer(machine, cvs_palette_ram, 0x10);
@ -580,7 +540,7 @@ static ADDRESS_MAP_START( cvs_speech_cpu_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x1d00, 0x1d00) AM_WRITE(cvs_speech_rom_address_lo_w) AM_RANGE(0x1d00, 0x1d00) AM_WRITE(cvs_speech_rom_address_lo_w)
AM_RANGE(0x1d40, 0x1d40) AM_WRITE(cvs_speech_rom_address_hi_w) AM_RANGE(0x1d40, 0x1d40) AM_WRITE(cvs_speech_rom_address_hi_w)
AM_RANGE(0x1d80, 0x1d80) AM_READ(cvs_speech_command_r) AM_RANGE(0x1d80, 0x1d80) AM_READ(cvs_speech_command_r)
AM_RANGE(0x1ddd, 0x1dde) AM_DEVWRITE("tms", cvs_tms5110_ctl_w) AM_BASE(&cvs_tms5110_ctl_data) AM_RANGE(0x1ddc, 0x1dde) AM_DEVWRITE("tms", cvs_tms5110_ctl_w) AM_BASE(&cvs_tms5110_ctl_data)
AM_RANGE(0x1ddf, 0x1ddf) AM_DEVWRITE("tms", cvs_tms5110_pdc_w) AM_RANGE(0x1ddf, 0x1ddf) AM_DEVWRITE("tms", cvs_tms5110_pdc_w)
ADDRESS_MAP_END ADDRESS_MAP_END