Previous 199869 Revisions Next

r40532 Friday 28th August, 2015 at 16:59:04 UTC by R. Belmont
Merge pull request #293 from JoakimLarsson/m0165_fcc1_3

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


Previous 199869 Revisions Next


© 1997-2024 The MAME Team