Previous 199869 Revisions Next

r40525 Wednesday 26th August, 2015 at 14:45:28 UTC by Logan B
Fix for ddanpei and ninjab (nw)
[/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
r249036r249037
11*~
22/*
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/
3!/*/
164!/.gitattributes
175!/.gitignore
186!/.travis.yml
197!/makefile
20!/mame.doxygen
8!/mame.doxygen
219!/*.md
10/cfg
11/diff
12/ini
13/inp
14/nvram
15/obj
16/roms
17/snap
2218src/regtests/chdman/temp
2319src/regtests/jedutil/output
24*.pyc
No newline at end of file
20/sta
21*.pyc
22/build
23/documentation
No newline at end of file
trunk/hash/megadriv.xml
r249036r249037
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>
r249036r249037
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
r249036r249037
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
r249036r249037
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   
2915   <software name="blckonyx" supported="no">
3016      <description>The Black Onyx</description>
3117      <year>1985</year>
r249036r249037
9076         </dataarea>
9177      </part>
9278   </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>
10579
10680   <software name="cprowsp">
10781      <description>Champion ProWres Special</description>
r249036r249037
322296         </dataarea>
323297      </part>
324298   </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>
337299
338300   <software name="mappy">
339301      <description>Mappy</description>
trunk/src/emu/drivers/emudummy.c
r249036r249037
3333ROM_END
3434
3535
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", MACHINE_NO_SOUND )
36GAME( 1900, __dummy, 0, __dummy, 0, driver_device, 0, ROT0, "(none)", "Dummy", GAME_NO_SOUND )
trunk/src/emu/netlist/nl_base.h
r249036r249037
12331233      pnamedlist_t<core_device_t *> m_started_devices;
12341234   #endif
12351235
1236   ATTR_COLD plog_base<NL_DEBUG> &log() { return m_log; }
12371236   ATTR_COLD const plog_base<NL_DEBUG> &log() const { return m_log; }
12381237
12391238   protected:
trunk/src/emu/netlist/nl_setup.h
r249036r249037
198198
199199      void model_parse(const pstring &model, model_map_t &map);
200200
201      plog_base<NL_DEBUG> &log() { return netlist().log(); }
202201      const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
203202
204203   protected:
trunk/src/emu/netlist/plib/pstring.c
r249036r249037
1414
1515#include "pstring.h"
1616#include "palloc.h"
17#include "plists.h"
1817
1918template<>
2019pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0);
r249036r249037
306305// static stuff ...
307306// ----------------------------------------------------------------------------------------
308307
309/*
310 * Cached allocation of string memory
311 *
312 * This improves startup performance by 30%.
313 */
314
315#if 1
316
317static pstack_t<pstr_t *> *stk = NULL;
318
319static inline unsigned countleadbits(unsigned x)
320{
321#ifndef count_leading_zeros
322   unsigned msk;
323   unsigned ret;
324   if (x < 0x100)
325   {
326      msk = 0x80;
327      ret = 24;
328   }
329   else if (x < 0x10000)
330   {
331      msk = 0x8000;
332      ret = 16;
333   }
334   else if (x < 0x1000000)
335   {
336      msk = 0x800000;
337      ret = 8;
338   }
339   else
340   {
341      msk = 0x80000000;
342      ret = 0;
343   }
344   while ((msk & x) == 0 && ret < 31)
345   {
346      msk = msk >> 1;
347      ret++;
348   }
349   return ret;
350#else
351   return count_leading_zeros(x);
352#endif
353}
354
355308template<typename F>
356309void pstring_t<F>::sfree(pstr_t *s)
357310{
358311   s->m_ref_count--;
359312   if (s->m_ref_count == 0 && s != &m_zero)
360313   {
361      if (stk != NULL)
362      {
363         unsigned sn= ((32 - countleadbits(s->len())) + 1) / 2;
364         stk[sn].push(s);
365      }
366      else
367         pfree_array(((char *)s));
368      //_mm_free(((char *)s));
369   }
370}
371
372template<typename F>
373pstr_t *pstring_t<F>::salloc(int n)
374{
375   if (stk == NULL)
376      stk = palloc_array(pstack_t<pstr_t *>, 17);
377   pstr_t *p;
378   unsigned sn= ((32 - countleadbits(n)) + 1) / 2;
379   unsigned size = sizeof(pstr_t) + (1<<(sn * 2)) + 1;
380   if (stk[sn].empty())
381      p = (pstr_t *) palloc_array(char, size);
382   else
383   {
384      //printf("%u %u\n", sn, (unsigned) stk[sn].count());
385      p = stk[sn].pop();
386   }
387
388   //  str_t *p = (str_t *) _mm_malloc(size, 8);
389   p->init(n);
390   return p;
391}
392template<typename F>
393void pstring_t<F>::resetmem()
394{
395   if (stk != NULL)
396   {
397      for (unsigned i=0; i<=16; i++)
398      {
399         for (; stk[i].count() > 0; )
400            pfree_array(stk[i].pop());
401      }
402      pfree_array(stk);
403      stk = NULL;
404   }
405}
406
407
408#else
409template<typename F>
410void pstring_t<F>::sfree(pstr_t *s)
411{
412   s->m_ref_count--;
413   if (s->m_ref_count == 0 && s != &m_zero)
414   {
415314      pfree_array(((char *)s));
416315      //_mm_free(((char *)s));
417316   }
r249036r249037
432331{
433332   // Release the 0 string
434333}
435#endif
436334
437
438335// ----------------------------------------------------------------------------------------
439336// pstring ...
440337// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/plib/pstring.h
r249036r249037
2222   struct pstr_t
2323   {
2424      //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; }
25      pstr_t(const unsigned alen)
25      pstr_t(const int alen)
2626      {
2727         init(alen);
2828      }
29      void init(const unsigned alen)
29      void init(const int alen)
3030      {
3131            m_ref_count = 1;
3232            m_len = alen;
3333            m_str[0] = 0;
3434      }
3535      char *str() { return &m_str[0]; }
36      unsigned len() const  { return m_len; }
36      int len() const  { return m_len; }
3737      int m_ref_count;
3838   private:
39      unsigned m_len;
39      int m_len;
4040      char m_str[1];
4141   };
4242
r249036r249037
548548class pfmt_writer_t
549549{
550550public:
551   pfmt_writer_t() : m_enabled(true) { }
551   pfmt_writer_t()  { }
552552   virtual ~pfmt_writer_t() { }
553553
554554   ATTR_COLD void operator ()(const char *fmt) const
555555   {
556      if (build_enabled && m_enabled) vdowrite(fmt);
556      if (build_enabled) vdowrite(fmt);
557557   }
558558
559559   template<typename T1>
560560   ATTR_COLD void operator ()(const char *fmt, const T1 &v1) const
561561   {
562      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1));
562      if (build_enabled) vdowrite(pfmt(fmt)(v1));
563563   }
564564
565565   template<typename T1, typename T2>
566566   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2) const
567567   {
568      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2));
568      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2));
569569   }
570570
571571   template<typename T1, typename T2, typename T3>
572572   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3) const
573573   {
574      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
574      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
575575   }
576576
577577   template<typename T1, typename T2, typename T3, typename T4>
578578   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const
579579   {
580      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
580      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
581581   }
582582
583583   template<typename T1, typename T2, typename T3, typename T4, typename T5>
584584   ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) const
585585   {
586      if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
586      if (build_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
587587   }
588588
589   void set_enabled(const bool v)
590   {
591      m_enabled = v;
592   }
593
594   bool is_enabled() const { return m_enabled; }
595
596589protected:
597590   virtual void vdowrite(const pstring &ls) const {}
598591
599private:
600   bool m_enabled;
601
602592};
603593
604594template <plog_level L, bool build_enabled = true>
trunk/src/emu/netlist/solver/nld_solver.h
r249036r249037
135135   ATTR_COLD int get_net_idx(net_t *net);
136136
137137   inline eSolverType type() const { return m_type; }
138   plog_base<NL_DEBUG> &log() { return netlist().log(); }
138   const plog_base<NL_DEBUG> &log() const { return netlist().log(); }
139139
140140   virtual void log_stats();
141141
trunk/src/emu/sound/c352.c
r249036r249037
1313    Supports 8-bit linear and 8-bit muLaw samples
1414    Output: digital, 16 bit, 4 channels
1515    Output sample rate is the input clock / (288 * 2).
16   
17    superctr: The clock divider appears to be configurable for each system.
18    Below is a list of the divider values followed by the systems that use it.
19   
20    * 228: System 11.
21    * 288: System 22, Super 22, NB-1/2, ND-1, FL.
22    * 296: System 23, Super 23.
23    * 332: System 12.
2416 */
2517
2618#include "emu.h"
r249036r249037
476468
477469void c352_device::device_start()
478470{
479   int i;
471   int i, divider;
480472   double x_max = 32752.0;
481473   double y_max = 127.0;
482474   double u = 10.0;
r249036r249037
484476   // find our direct access
485477   m_direct = &space().direct();
486478
487   m_sample_rate_base = clock() / m_divider;
479   switch(m_divider)
480   {
481      case C352_DIVIDER_228:
482         divider=228;
483         break;
484      case C352_DIVIDER_288:
485      default:
486         divider=288;
487         break;
488      case C352_DIVIDER_332:
489         divider=332;
490         break;
491   }
488492
493   m_sample_rate_base = clock() / divider;
494
489495   m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base);
490496
491497   // generate mulaw table for mulaw format samples
trunk/src/emu/sound/c352.h
r249036r249037
66#define __C352_H__
77
88//**************************************************************************
9//  CONSTANTS
10//**************************************************************************
11
12enum
13{
14   C352_DIVIDER_228 = 0,
15   C352_DIVIDER_288 = 1,
16   C352_DIVIDER_332 = 2
17};
18
19//**************************************************************************
920//  INTERFACE CONFIGURATION MACROS
1021//**************************************************************************
1122
trunk/src/emu/sound/tms5110.c
r249036r249037
1414
1515     Todo:
1616        - implement CS
17        - implement missing commands
1718        - TMS5110_CMD_TEST_TALK is only partially implemented
1819
1920     TMS5100:
r249036r249037
211212{
212213   save_item(NAME(m_variant));
213214
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
214220   save_item(NAME(m_PDC));
215221   save_item(NAME(m_CTL_pins));
216222   save_item(NAME(m_SPEN));
r249036r249037
235241   save_item(NAME(m_old_frame_pitch_idx));
236242   save_item(NAME(m_old_frame_k_idx));
237243   save_item(NAME(m_old_zpar));
238   save_item(NAME(m_old_uv_zpar));
239244#endif
240245   save_item(NAME(m_current_energy));
241246   save_item(NAME(m_current_pitch));
r249036r249037
305310}
306311#endif
307312
313
308314/******************************************************************************************
309315
310     extract_bits -- extract a specific number of bits from the VSM
316     FIFO_data_write -- handle bit data write to the TMS5110 (as a result of toggling M0 pin)
311317
312318******************************************************************************************/
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 */
313325
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
314343int tms5110_device::extract_bits(int count)
315344{
316345   int val = 0;
317   if (DEBUG_5110) logerror("requesting %d bits", count);
318   for (int i = 0; i < count; i++)
346   if (DEBUG_5110) logerror("requesting %d bits from fifo: ", count);
347   while (count--)
319348   {
320      val = (val<<1) | new_int_read();
321      if (DEBUG_5110) logerror("bit read: %d\n", val&1);
349      val = (val << 1) | (m_fifo[m_fifo_head] & 1);
350      m_fifo_count--;
351      m_fifo_head = (m_fifo_head + 1) % FIFO_SIZE;
322352   }
323353   if (DEBUG_5110) logerror("returning: %02x\n", val);
324354   return val;
325355}
326356
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}
327366
328367void tms5110_device::perform_dummy_read()
329368{
r249036r249037
350389   int i, bitout;
351390   INT32 this_sample;
352391
392   /* if we're not speaking, fill with nothingness */
393   if (!m_TALKD)
394      goto empty;
395
353396   /* loop until the buffer is full or we've stopped speaking */
354   while (size > 0)
397   while ((size > 0) && m_TALKD)
355398   {
356      if(m_TALKD) // speaking
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))
357407      {
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
408         m_OLDE = (m_new_frame_energy_idx == 0);
409         m_OLDP = (m_new_frame_pitch_idx == 0);
410      }
367411
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
368422#ifdef PERFECT_INTERPOLATION_HACK
369            /* remember previous frame energy, pitch, and coefficients */
370            m_old_frame_energy_idx = m_new_frame_energy_idx;
371            m_old_frame_pitch_idx = m_new_frame_pitch_idx;
372            for (i = 0; i < m_coeff->num_k; i++)
373               m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
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];
374428#endif
375429
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
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");
388434#endif
389            m_zpar = 0;
390            //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110
391            m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100
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;
392437
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            }
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         }
398443
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;
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;
411456
412457#ifdef DEBUG_GENERATION
413            /* Debug info for current parsed frame */
414            fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
415            fprintf(stderr,"Processing new frame: ");
416            if (m_inhibit == 0)
417               fprintf(stderr, "Normal Frame\n");
418            else
419               fprintf(stderr,"Interpolation Inhibited\n");
420            fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]);
421            fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
422               (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)),
423               m_new_frame_energy_idx,
424               (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)),
425               (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)),
426               (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)),
427               (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)),
428               (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)),
429               (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)),
430               (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)),
431               (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)),
432               (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)),
433               (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)),
434               (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) );
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)) );
435480#endif
436481
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;
437505         }
438         else // Not a new frame, just interpolate the existing frame.
506         else // we're done, play this frame for 1/8 frame.
439507         {
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));
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));
449510            for (i = 0; i < m_coeff->num_k; i++)
450               m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar)));
451            // now adjust each value to be exactly correct for each of the samples per frame
452            if (m_IP != 0) // if we're still interpolating...
453            {
454               m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
455               m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
456               for (i = 0; i < m_coeff->num_k; i++)
457                  m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar));
458            }
459            else // we're done, play this frame for 1/8 frame.
460            {
461               m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar));
462               m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar));
463               for (i = 0; i < m_coeff->num_k; i++)
464                  m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
465            }
511               m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
512         }
466513#else
467            //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
468            if (m_subcycle == 2)
514         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
515         if (m_subcycle == 2)
516         {
517            switch(m_PC)
469518            {
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               }
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;
486531            }
532         }
487533#endif
488         }
534      }
489535
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         }
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      }
513559
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 */
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 */
525571#ifdef DEBUG_GENERATION_VERBOSE
526         //fprintf(stderr,"C:%01d; ",m_subcycle);
527         fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
528         //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
529         for (i=0; i<10; i++)
530            fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
531         fprintf(stderr,"Out:%06d ", this_sample);
532//#ifdef PERFECT_INTERPOLATION_HACK
533//         fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar);
534//#else
535//         fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar);
536//#endif
537         fprintf(stderr,"\n");
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");
538579#endif
539         /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
540         while (this_sample > 16383) this_sample -= 32768;
541         while (this_sample < -16384) this_sample += 32768;
542         if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
543            buffer[buf_count] = clip_analog(this_sample);
544         else // digital I/O pin output is 12 bits
545         {
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      {
546587#ifdef ALLOW_4_LSB
547            // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
548            // N taps:                       ^                 = 0x2000;
549            // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
550            buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
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);
551592#else
552            this_sample &= ~0xF;
553            // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
554            // N taps:                       ^^ ^^^            = 0x3E00;
555            // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
556            buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
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);
557598#endif
558         }
559         // Update all counts
599      }
600      // Update all counts
560601
561         m_subcycle++;
562         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
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
563620         {
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. */
621            /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
580622#ifdef DEBUG_GENERATION
581               if (m_TALK == 0)
582                  fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
623            if (m_TALK == 0)
624               fprintf(stderr,"tms5110_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
583625#endif
584               m_TALKD = m_TALK; // TALKD is latched from TALK
585               m_TALK = m_SPEN; // TALK is latched from SPEN
586            }
587            m_subcycle = m_subc_reload;
588            m_PC = 0;
589            m_IP++;
590            m_IP&=0x7;
626            m_TALKD = m_TALK; // TALKD is latched from TALK
627            m_TALK = m_SPEN; // TALK is latched from SPEN
591628         }
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;
629         m_subcycle = m_subc_reload;
630         m_PC = 0;
631         m_IP++;
632         m_IP&=0x7;
600633      }
601      else // m_TALKD == 0
634      else if (m_subcycle == 3)
602635      {
603         m_subcycle++;
604         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
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
605654         {
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;
655            m_TALKD = m_TALK; // TALKD is latched from TALK
656            m_TALK = m_SPEN; // TALK is latched from SPEN
615657         }
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) */
658         m_subcycle = m_subc_reload;
659         m_PC = 0;
660         m_IP++;
661         m_IP&=0x7;
622662      }
623   buf_count++;
624   size--;
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--;
625671   }
626672}
627673
r249036r249037
853899               m_SPEN = 1; /* start immediately */
854900               /* clear out variables before speaking */
855901               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
863902               m_subc_reload = 0; // SPKSLOW means this is 0
903               m_subcycle = m_subc_reload;
904               m_PC = 0;
905               m_IP = 0;
864906               break;
865907
866908            case TMS5110_CMD_READ_BIT:
r249036r249037
874916#ifdef DEBUG_COMMAND_DUMP
875917                  fprintf(stderr,"actually reading a bit now\n");
876918#endif
919                  request_bits(1);
877920                  m_CTL_buffer >>= 1;
878921                  m_CTL_buffer |= (extract_bits(1)<<3);
879922                  m_CTL_buffer &= 0xF;
r249036r249037
888931               m_SPEN = 1; /* start immediately */
889932               /* clear out variables before speaking */
890933               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
898934               m_subc_reload = 1; // SPEAK means this is 1
935               m_subcycle = m_subc_reload;
936               m_PC = 0;
937               m_IP = 0;
899938               break;
900939
901940            case TMS5110_CMD_READ_BRANCH:
r249036r249037
940979
941980void tms5110_device::parse_frame()
942981{
943   int i, rep_flag;
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;
944986
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   }
945994   // attempt to extract the energy index
946995   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
947996#ifdef DEBUG_PARSE_FRAME_DUMP
r249036r249037
949998   fprintf(stderr," ");
950999#endif
9511000
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   }*/
9521022   // if the energy index is 0 or 15, we're done
9531023   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
9541024      return;
9551025
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   }
9561034   rep_flag = extract_bits(1);
9571035#ifdef DEBUG_PARSE_FRAME_DUMP
9581036   printbits(rep_flag, 1);
9591037   fprintf(stderr," ");
9601038#endif
9611039
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   }
9621047   m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits);
9631048#ifdef DEBUG_PARSE_FRAME_DUMP
9641049   printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits);
r249036r249037
9711056   // extract first 4 K coefficients
9721057   for (i = 0; i < 4; i++)
9731058   {
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      }
9741066      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
9751067#ifdef DEBUG_PARSE_FRAME_DUMP
9761068      printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
r249036r249037
9881080   // If we got here, we need the remaining 6 K's
9891081   for (i = 4; i < m_coeff->num_k; i++)
9901082   {
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      }
9911089      m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
9921090#ifdef DEBUG_PARSE_FRAME_DUMP
9931091      printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
9941092      fprintf(stderr," ");
9951093#endif
9961094   }
997#ifdef DEBUG_PARSE_FRAME_DUMP
998         fprintf(stderr,"\n");
999#endif
10001095#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
10011099      logerror("Parsed a frame successfully in ROM\n");
10021100#endif
10031101   return;
r249036r249037
11411239void tms5110_device::device_reset()
11421240{
11431241   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;
11441245
11451246   /* initialize the chip state */
11461247   m_SPEN = m_TALK = m_TALKD = 0;
r249036r249037
11531254#ifdef PERFECT_INTERPOLATION_HACK
11541255   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
11551256   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1156   m_old_zpar = m_old_uv_zpar = 0;
1257   m_old_zpar = 0;
11571258#endif
11581259   m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0;
11591260   m_new_frame_pitch_idx = m_current_pitch = 0;
r249036r249037
12901391}
12911392
12921393
1394
12931395/******************************************************************************
12941396
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
12951412     tms5110_update -- update the sound chip so that it is in sync with CPU execution
12961413
12971414******************************************************************************/
trunk/src/emu/sound/tms5110.h
r249036r249037
77
88#include "emu.h"
99
10/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
11#undef PERFECT_INTERPOLATION_HACK
10#define FIFO_SIZE               64 // TODO: technically the tms51xx chips don't have a fifo at all
1211
1312/* TMS5110 commands */
1413                              /* CTL8  CTL4  CTL2  CTL1  |   PDC's  */
r249036r249037
1615#define TMS5110_CMD_RESET        (0) /*    0     0     0     x  |     1    */
1716#define TMS5110_CMD_LOAD_ADDRESS (2) /*    0     0     1     x  |     2    */
1817#define TMS5110_CMD_OUTPUT       (4) /*    0     1     0     x  |     3    */
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. */
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. */
2019#define TMS5110_CMD_READ_BIT     (8) /*    1     0     0     x  |     1    */
2120#define TMS5110_CMD_SPEAK       (10) /*    1     0     1     x  |     1    */
2221#define TMS5110_CMD_READ_BRANCH (12) /*    1     1     0     x  |     1    */
r249036r249037
6564    */
6665   DECLARE_READ8_MEMBER( romclk_hack_r );
6766
67   int ready_r();
6868   void set_frequency(int frequency);
6969
7070   int _speech_rom_read_bit();
r249036r249037
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);
9697   int extract_bits(int count);
98   void request_bits(int no);
9799   void perform_dummy_read();
98100   INT32 lattice_filter();
99101   void process(INT16 *buffer, unsigned int size);
r249036r249037
107109   /* coefficient tables */
108110   const struct tms5100_coeffs *m_coeff;
109111
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
110118   /* these contain global status bits */
111119   UINT8 m_PDC;
112120   UINT8 m_CTL_pins;
r249036r249037
154162   UINT8 m_old_frame_pitch_idx;
155163   UINT8 m_old_frame_k_idx[10];
156164   UINT8 m_old_zpar;
157   UINT8 m_old_uv_zpar;
158165
159166   INT32 m_current_energy;
160167   INT32 m_current_pitch;
trunk/src/emu/sound/tms5220.c
r249036r249037
271271 * or clip logic, even though the real hardware doesn't do this, partially verified by decap */
272272#undef ALLOW_4_LSB
273273
274/* forces m_TALK active instantly whenever m_SPEN would be activated, causing speech delay to be reduced by up to one frame time */
275/* for some reason, this hack makes victory behave better, though it does not match the patent */
276#define FAST_START_HACK 1
277274
278
279275/* *****configuration of chip connection stuff***** */
280276/* must be defined; if 0, output the waveform as if it was tapped on the speaker pin as usual, if 1, output the waveform as if it was tapped on the i/o pin (volume is much lower in the latter case) */
281277#define FORCE_DIGITAL 0
r249036r249037
365361   save_item(NAME(m_fifo_count));
366362   save_item(NAME(m_fifo_bits_taken));
367363
368   save_item(NAME(m_previous_TALK_STATUS));
369   save_item(NAME(m_SPEN));
370   save_item(NAME(m_DDIS));
371   save_item(NAME(m_TALK));
372   save_item(NAME(m_TALKD));
364   save_item(NAME(m_speaking_now));
365   save_item(NAME(m_speak_external));
366   save_item(NAME(m_talk_status));
373367   save_item(NAME(m_buffer_low));
374368   save_item(NAME(m_buffer_empty));
375369   save_item(NAME(m_irq_pin));
r249036r249037
390384   save_item(NAME(m_current_pitch));
391385   save_item(NAME(m_current_k));
392386
387   save_item(NAME(m_target_energy));
388   save_item(NAME(m_target_pitch));
389   save_item(NAME(m_target_k));
390
393391   save_item(NAME(m_previous_energy));
394392
395393   save_item(NAME(m_subcycle));
r249036r249037
397395   save_item(NAME(m_PC));
398396   save_item(NAME(m_IP));
399397   save_item(NAME(m_inhibit));
400   save_item(NAME(m_uv_zpar));
401   save_item(NAME(m_zpar));
402   save_item(NAME(m_pitch_zero));
403398   save_item(NAME(m_c_variant_rate));
404399   save_item(NAME(m_pitch_count));
405400
r249036r249037
470465
471466void tms5220_device::data_write(int data)
472467{
473   int old_buffer_low = m_buffer_low;
474468#ifdef DEBUG_DUMP_INPUT_DATA
475469   fprintf(stdout, "%c",data);
476470#endif
477   if (m_DDIS) // If we're in speak external mode
471   if (m_speak_external) // If we're in speak external mode
478472   {
479473      // add this byte to the FIFO
480474      if (m_fifo_count < FIFO_SIZE)
r249036r249037
483477         m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE;
484478         m_fifo_count++;
485479#ifdef DEBUG_FIFO
486         fprintf(stderr,"data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
480         logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count);
487481#endif
488482         update_fifo_status_and_ints();
489         // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12)
490         if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT
483         if ((m_talk_status == 0) && (m_buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
491484         {
492            int i;
485         int i;
493486#ifdef DEBUG_FIFO
494            fprintf(stderr,"data_write triggered SPEN to go active!\n");
487         logerror("data_write triggered talk status to go active!\n");
495488#endif
496            // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() )
497            m_zpar = 1;
498            m_uv_zpar = 1; // zero k4-k10 as well
499            m_OLDE = 1; // 'silence/zpar' frames are zero energy
500            m_OLDP = 1; // 'silence/zpar' frames are zero pitch
501#ifdef PERFECT_INTERPOLATION_HACK
502            m_old_zpar = 1; // zero all the old parameters
503            m_old_uv_zpar = 1; // zero old k4-k10 as well
504#endif
505            m_SPEN = 1;
506#ifdef FAST_START_HACK
507            m_TALK = 1;
508#endif
489            // ...then we now have enough bytes to start talking; clear out the new frame parameters (it will become old frame just before the first call to parse_frame() )
490            // TODO: the 3 lines below (and others) are needed for victory to not fail its selftest due to a sample ending too late, may require additional investigation
491            m_subcycle = m_subc_reload;
492            m_PC = 0;
493            m_IP = reload_table[m_c_variant_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
509494            m_new_frame_energy_idx = 0;
510495            m_new_frame_pitch_idx = 0;
511496            for (i = 0; i < 4; i++)
r249036r249037
514499               m_new_frame_k_idx[i] = 0xF;
515500            for (i = 7; i < m_coeff->num_k; i++)
516501               m_new_frame_k_idx[i] = 0x7;
517
502            m_talk_status = m_speaking_now = 1;
518503         }
519504      }
520505      else
521506      {
522507#ifdef DEBUG_FIFO
523         fprintf(stderr,"data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
508         logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
524509         // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it.
525510#endif
526511      }
527512
528513
529514   }
530   else //(! m_DDIS)
515   else //(! m_speak_external)
531516      // R Nabet : we parse commands at once.  It is necessary for such commands as read.
532517      process_command(data);
533518}
r249036r249037
575560      m_buffer_low = 0;
576561
577562   /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
578   translates to having fifo_count equal to exactly 0
579   */
563   translates to having fifo_count equal to exactly 0 */
580564   if (m_fifo_count == 0)
581565   {
582566      // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
583567      if (!m_buffer_empty)
584568         set_interrupt_state(1);
585569      m_buffer_empty = 1;
586      m_TALK = m_SPEN = 0; // /BE being active clears the TALK(TCON) status which in turn clears SPEN
587570   }
588571   else
589572      m_buffer_empty = 0;
590573
591   // generate an interrupt if /TS was active, and is now inactive.
592   // also, in this case, regardless if DDIS was set, unset it.
593   if (m_previous_TALK_STATUS == 1 && (TALK_STATUS == 0))
574   /* TS is talk status and is set elsewhere in the fifo parser and in
575   the SPEAK command handler; however, if /BE is true during speak external
576   mode, it is immediately unset here. */
577   if ((m_speak_external == 1) && (m_buffer_empty == 1))
594578   {
595#ifdef VERBOSE
596      fprintf(stderr,"Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n");
597#endif
598      set_interrupt_state(1);
599      m_DDIS = 0;
579      // generate an interrupt: /TS was active, and is now inactive.
580      if (m_talk_status == 1)
581      {
582         m_talk_status = m_speak_external = 0;
583         set_interrupt_state(1);
584      }
600585   }
601   m_previous_TALK_STATUS = TALK_STATUS;
602
586   /* Note that TS being unset will also generate an interrupt when a STOP
587   frame is encountered; this is handled in the sample generator code and not here */
603588}
604589
605590/**********************************************************************************************
r249036r249037
612597{
613598   int val = 0;
614599
615   if (m_DDIS)
600   if (m_speak_external)
616601   {
617602      // extract from FIFO
618603      while (count--)
r249036r249037
658643      /* clear the interrupt pin on status read */
659644      set_interrupt_state(0);
660645#ifdef DEBUG_PIN_READS
661      fprintf(stderr,"Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty);
646      logerror("Status read: TS=%d BL=%d BE=%d\n", m_talk_status, m_buffer_low, m_buffer_empty);
662647#endif
663648
664      return (TALK_STATUS << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
649      return (m_talk_status << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5);
665650   }
666651}
667652
r249036r249037
675660int tms5220_device::ready_read()
676661{
677662#ifdef DEBUG_PIN_READS
678   fprintf(stderr,"ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS);
663   logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", m_io_ready, m_fifo_count);
679664#endif
680   return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready;
665   return ((m_fifo_count < FIFO_SIZE)||(!m_speak_external)) && m_io_ready;
681666}
682667
683668
r249036r249037
733718int tms5220_device::int_read()
734719{
735720#ifdef DEBUG_PIN_READS
736   fprintf(stderr,"int_read: irq pin read, state is %d\n", m_irq_pin);
721   logerror("int_read: irq pin read, state is %d\n", m_irq_pin);
737722#endif
738723   return m_irq_pin;
739724}
r249036r249037
748733void tms5220_device::process(INT16 *buffer, unsigned int size)
749734{
750735   int buf_count=0;
751   int i, bitout;
736   int i, bitout, zpar;
752737   INT32 this_sample;
753738
754#ifdef VERBOSE
755   fprintf(stderr,"process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
756#endif
739   /* the following gotos are probably safe to remove */
740   /* if we're empty and still not speaking, fill with nothingness */
741   if (!m_speaking_now)
742      goto empty;
757743
744   /* if speak external is set, but talk status is not (yet) set,
745   wait for buffer low to clear */
746   if (!m_talk_status && m_speak_external && m_buffer_low)
747      goto empty;
748
758749   /* loop until the buffer is full or we've stopped speaking */
759   while (size > 0)
750   while ((size > 0) && m_speaking_now)
760751   {
761      if(m_TALKD) // speaking
752      /* if it is the appropriate time to update the old energy/pitch indices,
753       * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
754       * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
755       * which happens 4 T-cycles later), we change on the latter.
756       * The indices are updated here ~12 PCs before the new frame is applied.
757       */
758      /** TODO: the patents 4331836, 4335277, and 4419540 disagree about the timing of this **/
759      if ((m_IP == 0) && (m_PC == 0) && (m_subcycle < 2))
762760      {
763         /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
764         * (In reality, the frame was really loaded incrementally during the entire IP=0
765         * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
766         */
767         if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
768         {
769            // HACK for regression testing, be sure to comment out before release!
770            //m_RNG = 0x1234;
771            // end HACK
761         m_OLDE = (m_new_frame_energy_idx == 0);
762         m_OLDP = (m_new_frame_pitch_idx == 0);
763      }
772764
773            /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
774            m_IP = reload_table[m_c_variant_rate&0x3];
765      /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
766       * (In reality, the frame was really loaded incrementally during the entire IP=0
767       * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
768       */
769      if ((m_IP == 0) && (m_PC == 12) && (m_subcycle == 1))
770      {
771         // HACK for regression testing, be sure to comment out before release!
772         //m_RNG = 0x1234;
773         // end HACK
775774
775         /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
776         m_IP = reload_table[m_c_variant_rate&0x3];
777
776778#ifdef PERFECT_INTERPOLATION_HACK
777            /* remember previous frame energy, pitch, and coefficients */
778            m_old_frame_energy_idx = m_new_frame_energy_idx;
779            m_old_frame_pitch_idx = m_new_frame_pitch_idx;
780            for (i = 0; i < m_coeff->num_k; i++)
781               m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
779         /* remember previous frame energy, pitch, and coefficients */
780         m_old_frame_energy_idx = m_new_frame_energy_idx;
781         m_old_frame_pitch_idx = m_new_frame_pitch_idx;
782         for (i = 0; i < m_coeff->num_k; i++)
783            m_old_frame_k_idx[i] = m_new_frame_k_idx[i];
782784#endif
783785
784            /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
785            parse_frame();
786         /* if the talk status was clear last frame, halt speech now. */
787         if (m_talk_status == 0)
788         {
789#ifdef DEBUG_GENERATION
790            fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n");
791#endif
792            if (m_speaking_now == 1) // we're done, set all coeffs to idle state but keep going for a bit...
793            {
794               /**TODO: should index clearing be done here, or elsewhere? **/
795               m_new_frame_energy_idx = 0;
796               m_new_frame_pitch_idx = 0;
797               for (i = 0; i < 4; i++)
798                  m_new_frame_k_idx[i] = 0;
799               for (i = 4; i < 7; i++)
800                  m_new_frame_k_idx[i] = 0xF;
801               for (i = 7; i < m_coeff->num_k; i++)
802                  m_new_frame_k_idx[i] = 0x7;
803               m_speaking_now = 2; // wait 8 extra interp periods before shutting down so we can interpolate everything to zero state
804            }
805            else // m_speaking_now == 2 // now we're really done.
806            {
807               m_speaking_now = 0; // finally halt speech
808               goto empty;
809            }
810         }
786811
787            // if the new frame is unvoiced (or silenced via ZPAR), be sure to zero out the k5-k10 parameters
788            // NOTE: this is probably the bug the tms5100/tmc0280 has, pre-rev D, I think.
789            // GUESS: Pre-rev D versions start zeroing k5-k10 immediately upon new frame load regardless of interpolation inhibit
790            // I.e. ZPAR = /TALKD || (PC>5&&P=0)
791            // GUESS: D and later versions only start or stop zeroing k5-k10 at the IP7->IP0 transition AFTER the frame
792            // I.e. ZPAR = /TALKD || (PC>5&&OLDP)
793#ifdef PERFECT_INTERPOLATION_HACK
794            m_old_uv_zpar = m_uv_zpar;
795            m_old_zpar = m_zpar; // unset old zpar on new frame
812
813         /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[],
814          * but only if we're not just about to end speech */
815         if (m_speaking_now == 1) parse_frame();
816#ifdef DEBUG_PARSE_FRAME_DUMP
817         fprintf(stderr,"\n");
796818#endif
797            m_zpar = 0;
798            //m_uv_zpar = (OLD_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: fixed version in tmc0280d/tms5100a/cd280x/tms5110
799            m_uv_zpar = (NEW_FRAME_UNVOICED_FLAG||m_zpar); // GUESS: buggy version in tmc0280/tms5100
800819
801            /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */
802            if (NEW_FRAME_STOP_FLAG == 1)
820         /* if the new frame is a stop frame, set an interrupt and set talk status to 0 */
821         /** TODO: investigate this later! **/
822         if (NEW_FRAME_STOP_FLAG == 1)
803823            {
804               m_TALK = m_SPEN = 0;
824               m_talk_status = m_speak_external = 0;
825               set_interrupt_state(1);
826               update_fifo_status_and_ints();
805827            }
806828
807            /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
808            Interpolation inhibit cases:
809            * Old frame was voiced, new is unvoiced
810            * Old frame was silence/zero energy, new has nonzero energy
811            * Old frame was unvoiced, new is voiced
812            * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx)
813            */
814            if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
815               || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0))
816               || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0))
817               || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) )
818               m_inhibit = 1;
819            else // normal frame, normal interpolation
820               m_inhibit = 0;
829         /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
830            Interpolation inhibit cases:
831          * Old frame was voiced, new is unvoiced
832          * Old frame was silence/zero energy, new has nonzero energy
833          * Old frame was unvoiced, new is voiced
834          * Old frame was unvoiced, new frame is silence/zero energy (unique to tms52xx)
835          */
836         if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
837            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0))
838            || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0))
839            || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 1)) )
840            m_inhibit = 1;
841         else // normal frame, normal interpolation
842            m_inhibit = 0;
821843
844         /* load new frame targets from tables, using parsed indices */
845         m_target_energy = m_coeff->energytable[m_new_frame_energy_idx];
846         m_target_pitch = m_coeff->pitchtable[m_new_frame_pitch_idx];
847         zpar = NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed
848         for (i = 0; i < 4; i++)
849            m_target_k[i] = m_coeff->ktable[i][m_new_frame_k_idx[i]];
850         for (i = 4; i < m_coeff->num_k; i++)
851            m_target_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-zpar));
852
822853#ifdef DEBUG_GENERATION
823            /* Debug info for current parsed frame */
824            fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
825            fprintf(stderr,"Processing new frame: ");
826            if (m_inhibit == 0)
827               fprintf(stderr, "Normal Frame\n");
828            else
829               fprintf(stderr,"Interpolation Inhibited\n");
830            fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]);
831            fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",
832               (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)),
833               m_new_frame_energy_idx,
834               (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)),
835               (m_coeff->ktable[0][m_new_frame_k_idx[0]] * (1-m_zpar)),
836               (m_coeff->ktable[1][m_new_frame_k_idx[1]] * (1-m_zpar)),
837               (m_coeff->ktable[2][m_new_frame_k_idx[2]] * (1-m_zpar)),
838               (m_coeff->ktable[3][m_new_frame_k_idx[3]] * (1-m_zpar)),
839               (m_coeff->ktable[4][m_new_frame_k_idx[4]] * (1-m_uv_zpar)),
840               (m_coeff->ktable[5][m_new_frame_k_idx[5]] * (1-m_uv_zpar)),
841               (m_coeff->ktable[6][m_new_frame_k_idx[6]] * (1-m_uv_zpar)),
842               (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)),
843               (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)),
844               (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) );
854         /* Debug info for current parsed frame */
855         fprintf(stderr, "OLDE: %d; OLDP: %d; ", m_OLDE, m_OLDP);
856         fprintf(stderr,"Processing frame: ");
857         if (m_inhibit == 0)
858            fprintf(stderr, "Normal Frame\n");
859         else
860            fprintf(stderr,"Interpolation Inhibited\n");
861         fprintf(stderr,"*** current Energy, Pitch and Ks =      %04d,   %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]);
862         fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_target_energy, m_new_frame_energy_idx, m_target_pitch, m_target_k[0], m_target_k[1], m_target_k[2], m_target_k[3], m_target_k[4], m_target_k[5], m_target_k[6], m_target_k[7], m_target_k[8], m_target_k[9]);
845863#endif
846864
847         }
848         else // Not a new frame, just interpolate the existing frame.
865         /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
866         if (m_talk_status == 0)
849867         {
850            int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value
851#ifdef PERFECT_INTERPOLATION_HACK
852            int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW
853            //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
854            int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
855            //fprintf(stderr, "CS: %03d", current_sample);
856            // reset the current energy, pitch, etc to what it was at frame start
857            m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar));
858            m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar));
859            for (i = 0; i < m_coeff->num_k; i++)
860               m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-((i<4)?m_old_zpar:m_old_uv_zpar)));
861            // now adjust each value to be exactly correct for each of the samples per frame
862            if (m_IP != 0) // if we're still interpolating...
863            {
864               m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
865               m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-m_zpar);
866               for (i = 0; i < m_coeff->num_k; i++)
867                  m_current_k[i] = (m_current_k[i] + (((m_coeff->ktable[i][m_new_frame_k_idx[i]] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame)*(1-((i<4)?m_zpar:m_uv_zpar));
868            }
869            else // we're done, play this frame for 1/8 frame.
870            {
871               m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar));
872               m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar));
873               for (i = 0; i < m_coeff->num_k; i++)
874                  m_current_k[i] = (m_coeff->ktable[i][m_new_frame_k_idx[i]] * (1-((i<4)?m_zpar:m_uv_zpar)));
875            }
876#else
877            //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
878            if (m_subcycle == 2)
879            {
880               switch(m_PC)
881               {
882                  case 0: /* PC = 0, B cycle, write updated energy */
883                  m_current_energy = (m_current_energy + (((m_coeff->energytable[m_new_frame_energy_idx] - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
884                  break;
885                  case 1: /* PC = 1, B cycle, write updated pitch */
886                  m_current_pitch = (m_current_pitch + (((m_coeff->pitchtable[m_new_frame_pitch_idx] - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT))*(1-m_zpar);
887                  break;
888                  case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
889                  /* PC = 2 through 11, B cycle, write updated K1 through K10 */
890                  m_current_k[m_PC-2] = (m_current_k[m_PC-2] + (((m_coeff->ktable[m_PC-2][m_new_frame_k_idx[m_PC-2]] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT))*(((m_PC-2)>4)?(1-m_uv_zpar):(1-m_zpar));
891                  break;
892                  case 12: /* PC = 12 */
893                  /* we should NEVER reach this point, PC=12 doesn't have a subcycle 2 */
894                  break;
895               }
896            }
868#ifdef DEBUG_GENERATION
869            fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
897870#endif
871            m_target_energy = 0;
898872         }
873      }
874      else // Not a new frame, just interpolate the existing frame.
875      {
876         int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value
877#ifdef PERFECT_INTERPOLATION_HACK
878         int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW
879         //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW
880         int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7));
899881
900         // calculate the output
901         if (OLD_FRAME_UNVOICED_FLAG == 1)
882         zpar = OLD_FRAME_UNVOICED_FLAG;
883         //fprintf(stderr, "CS: %03d", current_sample);
884         // reset the current energy, pitch, etc to what it was at frame start
885         m_current_energy = m_coeff->energytable[m_old_frame_energy_idx];
886         m_current_pitch = m_coeff->pitchtable[m_old_frame_pitch_idx];
887         for (i = 0; i < 4; i++)
888            m_current_k[i] = m_coeff->ktable[i][m_old_frame_k_idx[i]];
889         for (i = 4; i < m_coeff->num_k; i++)
890            m_current_k[i] = (m_coeff->ktable[i][m_old_frame_k_idx[i]] * (1-zpar));
891         // now adjust each value to be exactly correct for each of the samples per frame
892         if (m_IP != 0) // if we're still interpolating...
902893         {
903            // generate unvoiced samples here
904            if (m_RNG & 1)
905               m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/
906            else
907               m_excitation_data = 0x40;
894            m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
895            m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
896            for (i = 0; i < m_coeff->num_k; i++)
897               m_current_k[i] += (((m_target_k[i] - m_current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
908898         }
909         else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
899         else // we're done, play this frame for 1/8 frame.
910900         {
911            // generate voiced samples here
912            /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
913            * function has a chirp/peak and then a long chain of zeroes.
914            * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
915            * and if the address reaches that point the ADDRESS incrementer is
916            * disabled, forcing all samples beyond 51d to be == 51d
917            */
918            if (m_pitch_count >= 51)
919               m_excitation_data = (INT8)m_coeff->chirptable[51];
920            else /*m_pitch_count < 51*/
921               m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
901            m_current_energy = m_target_energy;
902            m_current_pitch = m_target_pitch;
903            for (i = 0; i < m_coeff->num_k; i++)
904               m_current_k[i] = m_target_k[i];
922905         }
923
924         // Update LFSR *20* times every sample (once per T cycle), like patent shows
925         for (i=0; i<20; i++)
906#else
907         //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
908         if (m_subcycle == 2)
926909         {
927            bitout = ((m_RNG >> 12) & 1) ^
928                  ((m_RNG >>  3) & 1) ^
929                  ((m_RNG >>  2) & 1) ^
930                  ((m_RNG >>  0) & 1);
931            m_RNG <<= 1;
932            m_RNG |= bitout;
910            switch(m_PC)
911            {
912               case 0: /* PC = 0, B cycle, write updated energy */
913               m_current_energy += (((m_target_energy - m_current_energy)*(1-inhibit_state)) INTERP_SHIFT);
914               break;
915               case 1: /* PC = 1, B cycle, write updated pitch */
916               m_current_pitch += (((m_target_pitch - m_current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
917               break;
918               case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
919               /* PC = 2 through 11, B cycle, write updated K1 through K10 */
920               m_current_k[m_PC-2] += (((m_target_k[m_PC-2] - m_current_k[m_PC-2])*(1-inhibit_state)) INTERP_SHIFT);
921               break;
922               case 12: /* PC = 12, do nothing */
923               break;
924            }
933925         }
934         this_sample = lattice_filter(); /* execute lattice filter */
926#endif
927      }
928
929      // calculate the output
930      if (OLD_FRAME_UNVOICED_FLAG == 1)
931      {
932         // generate unvoiced samples here
933         if (m_RNG & 1)
934            m_excitation_data = ~0x3F; /* according to the patent it is (either + or -) half of the maximum value in the chirp table, so either 01000000(0x40) or 11000000(0xC0)*/
935         else
936            m_excitation_data = 0x40;
937      }
938      else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
939      {
940         // generate voiced samples here
941         /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
942          * function has a chirp/peak and then a long chain of zeroes.
943          * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
944          * and if the address reaches that point the ADDRESS incrementer is
945          * disabled, forcing all samples beyond 51d to be == 51d
946          */
947         if (m_pitch_count >= 51)
948            m_excitation_data = (INT8)m_coeff->chirptable[51];
949         else /*m_pitch_count < 51*/
950            m_excitation_data = (INT8)m_coeff->chirptable[m_pitch_count];
951      }
952
953      // Update LFSR *20* times every sample (once per T cycle), like patent shows
954   for (i=0; i<20; i++)
955   {
956      bitout = ((m_RNG >> 12) & 1) ^
957            ((m_RNG >>  3) & 1) ^
958            ((m_RNG >>  2) & 1) ^
959            ((m_RNG >>  0) & 1);
960      m_RNG <<= 1;
961      m_RNG |= bitout;
962   }
963      this_sample = lattice_filter(); /* execute lattice filter */
935964#ifdef DEBUG_GENERATION_VERBOSE
936         //fprintf(stderr,"C:%01d; ",m_subcycle);
937         fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
938         //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
939         for (i=0; i<10; i++)
940            fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
941         fprintf(stderr,"Out:%06d ", this_sample);
942//#ifdef PERFECT_INTERPOLATION_HACK
943//         fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar);
944//#else
945//         fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar);
946//#endif
947         fprintf(stderr,"\n");
965      //fprintf(stderr,"C:%01d; ",m_subcycle);
966      fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
967      //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count);
968      for (i=0; i<10; i++)
969         fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]);
970      fprintf(stderr,"Out:%06d", this_sample);
971      fprintf(stderr,"\n");
948972#endif
949         /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
950         while (this_sample > 16383) this_sample -= 32768;
951         while (this_sample < -16384) this_sample += 32768;
952         if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
953            buffer[buf_count] = clip_analog(this_sample);
954         else // digital I/O pin output is 12 bits
955         {
973      /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
974      while (this_sample > 16383) this_sample -= 32768;
975      while (this_sample < -16384) this_sample += 32768;
976      if (m_digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
977         buffer[buf_count] = clip_analog(this_sample);
978      else // digital I/O pin output is 12 bits
979      {
956980#ifdef ALLOW_4_LSB
957            // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
958            // N taps:                       ^                 = 0x2000;
959            // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
960            buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
981         // input:  ssss ssss ssss ssss ssnn nnnn nnnn nnnn
982         // N taps:                       ^                 = 0x2000;
983         // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
984         buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
961985#else
962            this_sample &= ~0xF;
963            // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
964            // N taps:                       ^^ ^^^            = 0x3E00;
965            // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
966            buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
986         this_sample &= ~0xF;
987         // input:  ssss ssss ssss ssss ssnn nnnn nnnn 0000
988         // N taps:                       ^^ ^^^            = 0x3E00;
989         // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
990         buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
967991#endif
968         }
969         // Update all counts
992      }
993      // Update all counts
970994
971         m_subcycle++;
972         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
973         {
974            /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
975            * if INHIBIT was true during the most recent frame transition.
976            * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
977            * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
978            * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
979            * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
980            * convenient and should make no difference in output.
981            */
982            if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1;
983            if ((m_IP == 0)&&(m_pitch_zero==1)) m_pitch_zero = 0;
984            if (m_IP == 7) // RESETL4
985            {
986               // Latch OLDE and OLDP
987               OLD_FRAME_SILENCE_FLAG = NEW_FRAME_SILENCE_FLAG; // m_OLDE
988               OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // m_OLDP
989               /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */
990#ifdef DEBUG_GENERATION
991               fprintf(stderr,"RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
992#endif
993#ifdef DEBUG_GENERATION
994               if (m_TALK == 0)
995                  fprintf(stderr,"tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n");
996#endif
997               m_TALKD = m_TALK; // TALKD is latched from TALK
998               update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS is now inactive
999               m_TALK = m_SPEN; // TALK is latched from SPEN
1000#ifdef DEBUG_GENERATION
1001               fprintf(stderr,"RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD);
1002#endif
1003            }
1004            m_subcycle = m_subc_reload;
1005            m_PC = 0;
1006            m_IP++;
1007            m_IP&=0x7;
1008         }
1009         else if (m_subcycle == 3)
1010         {
1011            m_subcycle = m_subc_reload;
1012            m_PC++;
1013         }
1014         m_pitch_count++;
1015         if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0;
1016         m_pitch_count &= 0x1FF;
995      m_subcycle++;
996      if ((m_subcycle == 2) && (m_PC == 12))
997      {
998         /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
999          * if INHIBIT was true during the most recent frame transition.
1000          * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
1001          * and m_IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
1002          * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
1003          * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
1004          * convenient and should make no difference in output.
1005          */
1006         if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_count = 0;
1007         m_subcycle = m_subc_reload;
1008         m_PC = 0;
1009         m_IP++;
1010         m_IP&=0x7;
10171011      }
1018      else // m_TALKD == 0
1012      else if (m_subcycle == 3)
10191013      {
1020         m_subcycle++;
1021         if ((m_subcycle == 2) && (m_PC == 12)) // RESETF3
1022         {
1023            if (m_IP == 7) // RESETL4
1024            {
1025               m_TALKD = m_TALK; // TALKD is latched from TALK
1026               m_TALK = m_SPEN; // TALK is latched from SPEN
1027            }
1028            m_subcycle = m_subc_reload;
1029            m_PC = 0;
1030            m_IP++;
1031            m_IP&=0x7;
1032         }
1033         else if (m_subcycle == 3)
1034         {
1035            m_subcycle = m_subc_reload;
1036            m_PC++;
1037         }
1038         buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
1014         m_subcycle = m_subc_reload;
1015         m_PC++;
10391016      }
1040   buf_count++;
1041   size--;
1017      m_pitch_count++;
1018      if (m_pitch_count >= m_current_pitch) m_pitch_count = 0;
1019      m_pitch_count &= 0x1FF;
1020      buf_count++;
1021      size--;
10421022   }
1023
1024empty:
1025
1026   while (size > 0)
1027   {
1028      m_subcycle++;
1029      if ((m_subcycle == 2) && (m_PC == 12))
1030      {
1031         m_subcycle = m_subc_reload;
1032         m_PC = 0;
1033         m_IP++;
1034         m_IP&=0x7;
1035      }
1036      else if (m_subcycle == 3)
1037      {
1038         m_subcycle = m_subc_reload;
1039         m_PC++;
1040      }
1041      buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
1042      buf_count++;
1043      size--;
1044   }
10431045}
10441046
10451047/**********************************************************************************************
r249036r249037
11801182
11811183void tms5220_device::process_command(unsigned char cmd)
11821184{
1183   int i;
11841185#ifdef DEBUG_COMMAND_DUMP
11851186      fprintf(stderr,"process_command called with parameter %02X\n",cmd);
11861187#endif
r249036r249037
11881189      switch (cmd & 0x70)
11891190      {
11901191      case 0x10 : /* read byte */
1191         if (TALK_STATUS == 0) /* TALKST must be clear for RDBY */
1192         if (m_talk_status == 0) /* TALKST must be clear for RDBY */
11921193         {
11931194            if (m_schedule_dummy_read)
11941195            {
r249036r249037
12101211      break;
12111212
12121213      case 0x30 : /* read and branch */
1213         if (TALK_STATUS == 0) /* TALKST must be clear for RB */
1214         if (m_talk_status == 0) /* TALKST must be clear for RB */
12141215         {
12151216#ifdef VERBOSE
1216            fprintf(stderr,"read and branch command received\n");
1217            logerror("read and branch command received\n");
12171218#endif
12181219            m_RDB_flag = FALSE;
12191220            if (m_speechrom)
r249036r249037
12221223         break;
12231224
12241225      case 0x40 : /* load address */
1225         if (TALK_STATUS == 0) /* TALKST must be clear for LA */
1226         if (m_talk_status == 0) /* TALKST must be clear for LA */
12261227         {
12271228            /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
12281229               This code does not care about this. */
r249036r249037
12391240            if (m_speechrom)
12401241               m_speechrom->read(1);
12411242         }
1242         m_SPEN = 1;
1243#ifdef FAST_START_HACK
1244         m_TALK = 1;
1245#endif
1246         m_DDIS = 0;
1247         m_zpar = 1; // zero all the parameters
1248         m_uv_zpar = 1; // zero k4-k10 as well
1249         m_OLDE = 1; // 'silence/zpar' frames are zero energy
1250         m_OLDP = 1; // 'silence/zpar' frames are zero pitch
1251#ifdef PERFECT_INTERPOLATION_HACK
1252         m_old_zpar = 1; // zero all the old parameters
1253         m_old_uv_zpar = 1; // zero old k4-k10 as well
1254#endif
1255         // following is semi-hack but matches idle state observed on chip
1243         m_speaking_now = 1;
1244         m_speak_external = 0;
1245         m_talk_status = 1;  /* start immediately */
1246         /* clear out variables before speaking */
1247         // TODO: similar to the victory case described above, but for VSM speech
1248         m_subcycle = m_subc_reload;
1249         m_PC = 0;
1250         m_IP = reload_table[m_c_variant_rate&0x3];
12561251         m_new_frame_energy_idx = 0;
12571252         m_new_frame_pitch_idx = 0;
1253         int i;
12581254         for (i = 0; i < 4; i++)
12591255            m_new_frame_k_idx[i] = 0;
12601256         for (i = 4; i < 7; i++)
r249036r249037
12641260         break;
12651261
12661262      case 0x60 : /* speak external */
1267         // SPKEXT going active activates SPKEE which clears the fifo
1263         //SPKEXT going active activates SPKEE which clears the fifo
12681264         m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0;
1269         // SPEN is enabled when the fifo passes half full (falling edge of BL signal)
1270         m_DDIS = 1;
1271         m_zpar = 1; // zero all the parameters
1272         m_uv_zpar = 1; // zero k4-k10 as well
1273         m_OLDE = 1; // 'silence/zpar' frames are zero energy
1274         m_OLDP = 1; // 'silence/zpar' frames are zero pitch
1275#ifdef PERFECT_INTERPOLATION_HACK
1276         m_old_zpar = 1; // zero all the old parameters
1277         m_old_uv_zpar = 1; // zero old k4-k10 as well
1278#endif
1279         // following is semi-hack but matches idle state observed on chip
1280         m_new_frame_energy_idx = 0;
1281         m_new_frame_pitch_idx = 0;
1282         for (i = 0; i < 4; i++)
1283            m_new_frame_k_idx[i] = 0;
1284         for (i = 4; i < 7; i++)
1285            m_new_frame_k_idx[i] = 0xF;
1286         for (i = 7; i < m_coeff->num_k; i++)
1287            m_new_frame_k_idx[i] = 0x7;
1265         m_speak_external = 1;
12881266         m_RDB_flag = FALSE;
12891267         break;
12901268
r249036r249037
13301308   m_IP = reload_table[m_c_variant_rate&0x3];
13311309
13321310   update_fifo_status_and_ints();
1333   if (m_DDIS && m_buffer_empty) goto ranout;
1311   if (!m_talk_status) goto ranout;
13341312
13351313   // attempt to extract the energy index
13361314   m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
r249036r249037
13391317   fprintf(stderr," ");
13401318#endif
13411319   update_fifo_status_and_ints();
1342   if (m_DDIS && m_buffer_empty) goto ranout;
1320   if (!m_talk_status) goto ranout;
13431321   // if the energy index is 0 or 15, we're done
13441322   if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
13451323      return;
r249036r249037
13591337   fprintf(stderr," ");
13601338#endif
13611339   update_fifo_status_and_ints();
1362   if (m_DDIS && m_buffer_empty) goto ranout;
1340   if (!m_talk_status) goto ranout;
13631341   // if this is a repeat frame, just do nothing, it will reuse the old coefficients
13641342   if (rep_flag)
13651343      return;
r249036r249037
13731351      fprintf(stderr," ");
13741352#endif
13751353      update_fifo_status_and_ints();
1376      if (m_DDIS && m_buffer_empty) goto ranout;
1354      if (!m_talk_status) goto ranout;
13771355   }
13781356
13791357   // if the pitch index was zero, we only need 4 K's...
r249036r249037
13921370      fprintf(stderr," ");
13931371#endif
13941372      update_fifo_status_and_ints();
1395      if (m_DDIS && m_buffer_empty) goto ranout;
1373      if (!m_talk_status) goto ranout;
13961374   }
1397#ifdef DEBUG_PARSE_FRAME_DUMP
1398         fprintf(stderr,"\n");
1399#endif
14001375#ifdef VERBOSE
1401   if (m_DDIS)
1402      fprintf(stderr,"Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
1376   if (m_speak_external)
1377      logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken));
14031378   else
1404      fprintf(stderr,"Parsed a frame successfully in ROM\n");
1379      logerror("Parsed a frame successfully in ROM\n");
14051380#endif
14061381   return;
14071382
14081383   ranout:
14091384#ifdef DEBUG_FRAME_ERRORS
1410   fprintf(stderr,"Ran out of bits on a parse!\n");
1385   logerror("Ran out of bits on a parse!\n");
14111386#endif
14121387   return;
14131388}
r249036r249037
14221397{
14231398   if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin
14241399#ifdef DEBUG_PIN_READS
1425   fprintf(stderr,"irq pin set to state %d\n", state);
1400   logerror("irq pin set to state %d\n", state);
14261401#endif
14271402   if (!m_irq_handler.isnull() && state != m_irq_pin)
14281403      m_irq_handler(!state);
r249036r249037
14391414{
14401415   int state = ready_read();
14411416#ifdef DEBUG_PIN_READS
1442   fprintf(stderr,"ready pin set to state %d\n", state);
1417   logerror("ready pin set to state %d\n", state);
14431418#endif
14441419   if (!m_readyq_handler.isnull() && state != m_ready_pin)
14451420      m_readyq_handler(!state);
r249036r249037
15391514
15401515   /* initialize the chip state */
15411516   /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */
1542   m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0;
1517   m_speaking_now = m_speak_external = m_talk_status = m_irq_pin = m_ready_pin = 0;
15431518   set_interrupt_state(0);
15441519   update_ready_state();
15451520   m_buffer_empty = m_buffer_low = 1;
r249036r249037
15501525#ifdef PERFECT_INTERPOLATION_HACK
15511526   m_old_frame_energy_idx = m_old_frame_pitch_idx = 0;
15521527   memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx));
1553   m_old_zpar = 0;
15541528#endif
1555   m_new_frame_energy_idx = m_current_energy =  m_previous_energy = 0;
1556   m_new_frame_pitch_idx = m_current_pitch = 0;
1557   m_zpar = m_uv_zpar = 0;
1529   m_new_frame_energy_idx = m_current_energy = m_target_energy = m_previous_energy = 0;
1530   m_new_frame_pitch_idx = m_current_pitch = m_target_pitch = 0;
15581531   memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx));
15591532   memset(m_current_k, 0, sizeof(m_current_k));
1533   memset(m_target_k, 0, sizeof(m_target_k));
15601534
15611535   /* initialize the sample generators */
15621536   m_inhibit = 1;
r249036r249037
16001574            /* Write */
16011575            /* bring up to date first */
16021576#ifdef DEBUG_IO_READY
1603            fprintf(stderr,"Serviced write: %02x\n", m_write_latch);
1577            logerror("Serviced write: %02x\n", m_write_latch);
16041578            //fprintf(stderr, "Processed write data: %02X\n", m_write_latch);
16051579#endif
16061580            m_stream->update();
r249036r249037
16361610   m_true_timing = 1;
16371611   state &= 0x01;
16381612#ifdef DEBUG_RS_WS
1639   fprintf(stderr,"/RS written with data: %d\n", state);
1613   logerror("/RS written with data: %d\n", state);
16401614#endif
16411615   new_val = (m_rs_ws & 0x01) | (state<<1);
16421616   if (new_val != m_rs_ws)
r249036r249037
16491623#ifdef DEBUG_RS_WS
16501624         else
16511625            /* illegal */
1652            fprintf(stderr,"tms5220_rs_w: illegal\n");
1626            logerror("tms5220_rs_w: illegal\n");
16531627#endif
16541628         return;
16551629      }
r249036r249037
16671641      {
16681642         /* high to low - schedule ready cycle */
16691643#ifdef DEBUG_RS_WS
1670         fprintf(stderr,"Scheduling ready cycle for /RS...\n");
1644         logerror("Scheduling ready cycle for /RS...\n");
16711645#endif
16721646         /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */
16731647         m_io_ready = 0;
r249036r249037
16881662   m_true_timing = 1;
16891663   state &= 0x01;
16901664#ifdef DEBUG_RS_WS
1691   fprintf(stderr,"/WS written with data: %d\n", state);
1665   logerror("/WS written with data: %d\n", state);
16921666#endif
16931667   new_val = (m_rs_ws & 0x02) | (state<<0);
16941668   if (new_val != m_rs_ws)
r249036r249037
17011675#ifdef DEBUG_RS_WS
17021676         else
17031677            /* illegal */
1704            fprintf(stderr,"tms5220_ws_w: illegal\n");
1678            logerror("tms5220_ws_w: illegal\n");
17051679#endif
17061680         return;
17071681      }
r249036r249037
17191693      {
17201694         /* high to low - schedule ready cycle */
17211695#ifdef DEBUG_RS_WS
1722         fprintf(stderr,"Scheduling ready cycle for /WS...\n");
1696         logerror("Scheduling ready cycle for /WS...\n");
17231697#endif
17241698         /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */
17251699         m_io_ready = 0;
r249036r249037
17521726   if (space.debugger_access()) return;
17531727
17541728#ifdef DEBUG_RS_WS
1755   fprintf(stderr,"tms5220_data_w: data %02x\n", data);
1729   logerror("tms5220_data_w: data %02x\n", data);
17561730#endif
17571731   if (!m_true_timing)
17581732   {
r249036r249037
17651739      /* actually in a write ? */
17661740#ifdef DEBUG_RS_WS
17671741      if (!(m_rs_ws == 0x02))
1768         fprintf(stderr,"tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
1742         logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws);
17691743#endif
17701744      m_write_latch = data;
17711745   }
r249036r249037
17971771         return m_read_latch;
17981772#ifdef DEBUG_RS_WS
17991773      else
1800         fprintf(stderr,"tms5220_status_r: data read outside rs!\n");
1774         logerror("tms5220_status_r: data read outside rs!\n");
18011775#endif
18021776      return 0xff;
18031777   }
trunk/src/emu/sound/tms5220.h
r249036r249037
105105
106106
107107   /* these contain global status bits */
108   UINT8 m_previous_TALK_STATUS;      /* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */
109   UINT8 m_SPEN;             /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */
110   UINT8 m_DDIS;             /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
111   UINT8 m_TALK;             /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */
112#define TALK_STATUS (m_SPEN|m_TALKD)
113   UINT8 m_TALKD;            /* TALK(TCON) value, latched every RESETL4 */
108   UINT8 m_speaking_now;     /* True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.*/
109   UINT8 m_speak_external;   /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
110   UINT8 m_talk_status;      /* If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts. */
114111   UINT8 m_buffer_low;       /* If 1, FIFO has less than 8 bytes in it */
115112   UINT8 m_buffer_empty;     /* If 1, FIFO is empty */
116113   UINT8 m_irq_pin;          /* state of the IRQ pin (output) */
r249036r249037
135132   INT16 m_current_energy;
136133   INT16 m_current_pitch;
137134   INT16 m_current_k[10];
135
136   INT16 m_target_energy;
137   INT16 m_target_pitch;
138   INT16 m_target_k[10];
138139#else
139140   UINT8 m_old_frame_energy_idx;
140141   UINT8 m_old_frame_pitch_idx;
141142   UINT8 m_old_frame_k_idx[10];
142   UINT8 m_old_zpar;
143   UINT8 m_old_uv_zpar;
144143
145144   INT32 m_current_energy;
146145   INT32 m_current_pitch;
147146   INT32 m_current_k[10];
147
148   INT32 m_target_energy;
149   INT32 m_target_pitch;
150   INT32 m_target_k[10];
148151#endif
149152
150153   UINT16 m_previous_energy; /* needed for lattice filter to match patent */
r249036r249037
152155   UINT8 m_subcycle;         /* contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B */
153156   UINT8 m_subc_reload;      /* contains 1 for normal speech, 0 when SPKSLOW is active */
154157   UINT8 m_PC;               /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
155   /* NOTE: the interpolation period counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
158   /* TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
156159   UINT8 m_IP;               /* the current interpolation period */
157160   UINT8 m_inhibit;          /* If 1, interpolation is inhibited until the DIV1 period */
158   UINT8 m_uv_zpar;          /* If 1, zero k5 thru k10 coefficients */
159   UINT8 m_zpar;             /* If 1, zero ALL parameters. */
160   UINT8 m_pitch_zero;       /* circuit 412; pitch is forced to zero under certain circumstances */
161161   UINT8 m_c_variant_rate;    /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
162162   UINT16 m_pitch_count;     /* pitch counter; provides chirp rom address */
163163
164164   INT32 m_u[11];
165165   INT32 m_x[10];
166166
167   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 TODO: no it isn't */
167   UINT16 m_RNG;             /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
168168   INT16 m_excitation_data;
169169
170170   /* R Nabet : These have been added to emulate speech Roms */
trunk/src/mame/arcade.lst
r249036r249037
82208220nbajamte3       // (c) 1994 Midway
82218221nbajamten       // (c) 1995 Midway
82228222revx            // (c) 1994 Midway
8223revxp5          // (c) 1994 Midway
82248223mk3             // (c) 1994 Midway
82258224mk3r20          // (c) 1994 Midway
82268225mk3r10          // (c) 1994 Midway
trunk/src/mame/drivers/fcrash.c
r249036r249037
29582958
29592959GAME( 1992, sf2b,      sf2,      sf2b,      sf2mdt,   cps_state, sf2b,     ROT0,   "bootleg", "Street Fighter II: The World Warrior (bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) //910204 - based on World version
29602960
2961GAME( 1992, sf2m9,     sf2ce,    sf2m1,     sf2,      cps_state, sf2m1,    ROT0,   "bootleg", "Street Fighter II': Champion Edition (M9, bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 920313 ETC
2961GAME( 1992, sf2m9,     sf2ce,    sf2m1,     sf2,      cps_state, dinopic,  ROT0,   "bootleg", "Street Fighter II': Champion Edition (M9, bootleg)",  MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 920313 ETC
29622962
29632963GAME( 1993, slampic,   slammast, slampic,   slammast, cps_state, dinopic,  ROT0,   "bootleg", "Saturday Night Slam Masters (bootleg with PIC16c57)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // 930713 ETC
29642964
trunk/src/mame/drivers/lethalj.c
r249036r249037
681681
682682ROM_START( lethalj )
683683   ROM_REGION16_LE( 0x100000, "user1", 0 )     /* 34010 code */
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 */
684   ROM_LOAD16_BYTE( "vc8",  0x000000, 0x080000, CRC(8d568e1d) SHA1(e4dd3794789f9ccd7be8374978a3336f2b79136f) )
685   ROM_LOAD16_BYTE( "vc9",  0x000001, 0x080000, CRC(8f22add4) SHA1(e773d3ae9cf512810fc266e784d21ed115c8830c) )
686686
687687   ROM_REGION16_LE( 0x600000, "gfx1", 0 )          /* graphics data */
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 */
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) )
694694
695695   ROM_REGION( 0x40000, "oki1", 0 )                /* sound data */
696696   ROM_LOAD( "sound1.u20", 0x00000, 0x40000, CRC(7d93ca66) SHA1(9e1dc0efa5d0f770c7e1f10de56fbf5620dea437) )
r249036r249037
10071007 *
10081008 *************************************/
10091009
1010GAME( 1996, lethalj,   0,        lethalj,  lethalj,   driver_device, 0,        ROT0,  "The Game Room", "Lethal Justice (Version 2.3)", 0 )
1010GAME( 1996, lethalj,   0,        lethalj,  lethalj,   driver_device, 0,        ROT0,  "The Game Room", "Lethal Justice", 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
r249036r249037
345345   ROM_LOAD( "a-17721.u955", 0x200, 0x117, CRC(033fe902) SHA1(6efb4e519ed3c9d49fff046a679762b506b3a75b) )
346346ROM_END
347347
348ROM_START( revxp5 )
349   ROM_REGION16_LE( 0x1000000, "dcs", ROMREGION_ERASEFF )  /* sound data */
350   ROM_LOAD16_BYTE( "revx_snd.2", 0x000000, 0x80000, CRC(4ed9e803) SHA1(ba50f1beb9f2a2cf5110897209b5e9a2951ff165) )
351   ROM_LOAD16_BYTE( "revx_snd.3", 0x200000, 0x80000, CRC(af8f253b) SHA1(25a0000cab177378070f7a6e3c7378fe87fad63e) )
352   ROM_LOAD16_BYTE( "revx_snd.4", 0x400000, 0x80000, CRC(3ccce59c) SHA1(e81a31d64c64e7b1d25f178c53da3d68453c203c) )
353   ROM_LOAD16_BYTE( "revx_snd.5", 0x600000, 0x80000, CRC(a0438006) SHA1(560d216d21cb8073dbee0fd20ebe589932a9144e) )
354   ROM_LOAD16_BYTE( "revx_snd.6", 0x800000, 0x80000, CRC(b7b34f60) SHA1(3b9682c6a00fa3bdb47e69d8e8ceccc244ee55b5) )
355   ROM_LOAD16_BYTE( "revx_snd.7", 0xa00000, 0x80000, CRC(6795fd88) SHA1(7c3790730a8b99b63112c851318b1c7e4989e5e0) )
356   ROM_LOAD16_BYTE( "revx_snd.8", 0xc00000, 0x80000, CRC(793a7eb5) SHA1(4b1f81b68f95cedf1b356ef362d1eb37acc74b16) )
357   ROM_LOAD16_BYTE( "revx_snd.9", 0xe00000, 0x80000, CRC(14ddbea1) SHA1(8dba9dc5529ea77c4312ea61f825bf9062ffc6c3) )
358348
359   ROM_REGION16_LE( 0x200000, "maincpu", 0 )   /* 34020 code */
360   ROM_LOAD32_BYTE( "revx_p5.51",  0x00000, 0x80000, CRC(f3877eee) SHA1(7a4fdce36edddd35308c107c992ce626a2c9eb8c) )
361   ROM_LOAD32_BYTE( "revx_p5.52",  0x00001, 0x80000, CRC(199a54d8) SHA1(45319437e11176d4926c00c95c372098203a32a3) )
362   ROM_LOAD32_BYTE( "revx_p5.53",  0x00002, 0x80000, CRC(fcfcf72a) SHA1(b471afb416e3d348b046b0b40f497d27b0afa470) )
363   ROM_LOAD32_BYTE( "revx_p5.54",  0x00003, 0x80000, CRC(fd684c31) SHA1(db3453792e4d9fc375297d030f0b3f9cc3cad925) )
364349
365   ROM_REGION( 0x2000, "pic", 0 )
366   ROM_LOAD( "revx_16c57.bin", 0x0000000, 0x2000, CRC(eb8a8649) SHA1(a1e1d0b7a5e9802e8f889eb7e719259656dc8133) )
367
368   ROM_REGION( 0x1000000, "gfxrom", 0 )
369   ROM_LOAD32_BYTE( "revx.120", 0x0000000, 0x80000, CRC(523af1f0) SHA1(a67c0fd757e860fc1c1236945952a295b4d5df5a) )
370   ROM_LOAD32_BYTE( "revx.121", 0x0000001, 0x80000, CRC(78201d93) SHA1(fb0b8f887eec433f7624f387d7fb6f633ea30d7c) )
371   ROM_LOAD32_BYTE( "revx.122", 0x0000002, 0x80000, CRC(2cf36144) SHA1(22ed0eefa2c7c836811fac5f717c3f38254eabc2) )
372   ROM_LOAD32_BYTE( "revx.123", 0x0000003, 0x80000, CRC(6912e1fb) SHA1(416f0de711d80e9182ede524c568c5095b1bec61) )
373
374   ROM_LOAD32_BYTE( "revx.110", 0x0200000, 0x80000, CRC(e3f7f0af) SHA1(5877d9f488b0f4362a9482007c3ff7f4589a036f) )
375   ROM_LOAD32_BYTE( "revx.111", 0x0200001, 0x80000, CRC(49fe1a69) SHA1(9ae54b461f0524c034fbcb6fcd3fd5ccb5d7265a) )
376   ROM_LOAD32_BYTE( "revx.112", 0x0200002, 0x80000, CRC(7e3ba175) SHA1(dd2fe90988b544f67dbe6151282fd80d49631388) )
377   ROM_LOAD32_BYTE( "revx.113", 0x0200003, 0x80000, CRC(c0817583) SHA1(2f866e5888e212b245984344950d0e1fb8957a73) )
378
379   ROM_LOAD32_BYTE( "revx.101", 0x0400000, 0x80000, CRC(5a08272a) SHA1(17da3c9d71114f5fdbf50281a942be3da3b6f564) )
380   ROM_LOAD32_BYTE( "revx.102", 0x0400001, 0x80000, CRC(11d567d2) SHA1(7ebe6fd39a0335e1fdda150d2dc86c3eaab17b2e) )
381   ROM_LOAD32_BYTE( "revx.103", 0x0400002, 0x80000, CRC(d338e63b) SHA1(0a038217542667b3a01ecbcad824ee18c084f293) )
382   ROM_LOAD32_BYTE( "revx.104", 0x0400003, 0x80000, CRC(f7b701ee) SHA1(0fc5886e5857326bee7272d5d482a878cbcea83c) )
383
384   ROM_LOAD32_BYTE( "revx.91",  0x0600000, 0x80000, CRC(52a63713) SHA1(dcc0ff3596bd5d273a8d4fd33b0b9b9d588d8354) )
385   ROM_LOAD32_BYTE( "revx.92",  0x0600001, 0x80000, CRC(fae3621b) SHA1(715d41ea789c0c724baa5bd90f6f0f06b9cb1c64) )
386   ROM_LOAD32_BYTE( "revx.93",  0x0600002, 0x80000, CRC(7065cf95) SHA1(6c5888da099e51c4b1c592721c5027c899cf52e3) )
387   ROM_LOAD32_BYTE( "revx.94",  0x0600003, 0x80000, CRC(600d5b98) SHA1(6aef98c91f87390c0759fe71a272a3ccadd71066) )
388
389   ROM_LOAD32_BYTE( "revx.81",  0x0800000, 0x80000, CRC(729eacb1) SHA1(d130162ae22b99c84abfbe014c4e23e20afb757f) )
390   ROM_LOAD32_BYTE( "revx.82",  0x0800001, 0x80000, CRC(19acb904) SHA1(516059b516bc5b1669c9eb085e0cdcdee520dff0) )
391   ROM_LOAD32_BYTE( "revx.83",  0x0800002, 0x80000, CRC(0e223456) SHA1(1eedbd667f4a214533d1c22ca5312ecf2d4a3ab4) )
392   ROM_LOAD32_BYTE( "revx.84",  0x0800003, 0x80000, CRC(d3de0192) SHA1(2d22c5bac07a7411f326691167c7c70eba4b371f) )
393
394   ROM_LOAD32_BYTE( "revx.71",  0x0a00000, 0x80000, CRC(2b29fddb) SHA1(57b71e5c18b56bf58216e690fdefa6d30d88d34a) )
395   ROM_LOAD32_BYTE( "revx.72",  0x0a00001, 0x80000, CRC(2680281b) SHA1(d1ae0701d20166a00d8733d9d12246c140a5fb96) )
396   ROM_LOAD32_BYTE( "revx.73",  0x0a00002, 0x80000, CRC(420bde4d) SHA1(0f010cdeddb59631a5420dddfc142c50c2a1e65a) )
397   ROM_LOAD32_BYTE( "revx.74",  0x0a00003, 0x80000, CRC(26627410) SHA1(a612121554549afff5c8e8c54774ca7b0220eda8) )
398
399   ROM_LOAD32_BYTE( "revx.63",  0x0c00000, 0x80000, CRC(3066e3f3) SHA1(25548923db111bd6c6cff44bfb63cb9eb2ef0b53) )
400   ROM_LOAD32_BYTE( "revx.64",  0x0c00001, 0x80000, CRC(c33f5309) SHA1(6bb333f563ea66c4c862ffd5fb91fb5e1b919fe8) )
401   ROM_LOAD32_BYTE( "revx.65",  0x0c00002, 0x80000, CRC(6eee3e71) SHA1(0ef22732e0e2bb5207559decd43f90d1e338ad7b) )
402   ROM_LOAD32_BYTE( "revx.66",  0x0c00003, 0x80000, CRC(b43d6fff) SHA1(87584e7aeea9d52a43023d40c359591ff6342e84) )
403   
404   ROM_LOAD32_BYTE( "revx_p5.51",  0xe00000, 0x80000, CRC(f3877eee) SHA1(7a4fdce36edddd35308c107c992ce626a2c9eb8c) )
405   ROM_LOAD32_BYTE( "revx_p5.52",  0xe00001, 0x80000, CRC(199a54d8) SHA1(45319437e11176d4926c00c95c372098203a32a3) )
406   ROM_LOAD32_BYTE( "revx_p5.53",  0xe00002, 0x80000, CRC(fcfcf72a) SHA1(b471afb416e3d348b046b0b40f497d27b0afa470) )
407   ROM_LOAD32_BYTE( "revx_p5.54",  0xe00003, 0x80000, CRC(fd684c31) SHA1(db3453792e4d9fc375297d030f0b3f9cc3cad925) )
408
409   ROM_REGION( 0x400, "plds", 0 )
410   ROM_LOAD( "a-17722.u1",   0x000, 0x117, CRC(054de7a3) SHA1(bb7abaec50ed704c03b44d5d54296898f7c80d38) )
411   ROM_LOAD( "a-17721.u955", 0x200, 0x117, CRC(033fe902) SHA1(6efb4e519ed3c9d49fff046a679762b506b3a75b) )
412ROM_END
413
414
415
416350/*************************************
417351 *
418352 *  Game drivers
419353 *
420354 *************************************/
421355
422GAME( 1994, revx,     0,    midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (rev 1.0 6/16/94)", MACHINE_SUPPORTS_SAVE )
423GAME( 1994, revxp5,   revx, midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (prototype, rev 5.0 5/23/94)", MACHINE_SUPPORTS_SAVE )
356GAME( 1994, revx,   0,         midxunit, revx, midxunit_state, revx, ROT0, "Midway",   "Revolution X (Rev. 1.0 6/16/94)", MACHINE_SUPPORTS_SAVE )
trunk/src/mame/drivers/namcofl.c
r249036r249037
610610   MCFG_VIDEO_START_OVERRIDE(namcofl_state,namcofl)
611611
612612   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
613   MCFG_C352_ADD("c352", 48384000/2, 288)
613   MCFG_C352_ADD("c352", 48384000/2, C352_DIVIDER_288)
614614   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
615615   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
616616   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namconb1.c
r249036r249037
11261126   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb1)
11271127
11281128   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
1129   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_288)
11301130   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
11311131   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
11321132   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249036r249037
11631163   MCFG_VIDEO_START_OVERRIDE(namconb1_state,namconb2)
11641164
11651165   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, 288)
1166   MCFG_C352_ADD("c352", MASTER_CLOCK/2, C352_DIVIDER_288)
11671167   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
11681168   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
11691169   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcond1.c
r249036r249037
307307   /* sound hardware */
308308   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
309309
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, 288)
310   MCFG_C352_ADD("c352", XTAL_49_152MHz/2, C352_DIVIDER_288)
311311   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
312312   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
313313   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos11.c
r249036r249037
571571
572572   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
573573
574   MCFG_C352_ADD("c352", 20013200, 228)
574   MCFG_C352_ADD("c352", 20013200, C352_DIVIDER_228)
575575   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
576576   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
577577   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos12.c
r249036r249037
16221622   /* sound hardware */
16231623   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
16241624
1625   MCFG_C352_ADD("c352", 29168000, 332)
1625   MCFG_C352_ADD("c352", 29168000, C352_DIVIDER_332)
16261626   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
16271627   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
16281628   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos22.c
r249036r249037
37813781   /* sound hardware */
37823782   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
37833783
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
3784   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_288)
37853785   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
37863786   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
37873787   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249036r249037
38303830   /* sound hardware */
38313831   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
38323832
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, 288)
3833   MCFG_C352_ADD("c352", SS22_MASTER_CLOCK/2, C352_DIVIDER_288)
38343834   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
38353835   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
38363836   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/namcos23.c
r249036r249037
12471247#define JVSCLOCK    (XTAL_14_7456MHz)
12481248#define H8CLOCK     (16737350)      /* from 2061 */
12491249#define BUSCLOCK    (16737350*2)    /* 33MHz CPU bus clock / input */
1250#define C352CLOCK   (25992000)  /* measured at 25.992MHz from 2061 pin 9  */
1251#define C352DIV      (296)
1250#define C352CLOCK   (25992000)  /* measured at 25.992MHz from 2061 pin 9 (System 12 uses a divider of 332) */
12521251#define VSYNC1      (59.8824)
12531252#define VSYNC2      (59.915)
12541253#define HSYNC       (16666150)
r249036r249037
33213320   /* sound hardware */
33223321   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33233322
3324   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3323   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
33253324   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33263325   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33273326   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249036r249037
33903389   /* sound hardware */
33913390   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
33923391
3393   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3392   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
33943393   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
33953394   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
33963395   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
r249036r249037
34703469   /* sound hardware */
34713470   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
34723471
3473   MCFG_C352_ADD("c352", C352CLOCK, C352DIV)
3472   MCFG_C352_ADD("c352", C352CLOCK, C352_DIVIDER_332)
34743473   MCFG_SOUND_ROUTE(0, "rspeaker", 1.00)
34753474   MCFG_SOUND_ROUTE(1, "lspeaker", 1.00)
34763475   MCFG_SOUND_ROUTE(2, "rspeaker", 1.00)
trunk/src/mame/drivers/quantum.c
r249036r249037
334334   /* AVG PROM */
335335   ROM_REGION( 0x100, "user1", 0 )
336336   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
337
338   ROM_REGION( 0x200, "plds", 0 )
339   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
340337ROM_END
341338
342339
r249036r249037
355352   /* AVG PROM */
356353   ROM_REGION( 0x100, "user1", 0 )
357354   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
358
359   ROM_REGION( 0x200, "plds", 0 )
360   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
361355ROM_END
362356
363357
r249036r249037
376370   /* AVG PROM */
377371   ROM_REGION( 0x100, "user1", 0 )
378372   ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, BAD_DUMP CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
379
380   ROM_REGION( 0x200, "plds", 0 )
381   ROM_LOAD( "137290-001.1b",   0x0000, 0x0117, CRC(938a4598) SHA1(e5b6ddb1b4bb5546d3a0da5d00ce7c57a9e8e769) ) // GAL16V8
382373ROM_END
383374
384375
trunk/src/mame/includes/chihiro.h
r249036r249037
185185      memset(pfifo, 0, sizeof(pfifo));
186186      memset(pcrtc, 0, sizeof(pcrtc));
187187      memset(pmc, 0, sizeof(pmc));
188      memset(pgraph, 0, sizeof(pgraph));
189188      memset(ramin, 0, sizeof(ramin));
190189      computedilated();
191190      objectdata = &(object_data_alloc());
r249036r249037
195194      enabled_vertex_attributes = 0;
196195      indexesleft_count = 0;
197196      vertex_pipeline = 4;
198      color_mask = 0xffffffff;
199197      alpha_test_enabled = false;
200198      alpha_reference = 0;
201199      alpha_func = nv2a_renderer::ALWAYS;
r249036r249037
240238   }
241239   DECLARE_READ32_MEMBER(geforce_r);
242240   DECLARE_WRITE32_MEMBER(geforce_w);
243   void vblank_callback(screen_device &screen, bool state);
241   bool vblank_callback(screen_device &screen, bool state);
244242   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
245   bool update_interrupts();
246   void set_interrupt_device(pic8259_device *device);
247243
248244   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
249245   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
r249036r249037
307303   UINT32 pfifo[0x2000 / 4];
308304   UINT32 pcrtc[0x1000 / 4];
309305   UINT32 pmc[0x1000 / 4];
310   UINT32 pgraph[0x2000 / 4];
311306   UINT32 ramin[0x100000 / 4];
312307   UINT32 dma_offset[2];
313308   UINT32 dma_size[2];
314309   UINT8 *basemempointer;
315   pic8259_device *interruptdevice;
316310   rectangle limits_rendertarget;
317311   UINT32 pitch_rendertarget;
318312   UINT32 pitch_depthbuffer;
r249036r249037
447441      int used;
448442      osd_lock *lock;
449443   } combiner;
450   UINT32 color_mask;
451444   bool alpha_test_enabled;
452445   int alpha_func;
453446   int alpha_reference;
trunk/src/mame/machine/xbox.c
r249036r249037
465465
466466void xbox_base_state::vblank_callback(screen_device &screen, bool state)
467467{
468   nvidia_nv2a->vblank_callback(screen, state);
468   if (nvidia_nv2a->vblank_callback(screen, state))
469      xbox_base_devs.pic8259_1->ir3_w(1); // IRQ 3
470   else
471      xbox_base_devs.pic8259_1->ir3_w(0); // IRQ 3
469472}
470473
471474UINT32 xbox_base_state::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
r249036r249037
14571460   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
14581461      debug_console_register_command(machine(), "xbox", CMDFLAG_NONE, 0, 1, 4, xbox_debug_commands);
14591462   memset(&ohcist, 0, sizeof(ohcist));
1460   // PIC challenge handshake data
1461   pic16lc_buffer[0x1c] = 0x0c;
1462   pic16lc_buffer[0x1d] = 0x0d;
1463   pic16lc_buffer[0x1e] = 0x0e;
1464   pic16lc_buffer[0x1f] = 0x0f;
14651463#ifdef USB_ENABLED
14661464   ohcist.hc_regs[HcRevision] = 0x10;
14671465   ohcist.hc_regs[HcFmInterval] = 0x2edf;
r249036r249037
14851483   save_item(NAME(smbusst.rw));
14861484   save_item(NAME(smbusst.words));
14871485   save_item(NAME(pic16lc_buffer));
1488   nvidia_nv2a->set_interrupt_device(xbox_base_devs.pic8259_1);
14891486   nvidia_nv2a->start(&m_maincpu->space());
14901487   nvidia_nv2a->savestate_items();
14911488}
trunk/src/mame/video/chihiro.c
r249036r249037
33#include "emu.h"
44#include "video/poly.h"
55#include "bitmap.h"
6#include "machine/pic8259.h"
76#include "includes/chihiro.h"
87
98//#define LOG_NV2A
r249036r249037
946945UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
947946{
948947   UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
949   UINT32 o = (pfifo[0x210 / 4] & 0x1ff) << 8; // 0x1ff is not certain
948   UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ?
950949   UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
951950   UINT32 w;
952951
953   if (ramin[e / 4] != handle) {
954      // this should never happen
955      for (UINT32 aa = o / 4; aa < (sizeof(ramin) / 4); aa = aa + 2) {
956         if (ramin[aa] == handle) {
957            e = aa * 4;
958         }
959      }
960   }
952   if (ramin[e / 4] != handle)
953      e = 0;
961954   w = ramin[e / 4 + 1];
962   return (w & 0xffff) * 0x10; // 0xffff is not certain
955   return (w & 0xffff) * 0x10;
963956}
964957
965958void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
r249036r249037
12531246      addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
12541247   else // type_rendertarget == LINEAR*/
12551248      addr = rendertarget + (pitch_rendertarget / 4)*y + x;
1256   fbcolor = 0;
1257   if (color_mask != 0)
1258      fbcolor = *addr;
1249   fbcolor = *addr;
12591250   daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
12601251   deptsten = *daddr;
12611252   c[3] = color >> 24;
r249036r249037
17811772            break;
17821773      }
17831774   }
1784   if (color_mask != 0) {
1785      UINT32 fbcolor_tmp;
1786
1787      fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1788      *addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask);
1789   }
1775   fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1776   *addr = fbcolor;
17901777   if (depth_write_enabled)
17911778      dep = depth;
17921779   deptsten = (dep << 8) | sten;
r249036r249037
22462233   maddress = method * 4;
22472234   data = space.read_dword(address);
22482235   channel[chanel][subchannel].object.method[method] = data;
2249#ifdef LOG_NV2A
2250   printf("A:%08X MTHD:%08X D:%08X\n\r",address,maddress,data);
2251#endif
22522236   if (maddress == 0x17fc) {
22532237      indexesleft_count = 0;
22542238      indexesleft_first = 0;
r249036r249037
22862270         }
22872271         wait();
22882272      }
2289      else if (type == nv2a_renderer::TRIANGLE_FAN) {
2290         vertex_nv vert[3];
2291         vertex_t xy[3];
2292
2293         read_vertices_0x1810(space, vert, offset, 2);
2294         convert_vertices_poly(vert, xy, 2);
2295         count = count - 2;
2296         offset = offset + 2;
2297         for (n = 0; n <= count; n++) {
2298            read_vertices_0x1810(space, vert + (((n + 1) & 1) + 1), offset + n, 1);
2299            convert_vertices_poly(vert + (((n + 1) & 1) + 1), xy + (((n + 1) & 1) + 1), 1);
2300            render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~(n + 1) & 1) + 1], xy[((n + 1) & 1) + 1]);
2301         }
2302         wait();
2303      }
23042273      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
23052274         vertex_nv vert[4];
23062275         vertex_t xy[4];
r249036r249037
23422311      // each dword after 1800 contains two 16 bit index values to select the vartices
23432312      // each dword after 1808 contains a 32 bit index value to select the vartices
23442313      type = channel[chanel][subchannel].object.method[0x17fc / 4];
2314#ifdef LOG_NV2A
2315      printf("vertex %d %d %d\n\r", type, offset, count);
2316#endif
23452317      if (type == nv2a_renderer::QUADS) {
23462318         while (1) {
23472319            vertex_nv vert[4];
r249036r249037
23602332            render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
23612333         }
23622334      }
2363      else if (type == nv2a_renderer::TRIANGLE_FAN) {
2364         if ((countlen * mult + indexesleft_count) >= 3) {
2365            vertex_nv vert[3];
2366            vertex_t xy[3];
2367            int c, count;
2368
2369            if (mult == 1)
2370               c = read_vertices_0x1808(space, vert, address, 2);
2371            else
2372               c = read_vertices_0x1800(space, vert, address, 2);
2373            convert_vertices_poly(vert, xy, 2);
2374            address = address + c * 4;
2375            countlen = countlen - c;
2376            count = countlen * mult + indexesleft_count;
2377            for (n = 1; n <= count; n++) {
2378               if (mult == 1)
2379                  c = read_vertices_0x1808(space, vert + ((n & 1) + 1), address, 1);
2380               else
2381                  c = read_vertices_0x1800(space, vert + ((n & 1) + 1), address, 1);
2382
2383               convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
2384               address = address + c * 4;
2385               countlen = countlen - c;
2386               render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
2387            }
2388            wait();
2389         }
2390      }
23912335      else if (type == nv2a_renderer::TRIANGLES) {
23922336         while (1) {
23932337            vertex_nv vert[3];
r249036r249037
25022446         }
25032447         wait();
25042448      }
2505      else if (type == nv2a_renderer::TRIANGLES) {
2506         while (countlen > 0) {
2507            vertex_nv vert[3];
2508            vertex_t xy[3];
2509            int c;
2510
2511            c = read_vertices_0x1818(space, vert, address, 3);
2512            convert_vertices_poly(vert, xy, 3);
2513            countlen = countlen - c;
2514            if (countlen < 0) {
2515               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2516               countlen = 0;
2517               break;
2518            }
2519            address = address + c * 3;
2520            render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
2521         }
2522      }
25232449      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
25242450         vertex_nv vert[4];
25252451         vertex_t xy[4];
r249036r249037
26872613         // clear colors
26882614         UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
26892615         bm.fill(color);
2690#ifdef LOG_NV2A
2691         printf("clearscreen\n\r");
2692#endif
2616         //printf("clearscreen\n\r");
26932617      }
26942618      if ((data & 0x03) == 3) {
26952619         bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
r249036r249037
27252649      dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
27262650   }
27272651   if (maddress == 0x020c) {
2652      // line size ?
27282653      pitch_rendertarget=data & 0xffff;
27292654      pitch_depthbuffer=(data >> 16) & 0xffff;
2730#ifdef LOG_NV2A
2731      printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
2732#endif
2655      //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
27332656      countlen--;
27342657   }
27352658   if (maddress == 0x0100) {
2736      countlen--;
2737      if (data != 0) {
2738         pgraph[0x704 / 4] = 0x100;
2739         pgraph[0x708 / 4] = data;
2740         pgraph[0x100 / 4] |= 1;
2741         pgraph[0x108 / 4] |= 1;
2742         if (update_interrupts() == true)
2743            interruptdevice->ir3_w(1); // IRQ 3
2744         else
2745            interruptdevice->ir3_w(0); // IRQ 3
2746         return 2;
2659      // just temporarily
2660      if ((data & 0x1f) == 1) {
2661         data = data >> 5;
2662         data = data & 0x0ffffff0;
2663         displayedtarget = (UINT32 *)direct_access_ptr(data);
27472664      }
2748      else
2749         return 0;
27502665   }
27512666   if (maddress == 0x0130) {
27522667      countlen--;
r249036r249037
27552670      else
27562671         return 0;
27572672   }
2758   if (maddress == 0x1d8c) {
2759      countlen--;
2760      // it is used to specify the clear value for the depth buffer (zbuffer)
2761      // but also as a parameter for interrupt routines
2762      pgraph[0x1a88 / 4] = data;
2763   }
2764   if (maddress == 0x1d90) {
2765      countlen--;
2766      // it is used to specify the clear value for the color buffer
2767      // but also as a parameter for interrupt routines
2768      pgraph[0x186c / 4] = data;
2769   }
27702673   if (maddress == 0x0210) {
27712674      // framebuffer offset ?
27722675      rendertarget = (UINT32 *)direct_access_ptr(data);
2773#ifdef LOG_NV2A
2774      printf("Render target at %08X\n\r", data);
2775#endif
2676      //printf("Render target at %08X\n\r",data);
27762677      countlen--;
27772678   }
27782679   if (maddress == 0x0214) {
27792680      // zbuffer offset ?
27802681      depthbuffer = (UINT32 *)direct_access_ptr(data);
2781#ifdef LOG_NV2A
2782      printf("Depth buffer at %08X\n\r",data);
2783#endif
2682      //printf("Depth buffer at %08X\n\r",data);
27842683      if ((data == 0) || (data > 0x7ffffffc))
27852684         depth_write_enabled = false;
27862685      else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
r249036r249037
28102709   if (maddress == 0x0354) {
28112710      depth_function = data;
28122711   }
2813   if (maddress == 0x0358) {
2814      //color_mask = data;
2815      if (data & 0x000000ff)
2816         data |= 0x000000ff;
2817      if (data & 0x0000ff00)
2818         data |= 0x0000ff00;
2819      if (data & 0x00ff0000)
2820         data |= 0x00ff0000;
2821      if (data & 0xff000000)
2822         data |= 0xff000000;
2823      color_mask = data;
2824   }
28252712   if (maddress == 0x035c) {
28262713      UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
28272714      depth_write_enabled = data != 0;
r249036r249037
37613648   combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0f), -1.0f);
37623649}
37633650
3764void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
3651bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
37653652{
3766#ifdef LOG_NV2A
3767   printf("vblank_callback\n\r");
3768#endif
3769   if ((state == true) && (puller_waiting == 1)) {
3770      puller_waiting = 0;
3771      puller_timer_work(NULL, 0);
3772   }
3773   if (state == true) {
3653   //printf("vblank_callback\n\r");
3654   if (state == true)
37743655      pcrtc[0x100 / 4] |= 1;
3775      pcrtc[0x808 / 4] |= 0x10000;
3776   }
3777   else {
3778      pcrtc[0x100 / 4] &= ~1;
3779      pcrtc[0x808 / 4] &= ~0x10000;
3780   }
3781   if (update_interrupts() == true)
3782      interruptdevice->ir3_w(1); // IRQ 3
37833656   else
3784      interruptdevice->ir3_w(0); // IRQ 3
3785}
3786
3787bool nv2a_renderer::update_interrupts()
3788{
3657      pcrtc[0x100 / 4] &= ~1;
37893658   if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
37903659      pmc[0x100 / 4] |= 0x1000000;
37913660   else
37923661      pmc[0x100 / 4] &= ~0x1000000;
3793   if (pgraph[0x100 / 4] & pgraph[0x140 / 4])
3794      pmc[0x100 / 4] |= 0x1000;
3795   else
3796      pmc[0x100 / 4] &= ~0x1000;
3797   if (((pmc[0x100 / 4] & 0x7fffffff) && (pmc[0x140 / 4] & 1)) || ((pmc[0x100 / 4] & 0x80000000) && (pmc[0x140 / 4] & 2))) {
3662   if ((state == true) && (puller_waiting == 1)) {
3663      puller_waiting = 0;
3664      puller_timer_work(NULL, 0);
3665   }
3666   if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) {
37983667      // send interrupt
37993668      return true;
38003669   }
r249036r249037
38233692   int countlen;
38243693   int ret;
38253694   address_space *space = puller_space;
3826#ifdef LOG_NV2A
3827   UINT32 subch;
3828#endif
38293695
38303696   chanel = puller_channel;
38313697   subchannel = puller_subchannel;
r249036r249037
38823748            }
38833749            if (ret != 0) {
38843750               puller_timer->enable(false);
3885               puller_waiting = ret;
3751               puller_waiting = 1;
38863752               return;
38873753            }
38883754         }
r249036r249037
39813847      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
39823848   }
39833849   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3984      ret = pgraph[offset - 0x00400000 / 4];
39853850      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
39863851   }
39873852   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
r249036r249037
40053870      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
40063871      return ret;
40073872   }
3873   else
3874   {
3875      /* nothing */
3876   }
40083877   //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
40093878   return ret;
40103879}
40113880
40123881WRITE32_MEMBER(nv2a_renderer::geforce_w)
40133882{
4014   UINT32 old;
4015   bool update_int;
4016
4017   update_int = false;
40183883   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
40193884      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
40203885   }
r249036r249037
40333898      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
40343899   }
40353900   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
4036      int e = offset - 0x00400000 / 4;
4037      if (e >= (sizeof(pgraph) / sizeof(UINT32)))
4038         return;
4039      old = pgraph[e];
4040      COMBINE_DATA(pgraph + e);
4041      if (e == 0x100 / 4) {
4042         pgraph[e] = old & ~data;
4043         if (data & 1)
4044            pgraph[0x108 / 4] = 0;
4045         update_int = true;
4046      }
4047      if (e == 0x140 / 4)
4048         update_int = true;
4049      if (e == 0x720 / 4) {
4050         if ((data & 1) && (puller_waiting == 2)) {
4051            puller_waiting = 0;
4052            puller_timer->enable();
4053            puller_timer->adjust(attotime::zero);
4054         }
4055      }
4056      if ((e >= 0x900 / 4) && (e < 0xa00 / 4))
4057         pgraph[e] = 0;
40583901      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
40593902   }
40603903   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
40613904      int e = offset - 0x00600000 / 4;
40623905      if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
40633906         return;
4064      old = pcrtc[e];
40653907      COMBINE_DATA(pcrtc + e);
4066      if (e == 0x100 / 4) {
4067         pcrtc[e] = old & ~data;
4068         update_int = true;
4069      }
4070      if (e == 0x140 / 4)
4071         update_int = true;
40723908      if (e == 0x800 / 4) {
4073         displayedtarget = (UINT32 *)direct_access_ptr(pcrtc[e]);
4074#ifdef LOG_NV2A
4075         printf("crtc buffer %08X\n\r", data);
4076#endif
3909         displayedtarget = (UINT32 *)direct_access_ptr(data);
3910         //printf("crtc buffer %08X\n\r", data);
40773911      }
40783912      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
40793913   }
r249036r249037
40883922      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
40893923      int chanel, subchannel, suboffset;
40903924      //int method, count, handle, objclass;
3925#ifdef LOG_NV2A
3926      int subch;
3927#endif
40913928
40923929      suboffset = offset - 0x00800000 / 4;
40933930      chanel = (suboffset >> (16 - 2)) & 31;
r249036r249037
41223959   }
41233960   //else
41243961   //      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
4125   if (update_int == true) {
4126      if (update_interrupts() == true)
4127         interruptdevice->ir3_w(1); // IRQ 3
4128      else
4129         interruptdevice->ir3_w(0); // IRQ 3
4130   }
41313962}
41323963
41333964void nv2a_renderer::savestate_items()
r249036r249037
41403971   puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
41413972   puller_timer->enable(false);
41423973}
4143
4144void nv2a_renderer::set_interrupt_device(pic8259_device *device)
4145{
4146   interruptdevice = device;
4147}
trunk/src/mess/drivers/mc1000.c
r249036r249037
378378  +---------*---*---o V+
379379  |         |   |
380380 +-+        |   |
381 | |390K    |   |
381 | |309K    |   |
382382 | |R17     |8  |4
383383 +-+      +-------+
384384  |      7|       |3
r249036r249037
390390 | |   |  |  555  |
391391 +-+   |  |       |
392392  |    | 6|       |5
393  *----*--|       |---+
393  *----*?-|       |---+
394394  |       |       |   |
395395 ---C30   +-------+  ---C29
396 ---10n       |1     ---10n
396 ---103       |1     ---103
397397 _|_         _|_     _|_
398398 ///         ///     ///
399399
400400 Calculated properties:
401401
402402 * 99.74489795918367 Duty Cycle Percentage
403 * 367.3469387755102 Frequency in Hertz
403 * 368.1126130105722 Frequency in Hertz
404404 * 0.00000693 Seconds Low
405 * 0.00270963 Seconds High
405 * 0.0027096299999999998 Seconds High
406406
407407 */
408408
409#define MC1000_NE555_FREQ       (367) /* Hz */
409#define MC1000_NE555_FREQ       (368) /* 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
r249036r249037
1515
1616#include "strconv.h"
1717
18#include "winutil.h"
1918
20
2119// debugger view styles
2220#define DEBUG_VIEW_STYLE    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
2321#define DEBUG_VIEW_STYLE_EX 0
r249036r249037
5048
5149   // create the child view
5250   m_wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), NULL, DEBUG_VIEW_STYLE,
53          0, 0, 100, 100, parent, NULL, GetModuleHandleUni(), this);
51         0, 0, 100, 100, parent, NULL, GetModuleHandle(NULL), this);
5452   if (m_wnd == NULL)
5553      goto cleanup;
5654
5755   // create the scroll bars
5856   m_hscroll = CreateWindowEx(HSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, HSCROLL_STYLE,
59         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandleUni(), this);
57         0, 0, 100, CW_USEDEFAULT, m_wnd, NULL, GetModuleHandle(NULL), this);
6058   m_vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), NULL, VSCROLL_STYLE,
61         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandleUni(), this);
59         0, 0, CW_USEDEFAULT, 100, m_wnd, NULL, GetModuleHandle(NULL), this);
6260   if ((m_hscroll == NULL) || (m_vscroll == NULL))
6361      goto cleanup;
6462
r249036r249037
256254{
257255   // create a combo box
258256   HWND const result = CreateWindowEx(COMBO_BOX_STYLE_EX, TEXT("COMBOBOX"), NULL, COMBO_BOX_STYLE,
259         0, 0, 100, 1000, parent, NULL, GetModuleHandleUni(), NULL);
257         0, 0, 100, 1000, parent, NULL, GetModuleHandle(NULL), NULL);
260258   SetWindowLongPtr(result, GWLP_USERDATA, userdata);
261259   SendMessage(result, WM_SETFONT, (WPARAM)metrics().debug_font(), (LPARAM)FALSE);
262260
r249036r249037
791789
792790      // initialize the description of the window class
793791      wc.lpszClassName    = TEXT("MAMEDebugView");
794      wc.hInstance        = GetModuleHandleUni();
792      wc.hInstance        = GetModuleHandle(NULL);
795793      wc.lpfnWndProc      = &debugview_info::static_view_proc;
796794      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
797795      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249036r249037
800798      wc.style            = 0;
801799      wc.cbClsExtra       = 0;
802800      wc.cbWndExtra       = 0;
803     
804      UnregisterClass(wc.lpszClassName, wc.hInstance);
805801
806802      // register the class; fail if we can't
807803      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/debugwininfo.c
r249036r249037
1717#include "window.h"
1818#include "winutf8.h"
1919
20#include "winutil.h"
2120
22
2321bool debugwin_info::s_window_class_registered = false;
2422
2523
r249036r249037
3836   register_window_class();
3937
4038   m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
41         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandleUni(), this);
39         0, 0, 100, 100, win_window_list->m_hwnd, create_standard_menubar(), GetModuleHandle(NULL), this);
4240   if (m_wnd == NULL)
4341      return;
4442
r249036r249037
582580
583581      // initialize the description of the window class
584582      wc.lpszClassName    = TEXT("MAMEDebugWindow");
585      wc.hInstance        = GetModuleHandleUni();
583      wc.hInstance        = GetModuleHandle(NULL);
586584      wc.lpfnWndProc      = &debugwin_info::static_window_proc;
587585      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
588586      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
r249036r249037
591589      wc.style            = 0;
592590      wc.cbClsExtra       = 0;
593591      wc.cbWndExtra       = 0;
594     
595      UnregisterClass(wc.lpszClassName, wc.hInstance);
596592
597593      // register the class; fail if we can't
598594      if (!RegisterClass(&wc))
trunk/src/osd/modules/debugger/win/editwininfo.c
r249036r249037
1313
1414#include "strconv.h"
1515
16#include "winutil.h"
1716
18
1917// edit box styles
2018#define EDIT_BOX_STYLE      WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL
2119#define EDIT_BOX_STYLE_EX   0
r249036r249037
3432
3533   // create an edit box and override its key handling
3634   m_editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), NULL, EDIT_BOX_STYLE,
37         0, 0, 100, 100, window(), NULL, GetModuleHandleUni(), NULL);
35         0, 0, 100, 100, window(), NULL, GetModuleHandle(NULL), NULL);
3836   m_original_editproc = (WNDPROC)(FPTR)GetWindowLongPtr(m_editwnd, GWLP_WNDPROC);
3937   SetWindowLongPtr(m_editwnd, GWLP_USERDATA, (LONG_PTR)this);
4038   SetWindowLongPtr(m_editwnd, GWLP_WNDPROC, (LONG_PTR)&editwin_info::static_edit_proc);
trunk/src/osd/windows/input.c
r249036r249037
3838#include "strconv.h"
3939#include "config.h"
4040
41#include "winutil.h"
42
4341//============================================================
4442//  PARAMETERS
4543//============================================================
r249036r249037
11191117   int didevtype_joystick = DI8DEVCLASS_GAMECTRL;
11201118
11211119   dinput_version = DIRECTINPUT_VERSION;
1122   result = DirectInput8Create(GetModuleHandleUni(), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
1120   result = DirectInput8Create(GetModuleHandle(NULL), dinput_version, IID_IDirectInput8, (void **)&dinput, NULL);
11231121   if (result != DI_OK)
11241122   {
11251123      dinput_version = 0;
r249036r249037
11321130
11331131   // first attempt to initialize DirectInput at the current version
11341132   dinput_version = DIRECTINPUT_VERSION;
1135   result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1133   result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11361134   if (result != DI_OK)
11371135   {
11381136      // if that fails, try version 5
11391137      dinput_version = 0x0500;
1140      result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1138      result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11411139      if (result != DI_OK)
11421140      {
11431141         // if that fails, try version 3
11441142         dinput_version = 0x0300;
1145         result = DirectInputCreate(GetModuleHandleUni(), dinput_version, &dinput, NULL);
1143         result = DirectInputCreate(GetModuleHandle(NULL), dinput_version, &dinput, NULL);
11461144         if (result != DI_OK)
11471145         {
11481146            dinput_version = 0;
trunk/src/osd/windows/output.c
r249036r249037
1717// MAMEOS headers
1818#include "output.h"
1919
20#include "winutil.h"
2120
2221
23
2422//============================================================
2523//  CONSTANTS
2624//============================================================
r249036r249037
103101                  1, 1,
104102                  NULL,
105103                  NULL,
106                  GetModuleHandleUni(),
104                  GetModuleHandle(NULL),
107105                  NULL);
108106   assert(output_hwnd != NULL);
109107
r249036r249037
169167
170168      // initialize the description of the window class
171169      wc.lpszClassName    = OUTPUT_WINDOW_CLASS;
172      wc.hInstance        = GetModuleHandleUni();
170      wc.hInstance        = GetModuleHandle(NULL);
173171      wc.lpfnWndProc      = output_window_proc;
174     
175      UnregisterClass(wc.lpszClassName, wc.hInstance);
176172
177173      // register the class; fail if we can't
178174      if (!RegisterClass(&wc))
trunk/src/osd/windows/window.c
r249036r249037
3535#include "config.h"
3636#include "winutf8.h"
3737
38#include "winutil.h"
39
4038extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks);
4139extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks);
4240extern int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks);
r249036r249037
887885
888886      // initialize the description of the window class
889887      wc.lpszClassName    = TEXT("MAME");
890      wc.hInstance        = GetModuleHandleUni();
888      wc.hInstance        = GetModuleHandle(NULL);
891889      wc.lpfnWndProc      = winwindow_video_window_proc_ui;
892890      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
893891      wc.hIcon            = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
894     
895      UnregisterClass(wc.lpszClassName, wc.hInstance);
896892
897893      // register the class; fail if we can't
898894      if (!RegisterClass(&wc))
r249036r249037
11951191                  monitorbounds.left() + 100, monitorbounds.top() + 100,
11961192                  NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL,
11971193                  menu,
1198                  GetModuleHandleUni(),
1194                  GetModuleHandle(NULL),
11991195                  NULL);
12001196   if (m_hwnd == NULL)
12011197      return 1;
trunk/src/osd/windows/winmain.c
r249036r249037
13211321   dynamic_bind<PIMAGE_NT_HEADERS (WINAPI *)(PVOID)> image_nt_header(TEXT("dbghelp.dll"), "ImageNtHeader");
13221322
13231323   // start with the image base
1324   PVOID base = reinterpret_cast<PVOID>(GetModuleHandleUni());
1324   PVOID base = reinterpret_cast<PVOID>(GetModuleHandle(NULL));
13251325   assert(base != NULL);
13261326
13271327   // make sure we have the functions we need
trunk/src/osd/windows/winutil.c
r249036r249037
9292      is_first_time = FALSE;
9393
9494      // get the current module
95      module = GetModuleHandleUni();
95      module = GetModuleHandle(NULL);
9696      if (!module)
9797         return FALSE;
9898      image_ptr = (BYTE*) module;
r249036r249037
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
r249036r249037
1515file_error win_error_to_file_error(DWORD error);
1616osd_dir_entry_type win_attributes_to_entry_type(DWORD attributes);
1717BOOL win_is_gui_application(void);
18HMODULE WINAPI GetModuleHandleUni();
1918
2019#endif // __WINUTIL__


Previous 199869 Revisions Next


© 1997-2024 The MAME Team