Previous 199869 Revisions Next

r40519 Thursday 27th August, 2015 at 08:52:24 UTC by r09
Added three new Sharp X1 dumps
[hash]x1_cass.xml
[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/hash/x1_cass.xml
r249030r249031
1212
1313<softwarelist name="x1_cass" description="Sharp X1 cassettes">
1414
15   <software name="alamein">
16      <description>El Alamein</description>
17      <year>1983</year>
18      <publisher>ポニカ (Pony Canyon)</publisher>
19      <info name="alt_title" value="エル・アラメイン"/>
20      <info name="usage" value="In BASIC, type LOAD and then RUN"/>
21      <sharedfeat name="requirement" value="x1_flop:tapbas"/>
22      <part name="cass" interface="x1_cass">
23         <dataarea name="side1" size="158090">
24            <rom name="alamein.wav" size="12742140" crc="04e00f60" sha1="42f3ef356fdb67ddd0fbdb57e473c23d267f9bf4" offset="0" />
25         </dataarea>
26      </part>
27   </software>
28   
1529   <software name="blckonyx" supported="no">
1630      <description>The Black Onyx</description>
1731      <year>1985</year>
r249030r249031
7690         </dataarea>
7791      </part>
7892   </software>
93   
94   <software name="cball">
95      <description>Cannon Ball</description>
96      <year>1983</year>
97      <publisher>ハドソン (Hudson Soft)</publisher>
98      <info name="alt_title" value="キャノンボール"/>
99      <part name="cass" interface="x1_cass">
100         <dataarea name="side1" size="10807804">
101            <rom name="cball.wav" size="4857558" crc="4405cf21" sha1="769a43d97f69b5d72347ca8b72547e464b9d059b" offset="0" />
102         </dataarea>
103      </part>
104   </software>
79105
80106   <software name="cprowsp">
81107      <description>Champion ProWres Special</description>
r249030r249031
296322         </dataarea>
297323      </part>
298324   </software>
325   
326   <software name="machgjoe">
327      <description>Ginkou Goutou: Machinegun Joe vs. the Mafia</description>
328      <year>1983</year>
329      <publisher>ハドソン (Hudson Soft)</publisher>
330      <info name="alt_title" value="銀行強盗 マシンガンジョー VS ザ・マフィア"/>
331      <part name="cass" interface="x1_cass">
332         <dataarea name="side1" size="10807804">
333            <rom name="machgjoe.wav" size="15591932" crc="3769199a" sha1="81614c317f432055f2c5fdcce51438de9fbdad7f" offset="0" />
334         </dataarea>
335      </part>
336   </software>
299337
300338   <software name="mappy">
301339      <description>Mappy</description>
trunk/src/emu/drivers/emudummy.c
r249030r249031
3333ROM_END
3434
3535
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", MACHINE_NO_SOUND )
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", GAME_NO_SOUND )
trunk/src/emu/netlist/nl_base.h
r249030r249031
12331233      pnamedlist_t<core_device_t *> m_started_devices;
12341234   #endif
12351235
1236   ATTR_COLD plog_base<NL_DEBUG> &log() { return m_log; }
12371236   ATTR_COLD const plog_base<NL_DEBUG> &log() const { return m_log; }
12381237
12391238   protected:
trunk/src/emu/netlist/nl_setup.h
r249030r249031
198198
199199      void model_parse(const pstring &model, model_map_t &map);
200200
201      plog_base<NL_DEBUG> &log() { return netlist().log(); }
202201      const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
203202
204203   protected:
trunk/src/emu/netlist/plib/pstring.c
r249030r249031
1414
1515#include "pstring.h"
1616#include "palloc.h"
17#include "plists.h"
1817
1918template<>
2019pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0);
r249030r249031
306305// static stuff ...
307306// ----------------------------------------------------------------------------------------
308307
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
355308template<typename F>
356309void pstring_t<F>::sfree(pstr_t *s)
357310{
358311   s->m_ref_count--;
359312   if (s->m_ref_count == 0 && s != &m_zero)
360313   {
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   {
415314      pfree_array(((char *)s));
416315      //_mm_free(((char *)s));
417316   }
r249030r249031
432331{
433332   // Release the 0 string
434333}
435#endif
436334
437
438335// ----------------------------------------------------------------------------------------
439336// pstring ...
440337// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/plib/pstring.h
r249030r249031
2222   struct pstr_t
2323   {
2424      //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; }
25      pstr_t(const unsigned alen)
25      pstr_t(const int alen)
2626      {
2727         init(alen);
2828      }
29      void init(const unsigned alen)
29      void init(const int 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      unsigned len() const  { return m_len; }
36      int len() const  { return m_len; }
3737      int m_ref_count;
3838   private:
39      unsigned m_len;
39      int m_len;
4040      char m_str[1];
4141   };
4242
r249030r249031
548548class pfmt_writer_t
549549{
550550public:
551   pfmt_writer_t() : m_enabled(true) { }
551   pfmt_writer_t()  { }
552552   virtual ~pfmt_writer_t() { }
553553
554554   ATTR_COLD void operator ()(const char *fmt) const
555555   {
556      if (build_enabled && m_enabled) vdowrite(fmt);
556      if (build_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 && m_enabled) vdowrite(pfmt(fmt)(v1));
562      if (build_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 && m_enabled) vdowrite(pfmt(fmt)(v1)(v2));
568      if (build_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 && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
574      if (build_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 && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
580      if (build_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 && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
586      if (build_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
596589protected:
597590   virtual void vdowrite(const pstring &ls) const {}
598591
599private:
600   bool m_enabled;
601
602592};
603593
604594template <plog_level L, bool build_enabled = true>
trunk/src/emu/netlist/solver/nld_solver.h
r249030r249031
135135   ATTR_COLD int get_net_idx(net_t *net);
136136
137137   inline eSolverType type() const { return m_type; }
138   plog_base<NL_DEBUG> &log() { return netlist().log(); }
138   const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
139139
140140   virtual void log_stats();
141141
trunk/src/emu/sound/c352.c
r249030r249031
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.
2416 */
2517
2618#include "emu.h"
r249030r249031
476468
477469void c352_device::device_start()
478470{
479   int i;
471   int i, divider;
480472   double x_max = 32752.0;
481473   double y_max = 127.0;
482474   double u = 10.0;
r249030r249031
484476   // find our direct access
485477   m_direct = &space().direct();
486478
487   m_sample_rate_base = clock() / m_divider;
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   }
488492
493   m_sample_rate_base = clock() / divider;
494
489495   m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base);
490496
491497   // generate mulaw table for mulaw format samples
trunk/src/emu/sound/c352.h
r249030r249031
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//**************************************************************************
920//  INTERFACE CONFIGURATION MACROS
1021//**************************************************************************
1122
trunk/src/emu/sound/tms5110.c
r249030r249031
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));
239238#endif
240239   save_item(NAME(m_current_energy));
241240   save_item(NAME(m_current_pitch));
r249030r249031
350349   int i, bitout;
351350   INT32 this_sample;
352351
352   /* if we're not speaking, fill with nothingness */
353   if (!m_TALKD)
354      goto empty;
355
353356   /* loop until the buffer is full or we've stopped speaking */
354   while (size > 0)
357   while ((size > 0) && m_TALKD)
355358   {
356      if(m_TALKD) // speaking
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))
357367      {
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
368         m_OLDE = (m_new_frame_energy_idx == 0);
369         m_OLDP = (m_new_frame_pitch_idx == 0);
370      }
367371
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
368382#ifdef PERFECT_INTERPOLATION_HACK
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];
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];
374388#endif
375389
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
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");
388394#endif
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
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;
392397
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            }
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         }
398403
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;
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;
411416
412417#ifdef DEBUG_GENERATION
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)) );
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)) );
435440#endif
436441
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;
437465         }
438         else // Not a new frame, just interpolate the existing frame.
466         else // we're done, play this frame for 1/8 frame.
439467         {
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));
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));
449470            for (i = 0; i < m_coeff->num_k; i++)
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            }
471               m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
472         }
466473#else
467            //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
468            if (m_subcycle == 2)
474         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
475         if (m_subcycle == 2)
476         {
477            switch(m_PC)
469478            {
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               }
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;
486491            }
487#endif
488492         }
493#endif
494      }
489495
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         }
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      }
513519
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 */
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 */
525531#ifdef DEBUG_GENERATION_VERBOSE
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");
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");
538539#endif
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         {
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      {
546547#ifdef ALLOW_4_LSB
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);
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);
551552#else
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);
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);
557558#endif
558         }
559         // Update all counts
559      }
560      // Update all counts
560561
561         m_subcycle++;
562         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
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
563576         {
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. */
577            /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
580578#ifdef DEBUG_GENERATION
581               if (m_TALK == 0)
582                  fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
579            if (m_TALK == 0)
580               fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
583581#endif
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;
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
591588         }
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;
589         m_subcycle = m_subc_reload;
590         m_PC = 0;
591         m_IP++;
592         m_IP&=0x7;
600593      }
601      else // m_TALKD == 0
594      else if (m_subcycle == 3)
602595      {
603         m_subcycle++;
604         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
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
605614         {
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;
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
615621         }
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) */
622         m_subcycle = m_subc_reload;
623         m_PC = 0;
624         m_IP++;
625         m_IP&=0x7;
622626      }
623   buf_count++;
624   size--;
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--;
625635   }
626636}
627637
r249030r249031
853863               m_SPEN = 1; /* start immediately */
854864               /* clear out variables before speaking */
855865               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
863866               m_subc_reload = 0; // SPKSLOW means this is 0
867               m_subcycle = m_subc_reload;
868               m_PC = 0;
869               m_IP = 0;
864870               break;
865871
866872            case TMS5110_CMD_READ_BIT:
r249030r249031
888894               m_SPEN = 1; /* start immediately */
889895               /* clear out variables before speaking */
890896               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
898897               m_subc_reload = 1; // SPEAK means this is 1
898               m_subcycle = m_subc_reload;
899               m_PC = 0;
900               m_IP = 0;
899901               break;
900902
901903            case TMS5110_CMD_READ_BRANCH:
r249030r249031
994996      fprintf(stderr," ");
995997#endif
996998   }
997#ifdef DEBUG_PARSE_FRAME_DUMP
998         fprintf(stderr,"\n");
999#endif
1000999#ifdef VERBOSE
10011000      logerror("Parsed a frame successfully in ROM\n");
10021001#endif
r249030r249031
11531152#ifdef PERFECT_INTERPOLATION_HACK
11541153   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
11551154   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1156   m_old_zpar = m_old_uv_zpar = 0;
1155   m_old_zpar = 0;
11571156#endif
11581157   m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0;
11591158   m_new_frame_pitch_idx = m_current_pitch = 0;
trunk/src/emu/sound/tms5110.h
r249030r249031
77
88#include "emu.h"
99
10/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
1110#undef PERFECT_INTERPOLATION_HACK
1211
1312/* TMS5110 commands */
r249030r249031
154153   UINT8 m_old_frame_pitch_idx;
155154   UINT8 m_old_frame_k_idx[10];
156155   UINT8 m_old_zpar;
157   UINT8 m_old_uv_zpar;
158156
159157   INT32 m_current_energy;
160158   INT32 m_current_pitch;
trunk/src/emu/sound/tms5220.c
r249030r249031
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
277274
278
279275/* *****configuration of chip connection stuff***** */
280276/* 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) */
281277#define FORCE_DIGITAL 0
r249030r249031
365361   save_item(NAME(m_fifo_count));
366362   save_item(NAME(m_fifo_bits_taken));
367363
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));
364   save_item(NAME(m_speaking_now));
365   save_item(NAME(m_speak_external));
366   save_item(NAME(m_talk_status));
373367   save_item(NAME(m_buffer_low));
374368   save_item(NAME(m_buffer_empty));
375369   save_item(NAME(m_irq_pin));
r249030r249031
390384   save_item(NAME(m_current_pitch));
391385   save_item(NAME(m_current_k));
392386
387   save_item(NAME(m_target_energy));
388   save_item(NAME(m_target_pitch));
389   save_item(NAME(m_target_k));
390
393391   save_item(NAME(m_previous_energy));
394392
395393   save_item(NAME(m_subcycle));
r249030r249031
397395   save_item(NAME(m_PC));
398396   save_item(NAME(m_IP));
399397   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));
403398   save_item(NAME(m_c_variant_rate));
404399   save_item(NAME(m_pitch_count));
405400
r249030r249031
470465
471466void tms5220_device::data_write(int data)
472467{
473   int old_buffer_low = m_buffer_low;
474468#ifdef DEBUG_DUMP_INPUT_DATA
475469   fprintf(stdout, "%c",data);
476470#endif
477   if (m_DDIS) // If we're in speak external mode
471   if (m_speak_external) // If we're in speak external mode
478472   {
479473      // add this byte to the FIFO
480474      if (m_fifo_count < FIFO_SIZE)
r249030r249031
483477         m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE;
484478         m_fifo_count++;
485479#ifdef DEBUG_FIFO
486         fprintf(stderr,"data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
480         logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
487481#endif
488482         update_fifo_status_and_ints();
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
483         if ((m_talk_status == 0) && (m_buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
491484         {
492            int i;
485         int i;
493486#ifdef DEBUG_FIFO
494            fprintf(stderr,"data_write triggered SPEN to go active!\n");
487         logerror("data_write triggered talk status to go active!\n");
495488#endif
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
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?
509494            m_new_frame_energy_idx = 0;
510495            m_new_frame_pitch_idx = 0;
511496            for (i = 0; i < 4; i++)
r249030r249031
514499               m_new_frame_k_idx[i] = 0xF;
515500            for (i = 7; i < m_coeff->num_k; i++)
516501               m_new_frame_k_idx[i] = 0x7;
517
502            m_talk_status = m_speaking_now = 1;
518503         }
519504      }
520505      else
521506      {
522507#ifdef DEBUG_FIFO
523         fprintf(stderr,"data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
508         logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
524509         // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it.
525510#endif
526511      }
527512
528513
529514   }
530   else //(! m_DDIS)
515   else //(! m_speak_external)
531516      // R Nabet : we parse commands at once.  It is necessary for such commands as read.
532517      process_command(data);
533518}
r249030r249031
575560      m_buffer_low = 0;
576561
577562   /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
578   translates to having fifo_count equal to exactly 0
579   */
563   translates to having fifo_count equal to exactly 0 */
580564   if (m_fifo_count == 0)
581565   {
582566      // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
583567      if (!m_buffer_empty)
584568         set_interrupt_state(1);
585569      m_buffer_empty = 1;
586      m_TALK = m_SPEN = 0; // /BE being active clears the TALK(TCON) status which in turn clears SPEN
587570   }
588571   else
589572      m_buffer_empty = 0;
590573
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))
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))
594578   {
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;
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      }
600585   }
601   m_previous_TALK_STATUS = TALK_STATUS;
602
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 */
603588}
604589
605590/**********************************************************************************************
r249030r249031
612597{
613598   int val = 0;
614599
615   if (m_DDIS)
600   if (m_speak_external)
616601   {
617602      // extract from FIFO
618603      while (count--)
r249030r249031
658643      /* clear the interrupt pin on status read */
659644      set_interrupt_state(0);
660645#ifdef DEBUG_PIN_READS
661      fprintf(stderr,"Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty);
646      logerror("Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty);
662647#endif
663648
664      return (TALK_STATUS << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
649      return (m_talk_status << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
665650   }
666651}
667652
r249030r249031
675660int tms5220_device::ready_read()
676661{
677662#ifdef DEBUG_PIN_READS
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);
663   logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count);
679664#endif
680   return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready;
665   return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready;
681666}
682667
683668
r249030r249031
733718int tms5220_device::int_read()
734719{
735720#ifdef DEBUG_PIN_READS
736   fprintf(stderr,"int_read: irq pin read, state is %d\n", m_irq_pin);
721   logerror("int_read: irq pin read, state is %d\n", m_irq_pin);
737722#endif
738723   return m_irq_pin;
739724}
r249030r249031
748733void tms5220_device::process(INT16 *buffer, unsigned int size)
749734{
750735   int buf_count=0;
751   int i, bitout;
736   int i, bitout, zpar;
752737   INT32 this_sample;
753738
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
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;
757743
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
758749   /* loop until the buffer is full or we've stopped speaking */
759   while (size > 0)
750   while ((size > 0) && m_speaking_now)
760751   {
761      if(m_TALKD) // speaking
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))
762760      {
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
761         m_OLDE = (m_new_frame_energy_idx == 0);
762         m_OLDP = (m_new_frame_pitch_idx == 0);
763      }
772764
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];
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
775774
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
776778#ifdef PERFECT_INTERPOLATION_HACK
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];
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];
782784#endif
783785
784            /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
785            parse_frame();
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         }
786811
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
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");
796818#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
800819
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)
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)
803823            {
804               m_TALK = m_SPEN = 0;
824               m_talk_status = m_speak_external = 0;
825               set_interrupt_state(1);
826               update_fifo_status_and_ints();
805827            }
806828
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;
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;
821843
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
822853#ifdef DEBUG_GENERATION
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)) );
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]);
845863#endif
846864
847         }
848         else // Not a new frame, just interpolate the existing frame.
865         /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
866         if (m_talk_status == 0)
849867         {
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            }
868#ifdef DEBUG_GENERATION
869            fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
897870#endif
871            m_target_energy = 0;
898872         }
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));
899881
900         // calculate the output
901         if (OLD_FRAME_UNVOICED_FLAG == 1)
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...
902893         {
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;
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;
908898         }
909         else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
899         else // we're done, play this frame for 1/8 frame.
910900         {
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];
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];
922905         }
923
924         // Update LFSR *20* times every sample (once per T cycle), like patent shows
925         for (i=0; i<20; i++)
906#else
907         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
908         if (m_subcycle == 2)
926909         {
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;
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            }
933925         }
934         this_sample = lattice_filter(); /* execute lattice filter */
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 */
935964#ifdef DEBUG_GENERATION_VERBOSE
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");
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");
948972#endif
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         {
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      {
956980#ifdef ALLOW_4_LSB
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);
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);
961985#else
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);
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);
967991#endif
968         }
969         // Update all counts
992      }
993      // Update all counts
970994
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;
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;
10171011      }
1018      else // m_TALKD == 0
1012      else if (m_subcycle == 3)
10191013      {
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) */
1014         m_subcycle = m_subc_reload;
1015         m_PC++;
10391016      }
1040   buf_count++;
1041   size--;
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--;
10421022   }
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   }
10431045}
10441046
10451047/**********************************************************************************************
r249030r249031
11801182
11811183void tms5220_device::process_command(unsigned char cmd)
11821184{
1183   int i;
11841185#ifdef DEBUG_COMMAND_DUMP
11851186      fprintf(stderr,"process_command called with parameter %02X\n",cmd);
11861187#endif
r249030r249031
11881189      switch (cmd & 0x70)
11891190      {
11901191      case 0x10 : /* read byte */
1191         if (TALK_STATUS == 0) /* TALKST must be clear for RDBY */
1192         if (m_talk_status == 0) /* TALKST must be clear for RDBY */
11921193         {
11931194            if (m_schedule_dummy_read)
11941195            {
r249030r249031
12101211      break;
12111212
12121213      case 0x30 : /* read and branch */
1213         if (TALK_STATUS == 0) /* TALKST must be clear for RB */
1214         if (m_talk_status == 0) /* TALKST must be clear for RB */
12141215         {
12151216#ifdef VERBOSE
1216            fprintf(stderr,"read and branch command received\n");
1217            logerror("read and branch command received\n");
12171218#endif
12181219            m_RDB_flag = FALSE;
12191220            if (m_speechrom)
r249030r249031
12221223         break;
12231224
12241225      case 0x40 : /* load address */
1225         if (TALK_STATUS == 0) /* TALKST must be clear for LA */
1226         if (m_talk_status == 0) /* TALKST must be clear for LA */
12261227         {
12271228            /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
12281229               This code does not care about this. */
r249030r249031
12391240            if (m_speechrom)
12401241               m_speechrom->read(1);
12411242         }
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
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];
12561251         m_new_frame_energy_idx = 0;
12571252         m_new_frame_pitch_idx = 0;
1253         int i;
12581254         for (i = 0; i < 4; i++)
12591255            m_new_frame_k_idx[i] = 0;
12601256         for (i = 4; i < 7; i++)
r249030r249031
12641260         break;
12651261
12661262      case 0x60 : /* speak external */
1267         // SPKEXT going active activates SPKEE which clears the fifo
1263         //SPKEXT going active activates SPKEE which clears the fifo
12681264         m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0;
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;
1265         m_speak_external = 1;
12881266         m_RDB_flag = FALSE;
12891267         break;
12901268
r249030r249031
13301308   m_IP = reload_table[m_c_variant_rate&0x3];
13311309
13321310   update_fifo_status_and_ints();
1333   if (m_DDIS && m_buffer_empty) goto ranout;
1311   if (!m_talk_status) goto ranout;
13341312
13351313   // attempt to extract the energy index
13361314   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
r249030r249031
13391317   fprintf(stderr," ");
13401318#endif
13411319   update_fifo_status_and_ints();
1342   if (m_DDIS && m_buffer_empty) goto ranout;
1320   if (!m_talk_status) goto ranout;
13431321   // if the energy index is 0 or 15, we're done
13441322   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
13451323      return;
r249030r249031
13591337   fprintf(stderr," ");
13601338#endif
13611339   update_fifo_status_and_ints();
1362   if (m_DDIS && m_buffer_empty) goto ranout;
1340   if (!m_talk_status) goto ranout;
13631341   // if this is a repeat frame, just do nothing, it will reuse the old coefficients
13641342   if (rep_flag)
13651343      return;
r249030r249031
13731351      fprintf(stderr," ");
13741352#endif
13751353      update_fifo_status_and_ints();
1376      if (m_DDIS && m_buffer_empty) goto ranout;
1354      if (!m_talk_status) goto ranout;
13771355   }
13781356
13791357   // if the pitch index was zero, we only need 4 K's...
r249030r249031
13921370      fprintf(stderr," ");
13931371#endif
13941372      update_fifo_status_and_ints();
1395      if (m_DDIS && m_buffer_empty) goto ranout;
1373      if (!m_talk_status) goto ranout;
13961374   }
1397#ifdef DEBUG_PARSE_FRAME_DUMP
1398         fprintf(stderr,"\n");
1399#endif
14001375#ifdef VERBOSE
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));
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));
14031378   else
1404      fprintf(stderr,"Parsed a frame successfully in ROM\n");
1379      logerror("Parsed a frame successfully in ROM\n");
14051380#endif
14061381   return;
14071382
14081383   ranout:
14091384#ifdef DEBUG_FRAME_ERRORS
1410   fprintf(stderr,"Ran out of bits on a parse!\n");
1385   logerror("Ran out of bits on a parse!\n");
14111386#endif
14121387   return;
14131388}
r249030r249031
14221397{
14231398   if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin
14241399#ifdef DEBUG_PIN_READS
1425   fprintf(stderr,"irq pin set to state %d\n", state);
1400   logerror("irq pin set to state %d\n", state);
14261401#endif
14271402   if (!m_irq_handler.isnull() && state != m_irq_pin)
14281403      m_irq_handler(!state);
r249030r249031
14391414{
14401415   int state = ready_read();
14411416#ifdef DEBUG_PIN_READS
1442   fprintf(stderr,"ready pin set to state %d\n", state);
1417   logerror("ready pin set to state %d\n", state);
14431418#endif
14441419   if (!m_readyq_handler.isnull() && state != m_ready_pin)
14451420      m_readyq_handler(!state);
r249030r249031
15391514
15401515   /* initialize the chip state */
15411516   /* 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 */
1542   m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0;
1517   m_speaking_now = m_speak_external = m_talk_status = m_irq_pin = m_ready_pin = 0;
15431518   set_interrupt_state(0);
15441519   update_ready_state();
15451520   m_buffer_empty = m_buffer_low = 1;
r249030r249031
15501525#ifdef PERFECT_INTERPOLATION_HACK
15511526   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
15521527   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1553   m_old_zpar = 0;
15541528#endif
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;
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;
15581531   memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx));
15591532   memset(m_current_k, 0, sizeof(m_current_k));
1533   memset(m_target_k, 0, sizeof(m_target_k));
15601534
15611535   /* initialize the sample generators */
15621536   m_inhibit = 1;
r249030r249031
16001574            /* Write */
16011575            /* bring up to date first */
16021576#ifdef DEBUG_IO_READY
1603            fprintf(stderr,"Serviced write: %02x\n", m_write_latch);
1577            logerror("Serviced write: %02x\n", m_write_latch);
16041578            //fprintf(stderr, "Processed write data: %02X\n", m_write_latch);
16051579#endif
16061580            m_stream->update();
r249030r249031
16361610   m_true_timing = 1;
16371611   state &= 0x01;
16381612#ifdef DEBUG_RS_WS
1639   fprintf(stderr,"/RS written with data: %d\n", state);
1613   logerror("/RS written with data: %d\n", state);
16401614#endif
16411615   new_val = (m_rs_ws & 0x01) | (state<<1);
16421616   if (new_val != m_rs_ws)
r249030r249031
16491623#ifdef DEBUG_RS_WS
16501624         else
16511625            /* illegal */
1652            fprintf(stderr,"tms5220_rs_w: illegal\n");
1626            logerror("tms5220_rs_w: illegal\n");
16531627#endif
16541628         return;
16551629      }
r249030r249031
16671641      {
16681642         /* high to low - schedule ready cycle */
16691643#ifdef DEBUG_RS_WS
1670         fprintf(stderr,"Scheduling ready cycle for /RS...\n");
1644         logerror("Scheduling ready cycle for /RS...\n");
16711645#endif
16721646         /* 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. */
16731647         m_io_ready = 0;
r249030r249031
16881662   m_true_timing = 1;
16891663   state &= 0x01;
16901664#ifdef DEBUG_RS_WS
1691   fprintf(stderr,"/WS written with data: %d\n", state);
1665   logerror("/WS written with data: %d\n", state);
16921666#endif
16931667   new_val = (m_rs_ws & 0x02) | (state<<0);
16941668   if (new_val != m_rs_ws)
r249030r249031
17011675#ifdef DEBUG_RS_WS
17021676         else
17031677            /* illegal */
1704            fprintf(stderr,"tms5220_ws_w: illegal\n");
1678            logerror("tms5220_ws_w: illegal\n");
17051679#endif
17061680         return;
17071681      }
r249030r249031
17191693      {
17201694         /* high to low - schedule ready cycle */
17211695#ifdef DEBUG_RS_WS
1722         fprintf(stderr,"Scheduling ready cycle for /WS...\n");
1696         logerror("Scheduling ready cycle for /WS...\n");
17231697#endif
17241698         /* 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. */
17251699         m_io_ready = 0;
r249030r249031
17521726   if (space.debugger_access()) return;
17531727
17541728#ifdef DEBUG_RS_WS
1755   fprintf(stderr,"tms5220_data_w: data %02x\n", data);
1729   logerror("tms5220_data_w: data %02x\n", data);
17561730#endif
17571731   if (!m_true_timing)
17581732   {
r249030r249031
17651739      /* actually in a write ? */
17661740#ifdef DEBUG_RS_WS
17671741      if (!(m_rs_ws == 0x02))
1768         fprintf(stderr,"tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
1742         logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
17691743#endif
17701744      m_write_latch = data;
17711745   }
r249030r249031
17971771         return m_read_latch;
17981772#ifdef DEBUG_RS_WS
17991773      else
1800         fprintf(stderr,"tms5220_status_r: data read outside rs!\n");
1774         logerror("tms5220_status_r: data read outside rs!\n");
18011775#endif
18021776      return 0xff;
18031777   }
trunk/src/emu/sound/tms5220.h
r249030r249031
105105
106106
107107   /* these contain global status bits */
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 */
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. */
114111   UINT8 m_buffer_low;       /* If 1, FIFO has less than 8 bytes in it */
115112   UINT8 m_buffer_empty;     /* If 1, FIFO is empty */
116113   UINT8 m_irq_pin;          /* state of the IRQ pin (output) */
r249030r249031
135132   INT16 m_current_energy;
136133   INT16 m_current_pitch;
137134   INT16 m_current_k[10];
135
136   INT16 m_target_energy;
137   INT16 m_target_pitch;
138   INT16 m_target_k[10];
138139#else
139140   UINT8 m_old_frame_energy_idx;
140141   UINT8 m_old_frame_pitch_idx;
141142   UINT8 m_old_frame_k_idx[10];
142   UINT8 m_old_zpar;
143   UINT8 m_old_uv_zpar;
144143
145144   INT32 m_current_energy;
146145   INT32 m_current_pitch;
147146   INT32 m_current_k[10];
147
148   INT32 m_target_energy;
149   INT32 m_target_pitch;
150   INT32 m_target_k[10];
148151#endif
149152
150153   UINT16 m_previous_energy; /* needed for lattice filter to match patent */
r249030r249031
152155   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 */
153156   UINT8 m_subc_reload;      /* contains 1 for normal speech, 0 when SPKSLOW is active */
154157   UINT8 m_PC;               /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
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 */
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 */
156159   UINT8 m_IP;               /* the current interpolation period */
157160   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 TODO: no it isn't */
167   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
168168   INT16 m_excitation_data;
169169
170170   /* R Nabet : These have been added to emulate speech Roms */
trunk/src/mame/arcade.lst
r249030r249031
82208220nbajamte3       // (c) 1994 Midway
82218221nbajamten       // (c) 1995 Midway
82228222revx            // (c) 1994 Midway
8223revxp5          // (c) 1994 Midway
82248223mk3             // (c) 1994 Midway
82258224mk3r20          // (c) 1994 Midway
82268225mk3r10          // (c) 1994 Midway
trunk/src/mame/drivers/fcrash.c
r249030r249031
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, sf2m1,    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, dinopic,  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
r249030r249031
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) )
358348
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) )
364349
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
416350/*************************************
417351 *
418352 *  Game drivers
419353 *
420354 *************************************/
421355
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 )
356GAME( 1994, revx,   0,         midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (Rev. 1.0 6/16/94)", MACHINE_SUPPORTS_SAVE )
trunk/src/mame/drivers/namcofl.c
r249030r249031
610610   MCFG_VIDEO_START_OVERRIDE(namcofl_state,namcofl)
611611
612612   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
613   MCFG_C352_ADD("c352", 48384000/2, 288)
613   MCFG_C352_ADD("c352", 48384000/2, C352_DIVIDER_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
r249030r249031
11261126   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb1)
11271127
11281128   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_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)
r249030r249031
11631163   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb2)
11641164
11651165   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_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
r249030r249031
307307   /* sound hardware */
308308   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
309309
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, 288)
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, C352_DIVIDER_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
r249030r249031
571571
572572   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
573573
574   MCFG_C352_ADD("c352", 20013200, 228)
574   MCFG_C352_ADD("c352", 20013200, C352_DIVIDER_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
r249030r249031
16221622   /* sound hardware */
16231623   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
16241624
1625   MCFG_C352_ADD("c352", 29168000, 332)
1625   MCFG_C352_ADD("c352", 29168000, C352_DIVIDER_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
r249030r249031
37813781   /* sound hardware */
37823782   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
37833783
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_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)
r249030r249031
38303830   /* sound hardware */
38313831   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
38323832
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_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
r249030r249031
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  */
1251#define C352DIV      (296)
1250#define C352CLOCK   (25992000)  /* measured at 25.992MHz from 2061 pin 9 (System 12 uses a divider of 332) */
12521251#define VSYNC1      (59.8824)
12531252#define VSYNC2      (59.915)
12541253#define HSYNC       (16666150)
r249030r249031
33213320   /* sound hardware */
33223321   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33233322
3324   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3323   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
33253324   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33263325   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33273326   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249030r249031
33903389   /* sound hardware */
33913390   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33923391
3393   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3392   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
33943393   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33953394   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33963395   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249030r249031
34703469   /* sound hardware */
34713470   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
34723471
3473   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3472   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
34743473   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
34753474   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
34763475   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/quantum.c
r249030r249031
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
340337ROM_END
341338
342339
r249030r249031
355352   /* AVG PROM */
356353   ROM_REGION( 0x100, "user1", 0 )
357354   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
361355ROM_END
362356
363357
r249030r249031
376370   /* AVG PROM */
377371   ROM_REGION( 0x100, "user1", 0 )
378372   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
382373ROM_END
383374
384375
trunk/src/mame/includes/chihiro.h
r249030r249031
185185      memset(pfifo, 0, sizeof(pfifo));
186186      memset(pcrtc, 0, sizeof(pcrtc));
187187      memset(pmc, 0, sizeof(pmc));
188      memset(pgraph, 0, sizeof(pgraph));
189188      memset(ramin, 0, sizeof(ramin));
190189      computedilated();
191190      objectdata = &(object_data_alloc());
r249030r249031
195194      enabled_vertex_attributes = 0;
196195      indexesleft_count = 0;
197196      vertex_pipeline = 4;
198      color_mask = 0xffffffff;
199197      alpha_test_enabled = false;
200198      alpha_reference = 0;
201199      alpha_func = nv2a_renderer::ALWAYS;
r249030r249031
240238   }
241239   DECLARE_READ32_MEMBER(geforce_r);
242240   DECLARE_WRITE32_MEMBER(geforce_w);
243   void vblank_callback(screen_device &screen, bool state);
241   bool vblank_callback(screen_device &screen, bool state);
244242   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);
247243
248244   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
249245   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
r249030r249031
307303   UINT32 pfifo[0x2000 / 4];
308304   UINT32 pcrtc[0x1000 / 4];
309305   UINT32 pmc[0x1000 / 4];
310   UINT32 pgraph[0x2000 / 4];
311306   UINT32 ramin[0x100000 / 4];
312307   UINT32 dma_offset[2];
313308   UINT32 dma_size[2];
314309   UINT8 *basemempointer;
315   pic8259_device *interruptdevice;
316310   rectangle limits_rendertarget;
317311   UINT32 pitch_rendertarget;
318312   UINT32 pitch_depthbuffer;
r249030r249031
447441      int used;
448442      osd_lock *lock;
449443   } combiner;
450   UINT32 color_mask;
451444   bool alpha_test_enabled;
452445   int alpha_func;
453446   int alpha_reference;
trunk/src/mame/machine/xbox.c
r249030r249031
465465
466466void xbox_base_state::vblank_callback(screen_device &screen, bool state)
467467{
468   nvidia_nv2a->vblank_callback(screen, state);
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
469472}
470473
471474UINT32 xbox_base_state::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
r249030r249031
14571460   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
14581461      debug_console_register_command(machine(), "xbox", CMDFLAG_NONE, 0, 1, 4, xbox_debug_commands);
14591462   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;
14651463#ifdef USB_ENABLED
14661464   ohcist.hc_regs[HcRevision] = 0x10;
14671465   ohcist.hc_regs[HcFmInterval] = 0x2edf;
r249030r249031
14851483   save_item(NAME(smbusst.rw));
14861484   save_item(NAME(smbusst.words));
14871485   save_item(NAME(pic16lc_buffer));
1488   nvidia_nv2a->set_interrupt_device(xbox_base_devs.pic8259_1);
14891486   nvidia_nv2a->start(&m_maincpu->space());
14901487   nvidia_nv2a->savestate_items();
14911488}
trunk/src/mame/video/chihiro.c
r249030r249031
33#include "emu.h"
44#include "video/poly.h"
55#include "bitmap.h"
6#include "machine/pic8259.h"
76#include "includes/chihiro.h"
87
98//#define LOG_NV2A
r249030r249031
946945UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
947946{
948947   UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
949   UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain
948   UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ?
950949   UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
951950   UINT32 w;
952951
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   }
952   if (ramin[e / 4] != handle)
953      e = 0;
961954   w = ramin[e / 4 + 1];
962   return (w & 0xffff) * 0x10; // 0xffff is not certain
955   return (w & 0xffff) * 0x10;
963956}
964957
965958void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
r249030r249031
12531246      addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
12541247   else // type_rendertarget == LINEAR*/
12551248      addr = rendertarget + (pitch_rendertarget / 4)*y + x;
1256   fbcolor = 0;
1257   if (color_mask != 0)
1258      fbcolor = *addr;
1249   fbcolor = *addr;
12591250   daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
12601251   deptsten = *daddr;
12611252   c[3] = color >> 24;
r249030r249031
17811772            break;
17821773      }
17831774   }
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   }
1775   fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1776   *addr = fbcolor;
17901777   if (depth_write_enabled)
17911778      dep = depth;
17921779   deptsten = (dep << 8) | sten;
r249030r249031
22462233   maddress = method * 4;
22472234   data = space.read_dword(address);
22482235   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
22522236   if (maddress == 0x17fc) {
22532237      indexesleft_count = 0;
22542238      indexesleft_first = 0;
r249030r249031
22862270         }
22872271         wait();
22882272      }
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      }
23042273      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
23052274         vertex_nv vert[4];
23062275         vertex_t xy[4];
r249030r249031
23422311      // each dword after 1800 contains two 16 bit index values to select the vartices
23432312      // each dword after 1808 contains a 32 bit index value to select the vartices
23442313      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
23452317      if (type == nv2a_renderer::QUADS) {
23462318         while (1) {
23472319            vertex_nv vert[4];
r249030r249031
23602332            render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
23612333         }
23622334      }
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      }
23912335      else if (type == nv2a_renderer::TRIANGLES) {
23922336         while (1) {
23932337            vertex_nv vert[3];
r249030r249031
25022446         }
25032447         wait();
25042448      }
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      }
25232449      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
25242450         vertex_nv vert[4];
25252451         vertex_t xy[4];
r249030r249031
26872613         // clear colors
26882614         UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
26892615         bm.fill(color);
2690#ifdef LOG_NV2A
2691         printf("clearscreen\n\r");
2692#endif
2616         //printf("clearscreen\n\r");
26932617      }
26942618      if ((data & 0x03) == 3) {
26952619         bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
r249030r249031
27252649      dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
27262650   }
27272651   if (maddress == 0x020c) {
2652      // line size ?
27282653      pitch_rendertarget=data & 0xffff;
27292654      pitch_depthbuffer=(data >> 16) & 0xffff;
2730#ifdef LOG_NV2A
2731      printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
2732#endif
2655      //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
27332656      countlen--;
27342657   }
27352658   if (maddress == 0x0100) {
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;
2659      // just temporarily
2660      if ((data & 0x1f) == 1) {
2661         data = data >> 5;
2662         data = data & 0x0ffffff0;
2663         displayedtarget = (UINT32 *)direct_access_ptr(data);
27472664      }
2748      else
2749         return 0;
27502665   }
27512666   if (maddress == 0x0130) {
27522667      countlen--;
r249030r249031
27552670      else
27562671         return 0;
27572672   }
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   }
27702673   if (maddress == 0x0210) {
27712674      // framebuffer offset ?
27722675      rendertarget = (UINT32 *)direct_access_ptr(data);
2773#ifdef LOG_NV2A
2774      printf("Render target at %08X\n\r", data);
2775#endif
2676      //printf("Render target at %08X\n\r",data);
27762677      countlen--;
27772678   }
27782679   if (maddress == 0x0214) {
27792680      // zbuffer offset ?
27802681      depthbuffer = (UINT32 *)direct_access_ptr(data);
2781#ifdef LOG_NV2A
2782      printf("Depth buffer at %08X\n\r",data);
2783#endif
2682      //printf("Depth buffer at %08X\n\r",data);
27842683      if ((data == 0) || (data > 0x7ffffffc))
27852684         depth_write_enabled = false;
27862685      else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
r249030r249031
28102709   if (maddress == 0x0354) {
28112710      depth_function = data;
28122711   }
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   }
28252712   if (maddress == 0x035c) {
28262713      UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
28272714      depth_write_enabled = data != 0;
r249030r249031
37613648   combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f);
37623649}
37633650
3764void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
3651bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
37653652{
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) {
3653   //printf("vblank_callback\n\r");
3654   if (state == true)
37743655      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
37833656   else
3784      interruptdevice->ir3_w(0); // IRQ 3
3785}
3786
3787bool nv2a_renderer::update_interrupts()
3788{
3657      pcrtc[0x100 / 4] &= ~1;
37893658   if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
37903659      pmc[0x100 / 4] |= 0x1000000;
37913660   else
37923661      pmc[0x100 / 4] &= ~0x1000000;
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))) {
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)) {
37983667      // send interrupt
37993668      return true;
38003669   }
r249030r249031
38233692   int countlen;
38243693   int ret;
38253694   address_space *space = puller_space;
3826#ifdef LOG_NV2A
3827   UINT32 subch;
3828#endif
38293695
38303696   chanel = puller_channel;
38313697   subchannel = puller_subchannel;
r249030r249031
38823748            }
38833749            if (ret != 0) {
38843750               puller_timer->enable(false);
3885               puller_waiting = ret;
3751               puller_waiting = 1;
38863752               return;
38873753            }
38883754         }
r249030r249031
39813847      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
39823848   }
39833849   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3984      ret = pgraph[offset - 0x00400000 / 4];
39853850      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
39863851   }
39873852   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
r249030r249031
40053870      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
40063871      return ret;
40073872   }
3873   else
3874   {
3875      /* nothing */
3876   }
40083877   //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
40093878   return ret;
40103879}
40113880
40123881WRITE32_MEMBER(nv2a_renderer::geforce_w)
40133882{
4014   UINT32 old;
4015   bool update_int;
4016
4017   update_int = false;
40183883   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
40193884      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
40203885   }
r249030r249031
40333898      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
40343899   }
40353900   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;
40583901      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
40593902   }
40603903   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
40613904      int e = offset - 0x00600000 / 4;
40623905      if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
40633906         return;
4064      old = pcrtc[e];
40653907      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;
40723908      if (e == 0x800 / 4) {
4073         displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]);
4074#ifdef LOG_NV2A
4075         printf("crtc buffer %08X\n\r", data);
4076#endif
3909         displayedtarget = (UINT32 *)direct_access_ptr(data);
3910         //printf("crtc buffer %08X\n\r", data);
40773911      }
40783912      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
40793913   }
r249030r249031
40883922      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
40893923      int chanel, subchannel, suboffset;
40903924      //int method, count, handle, objclass;
3925#ifdef LOG_NV2A
3926      int subch;
3927#endif
40913928
40923929      suboffset = offset - 0x00800000 / 4;
40933930      chanel = (suboffset >> (16 - 2)) & 31;
r249030r249031
41223959   }
41233960   //else
41243961   //      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   }
41313962}
41323963
41333964void nv2a_renderer::savestate_items()
r249030r249031
41403971   puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
41413972   puller_timer->enable(false);
41423973}
4143
4144void nv2a_renderer::set_interrupt_device(pic8259_device *device)
4145{
4146   interruptdevice = device;
4147}
trunk/src/osd/modules/debugger/win/debugviewinfo.c
r249030r249031
1515
1616#include "strconv.h"
1717
18#include "winutil.h"
1918
20
2119// debugger view styles
2220#define DEBUG_VIEW_STYLE    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
2321#define DEBUG_VIEW_STYLE_EX 0
r249030r249031
5048
5149   // create the child view
5250   m_wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), NULL, DEBUG_VIEW_STYLE,
53          0, 0, 100, 100, parent, NULL, GetModuleHandleUni(), this);
51         0, 0, 100, 100, parent, NULL, GetModuleHandle(NULL), this);
5452   if (m_wnd == NULL)
5553      goto cleanup;
5654
5755   // create the scroll bars
5856   m_hscroll = CreateWindowEx(HSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, HSCROLL_STYLE,
59         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandleUni(), this);
57         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandle(NULL), this);
6058   m_vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, VSCROLL_STYLE,
61         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandleUni(), this);
59         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandle(NULL), this);
6260   if ((m_hscroll == NULL) || (m_vscroll == NULL))
6361      goto cleanup;
6462
r249030r249031
256254{
257255   // create a combo box
258256   HWND const result = CreateWindowEx(COMBO_BOX_STYLE_EX, TEXT("COMBOBOX"), NULL, COMBO_BOX_STYLE,
259         0, 0, 100, 1000, parent, NULL, GetModuleHandleUni(), NULL);
257         0, 0, 100, 1000, parent, NULL, GetModuleHandle(NULL), NULL);
260258   SetWindowLongPtr(result, GWLP_USERDATA, userdata);
261259   SendMessage(result, WM_SETFONT, (WPARAM)metrics().debug_font(), (LPARAM)FALSE);
262260
r249030r249031
791789
792790      // initialize the description of the window class
793791      wc.lpszClassName    = TEXT("MAMEDebugView");
794      wc.hInstance        = GetModuleHandleUni();
792      wc.hInstance        = GetModuleHandle(NULL);
795793      wc.lpfnWndProc      = &debugview_info::static_view_proc;
796794      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
797795      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249030r249031
800798      wc.style            = 0;
801799      wc.cbClsExtra       = 0;
802800      wc.cbWndExtra       = 0;
803     
804      UnregisterClass(wc.lpszClassName, wc.hInstance);
805801
806802      // register the class; fail if we can't
807803      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/debugwininfo.c
r249030r249031
1717#include "window.h"
1818#include "winutf8.h"
1919
20#include "winutil.h"
2120
22
2321bool debugwin_info::s_window_class_registered = false;
2422
2523
r249030r249031
3836   register_window_class();
3937
4038   m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
41         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandleUni(), this);
39         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandle(NULL), this);
4240   if (m_wnd == NULL)
4341      return;
4442
r249030r249031
582580
583581      // initialize the description of the window class
584582      wc.lpszClassName    = TEXT("MAMEDebugWindow");
585      wc.hInstance        = GetModuleHandleUni();
583      wc.hInstance        = GetModuleHandle(NULL);
586584      wc.lpfnWndProc      = &debugwin_info::static_window_proc;
587585      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
588586      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249030r249031
591589      wc.style            = 0;
592590      wc.cbClsExtra       = 0;
593591      wc.cbWndExtra       = 0;
594     
595      UnregisterClass(wc.lpszClassName, wc.hInstance);
596592
597593      // register the class; fail if we can't
598594      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/editwininfo.c
r249030r249031
1313
1414#include "strconv.h"
1515
16#include "winutil.h"
1716
18
1917// edit box styles
2018#define EDIT_BOX_STYLE      WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL
2119#define EDIT_BOX_STYLE_EX   0
r249030r249031
3432
3533   // create an edit box and override its key handling
3634   m_editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
37         0, 0, 100, 100, window(), NULL, GetModuleHandleUni(), NULL);
35         0, 0, 100, 100, window(), NULL, GetModuleHandle(NULL), NULL);
3836   m_original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(m_editwnd, GWLP_WNDPROC);
3937   SetWindowLongPtr(m_editwnd, GWLP_USERDATA, (LONG_PTR)this);
4038   SetWindowLongPtr(m_editwnd, GWLP_WNDPROC, (LONG_PTR)&editwin_info::static_edit_proc);
trunk/src/osd/windows/input.c
r249030r249031
3838#include "strconv.h"
3939#include "config.h"
4040
41#include "winutil.h"
42
4341//============================================================
4442//  PARAMETERS
4543//============================================================
r249030r249031
11191117   int didevtype_joystick = DI8DEVCLASS_GAMECTRL;
11201118
11211119   dinput_version = DIRECTINPUT_VERSION;
1122   result = DirectInput8Create(GetModuleHandleUni(), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
1120   result = DirectInput8Create(GetModuleHandle(NULL), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
11231121   if (result != DI_OK)
11241122   {
11251123      dinput_version = 0;
r249030r249031
11321130
11331131   // first attempt to initialize DirectInput at the current version
11341132   dinput_version = DIRECTINPUT_VERSION;
1135   result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1133   result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11361134   if (result != DI_OK)
11371135   {
11381136      // if that fails, try version 5
11391137      dinput_version = 0x0500;
1140      result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1138      result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11411139      if (result != DI_OK)
11421140      {
11431141         // if that fails, try version 3
11441142         dinput_version = 0x0300;
1145         result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1143         result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11461144         if (result != DI_OK)
11471145         {
11481146            dinput_version = 0;
trunk/src/osd/windows/output.c
r249030r249031
1717// MAMEOS headers
1818#include "output.h"
1919
20#include "winutil.h"
2120
2221
23
2422//============================================================
2523//  CONSTANTS
2624//============================================================
r249030r249031
103101                  1, 1,
104102                  NULL,
105103                  NULL,
106                  GetModuleHandleUni(),
104                  GetModuleHandle(NULL),
107105                  NULL);
108106   assert(output_hwnd != NULL);
109107
r249030r249031
169167
170168      // initialize the description of the window class
171169      wc.lpszClassName    = OUTPUT_WINDOW_CLASS;
172      wc.hInstance        = GetModuleHandleUni();
170      wc.hInstance        = GetModuleHandle(NULL);
173171      wc.lpfnWndProc      = output_window_proc;
174     
175      UnregisterClass(wc.lpszClassName, wc.hInstance);
176172
177173      // register the class; fail if we can't
178174      if (!RegisterClass(&wc))
trunk/src/osd/windows/window.c
r249030r249031
3535#include "config.h"
3636#include "winutf8.h"
3737
38#include "winutil.h"
39
4038extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks);
4139extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks);
4240extern int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks);
r249030r249031
887885
888886      // initialize the description of the window class
889887      wc.lpszClassName    = TEXT("MAME");
890      wc.hInstance        = GetModuleHandleUni();
888      wc.hInstance        = GetModuleHandle(NULL);
891889      wc.lpfnWndProc      = winwindow_video_window_proc_ui;
892890      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
893891      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
894     
895      UnregisterClass(wc.lpszClassName, wc.hInstance);
896892
897893      // register the class; fail if we can't
898894      if (!RegisterClass(&wc))
r249030r249031
11951191                  monitorbounds.left() + 100, monitorbounds.top() + 100,
11961192                  NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL,
11971193                  menu,
1198                  GetModuleHandleUni(),
1194                  GetModuleHandle(NULL),
11991195                  NULL);
12001196   if (m_hwnd == NULL)
12011197      return 1;
trunk/src/osd/windows/winmain.c
r249030r249031
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>(GetModuleHandleUni());
1324   PVOID base = reinterpret_cast<PVOID>(GetModuleHandle(NULL));
13251325   assert(base != NULL);
13261326
13271327   // make sure we have the functions we need
trunk/src/osd/windows/winutil.c
r249030r249031
9292      is_first_time = FALSE;
9393
9494      // get the current module
95      module = GetModuleHandleUni();
95      module = GetModuleHandle(NULL);
9696      if (!module)
9797         return FALSE;
9898      image_ptr = (BYTE*) module;
r249030r249031
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
r249030r249031
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();
1918
2019#endif // __WINUTIL__


Previous 199869 Revisions Next


© 1997-2024 The MAME Team