1 //#define SINGLE_STEP
2 //#define DEBUG
3 //#define DEBUG_FIFO
4 /*
5 * ============================================================================
6 * Title: Intellivoice Emulation
7 * Author: J. Zbiciak
8 * ============================================================================
9 * This module actually attempts to emulate the Intellivoice. Wild!
10 * ============================================================================
11 * The Intellivoice is mapped into two locations in memory, $0080-$0081.
12 * (This ignores the separate 8-bit bus that the SPB-640 provides, since
13 * nothing uses it and I haven't emulated it.)
14 *
15 * Location $0080 provides an interface to the "Address LoaD" (ALD)
16 * mechanism on the SP0256. Reads from this address return the current
17 * "Load ReQuest" (LRQ) state in bit 15. When LRQ is 1 (ie. bit 15 of
18 * location $0080 reads as 1), the SP0256 is ready to receive a new command.
19 * A new command address may then be written to location $0080 to trigger
20 * the playback of a sound. Note that command address register is actually
21 * a 1-deep FIFO, and so LRQ will go to 1 before the SP0256 is finished
22 * speaking.
23 *
24 * Location $0081 provides an interface to the SPB-640's 64-decle speech
25 * FIFO. Reads from this address return the "FIFO full" state in bit 15.
26 * When bit 15 reads as 0, the FIFO has room for at least 1 more decle.
27 * Writes to this address can either clear the FIFO, or provide new data
28 * to the FIFO. To clear the FIFO, write a value with Bit 10 == 1.
29 * To put a decle into the FIFO, write a value with Bit 10 == 0. It's
30 * currently unknown what happens when a program attempts to write to the
31 * FIFO when the FIFO is full. This emulation drops the extra data.
32 *
33 * The exact format of the SP0256 speech data, as well as the overall
34 * system view from the SP0256's perspective is documented elsewhere.
35 * ============================================================================
36 */
37
38 /*#define SINGLE_STEP*/
39
40 #undef DEBUG_FIFO
41 #ifdef DEBUG_FIFO
42 #define dfprintf(x) jzp_printf x ; jzp_flush()
43 #else
44 #define dfprintf(x)
45 #endif
46
47 #undef DEBUG
48 #ifdef DEBUG
49 #define jzdprintf(x) jzp_printf x ; jzp_flush()
50 #else
51 #define jzdprintf(x)
52 #endif
53
54 #undef HIGH_QUALITY
55 #define SCBUF_SIZE (4096) /* Must be power of 2 */
56 #define SCBUF_MASK (SCBUF_SIZE - 1)
57 #define PER_PAUSE (64) /* Equiv timing period for pauses. */
58 #define PER_NOISE (64) /* Equiv timing period for noise. */
59
60 #define FIFO_ADDR (0x1800 << 3) /* SP0256 address of speech FIFO. */
61
62
63 #include <assert.h>
64 #include "../config.h"
65 #include "periph/periph.h"
66 #include "snd/snd.h"
67 #include "gfx/gfx.h"
68 #include "demo/demo.h"
69 #include "stic/stic.h"
70 #include "speed/speed.h"
71 #include "misc/crc32.h"
72 #include "lzoe/lzoe.h"
73 #include "file/file.h"
74 #include "ivoice.h"
75
76 /* ======================================================================== */
77 /* Internal function prototypes. */
78 /* ======================================================================== */
79 LOCAL INLINE int16_t limit (int16_t s);
80 LOCAL INLINE uint32_t bitrev(uint32_t val);
81 LOCAL int lpc12_update(lpc12_t *f, int, int16_t *, uint32_t *);
82 LOCAL void lpc12_regdec(lpc12_t *f);
83 LOCAL uint32_t sp0256_getb(ivoice_t *ivoice, int len);
84 LOCAL void sp0256_micro(ivoice_t *iv);
85 LOCAL void iv_smp_start (ivoice_t *iv);
86 LOCAL void iv_smp_stop (ivoice_t *iv);
87 LOCAL INLINE void iv_smp_record(ivoice_t *iv, int ns, int16_t *out, int id);
88
89 LOCAL const uint8_t wav_hdr[44] =
90 {
91 0x52, 0x49, 0x46, 0x46, /* "RIFF" */
92 0x00, 0x00, 0x00, 0x00, /* Total file length - 8 */
93 0x57, 0x41, 0x56, 0x45, /* "WAVE" */
94 0x66, 0x6D, 0x74, 0x20, /* "fmt " */
95 0x10, 0x00, 0x00, 0x00, /* 0x10 == PCM */
96 0x01, 0x00, /* 0x01 == PCM */
97 0x01, 0x00, /* 1 channel */
98 0x10, 0x27, 0x00, 0x00, /* Sample rate == 10kHz */
99 0x20, 0x4E, 0x00, 0x00, /* Byte rate == 20 kB/sec */
100 0x02, 0x00, /* Block alignment: channels * bits/sample / 8 */
101 0x10, 0x00, /* Bits/sample = 16. */
102 0x64, 0x61, 0x74, 0x61, /* "data" */
103 0x00, 0x00, 0x00, 0x00 /* Total sample data length */
104 };
105
106 /* ======================================================================== */
107 /* IV_SMP_UPHDR -- Update length field in header for each sample block. */
108 /* ======================================================================== */
iv_smp_uphdr(ivoice_t * iv)109 LOCAL void iv_smp_uphdr(ivoice_t *iv)
110 {
111 uint32_t tot_smp_bytes, tot_file_bytes;
112 uint8_t upd_wav_hdr[44];
113
114 /* -------------------------------------------------------------------- */
115 /* Poke the size information into the header both places it appears. */
116 /* Do this to a private copy of the header. */
117 /* -------------------------------------------------------------------- */
118 memcpy(upd_wav_hdr, wav_hdr, 44);
119
120 tot_smp_bytes = iv->smp_totsmp * 2;
121 tot_file_bytes = tot_smp_bytes + 36;
122
123 /* Total file size, minus first 8 bytes */
124 upd_wav_hdr[ 4] = (tot_file_bytes >> 0) & 0xFF;
125 upd_wav_hdr[ 5] = (tot_file_bytes >> 8) & 0xFF;
126 upd_wav_hdr[ 6] = (tot_file_bytes >> 16) & 0xFF;
127 upd_wav_hdr[ 7] = (tot_file_bytes >> 24) & 0xFF;
128
129 /* Total size of sample-data payload */
130 upd_wav_hdr[40] = (tot_smp_bytes >> 0) & 0xFF;
131 upd_wav_hdr[41] = (tot_smp_bytes >> 8) & 0xFF;
132 upd_wav_hdr[42] = (tot_smp_bytes >> 16) & 0xFF;
133 upd_wav_hdr[43] = (tot_smp_bytes >> 24) & 0xFF;
134
135 /* -------------------------------------------------------------------- */
136 /* Rewind to the beginning of the file to write the header. Skip */
137 /* it if the seek fails for some reason. */
138 /* -------------------------------------------------------------------- */
139 if (fseek(iv->smp_file, 0, SEEK_SET) == 0)
140 {
141 fwrite(upd_wav_hdr, 44, 1, iv->smp_file);
142 fseek(iv->smp_file, 0, SEEK_END);
143 }
144 }
145
146 /* ======================================================================== */
147 /* IV_SMP_START -- Start a new sample recording file. */
148 /* ======================================================================== */
iv_smp_start(ivoice_t * iv)149 LOCAL void iv_smp_start(ivoice_t *iv)
150 {
151 int tries;
152
153 /* -------------------------------------------------------------------- */
154 /* We don't have a filename, don't do anything. */
155 /* -------------------------------------------------------------------- */
156 if (!iv->smp_tname)
157 return;
158
159 /* -------------------------------------------------------------------- */
160 /* Stop recording previous sample if two samples back-to-back. */
161 /* -------------------------------------------------------------------- */
162 if (iv->smp_file)
163 iv_smp_stop(iv);
164
165 /* -------------------------------------------------------------------- */
166 /* Generate a filename for the current sequence number. */
167 /* -------------------------------------------------------------------- */
168 tries = 10;
169 iv->smp_number--;
170 do
171 {
172 iv->smp_number++;
173 iv->smp_cksum = (uint32_t *)
174 realloc(iv->smp_cksum,
175 sizeof(uint32_t)*(iv->smp_number+1));
176 iv->smp_cksum[iv->smp_number] = 0x00000000;
177
178 sprintf(iv->smp_cname, "%s%.4d.wav", iv->smp_tname, iv->smp_number);
179 if (file_exists(iv->smp_cname))
180 continue;
181
182 iv->smp_file = fopen(iv->smp_cname, "wb");
183 } while (!iv->smp_file && tries-->0);
184
185 iv->smp_cursum = 0;
186 iv->smp_totsmp = 0;
187 if (iv->smp_file)
188 {
189 /* Write an initial WAV header w/out size information initially. */
190 fwrite(wav_hdr, 1, sizeof(wav_hdr), iv->smp_file);
191 jzp_clear_and_eol(
192 jzp_printf("ivoice: starting sample: %s", iv->smp_cname));
193 jzp_flush();
194 }
195 }
196
197 /* ======================================================================== */
198 /* IV_SMP_STOP -- Stop a sample recording file. */
199 /* ======================================================================== */
iv_smp_stop(ivoice_t * iv)200 LOCAL void iv_smp_stop(ivoice_t *iv)
201 {
202 int i;
203
204 /* -------------------------------------------------------------------- */
205 /* We don't have a filename or file, don't do anything. */
206 /* -------------------------------------------------------------------- */
207 if (!iv->smp_tname || !iv->smp_file)
208 return;
209
210 /* -------------------------------------------------------------------- */
211 /* Write the file length to the header and close the file. */
212 /* -------------------------------------------------------------------- */
213 iv_smp_uphdr(iv);
214 fclose(iv->smp_file);
215 iv->smp_file = NULL;
216
217 jzp_clear_and_eol(
218 jzp_printf("ivoice: stopping sample: %s CRC: %.8X len: %d",
219 iv->smp_cname, iv->smp_cursum, iv->smp_totsmp));
220
221 /* -------------------------------------------------------------------- */
222 /* If this file was unique, keep it. Otherwise unlink it. */
223 /* -------------------------------------------------------------------- */
224 i = 0;
225 if (iv->smp_cksum)
226 for (i = 0; i < iv->smp_number; i++)
227 if (iv->smp_cksum[i] == iv->smp_cursum)
228 break;
229
230 /* -------------------------------------------------------------------- */
231 /* If we found a match, so don't keep it. */
232 /* -------------------------------------------------------------------- */
233 if (i != iv->smp_number)
234 {
235 jzp_printf("ivoice: sample was a repeat of earlier sample: %d\n", i);
236 unlink(iv->smp_cname);
237 return;
238 }
239
240
241 iv->smp_cksum = (uint32_t*)realloc(iv->smp_cksum,
242 sizeof(uint32_t)*(iv->smp_number+1));
243 iv->smp_cksum[iv->smp_number++] = iv->smp_cursum;
244 }
245
246 /* ======================================================================== */
247 /* IV_SMP_RECORD -- Add a sample to a current sample record file. */
248 /* ======================================================================== */
iv_smp_record(ivoice_t * iv,int num_samp,int16_t * out,int oidx)249 LOCAL INLINE void iv_smp_record(ivoice_t *iv, int num_samp, int16_t *out,
250 int oidx)
251 {
252 uint8_t buf[SCBUF_SIZE * 2];
253
254 if (iv->smp_file)
255 {
256 int i;
257
258 for (i = 0; i < num_samp; i++)
259 {
260 buf[2*i + 0] = out[(i+oidx) & SCBUF_MASK] & 0xFF;
261 buf[2*i + 1] = (out[(i+oidx) & SCBUF_MASK] >> 8) & 0xFF;
262 }
263 fwrite(buf, 2, num_samp, iv->smp_file);
264 iv->smp_totsmp += num_samp;
265 iv_smp_uphdr(iv); /* fix bug where early exit leaves 0 len in hdr. */
266 }
267 }
268
iv_smp_ckupd(ivoice_t * iv,uint8_t byte)269 LOCAL INLINE void iv_smp_ckupd(ivoice_t *iv, uint8_t byte)
270 {
271 iv->smp_cursum = CRC32_UPDATE(iv->smp_cursum, byte);
272 }
273
274 /* ======================================================================== */
275 /* IVOICE_QTBL -- Coefficient Quantization Table. This comes from a */
276 /* SP0250 data sheet, and should be correct for SP0256. */
277 /* ======================================================================== */
278 LOCAL const int16_t qtbl[128] =
279 {
280 0, 9, 17, 25, 33, 41, 49, 57,
281 65, 73, 81, 89, 97, 105, 113, 121,
282 129, 137, 145, 153, 161, 169, 177, 185,
283 193, 201, 209, 217, 225, 233, 241, 249,
284 257, 265, 273, 281, 289, 297, 301, 305,
285 309, 313, 317, 321, 325, 329, 333, 337,
286 341, 345, 349, 353, 357, 361, 365, 369,
287 373, 377, 381, 385, 389, 393, 397, 401,
288 405, 409, 413, 417, 421, 425, 427, 429,
289 431, 433, 435, 437, 439, 441, 443, 445,
290 447, 449, 451, 453, 455, 457, 459, 461,
291 463, 465, 467, 469, 471, 473, 475, 477,
292 479, 481, 482, 483, 484, 485, 486, 487,
293 488, 489, 490, 491, 492, 493, 494, 495,
294 496, 497, 498, 499, 500, 501, 502, 503,
295 504, 505, 506, 507, 508, 509, 510, 511
296 };
297
298 /* ======================================================================== */
299 /* LIMIT -- Limiter function for digital sample output. */
300 /* ======================================================================== */
limit(int16_t s)301 LOCAL INLINE int16_t limit(int16_t s)
302 {
303 #ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */
304 if (s > 8191) return 8191;
305 if (s < -8192) return -8192;
306 #else
307 if (s > 127) return 127;
308 if (s < -128) return -128;
309 #endif
310 return s;
311 }
312
313 #if 0
314 /* ======================================================================== */
315 /* SAMP_MPY -- Multiply sample w/ coef */
316 /* ======================================================================== */
317 LOCAL int samp_mpy(int coef, int samp)
318 {
319 return coef * samp;
320 }
321 #endif
322
323 /* ======================================================================== */
324 /* AMP_DECODE -- Decode amplitude register */
325 /* ======================================================================== */
amp_decode(uint8_t a)326 LOCAL int amp_decode(uint8_t a)
327 {
328 /* -------------------------------------------------------------------- */
329 /* Amplitude has 3 bits of exponent and 5 bits of mantissa. This */
330 /* contradicts USP 4,296,269 but matches the SP0250 Apps Manual. */
331 /* -------------------------------------------------------------------- */
332 int expn = (a & 0xE0) >> 5;
333 int mant = (a & 0x1F);
334 int ampl = mant << expn;
335
336 /* -------------------------------------------------------------------- */
337 /* Careful reading of USP 4,296,279, around line 60 in column 14 on */
338 /* page 16 of the scan suggests the LSB might be held and injected */
339 /* into the output while the exponent gets counted down, although */
340 /* this seems dubious. */
341 /* -------------------------------------------------------------------- */
342 #if 0
343 if (mant & 1)
344 ampl |= (1u << expn) - 1;
345 #endif
346
347 return ampl;
348 }
349
350 /* ======================================================================== */
351 /* LPC12_UPDATE -- Update the 12-pole filter, outputting samples. */
352 /* ======================================================================== */
lpc12_update(lpc12_t * f,int num_samp,int16_t * out,uint32_t * optr)353 LOCAL int lpc12_update(lpc12_t *f, int num_samp, int16_t *out, uint32_t *optr)
354 {
355 int i, j;
356 int16_t samp;
357 int do_int, bit;
358 int oidx = *optr;
359
360 /* -------------------------------------------------------------------- */
361 /* Iterate up to the desired number of samples. We actually may */
362 /* break out early if our repeat count expires. */
363 /* -------------------------------------------------------------------- */
364 for (i = 0; i < num_samp; i++)
365 {
366 /* ---------------------------------------------------------------- */
367 /* Generate a series of periodic impulses, or random noise. */
368 /* ---------------------------------------------------------------- */
369 do_int = 0;
370 samp = 0;
371 bit = f->rng & 1;
372 f->rng = (f->rng >> 1) ^ (bit ? 0x4001 : 0);
373
374 if (--f->cnt <= 0)
375 {
376 if (f->rpt-- <= 0) /* Stop if we expire the repeat counter */
377 {
378 f->cnt = f->rpt = 0;
379 break;
380 }
381
382 f->cnt = f->per ? f->per : PER_NOISE;
383 samp = f->amp;
384 do_int = f->interp;
385 }
386
387 if (!f->per)
388 samp = bit ? -f->amp : f->amp;
389
390 /* ---------------------------------------------------------------- */
391 /* If we need to, process the interpolation registers. */
392 /* ---------------------------------------------------------------- */
393 if (do_int)
394 {
395 f->r[0] += f->r[14];
396 f->r[1] += f->r[15];
397
398 f->amp = amp_decode(f->r[0]);
399 f->per = f->r[1];
400
401 do_int = 0;
402 }
403
404 /* ---------------------------------------------------------------- */
405 /* Each 2nd order stage looks like one of these. The App. Manual */
406 /* gives the first form, the patent gives the second form. */
407 /* They're equivalent except for time delay. I implement the */
408 /* first form. (Note: 1/Z == 1 unit of time delay.) */
409 /* */
410 /* ---->(+)-------->(+)----------+-------> */
411 /* ^ ^ | */
412 /* | | | */
413 /* | | | */
414 /* [B] [2*F] | */
415 /* ^ ^ | */
416 /* | | | */
417 /* | | | */
418 /* +---[1/Z]<--+---[1/Z]<--+ */
419 /* */
420 /* */
421 /* +---[2*F]<---+ */
422 /* | | */
423 /* | | */
424 /* v | */
425 /* ---->(+)-->[1/Z]-->+-->[1/Z]---+------> */
426 /* ^ | */
427 /* | | */
428 /* | | */
429 /* +-----------[B]<---------+ */
430 /* */
431 /* ---------------------------------------------------------------- */
432 for (j = 0; j < 6; j++)
433 {
434 #if 1
435 samp += (((int)f->b_coef[j] * (int)f->z_data[j][1]) >> 9);
436 samp += (((int)f->f_coef[j] * (int)f->z_data[j][0]) >> 8);
437 #else
438 int temp;
439 /*temp = ((int)f->f_coef[j] * (int)f->z_data[j][0]) << 1;*/
440 /*temp += ((int)f->b_coef[j] * (int)f->z_data[j][1]);*/
441 static int fdly = 0;
442
443 if (f->f_coef[j] >= 0)
444 temp = 2 * f->f_coef[j] * f->z_data[j][0] + fdly;
445 else
446 temp = -(-2 * f->f_coef[j] * f->z_data[j][0] + fdly);
447
448 fdly = 1 & (temp >> 26);
449 temp += samp_mpy(f->b_coef[j], f->z_data[j][1]);
450 samp += temp >> 9;
451 #endif
452
453 f->z_data[j][1] = f->z_data[j][0];
454 f->z_data[j][0] = samp;
455 }
456
457 #ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */
458 out[oidx++ & SCBUF_MASK] = limit(samp) * 4;
459 #else
460 out[oidx++ & SCBUF_MASK] = limit(samp >> 4) * 256;
461 #endif
462 }
463
464 *optr = oidx;
465
466 return i;
467 }
468
469 /*LOCAL int stage_map[6] = { 4, 2, 0, 5, 3, 1 };*/
470 /*LOCAL int stage_map[6] = { 3, 0, 4, 1, 5, 2 };*/
471 /*LOCAL int stage_map[6] = { 3, 0, 1, 4, 2, 5 };*/
472 LOCAL const int stage_map[6] = { 0, 1, 2, 3, 4, 5 };
473
474 /* ======================================================================== */
475 /* LPC12_REGDEC -- Decode the register set in the filter bank. */
476 /* ======================================================================== */
lpc12_regdec(lpc12_t * f)477 LOCAL void lpc12_regdec(lpc12_t *f)
478 {
479 int i;
480
481 /* -------------------------------------------------------------------- */
482 /* Decode the Amplitude and Period registers. Force cnt to 0 to get */
483 /* the initial impulse. (Redundant?) */
484 /* -------------------------------------------------------------------- */
485 f->amp = amp_decode(f->r[0]);
486 f->cnt = 0;
487 f->per = f->r[1];
488
489 /* -------------------------------------------------------------------- */
490 /* Decode the filter coefficients from the quant table. */
491 /* -------------------------------------------------------------------- */
492 for (i = 0; i < 6; i++)
493 {
494 #define IQ(x) (((x) & 0x80) ? qtbl[0x7F & -(x)] : -qtbl[(x)])
495
496 f->b_coef[stage_map[i]] = IQ(f->r[2 + 2*i]);
497 f->f_coef[stage_map[i]] = IQ(f->r[3 + 2*i]);
498 }
499
500 /* -------------------------------------------------------------------- */
501 /* Set the Interp flag based on whether we have interpolation parms */
502 /* -------------------------------------------------------------------- */
503 f->interp = f->r[14] || f->r[15];
504
505 return;
506 }
507
508 /* ======================================================================== */
509 /* MASK table */
510 /* ======================================================================== */
511 LOCAL const uint8_t mask[4097] =
512 {
513 0xE8, 0xBB, 0xE8, 0x87, 0xE8, 0x17, 0xE8, 0x37, 0xE8, 0xF7, 0xE8, 0x8F,
514 0xE8, 0xCF, 0xE2, 0xD8, 0xE2, 0x9A, 0xE2, 0x89, 0xE2, 0xDD, 0xE2, 0x37,
515 0xE2, 0x2F, 0xEA, 0x04, 0xEA, 0x54, 0xEA, 0x4C, 0xEA, 0xD2, 0xEA, 0x8A,
516 0xEA, 0x8E, 0xEA, 0xB1, 0xEA, 0xFD, 0xEA, 0x53, 0xEA, 0xAB, 0xEA, 0x47,
517 0xEA, 0xCF, 0xEA, 0xFF, 0xE6, 0x10, 0xE6, 0x48, 0xE6, 0x3C, 0xE6, 0x62,
518 0xE6, 0x8A, 0xE6, 0xBA, 0xE6, 0x76, 0xE6, 0x5E, 0xE6, 0xC1, 0xE6, 0xB1,
519 0xE6, 0xCB, 0xEE, 0xC8, 0xEE, 0x98, 0xEE, 0xF8, 0xEE, 0xC2, 0xEE, 0x1E,
520 0xEE, 0x7E, 0xEE, 0x2D, 0xEE, 0x6D, 0xEE, 0x1D, 0xEE, 0x5D, 0xEE, 0x3D,
521 0x18, 0x2B, 0x15, 0xC0, 0x39, 0x24, 0x43, 0xE2, 0x1F, 0x00, 0x18, 0x23,
522 0x24, 0xC0, 0x28, 0x23, 0x62, 0xC6, 0x1D, 0xA5, 0x03, 0x20, 0x66, 0x52,
523 0x0C, 0x95, 0x03, 0x00, 0x19, 0x2C, 0x0C, 0x80, 0x31, 0x12, 0x62, 0xA7,
524 0x1C, 0x00, 0x18, 0x2C, 0x0C, 0xC0, 0x29, 0x94, 0xE0, 0x64, 0x9C, 0x85,
525 0x02, 0x38, 0x85, 0x12, 0x9C, 0x8C, 0x03, 0x00, 0x10, 0x35, 0xE7, 0x55,
526 0xAD, 0x6D, 0x7F, 0x26, 0x91, 0x85, 0xD4, 0x3C, 0xAB, 0xD6, 0xCF, 0x99,
527 0x7A, 0x00, 0x10, 0x34, 0x6F, 0xA1, 0x86, 0xCF, 0x3E, 0xAB, 0x0D, 0xBB,
528 0x86, 0x7C, 0x6C, 0xB5, 0x6D, 0xCF, 0x24, 0xB2, 0x88, 0x9E, 0xA7, 0x16,
529 0xF3, 0xA9, 0xD2, 0xE6, 0x3D, 0xD5, 0x55, 0xFD, 0x01, 0x00, 0x10, 0x32,
530 0x74, 0x98, 0xA9, 0xB7, 0x81, 0x1E, 0xA9, 0x87, 0xF4, 0x66, 0xA3, 0xFC,
531 0x8B, 0xD2, 0x96, 0x94, 0xFB, 0xFF, 0x10, 0x03, 0x80, 0x8E, 0x16, 0x0D,
532 0x00, 0x10, 0x32, 0x7C, 0x90, 0xAB, 0xB7, 0x81, 0x1E, 0xA9, 0xA7, 0x6E,
533 0xF7, 0x22, 0xDD, 0xC7, 0xAA, 0xFE, 0xA5, 0x9C, 0xDE, 0xCC, 0x7E, 0xF4,
534 0x2E, 0xAC, 0xFA, 0xC7, 0xD9, 0x91, 0xA5, 0xA5, 0xE4, 0xDC, 0x5F, 0xF4,
535 0x2B, 0x9D, 0xFC, 0x03, 0x00, 0x10, 0x31, 0x8F, 0xDC, 0xFF, 0x8C, 0x7C,
536 0x97, 0xF6, 0x41, 0xE6, 0xE3, 0xF4, 0xF4, 0xF6, 0x47, 0x23, 0xC2, 0x84,
537 0xB6, 0x85, 0x74, 0xFF, 0xD0, 0xDD, 0xCF, 0xEE, 0x3F, 0xB7, 0xEB, 0x01,
538 0x00, 0x74, 0x7B, 0xA3, 0xDC, 0x2D, 0x3A, 0x5A, 0xB7, 0x56, 0xEE, 0x45,
539 0xDF, 0x5B, 0xDA, 0xBF, 0x68, 0xE9, 0x3B, 0xFD, 0x1F, 0xF5, 0x78, 0x27,
540 0xFF, 0xA2, 0x4E, 0xF2, 0xDC, 0x1F, 0x00, 0x10, 0x36, 0x76, 0x9B, 0xA9,
541 0xB7, 0xBD, 0x1A, 0x1F, 0x66, 0xD4, 0x85, 0xA3, 0xBB, 0xCB, 0x95, 0x83,
542 0x00, 0x10, 0x32, 0x6E, 0xDA, 0x27, 0xBB, 0x7D, 0x22, 0x1F, 0xC6, 0x94,
543 0x16, 0x9C, 0xDE, 0x97, 0xD6, 0xA5, 0xD3, 0x7F, 0x52, 0x72, 0x58, 0xF2,
544 0x4F, 0xD7, 0x85, 0x03, 0x00, 0x10, 0x32, 0x35, 0x96, 0xA9, 0xB9, 0xBD,
545 0x1A, 0x1F, 0x86, 0xCE, 0x6E, 0x13, 0x3D, 0x09, 0xE9, 0xF6, 0x00, 0x10,
546 0x32, 0x7B, 0x94, 0xAB, 0xB7, 0x81, 0x1E, 0xA9, 0x87, 0x6E, 0xAF, 0x1B,
547 0xDD, 0xF9, 0xAA, 0xFE, 0xA4, 0x57, 0xE6, 0xCC, 0x5E, 0xF4, 0x36, 0xAD,
548 0xFA, 0xC7, 0xD5, 0xB5, 0xA4, 0xA5, 0xED, 0xDC, 0x5F, 0xF4, 0x73, 0x9E,
549 0xFC, 0x03, 0x00, 0x10, 0x32, 0xF7, 0x9F, 0xA9, 0xBD, 0x3F, 0x22, 0x11,
550 0x86, 0x6E, 0xCF, 0xA3, 0xDB, 0xFB, 0x46, 0xEB, 0xC8, 0xE9, 0x3F, 0x00,
551 0x10, 0x32, 0xAC, 0x98, 0x27, 0xBD, 0x81, 0x22, 0x1F, 0x87, 0xAE, 0x7E,
552 0x1C, 0x6D, 0x81, 0xE7, 0xFF, 0x72, 0xE4, 0x20, 0x00, 0xF1, 0xE1, 0x00,
553 0x00, 0x11, 0xFC, 0x13, 0xFF, 0x13, 0xFF, 0x00, 0xFE, 0x13, 0xFF, 0x00,
554 0x11, 0xFF, 0x00, 0xFF, 0x00, 0xF7, 0x00, 0x18, 0x32, 0xDD, 0xA0, 0x7D,
555 0x81, 0x0F, 0xC7, 0x03, 0xE3, 0xEA, 0x53, 0xC6, 0x75, 0xAB, 0xF0, 0x41,
556 0xE8, 0x9E, 0x17, 0x73, 0xA1, 0xD2, 0xDC, 0x62, 0xF6, 0x14, 0x34, 0x4D,
557 0x0F, 0x8C, 0xB7, 0x54, 0x99, 0x5A, 0xCB, 0x5F, 0x80, 0x84, 0x6D, 0x88,
558 0xF3, 0x65, 0x2A, 0x73, 0xBD, 0xF5, 0x77, 0x50, 0xAD, 0x5D, 0xEF, 0xA1,
559 0x5A, 0xF5, 0x45, 0x3C, 0x80, 0x53, 0x14, 0x83, 0xC8, 0xBC, 0xC9, 0x05,
560 0x60, 0x09, 0x03, 0x68, 0xB0, 0xAF, 0xA9, 0x81, 0x00, 0x38, 0x78, 0xD8,
561 0x8F, 0xD9, 0x61, 0xA2, 0x35, 0x77, 0x90, 0x7F, 0x07, 0xD3, 0xDA, 0x80,
562 0xFF, 0xEC, 0xB4, 0x66, 0xDF, 0x31, 0xD8, 0xD8, 0x89, 0xBF, 0x65, 0x9B,
563 0x9D, 0x5E, 0x82, 0x3E, 0x12, 0x24, 0x21, 0x6F, 0xFC, 0x24, 0x83, 0x03,
564 0x00, 0xF2, 0xF3, 0x1F, 0x5C, 0x3E, 0x48, 0x90, 0x60, 0x0D, 0xEE, 0x03,
565 0xA5, 0x8B, 0x00, 0x00, 0x1A, 0xFD, 0x38, 0x50, 0xA6, 0x00, 0xF0, 0x03,
566 0x21, 0x6E, 0xC7, 0x8D, 0xD9, 0xF3, 0xA0, 0x30, 0xD2, 0x6F, 0x22, 0xF1,
567 0x1A, 0x95, 0x71, 0x89, 0x0C, 0x44, 0x8A, 0xC6, 0xA7, 0xD1, 0x6B, 0xA2,
568 0x33, 0xAF, 0x9A, 0x41, 0xD1, 0xCE, 0xFC, 0x2E, 0x3B, 0x4D, 0x74, 0xC6,
569 0x24, 0x13, 0x18, 0x91, 0x61, 0x9E, 0x94, 0xD7, 0x75, 0xCE, 0xD4, 0x53,
570 0x0A, 0x24, 0x2A, 0xDB, 0x8F, 0xF2, 0x34, 0xD0, 0x19, 0x5B, 0x6A, 0x80,
571 0x64, 0x47, 0x79, 0xD7, 0x2D, 0xF7, 0x39, 0x53, 0x4B, 0x09, 0x90, 0xC8,
572 0x68, 0x1F, 0xAB, 0xBD, 0x46, 0x69, 0xDA, 0x26, 0x85, 0x08, 0xA2, 0xFE,
573 0x71, 0xF1, 0x55, 0xA9, 0xA4, 0x74, 0xE0, 0x87, 0x0F, 0x1E, 0x65, 0xCC,
574 0xDC, 0x48, 0x06, 0x2C, 0x2A, 0xF3, 0xDB, 0xE6, 0xB8, 0x52, 0x9A, 0x7D,
575 0xA8, 0xA0, 0x46, 0x85, 0x7E, 0x97, 0x0D, 0x47, 0x3A, 0x63, 0xFB, 0xD4,
576 0x2B, 0xB0, 0x28, 0xBE, 0x50, 0xC2, 0x44, 0x67, 0xDE, 0xA1, 0x88, 0x16,
577 0x19, 0xE6, 0x53, 0x39, 0x96, 0x28, 0x3F, 0x86, 0x49, 0x05, 0x80, 0xC7,
578 0x06, 0x10, 0x49, 0x27, 0x71, 0x00, 0x10, 0xC9, 0xF8, 0x46, 0xDB, 0x33,
579 0x5F, 0x51, 0xFB, 0x00, 0x0B, 0xCE, 0x76, 0x9F, 0x68, 0x36, 0xA6, 0x0D,
580 0xB2, 0x67, 0xA8, 0x59, 0x19, 0xA6, 0x0A, 0xD8, 0x57, 0x2A, 0x30, 0x84,
581 0x24, 0xE0, 0x22, 0x32, 0x8D, 0x6B, 0xB4, 0xCF, 0x60, 0xB3, 0xF4, 0xDF,
582 0xDF, 0x82, 0xC5, 0xA0, 0x69, 0x91, 0x0C, 0x7A, 0x76, 0xAC, 0x1F, 0xC9,
583 0x42, 0xAD, 0x32, 0xAF, 0x98, 0x41, 0x8B, 0x8A, 0xF5, 0x37, 0x59, 0x8A,
584 0x75, 0xC6, 0xDE, 0x63, 0xC8, 0xD8, 0xC9, 0x1E, 0x57, 0xC3, 0x91, 0xCE,
585 0xB8, 0x88, 0xEE, 0x15, 0x22, 0x8B, 0x13, 0x0E, 0xB3, 0xD0, 0x7D, 0x68,
586 0x03, 0xF3, 0xFB, 0x18, 0x23, 0x1C, 0x00, 0x29, 0x18, 0x80, 0x2A, 0xB9,
587 0xA6, 0x2E, 0x22, 0x20, 0xD9, 0xC1, 0x1D, 0x36, 0x63, 0x99, 0xCE, 0xD4,
588 0x46, 0x04, 0x22, 0x33, 0xBA, 0xC7, 0x6A, 0xB6, 0xCE, 0xC9, 0xEF, 0xD7,
589 0x0B, 0x24, 0x58, 0x44, 0xA7, 0xA1, 0x9D, 0xFA, 0x4D, 0x44, 0x12, 0x47,
590 0x20, 0x5D, 0x9C, 0x32, 0x2F, 0x54, 0xC9, 0x0A, 0x13, 0xFA, 0x27, 0x3C,
591 0xE9, 0x34, 0xE4, 0x02, 0xB0, 0x26, 0x52, 0x40, 0x98, 0x93, 0x58, 0x00,
592 0xC5, 0x64, 0x8E, 0x86, 0x7B, 0x91, 0x07, 0x00, 0x93, 0x38, 0xD0, 0xF1,
593 0x1F, 0xE2, 0x01, 0x58, 0xF3, 0x39, 0x70, 0x9E, 0x6B, 0xEC, 0x9E, 0x80,
594 0x92, 0x1D, 0xFE, 0x6D, 0xF5, 0x9C, 0x67, 0x65, 0x09, 0xE0, 0x00, 0x00,
595 0x00, 0xF1, 0xD0, 0xDC, 0x3C, 0x06, 0x1C, 0x4C, 0x6E, 0x07, 0xFC, 0xB1,
596 0x54, 0x9A, 0xDA, 0xA7, 0x60, 0x41, 0xA4, 0xEB, 0x7D, 0xA1, 0x95, 0x2A,
597 0xC3, 0x16, 0x11, 0x14, 0xD0, 0x6C, 0x0D, 0x1F, 0xA6, 0x50, 0x6B, 0x38,
598 0x27, 0x82, 0x82, 0x99, 0x9D, 0xFF, 0xC7, 0x1C, 0xA3, 0x4C, 0x97, 0x34,
599 0x50, 0x53, 0x95, 0x00, 0xAA, 0xE6, 0x91, 0x2D, 0x19, 0x00, 0x10, 0xF2,
600 0x04, 0x2F, 0xDB, 0xD0, 0x06, 0xF1, 0x00, 0x10, 0x33, 0x66, 0xA6, 0x67,
601 0x79, 0x85, 0x22, 0xA9, 0x87, 0xE6, 0x55, 0xB5, 0x6E, 0x00, 0x50, 0x24,
602 0xF5, 0xCC, 0xBC, 0x67, 0x9E, 0xED, 0x0D, 0x8A, 0xA4, 0x9E, 0x51, 0x9B,
603 0x6B, 0xF6, 0x5F, 0xBA, 0x97, 0xD1, 0xEE, 0x45, 0xCF, 0xBF, 0xB9, 0x3B,
604 0x04, 0x8D, 0x39, 0xF9, 0xF9, 0x7C, 0xAE, 0x48, 0xEA, 0x11, 0x7D, 0x7B,
605 0x69, 0xEE, 0xA5, 0xA6, 0x31, 0xBD, 0x3F, 0x1E, 0x00, 0x10, 0x33, 0x56,
606 0x22, 0x47, 0x4D, 0x81, 0xAE, 0x92, 0x58, 0xC6, 0x85, 0x53, 0x68, 0xD1,
607 0x6F, 0x95, 0xEE, 0xD7, 0xD8, 0x67, 0x1C, 0x35, 0xF4, 0xCE, 0x12, 0xF2,
608 0x9A, 0xFB, 0x8D, 0xD8, 0x98, 0x20, 0x11, 0x86, 0x22, 0x7A, 0x3F, 0x5E,
609 0xFD, 0x47, 0x5B, 0x57, 0xBB, 0xFF, 0x28, 0x4B, 0x6B, 0xF9, 0x1F, 0x2D,
610 0x8F, 0xED, 0xFE, 0xF1, 0x00, 0xD0, 0x56, 0x10, 0x33, 0xEE, 0xD4, 0xE5,
611 0xF9, 0xBF, 0x23, 0x2D, 0x67, 0xB4, 0xD5, 0x92, 0xDB, 0x97, 0xB6, 0x68,
612 0x52, 0xFB, 0xD1, 0xF2, 0x4F, 0x62, 0x4F, 0xFA, 0x71, 0xCA, 0xEB, 0x47,
613 0x39, 0x5F, 0x69, 0xFD, 0xE8, 0x83, 0x2D, 0xAB, 0x8F, 0x07, 0x00, 0xD0,
614 0x3E, 0x18, 0x33, 0xED, 0x5E, 0xF9, 0x82, 0x8A, 0xD2, 0x03, 0x03, 0xEB,
615 0x14, 0xC2, 0xA6, 0x5D, 0x33, 0xB5, 0x26, 0xD7, 0xE2, 0xC2, 0x90, 0xD6,
616 0x86, 0xB4, 0xFB, 0xD1, 0x96, 0x76, 0xFA, 0x4F, 0x67, 0x3A, 0x63, 0xC8,
617 0x90, 0xDA, 0xF6, 0x1E, 0x35, 0xB2, 0x07, 0x90, 0xAF, 0xCC, 0x78, 0x00,
618 0xD0, 0x61, 0xD0, 0x19, 0xD0, 0x55, 0xF1, 0x00, 0xD0, 0x61, 0x10, 0x37,
619 0x76, 0x99, 0xAD, 0xB3, 0x7F, 0x1E, 0xA2, 0xA7, 0x74, 0x8F, 0xB3, 0x1A,
620 0xCC, 0xED, 0x8D, 0xA4, 0x37, 0xA8, 0xDD, 0x9F, 0xEE, 0x9E, 0x1D, 0x75,
621 0x71, 0x29, 0xF7, 0xA2, 0x66, 0x30, 0xDD, 0x7E, 0xE5, 0x00, 0x98, 0x23,
622 0xC2, 0xC7, 0x03, 0x00, 0xD0, 0x06, 0xD0, 0x06, 0xD0, 0x53, 0xD0, 0x06,
623 0xF1, 0x00, 0xD0, 0x06, 0xD0, 0x06, 0xD0, 0xA7, 0xF1, 0x00, 0x10, 0x32,
624 0xF6, 0x9F, 0xA9, 0xBD, 0x3F, 0x22, 0x11, 0x86, 0x6E, 0xCF, 0xA3, 0xBB,
625 0xFB, 0x46, 0xEB, 0xC8, 0xE9, 0xFF, 0x3D, 0xB4, 0x15, 0xF1, 0x00, 0xD8,
626 0xB0, 0xD8, 0xB4, 0xF1, 0x00, 0xD0, 0x56, 0x10, 0x34, 0x76, 0x9B, 0xAB,
627 0xB9, 0xBD, 0x15, 0x1F, 0x87, 0xEE, 0xC6, 0x1B, 0xB5, 0x3B, 0xEB, 0xFE,
628 0xA3, 0xA5, 0xED, 0xDC, 0x9F, 0x8E, 0xBC, 0x9D, 0xEB, 0x96, 0xE3, 0x01,
629 0x00, 0x10, 0x32, 0x6D, 0xA0, 0xA7, 0xBF, 0x81, 0x15, 0x1F, 0xCA, 0xB4,
630 0xB6, 0x9B, 0x1E, 0x88, 0x96, 0x7D, 0x53, 0xFF, 0xD3, 0x77, 0x8E, 0x6A,
631 0x00, 0x7D, 0x0A, 0xF1, 0x00, 0xD0, 0x56, 0x10, 0x32, 0x9C, 0xA0, 0xA9,
632 0x2D, 0xBF, 0x22, 0x1F, 0x68, 0xF4, 0xF4, 0xA3, 0xF8, 0x93, 0xDE, 0x80,
633 0x55, 0x7F, 0xD3, 0xDA, 0xAF, 0xE6, 0x4F, 0x4A, 0x03, 0x56, 0x1C, 0x4A,
634 0xCD, 0x3C, 0x7A, 0x43, 0x9C, 0x99, 0x77, 0x4A, 0xF9, 0xCD, 0x0B, 0x4A,
635 0x06, 0x00, 0x53, 0x26, 0x78, 0x3C, 0x00, 0xD0, 0x3E, 0xD8, 0xD2, 0xFE,
636 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0, 0x61, 0xD0, 0x55, 0xF3, 0xD0,
637 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0, 0x61, 0xD8, 0x9E, 0xD0, 0x61, 0xF5,
638 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0, 0x06, 0xD0, 0x06, 0xD0, 0x53,
639 0xD0, 0x06, 0xD0, 0x06, 0xF4, 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0,
640 0x06, 0xD0, 0x06, 0xD8, 0xD1, 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD8,
641 0xCD, 0xFE, 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD8, 0xB0, 0xD8, 0xB4,
642 0xD0, 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0, 0x56, 0x10, 0x32, 0x6D, 0x93,
643 0xAB, 0xB1, 0xBF, 0x1A, 0x1F, 0x46, 0xEE, 0xED, 0x1A, 0xAD, 0xC7, 0x6A,
644 0xF6, 0xA2, 0x35, 0x5B, 0xDD, 0x9F, 0xF4, 0xA4, 0x9B, 0xFC, 0xDB, 0x8B,
645 0x3C, 0x00, 0x87, 0x60, 0xF6, 0x7A, 0x68, 0x2B, 0xD8, 0x13, 0xF1, 0x00,
646 0xD0, 0x3E, 0xD8, 0xD2, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0xD0, 0x61,
647 0xD0, 0x55, 0xF3, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0xD0, 0x61, 0xD8,
648 0x9E, 0xD0, 0x61, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0xD0, 0x06, 0xD0,
649 0x06, 0xD0, 0x53, 0xD0, 0x06, 0xD0, 0x06, 0xF4, 0xD0, 0x56, 0xD8, 0x13,
650 0xF1, 0x00, 0xD0, 0x06, 0xD0, 0x06, 0xD8, 0xD1, 0xD0, 0x56, 0xD8, 0x13,
651 0xF1, 0x00, 0xD8, 0xCD, 0xF7, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0xD8,
652 0xB0, 0xD8, 0xB4, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0x10, 0x25, 0x02,
653 0xC0, 0x10, 0x97, 0xBC, 0xA4, 0x01, 0xA8, 0x02, 0x93, 0xCF, 0xD8, 0x7D,
654 0xB6, 0xD6, 0xFE, 0x6A, 0x7C, 0x1C, 0xD2, 0x1D, 0xD0, 0xEE, 0x3F, 0x5A,
655 0xFE, 0x4D, 0xFD, 0x47, 0x4B, 0xC6, 0xB9, 0xFF, 0x88, 0x03, 0x20, 0x43,
656 0x27, 0x97, 0xE9, 0x40, 0x3D, 0xBD, 0xED, 0xD5, 0xF8, 0x38, 0xA3, 0x2E,
657 0x24, 0xDD, 0x5D, 0xF4, 0xCD, 0xA4, 0xDB, 0x8F, 0xBA, 0x95, 0x74, 0xFF,
658 0xD1, 0x8E, 0x72, 0xEE, 0x1F, 0x0F, 0x00, 0xD0, 0x3E, 0x10, 0x35, 0x37,
659 0x9A, 0xAB, 0xB5, 0xBF, 0x1A, 0x1F, 0xC7, 0x74, 0x4F, 0xB3, 0xFA, 0x97,
660 0xBE, 0x7E, 0x15, 0x03, 0x52, 0x33, 0x93, 0x66, 0x60, 0x52, 0x00, 0xAC,
661 0xF1, 0x06, 0x4E, 0x1A, 0x80, 0x3B, 0x06, 0xC5, 0x0C, 0xF7, 0xEA, 0x69,
662 0xED, 0xAF, 0xC6, 0xC7, 0x21, 0xED, 0x90, 0xE7, 0x06, 0xA2, 0x15, 0xF6,
663 0xD4, 0x7F, 0x3E, 0xA4, 0x00, 0x48, 0xE3, 0x91, 0xC7, 0x03, 0x00, 0xD0,
664 0x56, 0xD8, 0xBA, 0xF1, 0x00, 0xD0, 0x56, 0xD8, 0x13, 0xF1, 0x00, 0x10,
665 0x28, 0x1D, 0xC0, 0x18, 0x1D, 0x7C, 0x86, 0xDC, 0x33, 0xB5, 0x2E, 0x4F,
666 0xE3, 0xD2, 0x8C, 0xD6, 0x7F, 0x75, 0xF7, 0x51, 0x1B, 0xB1, 0x6E, 0x3F,
667 0x7A, 0xFB, 0xD5, 0xFD, 0xA1, 0x0D, 0x00, 0xD0, 0x06, 0xF1, 0x00, 0x10,
668 0x34, 0x76, 0x9C, 0xA9, 0xBB, 0x7F, 0x1D, 0x22, 0x68, 0x74, 0x7F, 0xAB,
669 0xFC, 0x8F, 0xB2, 0x77, 0x73, 0xFF, 0x99, 0xCB, 0x30, 0x62, 0xC7, 0x5F,
670 0x53, 0x82, 0x9E, 0x4F, 0xE2, 0x01, 0x58, 0xF2, 0xF1, 0x67, 0x4C, 0x44,
671 0x53, 0x6F, 0xFB, 0x3A, 0x44, 0x90, 0xA8, 0xE9, 0x4B, 0x77, 0x97, 0x2B,
672 0xD1, 0xE3, 0x01, 0x00, 0xD0, 0x19, 0xD0, 0x55, 0xF1, 0x00, 0x10, 0x32,
673 0xB4, 0xA9, 0xA9, 0xBB, 0x7F, 0x1D, 0x22, 0x48, 0xEE, 0x96, 0x0D, 0xDD,
674 0x8F, 0x6B, 0xFF, 0x72, 0xBB, 0x73, 0xE8, 0x1E, 0x6D, 0xF9, 0x17, 0x7D,
675 0x69, 0xEB, 0xFE, 0xA1, 0x2C, 0xE3, 0xDC, 0x60, 0xF4, 0xB4, 0x9B, 0x1A,
676 0xC4, 0x9D, 0x69, 0x73, 0x56, 0x9B, 0xA8, 0x4B, 0x45, 0x37, 0x88, 0x63,
677 0xAB, 0xE2, 0x01, 0x00, 0xF1, 0x00, 0xF1, 0x00, 0xF1, 0x00, 0xF1, 0x00,
678 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
684 };
685
686 /* ======================================================================== */
687 /* SP0256_DATAFMT -- Data format table for the SP0256's microsequencer */
688 /* */
689 /* len 4 bits Length of field to extract */
690 /* lshift 4 bits Left-shift amount on field */
691 /* param 4 bits Parameter number being updated */
692 /* delta 1 bit This is a delta-update. (Implies sign-extend) */
693 /* field 1 bit This is a field replace. */
694 /* clr5 1 bit Clear F5, B5. */
695 /* clrall 1 bit Clear all before doing this update */
696 /* ======================================================================== */
697
698 #define CR(l,s,p,d,f,c5,ca) \
699 ( \
700 (((l) & 15) << 0) | \
701 (((s) & 15) << 4) | \
702 (((p) & 15) << 8) | \
703 (((d) & 1) << 12) | \
704 (((f) & 1) << 13) | \
705 (((c5) & 1) << 14) | \
706 (((ca) & 1) << 15) \
707 )
708
709 #define CR_DELTA CR(0,0,0,1,0,0,0)
710 #define CR_FIELD CR(0,0,0,0,1,0,0)
711 #define CR_CLR5 CR(0,0,0,0,0,1,0)
712 #define CR_CLRL CR(0,0,0,0,0,0,1)
713 #define CR_LEN(x) ((x) & 15)
714 #define CR_SHF(x) (((x) >> 4) & 15)
715 #define CR_PRM(x) (((x) >> 8) & 15)
716
717 enum { AM = 0, PR, B0, F0, B1, F1, B2, F2, B3, F3, B4, F4, B5, F5, IA, IP };
718
719 LOCAL const uint16_t sp0256_datafmt[] =
720 {
721 /* -------------------------------------------------------------------- */
722 /* OPCODE 1111: PAUSE */
723 /* -------------------------------------------------------------------- */
724 /* 0 */ CR( 0, 0, 0, 0, 0, 0, 0), /* Clear all */
725
726 /* -------------------------------------------------------------------- */
727 /* Opcode 0001: LOADALL */
728 /* -------------------------------------------------------------------- */
729 /* Mode modes x1 */
730 /* 1 */ CR( 8, 0, AM, 0, 0, 0, 0), /* Amplitude */
731 /* 2 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
732 /* 3 */ CR( 8, 0, B0, 0, 0, 0, 0), /* B0 */
733 /* 4 */ CR( 8, 0, F0, 0, 0, 0, 0), /* F0 */
734 /* 5 */ CR( 8, 0, B1, 0, 0, 0, 0), /* B1 */
735 /* 6 */ CR( 8, 0, F1, 0, 0, 0, 0), /* F1 */
736 /* 7 */ CR( 8, 0, B2, 0, 0, 0, 0), /* B2 */
737 /* 8 */ CR( 8, 0, F2, 0, 0, 0, 0), /* F2 */
738 /* 9 */ CR( 8, 0, B3, 0, 0, 0, 0), /* B3 */
739 /* 10 */ CR( 8, 0, F3, 0, 0, 0, 0), /* F3 */
740 /* 11 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */
741 /* 12 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */
742 /* 13 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */
743 /* 14 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */
744 /* 15 */ CR( 8, 0, IA, 0, 0, 0, 0), /* Amp Interp */
745 /* 16 */ CR( 8, 0, IP, 0, 0, 0, 0), /* Pit Interp */
746
747 /* -------------------------------------------------------------------- */
748 /* Opcode 0100: LOAD_4 */
749 /* -------------------------------------------------------------------- */
750 /* Mode 00 and 01 */
751 /* 17 */ CR( 6, 2, AM, 0, 0, 0, 1), /* Amplitude */
752 /* 18 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
753 /* 19 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */
754 /* 20 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */
755 /* 21 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */
756 /* 22 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */
757 /* Mode 01 only */
758 /* 23 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */
759 /* 24 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */
760
761 /* Mode 10 and 11 */
762 /* 25 */ CR( 6, 2, AM, 0, 0, 0, 1), /* Amplitude */
763 /* 26 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
764 /* 27 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */
765 /* 28 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */
766 /* 29 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */
767 /* 30 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */
768 /* Mode 11 only */
769 /* 31 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */
770 /* 32 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */
771
772 /* -------------------------------------------------------------------- */
773 /* Opcode 0110: SETMSB_6 */
774 /* -------------------------------------------------------------------- */
775 /* Mode 00 only */
776 /* 33 */ CR( 0, 0, 0, 0, 0, 0, 0),
777 /* Mode 00 and 01 */
778 /* 34 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
779 /* 35 */ CR( 6, 2, F3, 0, 1, 0, 0), /* F3 (5 MSBs) */
780 /* 36 */ CR( 6, 2, F4, 0, 1, 0, 0), /* F4 (5 MSBs) */
781 /* Mode 01 only */
782 /* 37 */ CR( 8, 0, F5, 0, 1, 0, 0), /* F5 (5 MSBs) */
783
784 /* Mode 10 only */
785 /* 38 */ CR( 0, 0, 0, 0, 0, 0, 0),
786 /* Mode 10 and 11 */
787 /* 39 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
788 /* 40 */ CR( 7, 1, F3, 0, 1, 0, 0), /* F3 (6 MSBs) */
789 /* 41 */ CR( 8, 0, F4, 0, 1, 0, 0), /* F4 (6 MSBs) */
790 /* Mode 11 only */
791 /* 42 */ CR( 8, 0, F5, 0, 1, 0, 0), /* F5 (6 MSBs) */
792
793 /* 43 */ 0,
794 /* 44 */ 0,
795
796 /* -------------------------------------------------------------------- */
797 /* Opcode 1001: DELTA_9 */
798 /* -------------------------------------------------------------------- */
799 /* Mode 00 and 01 */
800 /* 45 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */
801 /* 46 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */
802 /* 47 */ CR( 3, 4, B0, 1, 0, 0, 0), /* B0 4 MSBs */
803 /* 48 */ CR( 3, 3, F0, 1, 0, 0, 0), /* F0 5 MSBs */
804 /* 49 */ CR( 3, 4, B1, 1, 0, 0, 0), /* B1 4 MSBs */
805 /* 50 */ CR( 3, 3, F1, 1, 0, 0, 0), /* F1 5 MSBs */
806 /* 51 */ CR( 3, 4, B2, 1, 0, 0, 0), /* B2 4 MSBs */
807 /* 52 */ CR( 3, 3, F2, 1, 0, 0, 0), /* F2 5 MSBs */
808 /* 53 */ CR( 3, 3, B3, 1, 0, 0, 0), /* B3 5 MSBs */
809 /* 54 */ CR( 4, 2, F3, 1, 0, 0, 0), /* F3 6 MSBs */
810 /* 55 */ CR( 4, 1, B4, 1, 0, 0, 0), /* B4 7 MSBs */
811 /* 56 */ CR( 4, 2, F4, 1, 0, 0, 0), /* F4 6 MSBs */
812 /* Mode 01 only */
813 /* 57 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */
814 /* 58 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */
815
816 /* Mode 10 and 11 */
817 /* 59 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */
818 /* 60 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */
819 /* 61 */ CR( 4, 1, B0, 1, 0, 0, 0), /* B0 7 MSBs */
820 /* 62 */ CR( 4, 2, F0, 1, 0, 0, 0), /* F0 6 MSBs */
821 /* 63 */ CR( 4, 1, B1, 1, 0, 0, 0), /* B1 7 MSBs */
822 /* 64 */ CR( 4, 2, F1, 1, 0, 0, 0), /* F1 6 MSBs */
823 /* 65 */ CR( 4, 1, B2, 1, 0, 0, 0), /* B2 7 MSBs */
824 /* 66 */ CR( 4, 2, F2, 1, 0, 0, 0), /* F2 6 MSBs */
825 /* 67 */ CR( 4, 1, B3, 1, 0, 0, 0), /* B3 7 MSBs */
826 /* 68 */ CR( 5, 1, F3, 1, 0, 0, 0), /* F3 7 MSBs */
827 /* 69 */ CR( 5, 0, B4, 1, 0, 0, 0), /* B4 8 MSBs */
828 /* 70 */ CR( 5, 0, F4, 1, 0, 0, 0), /* F4 8 MSBs */
829 /* Mode 11 only */
830 /* 71 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */
831 /* 72 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */
832
833 /* -------------------------------------------------------------------- */
834 /* Opcode 1010: SETMSB_A */
835 /* -------------------------------------------------------------------- */
836 /* Mode 00 only */
837 /* 73 */ CR( 0, 0, 0, 0, 0, 0, 0),
838 /* Mode 00 and 01 */
839 /* 74 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
840 /* 75 */ CR( 5, 3, F0, 0, 1, 0, 0), /* F0 (5 MSBs) */
841 /* 76 */ CR( 5, 3, F1, 0, 1, 0, 0), /* F1 (5 MSBs) */
842 /* 77 */ CR( 5, 3, F2, 0, 1, 0, 0), /* F2 (5 MSBs) */
843
844 /* Mode 10 only */
845 /* 78 */ CR( 0, 0, 0, 0, 0, 0, 0),
846 /* Mode 10 and 11 */
847 /* 79 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
848 /* 80 */ CR( 6, 2, F0, 0, 1, 0, 0), /* F0 (6 MSBs) */
849 /* 81 */ CR( 6, 2, F1, 0, 1, 0, 0), /* F1 (6 MSBs) */
850 /* 82 */ CR( 6, 2, F2, 0, 1, 0, 0), /* F2 (6 MSBs) */
851
852 /* -------------------------------------------------------------------- */
853 /* Opcode 0010: LOAD_2 Mode 00 and 10 */
854 /* Opcode 1100: LOAD_C Mode 00 and 10 */
855 /* -------------------------------------------------------------------- */
856 /* LOAD_2, LOAD_C Mode 00 */
857 /* 83 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
858 /* 84 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
859 /* 85 */ CR( 3, 4, B0, 0, 0, 0, 0), /* B0 (S=0) */
860 /* 86 */ CR( 5, 3, F0, 0, 0, 0, 0), /* F0 */
861 /* 87 */ CR( 3, 4, B1, 0, 0, 0, 0), /* B1 (S=0) */
862 /* 88 */ CR( 5, 3, F1, 0, 0, 0, 0), /* F1 */
863 /* 89 */ CR( 3, 4, B2, 0, 0, 0, 0), /* B2 (S=0) */
864 /* 90 */ CR( 5, 3, F2, 0, 0, 0, 0), /* F2 */
865 /* 91 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */
866 /* 92 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */
867 /* 93 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */
868 /* 94 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */
869 /* LOAD_2 only */
870 /* 95 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
871 /* 96 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
872
873 /* LOAD_2, LOAD_C Mode 10 */
874 /* 97 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
875 /* 98 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
876 /* 99 */ CR( 6, 1, B0, 0, 0, 0, 0), /* B0 (S=0) */
877 /* 100 */ CR( 6, 2, F0, 0, 0, 0, 0), /* F0 */
878 /* 101 */ CR( 6, 1, B1, 0, 0, 0, 0), /* B1 (S=0) */
879 /* 102 */ CR( 6, 2, F1, 0, 0, 0, 0), /* F1 */
880 /* 103 */ CR( 6, 1, B2, 0, 0, 0, 0), /* B2 (S=0) */
881 /* 104 */ CR( 6, 2, F2, 0, 0, 0, 0), /* F2 */
882 /* 105 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */
883 /* 106 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */
884 /* 107 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */
885 /* 108 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */
886 /* LOAD_2 only */
887 /* 109 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
888 /* 110 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
889
890 /* -------------------------------------------------------------------- */
891 /* OPCODE 1101: DELTA_D */
892 /* -------------------------------------------------------------------- */
893 /* Mode 00 and 01 */
894 /* 111 */ CR( 4, 2, AM, 1, 0, 0, 1), /* Amplitude */
895 /* 112 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */
896 /* 113 */ CR( 3, 3, B3, 1, 0, 0, 0), /* B3 5 MSBs */
897 /* 114 */ CR( 4, 2, F3, 1, 0, 0, 0), /* F3 6 MSBs */
898 /* 115 */ CR( 4, 1, B4, 1, 0, 0, 0), /* B4 7 MSBs */
899 /* 116 */ CR( 4, 2, F4, 1, 0, 0, 0), /* F4 6 MSBs */
900 /* Mode 01 only */
901 /* 117 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */
902 /* 118 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */
903
904 /* Mode 10 and 11 */
905 /* 119 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */
906 /* 120 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */
907 /* 121 */ CR( 4, 1, B3, 1, 0, 0, 0), /* B3 7 MSBs */
908 /* 122 */ CR( 5, 1, F3, 1, 0, 0, 0), /* F3 7 MSBs */
909 /* 123 */ CR( 5, 0, B4, 1, 0, 0, 0), /* B4 8 MSBs */
910 /* 124 */ CR( 5, 0, F4, 1, 0, 0, 0), /* F4 8 MSBs */
911 /* Mode 11 only */
912 /* 125 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */
913 /* 126 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */
914
915 /* -------------------------------------------------------------------- */
916 /* OPCODE 1110: LOAD_E */
917 /* -------------------------------------------------------------------- */
918 /* 127 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
919 /* 128 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
920
921 /* -------------------------------------------------------------------- */
922 /* Opcode 0010: LOAD_2 Mode 01 and 11 */
923 /* Opcode 1100: LOAD_C Mode 01 and 11 */
924 /* -------------------------------------------------------------------- */
925 /* LOAD_2, LOAD_C Mode 01 */
926 /* 129 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
927 /* 130 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
928 /* 131 */ CR( 3, 4, B0, 0, 0, 0, 0), /* B0 (S=0) */
929 /* 132 */ CR( 5, 3, F0, 0, 0, 0, 0), /* F0 */
930 /* 133 */ CR( 3, 4, B1, 0, 0, 0, 0), /* B1 (S=0) */
931 /* 134 */ CR( 5, 3, F1, 0, 0, 0, 0), /* F1 */
932 /* 135 */ CR( 3, 4, B2, 0, 0, 0, 0), /* B2 (S=0) */
933 /* 136 */ CR( 5, 3, F2, 0, 0, 0, 0), /* F2 */
934 /* 137 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */
935 /* 138 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */
936 /* 139 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */
937 /* 140 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */
938 /* 141 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */
939 /* 142 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */
940 /* LOAD_2 only */
941 /* 143 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
942 /* 144 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
943
944 /* LOAD_2, LOAD_C Mode 11 */
945 /* 145 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
946 /* 146 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
947 /* 147 */ CR( 6, 1, B0, 0, 0, 0, 0), /* B0 (S=0) */
948 /* 148 */ CR( 6, 2, F0, 0, 0, 0, 0), /* F0 */
949 /* 149 */ CR( 6, 1, B1, 0, 0, 0, 0), /* B1 (S=0) */
950 /* 150 */ CR( 6, 2, F1, 0, 0, 0, 0), /* F1 */
951 /* 151 */ CR( 6, 1, B2, 0, 0, 0, 0), /* B2 (S=0) */
952 /* 152 */ CR( 6, 2, F2, 0, 0, 0, 0), /* F2 */
953 /* 153 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */
954 /* 154 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */
955 /* 155 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */
956 /* 156 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */
957 /* 157 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */
958 /* 158 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */
959 /* LOAD_2 only */
960 /* 159 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
961 /* 160 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
962
963 /* -------------------------------------------------------------------- */
964 /* Opcode 0011: SETMSB_3 */
965 /* Opcode 0101: SETMSB_5 */
966 /* -------------------------------------------------------------------- */
967 /* Mode 00 only */
968 /* 161 */ CR( 0, 0, 0, 0, 0, 0, 0),
969 /* Mode 00 and 01 */
970 /* 162 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
971 /* 163 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
972 /* 164 */ CR( 5, 3, F0, 0, 1, 0, 0), /* F0 (5 MSBs) */
973 /* 165 */ CR( 5, 3, F1, 0, 1, 0, 0), /* F1 (5 MSBs) */
974 /* 166 */ CR( 5, 3, F2, 0, 1, 0, 0), /* F2 (5 MSBs) */
975 /* SETMSB_3 only */
976 /* 167 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
977 /* 168 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
978
979 /* Mode 10 only */
980 /* 169 */ CR( 0, 0, 0, 0, 0, 0, 0),
981 /* Mode 10 and 11 */
982 /* 170 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */
983 /* 171 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
984 /* 172 */ CR( 6, 2, F0, 0, 1, 0, 0), /* F0 (6 MSBs) */
985 /* 173 */ CR( 6, 2, F1, 0, 1, 0, 0), /* F1 (6 MSBs) */
986 /* 174 */ CR( 6, 2, F2, 0, 1, 0, 0), /* F2 (6 MSBs) */
987 /* SETMSB_3 only */
988 /* 175 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */
989 /* 176 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */
990
991 /* -------------------------------------------------------------------- */
992 /* Opcode 0001: LOADALL */
993 /* -------------------------------------------------------------------- */
994 /* Mode x0 */
995 /* 177 */ CR( 8, 0, AM, 0, 0, 0, 0), /* Amplitude */
996 /* 178 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */
997 /* 179 */ CR( 8, 0, B0, 0, 0, 0, 0), /* B0 */
998 /* 180 */ CR( 8, 0, F0, 0, 0, 0, 0), /* F0 */
999 /* 181 */ CR( 8, 0, B1, 0, 0, 0, 0), /* B1 */
1000 /* 182 */ CR( 8, 0, F1, 0, 0, 0, 0), /* F1 */
1001 /* 183 */ CR( 8, 0, B2, 0, 0, 0, 0), /* B2 */
1002 /* 184 */ CR( 8, 0, F2, 0, 0, 0, 0), /* F2 */
1003 /* 185 */ CR( 8, 0, B3, 0, 0, 0, 0), /* B3 */
1004 /* 186 */ CR( 8, 0, F3, 0, 0, 0, 0), /* F3 */
1005 /* 187 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */
1006 /* 188 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */
1007 /* 189 */ CR( 8, 0, IA, 0, 0, 0, 0), /* Amp Interp */
1008 /* 190 */ CR( 8, 0, IP, 0, 0, 0, 0), /* Pit Interp */
1009
1010 };
1011
1012
1013
1014 LOCAL const int16_t sp0256_df_idx[16 * 8] =
1015 {
1016 /* OPCODE 0000 */ -1, -1, -1, -1, -1, -1, -1, -1,
1017 /* OPCODE 1000 */ -1, -1, -1, -1, -1, -1, -1, -1,
1018 /* OPCODE 0100 */ 17, 22, 17, 24, 25, 30, 25, 32,
1019 /* OPCODE 1100 */ 83, 94, 129,142, 97, 108, 145,158,
1020 /* OPCODE 0010 */ 83, 96, 129,144, 97, 110, 145,160,
1021 /* OPCODE 1010 */ 73, 77, 74, 77, 78, 82, 79, 82,
1022 /* OPCODE 0110 */ 33, 36, 34, 37, 38, 41, 39, 42,
1023 /* OPCODE 1110 */ 127,128, 127,128, 127,128, 127,128,
1024 /* OPCODE 0001 */ 177,190, 1, 16, 177,190, 1, 16,
1025 /* OPCODE 1001 */ 45, 56, 45, 58, 59, 70, 59, 72,
1026 /* OPCODE 0101 */ 161,166, 162,166, 169,174, 170,174,
1027 /* OPCODE 1101 */ 111,116, 111,118, 119,124, 119,126,
1028 /* OPCODE 0011 */ 161,168, 162,168, 169,176, 170,176,
1029 /* OPCODE 1011 */ -1, -1, -1, -1, -1, -1, -1, -1,
1030 /* OPCODE 0111 */ -1, -1, -1, -1, -1, -1, -1, -1,
1031 /* OPCODE 1111 */ 0, 0, 0, 0, 0, 0, 0, 0
1032 };
1033
1034 /* ======================================================================== */
1035 /* BITREV -- Bit-reverse a 32-bit number. */
1036 /* ======================================================================== */
bitrev(uint32_t val)1037 LOCAL INLINE uint32_t bitrev(uint32_t val)
1038 {
1039 val = ((val & 0xFFFF0000) >> 16) | ((val & 0x0000FFFF) << 16);
1040 val = ((val & 0xFF00FF00) >> 8) | ((val & 0x00FF00FF) << 8);
1041 val = ((val & 0xF0F0F0F0) >> 4) | ((val & 0x0F0F0F0F) << 4);
1042 val = ((val & 0xCCCCCCCC) >> 2) | ((val & 0x33333333) << 2);
1043 val = ((val & 0xAAAAAAAA) >> 1) | ((val & 0x55555555) << 1);
1044
1045 return val;
1046 }
1047
1048 /* ======================================================================== */
1049 /* SP0256_GETB -- Get up to 8 bits at the current PC. */
1050 /* ======================================================================== */
sp0256_getb(ivoice_t * ivoice,int len)1051 LOCAL uint32_t sp0256_getb(ivoice_t *ivoice, int len)
1052 {
1053 uint32_t data = 0;
1054 uint32_t d0, d1;
1055
1056 /* -------------------------------------------------------------------- */
1057 /* Fetch data from the FIFO or from the MASK */
1058 /* -------------------------------------------------------------------- */
1059 if (ivoice->fifo_sel)
1060 {
1061 d0 = ivoice->fifo[(ivoice->fifo_tail ) & 63];
1062 d1 = ivoice->fifo[(ivoice->fifo_tail + 1) & 63];
1063
1064 data = ((d1 << 10) | d0) >> ivoice->fifo_bitp;
1065
1066 #ifdef DEBUG_FIFO
1067 dfprintf(("IV: RD_FIFO %.3X %d.%d %d\n", data & ((1u << len) - 1),
1068 ivoice->fifo_tail, ivoice->fifo_bitp, ivoice->fifo_head));
1069 #endif
1070
1071 /* ---------------------------------------------------------------- */
1072 /* Note the PC doesn't advance when we execute from FIFO. */
1073 /* Just the FIFO's bit-pointer advances. (That's not REALLY */
1074 /* what happens, but that's roughly how it behaves.) */
1075 /* ---------------------------------------------------------------- */
1076 ivoice->fifo_bitp += len;
1077 if (ivoice->fifo_bitp >= 10)
1078 {
1079 ivoice->fifo_tail++;
1080 ivoice->fifo_bitp -= 10;
1081 }
1082 } else
1083 {
1084 /* ---------------------------------------------------------------- */
1085 /* Figure out which ROMs are being fetched into, and grab two */
1086 /* adjacent bytes. The byte we're interested in is extracted */
1087 /* from the appropriate bit-boundary between them. */
1088 /* ---------------------------------------------------------------- */
1089 int idx0 = (ivoice->pc ) >> 3, page0 = idx0 >> 12;
1090 int idx1 = (ivoice->pc + 8) >> 3, page1 = idx1 >> 12;
1091
1092 idx0 &= 0xFFF;
1093 idx1 &= 0xFFF;
1094
1095 d0 = d1 = 0;
1096
1097 if (ivoice->rom[page0]) d0 = ivoice->rom[page0][idx0];
1098 if (ivoice->rom[page1]) d1 = ivoice->rom[page1][idx1];
1099
1100 data = ((d1 << 8) | d0) >> (ivoice->pc & 7);
1101
1102 ivoice->pc += len;
1103 }
1104
1105 /* -------------------------------------------------------------------- */
1106 /* Mask data to the requested length. */
1107 /* -------------------------------------------------------------------- */
1108 data &= ((1u << len) - 1);
1109
1110 return data;
1111 }
1112
1113 /* ======================================================================== */
1114 /* SP0256_MICRO -- Emulate the microsequencer in the SP0256. Executes */
1115 /* instructions either until the repeat count != 0 or */
1116 /* the sequencer gets halted by a RTS to 0. */
1117 /* ======================================================================== */
sp0256_micro(ivoice_t * iv)1118 LOCAL void sp0256_micro(ivoice_t *iv)
1119 {
1120 uint8_t immed4;
1121 uint8_t opcode;
1122 uint16_t cr;
1123 int ctrl_xfer = 0;
1124 int repeat = 0;
1125 int i, idx0, idx1;
1126
1127 /* -------------------------------------------------------------------- */
1128 /* Only execute instructions while the filter is not busy. */
1129 /* -------------------------------------------------------------------- */
1130 while (iv->filt.rpt <= 0 && iv->filt.cnt <= 0)
1131 {
1132 /* ---------------------------------------------------------------- */
1133 /* If the CPU is halted, see if we have a new command pending */
1134 /* in the Address LoaD buffer. */
1135 /* ---------------------------------------------------------------- */
1136 if (iv->halted && !iv->lrq)
1137 {
1138 iv->pc = iv->ald | (0x1000 << 3);
1139 iv->fifo_sel = 0;
1140 iv->halted = 0;
1141 iv->lrq = 0x8000;
1142 iv->ald = 0;
1143 /* for (i = 0; i < 16; i++)*/
1144 /* iv->filt.r[i] = 0;*/
1145 iv_smp_start(iv);
1146 }
1147
1148 /* ---------------------------------------------------------------- */
1149 /* If we're still halted, do nothing. */
1150 /* ---------------------------------------------------------------- */
1151 if (iv->halted)
1152 {
1153 iv->filt.rpt = 1;
1154 iv->filt.cnt = 0;
1155 iv->lrq = 0x8000;
1156 iv->ald = 0;
1157 /* for (i = 0; i < 16; i++)*/
1158 /* iv->filt.r[i] = 0;*/
1159 iv_smp_stop(iv);
1160 return;
1161 }
1162
1163 /* ---------------------------------------------------------------- */
1164 /* Fetch the first 8 bits of the opcode, which are always in the */
1165 /* same approximate format -- immed4 followed by opcode. */
1166 /* ---------------------------------------------------------------- */
1167 immed4 = sp0256_getb(iv, 4);
1168 opcode = sp0256_getb(iv, 4);
1169 repeat = 0;
1170 ctrl_xfer = 0;
1171
1172 iv_smp_ckupd(iv, immed4*16 + opcode);
1173
1174 jzdprintf(("$%.4X.%.1X: OPCODE %d%d%d%d.%d%d\n",
1175 (iv->pc >> 3) - 1, iv->pc & 7,
1176 !!(opcode & 1), !!(opcode & 2),
1177 !!(opcode & 4), !!(opcode & 8),
1178 !!(iv->mode&4), !!(iv->mode&2)));
1179
1180 /* ---------------------------------------------------------------- */
1181 /* Handle the special cases for specific opcodes. */
1182 /* ---------------------------------------------------------------- */
1183 switch (opcode)
1184 {
1185 /* ------------------------------------------------------------ */
1186 /* OPCODE 0000: RTS / SETPAGE */
1187 /* ------------------------------------------------------------ */
1188 case 0x0:
1189 {
1190 /* -------------------------------------------------------- */
1191 /* If immed4 != 0, then this is a SETPAGE instruction. */
1192 /* -------------------------------------------------------- */
1193 if (immed4) /* SETPAGE */
1194 {
1195 iv->page = bitrev(immed4) >> 13;
1196 } else
1197 /* -------------------------------------------------------- */
1198 /* Otherwise, this is an RTS / HLT. */
1199 /* -------------------------------------------------------- */
1200 {
1201 uint32_t btrg;
1202
1203 /* ---------------------------------------------------- */
1204 /* Figure out our branch target. */
1205 /* ---------------------------------------------------- */
1206 btrg = iv->stack;
1207
1208 iv->stack = 0;
1209
1210 /* ---------------------------------------------------- */
1211 /* If the branch target is zero, this is a HLT. */
1212 /* Otherwise, it's an RTS, so set the PC. */
1213 /* ---------------------------------------------------- */
1214 if (!btrg)
1215 {
1216 iv->halted = 1;
1217 iv->pc = 0;
1218 ctrl_xfer = 1;
1219 } else
1220 {
1221 iv->pc = btrg;
1222 ctrl_xfer = 1;
1223 }
1224 }
1225
1226 break;
1227 }
1228
1229 /* ------------------------------------------------------------ */
1230 /* OPCODE 0111: JMP Jump to 12-bit/16-bit Abs Addr */
1231 /* OPCODE 1011: JSR Jump to Subroutine */
1232 /* ------------------------------------------------------------ */
1233 case 0xE:
1234 case 0xD:
1235 {
1236 int btrg;
1237
1238 /* -------------------------------------------------------- */
1239 /* Figure out our branch target. */
1240 /* -------------------------------------------------------- */
1241 btrg = iv->page |
1242 (bitrev(immed4) >> 17) |
1243 (bitrev(sp0256_getb(iv, 8)) >> 21);
1244 iv_smp_ckupd(iv, btrg);
1245 ctrl_xfer = 1;
1246
1247 /* -------------------------------------------------------- */
1248 /* If this is a JSR, push our return address on the */
1249 /* stack. Make sure it's byte aligned. */
1250 /* -------------------------------------------------------- */
1251 if (opcode == 0xD)
1252 iv->stack = (iv->pc + 7) & ~7;
1253
1254 /* -------------------------------------------------------- */
1255 /* Jump to the new location! */
1256 /* -------------------------------------------------------- */
1257 iv->pc = btrg;
1258 break;
1259 }
1260
1261 /* ------------------------------------------------------------ */
1262 /* OPCODE 1000: SETMODE Set the Mode and Repeat MSBs */
1263 /* ------------------------------------------------------------ */
1264 case 0x1:
1265 {
1266 iv->mode = ((immed4 & 8) >> 2) | (immed4 & 4) |
1267 ((immed4 & 3) << 4);
1268 break;
1269 }
1270
1271 /* ------------------------------------------------------------ */
1272 /* OPCODE 0001: LOADALL Load All Parameters */
1273 /* OPCODE 0010: LOAD_2 Load Per, Ampl, Coefs, Interp. */
1274 /* OPCODE 0011: SETMSB_3 Load Pitch, Ampl, MSBs, & Intrp */
1275 /* OPCODE 0100: LOAD_4 Load Pitch, Ampl, Coeffs */
1276 /* OPCODE 0101: SETMSB_5 Load Pitch, Ampl, and Coeff MSBs */
1277 /* OPCODE 0110: SETMSB_6 Load Ampl, and Coeff MSBs. */
1278 /* OPCODE 1001: DELTA_9 Delta update Ampl, Pitch, Coeffs */
1279 /* OPCODE 1010: SETMSB_A Load Ampl and MSBs of 3 Coeffs */
1280 /* OPCODE 1100: LOAD_C Load Pitch, Ampl, Coeffs */
1281 /* OPCODE 1101: DELTA_D Delta update Ampl, Pitch, Coeffs */
1282 /* OPCODE 1110: LOAD_E Load Pitch, Amplitude */
1283 /* OPCODE 1111: PAUSE Silent pause */
1284 /* ------------------------------------------------------------ */
1285 default:
1286 {
1287 repeat = immed4 | (iv->mode & 0x30);
1288 break;
1289 }
1290 }
1291 if (opcode != 1) iv->mode &= 0xF;
1292
1293 /* ---------------------------------------------------------------- */
1294 /* If this was a control transfer, handle setting "fifo_sel" */
1295 /* and all that ugliness. */
1296 /* ---------------------------------------------------------------- */
1297 if (ctrl_xfer)
1298 {
1299 jzdprintf(("jumping to $%.4X.%.1X: ", iv->pc >> 3, iv->pc & 7));
1300
1301 /* ------------------------------------------------------------ */
1302 /* Set our "FIFO Selected" flag based on whether we're going */
1303 /* to the FIFO's address. */
1304 /* ------------------------------------------------------------ */
1305 iv->fifo_sel = iv->pc == FIFO_ADDR;
1306
1307 jzdprintf(("%s ", iv->fifo_sel ? "FIFO" : "ROM"));
1308
1309 /* ------------------------------------------------------------ */
1310 /* Control transfers to the FIFO cause it to discard the */
1311 /* partial decle that's at the front of the FIFO. */
1312 /* ------------------------------------------------------------ */
1313 if (iv->fifo_sel && iv->fifo_bitp)
1314 {
1315 jzdprintf(("bitp = %d -> Flush", iv->fifo_bitp));
1316
1317 /* Discard partially-read decle. */
1318 if (iv->fifo_tail < iv->fifo_head) iv->fifo_tail++;
1319 iv->fifo_bitp = 0;
1320 }
1321
1322 jzdprintf(("\n"));
1323
1324 continue;
1325 }
1326
1327 /* ---------------------------------------------------------------- */
1328 /* Otherwise, if we have a repeat count, then go grab the data */
1329 /* block and feed it to the filter. */
1330 /* ---------------------------------------------------------------- */
1331 if (!repeat) continue;
1332
1333
1334 #ifdef SINGLE_STEP
1335 jzp_printf("NEXT:\n"); jzp_flush();
1336 {
1337 char buf[1024];
1338 fgets(buf,sizeof(buf),stdin); if (opcode != 0xF) repeat <<= 3;
1339 }
1340 #endif
1341
1342 iv->filt.rpt = repeat;
1343 jzdprintf(("repeat = %d\n", repeat));
1344
1345 /* clear delay line on new opcode */
1346 for (i = 0; i < 6; i++)
1347 iv->filt.z_data[i][0] = iv->filt.z_data[i][1] = 0;
1348
1349 i = (opcode << 3) | (iv->mode & 6);
1350 idx0 = sp0256_df_idx[i++];
1351 idx1 = sp0256_df_idx[i ];
1352
1353 assert(idx0 >= 0 && idx1 >= 0 && idx1 >= idx0);
1354
1355 /* ---------------------------------------------------------------- */
1356 /* If we're in one of the 10-pole modes (x0), clear F5/B5. */
1357 /* ---------------------------------------------------------------- */
1358 if ((iv->mode & 2) == 0)
1359 iv->filt.r[F5] = iv->filt.r[B5] = 0;
1360
1361
1362 /* ---------------------------------------------------------------- */
1363 /* Step through control words in the description for data block. */
1364 /* ---------------------------------------------------------------- */
1365 for (i = idx0; i <= idx1; i++)
1366 {
1367 int len, shf, delta, field, prm, clrL;
1368 int8_t value;
1369
1370 /* ------------------------------------------------------------ */
1371 /* Get the control word and pull out some important fields. */
1372 /* ------------------------------------------------------------ */
1373 cr = sp0256_datafmt[i];
1374
1375 len = CR_LEN(cr);
1376 shf = CR_SHF(cr);
1377 prm = CR_PRM(cr);
1378 clrL = cr & CR_CLRL;
1379 delta = cr & CR_DELTA;
1380 field = cr & CR_FIELD;
1381 value = 0;
1382
1383 jzdprintf(("$%.4X.%.1X: len=%2d shf=%2d prm=%2d d=%d f=%d ",
1384 iv->pc >> 3, iv->pc & 7, len, shf, prm, !!delta, !!field));
1385 /* ------------------------------------------------------------ */
1386 /* Clear any registers that were requested to be cleared. */
1387 /* ------------------------------------------------------------ */
1388 if (clrL)
1389 {
1390 iv->filt.r[F0] = iv->filt.r[B0] = 0;
1391 iv->filt.r[F1] = iv->filt.r[B1] = 0;
1392 iv->filt.r[F2] = iv->filt.r[B2] = 0;
1393 }
1394
1395 /* ------------------------------------------------------------ */
1396 /* If this entry has a bitfield with it, grab the bitfield. */
1397 /* ------------------------------------------------------------ */
1398 if (len)
1399 {
1400 value = sp0256_getb(iv, len);
1401 iv_smp_ckupd(iv, value);
1402 }
1403 else
1404 {
1405 jzdprintf((" (no update)\n"));
1406 continue;
1407 }
1408
1409 /* ------------------------------------------------------------ */
1410 /* Sign extend if this is a delta update. */
1411 /* ------------------------------------------------------------ */
1412 if (delta) /* Sign extend */
1413 {
1414 if (value & (1u << (len - 1))) value |= -(1u << len);
1415 }
1416
1417 /* ------------------------------------------------------------ */
1418 /* Shift the value to the appropriate precision. */
1419 /* ------------------------------------------------------------ */
1420 if (shf)
1421 value = value < 0 ? -(-value << shf) : (value << shf);
1422
1423 jzdprintf(("v=%.2X (%c%.2X) ", value & 0xFF,
1424 value & 0x80 ? '-' : '+',
1425 0xFF & (value & 0x80 ? -value : value)));
1426
1427 iv->silent = 0;
1428
1429 /* ------------------------------------------------------------ */
1430 /* If this is a field-replace, insert the field. */
1431 /* ------------------------------------------------------------ */
1432 if (field)
1433 {
1434 jzdprintf(("--field-> r[%2d] = %.2X -> ", prm, iv->filt.r[prm]));
1435
1436 iv->filt.r[prm] &= ~(~0u << shf); /* Clear the old bits. */
1437 iv->filt.r[prm] |= value; /* Merge in the new bits. */
1438
1439 jzdprintf(("%.2X\n", iv->filt.r[prm]));
1440
1441 continue;
1442 }
1443
1444 /* ------------------------------------------------------------ */
1445 /* If this is a delta update, add to the appropriate field. */
1446 /* ------------------------------------------------------------ */
1447 if (delta)
1448 {
1449 jzdprintf(("--delta-> r[%2d] = %.2X -> ", prm, iv->filt.r[prm]));
1450
1451 iv->filt.r[prm] += value;
1452
1453 jzdprintf(("%.2X\n", iv->filt.r[prm]));
1454
1455 continue;
1456 }
1457
1458 /* ------------------------------------------------------------ */
1459 /* Otherwise, just write the new value. */
1460 /* ------------------------------------------------------------ */
1461 iv->filt.r[prm] = value;
1462 jzdprintf(("--value-> r[%2d] = %.2X\n", prm, iv->filt.r[prm]));
1463 }
1464
1465 /* ---------------------------------------------------------------- */
1466 /* Most opcodes clear IA, IP. */
1467 /* ---------------------------------------------------------------- */
1468 if (opcode != 0x1 && opcode != 0x2 && opcode != 0x3)
1469 {
1470 iv->filt.r[IA] = 0;
1471 iv->filt.r[IP] = 0;
1472 }
1473
1474 /* ---------------------------------------------------------------- */
1475 /* Special case: Set PAUSE's equivalent period. */
1476 /* ---------------------------------------------------------------- */
1477 if (opcode == 0xF)
1478 {
1479 iv->silent = 1;
1480 iv->filt.r[AM] = 0;
1481 iv->filt.r[PR] = PER_PAUSE;
1482 }
1483
1484 /* ---------------------------------------------------------------- */
1485 /* Now that we've updated the registers, go decode them. */
1486 /* ---------------------------------------------------------------- */
1487 lpc12_regdec(&iv->filt);
1488
1489 /* ---------------------------------------------------------------- */
1490 /* Break out since we now have a repeat count. */
1491 /* ---------------------------------------------------------------- */
1492 break;
1493 }
1494 }
1495
1496 /* ======================================================================== */
1497 /* IVOICE_RDROM -- Tries to read a ROM file in the current directory. */
1498 /* ======================================================================== */
ivoice_rdrom(ivoice_t * iv,int page)1499 LOCAL int ivoice_rdrom(ivoice_t *iv, int page)
1500 {
1501 uint8_t *rom;
1502 char buf[32];
1503 LZFILE *f;
1504 int i;
1505
1506 /* -------------------------------------------------------------------- */
1507 /* Generate a file name, and then see if it exists. */
1508 /* -------------------------------------------------------------------- */
1509 snprintf(buf, sizeof(buf), "sp0256_%.1X.bin", page);
1510
1511 f = lzoe_fopen(buf, "rb");
1512 if (!f) return 0;
1513
1514 /* -------------------------------------------------------------------- */
1515 /* Allocate 4K worth of space to the ROM image. */
1516 /* -------------------------------------------------------------------- */
1517 rom = CALLOC(uint8_t, 4096);
1518 if (!rom)
1519 {
1520 fprintf(stderr, "IVOICE: Out of memory in rdrom\n");
1521 return -1;
1522 }
1523
1524 /* -------------------------------------------------------------------- */
1525 /* Read in the ROM image and then bit-reverse it. */
1526 /* -------------------------------------------------------------------- */
1527 lzoe_fread(rom, 1, 4096, f);
1528 lzoe_fclose(f);
1529
1530 for (i = 0; i < 4096; i++)
1531 rom[i] = bitrev(rom[i]) >> 24;
1532
1533 /* -------------------------------------------------------------------- */
1534 /* Set this as our ROM page, and we're all set. */
1535 /* -------------------------------------------------------------------- */
1536 iv->rom[page] = rom;
1537
1538 jzp_printf("ivoice: added %s at SP0256 address $%.4X.0\n", buf, page<<12);
1539
1540 return 0;
1541 }
1542
1543
1544 /* ======================================================================== */
1545 /* IVOICE_TK -- Where the magic happens. Generate voice data for */
1546 /* our good friend, the Intellivoice. */
1547 /* ======================================================================== */
ivoice_tk(periph_t * per,uint32_t len)1548 LOCAL uint32_t ivoice_tk(periph_t *per, uint32_t len)
1549 {
1550 ivoice_t *ivoice = PERIPH_AS(ivoice_t, per);
1551 uint64_t until = (per->now + len) * 4;
1552 int samples, did_samp, old_idx;
1553 int sys_clock = ivoice->pal_mode ? 4000000 : 3579545;
1554 int clock_per_samp = ivoice->pal_mode ? 400 : 358;
1555
1556 /* -------------------------------------------------------------------- */
1557 /* If the rest of the machine hasn't caught up to us, just return. */
1558 /* -------------------------------------------------------------------- */
1559 if (until <= ivoice->sound_current)
1560 return 0;
1561
1562 /* -------------------------------------------------------------------- */
1563 /* Make sure we have a clean buffer to write in. */
1564 /* -------------------------------------------------------------------- */
1565 if (!ivoice->cur_buf)
1566 {
1567 if (ivoice->snd_buf.num_clean)
1568 {
1569 int clean_idx = --ivoice->snd_buf.num_clean;
1570 ivoice->cur_buf = ivoice->snd_buf.clean[clean_idx];
1571 ivoice->snd_buf.clean[clean_idx] = NULL;
1572 ivoice->cur_len = 0;
1573 } else
1574 return 0; /* No buffer available, so time doesn't advance. */
1575 }
1576
1577 /* -------------------------------------------------------------------- */
1578 /* Iterate the sound engine. */
1579 /* -------------------------------------------------------------------- */
1580 while (ivoice->sound_current < until)
1581 {
1582 /* ---------------------------------------------------------------- */
1583 /* Renormalize our sc_head and sc_tail. */
1584 /* ---------------------------------------------------------------- */
1585 while (ivoice->sc_head > SCBUF_SIZE && ivoice->sc_tail > SCBUF_SIZE)
1586 {
1587 ivoice->sc_head -= SCBUF_SIZE;
1588 ivoice->sc_tail -= SCBUF_SIZE;
1589 }
1590
1591 /* ---------------------------------------------------------------- */
1592 /* First, drain as much of our scratch buffer as we can into the */
1593 /* sound buffers. */
1594 /* ---------------------------------------------------------------- */
1595 while (ivoice->sc_tail < ivoice->sc_head)
1596 {
1597 int32_t s, ws;
1598
1599 ws = s = ivoice->scratch[ivoice->sc_tail++ & SCBUF_MASK];
1600
1601 if (ivoice->skipping < 0.0)
1602 {
1603 ivoice->skipping += 1.0;
1604 continue;
1605 }
1606
1607 if (ivoice->time_scale <= 1.0)
1608 {
1609 ivoice->sample_frc += ivoice->rate * clock_per_samp /
1610 ivoice->time_scale;
1611 } else
1612 {
1613 ivoice->sample_frc += ivoice->rate * clock_per_samp;
1614 ivoice->skipping += ivoice->time_scale - 1.0;
1615 }
1616
1617 if (ivoice->skipping >= 512.0)
1618 ivoice->skipping = -ivoice->skipping;
1619
1620 /* ------------------------------------------------------------ */
1621 /* Update the sliding window in down-sample mode */
1622 /* ------------------------------------------------------------ */
1623 if (ivoice->rate < 10000)
1624 {
1625 ivoice->wind_sum -= ivoice->window[ivoice->wind_ptr ];
1626 ivoice->wind_sum += ivoice->window[ivoice->wind_ptr++] = s;
1627 if (ivoice->wind_ptr >= ivoice->wind) ivoice->wind_ptr = 0;
1628
1629 ws = ivoice->wind_sum / ivoice->wind;
1630 }
1631
1632 while (ivoice->sample_frc > sys_clock)
1633 {
1634 ivoice->sample_frc -= sys_clock;
1635
1636 /* -------------------------------------------------------- */
1637 /* Update the sliding window in up-sample mode */
1638 /* -------------------------------------------------------- */
1639 if (ivoice->rate >= 10000)
1640 {
1641 ivoice->wind_sum -= ivoice->window[ivoice->wind_ptr ];
1642 ivoice->wind_sum += ivoice->window[ivoice->wind_ptr++] = s;
1643 if (ivoice->wind_ptr >= ivoice->wind) ivoice->wind_ptr = 0;
1644
1645 ws = ivoice->wind_sum / ivoice->wind;
1646 }
1647
1648 /* -------------------------------------------------------- */
1649 /* Store out the current sample. */
1650 /* -------------------------------------------------------- */
1651 ivoice->cur_buf[ivoice->cur_len++] = ws;
1652
1653 /* -------------------------------------------------------- */
1654 /* Commit the buffer when it's full. */
1655 /* -------------------------------------------------------- */
1656 if (ivoice->cur_len >= ivoice->snd_buf.snd->buf_size)
1657 {
1658 /* ---------------------------------------------------- */
1659 /* It's full. Put it on the dirty list. */
1660 /* ---------------------------------------------------- */
1661 ivoice->snd_buf.dirty[ivoice->snd_buf.num_dirty++] =
1662 ivoice->cur_buf;
1663
1664 /* ---------------------------------------------------- */
1665 /* Try to get a clean buffer. */
1666 /* ---------------------------------------------------- */
1667 if (ivoice->snd_buf.num_clean == 0)
1668 {
1669 /* ------------------------------------------------ */
1670 /* No clean buffers: Abort early. *sniffle* */
1671 /* ------------------------------------------------ */
1672 ivoice->cur_buf = NULL;
1673 goto abort;
1674 }
1675
1676 /* ---------------------------------------------------- */
1677 /* Pull the clean buffer off the end of the list. */
1678 /* ---------------------------------------------------- */
1679 ivoice->cur_buf =
1680 ivoice->snd_buf.clean[--ivoice->snd_buf.num_clean];
1681 ivoice->cur_len = 0;
1682 }
1683 }
1684 }
1685
1686 /* ---------------------------------------------------------------- */
1687 /* Calculate the number of samples required at ~10kHz. */
1688 /* (Actually, on NTSC this is 3579545 / 358, or 9998.73 Hz). */
1689 /* ---------------------------------------------------------------- */
1690 samples = ((int)(until - ivoice->sound_current + clock_per_samp - 1))
1691 / clock_per_samp;
1692
1693 /* ---------------------------------------------------------------- */
1694 /* Process the current set of filter coefficients as long as the */
1695 /* repeat count holds up and we have room in our scratch buffer. */
1696 /* ---------------------------------------------------------------- */
1697 did_samp = 0;
1698 old_idx = ivoice->sc_head;
1699 if (samples > 0) do
1700 {
1701 int do_samp;
1702
1703 /* ------------------------------------------------------------ */
1704 /* If our repeat count expired, emulate the microsequencer. */
1705 /* ------------------------------------------------------------ */
1706 if (ivoice->filt.rpt <= 0 && ivoice->filt.cnt <= 0)
1707 sp0256_micro(ivoice);
1708
1709 /* ------------------------------------------------------------ */
1710 /* Do as many samples as we can. */
1711 /* ------------------------------------------------------------ */
1712 do_samp = samples - did_samp;
1713 if (ivoice->sc_head + do_samp - ivoice->sc_tail > SCBUF_SIZE)
1714 do_samp = ivoice->sc_tail + SCBUF_SIZE - ivoice->sc_head;
1715
1716 if (do_samp == 0) break;
1717
1718 if (ivoice->silent &&
1719 ivoice->filt.rpt <= 0 && ivoice->filt.cnt <= 0)
1720 {
1721 int x, y = ivoice->sc_head;
1722
1723 for (x = 0; x < do_samp; x++)
1724 ivoice->scratch[y++ & SCBUF_MASK] = 0;
1725 ivoice->sc_head += do_samp;
1726 did_samp += do_samp;
1727 } else
1728 {
1729 did_samp += lpc12_update(&ivoice->filt, do_samp,
1730 ivoice->scratch, &ivoice->sc_head);
1731 }
1732
1733 } while ((ivoice->filt.rpt > 0 || ivoice->filt.cnt > 0) &&
1734 samples > did_samp);
1735 if (did_samp)
1736 iv_smp_record(ivoice, did_samp, ivoice->scratch, old_idx);
1737
1738 ivoice->sound_current += did_samp * clock_per_samp;
1739 }
1740
1741 abort:
1742 // if (per->now*4 - ivoice->sound_current > THRESH)
1743 // ivoice->snd_buf.drop++;
1744
1745 return (ivoice->sound_current >> 2) - per->now;
1746 }
1747
1748
1749 /* ======================================================================== */
1750 /* IVOICE_RD -- Handle reads from the Intellivoice. */
1751 /* ======================================================================== */
ivoice_rd(periph_t * per,periph_t * ign,uint32_t addr,uint32_t data)1752 LOCAL uint32_t ivoice_rd(periph_t *per, periph_t *ign,
1753 uint32_t addr, uint32_t data)
1754 {
1755 ivoice_t *ivoice = PERIPH_AS(ivoice_t, per);
1756
1757 UNUSED(data);
1758 UNUSED(ign);
1759
1760 /* -------------------------------------------------------------------- */
1761 /* Address 0x80 returns the SP0256 LRQ status on bit 15. */
1762 /* -------------------------------------------------------------------- */
1763 if (addr == 0)
1764 {
1765 return ivoice->lrq;
1766 }
1767
1768 /* -------------------------------------------------------------------- */
1769 /* Address 0x81 returns the SPB640 FIFO full status on bit 15. */
1770 /* -------------------------------------------------------------------- */
1771 if (addr == 1)
1772 {
1773 return (ivoice->fifo_head - ivoice->fifo_tail) >= 64 ? 0x8000 : 0;
1774 }
1775
1776 /* -------------------------------------------------------------------- */
1777 /* Just return 255 for all other addresses in our range. */
1778 /* -------------------------------------------------------------------- */
1779 return 0x00FF;
1780 }
1781
1782 /* ======================================================================== */
1783 /* IVOICE_WR -- Handle writes to the Intellivoice. */
1784 /* ======================================================================== */
ivoice_wr(periph_t * const per,periph_t * ign,uint32_t addr,uint32_t data)1785 LOCAL void ivoice_wr(periph_t *const per, periph_t *ign,
1786 uint32_t addr, uint32_t data)
1787 {
1788 ivoice_t *const ivoice = PERIPH_AS(ivoice_t, per);
1789 UNUSED(ign);
1790
1791 /* -------------------------------------------------------------------- */
1792 /* Ignore writes outside 0x80, 0x81. */
1793 /* -------------------------------------------------------------------- */
1794 if (addr > 1) return;
1795
1796 /* -------------------------------------------------------------------- */
1797 /* Address 0x80 is for Address Loads (essentially speech commands). */
1798 /* -------------------------------------------------------------------- */
1799 if (addr == 0)
1800 {
1801 /* ---------------------------------------------------------------- */
1802 /* Drop writes to the ALD register if we're busy. */
1803 /* ---------------------------------------------------------------- */
1804 if (!ivoice->lrq)
1805 return;
1806
1807 /* ---------------------------------------------------------------- */
1808 /* Set LRQ to "busy" and load the 8 LSBs of the data into the ALD */
1809 /* reg. We take the command address, and multiply by 2 bytes to */
1810 /* get the new PC address. */
1811 /* ---------------------------------------------------------------- */
1812 ivoice->lrq = 0;
1813 ivoice->ald = (0xFF & data) << 4;
1814
1815 return;
1816 }
1817
1818 /* -------------------------------------------------------------------- */
1819 /* Address 0x81 is for FIFOing up decles. The FIFO is 64 decles */
1820 /* long. The Head pointer points to where we insert new decles and */
1821 /* the Tail pointer is where we pull them from. */
1822 /* -------------------------------------------------------------------- */
1823 if (addr == 1)
1824 {
1825 /* ---------------------------------------------------------------- */
1826 /* If Bit 10 is set, just reset the FIFO and SP0256. */
1827 /* ---------------------------------------------------------------- */
1828 if (data & 0x400)
1829 {
1830 ivoice->fifo_head = ivoice->fifo_tail = ivoice->fifo_bitp = 0;
1831
1832 memset(&ivoice->filt, 0, sizeof(ivoice->filt));
1833 ivoice->halted = 1;
1834 ivoice->filt.rpt = -1;
1835 ivoice->filt.rng = 1;
1836 ivoice->lrq = 0x8000;
1837 ivoice->ald = 0x0000;
1838 ivoice->pc = 0x0000;
1839 ivoice->stack = 0x0000;
1840 ivoice->fifo_sel = 0;
1841 ivoice->mode = 0;
1842 ivoice->page = 0x1000 << 3;
1843 ivoice->silent = 1;
1844 return;
1845 }
1846
1847 /* ---------------------------------------------------------------- */
1848 /* If the FIFO is full, drop the data. */
1849 /* ---------------------------------------------------------------- */
1850 if ((ivoice->fifo_head - ivoice->fifo_tail) >= 64)
1851 {
1852 jzdprintf(("IV: Dropped FIFO write\n"));
1853 return;
1854 }
1855
1856 /* ---------------------------------------------------------------- */
1857 /* FIFO up the lower 10 bits of the data. */
1858 /* ---------------------------------------------------------------- */
1859 #ifdef DEBUG_FIFO
1860 dfprintf(("IV: WR_FIFO %.3X %d.%d %d\n", data & 0x3FF,
1861 ivoice->fifo_tail, ivoice->fifo_bitp, ivoice->fifo_head));
1862 #endif
1863 ivoice->fifo[ivoice->fifo_head++ & 63] = data & 0x3FF;
1864
1865 return;
1866 }
1867 }
1868
1869 /* ======================================================================== */
1870 /* IVOICE_RESET -- Resets the Intellivoice */
1871 /* ======================================================================== */
ivoice_reset(periph_t * const p)1872 LOCAL void ivoice_reset(periph_t *const p)
1873 {
1874 /* -------------------------------------------------------------------- */
1875 /* Do a software-style reset of the Intellivoice. */
1876 /* -------------------------------------------------------------------- */
1877 ivoice_wr(p, NULL, 1, 0x400);
1878 }
1879
1880 /* ======================================================================== */
1881 /* IVOICE_DTOR -- Destroy an Intellivoice */
1882 /* ======================================================================== */
ivoice_dtor(periph_t * const p)1883 LOCAL void ivoice_dtor(periph_t *const p)
1884 {
1885 ivoice_t *const ivoice = PERIPH_AS(ivoice_t, p);
1886
1887 CONDFREE(ivoice->window);
1888 CONDFREE(ivoice->scratch);
1889 CONDFREE(ivoice->smp_tname);
1890 CONDFREE(ivoice->smp_cname);
1891 CONDFREE(ivoice->smp_cksum);
1892 }
1893
1894 /* ======================================================================== */
1895 /* IVOICE_INIT -- Makes a new Intellivoice */
1896 /* ======================================================================== */
ivoice_init(ivoice_t * ivoice,uint32_t addr,snd_t * snd,int rate,int wind,const char * smp_tname,int pal_mode,double time_scale)1897 int ivoice_init
1898 (
1899 ivoice_t *ivoice, /* Structure to initialize. */
1900 uint32_t addr, /* Base address of ivoice. */
1901 snd_t *snd, /* Sound device to register w/. */
1902 int rate, /* Desired sample rate. */
1903 int wind, /* Sliding window size. */
1904 const char *smp_tname, /* Filename template for saving samples. */
1905 int pal_mode, /* PAL vs. NTSC */
1906 double time_scale /* For --macho */
1907 )
1908 {
1909 int i;
1910
1911 /* -------------------------------------------------------------------- */
1912 /* First, lets zero out the structure to be safe. */
1913 /* -------------------------------------------------------------------- */
1914 memset(ivoice, 0, sizeof(ivoice_t));
1915
1916 /* -------------------------------------------------------------------- */
1917 /* Sanity checks. */
1918 /* -------------------------------------------------------------------- */
1919 if (rate < 10000 || rate > 96000)
1920 {
1921 fprintf(stderr, "ivoice: Sampling rate of %d is invalid. Must be "
1922 "between 10000 and 96000.\n", rate);
1923 return -1;
1924 }
1925
1926 /* -------------------------------------------------------------------- */
1927 /* If wind == -1, calculate a window size based on the ratio of our */
1928 /* sample rate to the device's native rate. */
1929 /* -------------------------------------------------------------------- */
1930 if (wind == -1)
1931 {
1932 if (rate > 10000) wind = rate / 5000 + 3;
1933 else wind = 20000 / rate + 1;
1934
1935 if (wind < 1) wind = 1;
1936
1937 jzp_printf("ivoice: Automatic sliding-window setting: %d\n", wind);
1938 }
1939
1940 /* -------------------------------------------------------------------- */
1941 /* Set up the peripheral. */
1942 /* -------------------------------------------------------------------- */
1943 ivoice->periph.read = ivoice_rd;
1944 ivoice->periph.write = ivoice_wr;
1945 ivoice->periph.peek = ivoice_rd;
1946 ivoice->periph.poke = ivoice_wr;
1947 ivoice->periph.tick = ivoice_tk;
1948 ivoice->periph.reset = ivoice_reset;
1949 ivoice->periph.min_tick = 1024 * time_scale;
1950 ivoice->periph.max_tick = 14934 * time_scale;
1951 ivoice->periph.addr_base = addr;
1952 ivoice->periph.addr_mask = 0xFFFF;
1953 ivoice->periph.dtor = ivoice_dtor;
1954
1955 /* -------------------------------------------------------------------- */
1956 /* Configure our internal variables. */
1957 /* -------------------------------------------------------------------- */
1958 ivoice->rom[1] = mask;
1959 ivoice->rate = rate;
1960 ivoice->filt.rng = 1;
1961 ivoice->wind = wind;
1962 ivoice->window = CALLOC(int, wind);
1963 ivoice->wind_sum = 0;
1964 ivoice->pal_mode = pal_mode;
1965 ivoice->time_scale = time_scale;
1966 if (!ivoice->window)
1967 {
1968 fprintf(stderr, "ivoice: Out of memory allocating sliding window.\n");
1969 return -1;
1970 }
1971
1972
1973 /* -------------------------------------------------------------------- */
1974 /* Register this as a sound peripheral with the SND driver. */
1975 /* -------------------------------------------------------------------- */
1976 if (snd_register(AS_PERIPH(snd), &ivoice->snd_buf))
1977 return -1;
1978
1979 /* -------------------------------------------------------------------- */
1980 /* Set up our initial working buffer. */
1981 /* -------------------------------------------------------------------- */
1982 ivoice->cur_buf = ivoice->snd_buf.clean[--ivoice->snd_buf.num_clean];
1983 ivoice->cur_len = 0;
1984
1985 /* -------------------------------------------------------------------- */
1986 /* Allocate a scratch buffer for generating 10kHz samples. */
1987 /* -------------------------------------------------------------------- */
1988 ivoice->scratch = CALLOC(int16_t, SCBUF_SIZE);
1989 ivoice->sc_head = ivoice->sc_tail = 0;
1990
1991 if (!ivoice->scratch)
1992 return -1;
1993
1994 /* -------------------------------------------------------------------- */
1995 /* Set up the microsequencer's initial state. */
1996 /* -------------------------------------------------------------------- */
1997 iv_smp_stop(ivoice);
1998 ivoice->halted = 1;
1999 ivoice->filt.rpt = -1;
2000 ivoice->lrq = 0x8000;
2001 ivoice->page = 0x1000 << 3;
2002 ivoice->silent = 1;
2003
2004 /* -------------------------------------------------------------------- */
2005 /* Attempt to read SP0256 ROM files. This needs re-architecting if */
2006 /* you're going to have multiple SP0256's in a system, or use ROMs */
2007 /* from various places, but it'll do for the moment. */
2008 /* -------------------------------------------------------------------- */
2009 for (i = 0; i < 16; i++)
2010 if (ivoice_rdrom(ivoice, i))
2011 return -1;
2012
2013 /* -------------------------------------------------------------------- */
2014 /* If the user requested us to save samples, then set things up so */
2015 /* that that can happen. */
2016 /* -------------------------------------------------------------------- */
2017 if (smp_tname)
2018 {
2019 if ((ivoice->smp_tname = strdup(smp_tname)) != NULL)
2020 {
2021 if ((ivoice->smp_cname = CALLOC(char, strlen(smp_tname)+10))==NULL)
2022 {
2023 free(ivoice->smp_tname);
2024 ivoice->smp_tname = NULL;
2025 }
2026 }
2027 }
2028
2029 return 0;
2030 }
2031
2032
2033 /* ======================================================================== */
2034 /* This program is free software; you can redistribute it and/or modify */
2035 /* it under the terms of the GNU General Public License as published by */
2036 /* the Free Software Foundation; either version 2 of the License, or */
2037 /* (at your option) any later version. */
2038 /* */
2039 /* This program is distributed in the hope that it will be useful, */
2040 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
2041 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
2042 /* General Public License for more details. */
2043 /* */
2044 /* You should have received a copy of the GNU General Public License along */
2045 /* with this program; if not, write to the Free Software Foundation, Inc., */
2046 /* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2047 /* ======================================================================== */
2048 /* Copyright (c) 1998-2000, Joseph Zbiciak */
2049 /* ======================================================================== */
2050