1 /**********************************************************************************************
2 
3      TMS5220 simulator
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 <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 
15 #include "driver.h"
16 #include "tms5220.h"
17 
18 
19 /* Pull in the ROM tables */
20 #include "tms5220r.c"
21 
22 /*
23   Changes by R. Nabet
24    * added Speech ROM support
25    * modified code so that the beast only start speaking at the start of next frame, like the data
26      sheet says
27 */
28 #define USE_OBSOLETE_HACK 0
29 
30 
31 #ifndef TRUE
32 	#define TRUE 1
33 #endif
34 #ifndef FALSE
35 	#define FALSE 0
36 #endif
37 
38 
39 /* these contain data that describes the 128-bit data FIFO */
40 #define FIFO_SIZE 16
41 static UINT8 fifo[FIFO_SIZE];
42 static UINT8 fifo_head;
43 static UINT8 fifo_tail;
44 static UINT8 fifo_count;
45 static UINT8 fifo_bits_taken;
46 
47 
48 /* these contain global status bits */
49 /*
50 	R Nabet : speak_external is only set when a speak external command is going on.
51 	tms5220_speaking is set whenever a speak or speak external command is going on.
52 	Note that we really need to do anything in tms5220_process and play samples only when
53 	tms5220_speaking is true.  Else, we can play nothing as well, which is a
54 	speed-up...
55 */
56 static UINT8 tms5220_speaking;	/* Speak or Speak External command in progress */
57 static UINT8 speak_external;	/* Speak External command in progress */
58 #if USE_OBSOLETE_HACK
59 static UINT8 speak_delay_frames;
60 #endif
61 static UINT8 talk_status; 		/* tms5220 is really currently speaking */
62 static UINT8 first_frame;		/* we have just started speaking, and we are to parse the first frame */
63 static UINT8 last_frame;		/* we are doing the frame of sound */
64 static UINT8 buffer_low;		/* FIFO has less than 8 bytes in it */
65 static UINT8 buffer_empty;		/* FIFO is empty*/
66 static UINT8 irq_pin;			/* state of the IRQ pin (output) */
67 
68 static void (*irq_func)(int state); /* called when the state of the IRQ pin changes */
69 
70 
71 /* these contain data describing the current and previous voice frames */
72 static UINT16 old_energy;
73 static UINT16 old_pitch;
74 static int old_k[10];
75 
76 static UINT16 new_energy;
77 static UINT16 new_pitch;
78 static int new_k[10];
79 
80 
81 /* these are all used to contain the current state of the sound generation */
82 static UINT16 current_energy;
83 static UINT16 current_pitch;
84 static int current_k[10];
85 
86 static UINT16 target_energy;
87 static UINT16 target_pitch;
88 static int target_k[10];
89 
90 static UINT8 interp_count;		/* number of interp periods (0-7) */
91 static UINT8 sample_count;		/* sample number within interp (0-24) */
92 static int pitch_count;
93 
94 static int u[11];
95 static int x[10];
96 
97 static INT8 randbit;
98 
99 
100 /* Static function prototypes */
101 static void process_command(void);
102 static int extract_bits(int count);
103 static int parse_frame(int the_first_frame);
104 static void check_buffer_low(void);
105 static void set_interrupt_state(int state);
106 
107 
108 #define DEBUG_5220	0
109 
110 
111 
112 /* R Nabet : These have been added to emulate speech Roms */
113 static int (*read_callback)(int count) = NULL;
114 static void (*load_address_callback)(int data) = NULL;
115 static void (*read_and_branch_callback)(void) = NULL;
116 static int schedule_dummy_read;			/* set after each load address, so that next read operation
117 										  is preceded by a dummy read */
118 
119 static UINT8 data_register;				/* data register, used by read command */
120 static int RDB_flag;					/* whether we should read data register or status register */
121 
122 /* flag for tms0285 emulation */
123 /* The tms0285 is an early variant of the tms5220 used in the ti-99/4(a)
124 computer.  The exact relationship of this chip with tms5200 & tms5220 is
125 unknown, but it seems to use slightly different tables for LPC parameters. */
126 static tms5220_variant variant;
127 
128 /**********************************************************************************************
129 
130      tms5220_reset -- resets the TMS5220
131 
132 ***********************************************************************************************/
133 
tms5220_reset(void)134 void tms5220_reset(void)
135 {
136 	/* initialize the FIFO */
137 	/*memset(fifo, 0, sizeof(fifo));*/
138 	fifo_head = fifo_tail = fifo_count = fifo_bits_taken = 0;
139 
140 	/* initialize the chip state */
141 	/* Note that we do not actually clear IRQ on start-up : IRQ is even raised if buffer_empty or buffer_low are 0 */
142 	tms5220_speaking = speak_external = talk_status = first_frame = last_frame = irq_pin = 0;
143 #if USE_OBSOLETE_HACK
144 	speak_delay_frames = 0;
145 #endif
146 	if (irq_func) irq_func(0);
147 	buffer_empty = buffer_low = 1;
148 
149 	RDB_flag = FALSE;
150 
151 	/* initialize the energy/pitch/k states */
152 	old_energy = new_energy = current_energy = target_energy = 0;
153 	old_pitch = new_pitch = current_pitch = target_pitch = 0;
154 	memset(old_k, 0, sizeof(old_k));
155 	memset(new_k, 0, sizeof(new_k));
156 	memset(current_k, 0, sizeof(current_k));
157 	memset(target_k, 0, sizeof(target_k));
158 
159 	/* initialize the sample generators */
160 	interp_count = sample_count = pitch_count = 0;
161 	randbit = 0;
162 	memset(u, 0, sizeof(u));
163 	memset(x, 0, sizeof(x));
164 
165 	if (load_address_callback)
166 		(*load_address_callback)(0);
167 
168 	schedule_dummy_read = TRUE;
169 }
170 
171 
172 
173 /**********************************************************************************************
174 
175      tms5220_set_irq -- sets the interrupt handler
176 
177 ***********************************************************************************************/
178 
tms5220_set_irq(void (* func)(int))179 void tms5220_set_irq(void (*func)(int))
180 {
181     irq_func = func;
182 }
183 
184 
185 /**********************************************************************************************
186 
187      tms5220_set_read -- sets the speech ROM read handler
188 
189 ***********************************************************************************************/
190 
tms5220_set_read(int (* func)(int))191 void tms5220_set_read(int (*func)(int))
192 {
193 	read_callback = func;
194 }
195 
196 
197 /**********************************************************************************************
198 
199      tms5220_set_load_address -- sets the speech ROM load address handler
200 
201 ***********************************************************************************************/
202 
tms5220_set_load_address(void (* func)(int))203 void tms5220_set_load_address(void (*func)(int))
204 {
205 	load_address_callback = func;
206 }
207 
208 
209 /**********************************************************************************************
210 
211      tms5220_set_read_and_branch -- sets the speech ROM read and branch handler
212 
213 ***********************************************************************************************/
214 
tms5220_set_read_and_branch(void (* func)(void))215 void tms5220_set_read_and_branch(void (*func)(void))
216 {
217 	read_and_branch_callback = func;
218 }
219 
220 
221 /**********************************************************************************************
222 
223      tms5220_set_variant -- sets the tms5220 core to emulate its buggy forerunner, the tms0285
224 
225 ***********************************************************************************************/
226 
tms5220_set_variant(tms5220_variant new_variant)227 void tms5220_set_variant(tms5220_variant new_variant)
228 {
229 	variant = new_variant;
230 }
231 
232 
233 /**********************************************************************************************
234 
235      tms5220_data_write -- handle a write to the TMS5220
236 
237 ***********************************************************************************************/
238 
tms5220_data_write(int data)239 void tms5220_data_write(int data)
240 {
241     /* add this byte to the FIFO */
242     if (fifo_count < FIFO_SIZE)
243     {
244         fifo[fifo_tail] = data;
245         fifo_tail = (fifo_tail + 1) % FIFO_SIZE;
246         fifo_count++;
247 
248 		/* if we were speaking, then we're no longer empty */
249 		if (speak_external)
250 			buffer_empty = 0;
251 
252         if (DEBUG_5220) logerror("Added byte to FIFO (size=%2d)\n", fifo_count);
253     }
254     else
255     {
256         if (DEBUG_5220) logerror("Ran out of room in the FIFO!\n");
257     }
258 
259     /* update the buffer low state */
260     check_buffer_low();
261 
262 	if (! speak_external)
263 		/* R Nabet : we parse commands at once.  It is necessary for such commands as read. */
264 		process_command (/*data*/);
265 }
266 
267 
268 /**********************************************************************************************
269 
270      tms5220_status_read -- read status or data from the TMS5220
271 
272 	  From the data sheet:
273         bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data.
274                 Talk Status goes active at the initiation of a Speak command or after nine
275                 bytes of data are loaded into the FIFO following a Speak External command. It
276                 goes inactive (low) when the stop code (Energy=1111) is processed, or
277                 immediately by a buffer empty condition or a reset command.
278         bit 1 = BL - Buffer Low is active (high) when the FIFO buffer is more than half empty.
279                 Buffer Low is set when the "Last-In" byte is shifted down past the half-full
280                 boundary of the stack. Buffer Low is cleared when data is loaded to the stack
281                 so that the "Last-In" byte lies above the half-full boundary and becomes the
282                 ninth data byte of the stack.
283         bit 2 = BE - Buffer Empty is active (high) when the FIFO buffer has run out of data
284                 while executing a Speak External command. Buffer Empty is set when the last bit
285                 of the "Last-In" byte is shifted out to the Synthesis Section. This causes
286                 Talk Status to be cleared. Speed is terminated at some abnormal point and the
287                 Speak External command execution is terminated.
288 
289 ***********************************************************************************************/
290 
tms5220_status_read(void)291 int tms5220_status_read(void)
292 {
293 	if (RDB_flag)
294 	{	/* if last command was read, return data register */
295 		RDB_flag = FALSE;
296 		return(data_register);
297 	}
298 	else
299 	{	/* read status */
300 
301 		/* clear the interrupt pin */
302 		set_interrupt_state(0);
303 
304 		if (DEBUG_5220) logerror("Status read: TS=%d BL=%d BE=%d\n", talk_status, buffer_low, buffer_empty);
305 
306 		return (talk_status << 7) | (buffer_low << 6) | (buffer_empty << 5);
307 	}
308 }
309 
310 
311 
312 /**********************************************************************************************
313 
314      tms5220_ready_read -- returns the ready state of the TMS5220
315 
316 ***********************************************************************************************/
317 
tms5220_ready_read(void)318 int tms5220_ready_read(void)
319 {
320     return (fifo_count < FIFO_SIZE-1);
321 }
322 
323 
324 /**********************************************************************************************
325 
326      tms5220_ready_read -- returns the number of cycles until ready is asserted
327 
328 ***********************************************************************************************/
329 
tms5220_cycles_to_ready(void)330 int tms5220_cycles_to_ready(void)
331 {
332 	int answer;
333 
334 
335 	if (tms5220_ready_read())
336 		answer = 0;
337 	else
338 	{
339 		int val;
340 
341 		answer = 200-sample_count+1;
342 
343 		/* total number of bits available in current byte is (8 - fifo_bits_taken) */
344 		/* if more than 4 are available, we need to check the energy */
345 		if (fifo_bits_taken < 4)
346 		{
347 			/* read energy */
348 			val = (fifo[fifo_head] >> fifo_bits_taken) & 0xf;
349 			if (val == 0)
350 				/* 0 -> silence frame: we will only read 4 bits, and we will
351 				therefore need to read another frame before the FIFO is not
352 				full any more */
353 				answer += 200;
354 			/* 15 -> stop frame, we will only read 4 bits, but the FIFO will
355 			we cleared */
356 			/* otherwise, we need to parse the repeat flag (1 bit) and the
357 			pitch (6 bits), so everything will be OK. */
358 		}
359 	}
360 
361 	return answer;
362 }
363 
364 
365 /**********************************************************************************************
366 
367      tms5220_int_read -- returns the interrupt state of the TMS5220
368 
369 ***********************************************************************************************/
370 
tms5220_int_read(void)371 int tms5220_int_read(void)
372 {
373     return irq_pin;
374 }
375 
376 
377 
378 /**********************************************************************************************
379 
380      tms5220_process -- fill the buffer with a specific number of samples
381 
382 ***********************************************************************************************/
383 
tms5220_process(INT16 * buffer,unsigned int size)384 void tms5220_process(INT16 *buffer, unsigned int size)
385 {
386     int buf_count=0;
387     int i, interp_period;
388 
389 tryagain:
390 
391     /* if we're not speaking, parse commands */
392 	/*while (!speak_external && fifo_count > 0)
393 		process_command();*/
394 
395     /* if we're empty and still not speaking, fill with nothingness */
396 	if ((!tms5220_speaking) && (!last_frame))
397         goto empty;
398 
399     /* if we're to speak, but haven't started, wait for the 9th byte */
400 	if (!talk_status && speak_external)
401     {
402         if (fifo_count < 9)
403            goto empty;
404 
405         talk_status = 1;
406 		first_frame = 1;	/* will cause the first frame to be parsed */
407 		buffer_empty = 0;
408 	}
409 
410 #if 0
411 	/* we are to speak, yet we fill with 0s until start of next frame */
412 	if (first_frame)
413 	{
414 		while ((size > 0) && ((sample_count != 0) || (interp_count != 0)))
415 		{
416 			sample_count = (sample_count + 1) % 200;
417 			interp_count = (interp_count + 1) % 25;
418 			buffer[buf_count] = 0x00;	/* should be (-1 << 8) ??? (cf note in data sheet, p 10, table 4) */
419 			buf_count++;
420 			size--;
421 		}
422 	}
423 #endif
424 
425 #if USE_OBSOLETE_HACK
426     /* apply some delay before we actually consume data; Victory requires this */
427     if (speak_delay_frames)
428     {
429     	if (size <= speak_delay_frames)
430     	{
431     		speak_delay_frames -= size;
432     		size = 0;
433     	}
434     	else
435     	{
436     		size -= speak_delay_frames;
437     		speak_delay_frames = 0;
438     	}
439     }
440 #endif
441 
442     /* loop until the buffer is full or we've stopped speaking */
443 	while ((size > 0) && talk_status)
444     {
445         int current_val;
446 
447         /* if we're ready for a new frame */
448         if ((interp_count == 0) && (sample_count == 0))
449         {
450             /* Parse a new frame */
451 			if (!parse_frame(first_frame))
452 				break;
453 			first_frame = 0;
454 
455             /* Set old target as new start of frame */
456             current_energy = old_energy;
457             current_pitch = old_pitch;
458             for (i = 0; i < 10; i++)
459                 current_k[i] = old_k[i];
460 
461             /* is this a zero energy frame? */
462             if (current_energy == 0)
463             {
464                 /*printf("processing frame: zero energy\n");*/
465                 target_energy = 0;
466                 target_pitch = current_pitch;
467                 for (i = 0; i < 10; i++)
468                     target_k[i] = current_k[i];
469             }
470 
471             /* is this a stop frame? */
472             else if (current_energy == (energytable[15] >> 6))
473             {
474                 /*printf("processing frame: stop frame\n");*/
475                 current_energy = energytable[0] >> 6;
476                 target_energy = current_energy;
477 				/*interp_count = sample_count =*/ pitch_count = 0;
478 				last_frame = 0;
479 				if (tms5220_speaking)
480 					/* new speech command in progress */
481 					first_frame = 1;
482 				else
483 				{
484 					/* really stop speaking */
485 					talk_status = 0;
486 
487 					/* generate an interrupt if necessary */
488 					set_interrupt_state(1);
489 				}
490 
491                 /* try to fetch commands again */
492                 goto tryagain;
493             }
494             else
495             {
496                 /* is this the ramp down frame? */
497                 if (new_energy == (energytable[15] >> 6))
498                 {
499                     /*printf("processing frame: ramp down\n");*/
500                     target_energy = 0;
501                     target_pitch = current_pitch;
502                     for (i = 0; i < 10; i++)
503                         target_k[i] = current_k[i];
504                 }
505                 /* Reset the step size */
506                 else
507                 {
508                     /*printf("processing frame: Normal\n");*/
509                     /*printf("*** Energy = %d\n",current_energy);*/
510                     /*printf("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
511 
512                     target_energy = new_energy;
513                     target_pitch = new_pitch;
514 
515                     for (i = 0; i < 4; i++)
516                         target_k[i] = new_k[i];
517                     if (current_pitch == 0)
518                         for (i = 4; i < 10; i++)
519                         {
520                             target_k[i] = current_k[i] = 0;
521                         }
522                     else
523                         for (i = 4; i < 10; i++)
524                             target_k[i] = new_k[i];
525                 }
526             }
527         }
528         else if (interp_count == 0)
529         {
530             /* Update values based on step values */
531             /*printf("\n");*/
532 
533             interp_period = sample_count / 25;
534             current_energy += (target_energy - current_energy) / interp_coeff[interp_period];
535             if (old_pitch != 0)
536                 current_pitch += (target_pitch - current_pitch) / interp_coeff[interp_period];
537 
538             /*printf("*** Energy = %d\n",current_energy);*/
539 
540             for (i = 0; i < 10; i++)
541             {
542                 current_k[i] += (target_k[i] - current_k[i]) / interp_coeff[interp_period];
543             }
544         }
545 
546         if (old_energy == 0)
547         {
548             /* generate silent samples here */
549             current_val = 0x00;
550         }
551         else if (old_pitch == 0)
552         {
553             /* generate unvoiced samples here */
554             randbit = (rand() % 2) * 2 - 1;
555             current_val = (randbit * current_energy) / 4;
556         }
557         else
558         {
559             /* generate voiced samples here */
560             if (pitch_count < sizeof(chirptable))
561                 current_val = (chirptable[pitch_count] * current_energy) / 256;
562             else
563                 current_val = 0x00;
564         }
565 
566         /* Lattice filter here */
567 
568         u[10] = current_val;
569 
570         for (i = 9; i >= 0; i--)
571         {
572             u[i] = u[i+1] - ((current_k[i] * x[i]) / 32768);
573         }
574         for (i = 9; i >= 1; i--)
575         {
576             x[i] = x[i-1] + ((current_k[i-1] * u[i-1]) / 32768);
577         }
578 
579         x[0] = u[0];
580 
581         /* clipping, just like the chip */
582 
583         if (u[0] > 511)
584             buffer[buf_count] = 127<<8;
585         else if (u[0] < -512)
586             buffer[buf_count] = -128<<8;
587         else
588             buffer[buf_count] = u[0] << 6;
589 
590         /* Update all counts */
591 
592         size--;
593         sample_count = (sample_count + 1) % 200;
594 
595         if (current_pitch != 0)
596             pitch_count = (pitch_count + 1) % current_pitch;
597         else
598             pitch_count = 0;
599 
600         interp_count = (interp_count + 1) % 25;
601         buf_count++;
602     }
603 
604 empty:
605 
606     while (size > 0)
607     {
608 		sample_count = (sample_count + 1) % 200;
609 		interp_count = (interp_count + 1) % 25;
610 		buffer[buf_count] = 0x00;	/* should be (-1 << 8) ??? (cf note in data sheet, p 10, table 4) */
611         buf_count++;
612         size--;
613     }
614 }
615 
616 
617 
618 /**********************************************************************************************
619 
620      process_command -- extract a byte from the FIFO and interpret it as a command
621 
622 ***********************************************************************************************/
623 
process_command(void)624 static void process_command(void)
625 {
626     unsigned char cmd;
627 
628     /* if there are stray bits, ignore them */
629 	if (fifo_bits_taken)
630 	{
631 		fifo_bits_taken = 0;
632         fifo_count--;
633         fifo_head = (fifo_head + 1) % FIFO_SIZE;
634     }
635 
636     /* grab a full byte from the FIFO */
637     if (fifo_count > 0)
638     {
639 		cmd = fifo[fifo_head];
640 		fifo_count--;
641 		fifo_head = (fifo_head + 1) % FIFO_SIZE;
642 
643 		/* parse the command */
644 		switch (cmd & 0x70)
645 		{
646 		case 0x10 : /* read byte */
647 			if (schedule_dummy_read)
648 			{
649 				schedule_dummy_read = FALSE;
650 				if (read_callback)
651 					(*read_callback)(1);
652 			}
653 			if (read_callback)
654 				data_register = (*read_callback)(8);	/* read one byte from speech ROM... */
655 			RDB_flag = TRUE;
656 			break;
657 
658 		case 0x30 : /* read and branch */
659 			if (DEBUG_5220) logerror("read and branch command received\n");
660 			RDB_flag = FALSE;
661 			if (read_and_branch_callback)
662 				(*read_and_branch_callback)();
663 			break;
664 
665 		case 0x40 : /* load address */
666 			/* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
667 			  This code does not care about this. */
668 			if (load_address_callback)
669 				(*load_address_callback)(cmd & 0x0f);
670 			schedule_dummy_read = TRUE;
671 			break;
672 
673 		case 0x50 : /* speak */
674 			if (schedule_dummy_read)
675 			{
676 				schedule_dummy_read = FALSE;
677 				if (read_callback)
678 					(*read_callback)(1);
679 			}
680 			tms5220_speaking = 1;
681 			speak_external = 0;
682 			if (! last_frame)
683 			{
684 				first_frame = 1;
685 			}
686 			talk_status = 1;  /* start immediately */
687 			break;
688 
689 		case 0x60 : /* speak external */
690 			tms5220_speaking = speak_external = 1;
691 #if USE_OBSOLETE_HACK
692             speak_delay_frames = 10;
693 #endif
694 
695 			RDB_flag = FALSE;
696 
697             /* according to the datasheet, this will cause an interrupt due to a BE condition */
698             if (!buffer_empty)
699             {
700                 buffer_empty = 1;
701                 set_interrupt_state(1);
702             }
703 
704 			talk_status = 0;	/* wait to have 8 bytes in buffer before starting */
705 			break;
706 
707 		case 0x70 : /* reset */
708 			if (schedule_dummy_read)
709 			{
710 				schedule_dummy_read = FALSE;
711 				if (read_callback)
712 					(*read_callback)(1);
713 			}
714 			tms5220_reset();
715 			break;
716         }
717     }
718 
719     /* update the buffer low state */
720     check_buffer_low();
721 }
722 
723 
724 
725 /**********************************************************************************************
726 
727      extract_bits -- extract a specific number of bits from the FIFO
728 
729 ***********************************************************************************************/
730 
extract_bits(int count)731 static int extract_bits(int count)
732 {
733     int val = 0;
734 
735 	if (speak_external)
736 	{
737 		/* extract from FIFO */
738     	while (count--)
739     	{
740         	val = (val << 1) | ((fifo[fifo_head] >> fifo_bits_taken) & 1);
741         	fifo_bits_taken++;
742         	if (fifo_bits_taken >= 8)
743         	{
744         	    fifo_count--;
745         	    fifo_head = (fifo_head + 1) % FIFO_SIZE;
746         	    fifo_bits_taken = 0;
747         	}
748     	}
749     }
750 	else
751 	{
752 		/* extract from speech ROM */
753 		if (read_callback)
754 			val = (* read_callback)(count);
755 	}
756 
757     return val;
758 }
759 
760 
761 
762 /**********************************************************************************************
763 
764      parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer
765 
766 ***********************************************************************************************/
767 
parse_frame(int the_first_frame)768 static int parse_frame(int the_first_frame)
769 {
770 	int bits = 0;	/* number of bits in FIFO (speak external only) */
771 	int indx, i, rep_flag;
772 
773 	if (! the_first_frame)
774 	{
775     /* remember previous frame */
776     old_energy = new_energy;
777     old_pitch = new_pitch;
778     for (i = 0; i < 10; i++)
779         old_k[i] = new_k[i];
780 	}
781 
782     /* clear out the new frame */
783     new_energy = 0;
784     new_pitch = 0;
785     for (i = 0; i < 10; i++)
786         new_k[i] = 0;
787 
788     /* if the previous frame was a stop frame, don't do anything */
789 	if ((! the_first_frame) && (old_energy == (energytable[15] >> 6)))
790 		/*return 1;*/
791 	{
792 		buffer_empty = 1;
793 		return 1;
794 	}
795 
796 	if (speak_external)
797     	/* count the total number of bits available */
798 		bits = fifo_count * 8 - fifo_bits_taken;
799 
800     /* attempt to extract the energy index */
801 	if (speak_external)
802 	{
803     bits -= 4;
804     if (bits < 0)
805         goto ranout;
806 	}
807     indx = extract_bits(4);
808     new_energy = energytable[indx] >> 6;
809 
810 	/* if the index is 0 or 15, we're done */
811 	if (indx == 0 || indx == 15)
812 	{
813 		if (DEBUG_5220) logerror("  (4-bit energy=%d frame)\n",new_energy);
814 
815 		/* clear fifo if stop frame encountered */
816 		if (indx == 15)
817 		{
818 			fifo_head = fifo_tail = fifo_count = fifo_bits_taken = 0;
819 			speak_external = tms5220_speaking = 0;
820 			last_frame = 1;
821 		}
822 		goto done;
823 	}
824 
825     /* attempt to extract the repeat flag */
826 	if (speak_external)
827 	{
828     bits -= 1;
829     if (bits < 0)
830         goto ranout;
831 	}
832     rep_flag = extract_bits(1);
833 
834     /* attempt to extract the pitch */
835 	if (speak_external)
836 	{
837     bits -= 6;
838     if (bits < 0)
839         goto ranout;
840 	}
841     indx = extract_bits(6);
842     new_pitch = pitchtable[indx] / 256;
843 
844     /* if this is a repeat frame, just copy the k's */
845     if (rep_flag)
846     {
847         for (i = 0; i < 10; i++)
848             new_k[i] = old_k[i];
849 
850         if (DEBUG_5220) logerror("  (11-bit energy=%d pitch=%d rep=%d frame)\n", new_energy, new_pitch, rep_flag);
851         goto done;
852     }
853 
854     /* if the pitch index was zero, we need 4 k's */
855     if (indx == 0)
856     {
857         /* attempt to extract 4 K's */
858 		if (speak_external)
859 		{
860         bits -= 18;
861         if (bits < 0)
862             goto ranout;
863 		}
864         new_k[0] = k1table[extract_bits(5)];
865         new_k[1] = k2table[extract_bits(5)];
866         new_k[2] = k3table[extract_bits(4)];
867 		if (variant == variant_tms0285)
868 			new_k[3] = k3table[extract_bits(4)];	/* ??? */
869 		else
870 			new_k[3] = k4table[extract_bits(4)];
871 
872         if (DEBUG_5220) logerror("  (29-bit energy=%d pitch=%d rep=%d 4K frame)\n", new_energy, new_pitch, rep_flag);
873         goto done;
874     }
875 
876     /* else we need 10 K's */
877 	if (speak_external)
878 	{
879     bits -= 39;
880     if (bits < 0)
881         goto ranout;
882 	}
883 
884     new_k[0] = k1table[extract_bits(5)];
885     new_k[1] = k2table[extract_bits(5)];
886     new_k[2] = k3table[extract_bits(4)];
887 	if (variant == variant_tms0285)
888 		new_k[3] = k3table[extract_bits(4)];	/* ??? */
889 	else
890 		new_k[3] = k4table[extract_bits(4)];
891     new_k[4] = k5table[extract_bits(4)];
892     new_k[5] = k6table[extract_bits(4)];
893     new_k[6] = k7table[extract_bits(4)];
894     new_k[7] = k8table[extract_bits(3)];
895     new_k[8] = k9table[extract_bits(3)];
896     new_k[9] = k10table[extract_bits(3)];
897 
898     if (DEBUG_5220) logerror("  (50-bit energy=%d pitch=%d rep=%d 10K frame)\n", new_energy, new_pitch, rep_flag);
899 
900 done:
901 	if (DEBUG_5220)
902 	{
903 		if (speak_external)
904 			logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", bits);
905 		else
906 			logerror("Parsed a frame successfully in ROM\n");
907 	}
908 
909 	if (the_first_frame)
910 	{
911 		/* if this is the first frame, no previous frame to take as a starting point */
912 		old_energy = new_energy;
913 		old_pitch = new_pitch;
914 		for (i = 0; i < 10; i++)
915 			old_k[i] = new_k[i];
916     }
917 
918     /* update the buffer_low status */
919     check_buffer_low();
920     return 1;
921 
922 ranout:
923 
924     if (DEBUG_5220) logerror("Ran out of bits on a parse!\n");
925 
926     /* this is an error condition; mark the buffer empty and turn off speaking */
927     buffer_empty = 1;
928 	talk_status = speak_external = tms5220_speaking = the_first_frame = last_frame = 0;
929     fifo_count = fifo_head = fifo_tail = 0;
930 
931 	RDB_flag = FALSE;
932 
933     /* generate an interrupt if necessary */
934     set_interrupt_state(1);
935     return 0;
936 }
937 
938 
939 
940 /**********************************************************************************************
941 
942      check_buffer_low -- check to see if the buffer low flag should be on or off
943 
944 ***********************************************************************************************/
945 
check_buffer_low(void)946 static void check_buffer_low(void)
947 {
948     /* did we just become low? */
949     if (fifo_count <= 8)
950     {
951         /* generate an interrupt if necessary */
952         if (!buffer_low)
953             set_interrupt_state(1);
954         buffer_low = 1;
955 
956         if (DEBUG_5220) logerror("Buffer low set\n");
957     }
958 
959     /* did we just become full? */
960     else
961     {
962         buffer_low = 0;
963 
964         if (DEBUG_5220) logerror("Buffer low cleared\n");
965     }
966 }
967 
968 
969 
970 /**********************************************************************************************
971 
972      set_interrupt_state -- generate an interrupt
973 
974 ***********************************************************************************************/
975 
set_interrupt_state(int state)976 static void set_interrupt_state(int state)
977 {
978     if (irq_func && state != irq_pin)
979     	irq_func(state);
980     irq_pin = state;
981 }
982