Previous 199869 Revisions Next

r24565 Tuesday 30th July, 2013 at 02:36:14 UTC by Jonathan Gevaryahu
Add support for CD2501ECD variant of tms52xx, used in the TI 99/8 prototype.
Renamed TMC0285 to the more correct CD2501E in the TI 99/4a. [mizapf, Lord Nightmare]
[src/emu/sound]tms5220.c tms5220.h
[src/mess/machine/ti99]spchsyn.c spchsyn.h speech8.c

trunk/src/emu/sound/tms5220.c
r24564r24565
2323     US patent 4,335,277 describes the complete 52xx chip
2424     Special Thanks to Larry Brantingham for answering questions regarding the chip details
2525
26   TMS5200/TMS5220/TMS5220C:
26   TMS5200/TMS5220/TMS5220C/CD2501E/CD2501ECD:
2727
2828                 +-----------------+
2929        D7(d0)   |  1           28 |  /RS
r24564r24565
120120    01      7 0#3 4 5 6 7 0#3 4 5 6 7 0#3 4 5
121121    10      7 0#5 6 7 0#5 6 7 0#5 6 7 0#5 6 7
122122    11      7 0#7 0#7 0#7 0#7 0#7 0#7 0#7 0#7
123   Based on the behavior tested on the CD2501ECD this is assumed to be the same for that chip as well.
123124
124125Most of the following is based on figure 8c of 4,331,836, which is the
125126  TMS5100/TMC0280 patent, but the same information applies to the TMS52xx
r24564r24565
155156
156157
157158****Documentation of chip commands:***
158    x0x0xbcc : on 5200/5220: NOP (does nothing); on 5220C: Select frame length by cc, and b selects whether every frame is preceded by 2 bits to select the frame length (instead of using the value set by cc); the default (and after a reset command) is as if '0x00' was written, i.e. for frame length (200 samples) and 0 for whether the preceding 2 bits are enabled (off)
159    x0x0xbcc : on 5200/5220: NOP (does nothing); on 5220C and CD2501ECD: Select frame length by cc, and b selects whether every frame is preceded by 2 bits to select the frame length (instead of using the value set by cc); the default (and after a reset command) is as if '0x00' was written, i.e. for frame length (200 samples) and 0 for whether the preceding 2 bits are enabled (off)
159160
160161    x001xxxx: READ BYTE (RDBY) Sends eight read bit commands (M0 high M1 low) to VSM and reads the resulting bits serially into a temporary register, which becomes readable as the next byte read from the tms52xx once ready goes active. Note the bit order of the byte read from the TMS52xx is BACKWARDS as compared to the actual data order as in the rom on the VSM chips; the read byte command of the tms5100 reads the bits in the 'correct' order. This was IMHO a rather silly design decision of TI. (I (LN) asked Larry Brantingham about this but he wasn't involved with the TMS52xx chips, just the 5100); There's ASCII data in the TI 99/4 speech module VSMs which has the bit order reversed on purpose because of this!
161162    TALK STATUS must be CLEAR for this command to work; otherwise it is treated as a NOP.
r24564r24565
175176
176177
177178    Other chip differences:
178    The 5220 is 'noisier' when playing unvoiced frames than the 5220C is; I (LN) think the 5220C may use a different energy table (or use one value lower in the normal energy table) than the 5220 does, possibly only when playing unvoiced frames, but I can't prove this without a decap; the 5220C's PROMOUT pin (for dumping the lpc tables as played) is non-functional due to a changed design or a die bug (or may need special timing to know exactly when to read it, different than the 5200 and 5220 which are both easily readable).
179    In addition, the NOP commands on the FIFO interface have been changed on the 5220C and data passed in the low bits has a meaning regarding frame length, see above.
179    The 5220C (and CD2501ECD maybe?) are quieter due to a better dac arrangement on die which allows less crossover between bits, based on the decap differences.
180180
181    It is also possible but inconclusive that the chirp table was changed; The LPC tables between the 5220 and 5220C are MOSTLY the same of not completely so, but as mentioned above the energy table has some sort of difference.
182181
183
184182***MAME Driver specific notes:***
185183
186184    Victory's initial audio selftest is pretty brutal to the FIFO: it sends a
r24564r24565
220218serial chips); Street Electronics Corp.'s Apple II 'Echo 2' Speech
221219synthesizer (early cards only)
222220
221CD2501ECD: (1983)
222   Home computer: TI 99/8 (prototypes only)
223
223224TMS5220: (mostly on things made between 1981 and 1984-1985)
224225    Arcade: Bally/Midway's 'NFL Football'; Atari's 'Star Wars',
225226'Firefox', 'Return of the Jedi', 'Road Runner', 'The Empire Strikes
r24564r24565
265266
266267/* Other hacks */
267268/* HACK?: if defined, outputs the low 4 bits of the lattice filter to the i/o
268 * or clip logic, even though the real hardware doesn't do this...
269 * ...actually the tms5220c might legitamately do this! */
269 * or clip logic, even though the real hardware doesn't do this, partially verified by decap */
270270#undef ALLOW_4_LSB
271271
272272
r24564r24565
317317#define TMS5220_IS_5220C    (4)
318318#define TMS5220_IS_5200     (5)
319319#define TMS5220_IS_5220     (6)
320#define TMS5220_IS_CD2501ECD (7)
320321
321#define TMS5220_IS_TMC0285  TMS5220_IS_5200
322#define TMS5220_IS_CD2501E  TMS5220_IS_5200
322323
323static const UINT8 reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for 5220c only; 5200 and 5220 always reload with 0; keep in mind this is loaded on IP=0 PC=12 subcycle=1 so it immediately will increment after one sample, effectively being 1,3,5,7 as in the comments above.
324#define TMS5220_HAS_RATE_CONTROL ((m_variant == TMS5220_IS_5220C) || (m_variant == TMS5220_IS_CD2501ECD))
324325
326static const UINT8 reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for 5220c and cd2501ecd only; 5200 and 5220 always reload with 0; keep in mind this is loaded on IP=0 PC=12 subcycle=1 so it immediately will increment after one sample, effectively being 1,3,5,7 as in the comments above.
327
325328// Pull in the ROM tables
326329#include "tms5110r.c"
327330
r24564r24565
331334   switch (variant)
332335   {
333336      case TMS5220_IS_5200:
337      case TMS5220_IS_CD2501ECD:
334338         m_coeff = &tms5200_coeff;
335339         break;
336340      case TMS5220_IS_5220C:
r24564r24565
386390   save_item(NAME(m_PC));
387391   save_item(NAME(m_IP));
388392   save_item(NAME(m_inhibit));
389   save_item(NAME(m_tms5220c_rate));
393   save_item(NAME(m_c_variant_rate));
390394   save_item(NAME(m_pitch_count));
391395
392396   save_item(NAME(m_u));
r24564r24565
475479            // 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
476480            m_subcycle = m_subc_reload;
477481            m_PC = 0;
478            m_IP = reload_table[m_tms5220c_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
482            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?
479483            m_new_frame_energy_idx = 0;
480484            m_new_frame_pitch_idx = 0;
481485            for (i = 0; i < 4; i++)
r24564r24565
755759         // end HACK
756760
757761         /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
758         m_IP = reload_table[m_tms5220c_rate&0x3];
762         m_IP = reload_table[m_c_variant_rate&0x3];
759763
760764#ifdef PERFECT_INTERPOLATION_HACK
761765         /* remember previous frame energy, pitch, and coefficients */
r24564r24565
11651169         }
11661170         break;
11671171
1168      case 0x00: case 0x20: /* set rate (tms5220c only), otherwise NOP */
1169         if (m_variant == TMS5220_IS_5220C)
1172      case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */
1173         if (TMS5220_HAS_RATE_CONTROL)
11701174         {
1171            m_tms5220c_rate = cmd&0x0F;
1175            m_c_variant_rate = cmd&0x0F;
11721176         }
11731177      break;
11741178
r24564r24565
12091213         // TODO: similar to the victory case described above, but for VSM speech
12101214         m_subcycle = m_subc_reload;
12111215         m_PC = 0;
1212         m_IP = reload_table[m_tms5220c_rate&0x3];
1216         m_IP = reload_table[m_c_variant_rate&0x3];
12131217         m_new_frame_energy_idx = 0;
12141218         m_new_frame_pitch_idx = 0;
12151219         int i;
r24564r24565
12571261
12581262   /* if the chip is a tms5220C, and the rate mode is set to that each frame (0x04 bit set)
12591263   has a 2 bit rate preceding it, grab two bits here and store them as the rate; */
1260   if ((m_variant == TMS5220_IS_5220C) && (m_tms5220c_rate & 0x04))
1264   if ((TMS5220_HAS_RATE_CONTROL) && (m_c_variant_rate & 0x04))
12611265   {
12621266      indx = extract_bits(2);
12631267#ifdef DEBUG_PARSE_FRAME_DUMP
r24564r24565
12671271      m_IP = reload_table[indx];
12681272   }
12691273   else // non-5220C and 5220C in fixed rate mode
1270   m_IP = reload_table[m_tms5220c_rate&0x3];
1274   m_IP = reload_table[m_c_variant_rate&0x3];
12711275
12721276   update_status_and_ints();
12731277   if (!m_talk_status) goto ranout;
r24564r24565
14421446//  device_start - device-specific startup
14431447//-------------------------------------------------
14441448
1445void tmc0285_device::device_start()
1449void cd2501e_device::device_start()
14461450{
14471451   tms5220_device::device_start();
1448   set_variant(TMS5220_IS_TMC0285);
1452   set_variant(TMS5220_IS_CD2501E);
14491453}
14501454
14511455//-------------------------------------------------
r24564r24565
14581462   set_variant(TMS5220_IS_5200);
14591463}
14601464
1465//-------------------------------------------------
1466//  device_start - device-specific startup
1467//-------------------------------------------------
14611468
1469void cd2501ecd_device::device_start()
1470{
1471   tms5220_device::device_start();
1472   set_variant(TMS5220_IS_CD2501ECD);
1473}
1474
14621475//-------------------------------------------------
14631476//  device_reset - device-specific reset
14641477//-------------------------------------------------
r24564r24565
14921505
14931506   /* initialize the sample generators */
14941507   m_inhibit = 1;
1495   m_subcycle = m_tms5220c_rate = m_pitch_count = m_PC = 0;
1508   m_subcycle = m_c_variant_rate = m_pitch_count = m_PC = 0;
14961509   m_subc_reload = FORCE_SUBC_RELOAD;
14971510   m_OLDE = m_OLDP = 1;
1498   m_IP = reload_table[m_tms5220c_rate&0x3];
1511   m_IP = reload_table[m_c_variant_rate&0x3];
14991512   m_RNG = 0x1FFF;
15001513   memset(m_u, 0, sizeof(m_u));
15011514   memset(m_x, 0, sizeof(m_x));
r24564r24565
15751588      m_rs_ws = new_val;
15761589      if (new_val == 0)
15771590      {
1578         if (m_variant == TMS5220_IS_5220C)
1591         if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd
15791592            reset();
15801593#ifdef DEBUG_RS_WS
15811594         else
r24564r24565
16271640      m_rs_ws = new_val;
16281641      if (new_val == 0)
16291642      {
1630         if (m_variant == TMS5220_IS_5220C)
1643         if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd
16311644            reset();
16321645#ifdef DEBUG_RS_WS
16331646         else
r24564r24565
16631676         RDBY: between 60 and 140 cycles
16641677         RB: ? cycles (80?)
16651678         RST: between 60 and 140 cycles
1666         SET RATE (5220C only): ? cycles (probably ~16)
1679         SET RATE (5220C and CD2501ECD only): ? cycles (probably ~16)
16671680         */
16681681         // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles
16691682         m_timer_io_ready->adjust(attotime::from_hz(clock()/16), 1); // this should take around 10-16 (closer to ~15) cycles to complete for fifo writes, TODO: but actually depends on what command is written if in command mode
r24564r24565
18681881}
18691882
18701883
1871const device_type TMC0285 = &device_creator<tmc0285_device>;
1884const device_type CD2501E = &device_creator<cd2501e_device>;
18721885
1873tmc0285_device::tmc0285_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1874   : tms5220_device(mconfig, TMC0285, "TMC0285", tag, owner, clock, "tmc0285", __FILE__)
1886cd2501e_device::cd2501e_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1887   : tms5220_device(mconfig, CD2501E, "CD2501E", tag, owner, clock, "cd2501e", __FILE__)
18751888{
18761889}
18771890
r24564r24565
18821895   : tms5220_device(mconfig, TMS5200, "TMS5200", tag, owner, clock, "tms5200", __FILE__)
18831896{
18841897}
1898
1899
1900const device_type CD2501ECD = &device_creator<cd2501ecd_device>;
1901
1902cd2501ecd_device::cd2501ecd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1903   : tms5220_device(mconfig, CD2501ECD, "CD2501ECD", tag, owner, clock, "cd2501ecd", __FILE__)
1904{
1905}
trunk/src/emu/sound/tms5220.h
r24564r24565
156156   /* 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 */
157157   UINT8 m_IP;               /* the current interpolation period */
158158   UINT8 m_inhibit;          /* If 1, interpolation is inhibited until the DIV1 period */
159   UINT8 m_tms5220c_rate;    /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
159   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 */
160160   UINT16 m_pitch_count;     /* pitch counter; provides chirp rom address */
161161
162162   INT32 m_u[11];
r24564r24565
216216
217217extern const device_type TMS5220C;
218218
219class tmc0285_device : public tms5220_device
219class cd2501e_device : public tms5220_device
220220{
221221public:
222   tmc0285_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
222   cd2501e_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
223223protected:
224224   // device-level overrides
225225   virtual void device_start();
226226};
227227
228extern const device_type TMC0285;
228extern const device_type CD2501E;
229229
230230class tms5200_device : public tms5220_device
231231{
r24564r24565
238238
239239extern const device_type TMS5200;
240240
241class cd2501ecd_device : public tms5220_device
242{
243public:
244   cd2501ecd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
245protected:
246   // device-level overrides
247   virtual void device_start();
248};
249
250extern const device_type CD2501ECD;
251
241252#endif
trunk/src/mess/machine/ti99/spchsyn.h
r24564r24565
4141   virtual void            device_config_complete();
4242
4343private:
44   tmc0285_device *m_vsp;
44   cd2501e_device *m_vsp;
4545};
4646
4747#endif
trunk/src/mess/machine/ti99/speech8.c
r24564r24565
123123   if (VERBOSE>4) LOG("speech8: reset\n");
124124}
125125
126// Unlike the TI-99/4A, the 99/8 uses the TMS5220C
126// Unlike the TI-99/4A, the 99/8 uses the CD2501ECD
127// The CD2501ECD is a tms5200/cd2501e with the rate control from the tms5220c added in.
128// (it's probably actually a tms5220c die with the cd2501e/tms5200 lpc rom masked onto it)
127129MACHINE_CONFIG_FRAGMENT( ti998_speech )
128130   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
129131
130132   MCFG_SPEAKER_STANDARD_MONO("mono")
131   MCFG_SOUND_ADD(SPEECHSYN_TAG, TMS5220C, 640000L)
133   MCFG_SOUND_ADD(SPEECHSYN_TAG, CD2501ECD, 640000L)
132134   MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(ti998_spsyn_device, speech8_ready))
133135   MCFG_TMS52XX_SPEECHROM("vsm")
134136   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
r24564r24565
138140   as the TI speech synthesizer. */
139141ROM_START( ti998_speech )
140142   ROM_REGION(0x8000, "vsm", 0)
143   // Note: the following line is actually wrong; the speech roms in the ti 99/4a and 99/8 are two VSM roms labeled CD2325A and CD2326A, and contain the same data as the following line rom does, but with the byte bit order reversed. This bit ordering issue needs to be fixed elsewhere in the code here before the original/real roms can be used.
141144   ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
145   // correct lines are:
146   // ROM_LOAD_OPTIONAL("cd2325a.vsm", 0x0000, 0x4000, CRC(1f58b571) SHA1(0ef4f178716b575a1c0c970c56af8a8d97561ffe))
147   // ROM_LOAD_OPTIONAL("cd2326a.vsm", 0x4000, 0x4000, CRC(65d00401) SHA1(a367242c2c96cebf0e2bf21862f3f6734b2b3020))
142148ROM_END
143149
144150machine_config_constructor ti998_spsyn_device::device_mconfig_additions() const
trunk/src/mess/machine/ti99/spchsyn.c
r24564r24565
77    right side of the console. In order to be used with Geneve and SGCPU, the
88    speech synthesizer must be moved into the Peripheral Box.
99
10    The Speech Synthesizer used for the TI was the TMS5200, aka TMC0285, a
11    predecessor of the TMS5220 which was used in other commercial products.
10    The Speech Synthesizer used for the TI was the CD2501E, AKA TMS5200,
11   (internal name TMC0285), a predecessor of the TMS5220 which was used in
12   other commercial products.
1213
1314    Note that this adapter also contains the speech roms.
1415
r24564r24565
166167
167168void ti_speech_synthesizer_device::device_config_complete()
168169{
169   m_vsp = subdevice<tmc0285_device>("speechsyn");
170   m_vsp = subdevice<cd2501e_device>("speechsyn");
170171}
171172
172173void ti_speech_synthesizer_device::device_reset()
r24564r24565
187188   MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
188189
189190   MCFG_SPEAKER_STANDARD_MONO("mono")
190   MCFG_SOUND_ADD("speechsyn", TMC0285, 640000L)
191   MCFG_SOUND_ADD("speechsyn", CD2501E, 640000L)
191192   MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(ti_speech_synthesizer_device, speech_ready))
192193   MCFG_TMS52XX_SPEECHROM("vsm")
193194   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
r24564r24565
195196
196197ROM_START( ti99_speech )
197198   ROM_REGION(0x8000, "vsm", 0)
199   // Note: the following line is actually wrong; the speech roms in the ti 99/4a and 99/8 are two VSM roms labeled CD2325A and CD2326A, and contain the same data as the following line rom does, but with the byte bit order reversed. This bit ordering issue needs to be fixed elsewhere in the code here before the original/real roms can be used.
198200   ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
201   // correct lines are:
202   // ROM_LOAD_OPTIONAL("cd2325a.u2a", 0x0000, 0x4000, CRC(1f58b571) SHA1(0ef4f178716b575a1c0c970c56af8a8d97561ffe)) // at location u2, bottom of stack
203   // ROM_LOAD_OPTIONAL("cd2326a.u2b", 0x4000, 0x4000, CRC(65d00401) SHA1(a367242c2c96cebf0e2bf21862f3f6734b2b3020)) // at location u2, top of stack
199204ROM_END
200205
201206machine_config_constructor ti_speech_synthesizer_device::device_mconfig_additions() const

Previous 199869 Revisions Next


© 1997-2024 The MAME Team