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