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