Previous 199869 Revisions Next

r22819 Tuesday 14th May, 2013 at 10:21:05 UTC by smf
modernised TMS5220 [smf]
[src/emu/machine]spchrom.c* spchrom.h*
[src/emu/sound]sound.mak tms5220.c tms5220.h
[src/mame/audio]atarijsa.c cinemat.c exidy.c jedi.c midway.c starwars.c
[src/mame/drivers]atarisy1.c atarisy2.c esripsys.c firefox.c gauntlet.c icecold.c looping.c maygay1b.c polepos.c portrait.c tomcat.c zaccaria.c
[src/mame/includes]esripsys.h polepos.h portrait.h
[src/mame/machine]mhavoc.c
[src/mess]mess.mak
[src/mess/audio]spchroms.c spchroms.h
[src/mess/drivers]exelv.c mpf1.c pes.c
[src/mess/includes]mpf1.h
[src/mess/machine]a2echoii.c a2mockingboard.c rmnimbus.c
[src/mess/machine/ti99]spchsyn.c spchsyn.h speech8.c speech8.h

trunk/src/emu/machine/spchrom.c
r0r22819
1/*
2    spchroms.c - This is an emulator for "typical" speech ROMs from TI, as used by TI99/4(a).
3
4    In order to support its speech processor, TI designed some ROMs with a 1-bit data bus
5    and 4-bit address bus (multiplexed 5 times to provide a 18-bit address).
6    A fairly complete description of such a ROM (tms6100) is found in the tms5220 datasheet.
7
8    One notable thing is that the address is a byte address (*NOT* a bit address).
9
10    This file is designed to be interfaced with the tms5220 core.
11    Interfacing it with the tms5110 would make sense, too.
12*/
13
14#include "emu.h"
15#include "spchrom.h"
16
17#define TMS5220_ADDRESS_MASK 0x3FFFFUL  /* 18-bit mask for tms5220 address */
18
19// device type definition
20const device_type SPEECHROM = &device_creator<speechrom_device>;
21
22speechrom_device::speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
23   : device_t(mconfig, SPEECHROM, "SPEECHROM", tag, owner, clock),
24   m_speechROMaddr(0),
25   m_load_pointer(0),
26   m_ROM_bits_count(0)
27{
28}
29
30/*
31    Read 'count' bits serially from speech ROM
32*/
33int speechrom_device::read(int count)
34{
35   int val;
36
37   if (m_load_pointer)
38   {   /* first read after load address is ignored */
39      m_load_pointer = 0;
40      count--;
41   }
42
43   if (m_speechROMaddr < m_speechROMlen)
44      if (count < m_ROM_bits_count)
45      {
46         m_ROM_bits_count -= count;
47         val = (m_speechrom_data[m_speechROMaddr] >> m_ROM_bits_count) & (0xFF >> (8 - count));
48      }
49      else
50      {
51         val = ((int) m_speechrom_data[m_speechROMaddr]) << 8;
52
53         m_speechROMaddr = (m_speechROMaddr + 1) & TMS5220_ADDRESS_MASK;
54
55         if (m_speechROMaddr < m_speechROMlen)
56            val |= m_speechrom_data[m_speechROMaddr];
57
58         m_ROM_bits_count += 8 - count;
59
60         val = (val >> m_ROM_bits_count) & (0xFF >> (8 - count));
61      }
62   else
63      val = 0;
64
65   return val;
66}
67
68/*
69    Write an address nibble to speech ROM
70*/
71void speechrom_device::load_address(int data)
72{
73   /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
74     This code does not care about this. */
75   m_speechROMaddr = ( (m_speechROMaddr & ~(0xf << m_load_pointer))
76      | (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
77   m_load_pointer += 4;
78   m_ROM_bits_count = 8;
79}
80
81/*
82    Perform a read and branch command
83*/
84void speechrom_device::read_and_branch()
85{
86   /* tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
87     there is a bus contention.  This code does not care about this. */
88   if (m_speechROMaddr < m_speechROMlen-1)
89      m_speechROMaddr = (m_speechROMaddr & 0x3c000UL)
90         | (((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8)
91         | m_speechrom_data[m_speechROMaddr+1]) & 0x3fffUL);
92   else if (m_speechROMaddr == m_speechROMlen-1)
93      m_speechROMaddr = (m_speechROMaddr & 0x3c000UL)
94         | ((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8) & 0x3fffUL);
95   else
96      m_speechROMaddr = (m_speechROMaddr & 0x3c000UL);
97
98   m_ROM_bits_count = 8;
99}
100
101void speechrom_device::device_start()
102{
103   memory_region *region = memregion(tag());
104   if (region == NULL)
105   {
106      throw emu_fatalerror("No region for device '%s'\n", tag());
107   }
108
109   m_speechrom_data = region->base();
110   m_speechROMlen = region->bytes();
111
112   save_item(NAME(m_speechROMaddr));
113   save_item(NAME(m_load_pointer));
114   save_item(NAME(m_ROM_bits_count));
115}
Property changes on: trunk/src/emu/machine/spchrom.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/machine/spchrom.h
r0r22819
1/*
2 * Voice Synthesis Memory
3 *
4 */
5
6#ifndef __SPCHROMS_H
7#define __SPCHROMS_H
8
9#include "emu.h"
10
11class speechrom_device : public device_t
12{
13public:
14   // construction/destruction
15   speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
16
17   /// TODO: implement bus behaviour
18   int read(int count);
19   void load_address(int data);
20   void read_and_branch();
21
22   // device-level overrides
23   virtual void device_start();
24
25private:
26   UINT8 *m_speechrom_data;           /* pointer to speech ROM data */
27   unsigned long m_speechROMlen;      /* length of data pointed by speechrom_data, from 0 to 2^18 */
28   unsigned long m_speechROMaddr;     /* 18 bit pointer in ROM */
29   int m_load_pointer;                /* which 4-bit nibble will be affected by load address */
30   int m_ROM_bits_count;              /* current bit position in ROM */
31};
32
33
34// device type definition
35extern const device_type SPEECHROM;
36
37#endif
Property changes on: trunk/src/emu/machine/spchrom.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/sound/sound.mak
r22818r22819
644644# Texas Instruments TMS5200-series speech synthesizers
645645#-------------------------------------------------
646646ifneq ($(filter TMS5220,$(SOUNDS)),)
647SOUNDOBJS += $(SOUNDOBJ)/tms5220.o
647SOUNDOBJS += $(SOUNDOBJ)/tms5220.o $(EMUMACHINE)/spchrom.o
648648endif
649649
650650$(SOUNDOBJ)/tms5220.o:  $(SOUNDSRC)/tms5110r.c
trunk/src/emu/sound/tms5220.c
r22818r22819
251251#include "emu.h"
252252#include "tms5220.h"
253253
254static INT16 clip_analog(INT16 cliptemp);
255
254256/* *****optional defines***** */
255257
256258/* Hacky improvements which don't match patent: */
r22818r22819
258260 * One of the following two lines should be used, and the other commented
259261 * The second line is more accurate mathematically but not accurate to the patent
260262 */
261#define INTERP_SHIFT >> tms->coeff->interp_coeff[tms->IP]
262//define INTERP_SHIFT / (1<<tms->coeff->interp_coeff[tms->IP])
263#define INTERP_SHIFT >> m_coeff->interp_coeff[m_IP]
264//define INTERP_SHIFT / (1<<m_coeff->interp_coeff[m_IP])
263265
264266/* Other hacks */
265267/* HACK?: if defined, outputs the low 4 bits of the lattice filter to the i/o
r22818r22819
267269 * ...actually the tms5220c might legitamately do this! */
268270#undef ALLOW_4_LSB
269271
270/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
271#undef PERFECT_INTERPOLATION_HACK
272272
273
274273/* *****configuration of chip connection stuff***** */
275274/* must be defined; if 0, output the waveform as if it was tapped on the speaker pin as usual, if 1, output the waveform as if it was tapped on the i/o pin (volume is much lower in the latter case) */
276275#define FORCE_DIGITAL 0
r22818r22819
323322
324323static const UINT8 reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for 5220c only; 5200 and 5220 always reload with 0; keep in mind this is loaded on IP=0 PC=12 subcycle=1 so it immediately will increment after one sample, effectively being 1,3,5,7 as in the comments above.
325324
326struct tms5220_state
327{
328   /* coefficient tables */
329   int variant;                /* Variant of the 5xxx - see tms5110r.h */
330
331   /* coefficient tables */
332   const struct tms5100_coeffs *coeff;
333
334   /* callbacks */
335   devcb_resolved_write_line   irq_func;
336   devcb_resolved_write_line   readyq_func;
337
338   /* these contain data that describes the 128-bit data FIFO */
339   UINT8 fifo[FIFO_SIZE];
340   UINT8 fifo_head;
341   UINT8 fifo_tail;
342   UINT8 fifo_count;
343   UINT8 fifo_bits_taken;
344
345
346   /* these contain global status bits */
347   UINT8 speaking_now;     /* True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.*/
348   UINT8 speak_external;   /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
349   UINT8 talk_status;      /* If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts. */
350   UINT8 buffer_low;       /* If 1, FIFO has less than 8 bytes in it */
351   UINT8 buffer_empty;     /* If 1, FIFO is empty */
352   UINT8 irq_pin;          /* state of the IRQ pin (output) */
353   UINT8 ready_pin;        /* state of the READY pin (output) */
354
355   /* these contain data describing the current and previous voice frames */
356#define OLD_FRAME_SILENCE_FLAG tms->OLDE // 1 if E=0, 0 otherwise.
357#define OLD_FRAME_UNVOICED_FLAG tms->OLDP // 1 if P=0 (unvoiced), 0 if voiced
358   UINT8 OLDE;
359   UINT8 OLDP;
360
361#define NEW_FRAME_STOP_FLAG (tms->new_frame_energy_idx == 0xF) // 1 if this is a stop (Energy = 0xF) frame
362#define NEW_FRAME_SILENCE_FLAG (tms->new_frame_energy_idx == 0) // ditto as above
363#define NEW_FRAME_UNVOICED_FLAG (tms->new_frame_pitch_idx == 0) // ditto as above
364   UINT8 new_frame_energy_idx;
365   UINT8 new_frame_pitch_idx;
366   UINT8 new_frame_k_idx[10];
367
368
369   /* these are all used to contain the current state of the sound generation */
370#ifndef PERFECT_INTERPOLATION_HACK
371   INT16 current_energy;
372   INT16 current_pitch;
373   INT16 current_k[10];
374
375   INT16 target_energy;
376   INT16 target_pitch;
377   INT16 target_k[10];
378#else
379   UINT8 old_frame_energy_idx;
380   UINT8 old_frame_pitch_idx;
381   UINT8 old_frame_k_idx[10];
382
383   INT32 current_energy;
384   INT32 current_pitch;
385   INT32 current_k[10];
386
387   INT32 target_energy;
388   INT32 target_pitch;
389   INT32 target_k[10];
390#endif
391
392   UINT16 previous_energy; /* needed for lattice filter to match patent */
393
394   UINT8 subcycle;         /* contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B */
395   UINT8 subc_reload;      /* contains 1 for normal speech, 0 when SPKSLOW is active */
396   UINT8 PC;               /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
397   /* TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
398   UINT8 IP;               /* the current interpolation period */
399   UINT8 inhibit;          /* If 1, interpolation is inhibited until the DIV1 period */
400   UINT8 tms5220c_rate;    /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
401   UINT16 pitch_count;     /* pitch counter; provides chirp rom address */
402
403   INT32 u[11];
404   INT32 x[10];
405
406   UINT16 RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
407   INT16 excitation_data;
408
409   /* R Nabet : These have been added to emulate speech Roms */
410   UINT8 schedule_dummy_read;          /* set after each load address, so that next read operation is preceded by a dummy read */
411   UINT8 data_register;                /* data register, used by read command */
412   UINT8 RDB_flag;                 /* whether we should read data register or status register */
413
414   /* io_ready: page 3 of the datasheet specifies that READY will be asserted until
415    * data is available or processed by the system.
416    */
417   UINT8 io_ready;
418
419   /* flag for "true" timing involving rs/ws */
420   UINT8 true_timing;
421
422   /* rsws - state, rs bit 1, ws bit 0 */
423   UINT8 rs_ws;
424   UINT8 read_latch;
425   UINT8 write_latch;
426
427   /* The TMS52xx has two different ways of providing output data: the
428      analog speaker pin (which was usually used) and the Digital I/O pin.
429      The internal DAC used to feed the analog pin is only 8 bits, and has the
430      funny clipping/clamping logic, while the digital pin gives full 10 bit
431      resolution of the output data.
432      TODO: add a way to set/reset this other than the FORCE_DIGITAL define
433    */
434   UINT8 digital_select;
435   device_t *device;
436
437   const tms5220_interface *intf;
438   sound_stream *stream;
439   int clock;
440};
441
442
443325// Pull in the ROM tables
444326#include "tms5110r.c"
445327
446328
447INLINE tms5220_state *get_safe_token(device_t *device)
329void tms5220_device::set_variant(int variant)
448330{
449   assert(device != NULL);
450   assert(device->type() == TMS5220 ||
451         device->type() == TMS5220C ||
452         device->type() == TMC0285 ||
453         device->type() == TMS5200);
454   return (tms5220_state *)downcast<tms5220_device *>(device)->token();
455}
456
457/* Static function prototypes */
458static void process_command(tms5220_state *tms, unsigned char data);
459static void parse_frame(tms5220_state *tms);
460static void update_status_and_ints(tms5220_state *tms);
461static void set_interrupt_state(tms5220_state *tms, int state);
462static INT32 lattice_filter(tms5220_state *tms);
463static INT16 clip_analog(INT16 clip);
464static void update_ready_state(tms5220_state *tms);
465static STREAM_UPDATE( tms5220_update );
466
467static void tms5220_set_variant(tms5220_state *tms, int variant)
468{
469331   switch (variant)
470332   {
471333      case TMS5220_IS_5200:
472         tms->coeff = &tms5200_coeff;
334         m_coeff = &tms5200_coeff;
473335         break;
474336      case TMS5220_IS_5220C:
475337      case TMS5220_IS_5220:
476         tms->coeff = &tms5220_coeff;
338         m_coeff = &tms5220_coeff;
477339         break;
478340      default:
479341         fatalerror("Unknown variant in tms5220_set_variant\n");
480342   }
481   tms->variant = variant;
343   m_variant = variant;
482344}
483345
484346
485static void register_for_save_states(tms5220_state *tms)
347void tms5220_device::register_for_save_states()
486348{
487   tms->device->save_item(NAME(tms->fifo));
488   tms->device->save_item(NAME(tms->fifo_head));
489   tms->device->save_item(NAME(tms->fifo_tail));
490   tms->device->save_item(NAME(tms->fifo_count));
491   tms->device->save_item(NAME(tms->fifo_bits_taken));
349   save_item(NAME(m_fifo));
350   save_item(NAME(m_fifo_head));
351   save_item(NAME(m_fifo_tail));
352   save_item(NAME(m_fifo_count));
353   save_item(NAME(m_fifo_bits_taken));
492354
493   tms->device->save_item(NAME(tms->speaking_now));
494   tms->device->save_item(NAME(tms->speak_external));
495   tms->device->save_item(NAME(tms->talk_status));
496   tms->device->save_item(NAME(tms->buffer_low));
497   tms->device->save_item(NAME(tms->buffer_empty));
498   tms->device->save_item(NAME(tms->irq_pin));
499   tms->device->save_item(NAME(tms->ready_pin));
355   save_item(NAME(m_speaking_now));
356   save_item(NAME(m_speak_external));
357   save_item(NAME(m_talk_status));
358   save_item(NAME(m_buffer_low));
359   save_item(NAME(m_buffer_empty));
360   save_item(NAME(m_irq_pin));
361   save_item(NAME(m_ready_pin));
500362
501   tms->device->save_item(NAME(tms->OLDE));
502   tms->device->save_item(NAME(tms->OLDP));
363   save_item(NAME(m_OLDE));
364   save_item(NAME(m_OLDP));
503365
504   tms->device->save_item(NAME(tms->new_frame_energy_idx));
505   tms->device->save_item(NAME(tms->new_frame_pitch_idx));
506   tms->device->save_item(NAME(tms->new_frame_k_idx));
366   save_item(NAME(m_new_frame_energy_idx));
367   save_item(NAME(m_new_frame_pitch_idx));
368   save_item(NAME(m_new_frame_k_idx));
507369#ifdef PERFECT_INTERPOLATION_HACK
508   tms->device->save_item(NAME(tms->old_frame_energy_idx));
509   tms->device->save_item(NAME(tms->old_frame_pitch_idx));
510   tms->device->save_item(NAME(tms->old_frame_k_idx));
370   save_item(NAME(m_old_frame_energy_idx));
371   save_item(NAME(m_old_frame_pitch_idx));
372   save_item(NAME(m_old_frame_k_idx));
511373#endif
512   tms->device->save_item(NAME(tms->current_energy));
513   tms->device->save_item(NAME(tms->current_pitch));
514   tms->device->save_item(NAME(tms->current_k));
374   save_item(NAME(m_current_energy));
375   save_item(NAME(m_current_pitch));
376   save_item(NAME(m_current_k));
515377
516   tms->device->save_item(NAME(tms->target_energy));
517   tms->device->save_item(NAME(tms->target_pitch));
518   tms->device->save_item(NAME(tms->target_k));
378   save_item(NAME(m_target_energy));
379   save_item(NAME(m_target_pitch));
380   save_item(NAME(m_target_k));
519381
520   tms->device->save_item(NAME(tms->previous_energy));
382   save_item(NAME(m_previous_energy));
521383
522   tms->device->save_item(NAME(tms->subcycle));
523   tms->device->save_item(NAME(tms->subc_reload));
524   tms->device->save_item(NAME(tms->PC));
525   tms->device->save_item(NAME(tms->IP));
526   tms->device->save_item(NAME(tms->inhibit));
527   tms->device->save_item(NAME(tms->tms5220c_rate));
528   tms->device->save_item(NAME(tms->pitch_count));
384   save_item(NAME(m_subcycle));
385   save_item(NAME(m_subc_reload));
386   save_item(NAME(m_PC));
387   save_item(NAME(m_IP));
388   save_item(NAME(m_inhibit));
389   save_item(NAME(m_tms5220c_rate));
390   save_item(NAME(m_pitch_count));
529391
530   tms->device->save_item(NAME(tms->u));
531   tms->device->save_item(NAME(tms->x));
392   save_item(NAME(m_u));
393   save_item(NAME(m_x));
532394
533   tms->device->save_item(NAME(tms->RNG));
534   tms->device->save_item(NAME(tms->excitation_data));
395   save_item(NAME(m_RNG));
396   save_item(NAME(m_excitation_data));
535397
536   tms->device->save_item(NAME(tms->schedule_dummy_read));
537   tms->device->save_item(NAME(tms->data_register));
538   tms->device->save_item(NAME(tms->RDB_flag));
539   tms->device->save_item(NAME(tms->digital_select));
398   save_item(NAME(m_schedule_dummy_read));
399   save_item(NAME(m_data_register));
400   save_item(NAME(m_RDB_flag));
401   save_item(NAME(m_digital_select));
540402
541   tms->device->save_item(NAME(tms->io_ready));
403   save_item(NAME(m_io_ready));
542404}
543405
544406
r22818r22819
586448
587449***********************************************************************************************/
588450
589static void tms5220_data_write(tms5220_state *tms, int data)
451void tms5220_device::data_write(int data)
590452{
591453#ifdef DEBUG_DUMP_INPUT_DATA
592454   fprintf(stdout, "%c",data);
593455#endif
594   if (tms->speak_external) // If we're in speak external mode
456   if (m_speak_external) // If we're in speak external mode
595457   {
596458      // add this byte to the FIFO
597      if (tms->fifo_count < FIFO_SIZE)
459      if (m_fifo_count < FIFO_SIZE)
598460      {
599         tms->fifo[tms->fifo_tail] = data;
600         tms->fifo_tail = (tms->fifo_tail + 1) % FIFO_SIZE;
601         tms->fifo_count++;
461         m_fifo[m_fifo_tail] = data;
462         m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE;
463         m_fifo_count++;
602464#ifdef DEBUG_FIFO
603         logerror("data_write: Added byte to FIFO (current count=%2d)\n", tms->fifo_count);
465         logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
604466#endif
605         update_status_and_ints(tms);
606         if ((tms->talk_status == 0) && (tms->buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
467         update_status_and_ints();
468         if ((m_talk_status == 0) && (m_buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
607469         {
608470         int i;
609471#ifdef DEBUG_FIFO
r22818r22819
611473#endif
612474            // ...then we now have enough bytes to start talking; clear out the new frame parameters (it will become old frame just before the first call to parse_frame() )
613475            // TODO: the 3 lines below (and others) are needed for victory to not fail its selftest due to a sample ending too late, may require additional investigation
614            tms->subcycle = tms->subc_reload;
615            tms->PC = 0;
616            tms->IP = reload_table[tms->tms5220c_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
617            tms->new_frame_energy_idx = 0;
618            tms->new_frame_pitch_idx = 0;
476            m_subcycle = m_subc_reload;
477            m_PC = 0;
478            m_IP = reload_table[m_tms5220c_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
479            m_new_frame_energy_idx = 0;
480            m_new_frame_pitch_idx = 0;
619481            for (i = 0; i < 4; i++)
620               tms->new_frame_k_idx[i] = 0;
482               m_new_frame_k_idx[i] = 0;
621483            for (i = 4; i < 7; i++)
622               tms->new_frame_k_idx[i] = 0xF;
623            for (i = 7; i < tms->coeff->num_k; i++)
624               tms->new_frame_k_idx[i] = 0x7;
625            tms->talk_status = tms->speaking_now = 1;
484               m_new_frame_k_idx[i] = 0xF;
485            for (i = 7; i < m_coeff->num_k; i++)
486               m_new_frame_k_idx[i] = 0x7;
487            m_talk_status = m_speaking_now = 1;
626488         }
627489      }
628490      else
r22818r22819
635497
636498
637499   }
638   else //(! tms->speak_external)
500   else //(! m_speak_external)
639501      // R Nabet : we parse commands at once.  It is necessary for such commands as read.
640      process_command(tms,data);
502      process_command(data);
641503}
642504
643505/**********************************************************************************************
r22818r22819
663525
664526***********************************************************************************************/
665527
666static void update_status_and_ints(tms5220_state *tms)
528void tms5220_device::update_status_and_ints()
667529{
668530   /* update flags and set ints if needed */
669531
670   update_ready_state(tms);
532   update_ready_state();
671533
672534   /* BL is set if neither byte 9 nor 8 of the fifo are in use; this
673535   translates to having fifo_count (which ranges from 0 bytes in use to 16
674536   bytes used) being less than or equal to 8. Victory/Victorba depends on this. */
675   if (tms->fifo_count <= 8)
537   if (m_fifo_count <= 8)
676538   {
677539      // generate an interrupt if necessary; if /BL was inactive and is now active, set int.
678      if (!tms->buffer_low)
679         set_interrupt_state(tms, 1);
680      tms->buffer_low = 1;
540      if (!m_buffer_low)
541         set_interrupt_state(1);
542      m_buffer_low = 1;
681543   }
682544   else
683      tms->buffer_low = 0;
545      m_buffer_low = 0;
684546
685547   /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
686548   translates to having fifo_count equal to exactly 0 */
687   if (tms->fifo_count == 0)
549   if (m_fifo_count == 0)
688550   {
689551      // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
690      if (!tms->buffer_empty)
691         set_interrupt_state(tms, 1);
692      tms->buffer_empty = 1;
552      if (!m_buffer_empty)
553         set_interrupt_state(1);
554      m_buffer_empty = 1;
693555   }
694556   else
695      tms->buffer_empty = 0;
557      m_buffer_empty = 0;
696558
697559   /* TS is talk status and is set elsewhere in the fifo parser and in
698560   the SPEAK command handler; however, if /BE is true during speak external
699561   mode, it is immediately unset here. */
700   if ((tms->speak_external == 1) && (tms->buffer_empty == 1))
562   if ((m_speak_external == 1) && (m_buffer_empty == 1))
701563   {
702564      // generate an interrupt: /TS was active, and is now inactive.
703      if (tms->talk_status == 1)
565      if (m_talk_status == 1)
704566      {
705         tms->talk_status = tms->speak_external = 0;
706         set_interrupt_state(tms, 1);
567         m_talk_status = m_speak_external = 0;
568         set_interrupt_state(1);
707569      }
708570   }
709571   /* Note that TS being unset will also generate an interrupt when a STOP
r22818r22819
716578
717579***********************************************************************************************/
718580
719static int extract_bits(tms5220_state *tms, int count)
581int tms5220_device::extract_bits(int count)
720582{
721583   int val = 0;
722584
723   if (tms->speak_external)
585   if (m_speak_external)
724586   {
725587      // extract from FIFO
726588      while (count--)
727589      {
728         val = (val << 1) | ((tms->fifo[tms->fifo_head] >> tms->fifo_bits_taken) & 1);
729         tms->fifo_bits_taken++;
730         if (tms->fifo_bits_taken >= 8)
590         val = (val << 1) | ((m_fifo[m_fifo_head] >> m_fifo_bits_taken) & 1);
591         m_fifo_bits_taken++;
592         if (m_fifo_bits_taken >= 8)
731593         {
732            tms->fifo_count--;
733            tms->fifo[tms->fifo_head] = 0; // zero the newly depleted fifo head byte
734            tms->fifo_head = (tms->fifo_head + 1) % FIFO_SIZE;
735            tms->fifo_bits_taken = 0;
736            update_status_and_ints(tms);
594            m_fifo_count--;
595            m_fifo[m_fifo_head] = 0; // zero the newly depleted fifo head byte
596            m_fifo_head = (m_fifo_head + 1) % FIFO_SIZE;
597            m_fifo_bits_taken = 0;
598            update_status_and_ints();
737599         }
738600      }
739601   }
740602   else
741603   {
742604      // extract from VSM (speech ROM)
743      if (tms->intf->read)
744         val = (* tms->intf->read)(tms->device, count);
605      if (m_speechrom)
606         val = m_speechrom->read(count);
745607   }
746608
747609   return val;
r22818r22819
753615
754616***********************************************************************************************/
755617
756static int tms5220_status_read(tms5220_state *tms)
618int tms5220_device::status_read()
757619{
758   if (tms->RDB_flag)
620   if (m_RDB_flag)
759621   {   /* if last command was read, return data register */
760      tms->RDB_flag = FALSE;
761      return(tms->data_register);
622      m_RDB_flag = FALSE;
623      return(m_data_register);
762624   }
763625   else
764626   {   /* read status */
765627
766628      /* clear the interrupt pin on status read */
767      set_interrupt_state(tms, 0);
629      set_interrupt_state(0);
768630#ifdef DEBUG_PIN_READS
769      logerror("Status read: TS=%d BL=%d BE=%d\n", tms->talk_status, tms->buffer_low, tms->buffer_empty);
631      logerror("Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty);
770632#endif
771633
772      return (tms->talk_status << 7) | (tms->buffer_low << 6) | (tms->buffer_empty << 5);
634      return (m_talk_status << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
773635   }
774636}
775637
r22818r22819
780642
781643***********************************************************************************************/
782644
783static int tms5220_ready_read(tms5220_state *tms)
645int tms5220_device::ready_read()
784646{
785647#ifdef DEBUG_PIN_READS
786   logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", tms->io_ready, tms->fifo_count);
648   logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count);
787649#endif
788   return ((tms->fifo_count < FIFO_SIZE)||(!tms->speak_external)) && tms->io_ready;
650   return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready;
789651}
790652
791653
r22818r22819
797659
798660***********************************************************************************************/
799661
800static int tms5220_cycles_to_ready(tms5220_state *tms)
662int tms5220_device::cycles_to_ready()
801663{
802664   int answer;
803665
804666
805   if (tms5220_ready_read(tms))
667   if (ready_read())
806668      answer = 0;
807669   else
808670   {
809671      int val;
810      int samples_per_frame = tms->subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
811      int current_sample = ((tms->PC*(3-tms->subc_reload))+((tms->subc_reload?38:25)*tms->IP));
672      int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
673      int current_sample = ((m_PC*(3-m_subc_reload))+((m_subc_reload?38:25)*m_IP));
812674      answer = samples_per_frame-current_sample+8;
813675
814      // total number of bits available in current byte is (8 - tms->fifo_bits_taken)
676      // total number of bits available in current byte is (8 - m_fifo_bits_taken)
815677      // if more than 4 are available, we need to check the energy
816      if (tms->fifo_bits_taken < 4)
678      if (m_fifo_bits_taken < 4)
817679      {
818680         // read energy
819         val = (tms->fifo[tms->fifo_head] >> tms->fifo_bits_taken) & 0xf;
681         val = (m_fifo[m_fifo_head] >> m_fifo_bits_taken) & 0xf;
820682         if (val == 0)
821683            /* 0 -> silence frame: we will only read 4 bits, and we will
822684             * therefore need to read another frame before the FIFO is not
823685             * full any more */
824            answer += tms->subc_reload?200:304;
686            answer += m_subc_reload?200:304;
825687         /* 15 -> stop frame, we will only read 4 bits, but the FIFO will
826688          * we cleared; otherwise, we need to parse the repeat flag (1 bit)
827689          * and the pitch (6 bits), so everything will be OK. */
r22818r22819
838700
839701***********************************************************************************************/
840702
841static int tms5220_int_read(tms5220_state *tms)
703int tms5220_device::int_read()
842704{
843705#ifdef DEBUG_PIN_READS
844   logerror("int_read: irq pin read, state is %d\n", tms->irq_pin);
706   logerror("int_read: irq pin read, state is %d\n", m_irq_pin);
845707#endif
846   return tms->irq_pin;
708   return m_irq_pin;
847709}
848710
849711
r22818r22819
853715
854716***********************************************************************************************/
855717
856static void tms5220_process(tms5220_state *tms, INT16 *buffer, unsigned int size)
718void tms5220_device::process(INT16 *buffer, unsigned int size)
857719{
858720   int buf_count=0;
859721   int i, bitout, zpar;
r22818r22819
861723
862724   /* the following gotos are probably safe to remove */
863725   /* if we're empty and still not speaking, fill with nothingness */
864   if (!tms->speaking_now)
726   if (!m_speaking_now)
865727      goto empty;
866728
867729   /* if speak external is set, but talk status is not (yet) set,
868730   wait for buffer low to clear */
869   if (!tms->talk_status && tms->speak_external && tms->buffer_low)
731   if (!m_talk_status && m_speak_external && m_buffer_low)
870732      goto empty;
871733
872734   /* loop until the buffer is full or we've stopped speaking */
873   while ((size > 0) && tms->speaking_now)
735   while ((size > 0) && m_speaking_now)
874736   {
875737      /* if it is the appropriate time to update the old energy/pitch idxes,
876738       * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
877739       * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
878740       * which happens 4 T-cycles later), we change on the latter.*/
879      if ((tms->IP == 0) && (tms->PC == 0) && (tms->subcycle < 2))
741      if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2))
880742      {
881         tms->OLDE = (tms->new_frame_energy_idx == 0);
882         tms->OLDP = (tms->new_frame_pitch_idx == 0);
743         m_OLDE = (m_new_frame_energy_idx == 0);
744         m_OLDP = (m_new_frame_pitch_idx == 0);
883745      }
884746
885747      /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
886748       * (In reality, the frame was really loaded incrementally during the entire IP=0
887749       * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
888750       */
889      if ((tms->IP == 0) && (tms->PC == 12) && (tms->subcycle == 1))
751      if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
890752      {
891753         // HACK for regression testing, be sure to comment out before release!
892         //tms->RNG = 0x1234;
754         //m_RNG = 0x1234;
893755         // end HACK
894756
895757         /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
896         tms->IP = reload_table[tms->tms5220c_rate&0x3];
758         m_IP = reload_table[m_tms5220c_rate&0x3];
897759
898760#ifdef PERFECT_INTERPOLATION_HACK
899761         /* remember previous frame energy, pitch, and coefficients */
900         tms->old_frame_energy_idx = tms->new_frame_energy_idx;
901         tms->old_frame_pitch_idx = tms->new_frame_pitch_idx;
902         for (i = 0; i < tms->coeff->num_k; i++)
903            tms->old_frame_k_idx[i] = tms->new_frame_k_idx[i];
762         m_old_frame_energy_idx = m_new_frame_energy_idx;
763         m_old_frame_pitch_idx = m_new_frame_pitch_idx;
764         for (i = 0; i < m_coeff->num_k; i++)
765            m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
904766#endif
905767
906768         /* if the talk status was clear last frame, halt speech now. */
907         if (tms->talk_status == 0)
769         if (m_talk_status == 0)
908770         {
909771#ifdef DEBUG_GENERATION
910772            fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n");
911773#endif
912            tms->speaking_now = 0; // finally halt speech
774            m_speaking_now = 0; // finally halt speech
913775            goto empty;
914776         }
915777
916778
917779         /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
918         parse_frame(tms);
780         parse_frame();
919781#ifdef DEBUG_PARSE_FRAME_DUMP
920782         fprintf(stderr,"\n");
921783#endif
r22818r22819
923785         /* if the new frame is a stop frame, set an interrupt and set talk status to 0 */
924786         if (NEW_FRAME_STOP_FLAG == 1)
925787            {
926               tms->talk_status = tms->speak_external = 0;
927               set_interrupt_state(tms, 1);
928               update_status_and_ints(tms);
788               m_talk_status = m_speak_external = 0;
789               set_interrupt_state(1);
790               update_status_and_ints();
929791            }
930792
931793         /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
r22818r22819
937799         if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
938800            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */
939801            || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) )
940            tms->inhibit = 1;
802            m_inhibit = 1;
941803         else // normal frame, normal interpolation
942            tms->inhibit = 0;
804            m_inhibit = 0;
943805
944806         /* load new frame targets from tables, using parsed indices */
945         tms->target_energy = tms->coeff->energytable[tms->new_frame_energy_idx];
946         tms->target_pitch = tms->coeff->pitchtable[tms->new_frame_pitch_idx];
807         m_target_energy = m_coeff->energytable[m_new_frame_energy_idx];
808         m_target_pitch = m_coeff->pitchtable[m_new_frame_pitch_idx];
947809         zpar = NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed
948810         for (i = 0; i < 4; i++)
949            tms->target_k[i] = tms->coeff->ktable[i][tms->new_frame_k_idx[i]];
950         for (i = 4; i < tms->coeff->num_k; i++)
951            tms->target_k[i] = (tms->coeff->ktable[i][tms->new_frame_k_idx[i]] * (1-zpar));
811            m_target_k[i] = m_coeff->ktable[i][m_new_frame_k_idx[i]];
812         for (i = 4; i < m_coeff->num_k; i++)
813            m_target_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-zpar));
952814
953815#ifdef DEBUG_GENERATION
954816         /* Debug info for current parsed frame */
955         fprintf(stderr, "OLDE: %d; OLDP: %d; ", tms->OLDE, tms->OLDP);
817         fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
956818         fprintf(stderr,"Processing frame: ");
957         if (tms->inhibit == 0)
819         if (m_inhibit == 0)
958820            fprintf(stderr, "Normal Frame\n");
959821         else
960822            fprintf(stderr,"Interpolation Inhibited\n");
961         fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",tms->current_energy, tms->current_pitch, tms->current_k[0], tms->current_k[1], tms->current_k[2], tms->current_k[3], tms->current_k[4], tms->current_k[5], tms->current_k[6], tms->current_k[7], tms->current_k[8], tms->current_k[9]);
962         fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",tms->target_energy, tms->new_frame_energy_idx, tms->target_pitch, tms->target_k[0], tms->target_k[1], tms->target_k[2], tms->target_k[3], tms->target_k[4], tms->target_k[5], tms->target_k[6], tms->target_k[7], tms->target_k[8], tms->target_k[9]);
823         fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]);
824         fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_target_energy, m_new_frame_energy_idx, m_target_pitch, m_target_k[0], m_target_k[1], m_target_k[2], m_target_k[3], m_target_k[4], m_target_k[5], m_target_k[6], m_target_k[7], m_target_k[8], m_target_k[9]);
963825#endif
964826
965827         /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
966         if (tms->talk_status == 0)
828         if (m_talk_status == 0)
967829         {
968830#ifdef DEBUG_GENERATION
969831            fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
970832#endif
971            tms->target_energy = 0;
833            m_target_energy = 0;
972834         }
973835      }
974836      else // Not a new frame, just interpolate the existing frame.
975837      {
976         int inhibit_state = ((tms->inhibit==1)&&(tms->IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the tms->inhibit value
838         int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value
977839#ifdef PERFECT_INTERPOLATION_HACK
978         int samples_per_frame = tms->subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW
979         //int samples_per_frame = tms->subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
980         int current_sample = (tms->subcycle - tms->subc_reload)+(tms->PC*(3-tms->subc_reload))+((tms->subc_reload?25:38)*((tms->IP-1)&7));
840         int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW
841         //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
842         int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
981843
982844         zpar = OLD_FRAME_UNVOICED_FLAG;
983845         //fprintf(stderr, "CS: %03d", current_sample);
984846         // reset the current energy, pitch, etc to what it was at frame start
985         tms->current_energy = tms->coeff->energytable[tms->old_frame_energy_idx];
986         tms->current_pitch = tms->coeff->pitchtable[tms->old_frame_pitch_idx];
847         m_current_energy = m_coeff->energytable[m_old_frame_energy_idx];
848         m_current_pitch = m_coeff->pitchtable[m_old_frame_pitch_idx];
987849         for (i = 0; i < 4; i++)
988            tms->current_k[i] = tms->coeff->ktable[i][tms->old_frame_k_idx[i]];
989         for (i = 4; i < tms->coeff->num_k; i++)
990            tms->current_k[i] = (tms->coeff->ktable[i][tms->old_frame_k_idx[i]] * (1-zpar));
850            m_current_k[i] = m_coeff->ktable[i][m_old_frame_k_idx[i]];
851         for (i = 4; i < m_coeff->num_k; i++)
852            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-zpar));
991853         // now adjust each value to be exactly correct for each of the samples per frame
992         if (tms->IP != 0) // if we're still interpolating...
854         if (m_IP != 0) // if we're still interpolating...
993855         {
994            tms->current_energy += (((tms->target_energy - tms->current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
995            tms->current_pitch += (((tms->target_pitch - tms->current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
996            for (i = 0; i < tms->coeff->num_k; i++)
997               tms->current_k[i] += (((tms->target_k[i] - tms->current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
856            m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
857            m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
858            for (i = 0; i < m_coeff->num_k; i++)
859               m_current_k[i] += (((m_target_k[i] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
998860         }
999861         else // we're done, play this frame for 1/8 frame.
1000862         {
1001            tms->current_energy = tms->target_energy;
1002            tms->current_pitch = tms->target_pitch;
1003            for (i = 0; i < tms->coeff->num_k; i++)
1004               tms->current_k[i] = tms->target_k[i];
863            m_current_energy = m_target_energy;
864            m_current_pitch = m_target_pitch;
865            for (i = 0; i < m_coeff->num_k; i++)
866               m_current_k[i] = m_target_k[i];
1005867         }
1006868#else
1007869         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
1008         if (tms->subcycle == 2)
870         if (m_subcycle == 2)
1009871         {
1010            switch(tms->PC)
872            switch(m_PC)
1011873            {
1012874               case 0: /* PC = 0, B cycle, write updated energy */
1013               tms->current_energy += (((tms->target_energy - tms->current_energy)*(1-inhibit_state)) INTERP_SHIFT);
875               m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT);
1014876               break;
1015877               case 1: /* PC = 1, B cycle, write updated pitch */
1016               tms->current_pitch += (((tms->target_pitch - tms->current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
878               m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
1017879               break;
1018880               case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
1019881               /* PC = 2 through 11, B cycle, write updated K1 through K10 */
1020               tms->current_k[tms->PC-2] += (((tms->target_k[tms->PC-2] - tms->current_k[tms->PC-2])*(1-inhibit_state)) INTERP_SHIFT);
882               m_current_k[m_PC-2] += (((m_target_k[m_PC-2] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT);
1021883               break;
1022884               case 12: /* PC = 12, do nothing */
1023885               break;
r22818r22819
1030892      if (OLD_FRAME_UNVOICED_FLAG == 1)
1031893      {
1032894         // generate unvoiced samples here
1033         if (tms->RNG & 1)
1034            tms->excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/
895         if (m_RNG & 1)
896            m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/
1035897         else
1036            tms->excitation_data = 0x40;
898            m_excitation_data = 0x40;
1037899      }
1038900      else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
1039901      {
r22818r22819
1044906          * and if the address reaches that point the ADDRESS incrementer is
1045907          * disabled, forcing all samples beyond 51d to be == 51d
1046908          */
1047         if (tms->pitch_count >= 51)
1048            tms->excitation_data = tms->coeff->chirptable[51];
1049         else /*tms->pitch_count < 51*/
1050            tms->excitation_data = tms->coeff->chirptable[tms->pitch_count];
909         if (m_pitch_count >= 51)
910            m_excitation_data = m_coeff->chirptable[51];
911         else /*m_pitch_count < 51*/
912            m_excitation_data = m_coeff->chirptable[m_pitch_count];
1051913      }
1052914
1053915      // Update LFSR *20* times every sample (once per T cycle), like patent shows
1054916   for (i=0; i<20; i++)
1055917   {
1056      bitout = ((tms->RNG >> 12) & 1) ^
1057            ((tms->RNG >>  3) & 1) ^
1058            ((tms->RNG >>  2) & 1) ^
1059            ((tms->RNG >>  0) & 1);
1060      tms->RNG <<= 1;
1061      tms->RNG |= bitout;
918      bitout = ((m_RNG >> 12) & 1) ^
919            ((m_RNG >>  3) & 1) ^
920            ((m_RNG >>  2) & 1) ^
921            ((m_RNG >>  0) & 1);
922      m_RNG <<= 1;
923      m_RNG |= bitout;
1062924   }
1063      this_sample = lattice_filter(tms); /* execute lattice filter */
925      this_sample = lattice_filter(); /* execute lattice filter */
1064926#ifdef DEBUG_GENERATION_VERBOSE
1065      //fprintf(stderr,"C:%01d; ",tms->subcycle);
1066      fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",tms->IP, tms->PC, tms->excitation_data, tms->current_energy, tms->current_pitch, tms->pitch_count);
1067      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", tms->excitation_data, tms->current_energy, tms->current_pitch, tms->pitch_count);
927      //fprintf(stderr,"C:%01d; ",m_subcycle);
928      fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
929      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
1068930      for (i=0; i<10; i++)
1069         fprintf(stderr,"K%d:%04d ", i+1, tms->current_k[i]);
931         fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
1070932      fprintf(stderr,"Out:%06d", this_sample);
1071933      fprintf(stderr,"\n");
1072934#endif
1073935      /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
1074936      while (this_sample > 16383) this_sample -= 32768;
1075937      while (this_sample < -16384) this_sample += 32768;
1076      if (tms->digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
938      if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
1077939         buffer[buf_count] = clip_analog(this_sample);
1078940      else // digital I/O pin output is 12 bits
1079941      {
r22818r22819
1092954      }
1093955      // Update all counts
1094956
1095      tms->subcycle++;
1096      if ((tms->subcycle == 2) && (tms->PC == 12))
957      m_subcycle++;
958      if ((m_subcycle == 2) && (m_PC == 12))
1097959      {
1098960         /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
1099961          * if INHIBIT was true during the most recent frame transition.
1100962          * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
1101          * and tms->IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
963          * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
1102964          * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
1103965          * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
1104966          * convenient and should make no difference in output.
1105967          */
1106         if ((tms->IP == 7)&&(tms->inhibit==1)) tms->pitch_count = 0;
1107         tms->subcycle = tms->subc_reload;
1108         tms->PC = 0;
1109         tms->IP++;
1110         tms->IP&=0x7;
968         if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_count = 0;
969         m_subcycle = m_subc_reload;
970         m_PC = 0;
971         m_IP++;
972         m_IP&=0x7;
1111973      }
1112      else if (tms->subcycle == 3)
974      else if (m_subcycle == 3)
1113975      {
1114         tms->subcycle = tms->subc_reload;
1115         tms->PC++;
976         m_subcycle = m_subc_reload;
977         m_PC++;
1116978      }
1117      tms->pitch_count++;
1118      if (tms->pitch_count >= tms->current_pitch) tms->pitch_count = 0;
1119      tms->pitch_count &= 0x1FF;
979      m_pitch_count++;
980      if (m_pitch_count >= m_current_pitch) m_pitch_count = 0;
981      m_pitch_count &= 0x1FF;
1120982      buf_count++;
1121983      size--;
1122984   }
r22818r22819
1125987
1126988   while (size > 0)
1127989   {
1128      tms->subcycle++;
1129      if ((tms->subcycle == 2) && (tms->PC == 12))
990      m_subcycle++;
991      if ((m_subcycle == 2) && (m_PC == 12))
1130992      {
1131         tms->subcycle = tms->subc_reload;
1132         tms->PC = 0;
1133         tms->IP++;
1134         tms->IP&=0x7;
993         m_subcycle = m_subc_reload;
994         m_PC = 0;
995         m_IP++;
996         m_IP&=0x7;
1135997      }
1136      else if (tms->subcycle == 3)
998      else if (m_subcycle == 3)
1137999      {
1138         tms->subcycle = tms->subc_reload;
1139         tms->PC++;
1000         m_subcycle = m_subc_reload;
1001         m_PC++;
11401002      }
11411003      buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
11421004      buf_count++;
r22818r22819
12151077
12161078***********************************************************************************************/
12171079
1218static INT32 lattice_filter(tms5220_state *tms)
1080INT32 tms5220_device::lattice_filter()
12191081{
12201082   // Lattice filter here
12211083   // Aug/05/07: redone as unrolled loop, for clarity - LN
12221084   /* Originally Copied verbatim from table I in US patent 4,209,804, now updated to be in same order as the actual chip does it, not that it matters.
12231085     notation equivalencies from table:
1224     Yn(i) == tms->u[n-1]
1225     Kn = tms->current_k[n-1]
1226     bn = tms->x[n-1]
1086     Yn(i) == m_u[n-1]
1087     Kn = m_current_k[n-1]
1088     bn = m_x[n-1]
12271089    */
1228      tms->u[10] = matrix_multiply(tms->previous_energy, (tms->excitation_data<<6));  //Y(11)
1229      tms->u[9] = tms->u[10] - matrix_multiply(tms->current_k[9], tms->x[9]);
1230      tms->u[8] = tms->u[9] - matrix_multiply(tms->current_k[8], tms->x[8]);
1231      tms->u[7] = tms->u[8] - matrix_multiply(tms->current_k[7], tms->x[7]);
1232      tms->u[6] = tms->u[7] - matrix_multiply(tms->current_k[6], tms->x[6]);
1233      tms->u[5] = tms->u[6] - matrix_multiply(tms->current_k[5], tms->x[5]);
1234      tms->u[4] = tms->u[5] - matrix_multiply(tms->current_k[4], tms->x[4]);
1235      tms->u[3] = tms->u[4] - matrix_multiply(tms->current_k[3], tms->x[3]);
1236      tms->u[2] = tms->u[3] - matrix_multiply(tms->current_k[2], tms->x[2]);
1237      tms->u[1] = tms->u[2] - matrix_multiply(tms->current_k[1], tms->x[1]);
1238      tms->u[0] = tms->u[1] - matrix_multiply(tms->current_k[0], tms->x[0]);
1239      tms->x[9] = tms->x[8] + matrix_multiply(tms->current_k[8], tms->u[8]);
1240      tms->x[8] = tms->x[7] + matrix_multiply(tms->current_k[7], tms->u[7]);
1241      tms->x[7] = tms->x[6] + matrix_multiply(tms->current_k[6], tms->u[6]);
1242      tms->x[6] = tms->x[5] + matrix_multiply(tms->current_k[5], tms->u[5]);
1243      tms->x[5] = tms->x[4] + matrix_multiply(tms->current_k[4], tms->u[4]);
1244      tms->x[4] = tms->x[3] + matrix_multiply(tms->current_k[3], tms->u[3]);
1245      tms->x[3] = tms->x[2] + matrix_multiply(tms->current_k[2], tms->u[2]);
1246      tms->x[2] = tms->x[1] + matrix_multiply(tms->current_k[1], tms->u[1]);
1247      tms->x[1] = tms->x[0] + matrix_multiply(tms->current_k[0], tms->u[0]);
1248      tms->x[0] = tms->u[0];
1249      tms->previous_energy = tms->current_energy;
1090      m_u[10] = matrix_multiply(m_previous_energy, (m_excitation_data<<6));  //Y(11)
1091      m_u[9] = m_u[10] - matrix_multiply(m_current_k[9], m_x[9]);
1092      m_u[8] = m_u[9] - matrix_multiply(m_current_k[8], m_x[8]);
1093      m_u[7] = m_u[8] - matrix_multiply(m_current_k[7], m_x[7]);
1094      m_u[6] = m_u[7] - matrix_multiply(m_current_k[6], m_x[6]);
1095      m_u[5] = m_u[6] - matrix_multiply(m_current_k[5], m_x[5]);
1096      m_u[4] = m_u[5] - matrix_multiply(m_current_k[4], m_x[4]);
1097      m_u[3] = m_u[4] - matrix_multiply(m_current_k[3], m_x[3]);
1098      m_u[2] = m_u[3] - matrix_multiply(m_current_k[2], m_x[2]);
1099      m_u[1] = m_u[2] - matrix_multiply(m_current_k[1], m_x[1]);
1100      m_u[0] = m_u[1] - matrix_multiply(m_current_k[0], m_x[0]);
1101      m_x[9] = m_x[8] + matrix_multiply(m_current_k[8], m_u[8]);
1102      m_x[8] = m_x[7] + matrix_multiply(m_current_k[7], m_u[7]);
1103      m_x[7] = m_x[6] + matrix_multiply(m_current_k[6], m_u[6]);
1104      m_x[6] = m_x[5] + matrix_multiply(m_current_k[5], m_u[5]);
1105      m_x[5] = m_x[4] + matrix_multiply(m_current_k[4], m_u[4]);
1106      m_x[4] = m_x[3] + matrix_multiply(m_current_k[3], m_u[3]);
1107      m_x[3] = m_x[2] + matrix_multiply(m_current_k[2], m_u[2]);
1108      m_x[2] = m_x[1] + matrix_multiply(m_current_k[1], m_u[1]);
1109      m_x[1] = m_x[0] + matrix_multiply(m_current_k[0], m_u[0]);
1110      m_x[0] = m_u[0];
1111      m_previous_energy = m_current_energy;
12501112#ifdef DEBUG_LATTICE
12511113      int i;
1252      fprintf(stderr,"V:%04d ", tms->u[10]);
1114      fprintf(stderr,"V:%04d ", m_u[10]);
12531115      for (i = 9; i >= 0; i--)
12541116      {
1255         fprintf(stderr,"Y%d:%04d ", i+1, tms->u[i]);
1256         fprintf(stderr,"b%d:%04d ", i+1, tms->x[i]);
1117         fprintf(stderr,"Y%d:%04d ", i+1, m_u[i]);
1118         fprintf(stderr,"b%d:%04d ", i+1, m_x[i]);
12571119         if ((i % 5) == 0) fprintf(stderr,"\n");
12581120      }
12591121#endif
1260      return tms->u[0];
1122      return m_u[0];
12611123}
12621124
12631125
r22818r22819
12671129
12681130***********************************************************************************************/
12691131
1270static void process_command(tms5220_state *tms, unsigned char cmd)
1132void tms5220_device::process_command(unsigned char cmd)
12711133{
12721134#ifdef DEBUG_COMMAND_DUMP
12731135      fprintf(stderr,"process_command called with parameter %02X\n",cmd);
r22818r22819
12761138      switch (cmd & 0x70)
12771139      {
12781140      case 0x10 : /* read byte */
1279         if (tms->talk_status == 0) /* TALKST must be clear for RDBY */
1141         if (m_talk_status == 0) /* TALKST must be clear for RDBY */
12801142         {
1281            if (tms->schedule_dummy_read)
1143            if (m_schedule_dummy_read)
12821144            {
1283               tms->schedule_dummy_read = FALSE;
1284               if (tms->intf->read)
1285                  (*tms->intf->read)(tms->device, 1);
1145               m_schedule_dummy_read = FALSE;
1146               if (m_speechrom)
1147                  m_speechrom->read(1);
12861148            }
1287            if (tms->intf->read)
1288               tms->data_register = (*tms->intf->read)(tms->device, 8);    /* read one byte from speech ROM... */
1289            tms->RDB_flag = TRUE;
1149            if (m_speechrom)
1150               m_data_register = m_speechrom->read(8);    /* read one byte from speech ROM... */
1151            m_RDB_flag = TRUE;
12901152         }
12911153         break;
12921154
12931155      case 0x00: case 0x20: /* set rate (tms5220c only), otherwise NOP */
1294         if (tms->variant == TMS5220_IS_5220C)
1156         if (m_variant == TMS5220_IS_5220C)
12951157         {
1296            tms->tms5220c_rate = cmd&0x0F;
1158            m_tms5220c_rate = cmd&0x0F;
12971159         }
12981160      break;
12991161
13001162      case 0x30 : /* read and branch */
1301         if (tms->talk_status == 0) /* TALKST must be clear for RB */
1163         if (m_talk_status == 0) /* TALKST must be clear for RB */
13021164         {
13031165#ifdef VERBOSE
13041166            logerror("read and branch command received\n");
13051167#endif
1306            tms->RDB_flag = FALSE;
1307            if (tms->intf->read_and_branch)
1308               (*tms->intf->read_and_branch)(tms->device);
1168            m_RDB_flag = FALSE;
1169            if (m_speechrom)
1170               m_speechrom->read_and_branch();
13091171         }
13101172         break;
13111173
13121174      case 0x40 : /* load address */
1313         if (tms->talk_status == 0) /* TALKST must be clear for LA */
1175         if (m_talk_status == 0) /* TALKST must be clear for LA */
13141176         {
13151177            /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
13161178               This code does not care about this. */
1317            if (tms->intf->load_address)
1318               (*tms->intf->load_address)(tms->device, cmd & 0x0f);
1319            tms->schedule_dummy_read = TRUE;
1179            if (m_speechrom)
1180               m_speechrom->load_address(cmd & 0x0f);
1181            m_schedule_dummy_read = TRUE;
13201182         }
13211183         break;
13221184
13231185      case 0x50 : /* speak */
1324         if (tms->schedule_dummy_read)
1186         if (m_schedule_dummy_read)
13251187         {
1326            tms->schedule_dummy_read = FALSE;
1327            if (tms->intf->read)
1328               (*tms->intf->read)(tms->device, 1);
1188            m_schedule_dummy_read = FALSE;
1189            if (m_speechrom)
1190               m_speechrom->read(1);
13291191         }
1330         tms->speaking_now = 1;
1331         tms->speak_external = 0;
1332         tms->talk_status = 1;  /* start immediately */
1192         m_speaking_now = 1;
1193         m_speak_external = 0;
1194         m_talk_status = 1;  /* start immediately */
13331195         /* clear out variables before speaking */
13341196         // TODO: similar to the victory case described above, but for VSM speech
1335         tms->subcycle = tms->subc_reload;
1336         tms->PC = 0;
1337         tms->IP = reload_table[tms->tms5220c_rate&0x3];
1338         tms->new_frame_energy_idx = 0;
1339         tms->new_frame_pitch_idx = 0;
1197         m_subcycle = m_subc_reload;
1198         m_PC = 0;
1199         m_IP = reload_table[m_tms5220c_rate&0x3];
1200         m_new_frame_energy_idx = 0;
1201         m_new_frame_pitch_idx = 0;
13401202         int i;
13411203         for (i = 0; i < 4; i++)
1342            tms->new_frame_k_idx[i] = 0;
1204            m_new_frame_k_idx[i] = 0;
13431205         for (i = 4; i < 7; i++)
1344            tms->new_frame_k_idx[i] = 0xF;
1345         for (i = 7; i < tms->coeff->num_k; i++)
1346            tms->new_frame_k_idx[i] = 0x7;
1206            m_new_frame_k_idx[i] = 0xF;
1207         for (i = 7; i < m_coeff->num_k; i++)
1208            m_new_frame_k_idx[i] = 0x7;
13471209         break;
13481210
13491211      case 0x60 : /* speak external */
13501212         //SPKEXT going active activates SPKEE which clears the fifo
1351         tms->fifo_head = tms->fifo_tail = tms->fifo_count = tms->fifo_bits_taken = 0;
1352         tms->speak_external = 1;
1353         tms->RDB_flag = FALSE;
1213         m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0;
1214         m_speak_external = 1;
1215         m_RDB_flag = FALSE;
13541216         break;
13551217
13561218      case 0x70 : /* reset */
1357         if (tms->schedule_dummy_read)
1219         if (m_schedule_dummy_read)
13581220         {
1359            tms->schedule_dummy_read = FALSE;
1360            if (tms->intf->read)
1361               (*tms->intf->read)(tms->device, 1);
1221            m_schedule_dummy_read = FALSE;
1222            if (m_speechrom)
1223               m_speechrom->read(1);
13621224         }
1363         tms->device->reset();
1225         reset();
13641226         break;
13651227   }
13661228
13671229   /* update the buffer low state */
1368   update_status_and_ints(tms);
1230   update_status_and_ints();
13691231}
13701232
13711233/******************************************************************************************
r22818r22819
13741236
13751237******************************************************************************************/
13761238
1377static void parse_frame(tms5220_state *tms)
1239void tms5220_device::parse_frame()
13781240{
13791241   int indx, i, rep_flag;
13801242
r22818r22819
13821244
13831245   /* if the chip is a tms5220C, and the rate mode is set to that each frame (0x04 bit set)
13841246   has a 2 bit rate preceding it, grab two bits here and store them as the rate; */
1385   if ((tms->variant == TMS5220_IS_5220C) && (tms->tms5220c_rate & 0x04))
1247   if ((m_variant == TMS5220_IS_5220C) && (m_tms5220c_rate & 0x04))
13861248   {
1387      indx = extract_bits(tms, 2);
1249      indx = extract_bits(2);
13881250#ifdef DEBUG_PARSE_FRAME_DUMP
13891251      printbits(indx,2);
13901252      fprintf(stderr," ");
13911253#endif
1392      tms->IP = reload_table[indx];
1254      m_IP = reload_table[indx];
13931255   }
13941256   else // non-5220C and 5220C in fixed rate mode
1395   tms->IP = reload_table[tms->tms5220c_rate&0x3];
1257   m_IP = reload_table[m_tms5220c_rate&0x3];
13961258
1397   update_status_and_ints(tms);
1398   if (!tms->talk_status) goto ranout;
1259   update_status_and_ints();
1260   if (!m_talk_status) goto ranout;
13991261
14001262   // attempt to extract the energy index
1401   tms->new_frame_energy_idx = extract_bits(tms,tms->coeff->energy_bits);
1263   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
14021264#ifdef DEBUG_PARSE_FRAME_DUMP
1403   printbits(tms->new_frame_energy_idx,tms->coeff->energy_bits);
1265   printbits(m_new_frame_energy_idx,m_coeff->energy_bits);
14041266   fprintf(stderr," ");
14051267#endif
1406   update_status_and_ints(tms);
1407   if (!tms->talk_status) goto ranout;
1268   update_status_and_ints();
1269   if (!m_talk_status) goto ranout;
14081270   // if the energy index is 0 or 15, we're done
1409   if ((tms->new_frame_energy_idx == 0) || (tms->new_frame_energy_idx == 15))
1271   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
14101272      return;
14111273
14121274
14131275   // attempt to extract the repeat flag
1414   rep_flag = extract_bits(tms,1);
1276   rep_flag = extract_bits(1);
14151277#ifdef DEBUG_PARSE_FRAME_DUMP
14161278   printbits(rep_flag, 1);
14171279   fprintf(stderr," ");
14181280#endif
14191281
14201282   // attempt to extract the pitch
1421   tms->new_frame_pitch_idx = extract_bits(tms,tms->coeff->pitch_bits);
1283   m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits);
14221284#ifdef DEBUG_PARSE_FRAME_DUMP
1423   printbits(tms->new_frame_pitch_idx,tms->coeff->pitch_bits);
1285   printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits);
14241286   fprintf(stderr," ");
14251287#endif
1426   update_status_and_ints(tms);
1427   if (!tms->talk_status) goto ranout;
1288   update_status_and_ints();
1289   if (!m_talk_status) goto ranout;
14281290   // if this is a repeat frame, just do nothing, it will reuse the old coefficients
14291291   if (rep_flag)
14301292      return;
r22818r22819
14321294   // extract first 4 K coefficients
14331295   for (i = 0; i < 4; i++)
14341296   {
1435      tms->new_frame_k_idx[i] = extract_bits(tms,tms->coeff->kbits[i]);
1297      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
14361298#ifdef DEBUG_PARSE_FRAME_DUMP
1437      printbits(tms->new_frame_k_idx[i],tms->coeff->kbits[i]);
1299      printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
14381300      fprintf(stderr," ");
14391301#endif
1440      update_status_and_ints(tms);
1441      if (!tms->talk_status) goto ranout;
1302      update_status_and_ints();
1303      if (!m_talk_status) goto ranout;
14421304   }
14431305
14441306   // if the pitch index was zero, we only need 4 K's...
1445   if (tms->new_frame_pitch_idx == 0)
1307   if (m_new_frame_pitch_idx == 0)
14461308   {
14471309      /* and the rest of the coefficients are zeroed, but that's done in the generator code */
14481310      return;
14491311   }
14501312
14511313   // If we got here, we need the remaining 6 K's
1452   for (i = 4; i < tms->coeff->num_k; i++)
1314   for (i = 4; i < m_coeff->num_k; i++)
14531315   {
1454      tms->new_frame_k_idx[i] = extract_bits(tms, tms->coeff->kbits[i]);
1316      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
14551317#ifdef DEBUG_PARSE_FRAME_DUMP
1456      printbits(tms->new_frame_k_idx[i],tms->coeff->kbits[i]);
1318      printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
14571319      fprintf(stderr," ");
14581320#endif
1459      update_status_and_ints(tms);
1460      if (!tms->talk_status) goto ranout;
1321      update_status_and_ints();
1322      if (!m_talk_status) goto ranout;
14611323   }
14621324#ifdef VERBOSE
1463   if (tms->speak_external)
1464      logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (tms->fifo_count*8)-(tms->fifo_bits_taken));
1325   if (m_speak_external)
1326      logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
14651327   else
14661328      logerror("Parsed a frame successfully in ROM\n");
14671329#endif
r22818r22819
14801342
14811343***********************************************************************************************/
14821344
1483static void set_interrupt_state(tms5220_state *tms, int state)
1345void tms5220_device::set_interrupt_state(int state)
14841346{
14851347#ifdef DEBUG_PIN_READS
14861348   logerror("irq pin set to state %d\n", state);
14871349#endif
1488   if (!tms->irq_func.isnull() && state != tms->irq_pin)
1489      tms->irq_func(!state);
1490   tms->irq_pin = state;
1350   if (!m_irq_handler.isnull() && state != m_irq_pin)
1351      m_irq_handler(!state);
1352   m_irq_pin = state;
14911353}
14921354
14931355/**********************************************************************************************
r22818r22819
14961358
14971359***********************************************************************************************/
14981360
1499static void update_ready_state(tms5220_state *tms)
1361void tms5220_device::update_ready_state()
15001362{
1501   int state = tms5220_ready_read(tms);
1363   int state = ready_read();
15021364#ifdef DEBUG_PIN_READS
15031365   logerror("ready pin set to state %d\n", state);
15041366#endif
1505   if (!tms->readyq_func.isnull() && state != tms->ready_pin)
1506      tms->readyq_func(!state);
1507   tms->ready_pin = state;
1367   if (!m_readyq_handler.isnull() && state != m_ready_pin)
1368      m_readyq_handler(!state);
1369   m_ready_pin = state;
15081370}
15091371
15101372
r22818r22819
15141376
15151377***********************************************************************************************/
15161378
1517static DEVICE_START( tms5220 )
1379//-------------------------------------------------
1380//  device_start - device-specific startup
1381//-------------------------------------------------
1382
1383void tms5220_device::device_start()
15181384{
1519   static const tms5220_interface dummy = { DEVCB_NULL };
1520   tms5220_state *tms = get_safe_token(device);
1385   if (m_speechrom_tag)
1386   {
1387      m_speechrom = siblingdevice<speechrom_device>( m_speechrom_tag );
1388      if( !m_speechrom )
1389      {
1390         throw new emu_fatalerror("Error: %s '%s' can't find speechrom '%s'\n", shortname(), tag(), m_speechrom_tag );
1391      }
1392   }
1393   else
1394   {
1395      m_speechrom = NULL;
1396   }
15211397
1522   tms->intf = device->static_config() ? (const tms5220_interface *)device->static_config() : &dummy;
1523   //tms->table = *device->region();
1398   set_variant(TMS5220_IS_5220);
1399   m_clock = clock();
15241400
1525   tms->device = device;
1526   tms5220_set_variant(tms, TMS5220_IS_5220);
1527   tms->clock = device->clock();
1528
1529   assert_always(tms != NULL, "Error creating TMS5220 chip");
1530
15311401   /* resolve irq and readyq line */
1532   tms->irq_func.resolve(tms->intf->irq_func, *device);
1533   tms->readyq_func.resolve(tms->intf->readyq_func, *device);
1402   m_irq_handler.resolve();
1403   m_readyq_handler.resolve();
15341404
15351405   /* initialize a stream */
1536   tms->stream = device->machine().sound().stream_alloc(*device, 0, 1, device->clock() / 80, tms, tms5220_update);
1406   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80);
15371407
1538   /*if (tms->table == NULL)
1539   {
1540       assert_always(tms->intf->M0_callback != NULL, "Missing _mandatory_ 'M0_callback' function pointer in the TMS5110 interface\n  This function is used by TMS5220 to call for a new single bit\n  needed to generate the speech when in VSM mode\n  Aborting startup...\n");
1541       tms->M0_callback = tms->intf->M0_callback;
1542       tms->set_load_address = tms->intf->load_address;
1543   }
1544   else
1545   {
1546       tms->M0_callback = speech_rom_read_bit;
1547       tms->set_load_address = speech_rom_set_addr;
1548   }*/
1408   m_timer_io_ready = timer_alloc(0);
15491409
15501410   /* not during reset which is called frm within a write! */
1551   tms->io_ready = 1;
1552   tms->true_timing = 0;
1553   tms->rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup
1411   m_io_ready = 1;
1412   m_true_timing = 0;
1413   m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup
15541414
1555   register_for_save_states(tms);
1415   register_for_save_states();
15561416}
15571417
1558static DEVICE_START( tms5220c )
1418//-------------------------------------------------
1419//  device_start - device-specific startup
1420//-------------------------------------------------
1421
1422void tms5220c_device::device_start()
15591423{
1560   tms5220_state *tms = get_safe_token(device);
1561   DEVICE_START_CALL( tms5220 );
1562   tms5220_set_variant(tms, TMS5220_IS_5220C);
1424   tms5220_device::device_start();
1425   set_variant(TMS5220_IS_5220C);
15631426}
15641427
1565static DEVICE_START( tmc0285 )
1428//-------------------------------------------------
1429//  device_start - device-specific startup
1430//-------------------------------------------------
1431
1432void tmc0285_device::device_start()
15661433{
1567   tms5220_state *tms = get_safe_token(device);
1568   DEVICE_START_CALL( tms5220 );
1569   tms5220_set_variant(tms, TMS5220_IS_TMC0285);
1434   tms5220_device::device_start();
1435   set_variant(TMS5220_IS_TMC0285);
15701436}
15711437
1438//-------------------------------------------------
1439//  device_start - device-specific startup
1440//-------------------------------------------------
15721441
1573static DEVICE_START( tms5200 )
1442void tms5200_device::device_start()
15741443{
1575   tms5220_state *tms = get_safe_token(device);
1576   DEVICE_START_CALL( tms5220 );
1577   tms5220_set_variant(tms, TMS5220_IS_5200);
1444   tms5220_device::device_start();
1445   set_variant(TMS5220_IS_5200);
15781446}
15791447
15801448
1581static DEVICE_RESET( tms5220 )
1582{
1583   tms5220_state *tms = get_safe_token(device);
1449//-------------------------------------------------
1450//  device_reset - device-specific reset
1451//-------------------------------------------------
15841452
1585   tms->digital_select = FORCE_DIGITAL; // assume analog output
1453void tms5220_device::device_reset()
1454{
1455   m_digital_select = FORCE_DIGITAL; // assume analog output
15861456   /* initialize the FIFO */
1587   /*memset(tms->fifo, 0, sizeof(tms->fifo));*/
1588   tms->fifo_head = tms->fifo_tail = tms->fifo_count = tms->fifo_bits_taken = 0;
1457   /*memset(m_fifo, 0, sizeof(m_fifo));*/
1458   m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0;
15891459
15901460   /* initialize the chip state */
1591   /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if tms->buffer_empty or tms->buffer_low are 0 */
1592   tms->speaking_now = tms->speak_external = tms->talk_status = tms->irq_pin = tms->ready_pin = 0;
1593   set_interrupt_state(tms, 0);
1594   update_ready_state(tms);
1595   tms->buffer_empty = tms->buffer_low = 1;
1461   /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */
1462   m_speaking_now = m_speak_external = m_talk_status = m_irq_pin = m_ready_pin = 0;
1463   set_interrupt_state(0);
1464   update_ready_state();
1465   m_buffer_empty = m_buffer_low = 1;
15961466
1597   tms->RDB_flag = FALSE;
1467   m_RDB_flag = FALSE;
15981468
15991469   /* initialize the energy/pitch/k states */
16001470#ifdef PERFECT_INTERPOLATION_HACK
1601   tms->old_frame_energy_idx = tms->old_frame_pitch_idx = 0;
1602   memset(tms->old_frame_k_idx, 0, sizeof(tms->old_frame_k_idx));
1471   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
1472   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
16031473#endif
1604   tms->new_frame_energy_idx = tms->current_energy = tms->target_energy = 0;
1605   tms->new_frame_pitch_idx = tms->current_pitch = tms->target_pitch = 0;
1606   memset(tms->new_frame_k_idx, 0, sizeof(tms->new_frame_k_idx));
1607   memset(tms->current_k, 0, sizeof(tms->current_k));
1608   memset(tms->target_k, 0, sizeof(tms->target_k));
1474   m_new_frame_energy_idx = m_current_energy = m_target_energy = 0;
1475   m_new_frame_pitch_idx = m_current_pitch = m_target_pitch = 0;
1476   memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx));
1477   memset(m_current_k, 0, sizeof(m_current_k));
1478   memset(m_target_k, 0, sizeof(m_target_k));
16091479
16101480   /* initialize the sample generators */
1611   tms->inhibit = 1;
1612   tms->subcycle = tms->tms5220c_rate = tms->pitch_count = tms->PC = 0;
1613   tms->subc_reload = FORCE_SUBC_RELOAD;
1614   tms->OLDE = tms->OLDP = 1;
1615   tms->IP = reload_table[tms->tms5220c_rate&0x3];
1616   tms->RNG = 0x1FFF;
1617   memset(tms->u, 0, sizeof(tms->u));
1618   memset(tms->x, 0, sizeof(tms->x));
1481   m_inhibit = 1;
1482   m_subcycle = m_tms5220c_rate = m_pitch_count = m_PC = 0;
1483   m_subc_reload = FORCE_SUBC_RELOAD;
1484   m_OLDE = m_OLDP = 1;
1485   m_IP = reload_table[m_tms5220c_rate&0x3];
1486   m_RNG = 0x1FFF;
1487   memset(m_u, 0, sizeof(m_u));
1488   memset(m_x, 0, sizeof(m_x));
16191489
1620   if (tms->intf->load_address)
1621      (*tms->intf->load_address)(tms->device, 0);
1490   if (m_speechrom)
1491      m_speechrom->load_address(0);
16221492
1623   tms->schedule_dummy_read = TRUE;
1493   m_schedule_dummy_read = TRUE;
16241494}
16251495
16261496/**********************************************************************************************
r22818r22819
16291499
16301500***********************************************************************************************/
16311501
1632static TIMER_CALLBACK( io_ready_cb )
1502void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
16331503{
1634   tms5220_state *tms = (tms5220_state *) ptr;
1635   if (param)
1504   switch(id)
16361505   {
1637      switch (tms->rs_ws)
1506   case 0:
1507      if (param)
16381508      {
1639      case 0x02:
1640         /* Write */
1641         /* bring up to date first */
1509         switch (m_rs_ws)
1510         {
1511         case 0x02:
1512            /* Write */
1513            /* bring up to date first */
16421514#ifdef DEBUG_IO_READY
1643         logerror("Serviced write: %02x\n", tms->write_latch);
1644         //fprintf(stderr, "Processed write data: %02X\n", tms->write_latch);
1515            logerror("Serviced write: %02x\n", m_write_latch);
1516            //fprintf(stderr, "Processed write data: %02X\n", m_write_latch);
16451517#endif
1646         tms->stream->update();
1647         tms5220_data_write(tms, tms->write_latch);
1648         break;
1649      case 0x01:
1650         /* Read */
1651         /* bring up to date first */
1652         tms->stream->update();
1653         tms->read_latch = tms5220_status_read(tms);
1654         break;
1655      case 0x03:
1656         /* High Impedance */
1657      case 0x00:
1658         /* illegal */
1659         break;
1518            m_stream->update();
1519            data_write(m_write_latch);
1520            break;
1521         case 0x01:
1522            /* Read */
1523            /* bring up to date first */
1524            m_stream->update();
1525            m_read_latch = status_read();
1526            break;
1527         case 0x03:
1528            /* High Impedance */
1529         case 0x00:
1530            /* illegal */
1531            break;
1532         }
16601533      }
1534
1535      m_io_ready = param;
1536      update_ready_state();
1537      break;
16611538   }
1662   tms->io_ready = param;
1663   update_ready_state(tms);
16641539}
16651540
16661541/*
16671542 * /RS line write handler
16681543 */
1669WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w )
1544WRITE_LINE_MEMBER( tms5220_device::rsq_w )
16701545{
1671   tms5220_state *tms = get_safe_token(device);
16721546   UINT8 new_val;
16731547
1674   tms->true_timing = 1;
1548   m_true_timing = 1;
16751549   state &= 0x01;
16761550#ifdef DEBUG_RS_WS
16771551   logerror("/RS written with data: %d\n", state);
16781552#endif
1679   new_val = (tms->rs_ws & 0x01) | (state<<1);
1680   if (new_val != tms->rs_ws)
1553   new_val = (m_rs_ws & 0x01) | (state<<1);
1554   if (new_val != m_rs_ws)
16811555   {
1682      tms->rs_ws = new_val;
1556      m_rs_ws = new_val;
16831557      if (new_val == 0)
16841558      {
1685         if (tms->variant == TMS5220_IS_5220C)
1686            device->reset();
1559         if (m_variant == TMS5220_IS_5220C)
1560            reset();
16871561#ifdef DEBUG_RS_WS
16881562         else
16891563            /* illegal */
r22818r22819
16941568      else if ( new_val == 3)
16951569      {
16961570         /* high impedance */
1697         tms->read_latch = 0xff;
1571         m_read_latch = 0xff;
16981572         return;
16991573      }
17001574      if (state)
r22818r22819
17081582         logerror("Scheduling ready cycle for /RS...\n");
17091583#endif
17101584         /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */
1711         tms->io_ready = 0;
1712         update_ready_state(tms);
1585         m_io_ready = 0;
1586         update_ready_state();
17131587         /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */
1714         tms->device->machine().scheduler().timer_set(attotime::from_hz(device->clock()/16), FUNC(io_ready_cb), 1, tms); // this should take around 10-16 (closer to ~11?) cycles to complete
1588         m_timer_io_ready->adjust(attotime::from_hz(clock()/16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete
17151589      }
17161590   }
17171591}
r22818r22819
17191593/*
17201594 * /WS line write handler
17211595 */
1722WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w )
1596WRITE_LINE_MEMBER( tms5220_device::wsq_w )
17231597{
1724   tms5220_state *tms = get_safe_token(device);
17251598   UINT8 new_val;
17261599
1727   tms->true_timing = 1;
1600   m_true_timing = 1;
17281601   state &= 0x01;
17291602#ifdef DEBUG_RS_WS
17301603   logerror("/WS written with data: %d\n", state);
17311604#endif
1732   new_val = (tms->rs_ws & 0x02) | (state<<0);
1733   if (new_val != tms->rs_ws)
1605   new_val = (m_rs_ws & 0x02) | (state<<0);
1606   if (new_val != m_rs_ws)
17341607   {
1735      tms->rs_ws = new_val;
1608      m_rs_ws = new_val;
17361609      if (new_val == 0)
17371610      {
1738         if (tms->variant == TMS5220_IS_5220C)
1739            device->reset();
1611         if (m_variant == TMS5220_IS_5220C)
1612            reset();
17401613#ifdef DEBUG_RS_WS
17411614         else
17421615            /* illegal */
r22818r22819
17471620      else if ( new_val == 3)
17481621      {
17491622         /* high impedance */
1750         tms->read_latch = 0xff;
1623         m_read_latch = 0xff;
17511624         return;
17521625      }
17531626      if (state)
r22818r22819
17611634         logerror("Scheduling ready cycle for /WS...\n");
17621635#endif
17631636         /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */
1764         tms->io_ready = 0;
1765         update_ready_state(tms);
1637         m_io_ready = 0;
1638         update_ready_state();
17661639         /* Now comes the complicated part: long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not...
17671640         Speak external mode: ~16 cycles
17681641         Command Mode:
r22818r22819
17741647         SET RATE (5220C only): ? cycles (probably ~16)
17751648         */
17761649         // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles
1777         tms->device->machine().scheduler().timer_set(attotime::from_hz(device->clock()/16), FUNC(io_ready_cb), 1, tms); // this should take around 10-16 (closer to ~15) cycles to complete for fifo writes, TODO: but actually depends on what command is written if in command mode
1650         m_timer_io_ready->adjust(attotime::from_hz(clock()/16), 1); // this should take around 10-16 (closer to ~15) cycles to complete for fifo writes, TODO: but actually depends on what command is written if in command mode
17781651      }
17791652   }
17801653}
r22818r22819
17851658
17861659***********************************************************************************************/
17871660
1788WRITE8_DEVICE_HANDLER( tms5220_data_w )
1661WRITE8_MEMBER( tms5220_device::data_w )
17891662{
1790   tms5220_state *tms = get_safe_token(device);
17911663#ifdef DEBUG_RS_WS
17921664   logerror("tms5220_data_w: data %02x\n", data);
17931665#endif
1794   if (!tms->true_timing)
1666   if (!m_true_timing)
17951667   {
17961668      /* bring up to date first */
1797      tms->stream->update();
1798      tms5220_data_write(tms, data);
1669      m_stream->update();
1670      data_write(data);
17991671   }
18001672   else
18011673   {
18021674      /* actually in a write ? */
18031675#ifdef DEBUG_RS_WS
1804      if (!(tms->rs_ws == 0x02))
1805         logerror("tms5220_data_w: data written outside ws, status: %02x!\n", tms->rs_ws);
1676      if (!(m_rs_ws == 0x02))
1677         logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
18061678#endif
1807      tms->write_latch = data;
1679      m_write_latch = data;
18081680   }
18091681}
18101682
r22818r22819
18161688
18171689***********************************************************************************************/
18181690
1819READ8_DEVICE_HANDLER( tms5220_status_r )
1691READ8_MEMBER( tms5220_device::status_r )
18201692{
1821   tms5220_state *tms = get_safe_token(device);
1822   if (!tms->true_timing)
1693   if (!m_true_timing)
18231694   {
18241695      /* bring up to date first */
1825      tms->stream->update();
1826      return tms5220_status_read(tms);
1696      m_stream->update();
1697      return status_read();
18271698   }
18281699   else
18291700   {
18301701      /* actually in a read ? */
1831      if (tms->rs_ws == 0x01)
1832         return tms->read_latch;
1702      if (m_rs_ws == 0x01)
1703         return m_read_latch;
18331704#ifdef DEBUG_RS_WS
18341705      else
18351706         logerror("tms5220_status_r: data read outside rs!\n");
r22818r22819
18461717
18471718***********************************************************************************************/
18481719
1849READ_LINE_DEVICE_HANDLER( tms5220_readyq_r )
1720READ_LINE_MEMBER( tms5220_device::readyq_r )
18501721{
1851   tms5220_state *tms = get_safe_token(device);
18521722   /* bring up to date first */
1853   tms->stream->update();
1854   return !tms5220_ready_read(tms);
1723   m_stream->update();
1724   return !ready_read();
18551725}
18561726
18571727
r22818r22819
18621732
18631733***********************************************************************************************/
18641734
1865double tms5220_time_to_ready(device_t *device)
1735double tms5220_device::time_to_ready()
18661736{
1867   tms5220_state *tms = get_safe_token(device);
18681737   double cycles;
18691738
18701739   /* bring up to date first */
1871   tms->stream->update();
1872   cycles = tms5220_cycles_to_ready(tms);
1873   return cycles * 80.0 / tms->clock;
1740   m_stream->update();
1741   cycles = cycles_to_ready();
1742   return cycles * 80.0 / m_clock;
18741743}
18751744
18761745
r22818r22819
18811750
18821751***********************************************************************************************/
18831752
1884READ_LINE_DEVICE_HANDLER( tms5220_intq_r )
1753READ_LINE_MEMBER( tms5220_device::intq_r )
18851754{
1886   tms5220_state *tms = get_safe_token(device);
18871755   /* bring up to date first */
1888   tms->stream->update();
1889   return !tms5220_int_read(tms);
1756   m_stream->update();
1757   return !int_read();
18901758}
18911759
18921760
r22818r22819
18971765
18981766***********************************************************************************************/
18991767
1900static STREAM_UPDATE( tms5220_update )
1768//-------------------------------------------------
1769//  sound_stream_update - handle a stream update
1770//-------------------------------------------------
1771
1772void tms5220_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
19011773{
1902   tms5220_state *tms = (tms5220_state *)param;
19031774   INT16 sample_data[MAX_SAMPLE_CHUNK];
19041775   stream_sample_t *buffer = outputs[0];
19051776
r22818r22819
19101781      int index;
19111782
19121783      /* generate the samples and copy to the target buffer */
1913      tms5220_process(tms, sample_data, length);
1784      process(sample_data, length);
19141785      for (index = 0; index < length; index++)
19151786         *buffer++ = sample_data[index];
19161787
r22818r22819
19271798
19281799***********************************************************************************************/
19291800
1930void tms5220_set_frequency(device_t *device, int frequency)
1801void tms5220_device::set_frequency(int frequency)
19311802{
1932   tms5220_state *tms = get_safe_token(device);
1933   tms->stream->set_sample_rate(frequency / 80);
1934   tms->clock = frequency;
1803   m_stream->set_sample_rate(frequency / 80);
1804   m_clock = frequency;
19351805}
19361806
19371807const device_type TMS5220C = &device_creator<tms5220c_device>;
r22818r22819
19411811{
19421812}
19431813
1944//-------------------------------------------------
1945//  device_start - device-specific startup
1946//-------------------------------------------------
19471814
1948void tms5220c_device::device_start()
1949{
1950   DEVICE_START_NAME( tms5220c )(this);
1951}
1952
1953//-------------------------------------------------
1954//  sound_stream_update - handle a stream update
1955//-------------------------------------------------
1956
1957void tms5220c_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
1958{
1959   // should never get here
1960   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
1961}
1962
1963
19641815const device_type TMS5220 = &device_creator<tms5220_device>;
19651816
19661817tms5220_device::tms5220_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
19671818   : device_t(mconfig, TMS5220, "TMS5220", tag, owner, clock),
1968      device_sound_interface(mconfig, *this)
1819      device_sound_interface(mconfig, *this),
1820      m_irq_handler(*this),
1821      m_readyq_handler(*this),
1822      m_speechrom_tag(NULL)
19691823{
1970   m_token = global_alloc_clear(tms5220_state);
19711824}
1825
19721826tms5220_device::tms5220_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
19731827   : device_t(mconfig, type, name, tag, owner, clock),
1974      device_sound_interface(mconfig, *this)
1828      device_sound_interface(mconfig, *this),
1829      m_irq_handler(*this),
1830      m_readyq_handler(*this),
1831      m_speechrom_tag(NULL)
19751832{
1976   m_token = global_alloc_clear(tms5220_state);
19771833}
19781834
19791835//-------------------------------------------------
r22818r22819
19861842{
19871843}
19881844
1989//-------------------------------------------------
1990//  device_start - device-specific startup
1991//-------------------------------------------------
19921845
1993void tms5220_device::device_start()
1994{
1995   DEVICE_START_NAME( tms5220 )(this);
1996}
1997
1998//-------------------------------------------------
1999//  device_reset - device-specific reset
2000//-------------------------------------------------
2001
2002void tms5220_device::device_reset()
2003{
2004   DEVICE_RESET_NAME( tms5220 )(this);
2005}
2006
2007//-------------------------------------------------
2008//  sound_stream_update - handle a stream update
2009//-------------------------------------------------
2010
2011void tms5220_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
2012{
2013   // should never get here
2014   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
2015}
2016
2017
20181846const device_type TMC0285 = &device_creator<tmc0285_device>;
20191847
20201848tmc0285_device::tmc0285_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
r22818r22819
20221850{
20231851}
20241852
2025//-------------------------------------------------
2026//  device_start - device-specific startup
2027//-------------------------------------------------
20281853
2029void tmc0285_device::device_start()
2030{
2031   DEVICE_START_NAME( tmc0285 )(this);
2032}
2033
2034//-------------------------------------------------
2035//  sound_stream_update - handle a stream update
2036//-------------------------------------------------
2037
2038void tmc0285_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
2039{
2040   // should never get here
2041   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
2042}
2043
2044
20451854const device_type TMS5200 = &device_creator<tms5200_device>;
20461855
20471856tms5200_device::tms5200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
20481857   : tms5220_device(mconfig, TMS5200, "TMS5200", tag, owner, clock)
20491858{
20501859}
2051
2052//-------------------------------------------------
2053//  device_start - device-specific startup
2054//-------------------------------------------------
2055
2056void tms5200_device::device_start()
2057{
2058   DEVICE_START_NAME( tms5200 )(this);
2059}
2060
2061//-------------------------------------------------
2062//  sound_stream_update - handle a stream update
2063//-------------------------------------------------
2064
2065void tms5200_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
2066{
2067   // should never get here
2068   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
2069}
2070
2071
2072
2073
2074/******************************************************************************
2075   New class implementation
2076******************************************************************************/
2077
2078#define M_INTERP_SHIFT >> m_coeff->interp_coeff[m_IP]
2079
2080tms52xx_device::tms52xx_device(const machine_config &mconfig, device_type type,  const char *name, const char *tag, const struct tms5100_coeffs* coeffs, const int var, device_t *owner, UINT32 clock)
2081   : device_t(mconfig, type, name, tag, owner, clock),
2082      device_sound_interface(mconfig, *this),
2083      m_variant(var),
2084      m_coeff(coeffs)
2085{
2086}
2087
2088
2089tms5220n_device::tms5220n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2090   : tms52xx_device(mconfig, TMS5220N, "TMS5220N", tag, &tms5220_coeff, TMS5220_IS_5220, owner, clock)
2091{
2092}
2093
2094tms5220cn_device::tms5220cn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2095   : tms52xx_device(mconfig, TMS5220CN, "TMS5220CN", tag, &tms5220_coeff, TMS5220_IS_5220C, owner, clock)
2096{
2097}
2098
2099tmc0285n_device::tmc0285n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2100   : tms52xx_device(mconfig, TMC0285N, "TMC0285N", tag, &tms5200_coeff, TMS5220_IS_TMC0285, owner, clock)
2101{
2102}
2103
2104tms5200n_device::tms5200n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2105   : tms52xx_device(mconfig, TMS5200N, "TMS5200N", tag, &tms5200_coeff, TMS5220_IS_5200, owner, clock)
2106{
2107}
2108
2109void tms52xx_device::device_start()
2110{
2111   const tms52xx_config *conf = reinterpret_cast<const tms52xx_config *>(static_config());
2112   //m_table = region();
2113
2114   /* resolve irq and readyq line */
2115   m_irq_func.resolve(conf->irq_func, *this);
2116   m_readyq_func.resolve(conf->readyq_func, *this);
2117   m_read_mem.resolve(conf->read_mem, *this);
2118   m_load_address.resolve(conf->load_address, *this);
2119   m_read_and_branch.resolve(conf->read_and_branch, *this);
2120
2121   /* initialize a stream */
2122   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80, this);
2123
2124   /*if (m_table == NULL)
2125   {
2126       assert_always(m_conf->M0_callback != NULL, "Missing _mandatory_ 'M0_callback' function pointer in the TMS5110 interface\n  This function is used by TMS5220 to call for a new single bit\n  needed to generate the speech when in VSM mode\n  Aborting startup...\n");
2127       m_M0_callback = conf->M0_callback;
2128       m_set_load_address = conf->load_address;
2129   }
2130   else
2131   {
2132       m_M0_callback = speech_rom_read_bit;
2133       m_set_load_address = speech_rom_set_addr;
2134   }*/
2135
2136   /* not during reset which is called frm within a write! */
2137   m_io_ready = true;
2138   m_true_timing = false;
2139   m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup
2140
2141   m_ready_timer = timer_alloc(0);
2142
2143   register_for_save_states();
2144}
2145
2146void tms52xx_device::device_reset()
2147{
2148   m_digital_select = FORCE_DIGITAL;           // assume analog output
2149   // initialize the FIFO
2150   // should we do a memset here to clear the fifo contents?
2151   m_fifo_head = 0;
2152   m_fifo_tail = 0;
2153   m_fifo_count = 0;
2154   m_fifo_bits_taken = 0;
2155
2156   // initialize the chip state
2157   /* Note that we do not actually clear IRQ on start-up: IRQ is even raised
2158    * if m_buffer_empty or m_buffer_low are 0 */
2159   m_speaking_now = false;
2160   m_speak_external = false;
2161   m_talk_status = false;
2162   m_irq_pin = 0;      // CLEAR_LINE
2163   m_ready_pin = 0;    // CLEAR_LINE
2164
2165   set_interrupt_state(0);         // CLEAR_LINE
2166   update_ready_state();
2167   m_buffer_empty = true;
2168   m_buffer_low = true;
2169
2170   m_RDB_flag = false;
2171
2172   /* initialize the energy/pitch/k states */
2173#ifdef PERFECT_INTERPOLATION_HACK
2174   m_old_frame_energy_idx = 0;
2175   m_old_frame_pitch_idx = 0;
2176   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
2177#endif
2178
2179   m_new_frame_energy_idx = 0;
2180   m_current_energy = 0;
2181   m_target_energy = 0;
2182   m_new_frame_pitch_idx = 0;
2183   m_current_pitch = 0;
2184   m_target_pitch = 0;
2185
2186   memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx));
2187   memset(m_current_k, 0, sizeof(m_current_k));
2188   memset(m_target_k, 0, sizeof(m_target_k));
2189
2190   /* initialize the sample generators */
2191   m_inhibit = true;
2192   m_subcycle = 0;
2193   m_tms5220c_rate = 0;
2194   m_pitch_count = 0;
2195   m_PC = 0;
2196
2197   m_subc_reload = FORCE_SUBC_RELOAD;
2198   m_OLDE = 1;
2199   m_OLDP = 1;
2200
2201   m_IP = reload_table[m_tms5220c_rate&0x3];
2202   m_RNG = 0x1FFF;
2203   memset(m_u, 0, sizeof(m_u));
2204   memset(m_x, 0, sizeof(m_x));
2205
2206   m_load_address(0, 0);
2207   m_schedule_dummy_read = true;
2208}
2209
2210/******************************************************************************
2211     set_interrupt_state -- generate an interrupt
2212*******************************************************************************/
2213
2214void tms52xx_device::set_interrupt_state(int state)
2215{
2216#ifdef DEBUG_PIN_READS
2217   logerror("tms52xx: irq pin set to state %d\n", state);
2218#endif
2219   if (state != m_irq_pin) m_irq_func(!state);
2220   m_irq_pin = state;
2221}
2222
2223/******************************************************************************
2224     update_ready_state -- update the ready line
2225*******************************************************************************/
2226
2227void tms52xx_device::update_ready_state()
2228{
2229   int state = ready_read();
2230#ifdef DEBUG_PIN_READS
2231   logerror("tms52xx: ready pin set to state %d\n", state);
2232#endif
2233   if (state != m_ready_pin) m_readyq_func(!state);
2234   m_ready_pin = state;
2235}
2236
2237/******************************************************************************
2238     tms5220_set_frequency -- adjusts the playback frequency
2239*******************************************************************************/
2240
2241void tms52xx_device::set_frequency(int frequency)
2242{
2243   m_stream->set_sample_rate(frequency / 80);
2244   m_clock = frequency;
2245}
2246
2247/******************************************************************************
2248     tms5220_update -- update the sound chip so that it is in sync with CPU execution
2249*******************************************************************************/
2250
2251void tms52xx_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
2252{
2253   INT16 sample_data[MAX_SAMPLE_CHUNK];
2254   stream_sample_t *buffer = outputs[0];
2255
2256   /* loop while we still have samples to generate */
2257   while (samples>0)
2258   {
2259      int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples;
2260      int index;
2261
2262      /* generate the samples and copy to the target buffer */
2263      process(sample_data, length);
2264      for (index = 0; index < length; index++)
2265         *buffer++ = sample_data[index];
2266
2267      /* account for the samples */
2268      samples -= length;
2269   }
2270}
2271
2272/******************************************************************************
2273    process -- fill the buffer with a specific number of samples
2274*******************************************************************************/
2275
2276void tms52xx_device::process(INT16 *buffer, unsigned int size)
2277{
2278   int buf_count=0;
2279   int i, bitout;
2280   bool zpar;
2281   INT32 this_sample;
2282
2283   // The following gotos are probably safe to remove
2284   // if we're empty and still not speaking, fill with nothingness
2285   if (!m_speaking_now) goto empty;
2286
2287   // if speak external is set, but talk status is not (yet) set,
2288   // wait for buffer low to clear
2289   if (!m_talk_status && m_speak_external && m_buffer_low) goto empty;
2290
2291   // loop until the buffer is full or we've stopped speaking
2292   while ((size > 0) && m_speaking_now)
2293   {
2294      /* if it is the appropriate time to update the old energy/pitch idxes,
2295       * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
2296       * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
2297       * which happens 4 T-cycles later), we change on the latter.
2298       */
2299      if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2))
2300      {
2301         m_OLDE = (m_new_frame_energy_idx == 0);
2302         m_OLDP = (m_new_frame_pitch_idx == 0);
2303      }
2304
2305      /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
2306       * (In reality, the frame was really loaded incrementally during the
2307       * entire IP=0 PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
2308       */
2309      if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
2310      {
2311         // HACK for regression testing, be sure to comment out before release!
2312         // m_RNG = 0x1234;
2313         // end HACK
2314
2315         // appropriately override the interp count if needed; this will be incremented after the frame parse!
2316         m_IP = reload_table[m_tms5220c_rate & 0x3];
2317
2318#ifdef PERFECT_INTERPOLATION_HACK
2319         // remember previous frame energy, pitch, and coefficients
2320         m_old_frame_energy_idx = m_new_frame_energy_idx;
2321         m_old_frame_pitch_idx = m_new_frame_pitch_idx;
2322         for (i = 0; i < m_coeff->num_k; i++)
2323            m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
2324#endif
2325
2326         // if the talk status was clear last frame, halt speech now.
2327         if (m_talk_status == false)
2328         {
2329#ifdef DEBUG_GENERATION
2330            fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n");
2331#endif
2332            m_speaking_now = false; // finally halt speech
2333            goto empty;
2334         }
2335
2336         // Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[]
2337         parse_frame();
2338#ifdef DEBUG_PARSE_FRAME_DUMP
2339         fprintf(stderr,"\n");
2340#endif
2341         // if the new frame is a stop frame, set an interrupt and set talk status to 0
2342         if (M_NEW_FRAME_STOP_FLAG == 1)
2343         {
2344            m_talk_status = false;
2345            m_speak_external = false;
2346            set_interrupt_state(1);
2347            update_status_and_ints();
2348         }
2349
2350         // in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
2351         // Interpolation inhibit cases:
2352         // * Old frame was voiced, new is unvoiced
2353         // * Old frame was silence/zero energy, new has nonzero energy
2354         // * Old frame was unvoiced, new is voiced
2355
2356         if ( ((M_OLD_FRAME_UNVOICED_FLAG == false) && (M_NEW_FRAME_UNVOICED_FLAG == true))
2357            || ((M_OLD_FRAME_UNVOICED_FLAG == true) && (M_NEW_FRAME_UNVOICED_FLAG == false)) /* this line needs further investigation, starwars tie fighters may sound better without it */
2358            || ((M_OLD_FRAME_SILENCE_FLAG == true) && (M_NEW_FRAME_SILENCE_FLAG == false)) )
2359            m_inhibit = true;
2360         else // normal frame, normal interpolation
2361            m_inhibit = false;
2362
2363         // load new frame targets from tables, using parsed indices
2364         m_target_energy = m_coeff->energytable[m_new_frame_energy_idx];
2365         m_target_pitch = m_coeff->pitchtable[m_new_frame_pitch_idx];
2366         zpar = M_NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed
2367         for (i = 0; i < 4; i++)
2368            m_target_k[i] = m_coeff->ktable[i][m_new_frame_k_idx[i]];
2369         for (i = 4; i < m_coeff->num_k; i++)
2370            m_target_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-zpar));
2371
2372#ifdef DEBUG_GENERATION
2373         /* Debug info for current parsed frame */
2374         fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
2375         fprintf(stderr,"Processing frame: ");
2376         if (m_inhibit == 0)
2377            fprintf(stderr, "Normal Frame\n");
2378         else
2379            fprintf(stderr,"Interpolation Inhibited\n");
2380         fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
2381            m_current_energy, m_current_pitch,
2382            m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3],
2383            m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7],
2384            m_current_k[8], m_current_k[9]);
2385         fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
2386            m_target_energy, m_new_frame_energy_idx, m_target_pitch,
2387            m_target_k[0], m_target_k[1], m_target_k[2], m_target_k[3],
2388            m_target_k[4], m_target_k[5], m_target_k[6], m_target_k[7],
2389            m_target_k[8], m_target_k[9]);
2390#endif
2391
2392         /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
2393         if (!m_talk_status)
2394         {
2395#ifdef DEBUG_GENERATION
2396            fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
2397#endif
2398            m_target_energy = 0;
2399         }
2400      }
2401      else // Not a new frame, just interpolate the existing frame.
2402      {
2403         bool inhibit_state = (m_inhibit && (m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the tms->inhibit value
2404#ifdef PERFECT_INTERPOLATION_HACK
2405         int samples_per_frame = (m_subc_reload!=0)? 175:266;        // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW
2406         //int samples_per_frame = (m_subc_reload!=0)?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
2407         int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
2408
2409         zpar = M_OLD_FRAME_UNVOICED_FLAG;
2410         //fprintf(stderr, "CS: %03d", current_sample);
2411         // reset the current energy, pitch, etc to what it was at frame start
2412         m_current_energy = m_coeff->energytable[m_old_frame_energy_idx];
2413         m_current_pitch = m_coeff->pitchtable[m_old_frame_pitch_idx];
2414         for (i = 0; i < 4; i++)
2415            m_current_k[i] = m_coeff->ktable[i][m_old_frame_k_idx[i]];
2416         for (i = 4; i < m_coeff->num_k; i++)
2417            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-zpar));
2418         // now adjust each value to be exactly correct for each of the samples per frame
2419         if (m_IP != 0) // if we're still interpolating...
2420         {
2421            if (!inhibit_state)
2422            {
2423               m_current_energy += ((m_target_energy - m_current_energy)*current_sample)/samples_per_frame;
2424               m_current_pitch += ((m_target_pitch - m_current_pitch)*current_sample)/samples_per_frame;
2425               for (i = 0; i < m_coeff->num_k; i++)
2426               {
2427                  m_current_k[i] += ((m_target_k[i] - m_current_k[i])*current_sample)/samples_per_frame;
2428               }
2429            }
2430         }
2431         else // we're done, play this frame for 1/8 frame.
2432         {
2433            m_current_energy = m_target_energy;
2434            m_current_pitch = m_target_pitch;
2435            for (i = 0; i < m_coeff->num_k; i++)
2436               m_current_k[i] = m_target_k[i];
2437         }
2438#else
2439         // Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
2440         if (m_subcycle == 2)
2441         {
2442            if (!inhibit_state)
2443            {
2444               switch(m_PC)
2445               {
2446               case 0: // PC = 0, B cycle, write updated energy
2447                  m_current_energy += ((m_target_energy - m_current_energy) M_INTERP_SHIFT);
2448                  break;
2449               case 1: /* PC = 1, B cycle, write updated pitch */
2450                  m_current_pitch += ((m_target_pitch - m_current_pitch) M_INTERP_SHIFT);
2451                  break;
2452               case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
2453                  /* PC = 2 through 11, B cycle, write updated K1 through K10 */
2454                  m_current_k[m_PC-2] += ((m_target_k[m_PC-2] - m_current_k[m_PC-2]) M_INTERP_SHIFT);
2455                  break;
2456               case 12: /* PC = 12, do nothing */
2457                  break;
2458               }
2459            }
2460         }
2461#endif
2462      }
2463
2464      // calculate the output
2465      if (M_OLD_FRAME_UNVOICED_FLAG == true)
2466      {
2467         // generate unvoiced samples here
2468         if (m_RNG & 1)
2469            m_excitation_data = ~0x3F; // according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)
2470         else
2471            m_excitation_data = 0x40;
2472      }
2473      else // (M_OLD_FRAME_UNVOICED_FLAG == false)
2474      {
2475         // generate voiced samples here
2476         // US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
2477         // function has a chirp/peak and then a long chain of zeroes.
2478         // The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
2479         // and if the address reaches that point the ADDRESS incrementer is
2480         // disabled, forcing all samples beyond 51d to be == 51d
2481
2482         if (m_pitch_count >= 51)
2483            m_excitation_data = m_coeff->chirptable[51];
2484         else // tms->pitch_count < 51
2485            m_excitation_data = m_coeff->chirptable[m_pitch_count];
2486      }
2487
2488      // Update LFSR *20* times every sample (once per T cycle), like patent shows
2489      for (i=0; i<20; i++)
2490      {
2491         bitout = ((m_RNG >> 12) & 1) ^
2492               ((m_RNG >>  3) & 1) ^
2493               ((m_RNG >>  2) & 1) ^
2494               ((m_RNG >>  0) & 1);
2495         m_RNG <<= 1;
2496         m_RNG |= bitout;
2497      }
2498
2499      this_sample = lattice_filter(); // execute lattice filter
2500#ifdef DEBUG_GENERATION_VERBOSE
2501      //fprintf(stderr,"C:%01d; ",tms->subcycle);
2502      fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC,
2503         m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
2504      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
2505      for (i=0; i<10; i++)
2506         fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
2507      fprintf(stderr,"Out:%06d", this_sample);
2508      fprintf(stderr,"\n");
2509#endif
2510      // next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed)
2511      while (this_sample > 16383) this_sample -= 32768;
2512      while (this_sample < -16384) this_sample += 32768;
2513      if (!m_digital_select) // analog SPK pin output is only 8 bits, with clipping
2514         buffer[buf_count] = clip_analog(this_sample);
2515      else // digital I/O pin output is 12 bits
2516      {
2517#ifdef ALLOW_4_LSB
2518         // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
2519         // N taps:                       ^                 = 0x2000;
2520         // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
2521         buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
2522#else
2523         this_sample &= ~0xF;
2524         // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
2525         // N taps:                       ^^ ^^^            = 0x3E00;
2526         // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
2527         buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
2528#endif
2529      }
2530
2531      // Update all counts
2532      m_subcycle++;
2533      if ((m_subcycle == 2) && (m_PC == 12))
2534      {
2535         /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
2536          * if INHIBIT was true during the most recent frame transition.
2537          * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
2538          * and tms->IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
2539          * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
2540          * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
2541          * convenient and should make no difference in output.
2542          */
2543         if ((m_IP == 7) && m_inhibit) m_pitch_count = 0;
2544         m_subcycle = m_subc_reload;
2545         m_PC = 0;
2546         m_IP++;
2547         m_IP &= 0x7;
2548      }
2549      else if (m_subcycle == 3)
2550      {
2551         m_subcycle = m_subc_reload;
2552         m_PC++;
2553      }
2554      m_pitch_count++;
2555      if (m_pitch_count >= m_current_pitch) m_pitch_count = 0;
2556      m_pitch_count &= 0x1FF;
2557      buf_count++;
2558      size--;
2559   }
2560
2561empty:
2562
2563   while (size > 0)
2564   {
2565      m_subcycle++;
2566      if ((m_subcycle == 2) && (m_PC == 12))
2567      {
2568         m_subcycle = m_subc_reload;
2569         m_PC = 0;
2570         m_IP++;
2571         m_IP &= 0x7;
2572      }
2573      else if (m_subcycle == 3)
2574      {
2575         m_subcycle = m_subc_reload;
2576         m_PC++;
2577      }
2578      buffer[buf_count] = -1; // should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4)
2579      buf_count++;
2580      size--;
2581   }
2582}
2583
2584/******************************************************************************
2585    lattice_filter -- executes one 'full run' of the lattice filter on a
2586    specific byte of excitation data, and specific values of all the current k
2587    constants,  and returns the resulting sample.
2588******************************************************************************/
2589
2590INT32 tms52xx_device::lattice_filter()
2591{
2592   /* Lattice filter here */
2593   /* Aug/05/07: redone as unrolled loop, for clarity - LN
2594    * Originally Copied verbatim from table I in US patent 4,209,804, now updated
2595    * to be in same order as the actual chip does it, not that it matters.
2596    * notation equivalencies from table:
2597    *      Yn(i) == m_u[n-1]
2598    *      Kn = m_current_k[n-1]
2599    *      bn = m_x[n-1]
2600    */
2601
2602   m_u[10] = matrix_multiply(m_previous_energy, (m_excitation_data<<6));  //Y(11)
2603   m_u[9] = m_u[10] - matrix_multiply(m_current_k[9], m_x[9]);
2604   m_u[8] = m_u[9] - matrix_multiply(m_current_k[8], m_x[8]);
2605   m_u[7] = m_u[8] - matrix_multiply(m_current_k[7], m_x[7]);
2606   m_u[6] = m_u[7] - matrix_multiply(m_current_k[6], m_x[6]);
2607   m_u[5] = m_u[6] - matrix_multiply(m_current_k[5], m_x[5]);
2608   m_u[4] = m_u[5] - matrix_multiply(m_current_k[4], m_x[4]);
2609   m_u[3] = m_u[4] - matrix_multiply(m_current_k[3], m_x[3]);
2610   m_u[2] = m_u[3] - matrix_multiply(m_current_k[2], m_x[2]);
2611   m_u[1] = m_u[2] - matrix_multiply(m_current_k[1], m_x[1]);
2612   m_u[0] = m_u[1] - matrix_multiply(m_current_k[0], m_x[0]);
2613   m_x[9] = m_x[8] + matrix_multiply(m_current_k[8], m_u[8]);
2614   m_x[8] = m_x[7] + matrix_multiply(m_current_k[7], m_u[7]);
2615   m_x[7] = m_x[6] + matrix_multiply(m_current_k[6], m_u[6]);
2616   m_x[6] = m_x[5] + matrix_multiply(m_current_k[5], m_u[5]);
2617   m_x[5] = m_x[4] + matrix_multiply(m_current_k[4], m_u[4]);
2618   m_x[4] = m_x[3] + matrix_multiply(m_current_k[3], m_u[3]);
2619   m_x[3] = m_x[2] + matrix_multiply(m_current_k[2], m_u[2]);
2620   m_x[2] = m_x[1] + matrix_multiply(m_current_k[1], m_u[1]);
2621   m_x[1] = m_x[0] + matrix_multiply(m_current_k[0], m_u[0]);
2622   m_x[0] = m_u[0];
2623   m_previous_energy = m_current_energy;
2624#ifdef DEBUG_LATTICE
2625
2626   int i;
2627   fprintf(stderr,"V:%04d ", m_u[10]);
2628   for (i = 9; i >= 0; i--)
2629   {
2630      fprintf(stderr,"Y%d:%04d ", i+1, m_u[i]);
2631      fprintf(stderr,"b%d:%04d ", i+1, m_x[i]);
2632      if ((i % 5) == 0) fprintf(stderr,"\n");
2633   }
2634#endif
2635   return m_u[0];
2636}
2637
2638/**********************************************************************************************
2639    data_write -- handle a write to the TMS5220
2640***********************************************************************************************/
2641
2642void tms52xx_device::data_write(int data)
2643{
2644#ifdef DEBUG_DUMP_INPUT_DATA
2645   fprintf(stdout, "%c",data);
2646#endif
2647   if (m_speak_external) // If we're in speak external mode
2648   {
2649      /* add this byte to the FIFO */
2650      if (m_fifo_count < FIFO_SIZE)
2651      {
2652         m_fifo[m_fifo_tail] = data;
2653         m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE;
2654         m_fifo_count++;
2655#ifdef DEBUG_FIFO
2656         logerror("tms52xx: data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
2657#endif
2658         update_status_and_ints();
2659         if ((!m_talk_status) && (!m_buffer_low)) // we just unset buffer low with that last write, and talk status *was* zero...
2660         {
2661            int i;
2662#ifdef DEBUG_FIFO
2663            logerror("tms52xx: data_write triggered talk status to go active!\n");
2664#endif
2665            /* ...then we now have enough bytes to start talking; clear out
2666             * the new frame parameters (it will become old frame just before the first call to parse_frame())
2667             * TODO: the 3 lines below (and others) are needed for victory
2668             * to not fail its selftest due to a sample ending too late, may require additional investigation */
2669            m_subcycle = m_subc_reload;
2670            m_PC = 0;
2671            m_IP = reload_table[m_tms5220c_rate & 0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
2672            m_new_frame_energy_idx = 0;
2673            m_new_frame_pitch_idx = 0;
2674
2675            for (i = 0; i < 4; i++)
2676               m_new_frame_k_idx[i] = 0;
2677            for (i = 4; i < 7; i++)
2678               m_new_frame_k_idx[i] = 0xF;
2679            for (i = 7; i < m_coeff->num_k; i++)
2680               m_new_frame_k_idx[i] = 0x7;
2681            m_talk_status = m_speaking_now = true;
2682         }
2683      }
2684      else
2685      {
2686#ifdef DEBUG_FIFO
2687         logerror("tms52xx: data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
2688         // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it.
2689#endif
2690      }
2691
2692
2693   }
2694   else //(! m_speak_external)
2695      /* R Nabet : we parse commands at once.  It is necessary for such commands as read. */
2696      process_command(data);
2697}
2698
2699/******************************************************************************
2700    process_command -- extract a byte from the FIFO and interpret it as a command
2701*******************************************************************************/
2702
2703void tms52xx_device::process_command(unsigned char cmd)
2704{
2705#ifdef DEBUG_COMMAND_DUMP
2706   fprintf(stderr,"process_command called with parameter %02X\n",cmd);
2707#endif
2708   // parse the command
2709   switch (cmd & 0x70)
2710   {
2711   case 0x10 : // read byte
2712      if (!m_talk_status) // TALKST must be clear for RDBY
2713      {
2714         if (m_schedule_dummy_read)
2715         {
2716            m_schedule_dummy_read = false;
2717            (void)m_read_mem(1);
2718         }
2719         m_data_register = m_read_mem(8);    // read one byte from speech ROM...
2720         m_RDB_flag = true;
2721      }
2722      break;
2723
2724   case 0x00:
2725   case 0x20: // set rate (tms5220c only), otherwise NOP
2726      if (m_variant == TMS5220_IS_5220C)
2727      {
2728         m_tms5220c_rate = cmd & 0x0F;
2729      }
2730      break;
2731
2732   case 0x30: // read and branch
2733      if (!m_talk_status) // TALKST must be clear for RB
2734      {
2735#ifdef VERBOSE
2736         logerror("tms5520: read and branch command received\n");
2737#endif
2738         m_RDB_flag = false;
2739         m_read_and_branch(0, 0);
2740      }
2741      break;
2742
2743   case 0x40 : // load address
2744      if (!m_talk_status) // TALKST must be clear for LA
2745      {
2746         // tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
2747         // This code does not care about this.
2748         m_load_address(0, cmd & 0x0f);
2749         m_schedule_dummy_read = true;
2750      }
2751      break;
2752
2753   case 0x50:  // speak
2754      if (m_schedule_dummy_read)
2755      {
2756         m_schedule_dummy_read = false;
2757         (void)m_read_mem(1);
2758      }
2759      m_speaking_now = true;
2760      m_speak_external = false;
2761      m_talk_status = true;  // start immediately
2762      // clear out variables before speaking
2763      // TODO: similar to the victory case described above, but for VSM speech
2764      m_subcycle = m_subc_reload;
2765      m_PC = 0;
2766      m_IP = reload_table[m_tms5220c_rate & 0x3];
2767      m_new_frame_energy_idx = 0;
2768      m_new_frame_pitch_idx = 0;
2769
2770      int i;
2771      for (i = 0; i < 4; i++)
2772         m_new_frame_k_idx[i] = 0;
2773      for (i = 4; i < 7; i++)
2774         m_new_frame_k_idx[i] = 0xF;
2775      for (i = 7; i < m_coeff->num_k; i++)
2776         m_new_frame_k_idx[i] = 0x7;
2777      break;
2778
2779   case 0x60: // speak external
2780      //SPKEXT going active activates SPKEE which clears the fifo
2781      m_fifo_head = m_fifo_tail = 0;
2782      m_fifo_count = m_fifo_bits_taken = 0;
2783      m_speak_external = true;
2784      m_RDB_flag = false;
2785      break;
2786
2787   case 0x70: // reset
2788      if (m_schedule_dummy_read)
2789      {
2790         m_schedule_dummy_read = false;
2791         (void)m_read_mem(1);
2792      }
2793      device_reset();
2794      break;
2795   }
2796
2797   // update the buffer low state
2798   update_status_and_ints();
2799}
2800
2801/******************************************************************************
2802    parse_frame -- parse a new frame's worth of data; returns 0 if not
2803    enough bits in buffer
2804*******************************************************************************/
2805
2806void tms52xx_device::parse_frame()
2807{
2808   int indx, i, rep_flag;
2809
2810   /* We actually don't care how many bits are left in the fifo here; the
2811    * frame subpart will be processed normally, and any bits extracted 'past
2812    * the end' of the fifo will be read as zeroes; the fifo being emptied will
2813    * set the /BE latch which will halt speech exactly as if a stop frame had
2814    * been encountered (instead of whatever partial frame was read); the same
2815    * exact circuitry is used for both on the real chip, see us patent 4335277
2816    * sheet 16, gates 232a (decode stop frame) and 232b (decode /BE plus DDIS
2817    * (decode disable) which is active during speak external). */
2818
2819   /* if the chip is a tms5220C, and the rate mode is set to that each frame (0x04 bit set)
2820    * has a 2 bit rate preceding it, grab two bits here and store them as the rate; */
2821   if ((m_variant == TMS5220_IS_5220C) && (m_tms5220c_rate & 0x04))
2822   {
2823      indx = extract_bits(2);
2824#ifdef DEBUG_PARSE_FRAME_DUMP
2825      printbits(indx,2);
2826      fprintf(stderr," ");
2827#endif
2828      m_IP = reload_table[indx];
2829   }
2830   else // non-5220C and 5220C in fixed rate mode
2831      m_IP = reload_table[m_tms5220c_rate & 0x3];
2832
2833   update_status_and_ints();
2834   if (!m_talk_status) goto ranout;
2835
2836   // attempt to extract the energy index
2837   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
2838#ifdef DEBUG_PARSE_FRAME_DUMP
2839   printbits(m_new_frame_energy_idx,m_coeff->energy_bits);
2840   fprintf(stderr," ");
2841#endif
2842   update_status_and_ints();
2843   if (!m_talk_status) goto ranout;
2844   // if the energy index is 0 or 15, we're done
2845   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
2846      return;
2847
2848   // attempt to extract the repeat flag
2849   rep_flag = extract_bits(1);
2850#ifdef DEBUG_PARSE_FRAME_DUMP
2851   printbits(rep_flag, 1);
2852   fprintf(stderr," ");
2853#endif
2854
2855   // attempt to extract the pitch
2856   m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits);
2857#ifdef DEBUG_PARSE_FRAME_DUMP
2858   printbits(m_new_frame_pitch_idx, m_coeff->pitch_bits);
2859   fprintf(stderr," ");
2860#endif
2861   update_status_and_ints();
2862   if (!m_talk_status) goto ranout;
2863   /* if this is a repeat frame, just do nothing, it will reuse the
2864    * old coefficients */
2865   if (rep_flag) return;
2866
2867   // extract first 4 K coefficients
2868   for (i = 0; i < 4; i++)
2869   {
2870      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
2871#ifdef DEBUG_PARSE_FRAME_DUMP
2872      printbits(m_new_frame_k_idx[i], m_coeff->kbits[i]);
2873      fprintf(stderr," ");
2874#endif
2875      update_status_and_ints();
2876      if (!m_talk_status) goto ranout;
2877   }
2878
2879   // if the pitch index was zero, we only need 4 K's...
2880   if (m_new_frame_pitch_idx == 0)
2881   {
2882      // and the rest of the coefficients are zeroed, but that's done in the generator code
2883      return;
2884   }
2885
2886   // If we got here, we need the remaining 6 K's
2887   for (i = 4; i < m_coeff->num_k; i++)
2888   {
2889      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
2890#ifdef DEBUG_PARSE_FRAME_DUMP
2891      printbits(m_new_frame_k_idx[i], m_coeff->kbits[i]);
2892      fprintf(stderr," ");
2893#endif
2894      update_status_and_ints();
2895      if (!m_talk_status) goto ranout;
2896   }
2897#ifdef VERBOSE
2898   if (m_speak_external)
2899      logerror("tms52xx: Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
2900   else
2901      logerror("tms52xx: Parsed a frame successfully in ROM\n");
2902#endif
2903   return;
2904
2905   ranout:
2906#ifdef DEBUG_FRAME_ERRORS
2907   logerror("tms52xx: Ran out of bits on a parse!\n");
2908#endif
2909   return;
2910}
2911
2912/**********************************************************************************************
2913
2914     update_status_and_ints -- check to see if the various flags should be on or off
2915     Description of flags, and their position in the status register:
2916      From the data sheet:
2917        bit D0(bit 7) = TS - Talk Status is active (high) when the VSP is processing speech data.
2918                Talk Status goes active at the initiation of a Speak command or after nine
2919                bytes of data are loaded into the FIFO following a Speak External command. It
2920                goes inactive (low) when the stop code (Energy=1111) is processed, or
2921                immediately by a buffer empty condition or a reset command.
2922        bit D1(bit 6) = BL - Buffer Low is active (high) when the FIFO buffer is more than half empty.
2923                Buffer Low is set when the "Last-In" byte is shifted down past the half-full
2924                boundary of the stack. Buffer Low is cleared when data is loaded to the stack
2925                so that the "Last-In" byte lies above the half-full boundary and becomes the
2926                eighth data byte of the stack.
2927        bit D2(bit 5) = BE - Buffer Empty is active (high) when the FIFO buffer has run out of data
2928                while executing a Speak External command. Buffer Empty is set when the last bit
2929                of the "Last-In" byte is shifted out to the Synthesis Section. This causes
2930                Talk Status to be cleared. Speech is terminated at some abnormal point and the
2931                Speak External command execution is terminated.
2932
2933***********************************************************************************************/
2934
2935void tms52xx_device::update_status_and_ints()
2936{
2937   // update flags and set ints if needed
2938   update_ready_state();
2939
2940   /* BL is set if neither byte 9 nor 8 of the fifo are in use; this
2941    * translates to having fifo_count (which ranges from 0 bytes in use to 16
2942    * bytes used) being less than or equal to 8. Victory/Victorba depends on this. */
2943   if (m_fifo_count <= 8)
2944   {
2945      // generate an interrupt if necessary; if /BL was inactive and is now active, set int.
2946      if (!m_buffer_low) set_interrupt_state(1);
2947      m_buffer_low = true;
2948   }
2949   else
2950      m_buffer_low = false;
2951
2952   /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
2953    * translates to having fifo_count equal to exactly 0 */
2954   if (m_fifo_count == 0)
2955   {
2956      // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
2957      if (!m_buffer_empty) set_interrupt_state(1);
2958      m_buffer_empty = true;
2959   }
2960   else
2961      m_buffer_empty = false;
2962
2963   /* TS is talk status and is set elsewhere in the fifo parser and in
2964    * the SPEAK command handler; however, if /BE is true during speak external
2965    * mode, it is immediately unset here. */
2966   if (m_speak_external && m_buffer_empty)
2967   {
2968      // generate an interrupt: /TS was active, and is now inactive.
2969      if (m_talk_status)
2970      {
2971         m_talk_status = m_speak_external = false;
2972         set_interrupt_state(1);
2973      }
2974   }
2975   /* Note that TS being unset will also generate an interrupt when a STOP
2976    * frame is encountered; this is handled in the sample generator code and not here */
2977}
2978
2979/******************************************************************************
2980    extract_bits -- extract a specific number of bits from the current input stream (FIFO or VSM)
2981*******************************************************************************/
2982
2983int tms52xx_device::extract_bits(int count)
2984{
2985   int val = 0;
2986
2987   if (m_speak_external)
2988   {
2989      // extract from FIFO
2990      while (count--)
2991      {
2992         val = (val << 1) | ((m_fifo[m_fifo_head] >> m_fifo_bits_taken) & 1);
2993         m_fifo_bits_taken++;
2994         if (m_fifo_bits_taken >= 8)
2995         {
2996            m_fifo_count--;
2997            m_fifo[m_fifo_head] = 0; // zero the newly depleted fifo head byte
2998            m_fifo_head = (m_fifo_head + 1) % FIFO_SIZE;
2999            m_fifo_bits_taken = 0;
3000            update_status_and_ints();
3001         }
3002      }
3003   }
3004   else
3005   {
3006      // extract from VSM (speech ROM)
3007      val = m_read_mem(count);
3008   }
3009   return val;
3010}
3011
3012/******************************************************************************
3013    status_read -- read status or data from the TMS5220
3014*******************************************************************************/
3015
3016int tms52xx_device::status_read()
3017{
3018   if (m_RDB_flag)
3019   {   // if last command was read, return data register
3020      m_RDB_flag = false;
3021      return m_data_register;
3022   }
3023   else
3024   {   // read status
3025      // clear the interrupt pin on status read
3026      set_interrupt_state(0);
3027#ifdef DEBUG_PIN_READS
3028      logerror("tms52xx: Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty);
3029#endif
3030
3031      int retvalue = 0;
3032      if (m_talk_status) retvalue |= 0x80;
3033      if (m_buffer_low) retvalue |= 0x40;
3034      if (m_buffer_empty) retvalue |= 0x20;
3035      return retvalue;
3036   }
3037}
3038
3039/******************************************************************************
3040    ready_read -- returns the ready state of the TMS5220
3041*******************************************************************************/
3042
3043inline bool tms52xx_device::ready_read()
3044{
3045#ifdef DEBUG_PIN_READS
3046   logerror("tms52xx: ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count);
3047#endif
3048   return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready;
3049}
3050
3051/******************************************************************************
3052    int_read -- returns the interrupt state of the TMS5220
3053*******************************************************************************/
3054
3055inline int tms52xx_device::int_read()
3056{
3057#ifdef DEBUG_PIN_READS
3058   logerror("tms52xx: int_read: irq pin read, state is %d\n", m_irq_pin);
3059#endif
3060   return m_irq_pin;
3061}
3062
3063/******************************************************************************
3064    cycles_to_ready -- returns the number of cycles until ready is asserted
3065    NOTE: this function is deprecated and is known to be VERY inaccurate.
3066    Use at your own peril!
3067*******************************************************************************/
3068
3069int tms52xx_device::cycles_to_ready()
3070{
3071   int answer;
3072
3073   if (ready_read()) answer = 0;
3074   else
3075   {
3076      int val;
3077      int samples_per_frame = (m_subc_reload!=0)?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
3078      int current_sample = ((m_PC * (3-m_subc_reload)) + (((m_subc_reload!=0)? 38:25) * m_IP));
3079      answer = samples_per_frame - current_sample + 8;
3080
3081      // total number of bits available in current byte is (8 - tms->fifo_bits_taken)
3082      // if more than 4 are available, we need to check the energy
3083      if (m_fifo_bits_taken < 4)
3084      {
3085         // read energy
3086         val = (m_fifo[m_fifo_head] >> m_fifo_bits_taken) & 0xf;
3087         if (val == 0)
3088            // 0 -> silence frame: we will only read 4 bits, and we will
3089            // therefore need to read another frame before the FIFO is not
3090            // full any more
3091            answer += (m_subc_reload!=0)?200:304;
3092         // 15 -> stop frame, we will only read 4 bits, but the FIFO will
3093         // we cleared
3094         //otherwise, we need to parse the repeat flag (1 bit) and the
3095         // pitch (6 bits), so everything will be OK.
3096      }
3097   }
3098   return answer;
3099}
3100
3101/******************************************************************************
3102    True timing
3103*******************************************************************************/
3104
3105void tms52xx_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
3106{
3107   if (param)
3108   {
3109      switch (m_rs_ws)
3110      {
3111      case 0x02:
3112         // Write
3113         // bring up to date first
3114#ifdef DEBUG_IO_READY
3115         logerror("tms52xx: Serviced write: %02x\n", tms->write_latch);
3116         //fprintf(stderr, "Processed write data: %02X\n", tms->write_latch);
3117#endif
3118         m_stream->update();
3119         data_write(m_write_latch);
3120         break;
3121      case 0x01:
3122         // Read
3123         // bring up to date first
3124         m_stream->update();
3125         m_read_latch = status_read();
3126         break;
3127      case 0x03:
3128         // High Impedance
3129      case 0x00:
3130         // illegal
3131         break;
3132      }
3133   }
3134   m_io_ready = param;
3135   update_ready_state();
3136}
3137
3138/*****************************************************
3139    /RS line write handler
3140*****************************************************/
3141
3142WRITE_LINE_MEMBER( tms52xx_device::rsq_w )
3143{
3144   UINT8 new_val;
3145
3146   m_true_timing = true;
3147   state &= 0x01;
3148#ifdef DEBUG_RS_WS
3149   logerror("tms52xx: /RS written with data: %d\n", state);
3150#endif
3151   new_val = (m_rs_ws & 0x01) | (state<<1);
3152   if (new_val != m_rs_ws)
3153   {
3154      m_rs_ws = new_val;
3155      if (new_val == 0)
3156      {
3157         if (m_variant == TMS5220_IS_5220C)
3158            reset();
3159#ifdef DEBUG_RS_WS
3160         else
3161            // illegal
3162            logerror("tms52xx: illegal line setting /RS=0 and /WS=0\n");
3163#endif
3164         return;
3165      }
3166      else if (new_val == 3)
3167      {
3168         // high impedance
3169         m_read_latch = 0xff;
3170         return;
3171      }
3172      if (state)
3173      {
3174         // low to high
3175      }
3176      else
3177      {
3178         // high to low - schedule ready cycle
3179#ifdef DEBUG_RS_WS
3180         logerror("tms52xx: Scheduling ready cycle for /RS...\n");
3181#endif
3182         /* upon /RS being activated, /READY goes inactive after 100 nsec from
3183          * data sheet, through 3 asynchronous gates on patent. This is effectively
3184          * within one clock, so we immediately set io_ready to 0 and activate the callback. */
3185         m_io_ready = 0;
3186         update_ready_state();
3187         /* How long does /READY stay inactive, when /RS is pulled low?
3188          * I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */
3189         m_ready_timer->adjust(attotime::from_hz(clock()/16));
3190      }
3191   }
3192}
3193
3194/*****************************************************
3195    /WS line write handler
3196*****************************************************/
3197
3198WRITE_LINE_MEMBER( tms52xx_device::wsq_w )
3199{
3200   UINT8 new_val;
3201
3202   m_true_timing = true;
3203   state &= 0x01;
3204#ifdef DEBUG_RS_WS
3205   logerror("tms52xx: /WS written with data: %d\n", state);
3206#endif
3207   new_val = (m_rs_ws & 0x02) | (state<<0);
3208   if (new_val != m_rs_ws)
3209   {
3210      m_rs_ws = new_val;
3211      if (new_val == 0)
3212      {
3213         if (m_variant == TMS5220_IS_5220C)
3214            reset();
3215#ifdef DEBUG_RS_WS
3216         else
3217            // illegal
3218            logerror("tms52xx: illegal line setting /RS=0 and /WS=0\n");
3219#endif
3220         return;
3221      }
3222      else if ( new_val == 3)
3223      {
3224         // high impedance
3225         m_read_latch = 0xff;
3226         return;
3227      }
3228      if (state)
3229      {
3230         // low to high
3231      }
3232      else
3233      {
3234         // high to low - schedule ready cycle
3235#ifdef DEBUG_RS_WS
3236         logerror("tms52xx: Scheduling ready cycle for /WS...\n");
3237#endif
3238         /* upon /WS being activated, /READY goes inactive after 100 nsec
3239          * from data sheet, through 3 asynchronous gates on patent.
3240          * This is effectively within one clock, so we immediately set
3241          * io_ready to 0 and activate the callback. */
3242         m_io_ready = 0;
3243         update_ready_state();
3244         /* Now comes the complicated part: long does /READY stay inactive
3245          * when /WS is pulled low? This depends ENTIRELY on the command written,
3246          * or whether the chip is in speak external mode or not...
3247          * Speak external mode: ~16 cycles
3248          * Command Mode:
3249          * SPK: ? cycles
3250          * SPKEXT: ? cycles
3251          * RDBY: between 60 and 140 cycles
3252          * RB: ? cycles (80?)
3253          * RST: between 60 and 140 cycles
3254          * SET RATE (5220C only): ? cycles (probably ~16) */
3255
3256         // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles
3257         m_ready_timer->adjust(attotime::from_hz(clock()/16));
3258      }
3259   }
3260}
3261
3262/*****************************************************************************
3263    write -- write data to the sound chip
3264*******************************************************************************/
3265
3266WRITE8_MEMBER( tms52xx_device::write )
3267{
3268#ifdef DEBUG_RS_WS
3269   logerror("tms52xx: write data %02x\n", data);
3270#endif
3271   if (!m_true_timing)
3272   {
3273      // bring up to date first
3274      m_stream->update();
3275      data_write(data);
3276   }
3277   else
3278   {
3279      // actually in a write?
3280#ifdef DEBUG_RS_WS
3281      if (!(m_rs_ws == 0x02))
3282         logerror("tms52xx: write data written outside ws, status: %02x!\n", m_rs_ws);
3283#endif
3284      m_write_latch = data;
3285   }
3286}
3287
3288/******************************************************************************
3289    read -- read status or data from the sound chip
3290*******************************************************************************/
3291
3292READ8_MEMBER( tms52xx_device::read )
3293{
3294   if (!m_true_timing)
3295   {
3296      // bring up-to-date first
3297      m_stream->update();
3298      return status_read();
3299   }
3300   else
3301   {
3302      // actually in a read?
3303      if (m_rs_ws == 0x01)
3304         return m_read_latch;
3305#ifdef DEBUG_RS_WS
3306      else
3307         logerror("tms52xx: data read outside rs!\n");
3308#endif
3309      return 0xff;
3310   }
3311}
3312
3313/*******************************************************************************
3314    ready -- return the not ready status from the sound chip
3315*******************************************************************************/
3316
3317READ_LINE_MEMBER( tms52xx_device::readyq )
3318{
3319   // bring up-to-date first
3320   m_stream->update();
3321   return !ready_read();
3322}
3323
3324
3325/******************************************************************************
3326    time_to_ready -- return the time in seconds until the
3327    ready line is asserted
3328*******************************************************************************/
3329
3330double tms52xx_device::time_to_ready()
3331{
3332   double cycles;
3333
3334   // bring up-to-date
3335   m_stream->update();
3336   cycles = cycles_to_ready();
3337   return cycles * 80.0 / m_clock;
3338}
3339
3340/******************************************************************************
3341    intq -- return the interrupt status from the sound chip
3342******************************************************************************/
3343
3344READ_LINE_MEMBER( tms52xx_device::intq )
3345{
3346   // bring up-to-date first
3347   m_stream->update();
3348   return !int_read();
3349}
3350
3351void tms52xx_device::register_for_save_states()
3352{
3353   save_item(NAME(m_fifo));
3354   save_item(NAME(m_fifo_head));
3355   save_item(NAME(m_fifo_tail));
3356   save_item(NAME(m_fifo_count));
3357   save_item(NAME(m_fifo_bits_taken));
3358
3359   save_item(NAME(m_speaking_now));
3360   save_item(NAME(m_speak_external));
3361   save_item(NAME(m_talk_status));
3362   save_item(NAME(m_buffer_low));
3363   save_item(NAME(m_buffer_empty));
3364   save_item(NAME(m_irq_pin));
3365   save_item(NAME(m_ready_pin));
3366
3367   save_item(NAME(m_OLDE));
3368   save_item(NAME(m_OLDP));
3369
3370   save_item(NAME(m_new_frame_energy_idx));
3371   save_item(NAME(m_new_frame_pitch_idx));
3372   save_item(NAME(m_new_frame_k_idx));
3373#ifdef PERFECT_INTERPOLATION_HACK
3374   save_item(NAME(m_old_frame_energy_idx));
3375   save_item(NAME(m_old_frame_pitch_idx));
3376   save_item(NAME(m_old_frame_k_idx));
3377#endif
3378   save_item(NAME(m_current_energy));
3379   save_item(NAME(m_current_pitch));
3380   save_item(NAME(m_current_k));
3381
3382   save_item(NAME(m_target_energy));
3383   save_item(NAME(m_target_pitch));
3384   save_item(NAME(m_target_k));
3385
3386   save_item(NAME(m_previous_energy));
3387
3388   save_item(NAME(m_subcycle));
3389   save_item(NAME(m_subc_reload));
3390   save_item(NAME(m_PC));
3391   save_item(NAME(m_IP));
3392   save_item(NAME(m_inhibit));
3393   save_item(NAME(m_tms5220c_rate));
3394   save_item(NAME(m_pitch_count));
3395
3396   save_item(NAME(m_u));
3397   save_item(NAME(m_x));
3398
3399   save_item(NAME(m_RNG));
3400   save_item(NAME(m_excitation_data));
3401
3402   save_item(NAME(m_schedule_dummy_read));
3403   save_item(NAME(m_data_register));
3404   save_item(NAME(m_RDB_flag));
3405   save_item(NAME(m_digital_select));
3406
3407   save_item(NAME(m_io_ready));
3408}
3409
3410
3411const device_type TMS5220N = &device_creator<tms5220n_device>;
3412const device_type TMS5220CN = &device_creator<tms5220cn_device>;
3413const device_type TMC0285N = &device_creator<tmc0285n_device>;
3414const device_type TMS5200N = &device_creator<tms5200n_device>;
trunk/src/emu/sound/tms5220.h
r22818r22819
33#ifndef __TMS5220_H__
44#define __TMS5220_H__
55
6#include "devlegcy.h"
6#include "emu.h"
7#include "machine/spchrom.h"
78
9/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
10#undef PERFECT_INTERPOLATION_HACK
11
812#define FIFO_SIZE 16
913
1014/* clock rate = 80 * output sample rate,     */
1115/* usually 640000 for 8000 Hz sample rate or */
1216/* usually 800000 for 10000 Hz sample rate.  */
1317
14struct tms5220_interface
15{
16   devcb_write_line irq_func;      /* IRQ callback function, active low, i.e. state=0 */
17   devcb_write_line readyq_func;   /* Ready callback function, active low, i.e. state=0 */
18/* IRQ callback function, active low, i.e. state=0 */
19#define MCFG_TMS52XX_IRQ_HANDLER(_devcb) \
20   devcb = &tms5220_device::set_irq_handler(*device, DEVCB2_##_devcb);
1821
19   int (*read)(device_t *device, int count);           /* speech ROM read callback */
20   void (*load_address)(device_t *device, int data);   /* speech ROM load address callback */
21   void (*read_and_branch)(device_t *device);      /* speech ROM read and branch callback */
22};
22/* Ready callback function, active low, i.e. state=0 */
23#define MCFG_TMS52XX_READYQ_HANDLER(_devcb) \
24   devcb = &tms5220_device::set_readyq_handler(*device, DEVCB2_##_devcb);
2325
24/* Control lines - once written to will switch interface into
25 * "true" timing behaviour.
26 */
26#define MCFG_TMS52XX_SPEECHROM(_tag) \
27   tms5220_device::set_speechrom_tag(*device, _tag);
2728
28/* all lines with suffix q are active low! */
29
30WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w );
31WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w );
32
33DECLARE_WRITE8_DEVICE_HANDLER( tms5220_data_w );
34DECLARE_READ8_DEVICE_HANDLER( tms5220_status_r );
35
36READ_LINE_DEVICE_HANDLER( tms5220_readyq_r );
37READ_LINE_DEVICE_HANDLER( tms5220_intq_r );
38
39
40double tms5220_time_to_ready(device_t *device);
41
42void tms5220_set_frequency(device_t *device, int frequency);
43
4429class tms5220_device : public device_t,
4530                           public device_sound_interface
4631{
4732public:
4833   tms5220_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
4934   tms5220_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
50   ~tms5220_device() { global_free(m_token); }
5135
52   // access to legacy token
53   void *token() const { assert(m_token != NULL); return m_token; }
54protected:
55   // device-level overrides
56   virtual void device_config_complete();
57   virtual void device_start();
58   virtual void device_reset();
36   // static configuration helpers
37   template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<tms5220_device &>(device).m_irq_handler.set_callback(object); }
38   template<class _Object> static devcb2_base &set_readyq_handler(device_t &device, _Object object) { return downcast<tms5220_device &>(device).m_readyq_handler.set_callback(object); }
39   static void set_speechrom_tag(device_t &device, const char *_tag) { downcast<tms5220_device &>(device).m_speechrom_tag = _tag; }
5940
60   // sound stream update overrides
61   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
62private:
63   // internal state
64   void *m_token;
65};
41   /* Control lines - once written to will switch interface into
42    * "true" timing behaviour.
43    */
6644
67extern const device_type TMS5220;
45   /* all lines with suffix q are active low! */
6846
69class tms5220c_device : public tms5220_device
70{
71public:
72   tms5220c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
73protected:
74   // device-level overrides
75   virtual void device_start();
47   WRITE_LINE_MEMBER( rsq_w );
48   WRITE_LINE_MEMBER( wsq_w );
7649
77   // sound stream update overrides
78   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
79};
50   DECLARE_WRITE8_MEMBER( data_w );
51   DECLARE_READ8_MEMBER( status_r );
8052
81extern const device_type TMS5220C;
53   READ_LINE_MEMBER( readyq_r );
54   READ_LINE_MEMBER( intq_r );
8255
83class tmc0285_device : public tms5220_device
84{
85public:
86   tmc0285_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
87protected:
88   // device-level overrides
89   virtual void device_start();
56   double time_to_ready();
9057
91   // sound stream update overrides
92   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
93};
58   void set_frequency(int frequency);
9459
95extern const device_type TMC0285;
96
97class tms5200_device : public tms5220_device
98{
99public:
100   tms5200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
10160protected:
10261   // device-level overrides
62   virtual void device_config_complete();
10363   virtual void device_start();
64   virtual void device_reset();
10465
66   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
67
10568   // sound stream update overrides
10669   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
107};
10870
109extern const device_type TMS5200;
71   void set_variant(int variant);
11072
111
112
113/***************************************************************************
114        New class implementation
115        Michael Zapf, June 2012
116***************************************************************************/
117
118extern const device_type TMS5220N;
119extern const device_type TMS5220CN;
120extern const device_type TMC0285N;
121extern const device_type TMS5200N;
122
123
124struct tms52xx_config
125{
126   devcb_write_line        irq_func;                   // IRQ callback function, active low, i.e. state=0  (TODO: change to ASSERT/CLEAR)
127   devcb_write_line        readyq_func;                // Ready callback function, active low, i.e. state=0
128
129   devcb_read8             read_mem;                   // speech ROM read callback
130   devcb_write8            load_address;               // speech ROM load address callback
131   devcb_write8            read_and_branch;            // speech ROM read and branch callback
132
133};
134
135// Change back from 5220n to 5220 when all client drivers will be converted
136class tms52xx_device : public device_t, public device_sound_interface
137{
138public:
139   tms52xx_device(const machine_config &mconfig, device_type type,  const char *name, const char *tag, const struct tms5100_coeffs* coeffs, const int var, device_t *owner, UINT32 clock);
140   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
141   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
142
143   DECLARE_WRITE_LINE_MEMBER( rsq_w );
144   DECLARE_WRITE_LINE_MEMBER( wsq_w );
145   DECLARE_WRITE8_MEMBER( write );
146   DECLARE_READ8_MEMBER( read );
147   DECLARE_READ_LINE_MEMBER( readyq );
148   DECLARE_READ_LINE_MEMBER( intq );
149
150   double time_to_ready();
151
152protected:
153   virtual void device_start();
154   virtual void device_reset();
155
15673private:
157   // Methods
158   void set_interrupt_state(int state);
15974   void register_for_save_states();
160   void update_ready_state();
161   void set_frequency(int frequency);
162   void process(INT16 *buffer, unsigned int size);
16375   void data_write(int data);
16476   void update_status_and_ints();
165   void parse_frame();
166
16777   int extract_bits(int count);
16878   int status_read();
79   int ready_read();
16980   int cycles_to_ready();
81   int int_read();
82   void process(INT16 *buffer, unsigned int size);
17083   INT32 lattice_filter();
17184   void process_command(unsigned char cmd);
85   void parse_frame();
86   void set_interrupt_state(int state);
87   void update_ready_state();
17288
173   inline bool ready_read();
174   inline int int_read();
89   // internal state
17590
176   // coefficient tables
177   const int m_variant;                // Variant of the 5xxx - see tms5110r.h
91   /* coefficient tables */
92   int m_variant;                /* Variant of the 5xxx - see tms5110r.h */
17893
179   // coefficient tables
94   /* coefficient tables */
18095   const struct tms5100_coeffs *m_coeff;
18196
182   // callbacks
183   devcb_resolved_write_line   m_irq_func;
184   devcb_resolved_write_line   m_readyq_func;
185   devcb_resolved_read8        m_read_mem;
186   devcb_resolved_write8       m_load_address;
187   devcb_resolved_write8       m_read_and_branch;
97   /* these contain data that describes the 128-bit data FIFO */
98   UINT8 m_fifo[FIFO_SIZE];
99   UINT8 m_fifo_head;
100   UINT8 m_fifo_tail;
101   UINT8 m_fifo_count;
102   UINT8 m_fifo_bits_taken;
188103
189   // these contain data that describes the 128-bit data FIFO
190   UINT8   m_fifo[FIFO_SIZE];
191   UINT8   m_fifo_head;
192   UINT8   m_fifo_tail;
193   int     m_fifo_count;
194   int     m_fifo_bits_taken;
195104
196   // these contain global status bits
197   bool    m_speaking_now;     // True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.
198   bool    m_speak_external;   // If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO.
199   bool    m_talk_status;      // If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts.
200   bool    m_buffer_low;       // If 1, FIFO has less than 8 bytes in it
201   bool    m_buffer_empty;     // If 1, FIFO is empty
202   int     m_irq_pin;          // state of the IRQ pin (output)
203   int     m_ready_pin;        // state of the READY pin (output)
105   /* these contain global status bits */
106   UINT8 m_speaking_now;     /* True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.*/
107   UINT8 m_speak_external;   /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
108   UINT8 m_talk_status;      /* If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts. */
109   UINT8 m_buffer_low;       /* If 1, FIFO has less than 8 bytes in it */
110   UINT8 m_buffer_empty;     /* If 1, FIFO is empty */
111   UINT8 m_irq_pin;          /* state of the IRQ pin (output) */
112   UINT8 m_ready_pin;        /* state of the READY pin (output) */
204113
205   // these contain data describing the current and previous voice frames
206#define M_OLD_FRAME_SILENCE_FLAG m_OLDE // 1 if E=0, 0 otherwise.
207#define M_OLD_FRAME_UNVOICED_FLAG m_OLDP // 1 if P=0 (unvoiced), 0 if voiced
208   bool    m_OLDE;
209   bool    m_OLDP;
114   /* these contain data describing the current and previous voice frames */
115#define OLD_FRAME_SILENCE_FLAG m_OLDE // 1 if E=0, 0 otherwise.
116#define OLD_FRAME_UNVOICED_FLAG m_OLDP // 1 if P=0 (unvoiced), 0 if voiced
117   UINT8 m_OLDE;
118   UINT8 m_OLDP;
210119
211#define M_NEW_FRAME_STOP_FLAG (m_new_frame_energy_idx == 0xF)       // 1 if this is a stop (Energy = 0xF) frame
212#define M_NEW_FRAME_SILENCE_FLAG (m_new_frame_energy_idx == 0)  // ditto as above
213#define M_NEW_FRAME_UNVOICED_FLAG (m_new_frame_pitch_idx == 0)  // ditto as above
214   int     m_new_frame_energy_idx;
215   int     m_new_frame_pitch_idx;
216   int     m_new_frame_k_idx[10];
120#define NEW_FRAME_STOP_FLAG (m_new_frame_energy_idx == 0xF) // 1 if this is a stop (Energy = 0xF) frame
121#define NEW_FRAME_SILENCE_FLAG (m_new_frame_energy_idx == 0) // ditto as above
122#define NEW_FRAME_UNVOICED_FLAG (m_new_frame_pitch_idx == 0) // ditto as above
123   UINT8 m_new_frame_energy_idx;
124   UINT8 m_new_frame_pitch_idx;
125   UINT8 m_new_frame_k_idx[10];
217126
218   // these are all used to contain the current state of the sound generation
127
128   /* these are all used to contain the current state of the sound generation */
219129#ifndef PERFECT_INTERPOLATION_HACK
220   INT16   m_current_energy;
221   INT16   m_current_pitch;
222   INT16   m_current_k[10];
130   INT16 m_current_energy;
131   INT16 m_current_pitch;
132   INT16 m_current_k[10];
223133
224   INT16   m_target_energy;
225   INT16   m_target_pitch;
226   INT16   m_target_k[10];
134   INT16 m_target_energy;
135   INT16 m_target_pitch;
136   INT16 m_target_k[10];
227137#else
228   int     m_old_frame_energy_idx;
229   int     m_old_frame_pitch_idx;
230   int     m_old_frame_k_idx[10];
138   UINT8 m_old_frame_energy_idx;
139   UINT8 m_old_frame_pitch_idx;
140   UINT8 m_old_frame_k_idx[10];
231141
232   INT32   m_current_energy;
233   INT32   m_current_pitch;
234   INT32   m_current_k[10];
142   INT32 m_current_energy;
143   INT32 m_current_pitch;
144   INT32 m_current_k[10];
235145
236   INT32   m_target_energy;
237   INT32   m_target_pitch;
238   INT32   m_target_k[10];
146   INT32 m_target_energy;
147   INT32 m_target_pitch;
148   INT32 m_target_k[10];
239149#endif
240150
241   UINT16  m_previous_energy;  // needed for lattice filter to match patent
242   int     m_subcycle;         // contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B
243   int     m_subc_reload;      // contains 1 for normal speech, 0 when SPKSLOW is active
244   int     m_PC;               // current parameter counter (what param is being interpolated), ranges from 0 to 12
151   UINT16 m_previous_energy; /* needed for lattice filter to match patent */
245152
246   // TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1
247   int     m_IP;    // the current interpolation period
248   bool    m_inhibit;          // If 1, interpolation is inhibited until the DIV1 period
249   UINT8   m_tms5220c_rate;    // only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command
250   UINT16  m_pitch_count;      // pitch counter; provides chirp rom address
153   UINT8 m_subcycle;         /* contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B */
154   UINT8 m_subc_reload;      /* contains 1 for normal speech, 0 when SPKSLOW is active */
155   UINT8 m_PC;               /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
156   /* TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
157   UINT8 m_IP;               /* the current interpolation period */
158   UINT8 m_inhibit;          /* If 1, interpolation is inhibited until the DIV1 period */
159   UINT8 m_tms5220c_rate;    /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
160   UINT16 m_pitch_count;     /* pitch counter; provides chirp rom address */
251161
252   INT32   m_u[11];
253   INT32   m_x[10];
162   INT32 m_u[11];
163   INT32 m_x[10];
254164
255   UINT16  m_RNG;      // the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13
256   INT16   m_excitation_data;
165   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
166   INT16 m_excitation_data;
257167
258   // R Nabet : These have been added to emulate speech Roms
259   bool    m_schedule_dummy_read;  // set after each load address, so that next read operation is preceded by a dummy read
260   UINT8   m_data_register;        // data register, used by read command
261   bool    m_RDB_flag;             // whether we should read data register or status register
168   /* R Nabet : These have been added to emulate speech Roms */
169   UINT8 m_schedule_dummy_read;          /* set after each load address, so that next read operation is preceded by a dummy read */
170   UINT8 m_data_register;                /* data register, used by read command */
171   UINT8 m_RDB_flag;                 /* whether we should read data register or status register */
262172
263   // io_ready: page 3 of the datasheet specifies that READY will be asserted until
264   // data is available or processed by the system.
265   int     m_io_ready;
173   /* io_ready: page 3 of the datasheet specifies that READY will be asserted until
174    * data is available or processed by the system.
175    */
176   UINT8 m_io_ready;
266177
267   // flag for "true" timing involving rs/ws
268   bool    m_true_timing;
178   /* flag for "true" timing involving rs/ws */
179   UINT8 m_true_timing;
269180
270   // rsws - state, rs bit 1, ws bit 0
271   int     m_rs_ws;
272   UINT8   m_read_latch;
273   UINT8   m_write_latch;
181   /* rsws - state, rs bit 1, ws bit 0 */
182   UINT8 m_rs_ws;
183   UINT8 m_read_latch;
184   UINT8 m_write_latch;
274185
275   // The TMS52xx has two different ways of providing output data: the
276   // analog speaker pin (which was usually used) and the Digital I/O pin.
277   // The internal DAC used to feed the analog pin is only 8 bits, and has the
278   // funny clipping/clamping logic, while the digital pin gives full 12? bit
279   // resolution of the output data.
280   // TODO: add a way to set/reset this other than the FORCE_DIGITAL define
281   bool            m_digital_select;
186   /* The TMS52xx has two different ways of providing output data: the
187      analog speaker pin (which was usually used) and the Digital I/O pin.
188      The internal DAC used to feed the analog pin is only 8 bits, and has the
189      funny clipping/clamping logic, while the digital pin gives full 10 bit
190      resolution of the output data.
191      TODO: add a way to set/reset this other than the FORCE_DIGITAL define
192    */
193   UINT8 m_digital_select;
282194
283   sound_stream    *m_stream;
195   sound_stream *m_stream;
196   int m_clock;
197   emu_timer *m_timer_io_ready;
284198
285   emu_timer       *m_ready_timer;
199   /* callbacks */
200   devcb2_write_line m_irq_handler;
201   devcb2_write_line m_readyq_handler;
202   const char *m_speechrom_tag;
203   speechrom_device *m_speechrom;
286204};
287205
288class tms5220n_device : public tms52xx_device
289{
290public:
291   tms5220n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
292};
206extern const device_type TMS5220;
293207
294class tms5220cn_device : public tms52xx_device
208class tms5220c_device : public tms5220_device
295209{
296210public:
297   tms5220cn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
211   tms5220c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
212protected:
213   // device-level overrides
214   virtual void device_start();
298215};
299216
300class tmc0285n_device : public tms52xx_device
217extern const device_type TMS5220C;
218
219class tmc0285_device : public tms5220_device
301220{
302221public:
303   tmc0285n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
222   tmc0285_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
223protected:
224   // device-level overrides
225   virtual void device_start();
304226};
305227
306class tms5200n_device : public tms52xx_device
228extern const device_type TMC0285;
229
230class tms5200_device : public tms5220_device
307231{
308232public:
309   tms5200n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
233   tms5200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
234protected:
235   // device-level overrides
236   virtual void device_start();
310237};
311238
239extern const device_type TMS5200;
312240
313#endif /* __TMS5220_H__ */
241#endif
trunk/src/mess/drivers/exelv.c
r22818r22819
5454#include "cpu/tms7000/tms7000.h"
5555#include "video/tms3556.h"
5656#include "sound/tms5220.h"
57#include "audio/spchroms.h"
57#include "machine/spchrom.h"
5858//#include "imagedev/cartslot.h"
5959//#include "imagedev/cassette.h"
6060
r22818r22819
7474   required_device<tms5220c_device> m_tms5220c;
7575
7676   virtual void machine_start();
77   virtual void machine_reset();
7877
7978   DECLARE_READ8_MEMBER( mailbox_wx319_r );
8079   DECLARE_WRITE8_MEMBER( mailbox_wx318_w );
r22818r22819
281280   logerror("tms7041_porta_r\n");
282281
283282   data |= (m_tms7020_portb & 0x01 ) ? 0x04 : 0x00;
284   data |= tms5220_intq_r(m_tms5220c) ? 0x08 : 0x00;
283   data |= m_tms5220c->intq_r() ? 0x08 : 0x00;
285284   data |= (m_tms7020_portb & 0x02) ? 0x10 : 0x00;
286   data |= tms5220_readyq_r(m_tms5220c) ? 0x80 : 0x00;
285   data |= m_tms5220c->readyq_r() ? 0x80 : 0x00;
287286
288287   return data;
289288}
r22818r22819
319318{
320319   logerror("tms7041_portb_w: data = 0x%02x\n", data);
321320
322   tms5220_wsq_w(m_tms5220c, (data & 0x01) ? 1 : 0);
323   tms5220_rsq_w(m_tms5220c, (data & 0x02) ? 1 : 0);
321   m_tms5220c->wsq_w((data & 0x01) ? 1 : 0);
322   m_tms5220c->rsq_w((data & 0x02) ? 1 : 0);
324323
325324   m_maincpu->set_input_line(TMS7000_IRQ1_LINE, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE);
326325
r22818r22819
381380{
382381   logerror("tms7041_portd_w: data = 0x%02x\n", data);
383382
384   tms5220_data_w(m_tms5220c, space, 0, BITSWAP8(data,0,1,2,3,4,5,6,7));
383   m_tms5220c->data_w(space, 0, BITSWAP8(data,0,1,2,3,4,5,6,7));
385384   m_tms7041_portd = data;
386385}
387386
r22818r22819
475474INPUT_PORTS_END
476475
477476
478static const tms5220_interface exl100_tms5220_interface =
479{
480   DEVCB_NULL,                     /* no IRQ callback */
481   DEVCB_NULL,                     /* no Ready callback */
482   spchroms_read,                  /* speech ROM read handler */
483   spchroms_load_address,          /* speech ROM load address handler */
484   spchroms_read_and_branch        /* speech ROM read and branch handler */
485};
486
487
488477void exelv_state::palette_init()
489478{
490479   int i, red, green, blue;
r22818r22819
519508   save_item(NAME(m_wx319));
520509}
521510
522void exelv_state::machine_reset()
523{
524   static const spchroms_interface exelv_speech_intf = {"tms5220c"};
525   spchroms_config(machine(), &exelv_speech_intf);
526}
527
528511static MACHINE_CONFIG_START( exl100, exelv_state )
529512   /* basic machine hardware */
530513   MCFG_CPU_ADD("maincpu", TMS7000_EXL, XTAL_4_9152MHz)    /* TMS7020 */
r22818r22819
557540   MCFG_SCREEN_REFRESH_RATE(50)
558541   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
559542
543   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
544
560545   /* sound */
561546   MCFG_SPEAKER_STANDARD_MONO("mono")
562547   MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000)
563   MCFG_SOUND_CONFIG(exl100_tms5220_interface)
548   MCFG_TMS52XX_SPEECHROM("vsm")
564549   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
565550MACHINE_CONFIG_END
566551
r22818r22819
597582   MCFG_SCREEN_REFRESH_RATE(50)
598583   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
599584
585   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
586
600587   /* sound */
601588   MCFG_SPEAKER_STANDARD_MONO("mono")
602589   MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000)
603   MCFG_SOUND_CONFIG(exl100_tms5220_interface)
590   MCFG_TMS52XX_SPEECHROM("vsm")
604591   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
605592MACHINE_CONFIG_END
606593
r22818r22819
618605   ROM_REGION(0x10000, "user1", ROMREGION_ERASEFF)         /* cartridge area */
619606
620607   /* is this correct for exl100? */
621   ROM_REGION(0x8000, "tms5220c", 0)
608   ROM_REGION(0x8000, "vsm", 0)
622609   ROM_LOAD("cm62312.bin", 0x0000, 0x4000, CRC(93b817de) SHA1(03863087a071b8f22d36a52d18243f1c33e17ff7)) /* system speech ROM */
623610ROM_END
624611
r22818r22819
636623   ROM_SYSTEM_BIOS( 1, "spanish", "Spanish" )
637624   ROMX_LOAD("amper.bin", 0x0000, 0x10000, CRC(45af256c) SHA1(3bff16542f8ac55b9841084ea38034132459facb), ROM_BIOS(2)) /* Spanish system rom */
638625
639   ROM_REGION(0x8000, "tms5220c", 0)
626   ROM_REGION(0x8000, "vsm", 0)
640627   ROM_LOAD("cm62312.bin", 0x0000, 0x4000, CRC(93b817de) SHA1(03863087a071b8f22d36a52d18243f1c33e17ff7)) /* system speech ROM */
641628ROM_END
642629
trunk/src/mess/drivers/mpf1.c
r22818r22819
6464   AM_RANGE(0x00, 0x03) AM_MIRROR(0x3c) AM_DEVREADWRITE(I8255A_TAG, i8255_device, read, write)
6565   AM_RANGE(0x40, 0x43) AM_MIRROR(0x3c) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write)
6666   AM_RANGE(0x80, 0x83) AM_MIRROR(0x3c) AM_DEVREADWRITE(Z80PIO_TAG, z80pio_device, read, write)
67   AM_RANGE(0xfe, 0xfe) AM_MIRROR(0x01) AM_DEVREADWRITE_LEGACY(TMS5220_TAG, tms5220_status_r, tms5220_data_w)
67   AM_RANGE(0xfe, 0xfe) AM_MIRROR(0x01) AM_DEVREADWRITE(TMS5220_TAG, tms5220_device, status_r, data_w)
6868ADDRESS_MAP_END
6969
7070static ADDRESS_MAP_START( mpf1p_io_map, AS_IO, 8, mpf1_state )
r22818r22819
317317   NULL
318318};
319319
320/* TMS5220 Interface */
321
322static const tms5220_interface mpf1_tms5220_intf =
323{
324   DEVCB_NULL,                 /* no IRQ callback */
325   DEVCB_NULL,                 /* no Ready callback */
326#if 1
327   spchroms_read,              /* speech ROM read handler */
328   spchroms_load_address,      /* speech ROM load address handler */
329   spchroms_read_and_branch    /* speech ROM read and branch handler */
330#endif
331};
332
333320/* Machine Initialization */
334321
335322TIMER_DEVICE_CALLBACK_MEMBER(mpf1_state::check_halt_callback)
r22818r22819
404391   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
405392
406393   MCFG_SOUND_ADD(TMS5220_TAG, TMS5220, 680000L)
407   MCFG_SOUND_CONFIG(mpf1_tms5220_intf)
408394   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
409395
410396   MCFG_TIMER_DRIVER_ADD_PERIODIC("halt_timer", mpf1_state, check_halt_callback, attotime::from_hz(1))
trunk/src/mess/drivers/pes.c
r22818r22819
126126#ifdef DEBUG_PORTS
127127   logerror("port0 write: RSWS states updated: /RS: %d, /WS: %d\n", m_rsstate, m_wsstate);
128128#endif
129   tms5220_rsq_w(state->m_speech, m_rsstate);
130   tms5220_wsq_w(state->m_speech, m_wsstate);
129   state->m_speech->rsq_w(m_rsstate);
130   state->m_speech->wsq_w(m_wsstate);
131131}
132132
133133WRITE8_MEMBER( pes_state::port1_w )
r22818r22819
136136#ifdef DEBUG_PORTS
137137   logerror("port1 write: tms5220 data written: %02X\n", data);
138138#endif
139   tms5220_data_w(state->m_speech, space, 0, data);
139   state->m_speech->data_w(space, 0, data);
140140
141141}
142142
r22818r22819
144144{
145145   UINT8 data = 0xFF;
146146   pes_state *state = machine().driver_data<pes_state>();
147   data = tms5220_status_r(state->m_speech, space, 0);
147   data = state->m_speech->status_r(space, 0);
148148#ifdef DEBUG_PORTS
149149   logerror("port1 read: tms5220 data read: 0x%02X\n", data);
150150#endif
r22818r22819
186186   {
187187      data |= 0x10; // set RTS bit
188188   }
189   data |= (tms5220_intq_r(state->m_speech)<<2);
190   data |= (tms5220_readyq_r(state->m_speech)<<3);
189   data |= (state->m_speech->intq_r()<<2);
190   data |= (state->m_speech->readyq_r()<<3);
191191#ifdef DEBUG_PORTS
192192   logerror("port3 read: returning 0x%02X: ", data);
193193   logerror("RXD: %d; ", BIT(data,0));
trunk/src/mess/mess.mak
r22818r22819
509509
510510$(MESSOBJ)/shared.a: \
511511   $(MESS_AUDIO)/mea8000.o     \
512   $(MESS_AUDIO)/spchroms.o    \
513512   $(MESS_MACHINE)/3c503.o     \
514513   $(MESS_MACHINE)/68561mpcc.o \
515514   $(MESS_MACHINE)/8530scc.o   \
trunk/src/mess/audio/spchroms.c
r22818r22819
1/*
2    spchroms.c - This is an emulator for "typical" speech ROMs from TI, as used by TI99/4(a).
3
4    In order to support its speech processor, TI designed some ROMs with a 1-bit data bus
5    and 4-bit address bus (multiplexed 5 times to provide a 18-bit address).
6    A fairly complete description of such a ROM (tms6100) is found in the tms5220 datasheet.
7
8    One notable thing is that the address is a byte address (*NOT* a bit address).
9
10    This file is designed to be interfaced with the tms5220 core.
11    Interfacing it with the tms5110 would make sense, too.
12*/
13
14#include "emu.h"
15#include "spchroms.h"
16
17static UINT8 *speechrom_data = NULL;    /* pointer to speech ROM data */
18static unsigned long speechROMlen = 0;  /* length of data pointed by speechrom_data, from 0 to 2^18 */
19static unsigned long speechROMaddr;     /* 18 bit pointer in ROM */
20#define TMS5220_ADDRESS_MASK 0x3FFFFUL  /* 18-bit mask for tms5220 address */
21static int load_pointer = 0;            /* which 4-bit nibble will be affected by load address */
22static int ROM_bits_count;              /* current bit position in ROM */
23
24/*
25    set the speech ROMs
26*/
27void spchroms_config(running_machine &machine, const spchroms_interface *intf)
28{
29   if (intf->memory_region == NULL)
30   {   /* no speech ROM */
31      speechrom_data = NULL;
32      speechROMlen = 0;
33   }
34   else
35   {   /* speech ROM */
36      speechrom_data = machine.root_device().memregion(intf->memory_region)->base();
37      /* take region length */
38      speechROMlen = machine.root_device().memregion(intf->memory_region)->bytes();
39   }
40}
41
42/*
43    Read 'count' bits serially from speech ROM
44*/
45int spchroms_read(device_t *device, int count)
46{
47   int val;
48
49   if (load_pointer)
50   {   /* first read after load address is ignored */
51      load_pointer = 0;
52      count--;
53   }
54
55   if (speechROMaddr < speechROMlen)
56      if (count < ROM_bits_count)
57      {
58         ROM_bits_count -= count;
59         val = (speechrom_data[speechROMaddr] >> ROM_bits_count) & (0xFF >> (8 - count));
60      }
61      else
62      {
63         val = ((int) speechrom_data[speechROMaddr]) << 8;
64
65         speechROMaddr = (speechROMaddr + 1) & TMS5220_ADDRESS_MASK;
66
67         if (speechROMaddr < speechROMlen)
68            val |= speechrom_data[speechROMaddr];
69
70         ROM_bits_count += 8 - count;
71
72         val = (val >> ROM_bits_count) & (0xFF >> (8 - count));
73      }
74   else
75      val = 0;
76
77   return val;
78}
79
80/*
81    Write an address nibble to speech ROM
82*/
83void spchroms_load_address(device_t *device, int data)
84{
85   /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
86     This code does not care about this. */
87   speechROMaddr = ( (speechROMaddr & ~(0xf << load_pointer))
88      | (((unsigned long) (data & 0xf)) << load_pointer) ) & TMS5220_ADDRESS_MASK;
89   load_pointer += 4;
90   ROM_bits_count = 8;
91}
92
93/*
94    Perform a read and branch command
95*/
96void spchroms_read_and_branch(device_t *device)
97{
98   /* tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
99     there is a bus contention.  This code does not care about this. */
100   if (speechROMaddr < speechROMlen-1)
101      speechROMaddr = (speechROMaddr & 0x3c000UL)
102         | (((((unsigned long) speechrom_data[speechROMaddr]) << 8)
103         | speechrom_data[speechROMaddr+1]) & 0x3fffUL);
104   else if (speechROMaddr == speechROMlen-1)
105      speechROMaddr = (speechROMaddr & 0x3c000UL)
106         | ((((unsigned long) speechrom_data[speechROMaddr]) << 8) & 0x3fffUL);
107   else
108      speechROMaddr = (speechROMaddr & 0x3c000UL);
109
110   ROM_bits_count = 8;
111}
trunk/src/mess/audio/spchroms.h
r22818r22819
1#ifndef __SPCHROMS_H
2#define __SPCHROMS_H
3
4struct spchroms_interface
5{
6   const char *memory_region;          /* memory region where the speech ROM is.  NULL means no speech ROM */
7};
8
9void spchroms_config(running_machine &machine, const spchroms_interface *intf);
10
11int spchroms_read(device_t *device, int count);
12void spchroms_load_address(device_t *device, int data);
13void spchroms_read_and_branch(device_t *device);
14
15#endif
trunk/src/mess/machine/a2mockingboard.c
r22818r22819
545545   switch (offset)
546546   {
547547      case 0:
548         return 0x1f | tms5220_status_r(m_tms, space, 0);
548         return 0x1f | m_tms->status_r(space, 0);
549549   }
550550
551551   return 0;
r22818r22819
556556   switch (offset)
557557   {
558558      case 0:
559         tms5220_data_w(m_tms, space, offset, data);
559         m_tms->data_w(space, offset, data);
560560         break;
561561   }
562562}
trunk/src/mess/machine/a2echoii.c
r22818r22819
7979   switch (offset)
8080   {
8181      case 0:
82         return 0x1f | tms5220_status_r(m_tms, space, 0);
82         return 0x1f | m_tms->status_r(space, 0);
8383   }
8484
8585   return 0;
r22818r22819
9090   switch (offset)
9191   {
9292      case 0:
93         tms5220_data_w(m_tms, space, offset, data);
93         m_tms->data_w(space, offset, data);
9494         break;
9595   }
9696}
trunk/src/mess/machine/ti99/spchsyn.c
r22818r22819
2020
2121#include "spchsyn.h"
2222#include "sound/wave.h"
23#include "machine/spchrom.h"
2324
2425#define TMS5220_ADDRESS_MASK 0x3FFFFUL  /* 18-bit mask for tms5220 address */
2526
2627#define VERBOSE 1
2728#define LOG logerror
2829
29#define SPEECHROM_TAG "speechrom"
30
3130#define REAL_TIMING 0
3231
3332/****************************************************************************/
r22818r22819
108107   if ((offset & m_select_mask)==m_select_value)
109108   {
110109      machine().device("maincpu")->execute().adjust_icount(-(18+3));      /* this is just a minimum, it can be more */
111      *value = m_vsp->read(space, offset, 0xff) & 0xff;
110      *value = m_vsp->status_r(space, offset, 0xff) & 0xff;
112111      if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
113112   }
114113}
r22818r22819
126125      /* when there are 15 bytes in FIFO.  It should be 16.  Of course, if */
127126      /* it were the case, we would need to store the value on the bus, */
128127      /* which would be more complex. */
129      if (!m_vsp->readyq())
128      if (!m_vsp->readyq_r())
130129      {
131130         attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready());
132131         int cycles_to_ready = machine().device<cpu_device>("maincpu")->attotime_to_cycles(time_to_ready);
r22818r22819
136135         machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
137136      }
138137      if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
139      m_vsp->write(space, offset, data);
138      m_vsp->data_w(space, offset, data);
140139   }
141140}
142141#endif
143142
144/****************************************************************************
145    Callbacks from TMS5220
146*****************************************************************************/
147/*
148    Read 'count' bits serially from speech ROM. The offset is used as the count.
149*/
150READ8_MEMBER( ti_speech_synthesizer_device::spchrom_read )
151{
152   int val;
153   int count = offset;
154
155   if (m_load_pointer != 0)
156   {   // first read after load address is ignored
157      m_load_pointer = 0;
158      count--;
159   }
160
161   if (m_sprom_address < m_sprom_length)
162   {
163      if (count < m_rombits_count)
164      {
165         m_rombits_count -= count;
166         val = (m_speechrom[m_sprom_address] >> m_rombits_count) & (0xFF >> (8 - count));
167      }
168      else
169      {
170         val = ((int)m_speechrom[m_sprom_address]) << 8;
171
172         m_sprom_address = (m_sprom_address + 1) & TMS5220_ADDRESS_MASK;
173
174         if (m_sprom_address < m_sprom_length)
175            val |= m_speechrom[m_sprom_address];
176
177         m_rombits_count += 8 - count;
178
179         val = (val >> m_rombits_count) & (0xFF >> (8 - count));
180      }
181   }
182   else
183      val = 0;
184
185   return val;
186}
187
188/*
189    Write an address nibble to speech ROM. The address nibble is in the data,
190    the offset is ignored.
191*/
192WRITE8_MEMBER( ti_speech_synthesizer_device::spchrom_load_address )
193{
194   // tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
195   // This code does not care about this.
196   m_sprom_address = ((m_sprom_address & ~(0xf << m_load_pointer))
197      | (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
198   m_load_pointer += 4;
199   m_rombits_count = 8;
200}
201
202/*
203    Perform a read and branch command. We do not use the offset or data parameter.
204*/
205WRITE8_MEMBER( ti_speech_synthesizer_device::spchrom_read_and_branch )
206{
207   // tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
208   // there is a bus contention.  This code does not care about this. */
209   if (m_sprom_address < m_sprom_length-1)
210      m_sprom_address = (m_sprom_address & 0x3c000UL)
211         | (((((unsigned long) m_speechrom[m_sprom_address]) << 8)
212         | m_speechrom[m_sprom_address+1]) & 0x3fffUL);
213   else if (m_sprom_address == m_sprom_length-1)
214      m_sprom_address = (m_sprom_address & 0x3c000UL)
215         | ((((unsigned long) m_speechrom[m_sprom_address]) << 8) & 0x3fffUL);
216   else
217      m_sprom_address = (m_sprom_address & 0x3c000UL);
218
219   m_rombits_count = 8;
220}
221
222143/****************************************************************************/
223144
224/*
225    Callback interface instance
226*/
227static const tms52xx_config ti99_4x_tms5200interface =
228{
229   DEVCB_NULL,                     // no IRQ callback
230   DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, speech_ready),
231
232   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_read),             // speech ROM read handler
233   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_load_address),     // speech ROM load address handler
234   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_read_and_branch)   // speech ROM read and branch handler
235};
236
237/****************************************************************************/
238
239145WRITE_LINE_MEMBER( ti_speech_synthesizer_device::speech_ready )
240146{
241147   // The TMS5200 implementation uses TRUE/FALSE, not ASSERT/CLEAR semantics
r22818r22819
260166
261167void ti_speech_synthesizer_device::device_config_complete()
262168{
263   m_vsp = subdevice<tmc0285n_device>("speechsyn");
169   m_vsp = subdevice<tmc0285_device>("speechsyn");
264170}
265171
266172void ti_speech_synthesizer_device::device_reset()
267173{
268   m_speechrom = memregion(SPEECHROM_TAG)->base();
269   m_sprom_length = memregion(SPEECHROM_TAG)->bytes();
270   m_sprom_address = 0;
271   m_load_pointer = 0;
272   m_rombits_count = 0;
273
274174   if (m_genmod)
275175   {
276176      m_select_mask = 0x1ffc01;
r22818r22819
284184}
285185
286186MACHINE_CONFIG_FRAGMENT( ti99_speech )
187   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
188
287189   MCFG_SPEAKER_STANDARD_MONO("mono")
288   MCFG_SOUND_ADD("speechsyn", TMC0285N, 640000L)
289   MCFG_SOUND_CONFIG(ti99_4x_tms5200interface)
190   MCFG_SOUND_ADD("speechsyn", TMC0285, 640000L)
191   MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, speech_ready))
192   MCFG_TMS52XX_SPEECHROM("vsm")
290193   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
291194MACHINE_CONFIG_END
292195
293196ROM_START( ti99_speech )
294   ROM_REGION(0x8000, SPEECHROM_TAG, 0)
197   ROM_REGION(0x8000, "vsm", 0)
295198   ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
296199ROM_END
297200
trunk/src/mess/machine/ti99/spchsyn.h
r22818r22819
4141   virtual void            device_config_complete();
4242
4343private:
44   tmc0285n_device *m_vsp;
45
46   UINT8           *m_speechrom;           // pointer to speech ROM data
47   int             m_load_pointer;         // which 4-bit nibble will be affected by load address
48   int             m_rombits_count;        // current bit position in ROM
49   UINT32          m_sprom_address;        // 18 bit pointer in ROM
50   UINT32          m_sprom_length;         // length of data pointed by speechrom_data, from 0 to 2^18
44   tmc0285_device *m_vsp;
5145};
5246
5347#endif
trunk/src/mess/machine/ti99/speech8.c
r22818r22819
1313
1414#include "speech8.h"
1515#include "sound/wave.h"
16#include "machine/spchrom.h"
1617
1718#define TMS5220_ADDRESS_MASK 0x3FFFFUL  /* 18-bit mask for tms5220 address */
1819
r22818r22819
2021#define LOG logerror
2122
2223#define SPEECHSYN_TAG "speechsyn"
23#define SPEECHROM_TAG "speechrom"
2424
2525#define REAL_TIMING 0
2626
r22818r22819
3131
3232ti998_spsyn_device::ti998_spsyn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
3333: bus8z_device(mconfig, TI99_SPEECH8, "TI-99/8 Speech synthesizer (onboard)", tag, owner, clock, "ti99_speech8", __FILE__)
34, m_load_pointer(0)
3534{
3635}
3736
r22818r22819
7372   if ((offset & m_select_mask)==m_select_value)
7473   {
7574      machine().device("maincpu")->execute().adjust_icount(-(18+3));      /* this is just a minimum, it can be more */
76      *value = m_vsp->read(space, offset, 0xff) & 0xff;
75      *value = m_vsp->status_r(space, offset, 0xff) & 0xff;
7776      if (VERBOSE>4) LOG("speech8: read value = %02x\n", *value);
7877   }
7978}
r22818r22819
9190      /* when there are 15 bytes in FIFO.  It should be 16.  Of course, if */
9291      /* it were the case, we would need to store the value on the bus, */
9392      /* which would be more complex. */
94      if (!m_vsp->readyq())
93      if (!m_vsp->readyq_r())
9594      {
9695         attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready());
9796         int cycles_to_ready = machine().device<cpu_device>("maincpu")->attotime_to_cycles(time_to_ready);
r22818r22819
101100         machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
102101      }
103102      if (VERBOSE>4) LOG("speech8: write value = %02x\n", data);
104      m_vsp->write(space, offset, data);
103      m_vsp->data_w(space, offset, data);
105104   }
106105}
107106#endif
108107
109/****************************************************************************
110    Callbacks from TMS5220
111*****************************************************************************/
112/*
113    Read 'count' bits serially from speech ROM
114*/
115READ8_MEMBER( ti998_spsyn_device::spchrom_read )
116{
117   int val;
118   int count = offset;
119
120   if (m_load_pointer != 0)
121   {   // first read after load address is ignored
122      m_load_pointer = 0;
123      count--;
124   }
125
126   if (m_sprom_address < m_sprom_length)
127   {
128      if (count < m_rombits_count)
129      {
130         m_rombits_count -= count;
131         val = (m_speechrom[m_sprom_address] >> m_rombits_count) & (0xFF >> (8 - count));
132      }
133      else
134      {
135         val = ((int)m_speechrom[m_sprom_address]) << 8;
136
137         m_sprom_address = (m_sprom_address + 1) & TMS5220_ADDRESS_MASK;
138
139         if (m_sprom_address < m_sprom_length)
140            val |= m_speechrom[m_sprom_address];
141
142         m_rombits_count += 8 - count;
143
144         val = (val >> m_rombits_count) & (0xFF >> (8 - count));
145      }
146   }
147   else
148      val = 0;
149
150   return val;
151}
152
153/*
154    Write an address nibble to speech ROM
155*/
156WRITE8_MEMBER( ti998_spsyn_device::spchrom_load_address )
157{
158   // tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
159   // This code does not care about this.
160   m_sprom_address = ((m_sprom_address & ~(0xf << m_load_pointer))
161      | (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
162   m_load_pointer += 4;
163   m_rombits_count = 8;
164}
165
166/*
167    Perform a read and branch command
168*/
169WRITE8_MEMBER( ti998_spsyn_device::spchrom_read_and_branch )
170{
171   // tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
172   // there is a bus contention.  This code does not care about this. */
173   if (m_sprom_address < m_sprom_length-1)
174      m_sprom_address = (m_sprom_address & 0x3c000UL)
175         | (((((unsigned long) m_speechrom[m_sprom_address]) << 8)
176         | m_speechrom[m_sprom_address+1]) & 0x3fffUL);
177   else if (m_sprom_address == m_sprom_length-1)
178      m_sprom_address = (m_sprom_address & 0x3c000UL)
179         | ((((unsigned long) m_speechrom[m_sprom_address]) << 8) & 0x3fffUL);
180   else
181      m_sprom_address = (m_sprom_address & 0x3c000UL);
182
183   m_rombits_count = 8;
184}
185
186/*****************************************************************************/
187/*
188    Callback interface instance
189*/
190static const tms52xx_config ti99_8_tms5200interface =
191{
192   DEVCB_NULL,                     // no IRQ callback
193   DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, speech8_ready),
194
195   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_read),               // speech ROM read handler
196   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_load_address),       // speech ROM load address handler
197   DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_read_and_branch) // speech ROM read and branch handler
198};
199
200108/**************************************************************************/
201109
202110WRITE_LINE_MEMBER( ti998_spsyn_device::speech8_ready )
r22818r22819
219127{
220128   const speech8_config *conf = reinterpret_cast<const speech8_config *>(static_config());
221129   m_ready.resolve(conf->ready, *this);
222   m_vsp = subdevice<tms5220n_device>(SPEECHSYN_TAG);
130   m_vsp = subdevice<tms5220_device>(SPEECHSYN_TAG);
223131}
224132
225133void ti998_spsyn_device::device_reset()
226134{
227   m_speechrom = memregion(SPEECHROM_TAG)->base();
228   m_sprom_length = memregion(SPEECHROM_TAG)->bytes();
229   m_sprom_address = 0;
230   m_load_pointer = 0;
231   m_rombits_count = 0;
232
233135   m_select_mask = 0xfc01;
234136   m_select_value = 0x9000;
235137   if (VERBOSE>4) LOG("speech8: reset\n");
r22818r22819
237139
238140// Unlike the TI-99/4A, the 99/8 uses the TMS5220
239141MACHINE_CONFIG_FRAGMENT( ti998_speech )
142   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
143
240144   MCFG_SPEAKER_STANDARD_MONO("mono")
241   MCFG_SOUND_ADD(SPEECHSYN_TAG, TMS5220N, 640000L)
242   MCFG_SOUND_CONFIG(ti99_8_tms5200interface)
145   MCFG_SOUND_ADD(SPEECHSYN_TAG, TMS5220, 640000L)
146   MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, ti998_spsyn_device, speech8_ready))
147   MCFG_TMS52XX_SPEECHROM("vsm")
243148   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
244149MACHINE_CONFIG_END
245150
246151ROM_START( ti998_speech )
247   ROM_REGION(0x8000, SPEECHROM_TAG, 0)
152   ROM_REGION(0x8000, "vsm", 0)
248153   ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, BAD_DUMP CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
249154ROM_END
250155
trunk/src/mess/machine/ti99/speech8.h
r22818r22819
5353   virtual machine_config_constructor device_mconfig_additions() const;
5454
5555private:
56   tms5220n_device *m_vsp;
57   UINT8           *m_speechrom;           // pointer to speech ROM data
58   int             m_load_pointer;         // which 4-bit nibble will be affected by load address
59   int             m_rombits_count;        // current bit position in ROM
60   UINT32          m_sprom_address;        // 18 bit pointer in ROM
61   UINT32          m_sprom_length;         // length of data pointed by speechrom_data, from 0 to 2^18
56   tms5220_device  *m_vsp;
57//   UINT8           *m_speechrom;           // pointer to speech ROM data
58//   int             m_load_pointer;         // which 4-bit nibble will be affected by load address
59//   int             m_rombits_count;        // current bit position in ROM
60//   UINT32          m_sprom_address;        // 18 bit pointer in ROM
61//   UINT32          m_sprom_length;         // length of data pointed by speechrom_data, from 0 to 2^18
6262
6363   // Ready line to the CPU
6464   devcb_resolved_write_line m_ready;
trunk/src/mess/machine/rmnimbus.c
r22818r22819
27072707   //device_t *ay8910 = machine().device(AY8910_TAG);
27082708   device_t *msm5205 = machine().device(MSM5205_TAG);
27092709
2710   //ay8910_reset_ym(ay8910);
2710   //ay8910->reset();
27112711   msm5205_reset_w(msm5205, 1);
27122712
27132713   m_last_playmode=MSM5205_S48_4B;
trunk/src/mess/includes/mpf1.h
r22818r22819
55
66
77#include "emu.h"
8#include "audio/spchroms.h"
8#include "machine/spchrom.h"
99#include "cpu/z80/z80.h"
1010#include "cpu/z80/z80daisy.h"
1111#include "imagedev/cassette.h"
trunk/src/mame/machine/mhavoc.c
r22818r22819
203203
204204CUSTOM_INPUT_MEMBER(mhavoc_state::tms5220_r)
205205{
206   return tms5220_readyq_r(machine().device("tms")) ? 1 : 0;
206   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
207   return tms5220->readyq_r() ? 1 : 0;
207208}
208209
209210CUSTOM_INPUT_MEMBER(mhavoc_state::mhavoc_bit67_r)
r22818r22819
308309
309310WRITE8_MEMBER(mhavoc_state::mhavocrv_speech_strobe_w)
310311{
311   device_t *tms = machine().device("tms");
312   tms5220_data_w(tms, space, 0, m_speech_write_buffer);
312   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
313   tms5220->data_w(space, 0, m_speech_write_buffer);
313314}
314315
315316/*************************************
trunk/src/mame/includes/esripsys.h
r22818r22819
1111
1212#include "cpu/esrip/esrip.h"
1313#include "sound/dac.h"
14#include "sound/tms5220.h"
1415
1516/* TODO */
1617#define ESRIPSYS_PIXEL_CLOCK    (XTAL_25MHz / 2)
r22818r22819
4849   required_device<esrip_device> m_videocpu;
4950   required_device<cpu_device> m_gamecpu;
5051   required_device<cpu_device> m_soundcpu;
51   required_device<device_t> m_tms;
52   required_device<tms5220_device> m_tms;
5253
5354   UINT8 m_g_iodata;
5455   UINT8 m_g_ioaddr;
trunk/src/mame/includes/polepos.h
r22818r22819
2323      m_subcpu(*this, "sub"),
2424      m_subcpu2(*this, "sub2") { }
2525
26   optional_device<tms5220n_device> m_tms;
26   optional_device<tms5220_device> m_tms;
2727   UINT8 m_steer_last;
2828   UINT8 m_steer_delta;
2929   INT16 m_steer_accum;
trunk/src/mame/includes/portrait.h
r22818r22819
1111      m_spriteram(*this, "spriteram"),
1212      m_maincpu(*this, "maincpu") { }
1313
14   required_device<tms5200n_device> m_tms;
14   required_device<tms5200_device> m_tms;
1515   required_shared_ptr<UINT8> m_bgvideoram;
1616   required_shared_ptr<UINT8> m_fgvideoram;
1717   int m_scroll;
trunk/src/mame/drivers/portrait.c
r22818r22819
240240   GFXDECODE_ENTRY( "gfx1", 0x00000, tile_layout, 0, 0x800/8 )
241241GFXDECODE_END
242242
243static const tms52xx_config tms_intf =
244{
245   DEVCB_NULL
246};
247243
248
249244static MACHINE_CONFIG_START( portrait, portrait_state )
250245   MCFG_CPU_ADD("maincpu", Z80, 4000000)     /* 4 MHz ? */
251246   MCFG_CPU_PROGRAM_MAP(portrait_map)
r22818r22819
270265
271266   /* sound hardware */
272267   MCFG_SPEAKER_STANDARD_MONO("mono")
273   MCFG_SOUND_ADD("tms", TMS5200N, 640000)
268   MCFG_SOUND_ADD("tms", TMS5200, 640000)
274269   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
275   MCFG_SOUND_CONFIG(tms_intf)
276270MACHINE_CONFIG_END
277271
278272
trunk/src/mame/drivers/tomcat.c
r22818r22819
4646      m_maincpu(*this, "maincpu"),
4747      m_dsp(*this, "dsp") { }
4848
49   required_device<tms5220n_device> m_tms;
49   required_device<tms5220_device> m_tms;
5050   int m_control_num;
5151   required_shared_ptr<UINT16> m_shared_ram;
5252   UINT8 m_nvram[0x800];
r22818r22819
400400   DEVCB_NULL  // connected to IRQ line of 6502
401401};
402402
403static const tms52xx_config tms_intf =
404{
405   DEVCB_NULL
406};
407
408403static MACHINE_CONFIG_START( tomcat, tomcat_state )
409404   MCFG_CPU_ADD("maincpu", M68010, XTAL_12MHz / 2)
410405   MCFG_CPU_PROGRAM_MAP(tomcat_map)
r22818r22819
444439   MCFG_POKEY_ADD("pokey2", XTAL_14_31818MHz / 8)
445440   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.20)
446441
447   MCFG_SOUND_ADD("tms", TMS5220N, 325000)
442   MCFG_SOUND_ADD("tms", TMS5220, 325000)
448443   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50)
449444   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50)
450   MCFG_SOUND_CONFIG(tms_intf)
451445
452446   MCFG_YM2151_ADD("ymsnd", XTAL_14_31818MHz / 4)
453447   MCFG_SOUND_ROUTE(0, "lspeaker", 0.60)
trunk/src/mame/drivers/zaccaria.c
r22818r22819
9696   /* 150 below to scale to volume 100 */
9797   v = (150 * table[ba]) / (4700 + table[ba]);
9898   //printf("dac1w %02d %04d\n", ba, v);
99   ay8910_set_volume(machine().device("ay2"), 1, v);
99   machine().device<ay8910_device>("ay2")->set_volume(1, v);
100100}
101101
102102
r22818r22819
160160
161161WRITE8_MEMBER(zaccaria_state::zaccaria_port1b_w)
162162{
163   device_t *tms = machine().device("tms");
163   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
164164
165165   // bit 0 = /RS
166   tms5220_rsq_w(tms, (data >> 0) & 0x01);
166   tms5220->rsq_w((data >> 0) & 0x01);
167167   // bit 1 = /WS
168   tms5220_wsq_w(tms, (data >> 1) & 0x01);
168   tms5220->wsq_w((data >> 1) & 0x01);
169169
170170   // bit 3 = "ACS" (goes, inverted, to input port 6 bit 3)
171171   m_acs = ~data & 0x08;
r22818r22819
546546
547547static const pia6821_interface pia_1_config =
548548{
549   DEVCB_DEVICE_HANDLER("tms", tms5220_status_r),  /* port A in */
549   DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r),  /* port A in */
550550   DEVCB_NULL,                                     /* port B in */
551551   DEVCB_NULL,                                     /* line CA1 in */
552552   DEVCB_NULL,                                     /* line CB1 in */   // tms5220_intq_r, handled below in tms5220_config
553553   DEVCB_NULL,                                     /* line CA2 in */   // tms5220_readyq_r, "
554554   DEVCB_NULL,                                     /* line CB2 in */
555   DEVCB_DEVICE_HANDLER("tms", tms5220_data_w),    /* port A out */
555   DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w),    /* port A out */
556556   DEVCB_DRIVER_MEMBER(zaccaria_state,zaccaria_port1b_w),              /* port B out */
557557   DEVCB_NULL,                                     /* line CA2 out */
558558   DEVCB_NULL,                                     /* port CB2 out */
r22818r22819
560560   DEVCB_NULL                                      /* IRQB */
561561};
562562
563static const tms5220_interface tms5220_config =
564{
565   DEVCB_DEVICE_LINE_MEMBER("pia1", pia6821_device, cb1_w),    /* IRQ handler */
566   DEVCB_DEVICE_LINE_MEMBER("pia1", pia6821_device, ca2_w)     /* READYQ handler */
567};
568
569563INTERRUPT_GEN_MEMBER(zaccaria_state::vblank_irq)
570564{
571565   if(m_nmi_mask)
r22818r22819
622616   /* There is no xtal, the clock is obtained from a RC oscillator as shown in the TMS5220 datasheet (R=100kOhm C=22pF) */
623617   /* 162kHz measured on pin 3 20 minutesa fter power on. Clock would then be 162*4=648kHz. */
624618   MCFG_SOUND_ADD("tms", TMS5200, 649200) /* ROMCLK pin measured at 162.3Khz, OSC is exactly *4 of that) */
625   MCFG_SOUND_CONFIG(tms5220_config)
619   MCFG_TMS52XX_IRQ_HANDLER(DEVWRITELINE("pia1", pia6821_device, cb1_w))
620   MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE("pia1", pia6821_device, ca2_w))
626621   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
627622MACHINE_CONFIG_END
628623
trunk/src/mame/drivers/atarisy2.c
r22818r22819
350350
351351   if (m_cpu_to_sound_ready) result |= 0x01;
352352   if (m_sound_to_cpu_ready) result |= 0x02;
353   if ((m_has_tms5220) && (tms5220_readyq_r(machine().device("tms")) == 0))
353   if ((m_has_tms5220) && (machine().device<tms5220_device>("tms")->readyq_r() == 0))
354354      result &= ~0x04;
355355   if (!(ioport("1801")->read() & 0x80)) result |= 0x10;
356356
r22818r22819
363363   if (m_has_tms5220)
364364   {
365365      data = 12 | ((data >> 5) & 1);
366      tms5220_set_frequency(machine().device("tms"), MASTER_CLOCK/4 / (16 - data) / 2);
366      machine().device<tms5220_device>("tms")->set_frequency(MASTER_CLOCK/4 / (16 - data) / 2);
367367   }
368368}
369369
r22818r22819
736736{
737737   if (m_has_tms5220)
738738   {
739      tms5220_data_w(machine().device("tms"), space, 0, data);
739      machine().device<tms5220_device>("tms")->data_w(space, 0, data);
740740   }
741741}
742742
r22818r22819
744744{
745745   if (m_has_tms5220)
746746   {
747      tms5220_wsq_w(machine().device("tms"), 1-(offset & 1));
747      machine().device<tms5220_device>("tms")->wsq_w(1-(offset & 1));
748748   }
749749}
750750
r22818r22819
31783178
31793179   m_pedal_count = 0;
31803180   m_has_tms5220 = 1;
3181   tms5220_rsq_w(machine().device("tms")1); // /RS is tied high on sys2 hw
3181   machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
31823182}
31833183
31843184
r22818r22819
31913191
31923192   m_pedal_count = -1;
31933193   m_has_tms5220 = 1;
3194   tms5220_rsq_w(machine().device("tms")1); // /RS is tied high on sys2 hw
3194   machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
31953195}
31963196
31973197
r22818r22819
32333233
32343234   m_pedal_count = 2;
32353235   m_has_tms5220 = 1;
3236   tms5220_rsq_w(machine().device("tms")1); // /RS is tied high on sys2 hw
3236   machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
32373237}
32383238
32393239
trunk/src/mame/drivers/maygay1b.c
r22818r22819
795795
796796READ8_MEMBER(maygay1b_state::m1_meter_r)
797797{
798   device_t *ay8910 = machine().device("aysnd");
799   return ~ay8910_read_ym(ay8910);
798   ay8910_device *ay8910 = machine().device<ay8910_device>("aysnd");
799   return ~ay8910->data_r(space, offset);
800800}
801801
802802static ADDRESS_MAP_START( m1_memmap, AS_PROGRAM, 8, maygay1b_state )
trunk/src/mame/drivers/firefox.c
r22818r22819
351351
352352READ8_MEMBER(firefox_state::riot_porta_r)
353353{
354   device_t *tms = machine().device("tms");
354   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
355
355356   /* bit 7 = MAINFLAG */
356357   /* bit 6 = SOUNDFLAG */
357358   /* bit 5 = PA5 */
r22818r22819
361362   /* bit 1 = TMS /read */
362363   /* bit 0 = TMS /write */
363364
364   return (m_main_to_sound_flag << 7) | (m_sound_to_main_flag << 6) | 0x10 | (tms5220_readyq_r(tms) << 2);
365   return (m_main_to_sound_flag << 7) | (m_sound_to_main_flag << 6) | 0x10 | (tms5220->readyq_r() << 2);
365366}
366367
367368WRITE8_MEMBER(firefox_state::riot_porta_w)
368369{
369   device_t *tms = machine().device("tms");
370   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
370371
371372   /* handle 5220 read */
372   tms5220_rsq_w(tms, (data>>1) & 1);
373   tms5220->rsq_w((data>>1) & 1);
373374
374375   /* handle 5220 write */
375   tms5220_wsq_w(tms, data & 1);
376   tms5220->wsq_w(data & 1);
376377}
377378
378379WRITE_LINE_MEMBER(firefox_state::riot_irq)
r22818r22819
695696static const riot6532_interface riot_intf =
696697{
697698   DEVCB_DRIVER_MEMBER(firefox_state,riot_porta_r),
698   DEVCB_DEVICE_HANDLER("tms", tms5220_status_r),
699   DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r),
699700   DEVCB_DRIVER_MEMBER(firefox_state,riot_porta_w),
700   DEVCB_DEVICE_HANDLER("tms", tms5220_data_w),
701   DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w),
701702   DEVCB_DRIVER_LINE_MEMBER(firefox_state,riot_irq)
702703};
703704
trunk/src/mame/drivers/atarisy1.c
r22818r22819
394394
395395WRITE8_MEMBER(atarisy1_state::via_pa_w)
396396{
397   device_t *device = machine().device("tms");
398   tms5220_data_w(device, space, 0, data);
397   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
398   tms5220->data_w(space, 0, data);
399399}
400400
401401
402402READ8_MEMBER(atarisy1_state::via_pa_r)
403403{
404   device_t *device = machine().device("tms");
405   return tms5220_status_r(device, space, 0);
404   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
405   return tms5220->status_r(space, 0);
406406}
407407
408408
409409WRITE8_MEMBER(atarisy1_state::via_pb_w)
410410{
411   device_t *device = machine().device("tms");
411   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
412412   /* write strobe */
413   tms5220_wsq_w(device, data & 1);
413   tms5220->wsq_w(data & 1);
414414
415415   /* read strobe */
416   tms5220_rsq_w(device, (data & 2)>>1);
416   tms5220->rsq_w((data & 2)>>1);
417417
418418   /* bit 4 is connected to an up-counter, clocked by SYCLKB */
419419   data = 5 | ((data >> 3) & 2);
420   tms5220_set_frequency(device, ATARI_CLOCK_14MHz/2 / (16 - data));
420   tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / (16 - data));
421421}
422422
423423
424424READ8_MEMBER(atarisy1_state::via_pb_r)
425425{
426   device_t *device = machine().device("tms");
427   return (tms5220_readyq_r(device) << 2) | (tms5220_intq_r(device) << 3);
426   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
427   return (tms5220->readyq_r() << 2) | (tms5220->intq_r() << 3);
428428}
429429
430430
trunk/src/mame/drivers/looping.c
r22818r22819
552552   AM_RANGE(0x3c00, 0x3c00) AM_MIRROR(0x00f4) AM_DEVREADWRITE("aysnd", ay8910_device, data_r, address_w)
553553   AM_RANGE(0x3c02, 0x3c02) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("aysnd", ay8910_device, data_w)
554554   AM_RANGE(0x3c03, 0x3c03) AM_MIRROR(0x00f6) AM_NOP
555   AM_RANGE(0x3e00, 0x3e00) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("tms", tms5220n_device, write)
556   AM_RANGE(0x3e02, 0x3e02) AM_MIRROR(0x00f4) AM_DEVREAD("tms", tms5220n_device, read) AM_WRITENOP
555   AM_RANGE(0x3e00, 0x3e00) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("tms", tms5220_device, data_w)
556   AM_RANGE(0x3e02, 0x3e02) AM_MIRROR(0x00f4) AM_DEVREAD("tms", tms5220_device, status_r) AM_WRITENOP
557557   AM_RANGE(0x3e03, 0x3e03) AM_MIRROR(0x00f6) AM_NOP
558558ADDRESS_MAP_END
559559
r22818r22819
612612 *
613613 *************************************/
614614
615static const tms52xx_config tms5220interface =
616{
617   DEVCB_DRIVER_LINE_MEMBER(looping_state,looping_spcint),     // IRQ
618   DEVCB_NULL                      // READYQ
619};
620
621615static const ay8910_interface ay8910_config =
622616{
623617   AY8910_LEGACY_OUTPUT,
r22818r22819
676670   MCFG_SOUND_CONFIG(ay8910_config)
677671   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20)
678672
679   MCFG_SOUND_ADD("tms", TMS5220N, TMS_CLOCK)
680   MCFG_SOUND_CONFIG(tms5220interface)
673   MCFG_SOUND_ADD("tms", TMS5220, TMS_CLOCK)
674   MCFG_TMS52XX_IRQ_HANDLER(WRITELINE(looping_state, looping_spcint))
681675   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
682676
683677   MCFG_DAC_ADD("dac")
trunk/src/mame/drivers/icecold.c
r22818r22819
163163void icecold_state::machine_reset()
164164{
165165   // CH-C is used for generate a 30hz clock
166   ay8910_set_volume(m_ay8910_0, 2, 0);
166   m_ay8910_0->set_volume(2, 0);
167167
168168   m_rmotor = m_lmotor = 10;
169169   m_sint = 0;
trunk/src/mame/drivers/esripsys.c
r22818r22819
3030#include "machine/6840ptm.h"
3131#include "machine/nvram.h"
3232#include "sound/dac.h"
33#include "sound/tms5220.h"
3433#include "includes/esripsys.h"
3534
3635
r22818r22819
521520   if (offset == 0)
522521   {
523522      /* TMS5220 core returns status bits in D7-D6 */
524      UINT8 status = tms5220_status_r(m_tms, space, 0);
523      UINT8 status = m_tms->status_r(space, 0);
525524
526525      status = ((status & 0x80) >> 5) | ((status & 0x40) >> 5) | ((status & 0x20) >> 5);
527      return (tms5220_readyq_r(m_tms) << 7) | (tms5220_intq_r(m_tms) << 6) | status;
526      return (m_tms->readyq_r() << 7) | (m_tms->intq_r() << 6) | status;
528527   }
529528
530529   return 0xff;
r22818r22819
536535   if (offset == 0)
537536   {
538537      m_tms_data = data;
539      tms5220_data_w(m_tms, space, 0, m_tms_data);
538      m_tms->data_w(space, 0, m_tms_data);
540539   }
541540#if 0
542541   if (offset == 1)
543542   {
544      tms5220_data_w(m_tms, space, 0, m_tms_data);
543      m_tms->data_w(space, 0, m_tms_data);
545544   }
546545#endif
547546}
trunk/src/mame/drivers/polepos.c
r22818r22819
957957   "maincpu", "51xx", NULL, NULL, NULL
958958};
959959
960static const tms52xx_config tms_intf =
961{
962   DEVCB_NULL
963};
964
965960static MACHINE_CONFIG_START( topracern, polepos_state )
966961
967962   /* basic machine hardware */
r22818r22819
10301025   MCFG_CPU_PROGRAM_MAP(sound_z80_bootleg_map)
10311026   MCFG_CPU_IO_MAP(sound_z80_bootleg_iomap)
10321027
1033   MCFG_SOUND_ADD("tms", TMS5220N, 600000) /* ? Mhz */
1028   MCFG_SOUND_ADD("tms", TMS5220, 600000) /* ? Mhz */
10341029   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.80)
10351030   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.80)
1036   MCFG_SOUND_CONFIG(tms_intf)
10371031MACHINE_CONFIG_END
10381032
10391033
trunk/src/mame/drivers/gauntlet.c
r22818r22819
207207         if (m_sound_reset_val & 1)
208208         {
209209            machine().device("ymsnd")->reset();
210            machine().device("tms")->reset();
211            tms5220_set_frequency(machine().device("tms"), ATARI_CLOCK_14MHz/2 / 11);
210            tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
211            tms5220->reset();
212            tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / 11);
212213            set_ym2151_volume(0);
213214            set_pokey_volume(0);
214215            set_tms5220_volume(0);
r22818r22819
227228
228229READ8_MEMBER(gauntlet_state::switch_6502_r)
229230{
231   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
230232   int temp = 0x30;
231233
232234   if (m_cpu_to_sound_ready) temp ^= 0x80;
233235   if (m_sound_to_cpu_ready) temp ^= 0x40;
234   if (!tms5220_readyq_r(machine().device("tms"))) temp ^= 0x20;
236   if (!tms5220->readyq_r()) temp ^= 0x20;
235237   if (!(ioport("803008")->read() & 0x0008)) temp ^= 0x10;
236238
237239   return temp;
r22818r22819
246248
247249WRITE8_MEMBER(gauntlet_state::sound_ctl_w)
248250{
249   device_t *tms = machine().device("tms");
251   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
250252   switch (offset & 7)
251253   {
252254      case 0: /* music reset, bit D7, low reset */
r22818r22819
254256         break;
255257
256258      case 1: /* speech write, bit D7, active low */
257         tms5220_wsq_w(tms, data >> 7);
259         tms5220->wsq_w(data >> 7);
258260         break;
259261
260262      case 2: /* speech reset, bit D7, active low */
261         tms5220_rsq_w(tms, data >> 7);
263         tms5220->rsq_w(data >> 7);
262264         break;
263265
264266      case 3: /* speech squeak, bit D7 */
265267         data = 5 | ((data >> 6) & 2);
266         tms5220_set_frequency(tms, ATARI_CLOCK_14MHz/2 / (16 - data));
268         tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / (16 - data));
267269         break;
268270   }
269271}
r22818r22819
342344   AM_RANGE(0x1030, 0x103f) AM_MIRROR(0x27c0) AM_READWRITE(switch_6502_r, sound_ctl_w)
343345   AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x27c0) AM_DEVREADWRITE("pokey", pokey_device, read, write)
344346   AM_RANGE(0x1810, 0x1811) AM_MIRROR(0x27ce) AM_DEVREADWRITE("ymsnd", ym2151_device, read, write)
345   AM_RANGE(0x1820, 0x182f) AM_MIRROR(0x27c0) AM_DEVWRITE_LEGACY("tms", tms5220_data_w)
347   AM_RANGE(0x1820, 0x182f) AM_MIRROR(0x27c0) AM_DEVWRITE("tms", tms5220_device, data_w)
346348   AM_RANGE(0x1830, 0x183f) AM_MIRROR(0x27c0) AM_READWRITE(m6502_irq_ack_r, m6502_irq_ack_w)
347349   AM_RANGE(0x4000, 0xffff) AM_ROM
348350ADDRESS_MAP_END
trunk/src/mame/audio/cinemat.c
r22818r22819
14101410   state->m_last_portb_write = 0xff;
14111411
14121412   /* turn off channel A on AY8910 #0 because it is used as a low-pass filter */
1413   ay8910_set_volume(machine.device("ay1"), 0, 0);
1413   machine.device<ay8910_device>("ay1")->set_volume(0, 0);
14141414}
14151415
14161416
trunk/src/mame/audio/exidy.c
r22818r22819
103103
104104   /* 5220/CVSD variables */
105105   device_t *m_cvsd;
106   device_t *m_tms;
106   tms5220_device *m_tms;
107107   pia6821_device *m_pia1;
108108
109109   /* sound streaming variables */
r22818r22819
533533   if (state->m_tms != NULL)
534534   {
535535      logerror("(%f)%s:TMS5220 data write = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_riot->porta_out_get());
536      tms5220_data_w(state->m_tms, space, 0, data);
536      state->m_tms->data_w(space, 0, data);
537537   }
538538}
539539
r22818r22819
542542   exidy_sound_state *state = get_safe_token(device);
543543   if (state->m_tms != NULL)
544544   {
545      logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), tms5220_status_r(state->m_tms, space, 0));
546      return tms5220_status_r(state->m_tms, space, 0);
545      logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_tms->status_r(space, 0));
546      return state->m_tms->status_r(space, 0);
547547   }
548548   else
549549      return 0xff;
r22818r22819
554554   exidy_sound_state *state = get_safe_token(device);
555555   if (state->m_tms != NULL)
556556   {
557      tms5220_rsq_w(state->m_tms, data & 0x01);
558      tms5220_wsq_w(state->m_tms, (data >> 1) & 0x01);
557      state->m_tms->rsq_w(data & 0x01);
558      state->m_tms->wsq_w((data >> 1) & 0x01);
559559   }
560560}
561561
r22818r22819
567567   if (state->m_tms != NULL)
568568   {
569569      newdata &= ~0x0c;
570      if (tms5220_readyq_r(state->m_tms)) newdata |= 0x04;
571      if (tms5220_intq_r(state->m_tms)) newdata |= 0x08;
570      if (state->m_tms->readyq_r()) newdata |= 0x04;
571      if (state->m_tms->intq_r()) newdata |= 0x08;
572572   }
573573   return newdata;
574574}
r22818r22819
11261126   device->save_item(NAME(state->m_victory_sound_response_ack_clk));
11271127
11281128   DEVICE_START_CALL(venture_common_sh_start);
1129   state->m_tms = device->machine().device("tms");
1129   state->m_tms = device->machine().device<tms5220_device>("tms");
11301130}
11311131
11321132
trunk/src/mame/audio/midway.c
r22818r22819
372372
373373void midway_ssio_device::update_volumes()
374374{
375   ay8910_set_volume(m_ay0, 0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][0]]);
376   ay8910_set_volume(m_ay0, 1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][1]]);
377   ay8910_set_volume(m_ay0, 2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][2]]);
378   ay8910_set_volume(m_ay1, 0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][0]]);
379   ay8910_set_volume(m_ay1, 1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][1]]);
380   ay8910_set_volume(m_ay1, 2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][2]]);
375   m_ay0->set_volume(0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][0]]);
376   m_ay0->set_volume(1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][1]]);
377   m_ay0->set_volume(2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][2]]);
378   m_ay1->set_volume(0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][0]]);
379   m_ay1->set_volume(1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][1]]);
380   m_ay1->set_volume(2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][2]]);
381381}
382382
383383
r22818r22819
11981198   // write strobe -- pass the current command to the TMS5200
11991199   if (((data ^ m_tms_strobes) & 0x02) && !(data & 0x02))
12001200   {
1201      tms5220_data_w(m_tms5200, space, offset, m_tms_command);
1201      m_tms5200->data_w(space, offset, m_tms_command);
12021202
12031203      // DoT expects the ready line to transition on a command/write here, so we oblige
12041204      m_pia1->ca2_w(1);
r22818r22819
12081208   // read strobe -- read the current status from the TMS5200
12091209   else if (((data ^ m_tms_strobes) & 0x01) && !(data & 0x01))
12101210   {
1211      m_pia1->porta_w(tms5220_status_r(m_tms5200, space, offset));
1211      m_pia1->porta_w(m_tms5200->status_r(space, offset));
12121212
12131213      // DoT expects the ready line to transition on a command/write here, so we oblige
12141214      m_pia1->ca2_w(1);
trunk/src/mame/audio/starwars.c
r22818r22819
3434   /* Note: bit 4 is always set to avoid sound self test */
3535   UINT8 olddata = m_riot->porta_in_get();
3636
37   return (olddata & 0xc0) | 0x10 | (tms5220_readyq_r(machine().device("tms")) << 2);
37   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
38   return (olddata & 0xc0) | 0x10 | (tms5220->readyq_r() << 2);
3839}
3940
4041
4142WRITE8_MEMBER(starwars_state::r6532_porta_w)
4243{
43   device_t *device = machine().device("tms");
44   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
4445   /* handle 5220 read */
45   tms5220_rsq_w(device, (data & 2)>>1);
46   tms5220->rsq_w((data & 2)>>1);
4647   /* handle 5220 write */
47   tms5220_wsq_w(device, (data & 1)>>0);
48   tms5220->wsq_w((data & 1)>>0);
4849}
4950
5051
r22818r22819
5758const riot6532_interface starwars_riot6532_intf =
5859{
5960   DEVCB_DRIVER_MEMBER(starwars_state,r6532_porta_r),
60   DEVCB_DEVICE_HANDLER("tms", tms5220_status_r),
61   DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r),
6162   DEVCB_DRIVER_MEMBER(starwars_state,r6532_porta_w),
62   DEVCB_DEVICE_HANDLER("tms", tms5220_data_w),
63   DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w),
6364   DEVCB_DRIVER_LINE_MEMBER(starwars_state,snd_interrupt)
6465};
6566
trunk/src/mame/audio/jedi.c
r22818r22819
139139
140140   if ((new_speech_strobe_state != m_speech_strobe_state) && new_speech_strobe_state)
141141   {
142      device_t *tms = machine().device("tms");
143      tms5220_data_w(tms, space, 0, *m_speech_data);
142      tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
143      tms5220->data_w(space, 0, *m_speech_data);
144144   }
145145   m_speech_strobe_state = new_speech_strobe_state;
146146}
r22818r22819
148148
149149READ8_MEMBER(jedi_state::speech_ready_r)
150150{
151   return (tms5220_readyq_r(machine().device("tms"))) << 7;
151   tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
152   return (tms5220->readyq_r()) << 7;
152153}
153154
154155
trunk/src/mame/audio/atarijsa.c
r22818r22819
5959
6060static pokey_device *pokey;
6161static ym2151_device *ym2151;
62static device_t *tms5220;
62static tms5220_device *tms5220;
6363static okim6295_device *oki6295;
6464static okim6295_device *oki6295_l, *oki6295_r;
6565
r22818r22819
138138   bank_source_data = &rgn[0x10000];
139139
140140   /* determine which sound hardware is installed */
141   tms5220 = machine.device("tms");
141   tms5220 = machine.device<tms5220_device>("tms");
142142   ym2151 = machine.device<ym2151_device>("ymsnd");
143143   pokey = machine.device<pokey_device>("pokey");
144144   oki6295 = machine.device<okim6295_device>("adpcm");
r22818r22819
231231         if (!(space.machine().root_device().ioport(test_port)->read() & test_mask)) result ^= 0x80;
232232         if (atarigen->m_cpu_to_sound_ready) result ^= 0x40;
233233         if (atarigen->m_sound_to_cpu_ready) result ^= 0x20;
234         if ((tms5220 != NULL) && (tms5220_readyq_r(tms5220) == 0))
234         if ((tms5220 != NULL) && (tms5220->readyq_r() == 0))
235235            result |= 0x10;
236236         else
237237            result &= ~0x10;
r22818r22819
269269
270270      case 0x200:     /* /VOICE */
271271         if (tms5220 != NULL)
272            tms5220_data_w(tms5220, space, 0, data);
272            tms5220->data_w(space, 0, data);
273273         break;
274274
275275      case 0x202:     /* /WRP */
r22818r22819
291291         if (tms5220 != NULL)
292292         {
293293            int count;
294            tms5220_wsq_w(tms5220, (data&0x02)>>1);
295            tms5220_rsq_w(tms5220, (data&0x04)>>2);
294            tms5220->wsq_w((data&0x02)>>1);
295            tms5220->rsq_w((data&0x04)>>2);
296296            count = 5 | ((data >> 2) & 2);
297            tms5220_set_frequency(tms5220, JSA_MASTER_CLOCK*2 / (16 - count));
297            tms5220->set_frequency(JSA_MASTER_CLOCK*2 / (16 - count));
298298         }
299299
300300         /* reset the YM2151 if needed */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team