Previous 199869 Revisions Next

r40522 Friday 28th August, 2015 at 16:56:37 UTC by R. Belmont
Merge pull request #291 from rzero9/patch-1

Added three new Sharp X1 dumps
[src/emu/drivers]emudummy.c
[src/emu/netlist]nl_base.h nl_setup.h
[src/emu/netlist/plib]pstring.c pstring.h
[src/emu/netlist/solver]nld_solver.h
[src/emu/sound]c352.c c352.h tms5110.c tms5110.h tms5220.c tms5220.h
[src/mame]arcade.lst
[src/mame/drivers]fcrash.c midxunit.c namcofl.c namconb1.c namcond1.c namcos11.c namcos12.c namcos22.c namcos23.c quantum.c
[src/mame/includes]chihiro.h
[src/mame/machine]xbox.c
[src/mame/video]chihiro.c
[src/osd/modules/debugger/win]debugviewinfo.c debugwininfo.c editwininfo.c
[src/osd/windows]input.c output.c window.c winmain.c winutil.c winutil.h

trunk/src/emu/drivers/emudummy.c
r249033r249034
3333ROM_END
3434
3535
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", GAME_NO_SOUND )
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", MACHINE_NO_SOUND )
trunk/src/emu/netlist/nl_base.h
r249033r249034
12331233      pnamedlist_t<core_device_t *> m_started_devices;
12341234   #endif
12351235
1236   ATTR_COLD plog_base<NL_DEBUG> &log() { return m_log; }
12361237   ATTR_COLD const plog_base<NL_DEBUG> &log() const { return m_log; }
12371238
12381239   protected:
trunk/src/emu/netlist/nl_setup.h
r249033r249034
198198
199199      void model_parse(const pstring &model, model_map_t &map);
200200
201      plog_base<NL_DEBUG> &log() { return netlist().log(); }
201202      const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
202203
203204   protected:
trunk/src/emu/netlist/plib/pstring.c
r249033r249034
1414
1515#include "pstring.h"
1616#include "palloc.h"
17#include "plists.h"
1718
1819template<>
1920pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0);
r249033r249034
305306// static stuff ...
306307// ----------------------------------------------------------------------------------------
307308
309/*
310 * Cached allocation of string memory
311 *
312 * This improves startup performance by 30%.
313 */
314
315#if 1
316
317static pstack_t<pstr_t *> *stk = NULL;
318
319static inline unsigned countleadbits(unsigned x)
320{
321#ifndef count_leading_zeros
322   unsigned msk;
323   unsigned ret;
324   if (x < 0x100)
325   {
326      msk = 0x80;
327      ret = 24;
328   }
329   else if (x < 0x10000)
330   {
331      msk = 0x8000;
332      ret = 16;
333   }
334   else if (x < 0x1000000)
335   {
336      msk = 0x800000;
337      ret = 8;
338   }
339   else
340   {
341      msk = 0x80000000;
342      ret = 0;
343   }
344   while ((msk & x) == 0 && ret < 31)
345   {
346      msk = msk >> 1;
347      ret++;
348   }
349   return ret;
350#else
351   return count_leading_zeros(x);
352#endif
353}
354
308355template<typename F>
309356void pstring_t<F>::sfree(pstr_t *s)
310357{
311358   s->m_ref_count--;
312359   if (s->m_ref_count == 0 && s != &m_zero)
313360   {
361      if (stk != NULL)
362      {
363         unsigned sn= ((32 - countleadbits(s->len())) + 1) / 2;
364         stk[sn].push(s);
365      }
366      else
367         pfree_array(((char *)s));
368      //_mm_free(((char *)s));
369   }
370}
371
372template<typename F>
373pstr_t *pstring_t<F>::salloc(int n)
374{
375   if (stk == NULL)
376      stk = palloc_array(pstack_t<pstr_t *>, 17);
377   pstr_t *p;
378   unsigned sn= ((32 - countleadbits(n)) + 1) / 2;
379   unsigned size = sizeof(pstr_t) + (1<<(sn * 2)) + 1;
380   if (stk[sn].empty())
381      p = (pstr_t *) palloc_array(char, size);
382   else
383   {
384      //printf("%u %u\n", sn, (unsigned) stk[sn].count());
385      p = stk[sn].pop();
386   }
387
388   //  str_t *p = (str_t *) _mm_malloc(size, 8);
389   p->init(n);
390   return p;
391}
392template<typename F>
393void pstring_t<F>::resetmem()
394{
395   if (stk != NULL)
396   {
397      for (unsigned i=0; i<=16; i++)
398      {
399         for (; stk[i].count() > 0; )
400            pfree_array(stk[i].pop());
401      }
402      pfree_array(stk);
403      stk = NULL;
404   }
405}
406
407
408#else
409template<typename F>
410void pstring_t<F>::sfree(pstr_t *s)
411{
412   s->m_ref_count--;
413   if (s->m_ref_count == 0 && s != &m_zero)
414   {
314415      pfree_array(((char *)s));
315416      //_mm_free(((char *)s));
316417   }
r249033r249034
331432{
332433   // Release the 0 string
333434}
435#endif
334436
437
335438// ----------------------------------------------------------------------------------------
336439// pstring ...
337440// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/plib/pstring.h
r249033r249034
2222   struct pstr_t
2323   {
2424      //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; }
25      pstr_t(const int alen)
25      pstr_t(const unsigned alen)
2626      {
2727         init(alen);
2828      }
29      void init(const int alen)
29      void init(const unsigned alen)
3030      {
3131            m_ref_count = 1;
3232            m_len = alen;
3333            m_str[0] = 0;
3434      }
3535      char *str() { return &m_str[0]; }
36      int len() const  { return m_len; }
36      unsigned len() const  { return m_len; }
3737      int m_ref_count;
3838   private:
39      int m_len;
39      unsigned m_len;
4040      char m_str[1];
4141   };
4242
r249033r249034
548548class pfmt_writer_t
549549{
550550public:
551   pfmt_writer_t()  { }
551   pfmt_writer_t() : m_enabled(true) { }
552552   virtual ~pfmt_writer_t() { }
553553
554554   ATTR_COLD void operator ()(const char *fmt) const
555555   {
556      if (build_enabled) vdowrite(fmt);
556      if (build_enabled && m_enabled) vdowrite(fmt);
557557   }
558558
559559   template<typename T1>
560560   ATTR_COLD void operator ()(const char *fmt, const T1 &v1) const
561561   {
562      if (build_enabled) vdowrite(pfmt(fmt)(v1));
562      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1));
563563   }
564564
565565   template<typename T1, typename T2>
566566   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2) const
567567   {
568      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2));
568      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2));
569569   }
570570
571571   template<typename T1, typename T2, typename T3>
572572   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3) const
573573   {
574      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
574      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
575575   }
576576
577577   template<typename T1, typename T2, typename T3, typename T4>
578578   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const
579579   {
580      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
580      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
581581   }
582582
583583   template<typename T1, typename T2, typename T3, typename T4, typename T5>
584584   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) const
585585   {
586      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
586      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
587587   }
588588
589   void set_enabled(const bool v)
590   {
591      m_enabled = v;
592   }
593
594   bool is_enabled() const { return m_enabled; }
595
589596protected:
590597   virtual void vdowrite(const pstring &ls) const {}
591598
599private:
600   bool m_enabled;
601
592602};
593603
594604template <plog_level L, bool build_enabled = true>
trunk/src/emu/netlist/solver/nld_solver.h
r249033r249034
135135   ATTR_COLD int get_net_idx(net_t *net);
136136
137137   inline eSolverType type() const { return m_type; }
138   const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
138   plog_base<NL_DEBUG> &log() { return netlist().log(); }
139139
140140   virtual void log_stats();
141141
trunk/src/emu/sound/c352.c
r249033r249034
1313    Supports 8-bit linear and 8-bit muLaw samples
1414    Output: digital, 16 bit, 4 channels
1515    Output sample rate is the input clock / (288 * 2).
16   
17    superctr: The clock divider appears to be configurable for each system.
18    Below is a list of the divider values followed by the systems that use it.
19   
20    * 228: System 11.
21    * 288: System 22, Super 22, NB-1/2, ND-1, FL.
22    * 296: System 23, Super 23.
23    * 332: System 12.
1624 */
1725
1826#include "emu.h"
r249033r249034
468476
469477void c352_device::device_start()
470478{
471   int i, divider;
479   int i;
472480   double x_max = 32752.0;
473481   double y_max = 127.0;
474482   double u = 10.0;
r249033r249034
476484   // find our direct access
477485   m_direct = &space().direct();
478486
479   switch(m_divider)
480   {
481      case C352_DIVIDER_228:
482         divider=228;
483         break;
484      case C352_DIVIDER_288:
485      default:
486         divider=288;
487         break;
488      case C352_DIVIDER_332:
489         divider=332;
490         break;
491   }
487   m_sample_rate_base = clock() / m_divider;
492488
493   m_sample_rate_base = clock() / divider;
494
495489   m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base);
496490
497491   // generate mulaw table for mulaw format samples
trunk/src/emu/sound/c352.h
r249033r249034
66#define __C352_H__
77
88//**************************************************************************
9//  CONSTANTS
10//**************************************************************************
11
12enum
13{
14   C352_DIVIDER_228 = 0,
15   C352_DIVIDER_288 = 1,
16   C352_DIVIDER_332 = 2
17};
18
19//**************************************************************************
209//  INTERFACE CONFIGURATION MACROS
2110//**************************************************************************
2211
trunk/src/emu/sound/tms5110.c
r249033r249034
235235   save_item(NAME(m_old_frame_pitch_idx));
236236   save_item(NAME(m_old_frame_k_idx));
237237   save_item(NAME(m_old_zpar));
238   save_item(NAME(m_old_uv_zpar));
238239#endif
239240   save_item(NAME(m_current_energy));
240241   save_item(NAME(m_current_pitch));
r249033r249034
349350   int i, bitout;
350351   INT32 this_sample;
351352
352   /* if we're not speaking, fill with nothingness */
353   if (!m_TALKD)
354      goto empty;
355
356353   /* loop until the buffer is full or we've stopped speaking */
357   while ((size > 0) && m_TALKD)
354   while (size > 0)
358355   {
359      /* if it is the appropriate time to update the old energy/pitch indices,
360       * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
361       * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
362       * which happens 4 T-cycles later), we change on the latter.
363       * The indices are updated here ~12 PCs before the new frame is applied.
364       */
365      /** TODO: the patents 4331836, 4335277, and 4419540 disagree about the timing of this **/
366      if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2))
356      if(m_TALKD) // speaking
367357      {
368         m_OLDE = (m_new_frame_energy_idx == 0);
369         m_OLDP = (m_new_frame_pitch_idx == 0);
370      }
358         /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
359          * (In reality, the frame was really loaded incrementally during the entire IP=0
360          * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
361          */
362         if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
363         {
364            // HACK for regression testing, be sure to comment out before release!
365            //m_RNG = 0x1234;
366            // end HACK
371367
372      /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
373       * (In reality, the frame was really loaded incrementally during the entire IP=0
374       * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
375       */
376      if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
377      {
378         // HACK for regression testing, be sure to comment out before release!
379         //m_RNG = 0x1234;
380         // end HACK
381
382368#ifdef PERFECT_INTERPOLATION_HACK
383         /* remember previous frame energy, pitch, and coefficients */
384         m_old_frame_energy_idx = m_new_frame_energy_idx;
385         m_old_frame_pitch_idx = m_new_frame_pitch_idx;
386         for (i = 0; i < m_coeff->num_k; i++)
387            m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
369            /* remember previous frame energy, pitch, and coefficients */
370            m_old_frame_energy_idx = m_new_frame_energy_idx;
371            m_old_frame_pitch_idx = m_new_frame_pitch_idx;
372            for (i = 0; i < m_coeff->num_k; i++)
373               m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
388374#endif
389375
390         /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
391         parse_frame();
392#ifdef DEBUG_PARSE_FRAME_DUMP
393         fprintf(stderr,"\n");
376            /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
377            parse_frame();
378
379            // if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters
380            // NOTE: this is probably the bug the tms5100/tmc0280 has, pre-rev D, I think.
381            // GUESS: Pre-rev D versions start zeroing k5-k10 immediately upon new frame load regardless of interpolation inhibit
382            // I.e. ZPAR = /TALKD || (PC>5&&P=0)
383            // GUESS: D and later versions only start or stop zeroing k5-k10 at the IP7->IP0 transition AFTER the frame
384            // I.e. ZPAR = /TALKD || (PC>5&&OLDP)
385#ifdef PERFECT_INTERPOLATION_HACK
386            m_old_uv_zpar = m_uv_zpar;
387            m_old_zpar = m_zpar; // unset old zpar on new frame
394388#endif
395         /* if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters */
396         m_uv_zpar = NEW_FRAME_UNVOICED_FLAG | m_zpar;
389            m_zpar = 0;
390            //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110
391            m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100
397392
398         /* if the new frame is a stop frame, unset both TALK and SPEN. TALKD remains active while the energy is ramping to 0. */
399         if (NEW_FRAME_STOP_FLAG == 1)
400         {
401            m_TALK = m_SPEN = 0;
402         }
393            /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */
394            if (NEW_FRAME_STOP_FLAG == 1)
395            {
396               m_TALK = m_SPEN = 0;
397            }
403398
404         /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
405            Interpolation inhibit cases:
406          * Old frame was voiced, new is unvoiced
407          * Old frame was silence/zero energy, new has nonzero energy
408          * Old frame was unvoiced, new is voiced (note this is the case on the patent but may not be correct on the real final chip)
409          */
410         if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
411            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */
412            || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) )
413            m_inhibit = 1;
414         else // normal frame, normal interpolation
415            m_inhibit = 0;
399            /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
400               Interpolation inhibit cases:
401             * Old frame was voiced, new is unvoiced
402             * Old frame was silence/zero energy, new has nonzero energy
403             * Old frame was unvoiced, new is voiced (note this is the case on the patent but may not be correct on the real final chip)
404             */
405            if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
406               || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */
407               || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) )
408               m_inhibit = 1;
409            else // normal frame, normal interpolation
410               m_inhibit = 0;
416411
417412#ifdef DEBUG_GENERATION
418         /* Debug info for current parsed frame */
419         fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
420         fprintf(stderr,"Processing frame: ");
421         if (m_inhibit == 0)
422            fprintf(stderr, "Normal Frame\n");
423         else
424            fprintf(stderr,"Interpolation Inhibited\n");
425         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]);
426         fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
427            (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)),
428            m_new_frame_energy_idx,
429            (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)),
430            (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)),
431            (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)),
432            (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)),
433            (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)),
434            (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)),
435            (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)),
436            (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)),
437            (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)),
438            (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)),
439            (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) );
413            /* Debug info for current parsed frame */
414            fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
415            fprintf(stderr,"Processing new frame: ");
416            if (m_inhibit == 0)
417               fprintf(stderr, "Normal Frame\n");
418            else
419               fprintf(stderr,"Interpolation Inhibited\n");
420            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]);
421            fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
422               (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)),
423               m_new_frame_energy_idx,
424               (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)),
425               (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)),
426               (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)),
427               (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)),
428               (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)),
429               (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)),
430               (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)),
431               (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)),
432               (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)),
433               (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)),
434               (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) );
440435#endif
441436
442      }
443      else // Not a new frame, just interpolate the existing frame.
444      {
445         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
446#ifdef PERFECT_INTERPOLATION_HACK
447         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
448         //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
449         int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
450         //fprintf(stderr, "CS: %03d", current_sample);
451         // reset the current energy, pitch, etc to what it was at frame start
452         m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_zpar));
453         m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar));
454         for (i = 0; i < 4; i++)
455            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-m_old_zpar));
456         for (i = 4; i < m_coeff->num_k; i++)
457            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-m_uv_zpar));
458         // now adjust each value to be exactly correct for each of the samples per frame
459         if (m_IP != 0) // if we're still interpolating...
460         {
461            m_current_energy += ((((m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)) - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
462            m_current_pitch += ((((m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)) - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
463            for (i = 0; i < m_coeff->num_k; i++)
464               m_current_k[i] += ((((m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar))) - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
465437         }
466         else // we're done, play this frame for 1/8 frame.
438         else // Not a new frame, just interpolate the existing frame.
467439         {
468            m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar));
469            m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar));
440            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
441#ifdef PERFECT_INTERPOLATION_HACK
442            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
443            //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
444            int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
445            //fprintf(stderr, "CS: %03d", current_sample);
446            // reset the current energy, pitch, etc to what it was at frame start
447            m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar));
448            m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar));
470449            for (i = 0; i < m_coeff->num_k; i++)
471               m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
472         }
450               m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar)));
451            // now adjust each value to be exactly correct for each of the samples per frame
452            if (m_IP != 0) // if we're still interpolating...
453            {
454               m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
455               m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
456               for (i = 0; i < m_coeff->num_k; i++)
457                  m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar));
458            }
459            else // we're done, play this frame for 1/8 frame.
460            {
461               m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar));
462               m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar));
463               for (i = 0; i < m_coeff->num_k; i++)
464                  m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
465            }
473466#else
474         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
475         if (m_subcycle == 2)
476         {
477            switch(m_PC)
467            //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
468            if (m_subcycle == 2)
478469            {
479               case 0: /* PC = 0, B cycle, write updated energy */
480               m_current_energy += ((((m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)) - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT);
481               break;
482               case 1: /* PC = 1, B cycle, write updated pitch */
483               m_current_pitch += ((((m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)) - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
484               break;
485               case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
486               /* PC = 2 through 11, B cycle, write updated K1 through K10 */
487               m_current_k[m_PC-2] += ((((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] * (1-(((m_PC-2)<4)?m_zpar:m_uv_zpar))) - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT);
488               break;
489               case 12: /* PC = 12, do nothing */
490               break;
470               switch(m_PC)
471               {
472                  case 0: /* PC = 0, B cycle, write updated energy */
473                  m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
474                  break;
475                  case 1: /* PC = 1, B cycle, write updated pitch */
476                  m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
477                  break;
478                  case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
479                  /* PC = 2 through 11, B cycle, write updated K1 through K10 */
480                  m_current_k[m_PC-2] = (m_current_k[m_PC-2] + (((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT))*(((m_PC-2)>4)?(1-m_uv_zpar):(1-m_zpar));
481                  break;
482                  case 12: /* PC = 12 */
483                  /* we should NEVER reach this point, PC=12 doesn't have a subcycle 2 */
484                  break;
485               }
491486            }
487#endif
492488         }
493#endif
494      }
495489
496      // calculate the output
497      if (OLD_FRAME_UNVOICED_FLAG == 1)
498      {
499         // generate unvoiced samples here
500         if (m_RNG & 1)
501            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)*/
502         else
503            m_excitation_data = 0x40;
504      }
505      else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
506      {
507         // generate voiced samples here
508         /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
509          * function has a chirp/peak and then a long chain of zeroes.
510          * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
511          * and if the address reaches that point the ADDRESS incrementer is
512          * disabled, forcing all samples beyond 51d to be == 51d
513          */
514         if (m_pitch_count >= 51)
515            m_excitation_data = (INT8)m_coeff->chirptable[51];
516         else /*m_pitch_count < 51*/
517            m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
518      }
490         // calculate the output
491         if (OLD_FRAME_UNVOICED_FLAG == 1)
492         {
493            // generate unvoiced samples here
494            if (m_RNG & 1)
495               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)*/
496            else
497               m_excitation_data = 0x40;
498         }
499         else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
500         {
501            // generate voiced samples here
502            /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
503             * function has a chirp/peak and then a long chain of zeroes.
504             * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
505             * and if the address reaches that point the ADDRESS incrementer is
506             * disabled, forcing all samples beyond 51d to be == 51d
507             */
508            if (m_pitch_count >= 51)
509               m_excitation_data = (INT8)m_coeff->chirptable[51];
510            else /*m_pitch_count < 51*/
511               m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
512         }
519513
520      // Update LFSR *20* times every sample (once per T cycle), like patent shows
521   for (i=0; i<20; i++)
522   {
523      bitout = ((m_RNG >> 12) & 1) ^
524            ((m_RNG >>  3) & 1) ^
525            ((m_RNG >>  2) & 1) ^
526            ((m_RNG >>  0) & 1);
527      m_RNG <<= 1;
528      m_RNG |= bitout;
529   }
530      this_sample = lattice_filter(); /* execute lattice filter */
514         // Update LFSR *20* times every sample (once per T cycle), like patent shows
515         for (i=0; i<20; i++)
516         {
517            bitout = ((m_RNG >> 12) & 1) ^
518                  ((m_RNG >>  3) & 1) ^
519                  ((m_RNG >>  2) & 1) ^
520                  ((m_RNG >>  0) & 1);
521            m_RNG <<= 1;
522            m_RNG |= bitout;
523         }
524         this_sample = lattice_filter(); /* execute lattice filter */
531525#ifdef DEBUG_GENERATION_VERBOSE
532      //fprintf(stderr,"C:%01d; ",m_subcycle);
533      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);
534      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
535      for (i=0; i<10; i++)
536         fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
537      fprintf(stderr,"Out:%06d", this_sample);
538      fprintf(stderr,"\n");
526         //fprintf(stderr,"C:%01d; ",m_subcycle);
527         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);
528         //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
529         for (i=0; i<10; i++)
530            fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
531         fprintf(stderr,"Out:%06d ", this_sample);
532//#ifdef PERFECT_INTERPOLATION_HACK
533//         fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar);
534//#else
535//         fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar);
536//#endif
537         fprintf(stderr,"\n");
539538#endif
540      /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
541      while (this_sample > 16383) this_sample -= 32768;
542      while (this_sample < -16384) this_sample += 32768;
543      if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
544         buffer[buf_count] = clip_analog(this_sample);
545      else // digital I/O pin output is 12 bits
546      {
539         /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
540         while (this_sample > 16383) this_sample -= 32768;
541         while (this_sample < -16384) this_sample += 32768;
542         if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
543            buffer[buf_count] = clip_analog(this_sample);
544         else // digital I/O pin output is 12 bits
545         {
547546#ifdef ALLOW_4_LSB
548         // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
549         // N taps:                       ^                 = 0x2000;
550         // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
551         buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
547            // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
548            // N taps:                       ^                 = 0x2000;
549            // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
550            buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
552551#else
553         this_sample &= ~0xF;
554         // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
555         // N taps:                       ^^ ^^^            = 0x3E00;
556         // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
557         buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
552            this_sample &= ~0xF;
553            // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
554            // N taps:                       ^^ ^^^            = 0x3E00;
555            // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
556            buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
558557#endif
559      }
560      // Update all counts
558         }
559         // Update all counts
561560
562      m_subcycle++;
563      if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
564      {
565         /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
566          * if INHIBIT was true during the most recent frame transition.
567          * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
568          * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
569          * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
570          * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
571          * convenient and should make no difference in output.
572          */
573         if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1;
574         if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0;
575         if (m_IP == 7) // RESETL4
561         m_subcycle++;
562         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
576563         {
577            /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
564            /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
565             * if INHIBIT was true during the most recent frame transition.
566             * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
567             * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
568             * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
569             * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
570             * convenient and should make no difference in output.
571             */
572            if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1;
573            if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0;
574            if (m_IP == 7) // RESETL4
575            {
576               // Latch OLDE and OLDP
577               OLD_FRAME_SILENCE_FLAG = NEW_FRAME_SILENCE_FLAG; // m_OLDE
578               OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // m_OLDP
579               /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
578580#ifdef DEBUG_GENERATION
579            if (m_TALK == 0)
580               fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
581               if (m_TALK == 0)
582                  fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
581583#endif
582            m_TALKD = m_TALK; // TALKD is latched from TALK
583            m_TALK = m_SPEN; // TALK is latched from SPEN
584#ifdef PERFECT_INTERPOLATION_HACK
585            m_old_zpar = m_zpar;
586#endif
587            m_zpar = 1 - m_TALKD; // ZPAR is inverse of m_TALKD
584               m_TALKD = m_TALK; // TALKD is latched from TALK
585               m_TALK = m_SPEN; // TALK is latched from SPEN
586            }
587            m_subcycle = m_subc_reload;
588            m_PC = 0;
589            m_IP++;
590            m_IP&=0x7;
588591         }
589         m_subcycle = m_subc_reload;
590         m_PC = 0;
591         m_IP++;
592         m_IP&=0x7;
592         else if (m_subcycle == 3)
593         {
594            m_subcycle = m_subc_reload;
595            m_PC++;
596         }
597         m_pitch_count++;
598         if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0;
599         m_pitch_count &= 0x1FF;
593600      }
594      else if (m_subcycle == 3)
601      else // m_TALKD == 0
595602      {
596         m_subcycle = m_subc_reload;
597         m_PC++;
598      }
599      m_pitch_count++;
600      if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0;
601      m_pitch_count &= 0x1FF;
602      buf_count++;
603      size--;
604   }
605
606empty:
607
608   while (size > 0)
609   {
610      m_subcycle++;
611      if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
612      {
613         if (m_IP == 7) // RESETL4
603         m_subcycle++;
604         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
614605         {
615            m_TALKD = m_TALK; // TALKD is latched from TALK
616            m_TALK = m_SPEN; // TALK is latched from SPEN
617#ifdef PERFECT_INTERPOLATION_HACK
618            m_old_zpar = m_zpar;
619#endif
620            m_zpar = 1 - m_TALKD; // ZPAR is inverse of m_TALKD
606            if (m_IP == 7) // RESETL4
607            {
608               m_TALKD = m_TALK; // TALKD is latched from TALK
609               m_TALK = m_SPEN; // TALK is latched from SPEN
610            }
611            m_subcycle = m_subc_reload;
612            m_PC = 0;
613            m_IP++;
614            m_IP&=0x7;
621615         }
622         m_subcycle = m_subc_reload;
623         m_PC = 0;
624         m_IP++;
625         m_IP&=0x7;
616         else if (m_subcycle == 3)
617         {
618            m_subcycle = m_subc_reload;
619            m_PC++;
620         }
621         buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
626622      }
627      else if (m_subcycle == 3)
628      {
629         m_subcycle = m_subc_reload;
630         m_PC++;
631      }
632      buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
633      buf_count++;
634      size--;
623   buf_count++;
624   size--;
635625   }
636626}
637627
r249033r249034
863853               m_SPEN = 1; /* start immediately */
864854               /* clear out variables before speaking */
865855               m_zpar = 1; // zero all the parameters
856               m_uv_zpar = 1; // zero k4-k10 as well
857               m_OLDE = 1; // 'silence/zpar' frames are zero energy
858               m_OLDP = 1; // 'silence/zpar' frames are zero pitch
859#ifdef PERFECT_INTERPOLATION_HACK
860               m_old_zpar = 1; // zero all the old parameters
861               m_old_uv_zpar = 1; // zero old k4-k10 as well
862#endif
866863               m_subc_reload = 0; // SPKSLOW means this is 0
867               m_subcycle = m_subc_reload;
868               m_PC = 0;
869               m_IP = 0;
870864               break;
871865
872866            case TMS5110_CMD_READ_BIT:
r249033r249034
894888               m_SPEN = 1; /* start immediately */
895889               /* clear out variables before speaking */
896890               m_zpar = 1; // zero all the parameters
891               m_uv_zpar = 1; // zero k4-k10 as well
892               m_OLDE = 1; // 'silence/zpar' frames are zero energy
893               m_OLDP = 1; // 'silence/zpar' frames are zero pitch
894#ifdef PERFECT_INTERPOLATION_HACK
895               m_old_zpar = 1; // zero all the old parameters
896               m_old_uv_zpar = 1; // zero old k4-k10 as well
897#endif
897898               m_subc_reload = 1; // SPEAK means this is 1
898               m_subcycle = m_subc_reload;
899               m_PC = 0;
900               m_IP = 0;
901899               break;
902900
903901            case TMS5110_CMD_READ_BRANCH:
r249033r249034
996994      fprintf(stderr," ");
997995#endif
998996   }
997#ifdef DEBUG_PARSE_FRAME_DUMP
998         fprintf(stderr,"\n");
999#endif
9991000#ifdef VERBOSE
10001001      logerror("Parsed a frame successfully in ROM\n");
10011002#endif
r249033r249034
11521153#ifdef PERFECT_INTERPOLATION_HACK
11531154   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
11541155   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1155   m_old_zpar = 0;
1156   m_old_zpar = m_old_uv_zpar = 0;
11561157#endif
11571158   m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0;
11581159   m_new_frame_pitch_idx = m_current_pitch = 0;
trunk/src/emu/sound/tms5110.h
r249033r249034
77
88#include "emu.h"
99
10/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
1011#undef PERFECT_INTERPOLATION_HACK
1112
1213/* TMS5110 commands */
r249033r249034
153154   UINT8 m_old_frame_pitch_idx;
154155   UINT8 m_old_frame_k_idx[10];
155156   UINT8 m_old_zpar;
157   UINT8 m_old_uv_zpar;
156158
157159   INT32 m_current_energy;
158160   INT32 m_current_pitch;
trunk/src/emu/sound/tms5220.c
r249033r249034
271271 * or clip logic, even though the real hardware doesn't do this, partially verified by decap */
272272#undef ALLOW_4_LSB
273273
274/* forces m_TALK active instantly whenever m_SPEN would be activated, causing speech delay to be reduced by up to one frame time */
275/* for some reason, this hack makes victory behave better, though it does not match the patent */
276#define FAST_START_HACK 1
274277
278
275279/* *****configuration of chip connection stuff***** */
276280/* 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) */
277281#define FORCE_DIGITAL 0
r249033r249034
361365   save_item(NAME(m_fifo_count));
362366   save_item(NAME(m_fifo_bits_taken));
363367
364   save_item(NAME(m_speaking_now));
365   save_item(NAME(m_speak_external));
366   save_item(NAME(m_talk_status));
368   save_item(NAME(m_previous_TALK_STATUS));
369   save_item(NAME(m_SPEN));
370   save_item(NAME(m_DDIS));
371   save_item(NAME(m_TALK));
372   save_item(NAME(m_TALKD));
367373   save_item(NAME(m_buffer_low));
368374   save_item(NAME(m_buffer_empty));
369375   save_item(NAME(m_irq_pin));
r249033r249034
384390   save_item(NAME(m_current_pitch));
385391   save_item(NAME(m_current_k));
386392
387   save_item(NAME(m_target_energy));
388   save_item(NAME(m_target_pitch));
389   save_item(NAME(m_target_k));
390
391393   save_item(NAME(m_previous_energy));
392394
393395   save_item(NAME(m_subcycle));
r249033r249034
395397   save_item(NAME(m_PC));
396398   save_item(NAME(m_IP));
397399   save_item(NAME(m_inhibit));
400   save_item(NAME(m_uv_zpar));
401   save_item(NAME(m_zpar));
402   save_item(NAME(m_pitch_zero));
398403   save_item(NAME(m_c_variant_rate));
399404   save_item(NAME(m_pitch_count));
400405
r249033r249034
465470
466471void tms5220_device::data_write(int data)
467472{
473   int old_buffer_low = m_buffer_low;
468474#ifdef DEBUG_DUMP_INPUT_DATA
469475   fprintf(stdout, "%c",data);
470476#endif
471   if (m_speak_external) // If we're in speak external mode
477   if (m_DDIS) // If we're in speak external mode
472478   {
473479      // add this byte to the FIFO
474480      if (m_fifo_count < FIFO_SIZE)
r249033r249034
477483         m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE;
478484         m_fifo_count++;
479485#ifdef DEBUG_FIFO
480         logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
486         fprintf(stderr,"data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
481487#endif
482488         update_fifo_status_and_ints();
483         if ((m_talk_status == 0) && (m_buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
489         // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12)
490         if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT
484491         {
485         int i;
492            int i;
486493#ifdef DEBUG_FIFO
487         logerror("data_write triggered talk status to go active!\n");
494            fprintf(stderr,"data_write triggered SPEN to go active!\n");
488495#endif
489            // ...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() )
490            // 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
491            m_subcycle = m_subc_reload;
492            m_PC = 0;
493            m_IP = reload_table[m_c_variant_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
496            // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() )
497            m_zpar = 1;
498            m_uv_zpar = 1; // zero k4-k10 as well
499            m_OLDE = 1; // 'silence/zpar' frames are zero energy
500            m_OLDP = 1; // 'silence/zpar' frames are zero pitch
501#ifdef PERFECT_INTERPOLATION_HACK
502            m_old_zpar = 1; // zero all the old parameters
503            m_old_uv_zpar = 1; // zero old k4-k10 as well
504#endif
505            m_SPEN = 1;
506#ifdef FAST_START_HACK
507            m_TALK = 1;
508#endif
494509            m_new_frame_energy_idx = 0;
495510            m_new_frame_pitch_idx = 0;
496511            for (i = 0; i < 4; i++)
r249033r249034
499514               m_new_frame_k_idx[i] = 0xF;
500515            for (i = 7; i < m_coeff->num_k; i++)
501516               m_new_frame_k_idx[i] = 0x7;
502            m_talk_status = m_speaking_now = 1;
517
503518         }
504519      }
505520      else
506521      {
507522#ifdef DEBUG_FIFO
508         logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
523         fprintf(stderr,"data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
509524         // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it.
510525#endif
511526      }
512527
513528
514529   }
515   else //(! m_speak_external)
530   else //(! m_DDIS)
516531      // R Nabet : we parse commands at once.  It is necessary for such commands as read.
517532      process_command(data);
518533}
r249033r249034
560575      m_buffer_low = 0;
561576
562577   /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
563   translates to having fifo_count equal to exactly 0 */
578   translates to having fifo_count equal to exactly 0
579   */
564580   if (m_fifo_count == 0)
565581   {
566582      // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
567583      if (!m_buffer_empty)
568584         set_interrupt_state(1);
569585      m_buffer_empty = 1;
586      m_TALK = m_SPEN = 0; // /BE being active clears the TALK(TCON) status which in turn clears SPEN
570587   }
571588   else
572589      m_buffer_empty = 0;
573590
574   /* TS is talk status and is set elsewhere in the fifo parser and in
575   the SPEAK command handler; however, if /BE is true during speak external
576   mode, it is immediately unset here. */
577   if ((m_speak_external == 1) && (m_buffer_empty == 1))
591   // generate an interrupt if /TS was active, and is now inactive.
592   // also, in this case, regardless if DDIS was set, unset it.
593   if (m_previous_TALK_STATUS == 1 && (TALK_STATUS == 0))
578594   {
579      // generate an interrupt: /TS was active, and is now inactive.
580      if (m_talk_status == 1)
581      {
582         m_talk_status = m_speak_external = 0;
583         set_interrupt_state(1);
584      }
595#ifdef VERBOSE
596      fprintf(stderr,"Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n");
597#endif
598      set_interrupt_state(1);
599      m_DDIS = 0;
585600   }
586   /* Note that TS being unset will also generate an interrupt when a STOP
587   frame is encountered; this is handled in the sample generator code and not here */
601   m_previous_TALK_STATUS = TALK_STATUS;
602
588603}
589604
590605/**********************************************************************************************
r249033r249034
597612{
598613   int val = 0;
599614
600   if (m_speak_external)
615   if (m_DDIS)
601616   {
602617      // extract from FIFO
603618      while (count--)
r249033r249034
643658      /* clear the interrupt pin on status read */
644659      set_interrupt_state(0);
645660#ifdef DEBUG_PIN_READS
646      logerror("Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty);
661      fprintf(stderr,"Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty);
647662#endif
648663
649      return (m_talk_status << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
664      return (TALK_STATUS << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
650665   }
651666}
652667
r249033r249034
660675int tms5220_device::ready_read()
661676{
662677#ifdef DEBUG_PIN_READS
663   logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count);
678   fprintf(stderr,"ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS);
664679#endif
665   return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready;
680   return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready;
666681}
667682
668683
r249033r249034
718733int tms5220_device::int_read()
719734{
720735#ifdef DEBUG_PIN_READS
721   logerror("int_read: irq pin read, state is %d\n", m_irq_pin);
736   fprintf(stderr,"int_read: irq pin read, state is %d\n", m_irq_pin);
722737#endif
723738   return m_irq_pin;
724739}
r249033r249034
733748void tms5220_device::process(INT16 *buffer, unsigned int size)
734749{
735750   int buf_count=0;
736   int i, bitout, zpar;
751   int i, bitout;
737752   INT32 this_sample;
738753
739   /* the following gotos are probably safe to remove */
740   /* if we're empty and still not speaking, fill with nothingness */
741   if (!m_speaking_now)
742      goto empty;
754#ifdef VERBOSE
755   fprintf(stderr,"process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
756#endif
743757
744   /* if speak external is set, but talk status is not (yet) set,
745   wait for buffer low to clear */
746   if (!m_talk_status && m_speak_external && m_buffer_low)
747      goto empty;
748
749758   /* loop until the buffer is full or we've stopped speaking */
750   while ((size > 0) && m_speaking_now)
759   while (size > 0)
751760   {
752      /* if it is the appropriate time to update the old energy/pitch indices,
753       * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
754       * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
755       * which happens 4 T-cycles later), we change on the latter.
756       * The indices are updated here ~12 PCs before the new frame is applied.
757       */
758      /** TODO: the patents 4331836, 4335277, and 4419540 disagree about the timing of this **/
759      if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2))
761      if(m_TALKD) // speaking
760762      {
761         m_OLDE = (m_new_frame_energy_idx == 0);
762         m_OLDP = (m_new_frame_pitch_idx == 0);
763      }
763         /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
764         * (In reality, the frame was really loaded incrementally during the entire IP=0
765         * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
766         */
767         if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
768         {
769            // HACK for regression testing, be sure to comment out before release!
770            //m_RNG = 0x1234;
771            // end HACK
764772
765      /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
766       * (In reality, the frame was really loaded incrementally during the entire IP=0
767       * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
768       */
769      if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
770      {
771         // HACK for regression testing, be sure to comment out before release!
772         //m_RNG = 0x1234;
773         // end HACK
773            /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
774            m_IP = reload_table[m_c_variant_rate&0x3];
774775
775         /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
776         m_IP = reload_table[m_c_variant_rate&0x3];
777
778776#ifdef PERFECT_INTERPOLATION_HACK
779         /* remember previous frame energy, pitch, and coefficients */
780         m_old_frame_energy_idx = m_new_frame_energy_idx;
781         m_old_frame_pitch_idx = m_new_frame_pitch_idx;
782         for (i = 0; i < m_coeff->num_k; i++)
783            m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
777            /* remember previous frame energy, pitch, and coefficients */
778            m_old_frame_energy_idx = m_new_frame_energy_idx;
779            m_old_frame_pitch_idx = m_new_frame_pitch_idx;
780            for (i = 0; i < m_coeff->num_k; i++)
781               m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
784782#endif
785783
786         /* if the talk status was clear last frame, halt speech now. */
787         if (m_talk_status == 0)
788         {
789#ifdef DEBUG_GENERATION
790            fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n");
791#endif
792            if (m_speaking_now == 1) // we're done, set all coeffs to idle state but keep going for a bit...
793            {
794               /**TODO: should index clearing be done here, or elsewhere? **/
795               m_new_frame_energy_idx = 0;
796               m_new_frame_pitch_idx = 0;
797               for (i = 0; i < 4; i++)
798                  m_new_frame_k_idx[i] = 0;
799               for (i = 4; i < 7; i++)
800                  m_new_frame_k_idx[i] = 0xF;
801               for (i = 7; i < m_coeff->num_k; i++)
802                  m_new_frame_k_idx[i] = 0x7;
803               m_speaking_now = 2; // wait 8 extra interp periods before shutting down so we can interpolate everything to zero state
804            }
805            else // m_speaking_now == 2 // now we're really done.
806            {
807               m_speaking_now = 0; // finally halt speech
808               goto empty;
809            }
810         }
784            /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
785            parse_frame();
811786
812
813         /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[],
814          * but only if we're not just about to end speech */
815         if (m_speaking_now == 1) parse_frame();
816#ifdef DEBUG_PARSE_FRAME_DUMP
817         fprintf(stderr,"\n");
787            // if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters
788            // NOTE: this is probably the bug the tms5100/tmc0280 has, pre-rev D, I think.
789            // GUESS: Pre-rev D versions start zeroing k5-k10 immediately upon new frame load regardless of interpolation inhibit
790            // I.e. ZPAR = /TALKD || (PC>5&&P=0)
791            // GUESS: D and later versions only start or stop zeroing k5-k10 at the IP7->IP0 transition AFTER the frame
792            // I.e. ZPAR = /TALKD || (PC>5&&OLDP)
793#ifdef PERFECT_INTERPOLATION_HACK
794            m_old_uv_zpar = m_uv_zpar;
795            m_old_zpar = m_zpar; // unset old zpar on new frame
818796#endif
797            m_zpar = 0;
798            //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110
799            m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100
819800
820         /* if the new frame is a stop frame, set an interrupt and set talk status to 0 */
821         /** TODO: investigate this later! **/
822         if (NEW_FRAME_STOP_FLAG == 1)
801            /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */
802            if (NEW_FRAME_STOP_FLAG == 1)
823803            {
824               m_talk_status = m_speak_external = 0;
825               set_interrupt_state(1);
826               update_fifo_status_and_ints();
804               m_TALK = m_SPEN = 0;
827805            }
828806
829         /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
830            Interpolation inhibit cases:
831          * Old frame was voiced, new is unvoiced
832          * Old frame was silence/zero energy, new has nonzero energy
833          * Old frame was unvoiced, new is voiced
834          * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx)
835          */
836         if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
837            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0))
838            || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0))
839            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) )
840            m_inhibit = 1;
841         else // normal frame, normal interpolation
842            m_inhibit = 0;
807            /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
808            Interpolation inhibit cases:
809            * Old frame was voiced, new is unvoiced
810            * Old frame was silence/zero energy, new has nonzero energy
811            * Old frame was unvoiced, new is voiced
812            * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx)
813            */
814            if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
815               || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0))
816               || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0))
817               || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) )
818               m_inhibit = 1;
819            else // normal frame, normal interpolation
820               m_inhibit = 0;
843821
844         /* load new frame targets from tables, using parsed indices */
845         m_target_energy = m_coeff->energytable[m_new_frame_energy_idx];
846         m_target_pitch = m_coeff->pitchtable[m_new_frame_pitch_idx];
847         zpar = NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed
848         for (i = 0; i < 4; i++)
849            m_target_k[i] = m_coeff->ktable[i][m_new_frame_k_idx[i]];
850         for (i = 4; i < m_coeff->num_k; i++)
851            m_target_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-zpar));
852
853822#ifdef DEBUG_GENERATION
854         /* Debug info for current parsed frame */
855         fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
856         fprintf(stderr,"Processing frame: ");
857         if (m_inhibit == 0)
858            fprintf(stderr, "Normal Frame\n");
859         else
860            fprintf(stderr,"Interpolation Inhibited\n");
861         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]);
862         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]);
823            /* Debug info for current parsed frame */
824            fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
825            fprintf(stderr,"Processing new frame: ");
826            if (m_inhibit == 0)
827               fprintf(stderr, "Normal Frame\n");
828            else
829               fprintf(stderr,"Interpolation Inhibited\n");
830            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]);
831            fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
832               (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)),
833               m_new_frame_energy_idx,
834               (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)),
835               (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)),
836               (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)),
837               (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)),
838               (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)),
839               (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)),
840               (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)),
841               (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)),
842               (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)),
843               (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)),
844               (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) );
863845#endif
864846
865         /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
866         if (m_talk_status == 0)
847         }
848         else // Not a new frame, just interpolate the existing frame.
867849         {
868#ifdef DEBUG_GENERATION
869            fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
850            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
851#ifdef PERFECT_INTERPOLATION_HACK
852            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
853            //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
854            int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
855            //fprintf(stderr, "CS: %03d", current_sample);
856            // reset the current energy, pitch, etc to what it was at frame start
857            m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar));
858            m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar));
859            for (i = 0; i < m_coeff->num_k; i++)
860               m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar)));
861            // now adjust each value to be exactly correct for each of the samples per frame
862            if (m_IP != 0) // if we're still interpolating...
863            {
864               m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
865               m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
866               for (i = 0; i < m_coeff->num_k; i++)
867                  m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar));
868            }
869            else // we're done, play this frame for 1/8 frame.
870            {
871               m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar));
872               m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar));
873               for (i = 0; i < m_coeff->num_k; i++)
874                  m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
875            }
876#else
877            //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
878            if (m_subcycle == 2)
879            {
880               switch(m_PC)
881               {
882                  case 0: /* PC = 0, B cycle, write updated energy */
883                  m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
884                  break;
885                  case 1: /* PC = 1, B cycle, write updated pitch */
886                  m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
887                  break;
888                  case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
889                  /* PC = 2 through 11, B cycle, write updated K1 through K10 */
890                  m_current_k[m_PC-2] = (m_current_k[m_PC-2] + (((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT))*(((m_PC-2)>4)?(1-m_uv_zpar):(1-m_zpar));
891                  break;
892                  case 12: /* PC = 12 */
893                  /* we should NEVER reach this point, PC=12 doesn't have a subcycle 2 */
894                  break;
895               }
896            }
870897#endif
871            m_target_energy = 0;
872898         }
873      }
874      else // Not a new frame, just interpolate the existing frame.
875      {
876         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
877#ifdef PERFECT_INTERPOLATION_HACK
878         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
879         //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
880         int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
881899
882         zpar = OLD_FRAME_UNVOICED_FLAG;
883         //fprintf(stderr, "CS: %03d", current_sample);
884         // reset the current energy, pitch, etc to what it was at frame start
885         m_current_energy = m_coeff->energytable[m_old_frame_energy_idx];
886         m_current_pitch = m_coeff->pitchtable[m_old_frame_pitch_idx];
887         for (i = 0; i < 4; i++)
888            m_current_k[i] = m_coeff->ktable[i][m_old_frame_k_idx[i]];
889         for (i = 4; i < m_coeff->num_k; i++)
890            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-zpar));
891         // now adjust each value to be exactly correct for each of the samples per frame
892         if (m_IP != 0) // if we're still interpolating...
900         // calculate the output
901         if (OLD_FRAME_UNVOICED_FLAG == 1)
893902         {
894            m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
895            m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
896            for (i = 0; i < m_coeff->num_k; i++)
897               m_current_k[i] += (((m_target_k[i] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
903            // generate unvoiced samples here
904            if (m_RNG & 1)
905               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)*/
906            else
907               m_excitation_data = 0x40;
898908         }
899         else // we're done, play this frame for 1/8 frame.
909         else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
900910         {
901            m_current_energy = m_target_energy;
902            m_current_pitch = m_target_pitch;
903            for (i = 0; i < m_coeff->num_k; i++)
904               m_current_k[i] = m_target_k[i];
911            // generate voiced samples here
912            /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
913            * function has a chirp/peak and then a long chain of zeroes.
914            * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
915            * and if the address reaches that point the ADDRESS incrementer is
916            * disabled, forcing all samples beyond 51d to be == 51d
917            */
918            if (m_pitch_count >= 51)
919               m_excitation_data = (INT8)m_coeff->chirptable[51];
920            else /*m_pitch_count < 51*/
921               m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
905922         }
906#else
907         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
908         if (m_subcycle == 2)
923
924         // Update LFSR *20* times every sample (once per T cycle), like patent shows
925         for (i=0; i<20; i++)
909926         {
910            switch(m_PC)
911            {
912               case 0: /* PC = 0, B cycle, write updated energy */
913               m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT);
914               break;
915               case 1: /* PC = 1, B cycle, write updated pitch */
916               m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
917               break;
918               case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
919               /* PC = 2 through 11, B cycle, write updated K1 through K10 */
920               m_current_k[m_PC-2] += (((m_target_k[m_PC-2] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT);
921               break;
922               case 12: /* PC = 12, do nothing */
923               break;
924            }
927            bitout = ((m_RNG >> 12) & 1) ^
928                  ((m_RNG >>  3) & 1) ^
929                  ((m_RNG >>  2) & 1) ^
930                  ((m_RNG >>  0) & 1);
931            m_RNG <<= 1;
932            m_RNG |= bitout;
925933         }
926#endif
927      }
928
929      // calculate the output
930      if (OLD_FRAME_UNVOICED_FLAG == 1)
931      {
932         // generate unvoiced samples here
933         if (m_RNG & 1)
934            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)*/
935         else
936            m_excitation_data = 0x40;
937      }
938      else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
939      {
940         // generate voiced samples here
941         /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
942          * function has a chirp/peak and then a long chain of zeroes.
943          * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
944          * and if the address reaches that point the ADDRESS incrementer is
945          * disabled, forcing all samples beyond 51d to be == 51d
946          */
947         if (m_pitch_count >= 51)
948            m_excitation_data = (INT8)m_coeff->chirptable[51];
949         else /*m_pitch_count < 51*/
950            m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
951      }
952
953      // Update LFSR *20* times every sample (once per T cycle), like patent shows
954   for (i=0; i<20; i++)
955   {
956      bitout = ((m_RNG >> 12) & 1) ^
957            ((m_RNG >>  3) & 1) ^
958            ((m_RNG >>  2) & 1) ^
959            ((m_RNG >>  0) & 1);
960      m_RNG <<= 1;
961      m_RNG |= bitout;
962   }
963      this_sample = lattice_filter(); /* execute lattice filter */
934         this_sample = lattice_filter(); /* execute lattice filter */
964935#ifdef DEBUG_GENERATION_VERBOSE
965      //fprintf(stderr,"C:%01d; ",m_subcycle);
966      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);
967      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
968      for (i=0; i<10; i++)
969         fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
970      fprintf(stderr,"Out:%06d", this_sample);
971      fprintf(stderr,"\n");
936         //fprintf(stderr,"C:%01d; ",m_subcycle);
937         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);
938         //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
939         for (i=0; i<10; i++)
940            fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
941         fprintf(stderr,"Out:%06d ", this_sample);
942//#ifdef PERFECT_INTERPOLATION_HACK
943//         fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar);
944//#else
945//         fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar);
946//#endif
947         fprintf(stderr,"\n");
972948#endif
973      /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
974      while (this_sample > 16383) this_sample -= 32768;
975      while (this_sample < -16384) this_sample += 32768;
976      if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
977         buffer[buf_count] = clip_analog(this_sample);
978      else // digital I/O pin output is 12 bits
979      {
949         /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
950         while (this_sample > 16383) this_sample -= 32768;
951         while (this_sample < -16384) this_sample += 32768;
952         if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
953            buffer[buf_count] = clip_analog(this_sample);
954         else // digital I/O pin output is 12 bits
955         {
980956#ifdef ALLOW_4_LSB
981         // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
982         // N taps:                       ^                 = 0x2000;
983         // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
984         buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
957            // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
958            // N taps:                       ^                 = 0x2000;
959            // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
960            buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
985961#else
986         this_sample &= ~0xF;
987         // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
988         // N taps:                       ^^ ^^^            = 0x3E00;
989         // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
990         buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
962            this_sample &= ~0xF;
963            // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
964            // N taps:                       ^^ ^^^            = 0x3E00;
965            // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
966            buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
991967#endif
992      }
993      // Update all counts
968         }
969         // Update all counts
994970
995      m_subcycle++;
996      if ((m_subcycle == 2) && (m_PC == 12))
997      {
998         /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
999          * if INHIBIT was true during the most recent frame transition.
1000          * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
1001          * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
1002          * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
1003          * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
1004          * convenient and should make no difference in output.
1005          */
1006         if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_count = 0;
1007         m_subcycle = m_subc_reload;
1008         m_PC = 0;
1009         m_IP++;
1010         m_IP&=0x7;
971         m_subcycle++;
972         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
973         {
974            /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
975            * if INHIBIT was true during the most recent frame transition.
976            * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
977            * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
978            * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
979            * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
980            * convenient and should make no difference in output.
981            */
982            if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1;
983            if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0;
984            if (m_IP == 7) // RESETL4
985            {
986               // Latch OLDE and OLDP
987               OLD_FRAME_SILENCE_FLAG = NEW_FRAME_SILENCE_FLAG; // m_OLDE
988               OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // m_OLDP
989               /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
990#ifdef DEBUG_GENERATION
991               fprintf(stderr,"RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
992#endif
993#ifdef DEBUG_GENERATION
994               if (m_TALK == 0)
995                  fprintf(stderr,"tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
996#endif
997               m_TALKD = m_TALK; // TALKD is latched from TALK
998               update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS is now inactive
999               m_TALK = m_SPEN; // TALK is latched from SPEN
1000#ifdef DEBUG_GENERATION
1001               fprintf(stderr,"RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
1002#endif
1003            }
1004            m_subcycle = m_subc_reload;
1005            m_PC = 0;
1006            m_IP++;
1007            m_IP&=0x7;
1008         }
1009         else if (m_subcycle == 3)
1010         {
1011            m_subcycle = m_subc_reload;
1012            m_PC++;
1013         }
1014         m_pitch_count++;
1015         if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0;
1016         m_pitch_count &= 0x1FF;
10111017      }
1012      else if (m_subcycle == 3)
1018      else // m_TALKD == 0
10131019      {
1014         m_subcycle = m_subc_reload;
1015         m_PC++;
1020         m_subcycle++;
1021         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
1022         {
1023            if (m_IP == 7) // RESETL4
1024            {
1025               m_TALKD = m_TALK; // TALKD is latched from TALK
1026               m_TALK = m_SPEN; // TALK is latched from SPEN
1027            }
1028            m_subcycle = m_subc_reload;
1029            m_PC = 0;
1030            m_IP++;
1031            m_IP&=0x7;
1032         }
1033         else if (m_subcycle == 3)
1034         {
1035            m_subcycle = m_subc_reload;
1036            m_PC++;
1037         }
1038         buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
10161039      }
1017      m_pitch_count++;
1018      if (m_pitch_count >= m_current_pitch) m_pitch_count = 0;
1019      m_pitch_count &= 0x1FF;
1020      buf_count++;
1021      size--;
1040   buf_count++;
1041   size--;
10221042   }
1023
1024empty:
1025
1026   while (size > 0)
1027   {
1028      m_subcycle++;
1029      if ((m_subcycle == 2) && (m_PC == 12))
1030      {
1031         m_subcycle = m_subc_reload;
1032         m_PC = 0;
1033         m_IP++;
1034         m_IP&=0x7;
1035      }
1036      else if (m_subcycle == 3)
1037      {
1038         m_subcycle = m_subc_reload;
1039         m_PC++;
1040      }
1041      buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
1042      buf_count++;
1043      size--;
1044   }
10451043}
10461044
10471045/**********************************************************************************************
r249033r249034
11821180
11831181void tms5220_device::process_command(unsigned char cmd)
11841182{
1183   int i;
11851184#ifdef DEBUG_COMMAND_DUMP
11861185      fprintf(stderr,"process_command called with parameter %02X\n",cmd);
11871186#endif
r249033r249034
11891188      switch (cmd & 0x70)
11901189      {
11911190      case 0x10 : /* read byte */
1192         if (m_talk_status == 0) /* TALKST must be clear for RDBY */
1191         if (TALK_STATUS == 0) /* TALKST must be clear for RDBY */
11931192         {
11941193            if (m_schedule_dummy_read)
11951194            {
r249033r249034
12111210      break;
12121211
12131212      case 0x30 : /* read and branch */
1214         if (m_talk_status == 0) /* TALKST must be clear for RB */
1213         if (TALK_STATUS == 0) /* TALKST must be clear for RB */
12151214         {
12161215#ifdef VERBOSE
1217            logerror("read and branch command received\n");
1216            fprintf(stderr,"read and branch command received\n");
12181217#endif
12191218            m_RDB_flag = FALSE;
12201219            if (m_speechrom)
r249033r249034
12231222         break;
12241223
12251224      case 0x40 : /* load address */
1226         if (m_talk_status == 0) /* TALKST must be clear for LA */
1225         if (TALK_STATUS == 0) /* TALKST must be clear for LA */
12271226         {
12281227            /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
12291228               This code does not care about this. */
r249033r249034
12401239            if (m_speechrom)
12411240               m_speechrom->read(1);
12421241         }
1243         m_speaking_now = 1;
1244         m_speak_external = 0;
1245         m_talk_status = 1;  /* start immediately */
1246         /* clear out variables before speaking */
1247         // TODO: similar to the victory case described above, but for VSM speech
1248         m_subcycle = m_subc_reload;
1249         m_PC = 0;
1250         m_IP = reload_table[m_c_variant_rate&0x3];
1242         m_SPEN = 1;
1243#ifdef FAST_START_HACK
1244         m_TALK = 1;
1245#endif
1246         m_DDIS = 0;
1247         m_zpar = 1; // zero all the parameters
1248         m_uv_zpar = 1; // zero k4-k10 as well
1249         m_OLDE = 1; // 'silence/zpar' frames are zero energy
1250         m_OLDP = 1; // 'silence/zpar' frames are zero pitch
1251#ifdef PERFECT_INTERPOLATION_HACK
1252         m_old_zpar = 1; // zero all the old parameters
1253         m_old_uv_zpar = 1; // zero old k4-k10 as well
1254#endif
1255         // following is semi-hack but matches idle state observed on chip
12511256         m_new_frame_energy_idx = 0;
12521257         m_new_frame_pitch_idx = 0;
1253         int i;
12541258         for (i = 0; i < 4; i++)
12551259            m_new_frame_k_idx[i] = 0;
12561260         for (i = 4; i < 7; i++)
r249033r249034
12601264         break;
12611265
12621266      case 0x60 : /* speak external */
1263         //SPKEXT going active activates SPKEE which clears the fifo
1267         // SPKEXT going active activates SPKEE which clears the fifo
12641268         m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0;
1265         m_speak_external = 1;
1269         // SPEN is enabled when the fifo passes half full (falling edge of BL signal)
1270         m_DDIS = 1;
1271         m_zpar = 1; // zero all the parameters
1272         m_uv_zpar = 1; // zero k4-k10 as well
1273         m_OLDE = 1; // 'silence/zpar' frames are zero energy
1274         m_OLDP = 1; // 'silence/zpar' frames are zero pitch
1275#ifdef PERFECT_INTERPOLATION_HACK
1276         m_old_zpar = 1; // zero all the old parameters
1277         m_old_uv_zpar = 1; // zero old k4-k10 as well
1278#endif
1279         // following is semi-hack but matches idle state observed on chip
1280         m_new_frame_energy_idx = 0;
1281         m_new_frame_pitch_idx = 0;
1282         for (i = 0; i < 4; i++)
1283            m_new_frame_k_idx[i] = 0;
1284         for (i = 4; i < 7; i++)
1285            m_new_frame_k_idx[i] = 0xF;
1286         for (i = 7; i < m_coeff->num_k; i++)
1287            m_new_frame_k_idx[i] = 0x7;
12661288         m_RDB_flag = FALSE;
12671289         break;
12681290
r249033r249034
13081330   m_IP = reload_table[m_c_variant_rate&0x3];
13091331
13101332   update_fifo_status_and_ints();
1311   if (!m_talk_status) goto ranout;
1333   if (m_DDIS && m_buffer_empty) goto ranout;
13121334
13131335   // attempt to extract the energy index
13141336   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
r249033r249034
13171339   fprintf(stderr," ");
13181340#endif
13191341   update_fifo_status_and_ints();
1320   if (!m_talk_status) goto ranout;
1342   if (m_DDIS && m_buffer_empty) goto ranout;
13211343   // if the energy index is 0 or 15, we're done
13221344   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
13231345      return;
r249033r249034
13371359   fprintf(stderr," ");
13381360#endif
13391361   update_fifo_status_and_ints();
1340   if (!m_talk_status) goto ranout;
1362   if (m_DDIS && m_buffer_empty) goto ranout;
13411363   // if this is a repeat frame, just do nothing, it will reuse the old coefficients
13421364   if (rep_flag)
13431365      return;
r249033r249034
13511373      fprintf(stderr," ");
13521374#endif
13531375      update_fifo_status_and_ints();
1354      if (!m_talk_status) goto ranout;
1376      if (m_DDIS && m_buffer_empty) goto ranout;
13551377   }
13561378
13571379   // if the pitch index was zero, we only need 4 K's...
r249033r249034
13701392      fprintf(stderr," ");
13711393#endif
13721394      update_fifo_status_and_ints();
1373      if (!m_talk_status) goto ranout;
1395      if (m_DDIS && m_buffer_empty) goto ranout;
13741396   }
1397#ifdef DEBUG_PARSE_FRAME_DUMP
1398         fprintf(stderr,"\n");
1399#endif
13751400#ifdef VERBOSE
1376   if (m_speak_external)
1377      logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
1401   if (m_DDIS)
1402      fprintf(stderr,"Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
13781403   else
1379      logerror("Parsed a frame successfully in ROM\n");
1404      fprintf(stderr,"Parsed a frame successfully in ROM\n");
13801405#endif
13811406   return;
13821407
13831408   ranout:
13841409#ifdef DEBUG_FRAME_ERRORS
1385   logerror("Ran out of bits on a parse!\n");
1410   fprintf(stderr,"Ran out of bits on a parse!\n");
13861411#endif
13871412   return;
13881413}
r249033r249034
13971422{
13981423   if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin
13991424#ifdef DEBUG_PIN_READS
1400   logerror("irq pin set to state %d\n", state);
1425   fprintf(stderr,"irq pin set to state %d\n", state);
14011426#endif
14021427   if (!m_irq_handler.isnull() && state != m_irq_pin)
14031428      m_irq_handler(!state);
r249033r249034
14141439{
14151440   int state = ready_read();
14161441#ifdef DEBUG_PIN_READS
1417   logerror("ready pin set to state %d\n", state);
1442   fprintf(stderr,"ready pin set to state %d\n", state);
14181443#endif
14191444   if (!m_readyq_handler.isnull() && state != m_ready_pin)
14201445      m_readyq_handler(!state);
r249033r249034
15141539
15151540   /* initialize the chip state */
15161541   /* 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 */
1517   m_speaking_now = m_speak_external = m_talk_status = m_irq_pin = m_ready_pin = 0;
1542   m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0;
15181543   set_interrupt_state(0);
15191544   update_ready_state();
15201545   m_buffer_empty = m_buffer_low = 1;
r249033r249034
15251550#ifdef PERFECT_INTERPOLATION_HACK
15261551   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
15271552   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1553   m_old_zpar = 0;
15281554#endif
1529   m_new_frame_energy_idx = m_current_energy = m_target_energy = m_previous_energy = 0;
1530   m_new_frame_pitch_idx = m_current_pitch = m_target_pitch = 0;
1555   m_new_frame_energy_idx = m_current_energy =  m_previous_energy = 0;
1556   m_new_frame_pitch_idx = m_current_pitch = 0;
1557   m_zpar = m_uv_zpar = 0;
15311558   memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx));
15321559   memset(m_current_k, 0, sizeof(m_current_k));
1533   memset(m_target_k, 0, sizeof(m_target_k));
15341560
15351561   /* initialize the sample generators */
15361562   m_inhibit = 1;
r249033r249034
15741600            /* Write */
15751601            /* bring up to date first */
15761602#ifdef DEBUG_IO_READY
1577            logerror("Serviced write: %02x\n", m_write_latch);
1603            fprintf(stderr,"Serviced write: %02x\n", m_write_latch);
15781604            //fprintf(stderr, "Processed write data: %02X\n", m_write_latch);
15791605#endif
15801606            m_stream->update();
r249033r249034
16101636   m_true_timing = 1;
16111637   state &= 0x01;
16121638#ifdef DEBUG_RS_WS
1613   logerror("/RS written with data: %d\n", state);
1639   fprintf(stderr,"/RS written with data: %d\n", state);
16141640#endif
16151641   new_val = (m_rs_ws & 0x01) | (state<<1);
16161642   if (new_val != m_rs_ws)
r249033r249034
16231649#ifdef DEBUG_RS_WS
16241650         else
16251651            /* illegal */
1626            logerror("tms5220_rs_w: illegal\n");
1652            fprintf(stderr,"tms5220_rs_w: illegal\n");
16271653#endif
16281654         return;
16291655      }
r249033r249034
16411667      {
16421668         /* high to low - schedule ready cycle */
16431669#ifdef DEBUG_RS_WS
1644         logerror("Scheduling ready cycle for /RS...\n");
1670         fprintf(stderr,"Scheduling ready cycle for /RS...\n");
16451671#endif
16461672         /* 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. */
16471673         m_io_ready = 0;
r249033r249034
16621688   m_true_timing = 1;
16631689   state &= 0x01;
16641690#ifdef DEBUG_RS_WS
1665   logerror("/WS written with data: %d\n", state);
1691   fprintf(stderr,"/WS written with data: %d\n", state);
16661692#endif
16671693   new_val = (m_rs_ws & 0x02) | (state<<0);
16681694   if (new_val != m_rs_ws)
r249033r249034
16751701#ifdef DEBUG_RS_WS
16761702         else
16771703            /* illegal */
1678            logerror("tms5220_ws_w: illegal\n");
1704            fprintf(stderr,"tms5220_ws_w: illegal\n");
16791705#endif
16801706         return;
16811707      }
r249033r249034
16931719      {
16941720         /* high to low - schedule ready cycle */
16951721#ifdef DEBUG_RS_WS
1696         logerror("Scheduling ready cycle for /WS...\n");
1722         fprintf(stderr,"Scheduling ready cycle for /WS...\n");
16971723#endif
16981724         /* 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. */
16991725         m_io_ready = 0;
r249033r249034
17261752   if (space.debugger_access()) return;
17271753
17281754#ifdef DEBUG_RS_WS
1729   logerror("tms5220_data_w: data %02x\n", data);
1755   fprintf(stderr,"tms5220_data_w: data %02x\n", data);
17301756#endif
17311757   if (!m_true_timing)
17321758   {
r249033r249034
17391765      /* actually in a write ? */
17401766#ifdef DEBUG_RS_WS
17411767      if (!(m_rs_ws == 0x02))
1742         logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
1768         fprintf(stderr,"tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
17431769#endif
17441770      m_write_latch = data;
17451771   }
r249033r249034
17711797         return m_read_latch;
17721798#ifdef DEBUG_RS_WS
17731799      else
1774         logerror("tms5220_status_r: data read outside rs!\n");
1800         fprintf(stderr,"tms5220_status_r: data read outside rs!\n");
17751801#endif
17761802      return 0xff;
17771803   }
trunk/src/emu/sound/tms5220.h
r249033r249034
105105
106106
107107   /* these contain global status bits */
108   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.*/
109   UINT8 m_speak_external;   /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
110   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. */
108   UINT8 m_previous_TALK_STATUS;      /* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */
109   UINT8 m_SPEN;             /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */
110   UINT8 m_DDIS;             /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
111   UINT8 m_TALK;             /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */
112#define TALK_STATUS (m_SPEN|m_TALKD)
113   UINT8 m_TALKD;            /* TALK(TCON) value, latched every RESETL4 */
111114   UINT8 m_buffer_low;       /* If 1, FIFO has less than 8 bytes in it */
112115   UINT8 m_buffer_empty;     /* If 1, FIFO is empty */
113116   UINT8 m_irq_pin;          /* state of the IRQ pin (output) */
r249033r249034
132135   INT16 m_current_energy;
133136   INT16 m_current_pitch;
134137   INT16 m_current_k[10];
135
136   INT16 m_target_energy;
137   INT16 m_target_pitch;
138   INT16 m_target_k[10];
139138#else
140139   UINT8 m_old_frame_energy_idx;
141140   UINT8 m_old_frame_pitch_idx;
142141   UINT8 m_old_frame_k_idx[10];
142   UINT8 m_old_zpar;
143   UINT8 m_old_uv_zpar;
143144
144145   INT32 m_current_energy;
145146   INT32 m_current_pitch;
146147   INT32 m_current_k[10];
147
148   INT32 m_target_energy;
149   INT32 m_target_pitch;
150   INT32 m_target_k[10];
151148#endif
152149
153150   UINT16 m_previous_energy; /* needed for lattice filter to match patent */
r249033r249034
155152   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 */
156153   UINT8 m_subc_reload;      /* contains 1 for normal speech, 0 when SPKSLOW is active */
157154   UINT8 m_PC;               /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
158   /* 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 */
155   /* NOTE: the interpolation period counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
159156   UINT8 m_IP;               /* the current interpolation period */
160157   UINT8 m_inhibit;          /* If 1, interpolation is inhibited until the DIV1 period */
158   UINT8 m_uv_zpar;          /* If 1, zero k5 thru k10 coefficients */
159   UINT8 m_zpar;             /* If 1, zero ALL parameters. */
160   UINT8 m_pitch_zero;       /* circuit 412; pitch is forced to zero under certain circumstances */
161161   UINT8 m_c_variant_rate;    /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
162162   UINT16 m_pitch_count;     /* pitch counter; provides chirp rom address */
163163
164164   INT32 m_u[11];
165165   INT32 m_x[10];
166166
167   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
167   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 TODO: no it isn't */
168168   INT16 m_excitation_data;
169169
170170   /* R Nabet : These have been added to emulate speech Roms */
trunk/src/mame/arcade.lst
r249033r249034
82208220nbajamte3       // (c) 1994 Midway
82218221nbajamten       // (c) 1995 Midway
82228222revx            // (c) 1994 Midway
8223revxp5          // (c) 1994 Midway
82238224mk3             // (c) 1994 Midway
82248225mk3r20          // (c) 1994 Midway
82258226mk3r10          // (c) 1994 Midway
trunk/src/mame/drivers/fcrash.c
r249033r249034
29582958
29592959GAME( 1992, sf2b,      sf2,      sf2b,      sf2mdt,   cps_state, sf2b,     ROT0,   "bootleg", "Street Fighter II: The World Warrior (bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) //910204 - based on World version
29602960
2961GAME( 1992, sf2m9,     sf2ce,    sf2m1,     sf2,      cps_state, dinopic,  ROT0,   "bootleg", "Street Fighter II': Champion Edition (M9, bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 920313 ETC
2961GAME( 1992, sf2m9,     sf2ce,    sf2m1,     sf2,      cps_state, sf2m1,    ROT0,   "bootleg", "Street Fighter II': Champion Edition (M9, bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 920313 ETC
29622962
29632963GAME( 1993, slampic,   slammast, slampic,   slammast, cps_state, dinopic,  ROT0,   "bootleg", "Saturday Night Slam Masters (bootleg with PIC16c57)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // 930713 ETC
29642964
trunk/src/mame/drivers/midxunit.c
r249033r249034
345345   ROM_LOAD( "a-17721.u955", 0x200, 0x117, CRC(033fe902) SHA1(6efb4e519ed3c9d49fff046a679762b506b3a75b) )
346346ROM_END
347347
348ROM_START( revxp5 )
349   ROM_REGION16_LE( 0x1000000, "dcs", ROMREGION_ERASEFF )  /* sound data */
350   ROM_LOAD16_BYTE( "revx_snd.2", 0x000000, 0x80000, CRC(4ed9e803) SHA1(ba50f1beb9f2a2cf5110897209b5e9a2951ff165) )
351   ROM_LOAD16_BYTE( "revx_snd.3", 0x200000, 0x80000, CRC(af8f253b) SHA1(25a0000cab177378070f7a6e3c7378fe87fad63e) )
352   ROM_LOAD16_BYTE( "revx_snd.4", 0x400000, 0x80000, CRC(3ccce59c) SHA1(e81a31d64c64e7b1d25f178c53da3d68453c203c) )
353   ROM_LOAD16_BYTE( "revx_snd.5", 0x600000, 0x80000, CRC(a0438006) SHA1(560d216d21cb8073dbee0fd20ebe589932a9144e) )
354   ROM_LOAD16_BYTE( "revx_snd.6", 0x800000, 0x80000, CRC(b7b34f60) SHA1(3b9682c6a00fa3bdb47e69d8e8ceccc244ee55b5) )
355   ROM_LOAD16_BYTE( "revx_snd.7", 0xa00000, 0x80000, CRC(6795fd88) SHA1(7c3790730a8b99b63112c851318b1c7e4989e5e0) )
356   ROM_LOAD16_BYTE( "revx_snd.8", 0xc00000, 0x80000, CRC(793a7eb5) SHA1(4b1f81b68f95cedf1b356ef362d1eb37acc74b16) )
357   ROM_LOAD16_BYTE( "revx_snd.9", 0xe00000, 0x80000, CRC(14ddbea1) SHA1(8dba9dc5529ea77c4312ea61f825bf9062ffc6c3) )
348358
359   ROM_REGION16_LE( 0x200000, "maincpu", 0 )   /* 34020 code */
360   ROM_LOAD32_BYTE( "revx_p5.51",  0x00000, 0x80000, CRC(f3877eee) SHA1(7a4fdce36edddd35308c107c992ce626a2c9eb8c) )
361   ROM_LOAD32_BYTE( "revx_p5.52",  0x00001, 0x80000, CRC(199a54d8) SHA1(45319437e11176d4926c00c95c372098203a32a3) )
362   ROM_LOAD32_BYTE( "revx_p5.53",  0x00002, 0x80000, CRC(fcfcf72a) SHA1(b471afb416e3d348b046b0b40f497d27b0afa470) )
363   ROM_LOAD32_BYTE( "revx_p5.54",  0x00003, 0x80000, CRC(fd684c31) SHA1(db3453792e4d9fc375297d030f0b3f9cc3cad925) )
349364
365   ROM_REGION( 0x2000, "pic", 0 )
366   ROM_LOAD( "revx_16c57.bin", 0x0000000, 0x2000, CRC(eb8a8649) SHA1(a1e1d0b7a5e9802e8f889eb7e719259656dc8133) )
367
368   ROM_REGION( 0x1000000, "gfxrom", 0 )
369   ROM_LOAD32_BYTE( "revx.120", 0x0000000, 0x80000, CRC(523af1f0) SHA1(a67c0fd757e860fc1c1236945952a295b4d5df5a) )
370   ROM_LOAD32_BYTE( "revx.121", 0x0000001, 0x80000, CRC(78201d93) SHA1(fb0b8f887eec433f7624f387d7fb6f633ea30d7c) )
371   ROM_LOAD32_BYTE( "revx.122", 0x0000002, 0x80000, CRC(2cf36144) SHA1(22ed0eefa2c7c836811fac5f717c3f38254eabc2) )
372   ROM_LOAD32_BYTE( "revx.123", 0x0000003, 0x80000, CRC(6912e1fb) SHA1(416f0de711d80e9182ede524c568c5095b1bec61) )
373
374   ROM_LOAD32_BYTE( "revx.110", 0x0200000, 0x80000, CRC(e3f7f0af) SHA1(5877d9f488b0f4362a9482007c3ff7f4589a036f) )
375   ROM_LOAD32_BYTE( "revx.111", 0x0200001, 0x80000, CRC(49fe1a69) SHA1(9ae54b461f0524c034fbcb6fcd3fd5ccb5d7265a) )
376   ROM_LOAD32_BYTE( "revx.112", 0x0200002, 0x80000, CRC(7e3ba175) SHA1(dd2fe90988b544f67dbe6151282fd80d49631388) )
377   ROM_LOAD32_BYTE( "revx.113", 0x0200003, 0x80000, CRC(c0817583) SHA1(2f866e5888e212b245984344950d0e1fb8957a73) )
378
379   ROM_LOAD32_BYTE( "revx.101", 0x0400000, 0x80000, CRC(5a08272a) SHA1(17da3c9d71114f5fdbf50281a942be3da3b6f564) )
380   ROM_LOAD32_BYTE( "revx.102", 0x0400001, 0x80000, CRC(11d567d2) SHA1(7ebe6fd39a0335e1fdda150d2dc86c3eaab17b2e) )
381   ROM_LOAD32_BYTE( "revx.103", 0x0400002, 0x80000, CRC(d338e63b) SHA1(0a038217542667b3a01ecbcad824ee18c084f293) )
382   ROM_LOAD32_BYTE( "revx.104", 0x0400003, 0x80000, CRC(f7b701ee) SHA1(0fc5886e5857326bee7272d5d482a878cbcea83c) )
383
384   ROM_LOAD32_BYTE( "revx.91",  0x0600000, 0x80000, CRC(52a63713) SHA1(dcc0ff3596bd5d273a8d4fd33b0b9b9d588d8354) )
385   ROM_LOAD32_BYTE( "revx.92",  0x0600001, 0x80000, CRC(fae3621b) SHA1(715d41ea789c0c724baa5bd90f6f0f06b9cb1c64) )
386   ROM_LOAD32_BYTE( "revx.93",  0x0600002, 0x80000, CRC(7065cf95) SHA1(6c5888da099e51c4b1c592721c5027c899cf52e3) )
387   ROM_LOAD32_BYTE( "revx.94",  0x0600003, 0x80000, CRC(600d5b98) SHA1(6aef98c91f87390c0759fe71a272a3ccadd71066) )
388
389   ROM_LOAD32_BYTE( "revx.81",  0x0800000, 0x80000, CRC(729eacb1) SHA1(d130162ae22b99c84abfbe014c4e23e20afb757f) )
390   ROM_LOAD32_BYTE( "revx.82",  0x0800001, 0x80000, CRC(19acb904) SHA1(516059b516bc5b1669c9eb085e0cdcdee520dff0) )
391   ROM_LOAD32_BYTE( "revx.83",  0x0800002, 0x80000, CRC(0e223456) SHA1(1eedbd667f4a214533d1c22ca5312ecf2d4a3ab4) )
392   ROM_LOAD32_BYTE( "revx.84",  0x0800003, 0x80000, CRC(d3de0192) SHA1(2d22c5bac07a7411f326691167c7c70eba4b371f) )
393
394   ROM_LOAD32_BYTE( "revx.71",  0x0a00000, 0x80000, CRC(2b29fddb) SHA1(57b71e5c18b56bf58216e690fdefa6d30d88d34a) )
395   ROM_LOAD32_BYTE( "revx.72",  0x0a00001, 0x80000, CRC(2680281b) SHA1(d1ae0701d20166a00d8733d9d12246c140a5fb96) )
396   ROM_LOAD32_BYTE( "revx.73",  0x0a00002, 0x80000, CRC(420bde4d) SHA1(0f010cdeddb59631a5420dddfc142c50c2a1e65a) )
397   ROM_LOAD32_BYTE( "revx.74",  0x0a00003, 0x80000, CRC(26627410) SHA1(a612121554549afff5c8e8c54774ca7b0220eda8) )
398
399   ROM_LOAD32_BYTE( "revx.63",  0x0c00000, 0x80000, CRC(3066e3f3) SHA1(25548923db111bd6c6cff44bfb63cb9eb2ef0b53) )
400   ROM_LOAD32_BYTE( "revx.64",  0x0c00001, 0x80000, CRC(c33f5309) SHA1(6bb333f563ea66c4c862ffd5fb91fb5e1b919fe8) )
401   ROM_LOAD32_BYTE( "revx.65",  0x0c00002, 0x80000, CRC(6eee3e71) SHA1(0ef22732e0e2bb5207559decd43f90d1e338ad7b) )
402   ROM_LOAD32_BYTE( "revx.66",  0x0c00003, 0x80000, CRC(b43d6fff) SHA1(87584e7aeea9d52a43023d40c359591ff6342e84) )
403   
404   ROM_LOAD32_BYTE( "revx_p5.51",  0xe00000, 0x80000, CRC(f3877eee) SHA1(7a4fdce36edddd35308c107c992ce626a2c9eb8c) )
405   ROM_LOAD32_BYTE( "revx_p5.52",  0xe00001, 0x80000, CRC(199a54d8) SHA1(45319437e11176d4926c00c95c372098203a32a3) )
406   ROM_LOAD32_BYTE( "revx_p5.53",  0xe00002, 0x80000, CRC(fcfcf72a) SHA1(b471afb416e3d348b046b0b40f497d27b0afa470) )
407   ROM_LOAD32_BYTE( "revx_p5.54",  0xe00003, 0x80000, CRC(fd684c31) SHA1(db3453792e4d9fc375297d030f0b3f9cc3cad925) )
408
409   ROM_REGION( 0x400, "plds", 0 )
410   ROM_LOAD( "a-17722.u1",   0x000, 0x117, CRC(054de7a3) SHA1(bb7abaec50ed704c03b44d5d54296898f7c80d38) )
411   ROM_LOAD( "a-17721.u955", 0x200, 0x117, CRC(033fe902) SHA1(6efb4e519ed3c9d49fff046a679762b506b3a75b) )
412ROM_END
413
414
415
350416/*************************************
351417 *
352418 *  Game drivers
353419 *
354420 *************************************/
355421
356GAME( 1994, revx,   0,         midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (Rev. 1.0 6/16/94)", MACHINE_SUPPORTS_SAVE )
422GAME( 1994, revx,     0,    midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (rev 1.0 6/16/94)", MACHINE_SUPPORTS_SAVE )
423GAME( 1994, revxp5,   revx, midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (prototype, rev 5.0 5/23/94)", MACHINE_SUPPORTS_SAVE )
trunk/src/mame/drivers/namcofl.c
r249033r249034
610610   MCFG_VIDEO_START_OVERRIDE(namcofl_state,namcofl)
611611
612612   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
613   MCFG_C352_ADD("c352", 48384000/2, C352_DIVIDER_288)
613   MCFG_C352_ADD("c352", 48384000/2, 288)
614614   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
615615   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
616616   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namconb1.c
r249033r249034
11261126   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb1)
11271127
11281128   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_288)
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
11301130   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
11311131   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
11321132   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249033r249034
11631163   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb2)
11641164
11651165   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_288)
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
11671167   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
11681168   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
11691169   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcond1.c
r249033r249034
307307   /* sound hardware */
308308   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
309309
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, C352_DIVIDER_288)
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, 288)
311311   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
312312   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
313313   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos11.c
r249033r249034
571571
572572   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
573573
574   MCFG_C352_ADD("c352", 20013200, C352_DIVIDER_228)
574   MCFG_C352_ADD("c352", 20013200, 228)
575575   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
576576   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
577577   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos12.c
r249033r249034
16221622   /* sound hardware */
16231623   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
16241624
1625   MCFG_C352_ADD("c352", 29168000, C352_DIVIDER_332)
1625   MCFG_C352_ADD("c352", 29168000, 332)
16261626   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
16271627   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
16281628   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos22.c
r249033r249034
37813781   /* sound hardware */
37823782   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
37833783
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_288)
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
37853785   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
37863786   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
37873787   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249033r249034
38303830   /* sound hardware */
38313831   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
38323832
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_288)
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
38343834   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
38353835   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
38363836   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos23.c
r249033r249034
12471247#define JVSCLOCK    (XTAL_14_7456MHz)
12481248#define H8CLOCK     (16737350)      /* from 2061 */
12491249#define BUSCLOCK    (16737350*2)    /* 33MHz CPU bus clock / input */
1250#define C352CLOCK   (25992000)  /* measured at 25.992MHz from 2061 pin 9 (System 12 uses a divider of 332) */
1250#define C352CLOCK   (25992000)  /* measured at 25.992MHz from 2061 pin 9  */
1251#define C352DIV      (296)
12511252#define VSYNC1      (59.8824)
12521253#define VSYNC2      (59.915)
12531254#define HSYNC       (16666150)
r249033r249034
33203321   /* sound hardware */
33213322   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33223323
3323   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
3324   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
33243325   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33253326   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33263327   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249033r249034
33893390   /* sound hardware */
33903391   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33913392
3392   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
3393   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
33933394   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33943395   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33953396   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249033r249034
34693470   /* sound hardware */
34703471   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
34713472
3472   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
3473   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
34733474   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
34743475   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
34753476   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/quantum.c
r249033r249034
334334   /* AVG PROM */
335335   ROM_REGION( 0x100, "user1", 0 )
336336   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
337
338   ROM_REGION( 0x200, "plds", 0 )
339   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
337340ROM_END
338341
339342
r249033r249034
352355   /* AVG PROM */
353356   ROM_REGION( 0x100, "user1", 0 )
354357   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
358
359   ROM_REGION( 0x200, "plds", 0 )
360   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
355361ROM_END
356362
357363
r249033r249034
370376   /* AVG PROM */
371377   ROM_REGION( 0x100, "user1", 0 )
372378   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
379
380   ROM_REGION( 0x200, "plds", 0 )
381   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
373382ROM_END
374383
375384
trunk/src/mame/includes/chihiro.h
r249033r249034
185185      memset(pfifo, 0, sizeof(pfifo));
186186      memset(pcrtc, 0, sizeof(pcrtc));
187187      memset(pmc, 0, sizeof(pmc));
188      memset(pgraph, 0, sizeof(pgraph));
188189      memset(ramin, 0, sizeof(ramin));
189190      computedilated();
190191      objectdata = &(object_data_alloc());
r249033r249034
194195      enabled_vertex_attributes = 0;
195196      indexesleft_count = 0;
196197      vertex_pipeline = 4;
198      color_mask = 0xffffffff;
197199      alpha_test_enabled = false;
198200      alpha_reference = 0;
199201      alpha_func = nv2a_renderer::ALWAYS;
r249033r249034
238240   }
239241   DECLARE_READ32_MEMBER(geforce_r);
240242   DECLARE_WRITE32_MEMBER(geforce_w);
241   bool vblank_callback(screen_device &screen, bool state);
243   void vblank_callback(screen_device &screen, bool state);
242244   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
245   bool update_interrupts();
246   void set_interrupt_device(pic8259_device *device);
243247
244248   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
245249   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
r249033r249034
303307   UINT32 pfifo[0x2000 / 4];
304308   UINT32 pcrtc[0x1000 / 4];
305309   UINT32 pmc[0x1000 / 4];
310   UINT32 pgraph[0x2000 / 4];
306311   UINT32 ramin[0x100000 / 4];
307312   UINT32 dma_offset[2];
308313   UINT32 dma_size[2];
309314   UINT8 *basemempointer;
315   pic8259_device *interruptdevice;
310316   rectangle limits_rendertarget;
311317   UINT32 pitch_rendertarget;
312318   UINT32 pitch_depthbuffer;
r249033r249034
441447      int used;
442448      osd_lock *lock;
443449   } combiner;
450   UINT32 color_mask;
444451   bool alpha_test_enabled;
445452   int alpha_func;
446453   int alpha_reference;
trunk/src/mame/machine/xbox.c
r249033r249034
465465
466466void xbox_base_state::vblank_callback(screen_device &screen, bool state)
467467{
468   if (nvidia_nv2a->vblank_callback(screen, state))
469      xbox_base_devs.pic8259_1->ir3_w(1); // IRQ 3
470   else
471      xbox_base_devs.pic8259_1->ir3_w(0); // IRQ 3
468   nvidia_nv2a->vblank_callback(screen, state);
472469}
473470
474471UINT32 xbox_base_state::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
r249033r249034
14601457   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
14611458      debug_console_register_command(machine(), "xbox", CMDFLAG_NONE, 0, 1, 4, xbox_debug_commands);
14621459   memset(&ohcist, 0, sizeof(ohcist));
1460   // PIC challenge handshake data
1461   pic16lc_buffer[0x1c] = 0x0c;
1462   pic16lc_buffer[0x1d] = 0x0d;
1463   pic16lc_buffer[0x1e] = 0x0e;
1464   pic16lc_buffer[0x1f] = 0x0f;
14631465#ifdef USB_ENABLED
14641466   ohcist.hc_regs[HcRevision] = 0x10;
14651467   ohcist.hc_regs[HcFmInterval] = 0x2edf;
r249033r249034
14831485   save_item(NAME(smbusst.rw));
14841486   save_item(NAME(smbusst.words));
14851487   save_item(NAME(pic16lc_buffer));
1488   nvidia_nv2a->set_interrupt_device(xbox_base_devs.pic8259_1);
14861489   nvidia_nv2a->start(&m_maincpu->space());
14871490   nvidia_nv2a->savestate_items();
14881491}
trunk/src/mame/video/chihiro.c
r249033r249034
33#include "emu.h"
44#include "video/poly.h"
55#include "bitmap.h"
6#include "machine/pic8259.h"
67#include "includes/chihiro.h"
78
89//#define LOG_NV2A
r249033r249034
945946UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
946947{
947948   UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
948   UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ?
949   UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain
949950   UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
950951   UINT32 w;
951952
952   if (ramin[e / 4] != handle)
953      e = 0;
953   if (ramin[e / 4] != handle) {
954      // this should never happen
955      for (UINT32 aa = o / 4; aa < (sizeof(ramin) / 4); aa = aa + 2) {
956         if (ramin[aa] == handle) {
957            e = aa * 4;
958         }
959      }
960   }
954961   w = ramin[e / 4 + 1];
955   return (w & 0xffff) * 0x10;
962   return (w & 0xffff) * 0x10; // 0xffff is not certain
956963}
957964
958965void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
r249033r249034
12461253      addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
12471254   else // type_rendertarget == LINEAR*/
12481255      addr = rendertarget + (pitch_rendertarget / 4)*y + x;
1249   fbcolor = *addr;
1256   fbcolor = 0;
1257   if (color_mask != 0)
1258      fbcolor = *addr;
12501259   daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
12511260   deptsten = *daddr;
12521261   c[3] = color >> 24;
r249033r249034
17721781            break;
17731782      }
17741783   }
1775   fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1776   *addr = fbcolor;
1784   if (color_mask != 0) {
1785      UINT32 fbcolor_tmp;
1786
1787      fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1788      *addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask);
1789   }
17771790   if (depth_write_enabled)
17781791      dep = depth;
17791792   deptsten = (dep << 8) | sten;
r249033r249034
22332246   maddress = method * 4;
22342247   data = space.read_dword(address);
22352248   channel[chanel][subchannel].object.method[method] = data;
2249#ifdef LOG_NV2A
2250   printf("A:%08X MTHD:%08X D:%08X\n\r",address,maddress,data);
2251#endif
22362252   if (maddress == 0x17fc) {
22372253      indexesleft_count = 0;
22382254      indexesleft_first = 0;
r249033r249034
22702286         }
22712287         wait();
22722288      }
2289      else if (type == nv2a_renderer::TRIANGLE_FAN) {
2290         vertex_nv vert[3];
2291         vertex_t xy[3];
2292
2293         read_vertices_0x1810(space, vert, offset, 2);
2294         convert_vertices_poly(vert, xy, 2);
2295         count = count - 2;
2296         offset = offset + 2;
2297         for (n = 0; n <= count; n++) {
2298            read_vertices_0x1810(space, vert + (((n + 1) & 1) + 1), offset + n, 1);
2299            convert_vertices_poly(vert + (((n + 1) & 1) + 1), xy + (((n + 1) & 1) + 1), 1);
2300            render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~(n + 1) & 1) + 1], xy[((n + 1) & 1) + 1]);
2301         }
2302         wait();
2303      }
22732304      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
22742305         vertex_nv vert[4];
22752306         vertex_t xy[4];
r249033r249034
23112342      // each dword after 1800 contains two 16 bit index values to select the vartices
23122343      // each dword after 1808 contains a 32 bit index value to select the vartices
23132344      type = channel[chanel][subchannel].object.method[0x17fc / 4];
2314#ifdef LOG_NV2A
2315      printf("vertex %d %d %d\n\r", type, offset, count);
2316#endif
23172345      if (type == nv2a_renderer::QUADS) {
23182346         while (1) {
23192347            vertex_nv vert[4];
r249033r249034
23322360            render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
23332361         }
23342362      }
2363      else if (type == nv2a_renderer::TRIANGLE_FAN) {
2364         if ((countlen * mult + indexesleft_count) >= 3) {
2365            vertex_nv vert[3];
2366            vertex_t xy[3];
2367            int c, count;
2368
2369            if (mult == 1)
2370               c = read_vertices_0x1808(space, vert, address, 2);
2371            else
2372               c = read_vertices_0x1800(space, vert, address, 2);
2373            convert_vertices_poly(vert, xy, 2);
2374            address = address + c * 4;
2375            countlen = countlen - c;
2376            count = countlen * mult + indexesleft_count;
2377            for (n = 1; n <= count; n++) {
2378               if (mult == 1)
2379                  c = read_vertices_0x1808(space, vert + ((n & 1) + 1), address, 1);
2380               else
2381                  c = read_vertices_0x1800(space, vert + ((n & 1) + 1), address, 1);
2382
2383               convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
2384               address = address + c * 4;
2385               countlen = countlen - c;
2386               render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
2387            }
2388            wait();
2389         }
2390      }
23352391      else if (type == nv2a_renderer::TRIANGLES) {
23362392         while (1) {
23372393            vertex_nv vert[3];
r249033r249034
24462502         }
24472503         wait();
24482504      }
2505      else if (type == nv2a_renderer::TRIANGLES) {
2506         while (countlen > 0) {
2507            vertex_nv vert[3];
2508            vertex_t xy[3];
2509            int c;
2510
2511            c = read_vertices_0x1818(space, vert, address, 3);
2512            convert_vertices_poly(vert, xy, 3);
2513            countlen = countlen - c;
2514            if (countlen < 0) {
2515               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2516               countlen = 0;
2517               break;
2518            }
2519            address = address + c * 3;
2520            render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
2521         }
2522      }
24492523      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
24502524         vertex_nv vert[4];
24512525         vertex_t xy[4];
r249033r249034
26132687         // clear colors
26142688         UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
26152689         bm.fill(color);
2616         //printf("clearscreen\n\r");
2690#ifdef LOG_NV2A
2691         printf("clearscreen\n\r");
2692#endif
26172693      }
26182694      if ((data & 0x03) == 3) {
26192695         bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
r249033r249034
26492725      dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
26502726   }
26512727   if (maddress == 0x020c) {
2652      // line size ?
26532728      pitch_rendertarget=data & 0xffff;
26542729      pitch_depthbuffer=(data >> 16) & 0xffff;
2655      //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
2730#ifdef LOG_NV2A
2731      printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
2732#endif
26562733      countlen--;
26572734   }
26582735   if (maddress == 0x0100) {
2659      // just temporarily
2660      if ((data & 0x1f) == 1) {
2661         data = data >> 5;
2662         data = data & 0x0ffffff0;
2663         displayedtarget = (UINT32 *)direct_access_ptr(data);
2736      countlen--;
2737      if (data != 0) {
2738         pgraph[0x704 / 4] = 0x100;
2739         pgraph[0x708 / 4] = data;
2740         pgraph[0x100 / 4] |= 1;
2741         pgraph[0x108 / 4] |= 1;
2742         if (update_interrupts() == true)
2743            interruptdevice->ir3_w(1); // IRQ 3
2744         else
2745            interruptdevice->ir3_w(0); // IRQ 3
2746         return 2;
26642747      }
2748      else
2749         return 0;
26652750   }
26662751   if (maddress == 0x0130) {
26672752      countlen--;
r249033r249034
26702755      else
26712756         return 0;
26722757   }
2758   if (maddress == 0x1d8c) {
2759      countlen--;
2760      // it is used to specify the clear value for the depth buffer (zbuffer)
2761      // but also as a parameter for interrupt routines
2762      pgraph[0x1a88 / 4] = data;
2763   }
2764   if (maddress == 0x1d90) {
2765      countlen--;
2766      // it is used to specify the clear value for the color buffer
2767      // but also as a parameter for interrupt routines
2768      pgraph[0x186c / 4] = data;
2769   }
26732770   if (maddress == 0x0210) {
26742771      // framebuffer offset ?
26752772      rendertarget = (UINT32 *)direct_access_ptr(data);
2676      //printf("Render target at %08X\n\r",data);
2773#ifdef LOG_NV2A
2774      printf("Render target at %08X\n\r", data);
2775#endif
26772776      countlen--;
26782777   }
26792778   if (maddress == 0x0214) {
26802779      // zbuffer offset ?
26812780      depthbuffer = (UINT32 *)direct_access_ptr(data);
2682      //printf("Depth buffer at %08X\n\r",data);
2781#ifdef LOG_NV2A
2782      printf("Depth buffer at %08X\n\r",data);
2783#endif
26832784      if ((data == 0) || (data > 0x7ffffffc))
26842785         depth_write_enabled = false;
26852786      else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
r249033r249034
27092810   if (maddress == 0x0354) {
27102811      depth_function = data;
27112812   }
2813   if (maddress == 0x0358) {
2814      //color_mask = data;
2815      if (data & 0x000000ff)
2816         data |= 0x000000ff;
2817      if (data & 0x0000ff00)
2818         data |= 0x0000ff00;
2819      if (data & 0x00ff0000)
2820         data |= 0x00ff0000;
2821      if (data & 0xff000000)
2822         data |= 0xff000000;
2823      color_mask = data;
2824   }
27122825   if (maddress == 0x035c) {
27132826      UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
27142827      depth_write_enabled = data != 0;
r249033r249034
36483761   combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f);
36493762}
36503763
3651bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
3764void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
36523765{
3653   //printf("vblank_callback\n\r");
3654   if (state == true)
3766#ifdef LOG_NV2A
3767   printf("vblank_callback\n\r");
3768#endif
3769   if ((state == true) && (puller_waiting == 1)) {
3770      puller_waiting = 0;
3771      puller_timer_work(NULL, 0);
3772   }
3773   if (state == true) {
36553774      pcrtc[0x100 / 4] |= 1;
3775      pcrtc[0x808 / 4] |= 0x10000;
3776   }
3777   else {
3778      pcrtc[0x100 / 4] &= ~1;
3779      pcrtc[0x808 / 4] &= ~0x10000;
3780   }
3781   if (update_interrupts() == true)
3782      interruptdevice->ir3_w(1); // IRQ 3
36563783   else
3657      pcrtc[0x100 / 4] &= ~1;
3784      interruptdevice->ir3_w(0); // IRQ 3
3785}
3786
3787bool nv2a_renderer::update_interrupts()
3788{
36583789   if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
36593790      pmc[0x100 / 4] |= 0x1000000;
36603791   else
36613792      pmc[0x100 / 4] &= ~0x1000000;
3662   if ((state == true) && (puller_waiting == 1)) {
3663      puller_waiting = 0;
3664      puller_timer_work(NULL, 0);
3665   }
3666   if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) {
3793   if (pgraph[0x100 / 4] & pgraph[0x140 / 4])
3794      pmc[0x100 / 4] |= 0x1000;
3795   else
3796      pmc[0x100 / 4] &= ~0x1000;
3797   if (((pmc[0x100 / 4] & 0x7fffffff) && (pmc[0x140 / 4] & 1)) || ((pmc[0x100 / 4] & 0x80000000) && (pmc[0x140 / 4] & 2))) {
36673798      // send interrupt
36683799      return true;
36693800   }
r249033r249034
36923823   int countlen;
36933824   int ret;
36943825   address_space *space = puller_space;
3826#ifdef LOG_NV2A
3827   UINT32 subch;
3828#endif
36953829
36963830   chanel = puller_channel;
36973831   subchannel = puller_subchannel;
r249033r249034
37483882            }
37493883            if (ret != 0) {
37503884               puller_timer->enable(false);
3751               puller_waiting = 1;
3885               puller_waiting = ret;
37523886               return;
37533887            }
37543888         }
r249033r249034
38473981      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
38483982   }
38493983   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3984      ret = pgraph[offset - 0x00400000 / 4];
38503985      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
38513986   }
38523987   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
r249033r249034
38704005      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
38714006      return ret;
38724007   }
3873   else
3874   {
3875      /* nothing */
3876   }
38774008   //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
38784009   return ret;
38794010}
38804011
38814012WRITE32_MEMBER(nv2a_renderer::geforce_w)
38824013{
4014   UINT32 old;
4015   bool update_int;
4016
4017   update_int = false;
38834018   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
38844019      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
38854020   }
r249033r249034
38984033      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
38994034   }
39004035   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
4036      int e = offset - 0x00400000 / 4;
4037      if (e >= (sizeof(pgraph) / sizeof(UINT32)))
4038         return;
4039      old = pgraph[e];
4040      COMBINE_DATA(pgraph + e);
4041      if (e == 0x100 / 4) {
4042         pgraph[e] = old & ~data;
4043         if (data & 1)
4044            pgraph[0x108 / 4] = 0;
4045         update_int = true;
4046      }
4047      if (e == 0x140 / 4)
4048         update_int = true;
4049      if (e == 0x720 / 4) {
4050         if ((data & 1) && (puller_waiting == 2)) {
4051            puller_waiting = 0;
4052            puller_timer->enable();
4053            puller_timer->adjust(attotime::zero);
4054         }
4055      }
4056      if ((e >= 0x900 / 4) && (e < 0xa00 / 4))
4057         pgraph[e] = 0;
39014058      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
39024059   }
39034060   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
39044061      int e = offset - 0x00600000 / 4;
39054062      if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
39064063         return;
4064      old = pcrtc[e];
39074065      COMBINE_DATA(pcrtc + e);
4066      if (e == 0x100 / 4) {
4067         pcrtc[e] = old & ~data;
4068         update_int = true;
4069      }
4070      if (e == 0x140 / 4)
4071         update_int = true;
39084072      if (e == 0x800 / 4) {
3909         displayedtarget = (UINT32 *)direct_access_ptr(data);
3910         //printf("crtc buffer %08X\n\r", data);
4073         displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]);
4074#ifdef LOG_NV2A
4075         printf("crtc buffer %08X\n\r", data);
4076#endif
39114077      }
39124078      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
39134079   }
r249033r249034
39224088      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
39234089      int chanel, subchannel, suboffset;
39244090      //int method, count, handle, objclass;
3925#ifdef LOG_NV2A
3926      int subch;
3927#endif
39284091
39294092      suboffset = offset - 0x00800000 / 4;
39304093      chanel = (suboffset >> (16 - 2)) & 31;
r249033r249034
39594122   }
39604123   //else
39614124   //      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
4125   if (update_int == true) {
4126      if (update_interrupts() == true)
4127         interruptdevice->ir3_w(1); // IRQ 3
4128      else
4129         interruptdevice->ir3_w(0); // IRQ 3
4130   }
39624131}
39634132
39644133void nv2a_renderer::savestate_items()
r249033r249034
39714140   puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
39724141   puller_timer->enable(false);
39734142}
4143
4144void nv2a_renderer::set_interrupt_device(pic8259_device *device)
4145{
4146   interruptdevice = device;
4147}
trunk/src/osd/modules/debugger/win/debugviewinfo.c
r249033r249034
1515
1616#include "strconv.h"
1717
18#include "winutil.h"
1819
20
1921// debugger view styles
2022#define DEBUG_VIEW_STYLE    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
2123#define DEBUG_VIEW_STYLE_EX 0
r249033r249034
4850
4951   // create the child view
5052   m_wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), NULL, DEBUG_VIEW_STYLE,
51         0, 0, 100, 100, parent, NULL, GetModuleHandle(NULL), this);
53          0, 0, 100, 100, parent, NULL, GetModuleHandleUni(), this);
5254   if (m_wnd == NULL)
5355      goto cleanup;
5456
5557   // create the scroll bars
5658   m_hscroll = CreateWindowEx(HSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, HSCROLL_STYLE,
57         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandle(NULL), this);
59         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandleUni(), this);
5860   m_vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, VSCROLL_STYLE,
59         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandle(NULL), this);
61         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandleUni(), this);
6062   if ((m_hscroll == NULL) || (m_vscroll == NULL))
6163      goto cleanup;
6264
r249033r249034
254256{
255257   // create a combo box
256258   HWND const result = CreateWindowEx(COMBO_BOX_STYLE_EX, TEXT("COMBOBOX"), NULL, COMBO_BOX_STYLE,
257         0, 0, 100, 1000, parent, NULL, GetModuleHandle(NULL), NULL);
259         0, 0, 100, 1000, parent, NULL, GetModuleHandleUni(), NULL);
258260   SetWindowLongPtr(result, GWLP_USERDATA, userdata);
259261   SendMessage(result, WM_SETFONT, (WPARAM)metrics().debug_font(), (LPARAM)FALSE);
260262
r249033r249034
789791
790792      // initialize the description of the window class
791793      wc.lpszClassName    = TEXT("MAMEDebugView");
792      wc.hInstance        = GetModuleHandle(NULL);
794      wc.hInstance        = GetModuleHandleUni();
793795      wc.lpfnWndProc      = &debugview_info::static_view_proc;
794796      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
795797      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249033r249034
798800      wc.style            = 0;
799801      wc.cbClsExtra       = 0;
800802      wc.cbWndExtra       = 0;
803     
804      UnregisterClass(wc.lpszClassName, wc.hInstance);
801805
802806      // register the class; fail if we can't
803807      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/debugwininfo.c
r249033r249034
1717#include "window.h"
1818#include "winutf8.h"
1919
20#include "winutil.h"
2021
22
2123bool debugwin_info::s_window_class_registered = false;
2224
2325
r249033r249034
3638   register_window_class();
3739
3840   m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
39         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandle(NULL), this);
41         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandleUni(), this);
4042   if (m_wnd == NULL)
4143      return;
4244
r249033r249034
580582
581583      // initialize the description of the window class
582584      wc.lpszClassName    = TEXT("MAMEDebugWindow");
583      wc.hInstance        = GetModuleHandle(NULL);
585      wc.hInstance        = GetModuleHandleUni();
584586      wc.lpfnWndProc      = &debugwin_info::static_window_proc;
585587      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
586588      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249033r249034
589591      wc.style            = 0;
590592      wc.cbClsExtra       = 0;
591593      wc.cbWndExtra       = 0;
594     
595      UnregisterClass(wc.lpszClassName, wc.hInstance);
592596
593597      // register the class; fail if we can't
594598      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/editwininfo.c
r249033r249034
1313
1414#include "strconv.h"
1515
16#include "winutil.h"
1617
18
1719// edit box styles
1820#define EDIT_BOX_STYLE      WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL
1921#define EDIT_BOX_STYLE_EX   0
r249033r249034
3234
3335   // create an edit box and override its key handling
3436   m_editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
35         0, 0, 100, 100, window(), NULL, GetModuleHandle(NULL), NULL);
37         0, 0, 100, 100, window(), NULL, GetModuleHandleUni(), NULL);
3638   m_original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(m_editwnd, GWLP_WNDPROC);
3739   SetWindowLongPtr(m_editwnd, GWLP_USERDATA, (LONG_PTR)this);
3840   SetWindowLongPtr(m_editwnd, GWLP_WNDPROC, (LONG_PTR)&editwin_info::static_edit_proc);
trunk/src/osd/windows/input.c
r249033r249034
3838#include "strconv.h"
3939#include "config.h"
4040
41#include "winutil.h"
42
4143//============================================================
4244//  PARAMETERS
4345//============================================================
r249033r249034
11171119   int didevtype_joystick = DI8DEVCLASS_GAMECTRL;
11181120
11191121   dinput_version = DIRECTINPUT_VERSION;
1120   result = DirectInput8Create(GetModuleHandle(NULL), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
1122   result = DirectInput8Create(GetModuleHandleUni(), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
11211123   if (result != DI_OK)
11221124   {
11231125      dinput_version = 0;
r249033r249034
11301132
11311133   // first attempt to initialize DirectInput at the current version
11321134   dinput_version = DIRECTINPUT_VERSION;
1133   result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
1135   result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
11341136   if (result != DI_OK)
11351137   {
11361138      // if that fails, try version 5
11371139      dinput_version = 0x0500;
1138      result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
1140      result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
11391141      if (result != DI_OK)
11401142      {
11411143         // if that fails, try version 3
11421144         dinput_version = 0x0300;
1143         result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
1145         result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
11441146         if (result != DI_OK)
11451147         {
11461148            dinput_version = 0;
trunk/src/osd/windows/output.c
r249033r249034
1717// MAMEOS headers
1818#include "output.h"
1919
20#include "winutil.h"
2021
2122
23
2224//============================================================
2325//  CONSTANTS
2426//============================================================
r249033r249034
101103                  1, 1,
102104                  NULL,
103105                  NULL,
104                  GetModuleHandle(NULL),
106                  GetModuleHandleUni(),
105107                  NULL);
106108   assert(output_hwnd != NULL);
107109
r249033r249034
167169
168170      // initialize the description of the window class
169171      wc.lpszClassName    = OUTPUT_WINDOW_CLASS;
170      wc.hInstance        = GetModuleHandle(NULL);
172      wc.hInstance        = GetModuleHandleUni();
171173      wc.lpfnWndProc      = output_window_proc;
174     
175      UnregisterClass(wc.lpszClassName, wc.hInstance);
172176
173177      // register the class; fail if we can't
174178      if (!RegisterClass(&wc))
trunk/src/osd/windows/window.c
r249033r249034
3535#include "config.h"
3636#include "winutf8.h"
3737
38#include "winutil.h"
39
3840extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks);
3941extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks);
4042extern int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks);
r249033r249034
885887
886888      // initialize the description of the window class
887889      wc.lpszClassName    = TEXT("MAME");
888      wc.hInstance        = GetModuleHandle(NULL);
890      wc.hInstance        = GetModuleHandleUni();
889891      wc.lpfnWndProc      = winwindow_video_window_proc_ui;
890892      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
891893      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
894     
895      UnregisterClass(wc.lpszClassName, wc.hInstance);
892896
893897      // register the class; fail if we can't
894898      if (!RegisterClass(&wc))
r249033r249034
11911195                  monitorbounds.left() + 100, monitorbounds.top() + 100,
11921196                  NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL,
11931197                  menu,
1194                  GetModuleHandle(NULL),
1198                  GetModuleHandleUni(),
11951199                  NULL);
11961200   if (m_hwnd == NULL)
11971201      return 1;
trunk/src/osd/windows/winmain.c
r249033r249034
13211321   dynamic_bind<PIMAGE_NT_HEADERS (WINAPI *)(PVOID)> image_nt_header(TEXT("dbghelp.dll"), "ImageNtHeader");
13221322
13231323   // start with the image base
1324   PVOID base = reinterpret_cast<PVOID>(GetModuleHandle(NULL));
1324   PVOID base = reinterpret_cast<PVOID>(GetModuleHandleUni());
13251325   assert(base != NULL);
13261326
13271327   // make sure we have the functions we need
trunk/src/osd/windows/winutil.c
r249033r249034
9292      is_first_time = FALSE;
9393
9494      // get the current module
95      module = GetModuleHandle(NULL);
95      module = GetModuleHandleUni();
9696      if (!module)
9797         return FALSE;
9898      image_ptr = (BYTE*) module;
r249033r249034
122122   }
123123   return is_gui_frontend;
124124}
125
126//-------------------------------------------------
127//  Universal way to get module handle
128//-------------------------------------------------
129
130HMODULE WINAPI GetModuleHandleUni()
131{
132   MEMORY_BASIC_INFORMATION mbi;
133   VirtualQuery((LPCVOID)GetModuleHandleUni, &mbi, sizeof(mbi));
134   return (HMODULE)mbi.AllocationBase;
135}
trunk/src/osd/windows/winutil.h
r249033r249034
1515file_error win_error_to_file_error(DWORD error);
1616osd_dir_entry_type win_attributes_to_entry_type(DWORD attributes);
1717BOOL win_is_gui_application(void);
18HMODULE WINAPI GetModuleHandleUni();
1819
1920#endif // __WINUTIL__


Previous 199869 Revisions Next


© 1997-2024 The MAME Team