1 /**********************************************************************************************
2 
3      TMS5110 simulator (modified from TMS5220 by Jarek Burczynski)
4 
5      Written for MAME by Frank Palazzolo
6      With help from Neill Corlett
7      Additional tweaking by Aaron Giles
8 
9 ***********************************************************************************************/
10 
11 #include <stddef.h>
12 #include <math.h>
13 
14 #include "burnint.h"
15 #include "tms5110.h"
16 
17 /* Pull in the ROM tables */
18 #include "tms5110_tables.h"
19 
20 #define logerror
21 
22 struct tms5110
23 {
24 	/* these contain data that describes the 64 bits FIFO */
25 	#define FIFO_SIZE 64
26 	UINT8 fifo[FIFO_SIZE];
27 	UINT8 fifo_head;
28 	UINT8 fifo_tail;
29 	UINT8 fifo_count;
30 
31 	/* these contain global status bits */
32 	UINT8 PDC;
33 	UINT8 CTL_pins;
34 	UINT8 speaking_now;
35 	UINT8 speak_delay_frames;
36 	UINT8 talk_status;
37 
38 	/* these contain data describing the current and previous voice frames */
39 	UINT16 old_energy;
40 	UINT16 old_pitch;
41 	INT32 old_k[10];
42 
43 	UINT16 new_energy;
44 	UINT16 new_pitch;
45 	INT32 new_k[10];
46 
47 	/* these are all used to contain the current state of the sound generation */
48 	UINT16 current_energy;
49 	UINT16 current_pitch;
50 	INT32 current_k[10];
51 
52 	UINT16 target_energy;
53 	UINT16 target_pitch;
54 	INT32 target_k[10];
55 
56 	UINT8 interp_count;       /* number of interp periods (0-7) */
57 	UINT8 sample_count;       /* sample number within interp (0-24) */
58 	INT32 pitch_count;
59 
60 	INT32 u[11];
61 	INT32 x[10];
62 
63 	INT32 RNG;	/* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
64 
65 	INT32 (*M0_callback)();
66 };
67 
68 
69 /* Static function prototypes */
70 static void parse_frame(struct tms5110 *tms);
71 
72 #define DEBUG_5110	0
73 
74 static struct tms5110 *our_chip = NULL;
75 static INT32 tms5110_initted = 0;
76 static INT16 *soundbuf = NULL;
77 static INT32 samples_from; // "re"sampler
78 
tms5110_create(void)79 static void *tms5110_create(void)
80 {
81 	struct tms5110 *tms;
82 
83 	tms = (tms5110 *)malloc(sizeof(*tms));
84 	memset(tms, 0, sizeof(*tms));
85 	return tms;
86 }
87 
tms5110_destroy(void * chip)88 static void tms5110_destroy(void *chip)
89 {
90 	free(chip);
91 }
92 
tms5110_init(UINT32 freq)93 void tms5110_init(UINT32 freq)
94 {
95 	our_chip = (tms5110 *)tms5110_create();
96 	soundbuf = (INT16*)malloc(0x800);
97 
98 	tms5110_set_frequency(freq);
99 	tms5110_initted = 1;
100 }
101 
tms5110_exit()102 void tms5110_exit()
103 {
104 	if (tms5110_initted == 0) {
105 		bprintf(0, _T("Warning: tms5110_exit() called without init!\n"));
106 		return;
107 	}
108 
109 	tms5110_destroy(our_chip);
110 	free(soundbuf);
111 
112 	tms5110_initted = 0;
113 }
114 
tms5110_scan(INT32 nAction,INT32 * pnMin)115 void tms5110_scan(INT32 nAction, INT32 *pnMin)
116 {
117 	struct BurnArea ba;
118 
119 	if (nAction & ACB_DRIVER_DATA) {
120 		memset(&ba, 0, sizeof(ba));
121 		ba.Data		= our_chip;
122 		ba.nLen		= STRUCT_SIZE_HELPER(tms5110, M0_callback);
123 		ba.szName	= "TMS5110 SpeechSynth Chip";
124 		BurnAcb(&ba);
125 	}
126 }
127 
128 
129 /**********************************************************************************************
130 
131      tms5110_reset -- resets the TMS5110
132 
133 ***********************************************************************************************/
134 
tms5110_reset_chip(void * chip)135 static void tms5110_reset_chip(void *chip)
136 {
137 	struct tms5110 *tms = (tms5110 *)chip;
138 
139     /* initialize the FIFO */
140     memset(tms->fifo, 0, sizeof(tms->fifo));
141     tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
142 
143     /* initialize the chip state */
144     tms->speaking_now = tms->speak_delay_frames = tms->talk_status = 0;
145     tms->CTL_pins = 0;
146 	tms->RNG = 0xfff;
147 
148     /* initialize the energy/pitch/k states */
149     tms->old_energy = tms->new_energy = tms->current_energy = tms->target_energy = 0;
150     tms->old_pitch = tms->new_pitch = tms->current_pitch = tms->target_pitch = 0;
151     memset(tms->old_k, 0, sizeof(tms->old_k));
152     memset(tms->new_k, 0, sizeof(tms->new_k));
153     memset(tms->current_k, 0, sizeof(tms->current_k));
154     memset(tms->target_k, 0, sizeof(tms->target_k));
155 
156     /* initialize the sample generators */
157     tms->interp_count = tms->sample_count = tms->pitch_count = 0;
158     memset(tms->u, 0, sizeof(tms->u));
159     memset(tms->x, 0, sizeof(tms->x));
160 }
161 
tms5110_reset()162 void tms5110_reset()
163 {
164 	tms5110_reset_chip(our_chip);
165 }
166 
167 
168 /******************************************************************************************
169 
170      tms5110_set_M0_callback -- set M0 callback for the TMS5110
171 
172 ******************************************************************************************/
173 
tms5110_set_M0_callback(void * chip,INT32 (* func)())174 static void tms5110_set_M0_callback(void *chip, INT32 (*func)())
175 {
176 	struct tms5110 *tms = (tms5110 *)chip;
177     tms->M0_callback = func;
178 }
179 
tms5110_M0_callback(INT32 (* func)())180 void tms5110_M0_callback(INT32 (*func)())
181 {
182 	tms5110_set_M0_callback(our_chip, func);
183 }
184 
185 /******************************************************************************************
186 
187      FIFO_data_write -- handle bit data write to the TMS5110 (as a result of toggling M0 pin)
188 
189 ******************************************************************************************/
FIFO_data_write(struct tms5110 * tms,INT32 data)190 static void FIFO_data_write(struct tms5110 *tms, INT32 data)
191 {
192 	/* add this bit to the FIFO */
193 	if (tms->fifo_count < FIFO_SIZE)
194 	{
195 		tms->fifo[tms->fifo_tail] = (data&1); /* set bit to 1 or 0 */
196 
197 		tms->fifo_tail = (tms->fifo_tail + 1) % FIFO_SIZE;
198 		tms->fifo_count++;
199 
200 		if (DEBUG_5110) logerror("Added bit to FIFO (size=%2d)\n", tms->fifo_count);
201 	}
202 	else
203 	{
204 		if (DEBUG_5110) logerror("Ran out of room in the FIFO!\n");
205 	}
206 }
207 
208 /******************************************************************************************
209 
210      extract_bits -- extract a specific number of bits from the FIFO
211 
212 ******************************************************************************************/
213 
extract_bits(struct tms5110 * tms,INT32 count)214 static INT32 extract_bits(struct tms5110 *tms, INT32 count)
215 {
216     INT32 val = 0;
217 
218     while (count--)
219     {
220         val = (val << 1) | (tms->fifo[tms->fifo_head] & 1);
221         tms->fifo_count--;
222         tms->fifo_head = (tms->fifo_head + 1) % FIFO_SIZE;
223     }
224     return val;
225 }
226 
request_bits(struct tms5110 * tms,INT32 no)227 static void request_bits(struct tms5110 *tms, INT32 no)
228 {
229 	for (INT32 i=0; i<no; i++)
230 	{
231 		if (tms->M0_callback)
232 		{
233 			INT32 data = (*tms->M0_callback)();
234 			FIFO_data_write(tms, data);
235 		}
236 		else
237 			if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
238 	}
239 }
240 
perform_dummy_read(struct tms5110 * tms)241 static void perform_dummy_read(struct tms5110 *tms)
242 {
243 	if (tms->M0_callback)
244 	{
245 		INT32 data = (*tms->M0_callback)();
246 	        if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data&1);
247 	}
248     	else
249 	        if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
250 }
251 
252 /**********************************************************************************************
253 
254      tms5110_status_read -- read status from the TMS5110
255 
256         bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data.
257                 Talk Status goes active at the initiation of a SPEAK command.
258                 It goes inactive (low) when the stop code (Energy=1111) is processed, or
259                 immediately(?????? not TMS5110) by a RESET command.
260         TMS5110 datasheets mention this is only available as a result of executing
261                 TEST TALK command.
262 
263 
264 ***********************************************************************************************/
265 
tms5110_status_read_internal(void * chip)266 static INT32 tms5110_status_read_internal(void *chip)
267 {
268 	struct tms5110 *tms = (tms5110 *)chip;
269     if (DEBUG_5110) logerror("Status read: TS=%d\n", tms->talk_status);
270 
271     return (tms->talk_status << 0); /*CTL1 = still talking ? */
272 }
273 
tms5110_status_read()274 INT32 tms5110_status_read()
275 {
276 	 return tms5110_status_read_internal(our_chip);
277 }
278 
279 /**********************************************************************************************
280 
281      tms5110_ready_read -- returns the ready state of the TMS5110
282 
283 ***********************************************************************************************/
284 
tms5110_ready_read_internal(void * chip)285 static INT32 tms5110_ready_read_internal(void *chip)
286 {
287 	struct tms5110 *tms = (tms5110 *)chip;
288     return (tms->fifo_count < FIFO_SIZE-1);
289 }
290 
tms5110_ready_read()291 INT32 tms5110_ready_read()
292 {
293 	 return tms5110_ready_read_internal(our_chip);
294 }
295 
296 
297 /**********************************************************************************************
298 
299      tms5110_process -- fill the buffer with a specific number of samples
300 
301 ***********************************************************************************************/
302 
tms5110_process(void * chip,INT16 * buffer,INT32 size)303 void tms5110_process(void *chip, INT16 *buffer, INT32 size)
304 {
305 	struct tms5110 *tms = (tms5110 *)chip;
306     INT32 buf_count=0;
307     INT32 i, interp_period;
308 
309     /* if we're not speaking, fill with nothingness */
310     if (!tms->speaking_now)
311         goto empty;
312 
313     /* if we're to speak, but haven't started */
314     if (!tms->talk_status)
315     {
316 
317     /* a "dummy read" is mentioned in the tms5200 datasheet */
318     /* The Bagman speech roms data are organized in such a way that
319     ** the bit at address 0 is NOT a speech data. The bit at address 1
320     ** is the speech data. It seems that the tms5110 performs a dummy read
321     ** just before it executes a SPEAK command.
322     */
323 		perform_dummy_read(tms);
324 
325         /* clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) */
326         tms->new_energy = 0;
327         tms->new_pitch = 0;
328         for (i = 0; i < 10; i++)
329             tms->new_k[i] = 0;
330 
331         tms->talk_status = 1;
332     }
333 
334 
335     /* loop until the buffer is full or we've stopped speaking */
336     while ((size > 0) && tms->speaking_now)
337     {
338         INT32 current_val;
339 
340         /* if we're ready for a new frame */
341         if ((tms->interp_count == 0) && (tms->sample_count == 0))
342         {
343 
344             /* remember previous frame */
345             tms->old_energy = tms->new_energy;
346             tms->old_pitch = tms->new_pitch;
347             for (i = 0; i < 10; i++)
348                 tms->old_k[i] = tms->new_k[i];
349 
350 
351             /* if the old frame was a stop frame, exit and do not process any more frames */
352             if (tms->old_energy == energytable[15])
353             {
354                 /*if (DEBUG_5110) logerror("processing frame: stop frame\n");*/
355                 tms->target_energy = tms->current_energy = 0;
356                 tms->speaking_now = tms->talk_status = 0;
357                 tms->interp_count = tms->sample_count = tms->pitch_count = 0;
358                 goto empty;
359             }
360 
361 
362             /* Parse a new frame into the new_energy, new_pitch and new_k[] */
363             parse_frame(tms);
364 
365 
366             /* Set old target as new start of frame */
367             tms->current_energy = tms->old_energy;
368             tms->current_pitch = tms->old_pitch;
369             for (i = 0; i < 10; i++)
370                 tms->current_k[i] = tms->old_k[i];
371 
372 
373             /* is this the stop (ramp down) frame? */
374             if (tms->new_energy == energytable[15])
375             {
376                 /*logerror("processing frame: ramp down\n");*/
377                 tms->target_energy = 0;
378                 tms->target_pitch = tms->old_pitch;
379                 for (i = 0; i < 10; i++)
380                     tms->target_k[i] = tms->old_k[i];
381             }
382             else if ((tms->old_energy == 0) && (tms->new_energy != 0)) /* was the old frame a zero-energy frame? */
383             {
384                 /* if so, and if the new frame is non-zero energy frame then the new parameters
385                    should become our current and target parameters immediately,
386                    i.e. we should NOT interpolate them slowly in.
387                 */
388 
389                 /*logerror("processing non-zero energy frame after zero-energy frame\n");*/
390                 tms->target_energy = tms->new_energy;
391                 tms->target_pitch = tms->current_pitch = tms->new_pitch;
392                 for (i = 0; i < 10; i++)
393                     tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
394             }
395             else if ((tms->old_pitch == 0) && (tms->new_pitch != 0))    /* is this a change from unvoiced to voiced frame ? */
396             {
397                 /* if so, then the new parameters should become our current and target parameters immediately,
398                    i.e. we should NOT interpolate them slowly in.
399                 */
400                 /*if (DEBUG_5110) logerror("processing frame: UNVOICED->VOICED frame change\n");*/
401                 tms->target_energy = tms->new_energy;
402                 tms->target_pitch = tms->current_pitch = tms->new_pitch;
403                 for (i = 0; i < 10; i++)
404                     tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
405             }
406             else if ((tms->old_pitch != 0) && (tms->new_pitch == 0))    /* is this a change from voiced to unvoiced frame ? */
407             {
408                 /* if so, then the new parameters should become our current and target parameters immediately,
409                    i.e. we should NOT interpolate them slowly in.
410                 */
411                 /*if (DEBUG_5110) logerror("processing frame: VOICED->UNVOICED frame change\n");*/
412                 tms->target_energy = tms->new_energy;
413                 tms->target_pitch = tms->current_pitch = tms->new_pitch;
414                 for (i = 0; i < 10; i++)
415                     tms->target_k[i] = tms->current_k[i] = tms->new_k[i];
416             }
417             else
418             {
419                 /*logerror("processing frame: Normal\n");*/
420                 /*logerror("*** Energy = %d\n",current_energy);*/
421                 /*logerror("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
422 
423                 tms->target_energy = tms->new_energy;
424                 tms->target_pitch = tms->new_pitch;
425                 for (i = 0; i < 10; i++)
426                     tms->target_k[i] = tms->new_k[i];
427             }
428         }
429         else if (tms->interp_count == 0)
430         {
431             /* interpolate (update) values based on step values */
432             /*logerror("\n");*/
433 
434             interp_period = tms->sample_count / 25;
435             tms->current_energy += (tms->target_energy - tms->current_energy) / interp_coeff[interp_period];
436             tms->current_pitch += (tms->target_pitch - tms->current_pitch) / interp_coeff[interp_period];
437 
438             /*logerror("*** Energy = %d\n",current_energy);*/
439 
440             for (i = 0; i < 10; i++)
441             {
442                 tms->current_k[i] += (tms->target_k[i] - tms->current_k[i]) / interp_coeff[interp_period];
443             }
444         }
445 
446 	/* calculate the output */
447 
448         if (tms->current_energy == 0)
449         {
450             /* generate silent samples here */
451             current_val = 0x00;
452         }
453         else if (tms->old_pitch == 0)
454         {
455             INT32 bitout, randbit;
456 
457             /* generate unvoiced samples here */
458             if (tms->RNG&1)
459                 randbit = -64; /* according to the patent it is (either + or -) half of the maximum value in the chirp table */
460             else
461                 randbit = 64;
462 
463             bitout = ((tms->RNG>>12)&1) ^
464                      ((tms->RNG>>10)&1) ^
465                      ((tms->RNG>> 9)&1) ^
466                      ((tms->RNG>> 0)&1);
467             tms->RNG >>= 1;
468             tms->RNG |= (bitout<<12);
469 
470             current_val = (randbit * tms->current_energy) / 256;
471         }
472         else
473         {
474             /* generate voiced samples here */
475             if (tms->pitch_count < sizeof(chirptable))
476                 current_val = (chirptable[tms->pitch_count] * tms->current_energy) / 256;
477             else
478                 current_val = 0x00;
479         }
480 
481 
482         /* Lattice filter here */
483 
484         tms->u[10] = current_val;
485 
486         for (i = 9; i >= 0; i--)
487         {
488             tms->u[i] = tms->u[i+1] - ((tms->current_k[i] * tms->x[i]) / 32768);
489         }
490         for (i = 9; i >= 1; i--)
491         {
492             tms->x[i] = tms->x[i-1] + ((tms->current_k[i-1] * tms->u[i-1]) / 32768);
493         }
494 
495         tms->x[0] = tms->u[0];
496 
497 
498         /* clipping, just like the chip */
499 
500         if (tms->u[0] > 511)
501             buffer[buf_count] = 127<<8;
502         else if (tms->u[0] < -512)
503             buffer[buf_count] = -128<<8;
504         else
505             buffer[buf_count] = tms->u[0] << 6;
506 
507 
508         /* Update all counts */
509 
510         tms->sample_count = (tms->sample_count + 1) % 200;
511 
512         if (tms->current_pitch != 0)
513             tms->pitch_count = (tms->pitch_count + 1) % tms->current_pitch;
514         else
515             tms->pitch_count = 0;
516 
517         tms->interp_count = (tms->interp_count + 1) % 25;
518 
519         buf_count++;
520         size--;
521     }
522 
523 empty:
524 
525     while (size > 0)
526     {
527         tms->sample_count = (tms->sample_count + 1) % 200;
528         tms->interp_count = (tms->interp_count + 1) % 25;
529 
530         buffer[buf_count] = 0x00;
531         buf_count++;
532         size--;
533     }
534 }
535 
536 static INT32 our_freq = 0;
537 
tms5110_set_frequency(UINT32 freq)538 void tms5110_set_frequency(UINT32 freq)
539 {
540 	our_freq = freq/80;
541 	samples_from = (INT32)((double)((our_freq * 100) / nBurnFPS) + 0.5);
542 }
543 
tms5110_update(INT16 * buffer,INT32 samples_len)544 void tms5110_update(INT16 *buffer, INT32 samples_len)
545 {
546 	INT32 samples = (samples_from * samples_len) / nBurnSoundLen;
547 
548 	tms5110_process(our_chip, soundbuf, samples);
549 
550 	INT16 *mix = soundbuf;
551 
552 	for (INT32 j = 0; j < samples_len; j++)
553 	{
554 		INT32 k = (samples_from * j) / nBurnSoundLen;
555 
556 		INT32 s = mix[k];
557 		buffer[0] = BURN_SND_CLIP(buffer[0] + s);
558 		buffer[1] = BURN_SND_CLIP(buffer[1] + s);
559 		buffer += 2;
560 	}
561 
562 }
563 
564 
565 /******************************************************************************************
566 
567      CTL_set -- set CTL pins named CTL1, CTL2, CTL4 and CTL8
568 
569 ******************************************************************************************/
570 
tms5110_CTL_set_internal(void * chip,INT32 data)571 void tms5110_CTL_set_internal(void *chip, INT32 data)
572 {
573 	struct tms5110 *tms = (tms5110 *)chip;
574 	tms->CTL_pins = data & 0xf;
575 }
576 
tms5110_CTL_set(UINT8 data)577 void tms5110_CTL_set(UINT8 data)
578 {
579 	tms5110_CTL_set_internal(our_chip, data);
580 }
581 
582 /******************************************************************************************
583 
584      PDC_set -- set Processor Data Clock. Execute CTL_pins command on hi-lo transition.
585 
586 ******************************************************************************************/
587 
tms5110_PDC_set_internal(void * chip,INT32 data)588 void tms5110_PDC_set_internal(void *chip, INT32 data)
589 {
590 	struct tms5110 *tms = (tms5110 *)chip;
591 	if (tms->PDC != (data & 0x1) )
592 	{
593 		tms->PDC = data & 0x1;
594 		if (tms->PDC == 0) /* toggling 1->0 processes command on CTL_pins */
595 		{
596 			/* the only real commands we handle now are SPEAK and RESET */
597 
598 			switch (tms->CTL_pins & 0xe) /*CTL1 - don't care*/
599 			{
600 			case TMS5110_CMD_SPEAK:
601 				tms->speaking_now = 1;
602 
603 				//should FIFO be cleared now ?????
604 
605 				break;
606 
607         		case TMS5110_CMD_RESET:
608 				tms->speaking_now = 0;
609 				tms->talk_status = 0;
610 				break;
611 
612 			default:
613 				break;
614 			}
615 		}
616 	}
617 }
618 
tms5110_PDC_set(UINT8 data)619 void tms5110_PDC_set(UINT8 data)
620 {
621 	tms5110_PDC_set_internal(our_chip, data);
622 }
623 
624 
625 /******************************************************************************************
626 
627      parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer
628 
629 ******************************************************************************************/
630 
parse_frame(struct tms5110 * tms)631 static void parse_frame(struct tms5110 *tms)
632 {
633     INT32 bits, indx, i, rep_flag;
634 
635 
636     /* count the total number of bits available */
637     bits = tms->fifo_count;
638 
639 
640     /* attempt to extract the energy index */
641     bits -= 4;
642     if (bits < 0)
643     {
644         request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
645 	bits = 0;
646     }
647     indx = extract_bits(tms,4);
648     tms->new_energy = energytable[indx];
649 
650 
651     /* if the energy index is 0 or 15, we're done */
652 
653     if ((indx == 0) || (indx == 15))
654     {
655         if (DEBUG_5110) logerror("  (4-bit energy=%d frame)\n",tms->new_energy);
656 
657 	/* clear the k's */
658         if (indx == 0)
659         {
660             for (i = 0; i < 10; i++)
661                 tms->new_k[i] = 0;
662 	}
663 
664         /* clear fifo if stop frame encountered */
665         if (indx == 15)
666         {
667             if (DEBUG_5110) logerror("  (4-bit energy=%d STOP frame)\n",tms->new_energy);
668             tms->fifo_head = tms->fifo_tail = tms->fifo_count = 0;
669             //speaking_now = talk_status = 0;
670         }
671         return;
672     }
673 
674 
675     /* attempt to extract the repeat flag */
676     bits -= 1;
677     if (bits < 0)
678     {
679         request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
680 	bits = 0;
681     }
682     rep_flag = extract_bits(tms,1);
683 
684     /* attempt to extract the pitch */
685     bits -= 5;
686     if (bits < 0)
687     {
688         request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
689         bits = 0;
690     }
691     indx = extract_bits(tms,5);
692     tms->new_pitch = pitchtable[indx];
693 
694 
695     /* if this is a repeat frame, just copy the k's */
696     if (rep_flag)
697     {
698 	//actually, we do nothing because the k's were already loaded (on parsing the previous frame)
699 
700         if (DEBUG_5110) logerror("  (10-bit energy=%d pitch=%d rep=%d frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
701         return;
702     }
703 
704 
705     /* if the pitch index was zero, we need 4 k's */
706     if (indx == 0)
707     {
708         /* attempt to extract 4 K's */
709         bits -= 18;
710         if (bits < 0)
711         {
712 		request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
713 		bits = 0;
714         }
715         tms->new_k[0] = k1table[extract_bits(tms,5)];
716         tms->new_k[1] = k2table[extract_bits(tms,5)];
717         tms->new_k[2] = k3table[extract_bits(tms,4)];
718         tms->new_k[3] = k4table[extract_bits(tms,4)];
719 
720 	/* and clear the rest of the new_k[] */
721         for (i = 4; i < 10; i++)
722             tms->new_k[i] = 0;
723 
724         if (DEBUG_5110) logerror("  (28-bit energy=%d pitch=%d rep=%d 4K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
725         return;
726     }
727 
728     /* else we need 10 K's */
729     bits -= 39;
730     if (bits < 0)
731     {
732 	        request_bits( tms,-bits ); /* toggle M0 to receive needed bits */
733 		bits = 0;
734     }
735     tms->new_k[0] = k1table[extract_bits(tms,5)];
736     tms->new_k[1] = k2table[extract_bits(tms,5)];
737     tms->new_k[2] = k3table[extract_bits(tms,4)];
738     tms->new_k[3] = k4table[extract_bits(tms,4)];
739     tms->new_k[4] = k5table[extract_bits(tms,4)];
740     tms->new_k[5] = k6table[extract_bits(tms,4)];
741     tms->new_k[6] = k7table[extract_bits(tms,4)];
742     tms->new_k[7] = k8table[extract_bits(tms,3)];
743     tms->new_k[8] = k9table[extract_bits(tms,3)];
744     tms->new_k[9] = k10table[extract_bits(tms,3)];
745 
746     if (DEBUG_5110) logerror("  (49-bit energy=%d pitch=%d rep=%d 10K frame)\n", tms->new_energy, tms->new_pitch, rep_flag);
747 
748 }
749 
750 
751 #if 0
752 /*This is an example word TEN taken from the TMS5110A datasheet*/
753 static unsigned INT32 example_word_TEN[619]={
754 /* 1*/1,0,0,0,	0,	0,0,0,0,0,	1,1,0,0,0,	0,0,0,1,0,	0,1,1,1,	0,1,0,1,
755 /* 2*/1,0,0,0,	0,	0,0,0,0,0,	1,0,0,1,0,	0,0,1,1,0,	0,0,1,1,	0,1,0,1,
756 /* 3*/1,1,0,0,	0,	1,0,0,0,0,	1,0,1,0,0,	0,1,0,1,0,	0,1,0,0,	1,0,1,0,	1,0,0,0,	1,0,0,1,	0,1,0,1,	0,0,1,	0,1,0,	0,1,1,
757 /* 4*/1,1,1,0,	0,	0,1,1,1,1,	1,0,1,0,1,	0,1,1,1,0,	0,1,0,1,	0,1,1,1,	0,1,1,1,	1,0,1,1,	1,0,1,0,	0,1,1,	0,1,0,	0,1,1,
758 /* 5*/1,1,1,0,	0,	1,0,0,0,0,	1,0,1,0,0,	0,1,1,1,0,	0,1,0,1,	1,0,1,0,	1,0,0,0,	1,1,0,0,	1,0,1,1,	1,0,0,	0,1,0,	0,1,1,
759 /* 6*/1,1,1,0,	0,	1,0,0,0,1,	1,0,1,0,1,	0,1,1,0,1,	0,1,1,0,	0,1,1,1,	0,1,1,1,	1,0,1,0,	1,0,1,0,	1,1,0,	0,0,1,	1,0,0,
760 /* 7*/1,1,1,0,	0,	1,0,0,1,0,	1,0,1,1,1,	0,1,1,1,0,	0,1,1,1,	0,1,1,1,	0,1,0,1,	0,1,1,0,	1,0,0,1,	1,1,0,	0,1,0,	0,1,1,
761 /* 8*/1,1,1,0,	1,	1,0,1,0,1,
762 /* 9*/1,1,1,0,	0,	1,1,0,0,1,	1,0,1,1,1,	0,1,0,1,1,	1,0,1,1,	0,1,1,1,	0,1,0,0,	1,0,0,0,	1,0,0,0,	1,1,0,	0,1,1,	0,1,1,
763 /*10*/1,1,0,1,	0,	1,1,0,1,0,	1,0,1,0,1,	0,1,1,0,1,	1,0,1,1,	0,1,0,1,	0,1,0,0,	1,0,0,0,	1,0,1,0,	1,1,0,	0,1,0,	1,0,0,
764 /*11*/1,0,1,1,	0,	1,1,0,1,1,	1,0,0,1,1,	1,0,0,1,0,	0,1,1,0,	0,0,1,1,	0,1,0,1,	1,0,0,1,	1,0,1,0,	1,0,0,	0,1,1,	0,1,1,
765 /*12*/1,0,0,0,	0,	1,1,1,0,0,	1,0,0,1,1,	0,0,1,1,0,	0,1,0,0,	0,1,1,0,	1,1,0,0,	0,1,0,1,	1,0,0,0,	1,0,0,	0,1,0,	1,0,1,
766 /*13*/0,1,1,1,	1,	1,1,1,0,1,
767 /*14*/0,1,1,1,	0,	1,1,1,1,0,	1,0,0,1,1,	0,0,1,1,1,	0,1,0,1,	0,1,0,1,	1,1,0,0,	0,1,1,1,	1,0,0,0,	1,0,0,	0,1,0,	1,0,1,
768 /*15*/0,1,1,0,	0,	1,1,1,1,0,	1,0,1,0,1,	0,0,1,1,0,	0,1,0,0,	0,0,1,1,	1,1,0,0,	1,0,0,1,	0,1,1,1,	1,0,1,	0,1,0,	1,0,1,
769 /*16*/1,1,1,1
770 };
771 #endif
772 
773