summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2007-12-25 22:47:08 +0000
committer Couriersud <couriersud@users.noreply.github.com>2007-12-25 22:47:08 +0000
commitbf79fa49484679650e6184682ce5775871d12e18 (patch)
tree2d3f98b31e12dd176268d0778dc34d1b9fd242ea /src/emu
parentdd82d11edb75d24fcf6abfec72fbdcbab52a66a3 (diff)
- radarsc1 uses tms5110 speech synth
- cvs games: according to PCBInfos speech chip is TMS5100. Changed driver to use TMS5100 and "game system operational" now sounds more natural - removed sound/m58817.* - added support for multiple coefficients maps to tms5110.* - added coefficient maps for TMS5100 and M58817 from documented sources to tms5110r.c - fixed interpolation factors (see tms5110r.c for reason) - made lattice calculation precision 9bit - added support for READBIT and LOADADDRESS commands to tms5110.c - more changes in line with various patents
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/sndintrf.c4
-rw-r--r--src/emu/sndintrf.h1
-rw-r--r--src/emu/sound/5110intf.c48
-rw-r--r--src/emu/sound/5110intf.h6
-rw-r--r--src/emu/sound/m58817.c365
-rw-r--r--src/emu/sound/m58817.h24
-rw-r--r--src/emu/sound/sound.mak12
-rw-r--r--src/emu/sound/tms5110.c931
-rw-r--r--src/emu/sound/tms5110.h9
-rw-r--r--src/emu/sound/tms5110r.c350
10 files changed, 822 insertions, 928 deletions
diff --git a/src/emu/sndintrf.c b/src/emu/sndintrf.c
index 7532aacfd81..52f426c64a6 100644
--- a/src/emu/sndintrf.c
+++ b/src/emu/sndintrf.c
@@ -164,7 +164,6 @@ void sid6581_get_info(void *token, UINT32 state, sndinfo *info);
void sid8580_get_info(void *token, UINT32 state, sndinfo *info);
void sp0256_get_info(void *token, UINT32 state, sndinfo *info);
void s14001a_get_info(void *token, UINT32 state, sndinfo *info);
-void m58817_get_info(void *token, UINT32 state, sndinfo *info);
void filter_volume_get_info(void *token, UINT32 state, sndinfo *info);
void filter_rc_get_info(void *token, UINT32 state, sndinfo *info);
@@ -445,9 +444,6 @@ static const struct
#if (HAS_SP0256)
{ SOUND_SP0256, sp0256_get_info },
#endif
-#if (HAS_M58817)
- { SOUND_M58817, m58817_get_info },
-#endif
{ SOUND_FILTER_VOLUME, filter_volume_get_info },
{ SOUND_FILTER_RC, filter_rc_get_info },
diff --git a/src/emu/sndintrf.h b/src/emu/sndintrf.h
index 67b5271642b..746fa65ee57 100644
--- a/src/emu/sndintrf.h
+++ b/src/emu/sndintrf.h
@@ -125,7 +125,6 @@ enum _sound_type
SOUND_SID8580,
SOUND_SP0256,
SOUND_S14001A,
- SOUND_M58817,
/* filters start here */
SOUND_FILTER_VOLUME,
diff --git a/src/emu/sound/5110intf.c b/src/emu/sound/5110intf.c
index cfc22302e7a..472a5ef02c8 100644
--- a/src/emu/sound/5110intf.c
+++ b/src/emu/sound/5110intf.c
@@ -27,13 +27,36 @@ struct tms5110_info
const struct TMS5110interface *intf;
sound_stream *stream;
void *chip;
+ INT32 speech_rom_bitnum;
};
/* static function prototypes */
static void tms5110_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length);
+static int speech_rom_read_bit(void)
+{
+ struct tms5110_info *info = sndti_token(SOUND_TMS5110, 0);
+ const UINT8 *table = memory_region(info->intf->rom_region);
+
+ int r;
+
+ if (info->speech_rom_bitnum<0)
+ r = 0;
+ else
+ r = (table[info->speech_rom_bitnum >> 3] >> (0x07 - (info->speech_rom_bitnum & 0x07))) & 1;
+
+ info->speech_rom_bitnum++;
+ return r;
+}
+
+static void speech_rom_set_addr(int addr)
+{
+ struct tms5110_info *info = sndti_token(SOUND_TMS5110, 0);
+
+ info->speech_rom_bitnum = addr * 8 - 1;
+}
/******************************************************************************
@@ -43,14 +66,14 @@ static void tms5110_update(void *param, stream_sample_t **inputs, stream_sample_
static void *tms5110_start(int sndindex, int clock, const void *config)
{
- static const struct TMS5110interface dummy = { 0 };
+ static const struct TMS5110interface dummy = { TMS5110_IS_5110A, -1 };
struct tms5110_info *info;
info = auto_malloc(sizeof(*info));
memset(info, 0, sizeof(*info));
info->intf = config ? config : &dummy;
- info->chip = tms5110_create(sndindex);
+ info->chip = tms5110_create(sndindex, info->intf->variant);
if (!info->chip)
return NULL;
sndintrf_register_token(info);
@@ -58,12 +81,21 @@ static void *tms5110_start(int sndindex, int clock, const void *config)
/* initialize a stream */
info->stream = stream_create(0, 1, clock / 80, info, tms5110_update);
- if (info->intf->M0_callback==NULL)
- {
- logerror("\n file: 5110intf.c, tms5110_start(), line 53:\n Missing _mandatory_ 'M0_callback' function pointer in the TMS5110 interface\n This function is used by TMS5110 to call for a single bits\n needed to generate the speech\n Aborting startup...\n");
- return NULL;
- }
- tms5110_set_M0_callback(info->chip, info->intf->M0_callback );
+ if (info->intf->rom_region == -1 )
+ {
+ if (info->intf->M0_callback==NULL)
+ {
+ logerror("\n file: 5110intf.c, tms5110_start(), line 53:\n Missing _mandatory_ 'M0_callback' function pointer in the TMS5110 interface\n This function is used by TMS5110 to call for a single bits\n needed to generate the speech\n Aborting startup...\n");
+ return NULL;
+ }
+ tms5110_set_M0_callback(info->chip, info->intf->M0_callback );
+ tms5110_set_load_address(info->chip, info->intf->load_address );
+ }
+ else
+ {
+ tms5110_set_M0_callback(info->chip, speech_rom_read_bit );
+ tms5110_set_load_address(info->chip, speech_rom_set_addr );
+ }
/* reset the 5110 */
tms5110_reset_chip(info->chip);
diff --git a/src/emu/sound/5110intf.h b/src/emu/sound/5110intf.h
index 704550b4efa..ee9aa3c24da 100644
--- a/src/emu/sound/5110intf.h
+++ b/src/emu/sound/5110intf.h
@@ -7,8 +7,10 @@
struct TMS5110interface
{
- void (*irq)(int state); /* IRQ callback function */
- int (*M0_callback)(void); /* function to be called when chip requests another bit*/
+ int variant; /* Variant of the 5110 - see tms5110.h */
+ int rom_region; /* set to -1 to specifiy callbacks below */
+ int (*M0_callback)(void); /* function to be called when chip requests another bit */
+ void (*load_address)(int addr); /* speech ROM load address callback */
};
WRITE8_HANDLER( tms5110_CTL_w );
diff --git a/src/emu/sound/m58817.c b/src/emu/sound/m58817.c
deleted file mode 100644
index abccd8f60f5..00000000000
--- a/src/emu/sound/m58817.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/******************************************************************************
-
- M58817 interface
-
- Written for MAME by couriersud
-
- - structure from TMS5110 interface
- - this is a wrapper around the TMS5110 interface
- - M58817 & TMS5110 seem to be similar, however it is very probable
- that they use different "coding" tables for energy, pitch
- - Speech is understandable, but off
- - This driver supports to use a "sample" interface instead as well
-
-******************************************************************************/
-
-#include <math.h>
-
-#include "sndintrf.h"
-#include "streams.h"
-#include "tms5110.h"
-#include "m58817.h"
-#include "sound/samples.h"
-
-
-#define MAX_SAMPLE_CHUNK 10000
-
-enum {
- WAIT_CMD,
- WAIT_WRITE,
- WAIT_DONE1,
- WAIT_DONE2
-} m58817_states;
-
-/* the state of the streamed output */
-struct m58817_info
-{
- const struct M58817interface *intf;
- sound_stream *stream;
- void *chip;
- UINT8 state;
- UINT8 drq;
- UINT8 nibbles[4];
- UINT8 command_latch;
- INT32 count;
- INT32 address;
- INT32 speech_rom_bitnum;
-};
-
-
-/* static function prototypes */
-static void m58817_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length);
-
-static int speech_rom_read_bit(void)
-{
- struct m58817_info *info = sndti_token(SOUND_M58817, 0);
- const UINT8 *table = memory_region(info->intf->rom_region);
-
- int r;
-
- if (info->speech_rom_bitnum<0)
- r = 0;
- else
- r = (table[info->speech_rom_bitnum >> 3] >> (0x07 - (info->speech_rom_bitnum & 0x07))) & 1;
- //r = (table[speech_rom_bitnum >> 3] >> ((speech_rom_bitnum & 0x07))) & 1;
- info->speech_rom_bitnum++;
- //printf("Byte: 0x%02x\n", speech_rom_bitnum>>3);
- return r;
-}
-
-/******************************************************************************
-
- m58817_state_loop -- process commands
-
-******************************************************************************/
-
-static void m58817_state_loop(void *chip, int data)
-{
- struct m58817_info *info = chip;
- int i;
- switch (info->state)
- {
- case WAIT_CMD:
- switch (data)
- {
- case 0x00: // reset ????
- info->count=0;
- /*To be extremely accurate there should be a delays between each of
- the function calls below. In real they happen with the frequency of 160 kHz.
- */
-
- if (info->intf->rom_region != -1)
- {
- tms5110_CTL_set(info->chip, TMS5110_CMD_RESET);
- tms5110_PDC_set(info->chip, 0);
- tms5110_PDC_set(info->chip, 1);
- tms5110_PDC_set(info->chip, 0);
-
- tms5110_PDC_set(info->chip, 0);
- tms5110_PDC_set(info->chip, 1);
- tms5110_PDC_set(info->chip, 0);
-
- tms5110_PDC_set(info->chip, 0);
- tms5110_PDC_set(info->chip, 1);
- tms5110_PDC_set(info->chip, 0);
-
- info->speech_rom_bitnum = 0x0;
- }
- break;
- case 0x02: // latch next nibbel
- info->state=WAIT_WRITE;
- break;
- case 0x08: // play ????
- info->state=WAIT_DONE1;
- break;
- default:
- logerror("m58817: unknown cmd : 0x%02x\n", data);
- }
- break;
- case WAIT_WRITE:
- info->nibbles[info->count++] = data & 0x0f;
- info->state=WAIT_CMD;
- break;
- case WAIT_DONE1:
- if (data != 0x0A)
- logerror("m58817: expected 0x0A got 0x%02x\n", data);
- info->address = 0;
- for (i=0;i<info->count;i++)
- {
- info->address |= (info->nibbles[i] << (i*4));
- }
- logerror("m58817: address: 0x%04x\n", info->address);
-
-
- if (info->intf->rom_region != -1)
- {
- info->speech_rom_bitnum = info->address * 8 - 1;
- tms5110_CTL_set(info->chip, TMS5110_CMD_SPEAK);
- tms5110_PDC_set(info->chip, 0);
- tms5110_PDC_set(info->chip, 1);
- tms5110_PDC_set(info->chip, 0);
- }
- else
- {
- for (i=0;i<M58817_MAX_SAMPLES;i++)
- if (info->intf->sample_addr[i] == info->address)
- {
- sample_start(0,i,0);
- break;
- }
- }
-
- info->state=WAIT_CMD;
- break;
- }
-}
-
-
-/******************************************************************************
-
- m58817_start -- allocate buffers and reset the 5110
-
-******************************************************************************/
-
-static void *m58817_start(int sndindex, int clock, const void *config)
-{
- static const struct M58817interface dummy = { 0 };
- struct m58817_info *info;
-
- info = auto_malloc(sizeof(*info));
- memset(info, 0, sizeof(*info));
- info->intf = config ? config : &dummy;
-
- if (info->intf->rom_region != -1)
- {
- info->chip = tms5110_create(sndindex);
- if (!info->chip)
- return NULL;
- }
- sndintrf_register_token(info);
-
- /* initialize a stream */
- if (info->intf->rom_region != -1)
- {
- info->stream = stream_create(0, 1, clock / 80, info, m58817_update);
- tms5110_set_M0_callback(info->chip, speech_rom_read_bit );
- /* reset the 58817 */
- tms5110_reset_chip(info->chip);
- }
-
- state_save_register_item("m58817", sndindex, info->state);
- state_save_register_item("m58817", sndindex, info->drq);
- state_save_register_item_array("m58817", sndindex, info->nibbles);
- state_save_register_item("m58817", sndindex, info->count);
- state_save_register_item("m58817", sndindex, info->address);
- state_save_register_item("m58817", sndindex, info->speech_rom_bitnum);
-
- /* request a sound channel */
- return info;
-}
-
-
-
-/******************************************************************************
-
- m58817_stop -- free buffers
-
-******************************************************************************/
-
-static void m58817_stop(void *chip)
-{
- struct m58817_info *info = chip;
- if (info->intf->rom_region != -1)
- tms5110_destroy(info->chip);
-}
-
-
-static void m58817_reset(void *chip)
-{
- struct m58817_info *info = chip;
- if (info->intf->rom_region != -1)
- tms5110_reset_chip(info->chip);
- info->state = WAIT_CMD;
- info->drq = 0;
- info->command_latch = 0;
- info->count=0;
-}
-
-
-
-/******************************************************************************
-
- m58817_CTL_w -- write Control Command to the sound chip
- commands like Speech, Reset, etc., are loaded into the chip via the CTL pins
-
-******************************************************************************/
-
-WRITE8_HANDLER( m58817_CTL_w )
-{
- struct m58817_info *info = sndti_token(SOUND_M58817, 0);
-
- /* bring up to date first */
- //stream_update(info->stream);
- info->command_latch = data & 0x0f;
-}
-
-/******************************************************************************
-
- m58817_DRQ_w -- write to DRQ pin on the sound chip
-
-******************************************************************************/
-
-WRITE8_HANDLER( m58817_DRQ_w )
-{
- struct m58817_info *info = sndti_token(SOUND_M58817, 0);
-
- /* bring up to date first */
- if (info->intf->rom_region != -1)
- stream_update(info->stream);
- if (!data & info->drq)
- m58817_state_loop(info, info->command_latch);
- info->drq = data;
-}
-
-
-
-/******************************************************************************
-
- m58817_status_r -- read status from the sound chip
-
-******************************************************************************/
-
-READ8_HANDLER( m58817_status_r )
-{
- struct m58817_info *info = sndti_token(SOUND_M58817, 0);
-
- /* bring up to date first */
- if (info->intf->rom_region != -1)
- stream_update(info->stream);
- if (info->intf->rom_region != -1)
- return tms5110_status_read(info->chip);
- else
- return sample_playing(0);
-}
-
-
-
-/******************************************************************************
-
- m58817_update -- update the sound chip so that it is in sync with CPU execution
-
-******************************************************************************/
-
-static void m58817_update(void *param, stream_sample_t **inputs, stream_sample_t **_buffer, int length)
-{
- struct m58817_info *info = param;
- INT16 sample_data[MAX_SAMPLE_CHUNK];
- stream_sample_t *buffer = _buffer[0];
-
- /* loop while we still have samples to generate */
- while (length)
- {
- int samples = (length > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : length;
- int index;
-
- /* generate the samples and copy to the target buffer */
- tms5110_process(info->chip, sample_data, samples);
- for (index = 0; index < samples; index++)
- *buffer++ = sample_data[index];
-
- /* account for the samples */
- length -= samples;
- }
-}
-
-
-
-/******************************************************************************
-
- m58817_set_frequency -- adjusts the playback frequency
-
-******************************************************************************/
-
-void m58817_set_frequency(int frequency)
-{
- struct m58817_info *info = sndti_token(SOUND_M58817, 0);
- stream_set_sample_rate(info->stream, frequency / 80);
-}
-
-
-
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-static void m58817_set_info(void *token, UINT32 state, sndinfo *info)
-{
- switch (state)
- {
- /* no parameters to set */
- }
-}
-
-
-void m58817_get_info(void *token, UINT32 state, sndinfo *info)
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case SNDINFO_PTR_SET_INFO: info->set_info = m58817_set_info; break;
- case SNDINFO_PTR_START: info->start = m58817_start; break;
- case SNDINFO_PTR_STOP: info->stop = m58817_stop; break;
- case SNDINFO_PTR_RESET: info->reset = m58817_reset; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case SNDINFO_STR_NAME: info->s = "M58817"; break;
- case SNDINFO_STR_CORE_FAMILY: info->s = "Mitsubishi Speech"; break;
- case SNDINFO_STR_CORE_VERSION: info->s = "1.0"; break;
- case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break;
- case SNDINFO_STR_CORE_CREDITS: info->s = "Copyright (c) 2007, The MAME Team"; break;
- }
-}
-
diff --git a/src/emu/sound/m58817.h b/src/emu/sound/m58817.h
deleted file mode 100644
index 7374f2d03ef..00000000000
--- a/src/emu/sound/m58817.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef m58817_h
-#define m58817_h
-
-/* clock rate = 80 * output sample rate, */
-/* usually 640000 for 8000 Hz sample rate or */
-/* usually 800000 for 10000 Hz sample rate. */
-
-#define M58817_MAX_SAMPLES 20
-
-struct M58817interface
-{
- int rom_region; /* set to -1 to use samples */
- int sample_addr[M58817_MAX_SAMPLES];
-};
-
-WRITE8_HANDLER( m58817_CTL_w );
-WRITE8_HANDLER( m58817_DRQ_w );
-
-READ8_HANDLER( m58817_status_r );
-
-void m58817_set_frequency(int frequency);
-
-#endif
-
diff --git a/src/emu/sound/sound.mak b/src/emu/sound/sound.mak
index 17f9db32cc9..34b8a47b642 100644
--- a/src/emu/sound/sound.mak
+++ b/src/emu/sound/sound.mak
@@ -594,18 +594,6 @@ endif
#-------------------------------------------------
-# Mitsubishi M58817 speech synthesizer
-#-------------------------------------------------
-
-SOUNDDEFS += -DHAS_M58817=$(if $(filter M58817,$(SOUNDS)),1,0)
-
-ifneq ($(filter M58817,$(SOUNDS)),)
-SOUNDOBJS += $(SOUNDOBJ)/m58817.o
-endif
-
-
-
-#-------------------------------------------------
# VLM5030 speech synthesizer
#-------------------------------------------------
diff --git a/src/emu/sound/tms5110.c b/src/emu/sound/tms5110.c
index 96ceea772b7..7e882d7753c 100644
--- a/src/emu/sound/tms5110.c
+++ b/src/emu/sound/tms5110.c
@@ -1,26 +1,92 @@
/**********************************************************************************************
- TMS5110 simulator (modified from TMS5220 by Jarek Burczynski)
-
- Written for MAME by Frank Palazzolo
- With help from Neill Corlett
- Additional tweaking by Aaron Giles
- Various fixes by Lord Nightmare
+ TMS5110 simulator (modified from TMS5220 by Jarek Burczynski)
+
+ Written for MAME by Frank Palazzolo
+ With help from Neill Corlett
+ Additional tweaking by Aaron Giles
+ Various fixes by Lord Nightmare
+ Additional enhancements by Couriersud
+
+ Todo:
+ - implement CS
+ - implement missing commands
+
+ TMS5100:
+
+ +-----------------+
+ TST | 1 28 | CS
+ PDC | 2 27 | CTL8
+ ROM CK | 3 26 | ADD8
+ CPU CK | 4 25 | CTL1
+ VDD | 5 24 | ADD1
+ CR OSC | 6 23 | CTL2
+ RC OSC | 7 22 | ADD2
+ T11 | 8 21 | ADD4
+ NC | 9 20 | CTL4
+ I/O | 10 19 | M1
+ SPK1 | 11 18 | NC
+ SPK2 | 12 17 | NC
+ PROM OUT | 13 16 | NC
+ VSS | 14 15 | M0
+ +-----------------+
+
+ M58817
+
+ The following connections could be derived from radar scope schematics.
+ The M58817 is not 100% pin compatible to the 5100, but really close.
+
+ +-----------------+
+ (NC) | 1 28 | CS
+ PDC | 2 27 | CTL8
+ ROM CK | 3 26 | ADD8 (to 58819)
+ (NC) | 4 25 | CTL1
+ (VDD,-5) | 5 24 | ADD1 (to 58819)
+ (GND) | 6 23 | CTL2
+ Xin | 7 22 | ADD2 (to 58819)
+ Xout | 8 21 | ADD4 (to 58819)
+ (NC) | 9 20 | CTL4
+ (VDD,-5) | 10 19 | Status back to CPU
+ (NC) | 11 18 | C1 (to 58819)
+ SPKR | 12 17 | (NC)
+ SPKR | 13 16 | C0 (to 58819)
+ (NC) | 14 15 | (5V)
+ +-----------------+
***********************************************************************************************/
#include "sndintrf.h"
#include "tms5110.h"
-
-/* Pull in the ROM tables */
-#include "tms5110r.c"
-
+#define MAX_K 10
+#define MAX_SCALE_BITS 6
+#define MAX_SCALE (1<<MAX_SCALE_BITS)
+#define COEFF_ENERGY_SENTINEL (511)
+#define SUBTYPE_TMS5100 1
+#define SUBTYPE_M58817 2
+#define SUBTYPE_TMS5110 4
+#define FIFO_SIZE 64
+#define MAX_CHIRP_SIZE 51
+
+struct tms5100_coeffs
+{
+ int subtype;
+ int num_k;
+ int energy_bits;
+ int pitch_bits;
+ int kbits[MAX_K];
+ unsigned short energytable[MAX_SCALE];
+ unsigned short pitchtable[MAX_SCALE];
+ int ktable[MAX_K][MAX_SCALE];
+ INT8 chirptable[MAX_CHIRP_SIZE];
+ INT8 interp_coeff[8];
+};
struct tms5110
{
+ /* coefficient tables */
+ const struct tms5100_coeffs *coeff;
/* these contain data that describes the 64 bits FIFO */
- #define FIFO_SIZE 64
UINT8 fifo[FIFO_SIZE];
UINT8 fifo_head;
UINT8 fifo_tail;
@@ -33,8 +99,15 @@ struct tms5110
UINT8 speak_delay_frames;
UINT8 talk_status;
+ /* Rom interface */
+ UINT32 address;
+ UINT8 next_is_address;
+ UINT8 schedule_dummy_read;
+ UINT8 addr_bit;
+ /* external callback */
int (*M0_callback)(void);
+ void (*set_load_address)(int);
/* these contain data describing the current and previous voice frames */
UINT16 old_energy;
@@ -59,13 +132,17 @@ struct tms5110
UINT8 sample_count; /* sample number within interp (0-24) */
INT32 pitch_count;
- INT32 u[11];
- INT32 x[10];
+ INT32 x[11];
INT32 RNG; /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
};
+/* Pull in the ROM tables */
+#include "tms5110r.c"
+
+
+
/* Static function prototypes */
static void parse_frame(struct tms5110 *tms);
@@ -73,13 +150,28 @@ static void parse_frame(struct tms5110 *tms);
#define DEBUG_5110 0
-void *tms5110_create(int index)
+void *tms5110_create(int index, int variant)
{
struct tms5110 *tms;
tms = malloc_or_die(sizeof(*tms));
memset(tms, 0, sizeof(*tms));
+ switch (variant)
+ {
+ case TMS5110_IS_5110A:
+ tms->coeff = &tms5110_coeff;
+ break;
+ case TMS5110_IS_5100:
+ tms->coeff = &pat4209836_coeff;
+ break;
+ case TMS5110_IS_M58817:
+ tms->coeff = &pat4403965_coeff;
+ break;
+ default:
+ fatalerror("Unknown variant in tms5110_create\n");
+ }
+
state_save_register_item_array("tms5110", index, tms->fifo);
state_save_register_item("tms5110", index, tms->fifo_head);
state_save_register_item("tms5110", index, tms->fifo_tail);
@@ -111,7 +203,11 @@ void *tms5110_create(int index)
state_save_register_item("tms5110", index, tms->sample_count);
state_save_register_item("tms5110", index, tms->pitch_count);
- state_save_register_item_array("tms5110", index, tms->u);
+ state_save_register_item("tms5110", index, tms->next_is_address);
+ state_save_register_item("tms5110", index, tms->address);
+ state_save_register_item("tms5110", index, tms->schedule_dummy_read);
+ state_save_register_item("tms5110", index, tms->addr_bit);
+
state_save_register_item_array("tms5110", index, tms->x);
state_save_register_item("tms5110", index, tms->RNG);
@@ -138,47 +234,60 @@ void tms5110_reset_chip(void *chip)
{
struct tms5110 *tms = chip;
- /* initialize the FIFO */
- memset(tms->fifo, 0, sizeof(tms->fifo));
- tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
-
- /* initialize the chip state */
- tms->speaking_now = tms->speak_delay_frames = tms->talk_status = 0;
- tms->CTL_pins = 0;
- tms->RNG = 0x1fff;
-
- /* initialize the energy/pitch/k states */
- tms->old_energy = tms->new_energy = tms->current_energy = tms->target_energy = 0;
- tms->old_pitch = tms->new_pitch = tms->current_pitch = tms->target_pitch = 0;
- memset(tms->old_k, 0, sizeof(tms->old_k));
- memset(tms->new_k, 0, sizeof(tms->new_k));
- memset(tms->current_k, 0, sizeof(tms->current_k));
- memset(tms->target_k, 0, sizeof(tms->target_k));
-
- /* initialize the sample generators */
- tms->interp_count = tms->sample_count = tms->pitch_count = 0;
- memset(tms->u, 0, sizeof(tms->u));
- memset(tms->x, 0, sizeof(tms->x));
+ /* initialize the FIFO */
+ memset(tms->fifo, 0, sizeof(tms->fifo));
+ tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
+
+ /* initialize the chip state */
+ tms->speaking_now = tms->speak_delay_frames = tms->talk_status = 0;
+ tms->CTL_pins = 0;
+ tms->RNG = 0x1fff;
+
+ /* initialize the energy/pitch/k states */
+ tms->old_energy = tms->new_energy = tms->current_energy = tms->target_energy = 0;
+ tms->old_pitch = tms->new_pitch = tms->current_pitch = tms->target_pitch = 0;
+ memset(tms->old_k, 0, sizeof(tms->old_k));
+ memset(tms->new_k, 0, sizeof(tms->new_k));
+ memset(tms->current_k, 0, sizeof(tms->current_k));
+ memset(tms->target_k, 0, sizeof(tms->target_k));
+
+ /* initialize the sample generators */
+ tms->interp_count = tms->sample_count = tms->pitch_count = 0;
+ memset(tms->x, 0, sizeof(tms->x));
+ tms->next_is_address = FALSE;
+ tms->address = 0;
+ tms->schedule_dummy_read = TRUE;
+ tms->addr_bit = 0;
}
-
/******************************************************************************************
- tms5110_set_M0_callback -- set M0 callback for the TMS5110
+ tms5110_set_M0_callback -- set M0 callback for the TMS5110
******************************************************************************************/
void tms5110_set_M0_callback(void *chip, int (*func)(void))
{
struct tms5110 *tms = chip;
- tms->M0_callback = func;
+ tms->M0_callback = func;
}
+/******************************************************************************************
+
+ tms5110_set_load_address -- set M0 callback for the TMS5110
+
+******************************************************************************************/
+
+void tms5110_set_load_address(void *chip, void (*func)(int))
+{
+ struct tms5110 *tms = chip;
+ tms->set_load_address = func;
+}
/******************************************************************************************
- FIFO_data_write -- handle bit data write to the TMS5110 (as a result of toggling M0 pin)
+ FIFO_data_write -- handle bit data write to the TMS5110 (as a result of toggling M0 pin)
******************************************************************************************/
static void FIFO_data_write(struct tms5110 *tms, int data)
@@ -201,21 +310,21 @@ static void FIFO_data_write(struct tms5110 *tms, int data)
/******************************************************************************************
- extract_bits -- extract a specific number of bits from the FIFO
+ extract_bits -- extract a specific number of bits from the FIFO
******************************************************************************************/
static int extract_bits(struct tms5110 *tms, int count)
{
- int val = 0;
-
- while (count--)
- {
- val = (val << 1) | (tms->fifo[tms->fifo_head] & 1);
- tms->fifo_count--;
- tms->fifo_head = (tms->fifo_head + 1) % FIFO_SIZE;
- }
- return val;
+ int val = 0;
+
+ while (count--)
+ {
+ val = (val << 1) | (tms->fifo[tms->fifo_head] & 1);
+ tms->fifo_count--;
+ tms->fifo_head = (tms->fifo_head + 1) % FIFO_SIZE;
+ }
+ return val;
}
static void request_bits(struct tms5110 *tms, int no)
@@ -235,25 +344,29 @@ int i;
static void perform_dummy_read(struct tms5110 *tms)
{
- if (tms->M0_callback)
+ if (tms->schedule_dummy_read)
{
- int data = (*tms->M0_callback)();
- if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data&1);
+ if (tms->M0_callback)
+ {
+ int data = (*tms->M0_callback)();
+ if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data&1);
+ }
+ else
+ if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
+ tms->schedule_dummy_read = FALSE;
}
- else
- if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
}
/**********************************************************************************************
- tms5110_status_read -- read status from the TMS5110
+ tms5110_status_read -- read status from the TMS5110
- 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.
- It goes inactive (low) when the stop code (Energy=1111) is processed, or
- immediately(?????? not TMS5110) by a RESET command.
- TMS5110 datasheets mention this is only available as a result of executing
- TEST TALK command.
+ 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.
+ It goes inactive (low) when the stop code (Energy=1111) is processed, or
+ immediately(?????? not TMS5110) by a RESET command.
+ TMS5110 datasheets mention this is only available as a result of executing
+ TEST TALK command.
***********************************************************************************************/
@@ -261,175 +374,178 @@ static void perform_dummy_read(struct tms5110 *tms)
int tms5110_status_read(void *chip)
{
struct tms5110 *tms = chip;
- if (DEBUG_5110) logerror("Status read: TS=%d\n", tms->talk_status);
+ if (DEBUG_5110) logerror("Status read: TS=%d\n", tms->talk_status);
- return (tms->talk_status << 0); /*CTL1 = still talking ? */
+ return (tms->talk_status << 0); /*CTL1 = still talking ? */
}
/**********************************************************************************************
- tms5110_ready_read -- returns the ready state of the TMS5110
+ tms5110_ready_read -- returns the ready state of the TMS5110
***********************************************************************************************/
int tms5110_ready_read(void *chip)
{
struct tms5110 *tms = chip;
- return (tms->fifo_count < FIFO_SIZE-1);
+ return (tms->fifo_count < FIFO_SIZE-1);
}
/**********************************************************************************************
- tms5110_process -- fill the buffer with a specific number of samples
+ tms5110_process -- fill the buffer with a specific number of samples
***********************************************************************************************/
void tms5110_process(void *chip, INT16 *buffer, unsigned int size)
{
struct tms5110 *tms = chip;
- int buf_count=0;
- int i, interp_period, cliptemp;
-
- /* if we're not speaking, fill with nothingness */
- if (!tms->speaking_now)
- goto empty;
-
- /* if we're to speak, but haven't started */
- if (!tms->talk_status)
- {
-
- /* a "dummy read" is mentioned in the tms5200 datasheet */
- /* The Bagman speech roms data are organized in such a way that
- ** the bit at address 0 is NOT a speech data. The bit at address 1
- ** is the speech data. It seems that the tms5110 performs a dummy read
- ** just before it executes a SPEAK command.
- */
- perform_dummy_read(tms);
-
- /* clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) */
- tms->new_energy = 0;
- tms->new_pitch = 0;
- for (i = 0; i < 10; i++)
- tms->new_k[i] = 0;
-
- tms->talk_status = 1;
- }
-
-
- /* loop until the buffer is full or we've stopped speaking */
- while ((size > 0) && tms->speaking_now)
- {
- int current_val;
-
- /* if we're ready for a new frame */
- if ((tms->interp_count == 0) && (tms->sample_count == 0))
- {
-
- /* remember previous frame */
- tms->old_energy = tms->new_energy;
- tms->old_pitch = tms->new_pitch;
- for (i = 0; i < 10; i++)
- tms->old_k[i] = tms->new_k[i];
-
-
- /* if the old frame was a stop frame, exit and do not process any more frames */
- if (tms->old_energy == energytable[15])
- {
- /*if (DEBUG_5110) logerror("processing frame: stop frame\n");*/
- tms->target_energy = tms->current_energy = 0;
- tms->speaking_now = tms->talk_status = 0;
- tms->interp_count = tms->sample_count = tms->pitch_count = 0;
- goto empty;
- }
-
-
- /* Parse a new frame into the new_energy, new_pitch and new_k[] */
- parse_frame(tms);
-
-
- /* Set old target as new start of frame */
- tms->current_energy = tms->old_energy;
- tms->current_pitch = tms->old_pitch;
- for (i = 0; i < 10; i++)
- tms->current_k[i] = tms->old_k[i];
-
-
- /* is this the stop (ramp down) frame? */
- if (tms->new_energy == energytable[15])
- {
- /*logerror("processing frame: ramp down\n");*/
- tms->target_energy = 0;
- tms->target_pitch = tms->old_pitch;
- for (i = 0; i < 10; i++)
- tms->target_k[i] = tms->old_k[i];
- }
- else if ((tms->old_energy == 0) && (tms->new_energy != 0)) /* was the old frame a zero-energy frame? */
- {
- /* if so, and if the new frame is non-zero energy frame then the new parameters
- should become our current and target parameters immediately,
- i.e. we should NOT interpolate them slowly in.
- */
-
- /*logerror("processing non-zero energy frame after zero-energy frame\n");*/
- tms->target_energy = tms->new_energy;
- tms->target_pitch = tms->current_pitch = tms->new_pitch;
- for (i = 0; i < 10; i++)
- tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
- }
- else if ((tms->old_pitch == 0) && (tms->new_pitch != 0)) /* is this a change from unvoiced to voiced frame ? */
- {
- /* if so, then the new parameters should become our current and target parameters immediately,
- i.e. we should NOT interpolate them slowly in.
- */
- /*if (DEBUG_5110) logerror("processing frame: UNVOICED->VOICED frame change\n");*/
- tms->target_energy = tms->new_energy;
- tms->target_pitch = tms->current_pitch = tms->new_pitch;
- for (i = 0; i < 10; i++)
- tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
- }
- else if ((tms->old_pitch != 0) && (tms->new_pitch == 0)) /* is this a change from voiced to unvoiced frame ? */
- {
- /* if so, then the new parameters should become our current and target parameters immediately,
- i.e. we should NOT interpolate them slowly in.
- */
- /*if (DEBUG_5110) logerror("processing frame: VOICED->UNVOICED frame change\n");*/
- tms->target_energy = tms->new_energy;
- tms->target_pitch = tms->current_pitch = tms->new_pitch;
- for (i = 0; i < 10; i++)
- tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
- }
- else
- {
- /*logerror("processing frame: Normal\n");*/
- /*logerror("*** Energy = %d\n",current_energy);*/
- /*logerror("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
-
- tms->target_energy = tms->new_energy;
- tms->target_pitch = tms->new_pitch;
- for (i = 0; i < 10; i++)
- tms->target_k[i] = tms->new_k[i];
- }
- }
- else if (tms->interp_count == 0)
- {
- /* interpolate (update) values based on step values */
- /*logerror("\n");*/
-
- interp_period = tms->sample_count / 25;
- tms->current_energy += (tms->target_energy - tms->current_energy) / interp_coeff[interp_period];
- tms->current_pitch += (tms->target_pitch - tms->current_pitch) / interp_coeff[interp_period];
-
- /*logerror("*** Energy = %d\n",current_energy);*/
-
- for (i = 0; i < 10; i++)
- {
- tms->current_k[i] += (tms->target_k[i] - tms->current_k[i]) / interp_coeff[interp_period];
- }
- }
+ int buf_count=0;
+ int i, interp_period;
+ INT16 Y11, cliptemp;
+
+ /* if we're not speaking, fill with nothingness */
+ if (!tms->speaking_now)
+ goto empty;
+
+ /* if we're to speak, but haven't started */
+ if (!tms->talk_status)
+ {
+
+ /* a "dummy read" is mentioned in the tms5200 datasheet */
+ /* The Bagman speech roms data are organized in such a way that
+ ** the bit at address 0 is NOT a speech data. The bit at address 1
+ ** is the speech data. It seems that the tms5110 performs a dummy read
+ ** just before it executes a SPEAK command.
+ ** This has been moved to command logic ...
+ ** perform_dummy_read(tms);
+ */
+
+ /* clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) */
+ tms->new_energy = 0;
+ tms->new_pitch = 0;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->new_k[i] = 0;
+
+ tms->talk_status = 1;
+ }
+
+
+ /* loop until the buffer is full or we've stopped speaking */
+ while ((size > 0) && tms->speaking_now)
+ {
+ int current_val;
+
+ /* if we're ready for a new frame */
+ if ((tms->interp_count == 0) && (tms->sample_count == 0))
+ {
+
+ /* remember previous frame */
+ tms->old_energy = tms->new_energy;
+ tms->old_pitch = tms->new_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->old_k[i] = tms->new_k[i];
+
+
+ /* if the old frame was a stop frame, exit and do not process any more frames */
+ if (tms->old_energy == COEFF_ENERGY_SENTINEL)
+ {
+ /*if (DEBUG_5110) logerror("processing frame: stop frame\n");*/
+ tms->target_energy = tms->current_energy = 0;
+ tms->speaking_now = tms->talk_status = 0;
+ tms->interp_count = tms->sample_count = tms->pitch_count = 0;
+ goto empty;
+ }
+
+
+ /* Parse a new frame into the new_energy, new_pitch and new_k[] */
+ parse_frame(tms);
+
+
+ /* Set old target as new start of frame */
+ tms->current_energy = tms->old_energy;
+ tms->current_pitch = tms->old_pitch;
+
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->current_k[i] = tms->old_k[i];
+
+
+ /* is this the stop (ramp down) frame? */
+ if (tms->new_energy == COEFF_ENERGY_SENTINEL)
+ {
+ /*logerror("processing frame: ramp down\n");*/
+ tms->target_energy = 0;
+ tms->target_pitch = tms->old_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->target_k[i] = tms->old_k[i];
+ }
+ else if ((tms->old_energy == 0) && (tms->new_energy != 0)) /* was the old frame a zero-energy frame? */
+ {
+ /* if so, and if the new frame is non-zero energy frame then the new parameters
+ should become our current and target parameters immediately,
+ i.e. we should NOT interpolate them slowly in.
+ */
+
+ /*logerror("processing non-zero energy frame after zero-energy frame\n");*/
+ tms->target_energy = tms->new_energy;
+ tms->target_pitch = tms->current_pitch = tms->new_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
+ }
+ else if ((tms->old_pitch == 0) && (tms->new_pitch != 0)) /* is this a change from unvoiced to voiced frame ? */
+ {
+ /* if so, then the new parameters should become our current and target parameters immediately,
+ i.e. we should NOT interpolate them slowly in.
+ */
+ /*if (DEBUG_5110) logerror("processing frame: UNVOICED->VOICED frame change\n");*/
+ tms->target_energy = tms->new_energy;
+ tms->target_pitch = tms->current_pitch = tms->new_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
+ }
+ else if ((tms->old_pitch != 0) && (tms->new_pitch == 0)) /* is this a change from voiced to unvoiced frame ? */
+ {
+ /* if so, then the new parameters should become our current and target parameters immediately,
+ i.e. we should NOT interpolate them slowly in.
+ */
+ /*if (DEBUG_5110) logerror("processing frame: VOICED->UNVOICED frame change\n");*/
+ tms->target_energy = tms->new_energy;
+ tms->target_pitch = tms->current_pitch = tms->new_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
+ }
+ else
+ {
+ /*logerror("processing frame: Normal\n");*/
+ /*logerror("*** Energy = %d\n",current_energy);*/
+ /*logerror("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
+
+ tms->target_energy = tms->new_energy;
+ tms->target_pitch = tms->new_pitch;
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->target_k[i] = tms->new_k[i];
+ }
+ }
+ else if (tms->interp_count == 0)
+ {
+ /* interpolate (update) values based on step values */
+ /*logerror("\n");*/
+
+ interp_period = tms->sample_count / 25;
+ tms->current_energy += (tms->target_energy - tms->current_energy) / tms->coeff->interp_coeff[interp_period];
+ tms->current_pitch += (tms->target_pitch - tms->current_pitch) / tms->coeff->interp_coeff[interp_period];
+
+ /*logerror("*** Energy = %d\n",current_energy);*/
+
+ for (i = 0; i < tms->coeff->num_k; i++)
+ {
+ tms->current_k[i] += (tms->target_k[i] - tms->current_k[i]) / tms->coeff->interp_coeff[interp_period];
+ }
+ }
@@ -437,92 +553,108 @@ void tms5110_process(void *chip, INT16 *buffer, unsigned int size)
/* calculate the output */
- if (tms->current_energy == 0)
- {
- /* generate silent samples here */
- current_val = 0x00;
- }
- else if (tms->old_pitch == 0)
- {
- int bitout, randbit;
+ if (tms->current_energy == 0)
+ {
+ /* generate silent samples here */
+ current_val = 0x00;
+ }
+ else if (tms->old_pitch == 0)
+ {
+ int bitout, randbit;
+
+ /* generate unvoiced samples here */
+ if (tms->RNG&1)
+ randbit = -64; /* according to the patent it is (either + or -) half of the maximum value in the chirp table */
+ else
+ randbit = 64;
+
+ bitout = ((tms->RNG>>12)&1) ^
+ ((tms->RNG>>10)&1) ^
+ ((tms->RNG>> 9)&1) ^
+ ((tms->RNG>> 0)&1);
+ tms->RNG >>= 1;
+ tms->RNG |= (bitout<<12);
+
+ current_val = randbit;
+ }
+ else
+ {
+ /* generate voiced samples here */
+ if (tms->coeff->subtype & (SUBTYPE_TMS5100 | SUBTYPE_M58817))
+ {
+ if (tms->pitch_count > 50)
+ current_val = 0;
+ else
+ current_val = tms->coeff->chirptable[tms->pitch_count];
- /* generate unvoiced samples here */
- if (tms->RNG&1)
- randbit = -64; /* according to the patent it is (either + or -) half of the maximum value in the chirp table */
- else
- randbit = 64;
+ }
+ else
+ current_val = (tms->coeff->chirptable[tms->pitch_count%sizeof(tms->coeff->chirptable)]);
+ }
- bitout = ((tms->RNG>>12)&1) ^
- ((tms->RNG>>10)&1) ^
- ((tms->RNG>> 9)&1) ^
- ((tms->RNG>> 0)&1);
- tms->RNG >>= 1;
- tms->RNG |= (bitout<<12);
- current_val = (randbit * tms->current_energy) / 256;
- }
- else
- {
- /* generate voiced samples here */
- current_val = (chirptable[tms->pitch_count%sizeof(chirptable)] * tms->current_energy) / 256;
- }
+ /* Lattice filter here */
+ Y11 = (current_val * 64 * tms->current_energy) / 512;
- /* Lattice filter here */
+ for (i = tms->coeff->num_k - 1; i >= 0; i--)
+ {
+ Y11 = Y11 - ((tms->current_k[i] * tms->x[i]) / 512);
+ tms->x[i+1] = tms->x[i] + ((tms->current_k[i] * Y11) / 512);
+ }
- tms->u[10] = current_val;
+ tms->x[0] = Y11;
- for (i = 9; i >= 0; i--)
- {
- tms->u[i] = tms->u[i+1] - ((tms->current_k[i] * tms->x[i]) / 32768);
- }
- for (i = 9; i >= 1; i--)
- {
- tms->x[i] = tms->x[i-1] + ((tms->current_k[i-1] * tms->u[i-1]) / 32768);
- }
- tms->x[0] = tms->u[0];
+ /* clipping & wrapping, just like the patent */
+ /* YL10 - YL4 ==> DA6 - DA0 */
+ cliptemp = Y11 / 16;
- /* clipping & wrapping, just like the patent */
+ /* M58817 seems to be different */
+ if (tms->coeff->subtype & (SUBTYPE_M58817))
+ cliptemp = cliptemp / 2;
- cliptemp = tms->u[0];
- if (cliptemp > 2047) cliptemp = -2048 + (cliptemp-2047);
- else if (cliptemp < -2048) cliptemp = 2047 - (cliptemp+2048);
+ if (cliptemp > 511) cliptemp = -512 + (cliptemp-511);
+ else if (cliptemp < -512) cliptemp = 511 - (cliptemp+512);
- if (cliptemp > 511)
- buffer[buf_count] = 127<<8;
- else if (cliptemp < -512)
- buffer[buf_count] = -128<<8;
- else
- buffer[buf_count] = cliptemp << 6;
+ if (cliptemp > 127)
+ buffer[buf_count] = 127*256;
+ else if (cliptemp < -128)
+ buffer[buf_count] = -128*256;
+ else
+ buffer[buf_count] = cliptemp *256;
- /* Update all counts */
+ /* Update all counts */
- tms->sample_count = (tms->sample_count + 1) % 200;
+ tms->sample_count = (tms->sample_count + 1) % 200;
- if (tms->current_pitch != 0)
- tms->pitch_count = (tms->pitch_count + 1) % tms->current_pitch;
- else
- tms->pitch_count = 0;
+ if (tms->current_pitch != 0)
+ {
+ tms->pitch_count++;
+ if (tms->pitch_count >= tms->current_pitch)
+ tms->pitch_count = 0;
+ }
+ else
+ tms->pitch_count = 0;
- tms->interp_count = (tms->interp_count + 1) % 25;
+ tms->interp_count = (tms->interp_count + 1) % 25;
- buf_count++;
- size--;
- }
+ buf_count++;
+ size--;
+ }
empty:
- while (size > 0)
- {
- tms->sample_count = (tms->sample_count + 1) % 200;
- tms->interp_count = (tms->interp_count + 1) % 25;
+ while (size > 0)
+ {
+ tms->sample_count = (tms->sample_count + 1) % 200;
+ tms->interp_count = (tms->interp_count + 1) % 25;
- buffer[buf_count] = 0x00;
- buf_count++;
- size--;
- }
+ buffer[buf_count] = 0x00;
+ buf_count++;
+ size--;
+ }
}
@@ -530,7 +662,7 @@ empty:
/******************************************************************************************
- CTL_set -- set CTL pins named CTL1, CTL2, CTL4 and CTL8
+ CTL_set -- set CTL pins named CTL1, CTL2, CTL4 and CTL8
******************************************************************************************/
@@ -540,10 +672,9 @@ void tms5110_CTL_set(void *chip, int data)
tms->CTL_pins = data & 0xf;
}
-
/******************************************************************************************
- PDC_set -- set Processor Data Clock. Execute CTL_pins command on hi-lo transition.
+ PDC_set -- set Processor Data Clock. Execute CTL_pins command on hi-lo transition.
******************************************************************************************/
@@ -556,23 +687,50 @@ void tms5110_PDC_set(void *chip, int data)
if (tms->PDC == 0) /* toggling 1->0 processes command on CTL_pins */
{
/* the only real commands we handle now are SPEAK and RESET */
-
- switch (tms->CTL_pins & 0xe) /*CTL1 - don't care*/
+ if (tms->next_is_address)
{
- case TMS5110_CMD_SPEAK:
- tms->speaking_now = 1;
-
- //should FIFO be cleared now ?????
-
- break;
-
- case TMS5110_CMD_RESET:
- tms->speaking_now = 0;
- tms->talk_status = 0;
- break;
+ tms->next_is_address = FALSE;
+ tms->address = tms->address | ((tms->CTL_pins & 0x0F)<<tms->addr_bit);
+ tms->addr_bit = (tms->addr_bit + 4) % 12;
+ tms->schedule_dummy_read = TRUE;
+ if (tms->set_load_address)
+ tms->set_load_address(tms->address);
+ }
+ else
+ {
+ switch (tms->CTL_pins & 0xe) /*CTL1 - don't care*/
+ {
+ case TMS5110_CMD_SPEAK:
+ perform_dummy_read(tms);
+ tms->speaking_now = 1;
+
+ //should FIFO be cleared now ?????
+ break;
+
+ case TMS5110_CMD_RESET:
+ perform_dummy_read(tms);
+ tms5110_reset_chip(tms);
+ break;
+
+ case TMS5110_CMD_READ_BIT:
+ if (tms->schedule_dummy_read)
+ perform_dummy_read(tms);
+ else
+ {
+ request_bits(tms, 1);
+ tms->CTL_pins = (tms->CTL_pins & 0x0E) | extract_bits(tms, 1);
+ }
+ break;
+
+ case TMS5110_CMD_LOAD_ADDRESS:
+ tms->next_is_address = TRUE;
+ break;
+
+ default:
+ logerror("tms5110.c: unknown command: 0x%02x\n", tms->CTL_pins);
+ break;
+ }
- default:
- break;
}
}
}
@@ -582,126 +740,129 @@ void tms5110_PDC_set(void *chip, int data)
/******************************************************************************************
- parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer
+ parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer
******************************************************************************************/
static void parse_frame(struct tms5110 *tms)
{
- int bits, indx, i, rep_flag;
+ int bits, indx, i, rep_flag, ene;
- /* count the total number of bits available */
- bits = tms->fifo_count;
+ /* count the total number of bits available */
+ bits = tms->fifo_count;
- /* attempt to extract the energy index */
- bits -= 4;
- if (bits < 0)
- {
- request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
- bits = 0;
- }
- indx = extract_bits(tms,4);
- tms->new_energy = energytable[indx];
-
+ /* attempt to extract the energy index */
+ bits -= tms->coeff->energy_bits;
+ if (bits < 0)
+ {
+ request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
+ bits = 0;
+ }
+ indx = extract_bits(tms,tms->coeff->energy_bits);
+ tms->new_energy = tms->coeff->energytable[indx];
+ ene = indx;
- /* if the energy index is 0 or 15, we're done */
+ /* if the energy index is 0 or 15, we're done */
- if ((indx == 0) || (indx == 15))
- {
- if (DEBUG_5110) logerror(" (4-bit energy=%d frame)\n",tms->new_energy);
+ if ((indx == 0) || (indx == 15))
+ {
+ if (DEBUG_5110) logerror(" (4-bit energy=%d frame)\n",tms->new_energy);
/* clear the k's */
- if (indx == 0)
- {
- for (i = 0; i < 10; i++)
- tms->new_k[i] = 0;
+ if (indx == 0)
+ {
+ for (i = 0; i < tms->coeff->num_k; i++)
+ tms->new_k[i] = 0;
+ }
+
+ /* clear fifo if stop frame encountered */
+ if (indx == 15)
+ {
+ if (DEBUG_5110) logerror(" (4-bit energy=%d STOP frame)\n",tms->new_energy);
+ tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
+ }
+ return;
}
- /* clear fifo if stop frame encountered */
- if (indx == 15)
- {
- if (DEBUG_5110) logerror(" (4-bit energy=%d STOP frame)\n",tms->new_energy);
- tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
- //speaking_now = talk_status = 0;
- }
- return;
- }
-
-
- /* attempt to extract the repeat flag */
- bits -= 1;
- if (bits < 0)
- {
- request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
- bits = 0;
- }
- rep_flag = extract_bits(tms,1);
-
- /* attempt to extract the pitch */
- bits -= 5;
- if (bits < 0)
- {
- request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
- bits = 0;
- }
- indx = extract_bits(tms,5);
- tms->new_pitch = pitchtable[indx];
-
-
- /* if this is a repeat frame, just copy the k's */
- if (rep_flag)
- {
+
+ /* attempt to extract the repeat flag */
+ bits -= 1;
+ if (bits < 0)
+ {
+ request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
+ bits = 0;
+ }
+ rep_flag = extract_bits(tms,1);
+
+ /* attempt to extract the pitch */
+ bits -= tms->coeff->pitch_bits;
+ if (bits < 0)
+ {
+ request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
+ bits = 0;
+ }
+ indx = extract_bits(tms,tms->coeff->pitch_bits);
+ tms->new_pitch = tms->coeff->pitchtable[indx];
+
+ /* if this is a repeat frame, just copy the k's */
+ if (rep_flag)
+ {
//actually, we do nothing because the k's were already loaded (on parsing the previous frame)
- if (DEBUG_5110) logerror(" (10-bit energy=%d pitch=%d rep=%d frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
- return;
- }
+ if (DEBUG_5110) logerror(" (10-bit energy=%d pitch=%d rep=%d frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
+ return;
+ }
- /* if the pitch index was zero, we need 4 k's */
- if (indx == 0)
- {
- /* attempt to extract 4 K's */
- bits -= 18;
- if (bits < 0)
- {
+ /* if the pitch index was zero, we need 4 k's */
+ if (indx == 0)
+ {
+ /* attempt to extract 4 K's */
+ bits -= 18;
+ if (bits < 0)
+ {
request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
bits = 0;
- }
- tms->new_k[0] = k1table[extract_bits(tms,5)];
- tms->new_k[1] = k2table[extract_bits(tms,5)];
- tms->new_k[2] = k3table[extract_bits(tms,4)];
- tms->new_k[3] = k4table[extract_bits(tms,4)];
+ }
+ for (i = 0; i < 4; i++)
+ tms->new_k[i] = tms->coeff->ktable[i][extract_bits(tms,tms->coeff->kbits[i])];
/* and clear the rest of the new_k[] */
- for (i = 4; i < 10; i++)
- tms->new_k[i] = 0;
-
- if (DEBUG_5110) logerror(" (28-bit energy=%d pitch=%d rep=%d 4K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
- return;
- }
-
- /* else we need 10 K's */
- bits -= 39;
- if (bits < 0)
- {
- request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
+ for (i = 4; i < tms->coeff->num_k; i++)
+ tms->new_k[i] = 0;
+
+ if (DEBUG_5110) logerror(" (28-bit energy=%d pitch=%d rep=%d 4K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
+ return;
+ }
+
+ /* else we need 10 K's */
+ bits -= 39;
+ if (bits < 0)
+ {
+ request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
bits = 0;
- }
- tms->new_k[0] = k1table[extract_bits(tms,5)];
- tms->new_k[1] = k2table[extract_bits(tms,5)];
- tms->new_k[2] = k3table[extract_bits(tms,4)];
- tms->new_k[3] = k4table[extract_bits(tms,4)];
- tms->new_k[4] = k5table[extract_bits(tms,4)];
- tms->new_k[5] = k6table[extract_bits(tms,4)];
- tms->new_k[6] = k7table[extract_bits(tms,4)];
- tms->new_k[7] = k8table[extract_bits(tms,3)];
- tms->new_k[8] = k9table[extract_bits(tms,3)];
- tms->new_k[9] = k10table[extract_bits(tms,3)];
-
- if (DEBUG_5110) logerror(" (49-bit energy=%d pitch=%d rep=%d 10K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
+ }
+#if (DEBUG_5110)
+ printf("FrameDump %02d ", ene);
+ for (i = 0; i < tms->coeff->num_k; i++)
+ {
+ int x;
+ x = extract_bits(tms, tms->coeff->kbits[i]);
+ tms->new_k[i] = tms->coeff->ktable[i][x];
+ printf("%02d ", x);
+ }
+ printf("\n");
+#else
+ for (i = 0; i < tms->coeff->num_k; i++)
+ {
+ int x;
+ x = extract_bits(tms, tms->coeff->kbits[i]);
+ tms->new_k[i] = tms->coeff->ktable[i][x];
+ }
+#endif
+ if (DEBUG_5110) logerror(" (49-bit energy=%d pitch=%d rep=%d 10K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
}
diff --git a/src/emu/sound/tms5110.h b/src/emu/sound/tms5110.h
index faaba5375a2..63ec60dca47 100644
--- a/src/emu/sound/tms5110.h
+++ b/src/emu/sound/tms5110.h
@@ -13,12 +13,19 @@
#define TMS5110_CMD_READ_BRANCH (12) /* 1 1 0 x | 1 */
#define TMS5110_CMD_TEST_TALK (14) /* 1 1 1 x | 3 */
+/* Variants */
-void *tms5110_create(int index);
+#define TMS5110_IS_5110A (1)
+#define TMS5110_IS_5100 (2)
+#define TMS5110_IS_M58817 (3)
+
+
+void *tms5110_create(int index, int variant);
void tms5110_destroy(void *chip);
void tms5110_reset_chip(void *chip);
void tms5110_set_M0_callback(void *chip, int (*func)(void));
+void tms5110_set_load_address(void *chip, void (*func)(int));
void tms5110_CTL_set(void *chip, int data);
void tms5110_PDC_set(void *chip, int data);
diff --git a/src/emu/sound/tms5110r.c b/src/emu/sound/tms5110r.c
index 7e0040cf839..76d2d3ebcca 100644
--- a/src/emu/sound/tms5110r.c
+++ b/src/emu/sound/tms5110r.c
@@ -1,136 +1,234 @@
/* TMS5110 ROM Tables */
-/* Note: all the tables in this file were read from the real TMS5110A chip, except
- for the chirptable and the interp_coeff
-*/
-
-
-/* This is the energy lookup table (4-bits -> 10-bits) */
-const static unsigned short energytable[0x10] = {
-0*2, 1*2, 2*2, 3*2,
-4*2, 6*2, 8*2, 11*2,
-16*2, 23*2, 33*2, 47*2,
-63*2, 85*2, 114*2, 511 }; /*note: the last value (511) is not a true energy value, it's just a stop-sentinel */
-
-
-/* This is the tms5110 pitchtable */
-const static unsigned short pitchtable [0x20]={
-0, 15, 16, 17,
-19, 21, 22, 25,
-26, 29, 32, 36,
-40, 42, 46, 50,
-55, 60, 64, 68,
-72, 76, 80, 84,
-86, 93, 101, 110,
-120, 132, 144, 159 };
-
-
-/* These are the reflection coefficient lookup tables */
-
-/* K1 is (5-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k1table[0x20] = {
--501*64, -498*64, -497*64, -495*64,
--493*64, -491*64, -488*64, -482*64,
--478*64, -474*64, -469*64, -464*64,
--459*64, -452*64, -445*64, -437*64,
--412*64, -380*64, -339*64, -288*64,
--227*64, -158*64, -81*64, -1*64,
- 80*64, 157*64, 226*64, 287*64,
- 337*64, 379*64, 411*64, 436*64 };
-
-/* K2 is (5-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k2table[0x20] = {
--328*64, -303*64, -274*64, -244*64,
--211*64, -175*64, -138*64, -99*64,
- -59*64, -18*64, 24*64, 64*64,
- 105*64, 143*64, 180*64, 215*64,
- 248*64, 278*64, 306*64, 331*64,
- 354*64, 374*64, 392*64, 408*64,
- 422*64, 435*64, 445*64, 455*64,
- 463*64, 470*64, 476*64, 506*64 };
-
-/* K3 is (4-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k3table[0x10] = {
--441*64, -387*64, -333*64, -279*64,
--225*64, -171*64, -117*64, -63*64,
- -9*64, 45*64, 98*64, 152*64,
- 206*64, 260*64, 314*64, 368*64 };
-
-/* K4 is (4-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k4table[0x10] = {
--328*64, -273*64, -217*64, -161*64,
--106*64, -50*64, 5*64, 61*64,
- 116*64, 172*64, 228*64, 283*64,
- 339*64, 394*64, 450*64, 506*64 };
-
-/* K5 is (4-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k5table[0x10] = {
--328*64, -282*64, -235*64, -189*64,
--142*64, -96*64, -50*64, -3*64,
- 43*64, 90*64, 136*64, 182*64,
- 229*64, 275*64, 322*64, 368*64 };
-
-/* K6 is (4-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k6table[0x10] = {
--256*64, -212*64, -168*64, -123*64,
- -79*64, -35*64, 10*64, 54*64,
- 98*64, 143*64, 187*64, 232*64,
- 276*64, 320*64, 365*64, 409*64 };
-
-/* K7 is (4-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k7table[0x10] = {
--308*64, -260*64, -212*64, -164*64,
--117*64, -69*64, -21*64, 27*64,
- 75*64, 122*64, 170*64, 218*64,
- 266*64, 314*64, 361*64, 409*64 };
-
-/* K8 is (3-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k8table[0x08] = {
--256*64, -161*64, -66*64, 29*64,
- 124*64, 219*64, 314*64, 409*64 };
-
-/* K9 is (3-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
-
-const static int k9table[0x08] = {
--256*64, -176*64, -96*64, -15*64,
- 65*64, 146*64, 226*64, 307*64 };
+/* Kx is (5-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
+
+/* The following table is assumed to be for TMS5100
+ *
+ * US Patent 4209836
+ * 4331836
+ * 4304964
+ * 4234761
+ * 4189779
+ * 4449233
+ *
+ * All patents give interpolation coefficients
+ * { 8, 8, 8, 4, 4, 2, 2, 1 }
+ * This sequence will not calculate the published
+ * fractions:
+ * 1 8 0.125
+ * 2 8 0.234
+ * 3 8 0.330
+ * 4 4 0.498
+ * 5 4 0.623
+ * 6 2 0.717
+ * 7 2 0.859
+ * 0 1 1.000
+ *
+ * Instead, { 8, 8, 8, 4, 4, 4, 2, 1 }
+ * will calculate those coefficients and this has been used below.
+ */
+
+static const struct tms5100_coeffs pat4209836_coeff =
+{
+ /* subtype */
+ SUBTYPE_TMS5100,
+ 10,
+ 4,
+ 5,
+ { 5, 5, 4, 4, 4, 4, 4, 3, 3, 3 },
+ /* E */
+ { 0, 0, 1, 1, 2, 3, 5, 7, 10, 15, 21, 31, 43, 61, 86, 511 },
+ /* P */
+ { 0, 41, 43, 45, 47, 49, 51, 53,
+ 55, 58, 60, 63, 66, 70, 73, 76,
+ 79, 83, 87, 90, 94, 99, 103, 104,
+ 112, 118, 120, 129, 134, 140, 147, 153 },
+ {
+ /* K1 */
+ { -504, -497, -493, -488, -471, -471, -460, -446,
+ -427, -405, -378, -344, -501, -259, -206, -148,
+ -86, -5, 45, 110, 168, 131, 277, 320,
+ 357, 388, 413, 434, 451, 464, 474, 482 },
+ /* K2 */
+ { -349, -376, -305, -264, -252, -223, -192, -158,
+ -124, -88, -51, -14, 23, 60, 97, 133,
+ 167, 215, 230, 259, 286, 310, 333, 354,
+ 372, 389, 404, 417, 429, 439, 449, 506 },
+ /* K3 */
+ { -397, -365, -327, -266, -229, -170, -104, -36,
+ 35, 104, 169, 228, 281, 326, 364, 396 },
+ /* K4 */
+ { -369, -334, -296, -246, -191, -131, -67, -1,
+ 64, 128, 188, 243, 291, 332, 367, 397 },
+ /* K5 */
+ { -319, -286, -250, -211, -168, -122, -74, -25,
+ 24, 73, 121, 167, 210, 249, 285, 318 },
+ /* K6 */
+ { -290, -252, -209, -163, -114, -62, -9, 44,
+ 97, 147, 194, 255, 278, 313, 344, 371 },
+ /* K7 */
+ { -291, -256, -216, -174, -128, -96, -31, 19,
+ 69, 117, 163, 206, 246, 280, 316, 345 },
+ /* K8 */
+ { -218, -133, -38, 56, 152, 251, 305, 361 },
+ /* K9 */
+ { -225, -157, -82, -3, 76, 151, 220, 280 },
+ /* K10 */
+ { -179, -122, -61, 1, 62, 123, 179, 247 },
+ },
+ /* Chirptable */
+ { 0, 42, -44, 50, -78, 18, 37, 20,
+ 2, -31, -59, 2, 95, 90, 5, 15,
+ 38, -4, -91,-91, -42,-35,-36, -4,
+ 37, 43, 34, 33, 15, -1, -8,-18,
+ -19,-17, -9,-10, -6, 0, 3, 2,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ /* interpolation coefficients */
+ { 8, 8, 8, 4, 4, 4, 2, 1 }
+};
-/* K10 is (3-bits -> 9 bits+sign, 2's comp. fractional (-1 < x < 1) */
+/*
+ * This table is from patent 4403965
+ * also listed in 4331836
+ * also listed in 4946391
+ *
+ * Works best with M58817 ...
+ */
+
+static const struct tms5100_coeffs pat4403965_coeff =
+{
+ /* subtype */
+ SUBTYPE_M58817,
+ 10,
+ 4,
+ 5,
+ { 5, 5, 4, 4, 4, 4, 4, 3, 3, 3 },
+ /* E */
+ { 0,1,2,3,4,6,8,11,16,23,33,47,63,85,114,511, },
+ /* P */
+ { 0,41,43,45,47,49,51,53,55,58,60,63,66,70,73,76,79,83,87,90,94,99,103,107,112,118,123,129,134,140,147,153,
+ },
+ {
+ /* K1 */
+ {
+ -501,-498,-495,-490,-485,-478,-469,-459,-446,-431,-412,-389,-362,-331,-295,-253,-207,-156,-102,-45,13,70,126,179,228,272,311,345,374,399,420,437,
+ },
+ /* K2 */
+ {
+ -376,-357,-335,-312,-286,-258,-227,-195,-161,-124,-87,-49,-10,29,68,106,143,178,212,243,272,299,324,346,366,384,400,414,427,438,448,506,
+ },
+ /* K3 */
+ {
+ -407,-381,-349,-311,-268,-218,-162,-102,-39,25,89,149,206,257,302,341,
+ },
+ /* K4 */
+ {
+ -290,-252,-209,-163,-114,-62,-9,44,97,147,194,238,278,313,344,371,
+ },
+ /* K5 */
+ {
+ -318,-283,-245,-202,-156,-107,-56,-3,49,101,150,196,239,278,313,344,
+ },
+ /* K6 */
+ {
+ -193,-152,-109,-65,-20,26,71,115,158,198,235,270,301,330,355,377,
+ },
+ /* K7 */
+ {
+ -254,-218,-180,-140,-97,-53,-8,36,81,124,165,204,240,274,304,332,
+ },
+ /* K8 */
+ {
+ -205,-112,-10,92,187,269,336,387,
+ },
+ /* K9 */
+ {
+ -249,-183,-110,-19,48,126,198,261,
+ },
+ /* K10 */
+ {
+ -190,-133,-73,-10,53,115,173,227,
+ },
+ },
+ /* Chirptable */
+ { 0,43,-44,51,-77,18,37,20,
+ 2,-30,-58,3,96,91,5,15,
+ 38,-4,-90,-91,-42,-35,-35,-3,
+ 37,43,35,34,15,-1,-8,-17,
+ -19,-17,-9,-9,-6,1,4,3,
+ 1,0,0,0,0,0,0,0,
+ 0,0,0
+ },
+ /* interpolation coefficients */
+ { 8, 8, 8, 4, 4, 4, 2, 1 }
+};
-const static int k10table[0x08] = {
--205*64, -132*64, -59*64, 14*64,
- 87*64, 160*64, 234*64, 307*64 };
+/* Note: the following tables in this file were read from the real TMS5110A chip, except
+ for the chirptable and the interp_coeff
+*/
-/* chirp table */
-const static signed char chirptable[51] = {
-0x00, 0x2a, (char)0xd4, 0x32,
-(char)0xb2, 0x12, 0x25, 0x14,
-0x02, (char)0xe1, (char)0xc5, 0x02,
-0x5f, 0x5a, 0x05, 0x0f,
-0x26, (char)0xfc, (char)0xa5, (char)0xa5,
-(char)0xd6, (char)0xdd, (char)0xdc, (char)0xfc,
-0x25, 0x2b, 0x22, 0x21,
-0x0f, (char)0xff, (char)0xf8, (char)0xee,
-(char)0xed, (char)0xef, (char)0xf7, (char)0xf6,
-(char)0xfa, 0x00, 0x03, 0x02,
-0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00
+static const struct tms5100_coeffs tms5110_coeff =
+{
+ /* subtype */
+ SUBTYPE_TMS5110,
+ 10,
+ 4,
+ 5,
+ { 5, 5, 4, 4, 4, 4, 4, 3, 3, 3 },
+ /* E */
+ { 0, 1, 2, 3, 4, 6, 8, 11,
+ 16, 23, 33, 47, 63, 85, 114, 511 },
+ /* P */
+ { 0, 15, 16, 17, 19, 21, 22, 25,
+ 26, 29, 32, 36, 40, 42, 46, 50,
+ 55, 60, 64, 68, 72, 76, 80, 84,
+ 86, 93, 101, 110, 120, 132, 144, 159 },
+ {
+ /* K1 */
+ { -501, -498, -497, -495, -493, -491, -488, -482,
+ -478, -474, -469, -464, -459, -452, -445, -437,
+ -412, -380, -339, -288, -227, -158, -81, -1,
+ 80, 157, 226, 287, 337, 379, 411, 436 },
+ /* K2 */
+ { -328, -303, -274, -244, -211, -175, -138, -99,
+ -59, -18, 24, 64, 105, 143, 180, 215,
+ 248, 278, 306, 331, 354, 374, 392, 408,
+ 422, 435, 445, 455, 463, 470, 476, 506 },
+ /* K3 */
+ { -441, -387, -333, -279, -225, -171, -117, -63,
+ -9, 45, 98, 152, 206, 260, 314, 368 },
+ /* K4 */
+ { -328, -273, -217, -161, -106, -50, 5, 61,
+ 116, 172, 228, 283, 339, 394, 450, 506 },
+ /* K5 */
+ { -328, -282, -235, -189, -142, -96, -50, -3,
+ 43, 90, 136, 182, 229, 275, 322, 368 },
+ /* K6 */
+ { -256, -212, -168, -123, -79, -35, 10, 54,
+ 98, 143, 187, 232, 276, 320, 365, 409 },
+ /* K7 */
+ { -308, -260, -212, -164, -117, -69, -21, 27,
+ 75, 122, 170, 218, 266, 314, 361, 409 },
+ /* K8 */
+ { -256, -161, -66, 29, 124, 219, 314, 409 },
+ /* K9 */
+ { -256, -176, -96, -15, 65, 146, 226, 307 },
+ /* K10 */
+ { -205, -132, -59, 14, 87, 160, 234, 307 },
+ },
+ /* Chirptable */
+ { 0, 42, -44, 50, -78, 18, 37, 20,
+ 2, -31, -59, 2, 95, 90, 5, 15,
+ 38, -4, -91,-91, -42,-35,-36, -4,
+ 37, 43, 34, 33, 15, -1, -8,-18,
+ -19,-17, -9,-10, -6, 0, 3, 2,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ /* interpolation coefficients */
+ { 8, 8, 8, 4, 4, 4, 2, 1 }
};
-/* interpolation coefficients */
-
-const static char interp_coeff[8] = {
-8, 8, 8, 4, 4, 2, 2, 1
-};