1 /**********************************************************************************************
2
3 TMS5200/5220 simulator
4
5 Written for MAME by Frank Palazzolo
6 With help from Neill Corlett
7 Additional tweaking by Aaron Giles
8 TMS6100 Speech Rom support added by Raphael Nabet
9 PRNG code by Jarek Burczynski backported from tms5110.c by Lord Nightmare
10 Chirp/excitation table fixes by Lord Nightmare
11 Various fixes by Lord Nightmare
12 Modularization by Lord Nightmare
13 Sub-interpolation-cycle parameter updating added by Lord Nightmare
14 Preliminary MASSIVE merge of tms5110 and tms5220 cores by Lord Nightmare
15 Lattice Filter, Multiplier, and clipping redone by Lord Nightmare
16 TMS5220C multi-rate feature added by Lord Nightmare
17 Massive rewrite and reorganization by Lord Nightmare
18 Additional IP, PC, subcycle timing rewrite by Lord Nightmare
19 Updated based on the chip decaps done by digshadow
20
21 Much information regarding the lpc encoding used here comes from US patent 4,209,844
22 US patent 4,331,836 describes the complete 51xx chip
23 US patent 4,335,277 describes the complete 52xx chip
24 Special Thanks to Larry Brantingham for answering questions regarding the chip details
25
26 TMS5200/TMS5220/TMS5220C:
27
28 +-----------------+
29 D7(d0) | 1 28 | /RS
30 ADD1 | 2 27 | /WS
31 ROMCLK | 3 26 | D6(d1)
32 VDD(-5) | 4 25 | ADD2
33 VSS(+5) | 5 24 | D5(d2)
34 OSC | 6 23 | ADD4
35 T11 | 7 22 | D4(d3)
36 SPKR | 8 21 | ADD8/DATA
37 I/O | 9 20 | TEST
38 PROMOUT | 10 19 | D3(d4)
39 VREF(GND)| 11 18 | /READY
40 D2(d5) | 12 17 | /INT
41 D1(d6) | 13 16 | M1
42 D0(d7) | 14 15 | M0
43 +-----------------+
44 Note the standard naming for d* data bits with 7 as MSB and 0 as LSB is in lowercase.
45 TI's naming has D7 as LSB and D0 as MSB and is in uppercase
46
47 TODO:
48 * Ever since the big rewrite, there are glitches on certain frame transitions
49 for example in the word 'robots' during the eprom attract mode,
50 I (LN) am not entirely sure why the real chip doesn't have these as well.
51 Needs more real hardware testing/dumps for comparison.
52 * Ever since the timing rewrite, the above problem is slightly worse. This
53 time, however, it is probably a 'real' bug, which I (LN) am in the process
54 of tracking down.
55 i.e. the word 'congratulations' in victory when you get a high score.
56 * Implement a ready callback for pc interfaces
57 - this will be quite a challenge since for it to be really accurate
58 the whole emulation has to run in sync (lots of timers) with the
59 cpu cores.
60 * If a command is still executing, /READY will be kept high until the command has
61 finished if the next command is written.
62 * tomcat has a 5220 which is not hooked up at all
63 * Is the TS=0 forcing energy to 0 for next frame in the interpolator actually correct? I'm (LN) guessing no. The patent schematics state that TS=0 shuts off the output dac completely, though doesn't affect the I/O pin.
64
65 Pedantic detail from observation of real chip:
66 The 5200 and 5220 chips outputs the following coefficients over PROMOUT while
67 'idle' and not speaking, in this order:
68 e[0 or f] p[0] k1[0] k2[0] k3[0] k4[0] k5[f] k6[f] k7[f] k8[7] k9[7] k10[7]
69
70 Patent notes (important timing info for interpolation):
71 * TCycle ranges from 1 to 20, is clocked based on the clock input or RC clock
72 to the chip / 4. This emulation core completely ignores TCycle, as it isn't
73 very relevant.
74 Every full TCycle count (i.e. overflow from 20 to 1), Subcycle is
75 incremented.
76 * Subcycle ranges from 0 to 2, reload is 0 in SPKSLOW mode, 1 normally, and
77 corresponds to whether an interpolation value is being calculated (0 or 1)
78 or being written to ram (2). 0 and 1 correspond to 'A' cycles on the
79 patent, while 2 corresponds to 'B' cycles.
80 Every Subcycle full count (i.e. overflow from 2 to (0 or 1)), PC is
81 incremented. (NOTE: if PC=12, overflow happens on the 1->2 transition,
82 not 2->0; PC=12 has no B cycle.)
83 * PC ranges from 0 to 12, and corresponds to the parameter being interpolated
84 or otherwise read from rom using PROMOUT.
85 The order is:
86 0 = Energy
87 1 = Pitch
88 2 = K1
89 3 = K2
90 ...
91 11 = K10
92 12 = nothing
93 Every PC full count (i.e. overflow from 12 to 0), IP (aka "Interpolation Period")
94 is incremented.
95 * IP (aka "Interpolation Period") ranges from 0 to 7, and corresponds with the amount
96 of rightshift that the difference between current and target for a given
97 parameter will have applied to it, before being added to the current
98 parameter. Note that when interpolation is inhibited, only IP=0 will
99 cause any change to the current values of the coefficients.
100 The order is, after new frame parse (last ip was 0 before parse):
101 1 = >>3 (/8)
102 2 = >>3 (/8)
103 3 = >>3 (/8)
104 4 = >>2 (/4)
105 5 = >>2 (/4)
106 6 = >>1 (/2) (NOTE: the patent has an error regarding this value on one table implying it should be /4, but circuit simulation of parts of the patent shows that the /2 value is correct.)
107 7 = >>1 (/2)
108 0 = >>0 (/1, forcing current values to equal target values)
109 Every IP full count, a new frame is parsed, but ONLY on the 0->*
110 transition.
111 NOTE: on TMS5220C ONLY, the datasheet IMPLIES the following:
112 Upon new frame parse (end of IP=0), the IP is forced to a value depending
113 on the TMS5220C-specific rate setting. For rate settings 0, 1, 2, 3, it
114 will be forced to 1, 3, 5 or 7 respectively. On non-TMS5220 chips, it
115 counts as expected (IP=1 follows IP=0) always.
116 This means, the tms5220c with rates set to n counts IP as follows:
117 (new frame parse is indicated with a #)
118 Rate IP Count
119 00 7 0#1 2 3 4 5 6 7 0#1 2 3 4 5 6 7 <- non-tms5220c chips always follow this pattern
120 01 7 0#3 4 5 6 7 0#3 4 5 6 7 0#3 4 5
121 10 7 0#5 6 7 0#5 6 7 0#5 6 7 0#5 6 7
122 11 7 0#7 0#7 0#7 0#7 0#7 0#7 0#7 0#7
123
124 Most of the following is based on figure 8c of 4,331,836, which is the
125 TMS5100/TMC0280 patent, but the same information applies to the TMS52xx
126 as well.
127
128 OLDP is a status flag which controls whether unvoiced or voiced excitation is
129 being generated. It is latched from "P=0" at IP=7 PC=12 T=16.
130 (This means that, during normal operation, between IP=7 PC=12 T16 and
131 IP=0 PC=1 T17, OLDP and P=0 are the same)
132 "P=0" is a status flag which is set if the index value for pitch for the new
133 frame being parsed (which will become the new target frame) is zero.
134 It is used for determining whether interpolation of the next frame is
135 inhibited or not. It is updated at IP=0 PC=1 T17. See next section.
136 OLDE is a status flag which is only used for determining whether
137 interpolation is inhibited or not.
138 It is latched from "E=0" at IP=7 PC=12 T=16.
139 (This means that, during normal operation, between IP=7 PC=12 T16 and
140 IP=0 PC=0 T17, OLDE and E=0 are the same)
141 "E=0" is a status flag which is set if the index value for energy for the new
142 frame being parsed (which will become the new target frame) is zero.
143 It is used for determining whether interpolation of the next frame is
144 inhibited or not. It is updated at IP=0 PC=0 T17. See next section.
145
146 Interpolation is inhibited (i.e. interpolation at IP frames will not happen
147 except for IP=0) under the following circumstances:
148 "P=0" != "OLDP" ("P=0" = 1, and OLDP = 0; OR "P=0" = 0, and OLDP = 1)
149 This means the new frame is unvoiced and the old one was voiced, or vice
150 versa.
151 * TODO the 5100 and 5200 patents are inconsistent about the above. Trace the decaps!
152 "OLDE" = 1 and "E=0" = 0
153 This means the new frame is not silent, and the old frame was silent.
154
155
156
157 ****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
160 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!
161 TALK STATUS must be CLEAR for this command to work; otherwise it is treated as a NOP.
162
163 x011xxxx: READ AND BRANCH (RB) Sends a read and branch command (M0 high, M1 high) to force VSM to set its data pointer to whatever the data is at its current pointer location is)
164 TALK STATUS must be CLEAR for this command to work; otherwise it is treated as a NOP.
165
166 x100aaaa: LOAD ADDRESS (LA) Send a load address command (M0 low M1 high) to VSM with the 4 'a' bits; Note you need to send four or five of these in sequence to actually specify an address to the vsm.
167 TALK STATUS must be CLEAR for this command to work; otherwise it is treated as a NOP.
168
169 x101xxxx: SPEAK (SPK) Begins speaking, pulling spech data from the current address pointer location of the VSM modules.
170
171 x110xxxx: SPEAK EXTERNAL (SPKEXT) Clears the FIFO using SPKEE line, then sets TALKD (TALKST remains zero) until 8 bytes have been written to the FIFO, at which point it begins speaking, pulling data from the 16 byte fifo.
172 The patent implies TALK STATUS must be CLEAR for this command to work; otherwise it is treated as a NOP, but the decap shows that this is not true, and is an error on the patent diagram.
173
174 x111xxxx: RESET (RST) Resets the speech synthesis core immediately, and clears the FIFO.
175
176
177 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.
180
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.
182
183
184 ***MAME Driver specific notes:***
185
186 Victory's initial audio selftest is pretty brutal to the FIFO: it sends a
187 sequence of bytes to the FIFO and checks the status bits after each one; if
188 even one bit is in the wrong state (i.e. speech starts one byte too early or
189 late), the test fails!
190 The sample in Victory 'Shields up!' after you activate shields, the 'up' part
191 of the sample is missing the STOP frame at the end of it; this causes the
192 speech core to run out of bits to parse from the FIFO, cutting the sample off
193 by one frame. This appears to be an original game code bug.
194
195 Progress list for drivers using old vs new interface:
196 starwars: uses new interface (couriersud)
197 gauntlet: uses new interface (couriersud)
198 atarisy1: uses new interface (Lord Nightmare)
199 atarisy2: uses new interface (Lord Nightmare)
200 atarijsa: uses new interface (Lord Nightmare)
201 firefox: uses new interface (couriersud)
202 mhavoc: uses old interface, and is in the machine file instead of the driver.
203 monymony/jackrabt(zaccaria.c): uses new interface (couriersud)
204 victory(audio/exidy.c): uses new interface (couriersud)
205 looping: uses old interface
206 portraits: uses *NO* interface; the i/o cpu hasn't been hooked to anything!
207 dotron and midwayfb(mcr.c): uses old interface
208
209
210 As for which games used which chips:
211
212 TMS5200 AKA TMC0285 AKA CD2501E: (1980 to 1983)
213 Arcade: Zaccaria's 'money money' and 'jack rabbit'; Bally/Midway's
214 'Discs of Tron' (all environmental cabs and a few upright cabs; the code
215 exists on all versions for the speech though, and upright cabs can be
216 upgraded to add it by hacking on a 'Squawk & Talk' pinball speech board
217 (which is also TMS5200 based) with a few modded components)
218 Pinball: All Bally/Midway machines which uses the 'Squawk & Talk' board.
219 Home computer: TI 99/4 PHP1500 Speech module (along with two VSM
220 serial chips); Street Electronics Corp.'s Apple II 'Echo 2' Speech
221 synthesizer (early cards only)
222
223 TMS5220: (mostly on things made between 1981 and 1984-1985)
224 Arcade: Bally/Midway's 'NFL Football'; Atari's 'Star Wars',
225 'Firefox', 'Return of the Jedi', 'Road Runner', 'The Empire Strikes
226 Back' (all verified with schematics); Venture Line's 'Looping' and 'Sky
227 Bumper' (need verify for both); Olympia's 'Portraits' (need verify);
228 Exidy's 'Victory' and 'Victor Banana' (need verify for both)
229 Pinball: Several (don't know names offhand, have not checked schematics; likely Zaccaria's 'Farfalla')
230 Home computer: Street Electronics Corp.'s Apple II 'Echo 2' Speech
231 synthesizer (later cards only); Texas Instruments' 'Speak and Learn'
232 scanner wand unit.
233
234 TMS5220C AKA TSP5220C: (on stuff made from 1984 to 1992 or so)
235 Arcade: Atari's 'Indiana Jones and the Temple of Doom', '720',
236 'Gauntlet', 'Gauntlet II', 'A.P.B.', 'Paperboy', 'RoadBlasters',
237 'Vindicators Pt II'(verify?), and 'Escape from the Planet of the Robot
238 Monsters' (all verified except for vindicators pt 2)
239 Pinball: Several (less common than the tms5220? (not sure about
240 this), mostly on later pinballs with LPC speech)
241 Home computer: Street Electronics Corp.'s 'ECHO' parallel/hobbyist
242 module (6511 based), IBM PS/2 Speech adapter (parallel port connection
243 device), PES Speech adapter (serial port connection)
244
245 Street electronics had a later 1989-era ECHO appleII card which is TSP50c0x/1x
246 MCU based speech and not tms5xxx based (though it is likely emulating the tms5220
247 in MCU code). Look for a 16-pin chip at U6 labeled "ECHO-3 SN".
248
249 ***********************************************************************************************/
250
251 #include <stddef.h>
252 #include <math.h>
253
254 #include "burnint.h"
255 #include "tms5220.h"
256
257 #define DINK_DEBUG 0
258 #undef PERFECT_INTERPOLATION_HACK
259
260 #define FIFO_SIZE 16
261
262 #ifdef TRUE
263 #undef TRUE
264 #endif
265 #define TRUE 1
266 #ifdef FALSE
267 #undef FALSE
268 #endif
269 #define FALSE 0
270
271 /* *****optional defines***** */
272
273 /* Hacky improvements which don't match patent: */
274 /* Interpolation shift logic:
275 * One of the following two lines should be used, and the other commented
276 * The second line is more accurate mathematically but not accurate to the patent
277 */
278 #define INTERP_SHIFT >> tms->coeff->interp_coeff[tms->IP]
279 //define INTERP_SHIFT / (1<<tms->coeff->interp_coeff[tms->IP])
280
281 /* Other hacks */
282 /* HACK?: if defined, outputs the low 4 bits of the lattice filter to the i/o
283 * or clip logic, even though the real hardware doesn't do this...
284 * ...actually the tms5220c might legitamately do this! */
285 #undef ALLOW_4_LSB
286
287 /* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
288 #undef PERFECT_INTERPOLATION_HACK
289
290
291 /* *****configuration of chip connection stuff***** */
292 /* 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) */
293 #define FORCE_DIGITAL 0
294
295 /* must be defined; if 1, normal speech (one A cycle, one B cycle per interpolation step); if 0; speak as if SPKSLOW was used (two A cycles, one B cycle per interpolation step) */
296 #define FORCE_SUBC_RELOAD 1
297
298
299 /* *****debugging defines***** */
300 #undef VERBOSE
301 // above is general, somewhat obsolete, catch all for debugs which don't fit elsewhere
302 #undef DEBUG_DUMP_INPUT_DATA
303 // above dumps the data input to the tms52xx to stdout, useful for making logged data dumps for real hardware tests
304 #undef DEBUG_FIFO
305 // above debugs fifo stuff: writes, reads and flag updates
306 #undef DEBUG_PARSE_FRAME_DUMP
307 // above dumps each frame to stderr: be sure to select one of the options below if you define it!
308 #undef DEBUG_PARSE_FRAME_DUMP_BIN
309 // dumps each speech frame as binary
310 #undef DEBUG_PARSE_FRAME_DUMP_HEX
311 // dumps each speech frame as hex
312 #undef DEBUG_FRAME_ERRORS
313 // above dumps info if a frame ran out of data
314 #undef DEBUG_COMMAND_DUMP
315 // above dumps all non-speech-data command writes
316 #undef DEBUG_PIN_READS
317 // above spams the errorlog with i/o ready messages whenever the ready or irq pin is read
318 #undef DEBUG_GENERATION
319 // above dumps debug information related to the sample generation loop, i.e. whether interpolation is inhibited or not, and what the current and target values for each frame are.
320 #undef DEBUG_GENERATION_VERBOSE
321 // above dumps MUCH MORE debug information related to the sample generation loop, namely the excitation, energy, pitch, k*, and output values for EVERY SINGLE SAMPLE during a frame.
322 #undef DEBUG_LATTICE
323 // above dumps the lattice filter state data each sample.
324 #undef DEBUG_CLIP
325 // above dumps info to stderr whenever the analog clip hardware is (or would be) clipping the signal.
326 #undef DEBUG_IO_READY
327 // above debugs the io ready callback
328 #undef DEBUG_RS_WS
329 // above debugs the tms5220_data_r and data_w access methods which actually respect rs and ws
330
331 #define MAX_SAMPLE_CHUNK 512
332
333 /* Variants */
334
335 #define TMS5220_IS_5220C (4)
336 #define TMS5220_IS_5200 (5)
337 #define TMS5220_IS_5220 (6)
338
339 #define TMS5220_IS_TMC0285 TMS5220_IS_5200
340
341 static 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.
342
343 struct tms5220_state
344 {
345 /* these contain data that describes the 128-bit data FIFO */
346 UINT8 fifo[FIFO_SIZE];
347 UINT8 fifo_head;
348 UINT8 fifo_tail;
349 UINT8 fifo_count;
350 UINT8 fifo_bits_taken;
351
352
353 /* these contain global status bits */
354 UINT8 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.*/
355 UINT8 speak_external; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
356 UINT8 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. */
357 UINT8 buffer_low; /* If 1, FIFO has less than 8 bytes in it */
358 UINT8 buffer_empty; /* If 1, FIFO is empty */
359 UINT8 irq_pin; /* state of the IRQ pin (output) */
360 UINT8 ready_pin; /* state of the READY pin (output) */
361
362 /* these contain data describing the current and previous voice frames */
363 #define OLD_FRAME_SILENCE_FLAG tms->OLDE // 1 if E=0, 0 otherwise.
364 #define OLD_FRAME_UNVOICED_FLAG tms->OLDP // 1 if P=0 (unvoiced), 0 if voiced
365 UINT8 OLDE;
366 UINT8 OLDP;
367
368 #define NEW_FRAME_STOP_FLAG (tms->new_frame_energy_idx == 0xF) // 1 if this is a stop (Energy = 0xF) frame
369 #define NEW_FRAME_SILENCE_FLAG (tms->new_frame_energy_idx == 0) // ditto as above
370 #define NEW_FRAME_UNVOICED_FLAG (tms->new_frame_pitch_idx == 0) // ditto as above
371 UINT8 new_frame_energy_idx;
372 UINT8 new_frame_pitch_idx;
373 UINT8 new_frame_k_idx[10];
374
375
376 /* these are all used to contain the current state of the sound generation */
377 #ifndef PERFECT_INTERPOLATION_HACK
378 INT16 current_energy;
379 INT16 current_pitch;
380 INT16 current_k[10];
381
382 INT16 target_energy;
383 INT16 target_pitch;
384 INT16 target_k[10];
385 #else
386 UINT8 old_frame_energy_idx;
387 UINT8 old_frame_pitch_idx;
388 UINT8 old_frame_k_idx[10];
389
390 INT32 current_energy;
391 INT32 current_pitch;
392 INT32 current_k[10];
393
394 INT32 target_energy;
395 INT32 target_pitch;
396 INT32 target_k[10];
397 #endif
398
399 UINT16 previous_energy; /* needed for lattice filter to match patent */
400
401 UINT8 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 */
402 UINT8 subc_reload; /* contains 1 for normal speech, 0 when SPKSLOW is active */
403 UINT8 PC; /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
404 /* 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 */
405 UINT8 IP; /* the current interpolation period */
406 UINT8 inhibit; /* If 1, interpolation is inhibited until the DIV1 period */
407 UINT8 tms5220c_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
408 UINT16 pitch_count; /* pitch counter; provides chirp rom address */
409
410 INT32 u[11];
411 INT32 x[10];
412
413 UINT16 RNG; /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
414 INT16 excitation_data;
415
416 /* R Nabet : These have been added to emulate speech Roms */
417 UINT8 schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */
418 UINT8 data_register; /* data register, used by read command */
419 UINT8 RDB_flag; /* whether we should read data register or status register */
420
421 /* io_ready: page 3 of the datasheet specifies that READY will be asserted until
422 * data is available or processed by the system.
423 */
424 UINT8 io_ready;
425
426 /* flag for "true" timing involving rs/ws */
427 UINT8 true_timing;
428
429 /* rsws - state, rs bit 1, ws bit 0 */
430 UINT8 rs_ws;
431 UINT8 read_latch;
432 UINT8 write_latch;
433
434 /* coefficient tables */
435 INT32 variant; /* Variant of the 5xxx - see tms5110r.h */
436
437 /* coefficient tables */
438 const struct tms5100_coeffs *coeff;
439
440 /* callbacks */
441 // devcb_resolved_write_line irq_func;
442 // devcb_resolved_write_line readyq_func;
443
444 INT32 (*read_callback)(INT32 count);
445 void (*load_address_callback)(INT32 data);
446 void (*read_and_branch_callback)(void);
447 void (*irq_func)(INT32 state); /* called when the state of the IRQ pin changes */
448 void (*readyq_func)(INT32 state);
449
450
451 /* The TMS52xx has two different ways of providing output data: the
452 analog speaker pin (which was usually used) and the Digital I/O pin.
453 The internal DAC used to feed the analog pin is only 8 bits, and has the
454 funny clipping/clamping logic, while the digital pin gives full 10 bit
455 resolution of the output data.
456 TODO: add a way to set/reset this other than the FORCE_DIGITAL define
457 */
458 UINT8 digital_select;
459 //device_t *device;
460
461 //const tms5220_interface *intf;
462 //sound_stream *stream;
463 INT32 clock;
464 };
465
466
467 static tms5220_state *our_chip = NULL;
468 static INT16 *soundbuf;
469
470 static double tms5220_vol;
471
472 // for resampling
473 static UINT32 nSampleSize;
474 static INT32 nFractionalPosition;
475 static INT32 nPosition;
476 static INT32 our_freq = 0; // for tms5220_set_frequency()
477
478 // for stream-sync
479 static INT32 tms5220_buffered = 0;
480 static INT32 (*pCPUTotalCycles)() = NULL;
481 static UINT32 nDACCPUMHZ = 0;
482
483 // Streambuffer handling
SyncInternal()484 static INT32 SyncInternal()
485 {
486 if (!tms5220_buffered) return 0;
487 return (INT32)(float)(nBurnSoundLen * (pCPUTotalCycles() / (nDACCPUMHZ / (nBurnFPS / 100.0000))));
488 }
489
490 static void tms5220_process(tms5220_state *tms, INT16 *buffer, UINT32 size);
491
UpdateStream(INT32 samples_len)492 void UpdateStream(INT32 samples_len)
493 {
494 if (!tms5220_buffered) return;
495 if (samples_len > nBurnSoundLen) samples_len = nBurnSoundLen;
496
497 INT32 nSamplesNeeded = ((((((our_freq * 1000) / nBurnFPS) * samples_len) / nBurnSoundLen)) / 10) + 1;
498 if (nBurnSoundRate < 44100) nSamplesNeeded += 2; // so we don't end up with negative nPosition below
499
500 nSamplesNeeded -= nPosition;
501 if (nSamplesNeeded <= 0) return;
502
503 INT16 *mix = soundbuf + 5 + nPosition;
504 memset(mix, 0, nSamplesNeeded * sizeof(INT16));
505 if (DINK_DEBUG) bprintf(0, _T("tms5220_sync: %d samples frame %d\n"), nSamplesNeeded, nCurrentFrame);
506 tms5220_process(our_chip, mix, nSamplesNeeded);
507
508 nPosition += nSamplesNeeded;
509 }
510
511
512 // Pull in the ROM tables
513 #include "tms5220_tables.h"
514
515 /* Static function prototypes */
516 static void process_command(tms5220_state *tms, UINT8 data);
517 static void parse_frame(tms5220_state *tms);
518 static void update_status_and_ints(tms5220_state *tms);
519 static void set_interrupt_state(tms5220_state *tms, INT32 state);
520 static INT32 lattice_filter(tms5220_state *tms);
521 static INT16 clip_analog(INT16 clip);
522 static void update_ready_state(tms5220_state *tms);
523
tms5220_set_variant(tms5220_state * tms,INT32 variant)524 static void tms5220_set_variant(tms5220_state *tms, INT32 variant)
525 {
526 switch (variant)
527 {
528 case TMS5220_IS_5200:
529 tms->coeff = &tms5200_coeff;
530 break;
531 case TMS5220_IS_5220C:
532 case TMS5220_IS_5220:
533 tms->coeff = &tms5220_coeff;
534 break;
535 default:
536 //fatalerror("Unknown variant in tms5220_set_variant\n");
537 break;
538 }
539 tms->variant = variant;
540 }
541
542 /**********************************************************************************************
543
544 printbits helper function: takes a long int input and prints the resulting bits to stderr
545
546 ***********************************************************************************************/
547
548 #ifdef DEBUG_PARSE_FRAME_DUMP_BIN
printbits(long data,INT32 num)549 static void printbits(long data, INT32 num)
550 {
551 INT32 i;
552 for (i=(num-1); i>=0; i--)
553 fprintf(stderr,"%0ld", (data>>i)&1);
554 }
555 #endif
556 #ifdef DEBUG_PARSE_FRAME_DUMP_HEX
printbits(long data,INT32 num)557 static void printbits(long data, INT32 num)
558 {
559 switch((num-1)&0xFC)
560 {
561 case 0:
562 fprintf(stderr,"%0lx", data);
563 break;
564 case 4:
565 fprintf(stderr,"%02lx", data);
566 break;
567 case 8:
568 fprintf(stderr,"%03lx", data);
569 break;
570 case 12:
571 fprintf(stderr,"%04lx", data);
572 break;
573 default:
574 fprintf(stderr,"%04lx", data);
575 break;
576 }
577 }
578 #endif
579
580 /**********************************************************************************************
581
582 tms5220_data_write -- handle a write to the TMS5220
583
584 ***********************************************************************************************/
585
tms5220_data_write(tms5220_state * tms,INT32 data)586 static void tms5220_data_write(tms5220_state *tms, INT32 data)
587 {
588 #ifdef DEBUG_DUMP_INPUT_DATA
589 fprintf(stdout, "%c",data);
590 #endif
591 if (tms->speak_external) // If we're in speak external mode
592 {
593 // add this byte to the FIFO
594 if (tms->fifo_count < FIFO_SIZE)
595 {
596 tms->fifo[tms->fifo_tail] = data;
597 tms->fifo_tail = (tms->fifo_tail + 1) % FIFO_SIZE;
598 tms->fifo_count++;
599 #ifdef DEBUG_FIFO
600 logerror("data_write: Added byte to FIFO (current count=%2d)\n", tms->fifo_count);
601 #endif
602 update_status_and_ints(tms);
603 if ((tms->talk_status == 0) && (tms->buffer_low == 0)) // we just unset buffer low with that last write, and talk status *was* zero...
604 {
605 INT32 i;
606 #ifdef DEBUG_FIFO
607 logerror("data_write triggered talk status to go active!\n");
608 #endif
609 // ...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() )
610 // 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
611 tms->subcycle = tms->subc_reload;
612 tms->PC = 0;
613 tms->IP = reload_table[tms->tms5220c_rate&0x3]; // is this correct? should this be always 7 instead, so that the new frame is loaded quickly?
614 tms->new_frame_energy_idx = 0;
615 tms->new_frame_pitch_idx = 0;
616 for (i = 0; i < 4; i++)
617 tms->new_frame_k_idx[i] = 0;
618 for (i = 4; i < 7; i++)
619 tms->new_frame_k_idx[i] = 0xF;
620 for (i = 7; i < tms->coeff->num_k; i++)
621 tms->new_frame_k_idx[i] = 0x7;
622 tms->talk_status = tms->speaking_now = 1;
623 }
624 }
625 else
626 {
627 #ifdef DEBUG_FIFO
628 logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n");
629 // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it.
630 #endif
631 }
632
633
634 }
635 else //(! tms->speak_external)
636 // R Nabet : we parse commands at once. It is necessary for such commands as read.
637 process_command(tms,data);
638 }
639
640 /**********************************************************************************************
641
642 update_status_and_ints -- check to see if the various flags should be on or off
643 Description of flags, and their position in the status register:
644 From the data sheet:
645 bit D0(bit 7) = TS - Talk Status is active (high) when the VSP is processing speech data.
646 Talk Status goes active at the initiation of a Speak command or after nine
647 bytes of data are loaded into the FIFO following a Speak External command. It
648 goes inactive (low) when the stop code (Energy=1111) is processed, or
649 immediately by a buffer empty condition or a reset command.
650 bit D1(bit 6) = BL - Buffer Low is active (high) when the FIFO buffer is more than half empty.
651 Buffer Low is set when the "Last-In" byte is shifted down past the half-full
652 boundary of the stack. Buffer Low is cleared when data is loaded to the stack
653 so that the "Last-In" byte lies above the half-full boundary and becomes the
654 eighth data byte of the stack.
655 bit D2(bit 5) = BE - Buffer Empty is active (high) when the FIFO buffer has run out of data
656 while executing a Speak External command. Buffer Empty is set when the last bit
657 of the "Last-In" byte is shifted out to the Synthesis Section. This causes
658 Talk Status to be cleared. Speech is terminated at some abnormal point and the
659 Speak External command execution is terminated.
660
661 ***********************************************************************************************/
662
update_status_and_ints(tms5220_state * tms)663 static void update_status_and_ints(tms5220_state *tms)
664 {
665 /* update flags and set ints if needed */
666
667 update_ready_state(tms);
668
669 /* BL is set if neither byte 9 nor 8 of the fifo are in use; this
670 translates to having fifo_count (which ranges from 0 bytes in use to 16
671 bytes used) being less than or equal to 8. Victory/Victorba depends on this. */
672 if (tms->fifo_count <= 8)
673 {
674 // generate an interrupt if necessary; if /BL was inactive and is now active, set int.
675 if (!tms->buffer_low)
676 set_interrupt_state(tms, 1);
677 tms->buffer_low = 1;
678 }
679 else
680 tms->buffer_low = 0;
681
682 /* BE is set if neither byte 15 nor 14 of the fifo are in use; this
683 translates to having fifo_count equal to exactly 0 */
684 if (tms->fifo_count == 0)
685 {
686 // generate an interrupt if necessary; if /BE was inactive and is now active, set int.
687 if (!tms->buffer_empty)
688 set_interrupt_state(tms, 1);
689 tms->buffer_empty = 1;
690 }
691 else
692 tms->buffer_empty = 0;
693
694 /* TS is talk status and is set elsewhere in the fifo parser and in
695 the SPEAK command handler; however, if /BE is true during speak external
696 mode, it is immediately unset here. */
697 if ((tms->speak_external == 1) && (tms->buffer_empty == 1))
698 {
699 // generate an interrupt: /TS was active, and is now inactive.
700 if (tms->talk_status == 1)
701 {
702 tms->talk_status = tms->speak_external = 0;
703 set_interrupt_state(tms, 1);
704 }
705 }
706 /* Note that TS being unset will also generate an interrupt when a STOP
707 frame is encountered; this is handled in the sample generator code and not here */
708 }
709
710 /**********************************************************************************************
711
712 extract_bits -- extract a specific number of bits from the current input stream (FIFO or VSM)
713
714 ***********************************************************************************************/
715
extract_bits(tms5220_state * tms,INT32 count)716 static INT32 extract_bits(tms5220_state *tms, INT32 count)
717 {
718 INT32 val = 0;
719
720 if (tms->speak_external)
721 {
722 // extract from FIFO
723 while (count--)
724 {
725 val = (val << 1) | ((tms->fifo[tms->fifo_head] >> tms->fifo_bits_taken) & 1);
726 tms->fifo_bits_taken++;
727 if (tms->fifo_bits_taken >= 8)
728 {
729 tms->fifo_count--;
730 tms->fifo[tms->fifo_head] = 0; // zero the newly depleted fifo head byte
731 tms->fifo_head = (tms->fifo_head + 1) % FIFO_SIZE;
732 tms->fifo_bits_taken = 0;
733 update_status_and_ints(tms);
734 }
735 }
736 }
737 else
738 {
739 // extract from VSM (speech ROM)
740 if (tms->read_callback)
741 val = (* tms->read_callback)(count);
742 }
743
744 return val;
745 }
746
747 /**********************************************************************************************
748
749 tms5220_status_read -- read status or data from the TMS5220
750
751 ***********************************************************************************************/
752
tms5220_status_read(tms5220_state * tms)753 static INT32 tms5220_status_read(tms5220_state *tms)
754 {
755 if (tms->RDB_flag)
756 { /* if last command was read, return data register */
757 tms->RDB_flag = FALSE;
758 return(tms->data_register);
759 }
760 else
761 { /* read status */
762
763 /* clear the interrupt pin on status read */
764 set_interrupt_state(tms, 0);
765 #ifdef DEBUG_PIN_READS
766 logerror("Status read: TS=%d BL=%d BE=%d\n", tms->talk_status, tms->buffer_low, tms->buffer_empty);
767 #endif
768
769 return (tms->talk_status << 7) | (tms->buffer_low << 6) | (tms->buffer_empty << 5);
770 }
771 }
772
773
774 /**********************************************************************************************
775
776 tms5220_ready_read -- returns the ready state of the TMS5220
777
778 ***********************************************************************************************/
779
tms5220_ready_read(tms5220_state * tms)780 static INT32 tms5220_ready_read(tms5220_state *tms)
781 {
782 #ifdef DEBUG_PIN_READS
783 logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d\n", tms->io_ready, tms->fifo_count);
784 #endif
785 return ((tms->fifo_count < FIFO_SIZE)||(!tms->speak_external)) && tms->io_ready;
786 }
787
788
789 /**********************************************************************************************
790
791 tms5220_cycles_to_ready -- returns the number of cycles until ready is asserted
792 NOTE: this function is deprecated and is known to be VERY inaccurate.
793 Use at your own peril!
794
795 ***********************************************************************************************/
796
tms5220_cycles_to_ready(tms5220_state * tms)797 static INT32 tms5220_cycles_to_ready(tms5220_state *tms)
798 {
799 INT32 answer;
800
801
802 if (tms5220_ready_read(tms))
803 answer = 0;
804 else
805 {
806 INT32 val;
807 INT32 samples_per_frame = tms->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
808 INT32 current_sample = ((tms->PC*(3-tms->subc_reload))+((tms->subc_reload?38:25)*tms->IP));
809 answer = samples_per_frame-current_sample+8;
810
811 // total number of bits available in current byte is (8 - tms->fifo_bits_taken)
812 // if more than 4 are available, we need to check the energy
813 if (tms->fifo_bits_taken < 4)
814 {
815 // read energy
816 val = (tms->fifo[tms->fifo_head] >> tms->fifo_bits_taken) & 0xf;
817 if (val == 0)
818 /* 0 -> silence frame: we will only read 4 bits, and we will
819 * therefore need to read another frame before the FIFO is not
820 * full any more */
821 answer += tms->subc_reload?200:304;
822 /* 15 -> stop frame, we will only read 4 bits, but the FIFO will
823 * we cleared; otherwise, we need to parse the repeat flag (1 bit)
824 * and the pitch (6 bits), so everything will be OK. */
825 }
826 }
827
828 return answer;
829 }
830
831
832 /**********************************************************************************************
833
834 tms5220_int_read -- returns the interrupt state of the TMS5220
835
836 ***********************************************************************************************/
837
tms5220_int_read(tms5220_state * tms)838 static INT32 tms5220_int_read(tms5220_state *tms)
839 {
840 #ifdef DEBUG_PIN_READS
841 logerror("int_read: irq pin read, state is %d\n", tms->irq_pin);
842 #endif
843 return tms->irq_pin;
844 }
845
846
847 /**********************************************************************************************
848
849 tms5220_process -- fill the buffer with a specific number of samples
850
851 ***********************************************************************************************/
852
tms5220_process(tms5220_state * tms,INT16 * buffer,UINT32 size)853 static void tms5220_process(tms5220_state *tms, INT16 *buffer, UINT32 size)
854 {
855 INT32 buf_count=0;
856 INT32 i, bitout, zpar;
857 INT32 this_sample;
858
859 /* the following gotos are probably safe to remove */
860 /* if we're empty and still not speaking, fill with nothingness */
861 if (!tms->speaking_now)
862 goto empty;
863
864 /* if speak external is set, but talk status is not (yet) set,
865 wait for buffer low to clear */
866 if (!tms->talk_status && tms->speak_external && tms->buffer_low)
867 goto empty;
868
869 /* loop until the buffer is full or we've stopped speaking */
870 while ((size > 0) && tms->speaking_now)
871 {
872 /* if it is the appropriate time to update the old energy/pitch idxes,
873 * i.e. when IP=7, PC=12, T=17, subcycle=2, do so. Since IP=7 PC=12 T=17
874 * is JUST BEFORE the transition to IP=0 PC=0 T=0 sybcycle=(0 or 1),
875 * which happens 4 T-cycles later), we change on the latter.*/
876 if ((tms->IP == 0) && (tms->PC == 0) && (tms->subcycle < 2))
877 {
878 tms->OLDE = (tms->new_frame_energy_idx == 0);
879 tms->OLDP = (tms->new_frame_pitch_idx == 0);
880 }
881
882 /* if we're ready for a new frame to be applied, i.e. when IP=0, PC=12, Sub=1
883 * (In reality, the frame was really loaded incrementally during the entire IP=0
884 * PC=x time period, but it doesn't affect anything until IP=0 PC=12 happens)
885 */
886 if ((tms->IP == 0) && (tms->PC == 12) && (tms->subcycle == 1))
887 {
888 // HACK for regression testing, be sure to comment out before release!
889 //tms->RNG = 0x1234;
890 // end HACK
891
892 /* appropriately override the interp count if needed; this will be incremented after the frame parse! */
893 tms->IP = reload_table[tms->tms5220c_rate&0x3];
894
895 #ifdef PERFECT_INTERPOLATION_HACK
896 /* remember previous frame energy, pitch, and coefficients */
897 tms->old_frame_energy_idx = tms->new_frame_energy_idx;
898 tms->old_frame_pitch_idx = tms->new_frame_pitch_idx;
899 for (i = 0; i < tms->coeff->num_k; i++)
900 tms->old_frame_k_idx[i] = tms->new_frame_k_idx[i];
901 #endif
902
903 /* if the talk status was clear last frame, halt speech now. */
904 if (tms->talk_status == 0)
905 {
906 #ifdef DEBUG_GENERATION
907 fprintf(stderr,"tms5220_process: processing frame: talk status = 0 caused by stop frame or buffer empty, halting speech.\n");
908 #endif
909 tms->speaking_now = 0; // finally halt speech
910 goto empty;
911 }
912
913
914 /* Parse a new frame into the new_target_energy, new_target_pitch and new_target_k[] */
915 parse_frame(tms);
916 #ifdef DEBUG_PARSE_FRAME_DUMP
917 fprintf(stderr,"\n");
918 #endif
919
920 /* if the new frame is a stop frame, set an interrupt and set talk status to 0 */
921 if (NEW_FRAME_STOP_FLAG == 1)
922 {
923 tms->talk_status = tms->speak_external = 0;
924 set_interrupt_state(tms, 1);
925 update_status_and_ints(tms);
926 }
927
928 /* in all cases where interpolation would be inhibited, set the inhibit flag; otherwise clear it.
929 Interpolation inhibit cases:
930 * Old frame was voiced, new is unvoiced
931 * Old frame was silence/zero energy, new has nonzero energy
932 * 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)
933 */
934 if ( ((OLD_FRAME_UNVOICED_FLAG == 0) && (NEW_FRAME_UNVOICED_FLAG == 1))
935 || ((OLD_FRAME_UNVOICED_FLAG == 1) && (NEW_FRAME_UNVOICED_FLAG == 0)) /* this line needs further investigation, starwars tie fighters may sound better without it */
936 || ((OLD_FRAME_SILENCE_FLAG == 1) && (NEW_FRAME_SILENCE_FLAG == 0)) )
937 tms->inhibit = 1;
938 else // normal frame, normal interpolation
939 tms->inhibit = 0;
940
941 /* load new frame targets from tables, using parsed indices */
942 tms->target_energy = tms->coeff->energytable[tms->new_frame_energy_idx];
943 tms->target_pitch = tms->coeff->pitchtable[tms->new_frame_pitch_idx];
944 zpar = NEW_FRAME_UNVOICED_FLAG; // find out if parameters k5-k10 should be zeroed
945 for (i = 0; i < 4; i++)
946 tms->target_k[i] = tms->coeff->ktable[i][tms->new_frame_k_idx[i]];
947 for (i = 4; i < tms->coeff->num_k; i++)
948 tms->target_k[i] = (tms->coeff->ktable[i][tms->new_frame_k_idx[i]] * (1-zpar));
949
950 #ifdef DEBUG_GENERATION
951 /* Debug info for current parsed frame */
952 fprintf(stderr, "OLDE: %d; OLDP: %d; ", tms->OLDE, tms->OLDP);
953 fprintf(stderr,"Processing frame: ");
954 if (tms->inhibit == 0)
955 fprintf(stderr, "Normal Frame\n");
956 else
957 fprintf(stderr,"Interpolation Inhibited\n");
958 fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",tms->current_energy, tms->current_pitch, tms->current_k[0], tms->current_k[1], tms->current_k[2], tms->current_k[3], tms->current_k[4], tms->current_k[5], tms->current_k[6], tms->current_k[7], tms->current_k[8], tms->current_k[9]);
959 fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",tms->target_energy, tms->new_frame_energy_idx, tms->target_pitch, tms->target_k[0], tms->target_k[1], tms->target_k[2], tms->target_k[3], tms->target_k[4], tms->target_k[5], tms->target_k[6], tms->target_k[7], tms->target_k[8], tms->target_k[9]);
960 #endif
961
962 /* if TS is now 0, ramp the energy down to 0. Is this really correct to hardware? */
963 if (tms->talk_status == 0)
964 {
965 #ifdef DEBUG_GENERATION
966 fprintf(stderr,"Talk status is 0, forcing target energy to 0\n");
967 #endif
968 tms->target_energy = 0;
969 }
970 }
971 else // Not a new frame, just interpolate the existing frame.
972 {
973 INT32 inhibit_state = ((tms->inhibit==1)&&(tms->IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the tms->inhibit value
974 #ifdef PERFECT_INTERPOLATION_HACK
975 INT32 samples_per_frame = tms->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
976 //INT32 samples_per_frame = tms->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
977 INT32 current_sample = (tms->subcycle - tms->subc_reload)+(tms->PC*(3-tms->subc_reload))+((tms->subc_reload?25:38)*((tms->IP-1)&7));
978
979 zpar = OLD_FRAME_UNVOICED_FLAG;
980 //fprintf(stderr, "CS: %03d", current_sample);
981 // reset the current energy, pitch, etc to what it was at frame start
982 tms->current_energy = tms->coeff->energytable[tms->old_frame_energy_idx];
983 tms->current_pitch = tms->coeff->pitchtable[tms->old_frame_pitch_idx];
984 for (i = 0; i < 4; i++)
985 tms->current_k[i] = tms->coeff->ktable[i][tms->old_frame_k_idx[i]];
986 for (i = 4; i < tms->coeff->num_k; i++)
987 tms->current_k[i] = (tms->coeff->ktable[i][tms->old_frame_k_idx[i]] * (1-zpar));
988 // now adjust each value to be exactly correct for each of the samples per frame
989 if (tms->IP != 0) // if we're still interpolating...
990 {
991 tms->current_energy += (((tms->target_energy - tms->current_energy)*(1-inhibit_state))*current_sample)/samples_per_frame;
992 tms->current_pitch += (((tms->target_pitch - tms->current_pitch)*(1-inhibit_state))*current_sample)/samples_per_frame;
993 for (i = 0; i < tms->coeff->num_k; i++)
994 tms->current_k[i] += (((tms->target_k[i] - tms->current_k[i])*(1-inhibit_state))*current_sample)/samples_per_frame;
995 }
996 else // we're done, play this frame for 1/8 frame.
997 {
998 tms->current_energy = tms->target_energy;
999 tms->current_pitch = tms->target_pitch;
1000 for (i = 0; i < tms->coeff->num_k; i++)
1001 tms->current_k[i] = tms->target_k[i];
1002 }
1003 #else
1004 //Updates to parameters only happen on subcycle '2' (B cycle) of PCs.
1005 if (tms->subcycle == 2)
1006 {
1007 switch(tms->PC)
1008 {
1009 case 0: /* PC = 0, B cycle, write updated energy */
1010 tms->current_energy += (((tms->target_energy - tms->current_energy)*(1-inhibit_state)) INTERP_SHIFT);
1011 break;
1012 case 1: /* PC = 1, B cycle, write updated pitch */
1013 tms->current_pitch += (((tms->target_pitch - tms->current_pitch)*(1-inhibit_state)) INTERP_SHIFT);
1014 break;
1015 case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
1016 /* PC = 2 through 11, B cycle, write updated K1 through K10 */
1017 tms->current_k[tms->PC-2] += (((tms->target_k[tms->PC-2] - tms->current_k[tms->PC-2])*(1-inhibit_state)) INTERP_SHIFT);
1018 break;
1019 case 12: /* PC = 12, do nothing */
1020 break;
1021 }
1022 }
1023 #endif
1024 }
1025
1026 // calculate the output
1027 if (OLD_FRAME_UNVOICED_FLAG == 1)
1028 {
1029 // generate unvoiced samples here
1030 if (tms->RNG & 1)
1031 tms->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)*/
1032 else
1033 tms->excitation_data = 0x40;
1034 }
1035 else /* (OLD_FRAME_UNVOICED_FLAG == 0) */
1036 {
1037 // generate voiced samples here
1038 /* US patent 4331836 Figure 14B shows, and logic would hold, that a pitch based chirp
1039 * function has a chirp/peak and then a long chain of zeroes.
1040 * The last entry of the chirp rom is at address 0b110011 (51d), the 52nd sample,
1041 * and if the address reaches that point the ADDRESS incrementer is
1042 * disabled, forcing all samples beyond 51d to be == 51d
1043 */
1044 if (tms->pitch_count >= 51)
1045 tms->excitation_data = tms->coeff->chirptable[51];
1046 else /*tms->pitch_count < 51*/
1047 tms->excitation_data = tms->coeff->chirptable[tms->pitch_count];
1048 }
1049
1050 // Update LFSR *20* times every sample (once per T cycle), like patent shows
1051 for (i=0; i<20; i++)
1052 {
1053 bitout = ((tms->RNG >> 12) & 1) ^
1054 ((tms->RNG >> 3) & 1) ^
1055 ((tms->RNG >> 2) & 1) ^
1056 ((tms->RNG >> 0) & 1);
1057 tms->RNG <<= 1;
1058 tms->RNG |= bitout;
1059 }
1060 this_sample = lattice_filter(tms); /* execute lattice filter */
1061 #ifdef DEBUG_GENERATION_VERBOSE
1062 //fprintf(stderr,"C:%01d; ",tms->subcycle);
1063 fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",tms->IP, tms->PC, tms->excitation_data, tms->current_energy, tms->current_pitch, tms->pitch_count);
1064 //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", tms->excitation_data, tms->current_energy, tms->current_pitch, tms->pitch_count);
1065 for (i=0; i<10; i++)
1066 fprintf(stderr,"K%d:%04d ", i+1, tms->current_k[i]);
1067 fprintf(stderr,"Out:%06d", this_sample);
1068 fprintf(stderr,"\n");
1069 #endif
1070 /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */
1071 while (this_sample > 16383) this_sample -= 32768;
1072 while (this_sample < -16384) this_sample += 32768;
1073 if (tms->digital_select == 0) // analog SPK pin output is only 8 bits, with clipping
1074 buffer[buf_count] = clip_analog(this_sample);
1075 else // digital I/O pin output is 12 bits
1076 {
1077 #ifdef ALLOW_4_LSB
1078 // input: ssss ssss ssss ssss ssnn nnnn nnnn nnnn
1079 // N taps: ^ = 0x2000;
1080 // output: ssss ssss ssss ssss snnn nnnn nnnn nnnN
1081 buffer[buf_count] = (this_sample<<1)|((this_sample&0x2000)>>13);
1082 #else
1083 this_sample &= ~0xF;
1084 // input: ssss ssss ssss ssss ssnn nnnn nnnn 0000
1085 // N taps: ^^ ^^^ = 0x3E00;
1086 // output: ssss ssss ssss ssss snnn nnnn nnnN NNNN
1087 buffer[buf_count] = (this_sample<<1)|((this_sample&0x3E00)>>9);
1088 #endif
1089 }
1090 // Update all counts
1091
1092 tms->subcycle++;
1093 if ((tms->subcycle == 2) && (tms->PC == 12))
1094 {
1095 /* Circuit 412 in the patent acts a reset, resetting the pitch counter to 0
1096 * if INHIBIT was true during the most recent frame transition.
1097 * The exact time this occurs is betwen IP=7, PC=12 sub=0, T=t12
1098 * and tms->IP = 0, PC=0 sub=0, T=t12, a period of exactly 20 cycles,
1099 * which overlaps the time OLDE and OLDP are updated at IP=7 PC=12 T17
1100 * (and hence INHIBIT itself 2 t-cycles later). We do it here because it is
1101 * convenient and should make no difference in output.
1102 */
1103 if ((tms->IP == 7)&&(tms->inhibit==1)) tms->pitch_count = 0;
1104 tms->subcycle = tms->subc_reload;
1105 tms->PC = 0;
1106 tms->IP++;
1107 tms->IP&=0x7;
1108 }
1109 else if (tms->subcycle == 3)
1110 {
1111 tms->subcycle = tms->subc_reload;
1112 tms->PC++;
1113 }
1114 tms->pitch_count++;
1115 if (tms->pitch_count >= tms->current_pitch) tms->pitch_count = 0;
1116 tms->pitch_count &= 0x1FF;
1117 buf_count++;
1118 size--;
1119 }
1120
1121 empty:
1122
1123 while (size > 0)
1124 {
1125 tms->subcycle++;
1126 if ((tms->subcycle == 2) && (tms->PC == 12))
1127 {
1128 tms->subcycle = tms->subc_reload;
1129 tms->PC = 0;
1130 tms->IP++;
1131 tms->IP&=0x7;
1132 }
1133 else if (tms->subcycle == 3)
1134 {
1135 tms->subcycle = tms->subc_reload;
1136 tms->PC++;
1137 }
1138 buffer[buf_count] = -1; /* should be just -1; actual chip outputs -1 every idle sample; (cf note in data sheet, p 10, table 4) */
1139 buf_count++;
1140 size--;
1141 }
1142 }
1143
1144 /**********************************************************************************************
1145
1146 clip_analog -- clips the 14 bit return value from the lattice filter to its final 10 bit value (-512 to 511), and upshifts/range extends this to 16 bits
1147
1148 ***********************************************************************************************/
1149
clip_analog(INT16 cliptemp)1150 static INT16 clip_analog(INT16 cliptemp)
1151 {
1152 /* clipping, just like the patent shows:
1153 * the top 10 bits of this result are visible on the digital output IO pin.
1154 * next, if the top 3 bits of the 14 bit result are all the same, the lowest of those 3 bits plus the next 7 bits are the signed analog output, otherwise the low bits are all forced to match the inverse of the topmost bit, i.e.:
1155 * 1x xxxx xxxx xxxx -> 0b10000000
1156 * 11 1bcd efgh xxxx -> 0b1bcdefgh
1157 * 00 0bcd efgh xxxx -> 0b0bcdefgh
1158 * 0x xxxx xxxx xxxx -> 0b01111111
1159 */
1160 #ifdef DEBUG_CLIP
1161 if ((cliptemp > 2047) || (cliptemp < -2048)) fprintf(stderr,"clipping cliptemp to range; was %d\n", cliptemp);
1162 #endif
1163 if (cliptemp > 2047) cliptemp = 2047;
1164 else if (cliptemp < -2048) cliptemp = -2048;
1165 /* at this point the analog output is tapped */
1166 #ifdef ALLOW_4_LSB
1167 // input: ssss snnn nnnn nnnn
1168 // N taps: ^^^ ^ = 0x0780
1169 // output: snnn nnnn nnnn NNNN
1170 return (cliptemp << 4)|((cliptemp&0x780)>>7); // upshift and range adjust
1171 #else
1172 cliptemp &= ~0xF;
1173 // input: ssss snnn nnnn 0000
1174 // N taps: ^^^ ^^^^ = 0x07F0
1175 // P taps: ^ = 0x0400
1176 // output: snnn nnnn NNNN NNNP
1177 return (cliptemp << 4)|((cliptemp&0x7F0)>>3)|((cliptemp&0x400)>>10); // upshift and range adjust
1178 #endif
1179 }
1180
1181
1182 /**********************************************************************************************
1183
1184 matrix_multiply -- does the proper multiply and shift
1185 a is the k coefficient and is clamped to 10 bits (9 bits plus a sign)
1186 b is the running result and is clamped to 14 bits.
1187 output is 14 bits, but note the result LSB bit is always 1.
1188 Because the low 4 bits of the result are trimmed off before
1189 output, this makes almost no difference in the computation.
1190
1191 **********************************************************************************************/
matrix_multiply(INT32 a,INT32 b)1192 static INT32 matrix_multiply(INT32 a, INT32 b)
1193 {
1194 INT32 result;
1195 while (a>511) { a-=1024; }
1196 while (a<-512) { a+=1024; }
1197 while (b>16383) { b-=32768; }
1198 while (b<-16384) { b+=32768; }
1199 result = ((a*b)>>9)|1;//&(~1);
1200 #ifdef VERBOSE
1201 if (result>16383) fprintf(stderr,"matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result);
1202 if (result<-16384) fprintf(stderr,"matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result);
1203 #endif
1204 return result;
1205 }
1206
1207 /**********************************************************************************************
1208
1209 lattice_filter -- executes one 'full run' of the lattice filter on a specific byte of
1210 excitation data, and specific values of all the current k constants, and returns the
1211 resulting sample.
1212
1213 ***********************************************************************************************/
1214
lattice_filter(tms5220_state * tms)1215 static INT32 lattice_filter(tms5220_state *tms)
1216 {
1217 // Lattice filter here
1218 // Aug/05/07: redone as unrolled loop, for clarity - LN
1219 /* Originally Copied verbatim from table I in US patent 4,209,804, now updated to be in same order as the actual chip does it, not that it matters.
1220 notation equivalencies from table:
1221 Yn(i) == tms->u[n-1]
1222 Kn = tms->current_k[n-1]
1223 bn = tms->x[n-1]
1224 */
1225 tms->u[10] = matrix_multiply(tms->previous_energy, (tms->excitation_data<<6)); //Y(11)
1226 tms->u[9] = tms->u[10] - matrix_multiply(tms->current_k[9], tms->x[9]);
1227 tms->u[8] = tms->u[9] - matrix_multiply(tms->current_k[8], tms->x[8]);
1228 tms->u[7] = tms->u[8] - matrix_multiply(tms->current_k[7], tms->x[7]);
1229 tms->u[6] = tms->u[7] - matrix_multiply(tms->current_k[6], tms->x[6]);
1230 tms->u[5] = tms->u[6] - matrix_multiply(tms->current_k[5], tms->x[5]);
1231 tms->u[4] = tms->u[5] - matrix_multiply(tms->current_k[4], tms->x[4]);
1232 tms->u[3] = tms->u[4] - matrix_multiply(tms->current_k[3], tms->x[3]);
1233 tms->u[2] = tms->u[3] - matrix_multiply(tms->current_k[2], tms->x[2]);
1234 tms->u[1] = tms->u[2] - matrix_multiply(tms->current_k[1], tms->x[1]);
1235 tms->u[0] = tms->u[1] - matrix_multiply(tms->current_k[0], tms->x[0]);
1236 tms->x[9] = tms->x[8] + matrix_multiply(tms->current_k[8], tms->u[8]);
1237 tms->x[8] = tms->x[7] + matrix_multiply(tms->current_k[7], tms->u[7]);
1238 tms->x[7] = tms->x[6] + matrix_multiply(tms->current_k[6], tms->u[6]);
1239 tms->x[6] = tms->x[5] + matrix_multiply(tms->current_k[5], tms->u[5]);
1240 tms->x[5] = tms->x[4] + matrix_multiply(tms->current_k[4], tms->u[4]);
1241 tms->x[4] = tms->x[3] + matrix_multiply(tms->current_k[3], tms->u[3]);
1242 tms->x[3] = tms->x[2] + matrix_multiply(tms->current_k[2], tms->u[2]);
1243 tms->x[2] = tms->x[1] + matrix_multiply(tms->current_k[1], tms->u[1]);
1244 tms->x[1] = tms->x[0] + matrix_multiply(tms->current_k[0], tms->u[0]);
1245 tms->x[0] = tms->u[0];
1246 tms->previous_energy = tms->current_energy;
1247 #ifdef DEBUG_LATTICE
1248 INT32 i;
1249 fprintf(stderr,"V:%04d ", tms->u[10]);
1250 for (i = 9; i >= 0; i--)
1251 {
1252 fprintf(stderr,"Y%d:%04d ", i+1, tms->u[i]);
1253 fprintf(stderr,"b%d:%04d ", i+1, tms->x[i]);
1254 if ((i % 5) == 0) fprintf(stderr,"\n");
1255 }
1256 #endif
1257 return tms->u[0];
1258 }
1259
1260
1261 /**********************************************************************************************
1262
1263 process_command -- extract a byte from the FIFO and interpret it as a command
1264
1265 ***********************************************************************************************/
1266
process_command(tms5220_state * tms,UINT8 cmd)1267 static void process_command(tms5220_state *tms, UINT8 cmd)
1268 {
1269 #ifdef DEBUG_COMMAND_DUMP
1270 fprintf(stderr,"process_command called with parameter %02X\n",cmd);
1271 #endif
1272 /* parse the command */
1273 switch (cmd & 0x70)
1274 {
1275 case 0x10 : /* read byte */
1276 if (tms->talk_status == 0) /* TALKST must be clear for RDBY */
1277 {
1278 if (tms->schedule_dummy_read)
1279 {
1280 tms->schedule_dummy_read = FALSE;
1281 if (tms->read_callback)
1282 (*tms->read_callback)(1);
1283 }
1284 if (tms->read_callback)
1285 tms->data_register = (*tms->read_callback)(8); /* read one byte from speech ROM... */
1286 tms->RDB_flag = TRUE;
1287 }
1288 break;
1289
1290 case 0x00: case 0x20: /* set rate (tms5220c only), otherwise NOP */
1291 if (tms->variant == TMS5220_IS_5220C)
1292 {
1293 tms->tms5220c_rate = cmd&0x0F;
1294 }
1295 break;
1296
1297 case 0x30 : /* read and branch */
1298 if (tms->talk_status == 0) /* TALKST must be clear for RB */
1299 {
1300 #ifdef VERBOSE
1301 logerror("read and branch command received\n");
1302 #endif
1303 tms->RDB_flag = FALSE;
1304 if (tms->read_and_branch_callback)
1305 (*tms->read_and_branch_callback)();
1306 }
1307 break;
1308
1309 case 0x40 : /* load address */
1310 if (tms->talk_status == 0) /* TALKST must be clear for LA */
1311 {
1312 /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
1313 This code does not care about this. */
1314 if (tms->load_address_callback)
1315 (*tms->load_address_callback)(cmd & 0x0f);
1316 tms->schedule_dummy_read = TRUE;
1317 }
1318 break;
1319
1320 case 0x50 : /* speak */
1321 if (tms->schedule_dummy_read)
1322 {
1323 tms->schedule_dummy_read = FALSE;
1324 if (tms->read_callback)
1325 (*tms->read_callback)(1);
1326 }
1327 tms->speaking_now = 1;
1328 tms->speak_external = 0;
1329 tms->talk_status = 1; /* start immediately */
1330 /* clear out variables before speaking */
1331 // TODO: similar to the victory case described above, but for VSM speech
1332 tms->subcycle = tms->subc_reload;
1333 tms->PC = 0;
1334 tms->IP = reload_table[tms->tms5220c_rate&0x3];
1335 tms->new_frame_energy_idx = 0;
1336 tms->new_frame_pitch_idx = 0;
1337 INT32 i;
1338 for (i = 0; i < 4; i++)
1339 tms->new_frame_k_idx[i] = 0;
1340 for (i = 4; i < 7; i++)
1341 tms->new_frame_k_idx[i] = 0xF;
1342 for (i = 7; i < tms->coeff->num_k; i++)
1343 tms->new_frame_k_idx[i] = 0x7;
1344 break;
1345
1346 case 0x60 : /* speak external */
1347 //SPKEXT going active activates SPKEE which clears the fifo
1348 tms->fifo_head = tms->fifo_tail = tms->fifo_count = tms->fifo_bits_taken = 0;
1349 tms->speak_external = 1;
1350 tms->RDB_flag = FALSE;
1351 break;
1352
1353 case 0x70 : /* reset */
1354 if (tms->schedule_dummy_read)
1355 {
1356 tms->schedule_dummy_read = FALSE;
1357 if (tms->read_callback)
1358 (*tms->read_callback)(1);
1359 }
1360 tms5220_reset();
1361 break;
1362 }
1363
1364 /* update the buffer low state */
1365 update_status_and_ints(tms);
1366 }
1367
1368 /******************************************************************************************
1369
1370 parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer
1371
1372 ******************************************************************************************/
1373
parse_frame(tms5220_state * tms)1374 static void parse_frame(tms5220_state *tms)
1375 {
1376 INT32 indx, i, rep_flag;
1377
1378 // We actually don't care how many bits are left in the fifo here; the frame subpart will be processed normally, and any bits extracted 'past the end' of the fifo will be read as zeroes; the fifo being emptied will set the /BE latch which will halt speech exactly as if a stop frame had been encountered (instead of whatever partial frame was read); the same exact circuitry is used for both on the real chip, see us patent 4335277 sheet 16, gates 232a (decode stop frame) and 232b (decode /BE plus DDIS (decode disable) which is active during speak external).
1379
1380 /* if the chip is a tms5220C, and the rate mode is set to that each frame (0x04 bit set)
1381 has a 2 bit rate preceding it, grab two bits here and store them as the rate; */
1382 if ((tms->variant == TMS5220_IS_5220C) && (tms->tms5220c_rate & 0x04))
1383 {
1384 indx = extract_bits(tms, 2);
1385 #ifdef DEBUG_PARSE_FRAME_DUMP
1386 printbits(indx,2);
1387 fprintf(stderr," ");
1388 #endif
1389 tms->IP = reload_table[indx];
1390 }
1391 else // non-5220C and 5220C in fixed rate mode
1392 tms->IP = reload_table[tms->tms5220c_rate&0x3];
1393
1394 update_status_and_ints(tms);
1395 if (!tms->talk_status) goto ranout;
1396
1397 // attempt to extract the energy index
1398 tms->new_frame_energy_idx = extract_bits(tms,tms->coeff->energy_bits);
1399 #ifdef DEBUG_PARSE_FRAME_DUMP
1400 printbits(tms->new_frame_energy_idx,tms->coeff->energy_bits);
1401 fprintf(stderr," ");
1402 #endif
1403 update_status_and_ints(tms);
1404 if (!tms->talk_status) goto ranout;
1405 // if the energy index is 0 or 15, we're done
1406 if ((tms->new_frame_energy_idx == 0) || (tms->new_frame_energy_idx == 15))
1407 return;
1408
1409
1410 // attempt to extract the repeat flag
1411 rep_flag = extract_bits(tms,1);
1412 #ifdef DEBUG_PARSE_FRAME_DUMP
1413 printbits(rep_flag, 1);
1414 fprintf(stderr," ");
1415 #endif
1416
1417 // attempt to extract the pitch
1418 tms->new_frame_pitch_idx = extract_bits(tms,tms->coeff->pitch_bits);
1419 #ifdef DEBUG_PARSE_FRAME_DUMP
1420 printbits(tms->new_frame_pitch_idx,tms->coeff->pitch_bits);
1421 fprintf(stderr," ");
1422 #endif
1423 update_status_and_ints(tms);
1424 if (!tms->talk_status) goto ranout;
1425 // if this is a repeat frame, just do nothing, it will reuse the old coefficients
1426 if (rep_flag)
1427 return;
1428
1429 // extract first 4 K coefficients
1430 for (i = 0; i < 4; i++)
1431 {
1432 tms->new_frame_k_idx[i] = extract_bits(tms,tms->coeff->kbits[i]);
1433 #ifdef DEBUG_PARSE_FRAME_DUMP
1434 printbits(tms->new_frame_k_idx[i],tms->coeff->kbits[i]);
1435 fprintf(stderr," ");
1436 #endif
1437 update_status_and_ints(tms);
1438 if (!tms->talk_status) goto ranout;
1439 }
1440
1441 // if the pitch index was zero, we only need 4 K's...
1442 if (tms->new_frame_pitch_idx == 0)
1443 {
1444 /* and the rest of the coefficients are zeroed, but that's done in the generator code */
1445 return;
1446 }
1447
1448 // If we got here, we need the remaining 6 K's
1449 for (i = 4; i < tms->coeff->num_k; i++)
1450 {
1451 tms->new_frame_k_idx[i] = extract_bits(tms, tms->coeff->kbits[i]);
1452 #ifdef DEBUG_PARSE_FRAME_DUMP
1453 printbits(tms->new_frame_k_idx[i],tms->coeff->kbits[i]);
1454 fprintf(stderr," ");
1455 #endif
1456 update_status_and_ints(tms);
1457 if (!tms->talk_status) goto ranout;
1458 }
1459 #ifdef VERBOSE
1460 if (tms->speak_external)
1461 logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (tms->fifo_count*8)-(tms->fifo_bits_taken));
1462 else
1463 logerror("Parsed a frame successfully in ROM\n");
1464 #endif
1465 return;
1466
1467 ranout:
1468 #ifdef DEBUG_FRAME_ERRORS
1469 logerror("Ran out of bits on a parse!\n");
1470 #endif
1471 return;
1472 }
1473
1474 /**********************************************************************************************
1475
1476 set_interrupt_state -- generate an interrupt
1477
1478 ***********************************************************************************************/
1479
set_interrupt_state(tms5220_state * tms,INT32 state)1480 static void set_interrupt_state(tms5220_state *tms, INT32 state)
1481 {
1482 #ifdef DEBUG_PIN_READS
1483 logerror("irq pin set to state %d\n", state);
1484 #endif
1485 if (tms->irq_func != NULL && state != tms->irq_pin)
1486 tms->irq_func(!state);
1487 tms->irq_pin = state;
1488 }
1489
1490 /**********************************************************************************************
1491
1492 update_ready_state -- update the ready line
1493
1494 ***********************************************************************************************/
1495
update_ready_state(tms5220_state * tms)1496 static void update_ready_state(tms5220_state *tms)
1497 {
1498 INT32 state = tms5220_ready_read(tms);
1499 #ifdef DEBUG_PIN_READS
1500 logerror("ready pin set to state %d\n", state);
1501 #endif
1502 if (tms->readyq_func != NULL && state != tms->ready_pin)
1503 tms->readyq_func(!state);
1504 tms->ready_pin = state;
1505 }
1506
1507
1508 /**********************************************************************************************
1509
1510 DEVICE_START( tms5220 ) -- allocate buffers and reset the 5220
1511
1512 ***********************************************************************************************/
1513
tms5220_init_int(INT32 chipvariant)1514 static void tms5220_init_int(INT32 chipvariant)
1515 {
1516 our_chip = (tms5220_state*)BurnMalloc(sizeof(tms5220_state));
1517
1518 memset(our_chip, 0, sizeof(tms5220_state));
1519
1520 tms5220_set_variant(our_chip, chipvariant);
1521 //tms->clock = clock;
1522
1523 /* not during reset which is called frm within a write! */
1524 our_chip->io_ready = 1;
1525 our_chip->true_timing = 0;
1526 our_chip->rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup
1527
1528 our_freq = 0;
1529
1530 tms5220_volume(1.00);
1531
1532 soundbuf = (INT16*)BurnMalloc(0x1000);
1533 }
1534
tms5200_init()1535 void tms5200_init()
1536 {
1537 tms5220_init_int(TMS5220_IS_5200);
1538 }
1539
tms5220_init()1540 void tms5220_init()
1541 {
1542 tms5220_init_int(TMS5220_IS_5220);
1543 }
1544
tms5220c_init()1545 void tms5220c_init()
1546 {
1547 tms5220_init_int(TMS5220_IS_5220C);
1548 }
1549
tms5200_init(INT32 (* pCPUCyclesCB)(),INT32 nCpuMHZ)1550 void tms5200_init(INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
1551 {
1552 bprintf(0, _T("*** Using BUFFERED tms5220-mode.\n"));
1553 tms5220_buffered = 1;
1554
1555 tms5200_init();
1556
1557 pCPUTotalCycles = pCPUCyclesCB;
1558 nDACCPUMHZ = nCpuMHZ;
1559 }
1560
tms5220_init(INT32 (* pCPUCyclesCB)(),INT32 nCpuMHZ)1561 void tms5220_init(INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
1562 {
1563 bprintf(0, _T("*** Using BUFFERED tms5220-mode.\n"));
1564 tms5220_buffered = 1;
1565
1566 tms5220_init();
1567
1568 pCPUTotalCycles = pCPUCyclesCB;
1569 nDACCPUMHZ = nCpuMHZ;
1570 }
1571
tms5220c_init(INT32 (* pCPUCyclesCB)(),INT32 nCpuMHZ)1572 void tms5220c_init(INT32 (*pCPUCyclesCB)(), INT32 nCpuMHZ)
1573 {
1574 bprintf(0, _T("*** Using BUFFERED tms5220C-mode.\n"));
1575 tms5220_buffered = 1;
1576
1577 tms5220c_init();
1578
1579 pCPUTotalCycles = pCPUCyclesCB;
1580 nDACCPUMHZ = nCpuMHZ;
1581 }
1582
tms5220_exit()1583 void tms5220_exit()
1584 {
1585 BurnFree(our_chip);
1586 BurnFree(soundbuf);
1587
1588 tms5220_buffered = 0;
1589 pCPUTotalCycles = NULL;
1590 nDACCPUMHZ = 0;
1591 our_freq = 0;
1592 }
1593
tms5220_volume(double vol)1594 void tms5220_volume(double vol)
1595 {
1596 tms5220_vol = vol;
1597 }
1598
tms5220_reset()1599 void tms5220_reset()
1600 {
1601 tms5220_state *tms = our_chip;
1602
1603 tms->digital_select = FORCE_DIGITAL; // assume analog output
1604 /* initialize the FIFO */
1605 /*memset(tms->fifo, 0, sizeof(tms->fifo));*/
1606 tms->fifo_head = tms->fifo_tail = tms->fifo_count = tms->fifo_bits_taken = 0;
1607
1608 /* initialize the chip state */
1609 /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if tms->buffer_empty or tms->buffer_low are 0 */
1610 tms->speaking_now = tms->speak_external = tms->talk_status = tms->irq_pin = tms->ready_pin = 0;
1611 set_interrupt_state(tms, 0);
1612 update_ready_state(tms);
1613 tms->buffer_empty = tms->buffer_low = 1;
1614
1615 tms->RDB_flag = FALSE;
1616
1617 /* initialize the energy/pitch/k states */
1618 #ifdef PERFECT_INTERPOLATION_HACK
1619 tms->old_frame_energy_idx = tms->old_frame_pitch_idx = 0;
1620 memset(tms->old_frame_k_idx, 0, sizeof(tms->old_frame_k_idx));
1621 #endif
1622 tms->new_frame_energy_idx = tms->current_energy = tms->target_energy = 0;
1623 tms->new_frame_pitch_idx = tms->current_pitch = tms->target_pitch = 0;
1624 memset(tms->new_frame_k_idx, 0, sizeof(tms->new_frame_k_idx));
1625 memset(tms->current_k, 0, sizeof(tms->current_k));
1626 memset(tms->target_k, 0, sizeof(tms->target_k));
1627
1628 /* initialize the sample generators */
1629 tms->inhibit = 1;
1630 tms->subcycle = tms->tms5220c_rate = tms->pitch_count = tms->PC = 0;
1631 tms->subc_reload = FORCE_SUBC_RELOAD;
1632 tms->OLDE = tms->OLDP = 1;
1633 tms->IP = reload_table[tms->tms5220c_rate&0x3];
1634 tms->RNG = 0x1FFF;
1635 memset(tms->u, 0, sizeof(tms->u));
1636 memset(tms->x, 0, sizeof(tms->x));
1637
1638 if (tms->load_address_callback)
1639 (*tms->load_address_callback)(0);
1640
1641 tms->schedule_dummy_read = TRUE;
1642 }
1643
tms5220_scan(INT32 nAction,INT32 * pnMin)1644 void tms5220_scan(INT32 nAction, INT32 *pnMin)
1645 {
1646 struct BurnArea ba;
1647
1648 if (nAction & ACB_DRIVER_DATA) {
1649 memset(&ba, 0, sizeof(ba));
1650 ba.Data = our_chip;
1651 ba.nLen = STRUCT_SIZE_HELPER(tms5220_state, variant);
1652 ba.szName = "TMS5220 SpeechSynth Chip";
1653 BurnAcb(&ba);
1654 }
1655 }
1656
1657 /**********************************************************************************************
1658
1659 True timing
1660
1661 ***********************************************************************************************/
1662
io_ready_cb(INT32 param)1663 static void io_ready_cb(INT32 param)
1664 {
1665 tms5220_state *tms = our_chip;
1666 if (param)
1667 {
1668 switch (tms->rs_ws)
1669 {
1670 case 0x02:
1671 /* Write */
1672 /* bring up to date first */
1673 #ifdef DEBUG_IO_READY
1674 logerror("Serviced write: %02x\n", tms->write_latch);
1675 //fprintf(stderr, "Processed write data: %02X\n", tms->write_latch);
1676 #endif
1677 UpdateStream(SyncInternal());
1678 tms5220_data_write(tms, tms->write_latch);
1679 break;
1680 case 0x01:
1681 /* Read */
1682 /* bring up to date first */
1683 UpdateStream(SyncInternal());
1684 tms->read_latch = tms5220_status_read(tms);
1685 break;
1686 case 0x03:
1687 /* High Impedance */
1688 case 0x00:
1689 /* illegal */
1690 break;
1691 }
1692 }
1693 tms->io_ready = param;
1694 update_ready_state(tms);
1695 }
1696
1697 /*
1698 * /RS line write handler
1699 */
tms5220_rsq_w(UINT8 state)1700 void tms5220_rsq_w(UINT8 state)
1701 {
1702 tms5220_state *tms = our_chip;
1703 UINT8 new_val;
1704
1705 tms->true_timing = 1;
1706 state &= 0x01;
1707 #ifdef DEBUG_RS_WS
1708 logerror("/RS written with data: %d\n", state);
1709 #endif
1710 new_val = (tms->rs_ws & 0x01) | (state<<1);
1711 if (new_val != tms->rs_ws)
1712 {
1713 tms->rs_ws = new_val;
1714 if (new_val == 0)
1715 {
1716 if (tms->variant == TMS5220_IS_5220C)
1717 tms5220_reset();
1718 #ifdef DEBUG_RS_WS
1719 else
1720 /* illegal */
1721 logerror("tms5220_rs_w: illegal\n");
1722 #endif
1723 return;
1724 }
1725 else if ( new_val == 3)
1726 {
1727 /* high impedance */
1728 tms->read_latch = 0xff;
1729 return;
1730 }
1731 if (state)
1732 {
1733 /* low to high */
1734 }
1735 else
1736 {
1737 /* high to low - schedule ready cycle */
1738 #ifdef DEBUG_RS_WS
1739 logerror("Scheduling ready cycle for /RS...\n");
1740 #endif
1741 /* 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. */
1742 tms->io_ready = 0;
1743 update_ready_state(tms);
1744 /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */
1745 io_ready_cb(1);
1746 //tms->device->machine().scheduler().timer_set(attotime::from_hz(device->clock()/16), FUNC(io_ready_cb), 1, tms); // this should take around 10-16 (closer to ~11?) cycles to complete
1747 }
1748 }
1749 }
1750
1751 /*
1752 * /WS line write handler
1753 */
tms5220_wsq_w(UINT8 state)1754 void tms5220_wsq_w(UINT8 state)
1755 {
1756 tms5220_state *tms = our_chip;
1757 UINT8 new_val;
1758
1759 tms->true_timing = 1;
1760 state &= 0x01;
1761 #ifdef DEBUG_RS_WS
1762 logerror("/WS written with data: %d\n", state);
1763 #endif
1764 new_val = (tms->rs_ws & 0x02) | (state<<0);
1765 if (new_val != tms->rs_ws)
1766 {
1767 tms->rs_ws = new_val;
1768 if (new_val == 0)
1769 {
1770 if (tms->variant == TMS5220_IS_5220C)
1771 tms5220_reset();
1772 #ifdef DEBUG_RS_WS
1773 else
1774 /* illegal */
1775 logerror("tms5220_ws_w: illegal\n");
1776 #endif
1777 return;
1778 }
1779 else if ( new_val == 3)
1780 {
1781 /* high impedance */
1782 tms->read_latch = 0xff;
1783 return;
1784 }
1785 if (state)
1786 {
1787 /* low to high */
1788 }
1789 else
1790 {
1791 /* high to low - schedule ready cycle */
1792 #ifdef DEBUG_RS_WS
1793 logerror("Scheduling ready cycle for /WS...\n");
1794 #endif
1795 /* 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. */
1796 tms->io_ready = 0;
1797 update_ready_state(tms);
1798 /* Now comes the complicated part: long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not...
1799 Speak external mode: ~16 cycles
1800 Command Mode:
1801 SPK: ? cycles
1802 SPKEXT: ? cycles
1803 RDBY: between 60 and 140 cycles
1804 RB: ? cycles (80?)
1805 RST: between 60 and 140 cycles
1806 SET RATE (5220C only): ? cycles (probably ~16)
1807 */
1808 // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles
1809 //tms->device->machine().scheduler().timer_set(attotime::from_hz(device->clock()/16), FUNC(io_ready_cb), 1, tms); // 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
1810 io_ready_cb(1);
1811 }
1812 }
1813 }
1814
1815 /**********************************************************************************************
1816
1817 tms5220_data_w -- write data to the sound chip
1818
1819 ***********************************************************************************************/
1820
tms5220_write(UINT8 data)1821 void tms5220_write(UINT8 data)
1822 {
1823 tms5220_state *tms = our_chip;
1824 #ifdef DEBUG_RS_WS
1825 logerror("tms5220_data_w: data %02x\n", data);
1826 #endif
1827 if (!tms->true_timing)
1828 {
1829 /* bring up to date first */
1830 UpdateStream(SyncInternal());
1831 tms5220_data_write(tms, data);
1832 }
1833 else
1834 {
1835 /* actually in a write ? */
1836 #ifdef DEBUG_RS_WS
1837 if (!(tms->rs_ws == 0x02))
1838 logerror("tms5220_data_w: data written outside ws, status: %02x!\n", tms->rs_ws);
1839 #endif
1840 tms->write_latch = data;
1841 }
1842 }
1843
1844
1845
1846 /**********************************************************************************************
1847
1848 tms5220_status_r -- read status or data from the sound chip
1849
1850 ***********************************************************************************************/
1851
tms5220_status()1852 UINT8 tms5220_status()
1853 {
1854 tms5220_state *tms = our_chip;
1855 if (!tms->true_timing)
1856 {
1857 /* bring up to date first */
1858 UpdateStream(SyncInternal());
1859 return tms5220_status_read(tms);
1860 }
1861 else
1862 {
1863 /* actually in a read ? */
1864 if (tms->rs_ws == 0x01)
1865 return tms->read_latch;
1866 #ifdef DEBUG_RS_WS
1867 else
1868 logerror("tms5220_status_r: data read outside rs!\n");
1869 #endif
1870 return 0xff;
1871 }
1872 }
1873
1874
1875
1876 /**********************************************************************************************
1877
1878 tms5220_ready_r -- return the not ready status from the sound chip
1879
1880 ***********************************************************************************************/
1881
tms5220_ready()1882 UINT8 tms5220_ready()
1883 {
1884 tms5220_state *tms = our_chip;
1885 /* bring up to date first */
1886 UpdateStream(SyncInternal());
1887 return tms5220_ready_read(tms);
1888 }
1889
1890
1891
1892 /**********************************************************************************************
1893
1894 tms5220_time_to_ready -- return the time in seconds until the ready line is asserted
1895
1896 ***********************************************************************************************/
1897
tms5220_time_to_ready()1898 double tms5220_time_to_ready()
1899 {
1900 tms5220_state *tms = our_chip;
1901 double cycles;
1902
1903 /* bring up to date first */
1904 UpdateStream(SyncInternal());
1905 cycles = tms5220_cycles_to_ready(tms);
1906 return cycles * 80.0 / our_freq;
1907 }
1908
1909
1910
1911 /**********************************************************************************************
1912
1913 tms5220_int_r -- return the int status from the sound chip
1914
1915 ***********************************************************************************************/
1916
tms5220_intq()1917 UINT8 tms5220_intq()
1918 {
1919 tms5220_state *tms = our_chip;
1920 /* bring up to date first */
1921 UpdateStream(SyncInternal());
1922 return !tms5220_int_read(tms);
1923 }
1924
1925
1926
1927 /**********************************************************************************************
1928
1929 tms5220_set_frequency -- adjusts the playback frequency
1930
1931 ***********************************************************************************************/
1932
tms5220_set_frequency(UINT32 frequency)1933 void tms5220_set_frequency(UINT32 frequency)
1934 {
1935 if ((frequency/80) != our_freq) {
1936 UpdateStream(SyncInternal());
1937
1938 our_freq = frequency/80;
1939 nSampleSize = (UINT32)our_freq * (1 << 16) / nBurnSoundRate;
1940 }
1941 }
1942
tms5220_update(INT16 * buffer,INT32 samples_len)1943 void tms5220_update(INT16 *buffer, INT32 samples_len)
1944 {
1945 INT32 nSamplesNeeded = ((((((our_freq * 1000) / nBurnFPS) * samples_len) / nBurnSoundLen)) / 10) + 1;
1946 if (nBurnSoundRate < 44100) nSamplesNeeded += 2; // so we don't end up with negative nPosition below
1947
1948 INT16 *mix = soundbuf + 5 + nPosition;
1949 memset(mix, 0, nSamplesNeeded * sizeof(INT16));
1950
1951 tms5220_process(our_chip, mix, nSamplesNeeded - nPosition);
1952
1953 INT16 *pBufL = soundbuf + 5;
1954
1955 for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < (samples_len << 1); i += 2, nFractionalPosition += nSampleSize) {
1956 INT32 nLeftSample[4] = {0, 0, 0, 0};
1957 INT32 nTotalLeftSample; // it's mono!
1958
1959 nLeftSample[0] += (INT32)(pBufL[(nFractionalPosition >> 16) - 3]);
1960 nLeftSample[1] += (INT32)(pBufL[(nFractionalPosition >> 16) - 2]);
1961 nLeftSample[2] += (INT32)(pBufL[(nFractionalPosition >> 16) - 1]);
1962 nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition >> 16) - 0]);
1963
1964 nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
1965 nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample * tms5220_vol);
1966
1967 buffer[i + 0] = BURN_SND_CLIP(buffer[i + 0] + nTotalLeftSample);
1968 buffer[i + 1] = BURN_SND_CLIP(buffer[i + 1] + nTotalLeftSample);
1969 }
1970
1971 if (samples_len >= nBurnSoundLen) {
1972 INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16);
1973
1974 for (INT32 i = -4; i < nExtraSamples; i++) {
1975 pBufL[i] = pBufL[(nFractionalPosition >> 16) + i];
1976 }
1977
1978 nFractionalPosition &= 0xFFFF;
1979
1980 nPosition = nExtraSamples;
1981 }
1982 }
1983
1984