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