1 /*
2    GI SP0256 Narrator Speech Processor
3    GI SPB640 Speech Buffer
4 
5    By Joe Zbiciak. Ported to MESS by tim lindner.
6 
7    Unimplemented:
8    - Microsequencer repeat count of zero
9    - Support for non bit-flipped ROMs
10    - SPB-640 perpherial/RAM bus
11 
12  Copyright Joseph Zbiciak, all rights reserved.
13  Copyright tim lindner, all rights reserved.
14 
15  - This source code is released as freeware for non-commercial purposes.
16  - You are free to use and redistribute this code in modified or
17    unmodified form, provided you list us in the credits.
18  - If you modify this source code, you must add a notice to each
19    modified source file that it has been changed.  If you're a nice
20    person, you will clearly mark each change too.  :)
21  - If you wish to use this for commercial purposes, please contact us at
22    intvnut@gmail.com (Joseph Zbiciak), tlindner@macmess.org (tim lindner)
23  - This entire notice must remain in the source code.
24 */
25 
26 #include "burnint.h"
27 #include "sp0256.h"
28 
29 #define READY_TIMER     (0x0010)
30 #define CLOCK_DIVIDER   (7*6*8)
31 #define HIGH_QUALITY
32 
33 #define SCBUF_SIZE      (4096)             /* Must be power of 2               */
34 #define SCBUF_MASK      (SCBUF_SIZE - 1)
35 #define PER_PAUSE       (64)               /* Equiv timing period for pauses.  */
36 #define PER_NOISE       (64)               /* Equiv timing period for noise.   */
37 
38 #define FIFO_ADDR       (0x1800 << 3)      /* address of SPB260 speech FIFO.   */
39 
40 #define VERBOSE 0
41 #define DEBUG_FIFO 0
42 
43 #define LOG(x)  do { if (VERBOSE) bprintf x; } while (0)
44 #define LOG_FIFO(x) do { if (DEBUG_FIFO) bprintf x; } while (0)
45 
46 #define SET_SBY(line_state) {       \
47 	if (m_sby_line != line_state)   \
48 	{                               \
49 		m_sby_line = line_state;    \
50 		m_sby_cb(m_sby_line);       \
51 	}                               \
52 }
53 
54 struct lpc12_t
55 {
56 	INT32   rpt, cnt;       /* Repeat counter, Period down-counter.         */
57 	UINT32  per, rng;       /* Period, Amplitude, Random Number Generator   */
58 	INT32   amp;
59 	INT16   f_coef[6];      /* F0 through F5.                               */
60 	INT16   b_coef[6];      /* B0 through B5.                               */
61 	INT16   z_data[6][2];   /* Time-delay data for the filter stages.       */
62 	UINT8   r[16];          /* The encoded register set.                    */
63 	INT32   interp;
64 };
65 
66 static void (*m_drq_cb)(UINT8) = NULL;
67 static void (*m_sby_cb)(UINT8) = NULL;
68 
null_callback_drq(UINT8 data)69 static void null_callback_drq(UINT8 data)
70 {
71 	//bprintf(0, _T("null callback drq: %X\n"), data);
72 }
73 
null_callback_sby(UINT8 data)74 static void null_callback_sby(UINT8 data)
75 {
76 	//bprintf(0, _T("null callback sby: %X\n"), data);
77 }
78 
sp0256_set_drq_cb(void (* cb)(UINT8))79 void sp0256_set_drq_cb(void (*cb)(UINT8))
80 {
81 	m_drq_cb = cb;
82 }
83 
sp0256_set_sby_cb(void (* cb)(UINT8))84 void sp0256_set_sby_cb(void (*cb)(UINT8))
85 {
86 	m_sby_cb = cb;
87 }
88 
89 // "re"sampler stuff
90 static INT32            samples_from;
91 static INT16            *mixer_buffer;
92 
93 static UINT8            *m_rom;            /* 64K ROM.                                     */
94 
95 static INT32            m_sby_line;        /* Standby line state                           */
96 static INT32            m_silent;          /* Flag: SP0256 is silent.                      */
97 
98 static INT16            *m_scratch;        /* Scratch buffer for audio.                    */
99 static UINT32           m_sc_head;         /* Head pointer into scratch circular buf       */
100 static UINT32           m_sc_tail;         /* Tail pointer into scratch circular buf       */
101 
102 static struct lpc12_t   m_filt;            /* 12-pole filter                               */
103 static INT32            m_lrq;             /* Load ReQuest.  == 0 if we can accept a load  */
104 static INT32            m_ald;             /* Address LoaD.  < 0 if no command pending.    */
105 static INT32            m_pc;              /* Microcontroller's PC value.                  */
106 static INT32            m_stack;           /* Microcontroller's PC stack.                  */
107 static INT32            m_fifo_sel;        /* True when executing from FIFO.               */
108 static INT32            m_halted;          /* True when CPU is halted.                     */
109 static UINT32           m_mode;            /* Mode register.                               */
110 static UINT32           m_page;            /* Page set by SETPAGE                          */
111 
112 static UINT32           m_fifo_head;       /* FIFO head pointer (where new data goes).     */
113 static UINT32           m_fifo_tail;       /* FIFO tail pointer (where data comes from).   */
114 static UINT32           m_fifo_bitp;       /* FIFO bit-pointer (for partial decles).       */
115 static UINT16           m_fifo[64];        /* The 64-decle FIFO.                           */
116 
117 
118 //-------------------------------------------------
119 //  device_start - device-specific startup
120 //-------------------------------------------------
sp0256_set_clock(INT32 clock)121 void sp0256_set_clock(INT32 clock)
122 {
123 	samples_from = (INT32)((double)(((clock / CLOCK_DIVIDER) * 100) / nBurnFPS) + 0.5);
124 }
125 
sp0256_scan(INT32 nAction,INT32 * pnMin)126 void sp0256_scan(INT32 nAction, INT32* pnMin)
127 {
128 	if (pnMin && *pnMin < 0x029521) {
129 		*pnMin = 0x029521;
130 	}
131 
132 	if (nAction & ACB_DRIVER_DATA) {
133 		ScanVar(m_scratch, SCBUF_SIZE * sizeof(INT16), "sp0256 ScratchRam");
134 
135 		SCAN_VAR(m_sby_line);
136 		SCAN_VAR(m_silent);
137 
138 		SCAN_VAR(m_sc_head);
139 		SCAN_VAR(m_sc_tail);
140 
141 		SCAN_VAR(m_filt);
142 		SCAN_VAR(m_lrq);
143 		SCAN_VAR(m_ald);
144 		SCAN_VAR(m_pc);
145 		SCAN_VAR(m_stack);
146 		SCAN_VAR(m_fifo_sel);
147 		SCAN_VAR(m_halted);
148 		SCAN_VAR(m_mode);
149 		SCAN_VAR(m_page);
150 
151 		SCAN_VAR(m_fifo_head);
152 		SCAN_VAR(m_fifo_tail);
153 		SCAN_VAR(m_fifo_bitp);
154 		SCAN_VAR(m_fifo);
155 	}
156 }
157 
sp0256_init(UINT8 * rom,INT32 clock)158 void sp0256_init(UINT8 *rom, INT32 clock)
159 {
160 	m_rom = rom;
161 
162 	sp0256_set_drq_cb(null_callback_drq);
163 	sp0256_set_sby_cb(null_callback_sby);
164 
165 	/* -------------------------------------------------------------------- */
166 	/*  Allocate a scratch buffer for generating ~10kHz samples.             */
167 	/* -------------------------------------------------------------------- */
168 	m_scratch = (INT16 *)BurnMalloc(SCBUF_SIZE * sizeof(INT16));
169 
170 	// Init Re-sampler buffer
171 	mixer_buffer = (INT16 *)BurnMalloc(nBurnSoundRate * sizeof(INT16));
172 	sp0256_set_clock(clock);
173 }
174 
sp0256_exit()175 void sp0256_exit()
176 {
177 	BurnFree(m_scratch);
178 	BurnFree(mixer_buffer);
179 }
180 
181 //-------------------------------------------------
182 //  device_reset - device-specific reset
183 //-------------------------------------------------
184 
sp0256_reset()185 void sp0256_reset()
186 {
187 	// reset FIFO and SP0256
188 	m_fifo_head = m_fifo_tail = m_fifo_bitp = 0;
189 	m_sc_head = m_sc_tail = 0;
190 
191 	memset(m_scratch, 0, SCBUF_SIZE * sizeof(INT16));
192 	memset(&m_filt, 0, sizeof(m_filt));
193 	memset(&m_fifo, 0, sizeof(m_fifo));
194 	m_halted   = 1;
195 	m_filt.rpt = -1;
196 	m_filt.rng = 1;
197 	m_lrq      = 0x0000;
198 	m_ald      = 0x0000;
199 	m_pc       = 0x0000;
200 	m_stack    = 0x0000;
201 	m_fifo_sel = 0;
202 	m_mode     = 0;
203 	m_page     = 0x1000 << 3;
204 	m_silent   = 1;
205 	m_sby_line = 1;
206 	//m_drq_cb(1);
207 	//SET_SBY(1)
208 }
209 
210 
211 /* ======================================================================== */
212 /*  LIMIT            -- Limiter function for digital sample output.         */
213 /* ======================================================================== */
limit(INT16 s)214 static INT16 limit(INT16 s)
215 {
216 #ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */
217 	if (s >  8191) return  8191;
218 	if (s < -8192) return -8192;
219 #else
220 	if (s >  127) return  127;
221 	if (s < -128) return -128;
222 #endif
223 	return s;
224 }
225 
226 /* ======================================================================== */
227 /*  LPC12_UPDATE     -- Update the 12-pole filter, outputting samples.      */
228 /* ======================================================================== */
lpc12_update(struct lpc12_t * f,INT32 num_samp,INT16 * out,UINT32 * optr)229 static INT32 lpc12_update(struct lpc12_t *f, INT32 num_samp, INT16 *out, UINT32 *optr)
230 {
231 	INT32 i, j;
232 	INT16 samp;
233 	INT32 do_int;
234 	INT32 oidx = *optr;
235 
236 	/* -------------------------------------------------------------------- */
237 	/*  Iterate up to the desired number of samples.  We actually may       */
238 	/*  break out early if our repeat count expires.                        */
239 	/* -------------------------------------------------------------------- */
240 	for (i = 0; i < num_samp; i++)
241 	{
242 		/* ---------------------------------------------------------------- */
243 		/*  Generate a series of periodic impulses, or random noise.        */
244 		/* ---------------------------------------------------------------- */
245 		do_int = 0;
246 		samp   = 0;
247 		if (f->per)
248 		{
249 			if (f->cnt <= 0)
250 			{
251 				f->cnt += f->per;
252 				samp    = f->amp;
253 				f->rpt--;
254 				do_int  = f->interp;
255 
256 				for (j = 0; j < 6; j++)
257 					f->z_data[j][1] = f->z_data[j][0] = 0;
258 
259 			} else
260 			{
261 				samp = 0;
262 				f->cnt--;
263 			}
264 
265 		} else
266 		{
267 			INT32 bit;
268 
269 			if (--f->cnt <= 0)
270 			{
271 				do_int = f->interp;
272 				f->cnt = PER_NOISE;
273 				f->rpt--;
274 				for (j = 0; j < 6; j++)
275 					f->z_data[j][0] = f->z_data[j][1] = 0;
276 			}
277 
278 			bit = f->rng & 1;
279 			f->rng = (f->rng >> 1) ^ (bit ? 0x4001 : 0);
280 
281 			if (bit) { samp =  f->amp; }
282 			else     { samp = -f->amp; }
283 		}
284 
285 		/* ---------------------------------------------------------------- */
286 		/*  If we need to, process the interpolation registers.             */
287 		/* ---------------------------------------------------------------- */
288 		if (do_int)
289 		{
290 			f->r[0] += f->r[14];
291 			f->r[1] += f->r[15];
292 
293 			f->amp   = (f->r[0] & 0x1F) << (((f->r[0] & 0xE0) >> 5) + 0);
294 			f->per   = f->r[1];
295 		}
296 
297 		/* ---------------------------------------------------------------- */
298 		/*  Stop if we expire our repeat counter and return the actual      */
299 		/*  number of samples we did.                                       */
300 		/* ---------------------------------------------------------------- */
301 		if (f->rpt <= 0) break;
302 
303 		/* ---------------------------------------------------------------- */
304 		/*  Each 2nd order stage looks like one of these.  The App. Manual  */
305 		/*  gives the first form, the patent gives the second form.         */
306 		/*  They're equivalent except for time delay.  I implement the      */
307 		/*  first form.   (Note: 1/Z == 1 unit of time delay.)              */
308 		/*                                                                  */
309 		/*          ---->(+)-------->(+)----------+------->                 */
310 		/*                ^           ^           |                         */
311 		/*                |           |           |                         */
312 		/*                |           |           |                         */
313 		/*               [B]        [2*F]         |                         */
314 		/*                ^           ^           |                         */
315 		/*                |           |           |                         */
316 		/*                |           |           |                         */
317 		/*                +---[1/Z]<--+---[1/Z]<--+                         */
318 		/*                                                                  */
319 		/*                                                                  */
320 		/*                +---[2*F]<---+                                    */
321 		/*                |            |                                    */
322 		/*                |            |                                    */
323 		/*                v            |                                    */
324 		/*          ---->(+)-->[1/Z]-->+-->[1/Z]---+------>                 */
325 		/*                ^                        |                        */
326 		/*                |                        |                        */
327 		/*                |                        |                        */
328 		/*                +-----------[B]<---------+                        */
329 		/*                                                                  */
330 		/* ---------------------------------------------------------------- */
331 		for (j = 0; j < 6; j++)
332 		{
333 			samp += (((int)f->b_coef[j] * (int)f->z_data[j][1]) >> 9);
334 			samp += (((int)f->f_coef[j] * (int)f->z_data[j][0]) >> 8);
335 
336 			f->z_data[j][1] = f->z_data[j][0];
337 			f->z_data[j][0] = samp;
338 		}
339 
340 #ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */
341 		out[oidx++ & SCBUF_MASK] = limit(samp) << 2;
342 #else
343 		out[oidx++ & SCBUF_MASK] = (limit(samp >> 4) << 8);
344 #endif
345 	}
346 
347 	*optr = oidx;
348 
349 	return i;
350 }
351 
352 /* ======================================================================== */
353 /*  LPC12_REGDEC -- Decode the register set in the filter bank.             */
354 /* ======================================================================== */
lpc12_regdec(struct lpc12_t * f)355 static void lpc12_regdec(struct lpc12_t *f)
356 {
357 	/* ======================================================================== */
358 	/*  qtbl  -- Coefficient Quantization Table.  This comes from a             */
359 	/*              SP0250 data sheet, and should be correct for SP0256.        */
360 	/* ======================================================================== */
361 	static const INT16 qtbl[128] =
362 	{
363 		0,      9,      17,     25,     33,     41,     49,     57,
364 		65,     73,     81,     89,     97,     105,    113,    121,
365 		129,    137,    145,    153,    161,    169,    177,    185,
366 		193,    201,    209,    217,    225,    233,    241,    249,
367 		257,    265,    273,    281,    289,    297,    301,    305,
368 		309,    313,    317,    321,    325,    329,    333,    337,
369 		341,    345,    349,    353,    357,    361,    365,    369,
370 		373,    377,    381,    385,    389,    393,    397,    401,
371 		405,    409,    413,    417,    421,    425,    427,    429,
372 		431,    433,    435,    437,    439,    441,    443,    445,
373 		447,    449,    451,    453,    455,    457,    459,    461,
374 		463,    465,    467,    469,    471,    473,    475,    477,
375 		479,    481,    482,    483,    484,    485,    486,    487,
376 		488,    489,    490,    491,    492,    493,    494,    495,
377 		496,    497,    498,    499,    500,    501,    502,    503,
378 		504,    505,    506,    507,    508,    509,    510,    511
379 	};
380 
381 	/* -------------------------------------------------------------------- */
382 	/*  Decode the Amplitude and Period registers.  Force the 'cnt' to 0    */
383 	/*  to get an initial impulse.  We compensate elsewhere by setting      */
384 	/*  the repeat count to "repeat + 1".                                   */
385 	/* -------------------------------------------------------------------- */
386 	f->amp = (f->r[0] & 0x1F) << (((f->r[0] & 0xE0) >> 5) + 0);
387 	f->cnt = 0;
388 	f->per = f->r[1];
389 
390 	/* -------------------------------------------------------------------- */
391 	/*  Decode the filter coefficients from the quant table.                */
392 	/* -------------------------------------------------------------------- */
393 	for (INT32 i = 0; i < 6; i++)
394 	{
395 		#define IQ(x) (((x) & 0x80) ? qtbl[0x7F & -(x)] : -qtbl[(x)])
396 
397 		f->b_coef[i] = IQ(f->r[2 + 2*i]);
398 		f->f_coef[i] = IQ(f->r[3 + 2*i]);
399 	}
400 
401 	/* -------------------------------------------------------------------- */
402 	/*  Set the Interp flag based on whether we have interpolation parms    */
403 	/* -------------------------------------------------------------------- */
404 	f->interp = f->r[14] || f->r[15];
405 
406 	return;
407 }
408 
409 /* ======================================================================== */
410 /*  SP0256_DATAFMT   -- Data format table for the SP0256's microsequencer   */
411 /*                                                                          */
412 /*  len     4 bits      Length of field to extract                          */
413 /*  lshift  4 bits      Left-shift amount on field                          */
414 /*  param   4 bits      Parameter number being updated                      */
415 /*  delta   1 bit       This is a delta-update.  (Implies sign-extend)      */
416 /*  field   1 bit       This is a field replace.                            */
417 /*  clr5    1 bit       Clear F5, B5.                                       */
418 /*  clrall  1 bit       Clear all before doing this update                  */
419 /* ======================================================================== */
420 
421 #define CR(l,s,p,d,f,c5,ca)         \
422 		(                           \
423 			(((l)  & 15) <<  0) |   \
424 			(((s)  & 15) <<  4) |   \
425 			(((p)  & 15) <<  8) |   \
426 			(((d)  &  1) << 12) |   \
427 			(((f)  &  1) << 13) |   \
428 			(((c5) &  1) << 14) |   \
429 			(((ca) &  1) << 15)     \
430 		)
431 
432 #define CR_DELTA  CR(0,0,0,1,0,0,0)
433 #define CR_FIELD  CR(0,0,0,0,1,0,0)
434 #define CR_CLR5   CR(0,0,0,0,0,1,0)
435 #define CR_CLRA   CR(0,0,0,0,0,0,1)
436 #define CR_LEN(x) ((x) & 15)
437 #define CR_SHF(x) (((x) >> 4) & 15)
438 #define CR_PRM(x) (((x) >> 8) & 15)
439 
440 enum { AM = 0, PR, B0, F0, B1, F1, B2, F2, B3, F3, B4, F4, B5, F5, IA, IP };
441 
442 static const UINT16 sp0256_datafmt[] =
443 {
444 	/* -------------------------------------------------------------------- */
445 	/*  OPCODE 1111: PAUSE                                                  */
446 	/* -------------------------------------------------------------------- */
447 	/*    0 */  CR( 0,  0,  0,  0,  0,  0,  1),     /*  Clear all   */
448 
449 	/* -------------------------------------------------------------------- */
450 	/*  Opcode 0001: LOADALL                                                */
451 	/* -------------------------------------------------------------------- */
452 				/* All modes                */
453 	/*    1 */  CR( 8,  0,  AM, 0,  0,  0,  1),     /*  Amplitude   */
454 	/*    2 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
455 	/*    3 */  CR( 8,  0,  B0, 0,  0,  0,  0),     /*  B0          */
456 	/*    4 */  CR( 8,  0,  F0, 0,  0,  0,  0),     /*  F0          */
457 	/*    5 */  CR( 8,  0,  B1, 0,  0,  0,  0),     /*  B1          */
458 	/*    6 */  CR( 8,  0,  F1, 0,  0,  0,  0),     /*  F1          */
459 	/*    7 */  CR( 8,  0,  B2, 0,  0,  0,  0),     /*  B2          */
460 	/*    8 */  CR( 8,  0,  F2, 0,  0,  0,  0),     /*  F2          */
461 	/*    9 */  CR( 8,  0,  B3, 0,  0,  0,  0),     /*  B3          */
462 	/*   10 */  CR( 8,  0,  F3, 0,  0,  0,  0),     /*  F3          */
463 	/*   11 */  CR( 8,  0,  B4, 0,  0,  0,  0),     /*  B4          */
464 	/*   12 */  CR( 8,  0,  F4, 0,  0,  0,  0),     /*  F4          */
465 	/*   13 */  CR( 8,  0,  B5, 0,  0,  0,  0),     /*  B5          */
466 	/*   14 */  CR( 8,  0,  F5, 0,  0,  0,  0),     /*  F5          */
467 				/* Mode 01 and 11 only      */
468 	/*   15 */  CR( 8,  0,  IA, 0,  0,  0,  0),     /*  Amp Interp  */
469 	/*   16 */  CR( 8,  0,  IP, 0,  0,  0,  0),     /*  Pit Interp  */
470 
471 	/* -------------------------------------------------------------------- */
472 	/*  Opcode 0100: LOAD_4                                                 */
473 	/* -------------------------------------------------------------------- */
474 				/* Mode 00 and 01           */
475 	/*   17 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
476 	/*   18 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
477 	/*   19 */  CR( 4,  3,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
478 	/*   20 */  CR( 6,  2,  F3, 0,  0,  0,  0),     /*  F3          */
479 	/*   21 */  CR( 7,  1,  B4, 0,  0,  0,  0),     /*  B4          */
480 	/*   22 */  CR( 6,  2,  F4, 0,  0,  0,  0),     /*  F4          */
481 				/* Mode 01 only             */
482 	/*   23 */  CR( 8,  0,  B5, 0,  0,  0,  0),     /*  B5          */
483 	/*   24 */  CR( 8,  0,  F5, 0,  0,  0,  0),     /*  F5          */
484 
485 				/* Mode 10 and 11           */
486 	/*   25 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
487 	/*   26 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
488 	/*   27 */  CR( 6,  1,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
489 	/*   28 */  CR( 7,  1,  F3, 0,  0,  0,  0),     /*  F3          */
490 	/*   29 */  CR( 8,  0,  B4, 0,  0,  0,  0),     /*  B4          */
491 	/*   30 */  CR( 8,  0,  F4, 0,  0,  0,  0),     /*  F4          */
492 				/* Mode 11 only             */
493 	/*   31 */  CR( 8,  0,  B5, 0,  0,  0,  0),     /*  B5          */
494 	/*   32 */  CR( 8,  0,  F5, 0,  0,  0,  0),     /*  F5          */
495 
496 	/* -------------------------------------------------------------------- */
497 	/*  Opcode 0110: SETMSB_6                                               */
498 	/* -------------------------------------------------------------------- */
499 				/* Mode 00 only             */
500 	/*   33 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
501 				/* Mode 00 and 01           */
502 	/*   34 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
503 	/*   35 */  CR( 6,  2,  F3, 0,  1,  0,  0),     /*  F3 (5 MSBs) */
504 	/*   36 */  CR( 6,  2,  F4, 0,  1,  0,  0),     /*  F4 (5 MSBs) */
505 				/* Mode 01 only             */
506 	/*   37 */  CR( 8,  0,  F5, 0,  1,  0,  0),     /*  F5 (5 MSBs) */
507 
508 				/* Mode 10 only             */
509 	/*   38 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
510 				/* Mode 10 and 11           */
511 	/*   39 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
512 	/*   40 */  CR( 7,  1,  F3, 0,  1,  0,  0),     /*  F3 (6 MSBs) */
513 	/*   41 */  CR( 8,  0,  F4, 0,  1,  0,  0),     /*  F4 (6 MSBs) */
514 				/* Mode 11 only             */
515 	/*   42 */  CR( 8,  0,  F5, 0,  1,  0,  0),     /*  F5 (6 MSBs) */
516 
517 	/*   43 */  0,  /* unused */
518 	/*   44 */  0,  /* unused */
519 
520 	/* -------------------------------------------------------------------- */
521 	/*  Opcode 1001: DELTA_9                                                */
522 	/* -------------------------------------------------------------------- */
523 				/* Mode 00 and 01           */
524 	/*   45 */  CR( 4,  2,  AM, 1,  0,  0,  0),     /*  Amplitude   */
525 	/*   46 */  CR( 5,  0,  PR, 1,  0,  0,  0),     /*  Period      */
526 	/*   47 */  CR( 3,  4,  B0, 1,  0,  0,  0),     /*  B0 4 MSBs   */
527 	/*   48 */  CR( 3,  3,  F0, 1,  0,  0,  0),     /*  F0 5 MSBs   */
528 	/*   49 */  CR( 3,  4,  B1, 1,  0,  0,  0),     /*  B1 4 MSBs   */
529 	/*   50 */  CR( 3,  3,  F1, 1,  0,  0,  0),     /*  F1 5 MSBs   */
530 	/*   51 */  CR( 3,  4,  B2, 1,  0,  0,  0),     /*  B2 4 MSBs   */
531 	/*   52 */  CR( 3,  3,  F2, 1,  0,  0,  0),     /*  F2 5 MSBs   */
532 	/*   53 */  CR( 3,  3,  B3, 1,  0,  0,  0),     /*  B3 5 MSBs   */
533 	/*   54 */  CR( 4,  2,  F3, 1,  0,  0,  0),     /*  F3 6 MSBs   */
534 	/*   55 */  CR( 4,  1,  B4, 1,  0,  0,  0),     /*  B4 7 MSBs   */
535 	/*   56 */  CR( 4,  2,  F4, 1,  0,  0,  0),     /*  F4 6 MSBs   */
536 				/* Mode 01 only             */
537 	/*   57 */  CR( 5,  0,  B5, 1,  0,  0,  0),     /*  B5 8 MSBs   */
538 	/*   58 */  CR( 5,  0,  F5, 1,  0,  0,  0),     /*  F5 8 MSBs   */
539 
540 				/* Mode 10 and 11           */
541 	/*   59 */  CR( 4,  2,  AM, 1,  0,  0,  0),     /*  Amplitude   */
542 	/*   60 */  CR( 5,  0,  PR, 1,  0,  0,  0),     /*  Period      */
543 	/*   61 */  CR( 4,  1,  B0, 1,  0,  0,  0),     /*  B0 7 MSBs   */
544 	/*   62 */  CR( 4,  2,  F0, 1,  0,  0,  0),     /*  F0 6 MSBs   */
545 	/*   63 */  CR( 4,  1,  B1, 1,  0,  0,  0),     /*  B1 7 MSBs   */
546 	/*   64 */  CR( 4,  2,  F1, 1,  0,  0,  0),     /*  F1 6 MSBs   */
547 	/*   65 */  CR( 4,  1,  B2, 1,  0,  0,  0),     /*  B2 7 MSBs   */
548 	/*   66 */  CR( 4,  2,  F2, 1,  0,  0,  0),     /*  F2 6 MSBs   */
549 	/*   67 */  CR( 4,  1,  B3, 1,  0,  0,  0),     /*  B3 7 MSBs   */
550 	/*   68 */  CR( 5,  1,  F3, 1,  0,  0,  0),     /*  F3 7 MSBs   */
551 	/*   69 */  CR( 5,  0,  B4, 1,  0,  0,  0),     /*  B4 8 MSBs   */
552 	/*   70 */  CR( 5,  0,  F4, 1,  0,  0,  0),     /*  F4 8 MSBs   */
553 				/* Mode 11 only             */
554 	/*   71 */  CR( 5,  0,  B5, 1,  0,  0,  0),     /*  B5 8 MSBs   */
555 	/*   72 */  CR( 5,  0,  F5, 1,  0,  0,  0),     /*  F5 8 MSBs   */
556 
557 	/* -------------------------------------------------------------------- */
558 	/*  Opcode 1010: SETMSB_A                                               */
559 	/* -------------------------------------------------------------------- */
560 				/* Mode 00 only             */
561 	/*   73 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
562 				/* Mode 00 and 01           */
563 	/*   74 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
564 	/*   75 */  CR( 5,  3,  F0, 0,  1,  0,  0),     /*  F0 (5 MSBs) */
565 	/*   76 */  CR( 5,  3,  F1, 0,  1,  0,  0),     /*  F1 (5 MSBs) */
566 	/*   77 */  CR( 5,  3,  F2, 0,  1,  0,  0),     /*  F2 (5 MSBs) */
567 
568 				/* Mode 10 only             */
569 	/*   78 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
570 				/* Mode 10 and 11           */
571 	/*   79 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
572 	/*   80 */  CR( 6,  2,  F0, 0,  1,  0,  0),     /*  F0 (6 MSBs) */
573 	/*   81 */  CR( 6,  2,  F1, 0,  1,  0,  0),     /*  F1 (6 MSBs) */
574 	/*   82 */  CR( 6,  2,  F2, 0,  1,  0,  0),     /*  F2 (6 MSBs) */
575 
576 	/* -------------------------------------------------------------------- */
577 	/*  Opcode 0010: LOAD_2  Mode 00 and 10                                 */
578 	/*  Opcode 1100: LOAD_C  Mode 00 and 10                                 */
579 	/* -------------------------------------------------------------------- */
580 				/* LOAD_2, LOAD_C  Mode 00  */
581 	/*   83 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
582 	/*   84 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
583 	/*   85 */  CR( 3,  4,  B0, 0,  0,  0,  0),     /*  B0 (S=0)    */
584 	/*   86 */  CR( 5,  3,  F0, 0,  0,  0,  0),     /*  F0          */
585 	/*   87 */  CR( 3,  4,  B1, 0,  0,  0,  0),     /*  B1 (S=0)    */
586 	/*   88 */  CR( 5,  3,  F1, 0,  0,  0,  0),     /*  F1          */
587 	/*   89 */  CR( 3,  4,  B2, 0,  0,  0,  0),     /*  B2 (S=0)    */
588 	/*   90 */  CR( 5,  3,  F2, 0,  0,  0,  0),     /*  F2          */
589 	/*   91 */  CR( 4,  3,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
590 	/*   92 */  CR( 6,  2,  F3, 0,  0,  0,  0),     /*  F3          */
591 	/*   93 */  CR( 7,  1,  B4, 0,  0,  0,  0),     /*  B4          */
592 	/*   94 */  CR( 6,  2,  F4, 0,  0,  0,  0),     /*  F4          */
593 				/* LOAD_2 only              */
594 	/*   95 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
595 	/*   96 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
596 
597 				/* LOAD_2, LOAD_C  Mode 10  */
598 	/*   97 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
599 	/*   98 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
600 	/*   99 */  CR( 6,  1,  B0, 0,  0,  0,  0),     /*  B0 (S=0)    */
601 	/*  100 */  CR( 6,  2,  F0, 0,  0,  0,  0),     /*  F0          */
602 	/*  101 */  CR( 6,  1,  B1, 0,  0,  0,  0),     /*  B1 (S=0)    */
603 	/*  102 */  CR( 6,  2,  F1, 0,  0,  0,  0),     /*  F1          */
604 	/*  103 */  CR( 6,  1,  B2, 0,  0,  0,  0),     /*  B2 (S=0)    */
605 	/*  104 */  CR( 6,  2,  F2, 0,  0,  0,  0),     /*  F2          */
606 	/*  105 */  CR( 6,  1,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
607 	/*  106 */  CR( 7,  1,  F3, 0,  0,  0,  0),     /*  F3          */
608 	/*  107 */  CR( 8,  0,  B4, 0,  0,  0,  0),     /*  B4          */
609 	/*  108 */  CR( 8,  0,  F4, 0,  0,  0,  0),     /*  F4          */
610 				/* LOAD_2 only              */
611 	/*  109 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
612 	/*  110 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
613 
614 	/* -------------------------------------------------------------------- */
615 	/*  OPCODE 1101: DELTA_D                                                */
616 	/* -------------------------------------------------------------------- */
617 				/* Mode 00 and 01           */
618 	/*  111 */  CR( 4,  2,  AM, 1,  0,  0,  0),     /*  Amplitude   */
619 	/*  112 */  CR( 5,  0,  PR, 1,  0,  0,  0),     /*  Period      */
620 	/*  113 */  CR( 3,  3,  B3, 1,  0,  0,  0),     /*  B3 5 MSBs   */
621 	/*  114 */  CR( 4,  2,  F3, 1,  0,  0,  0),     /*  F3 6 MSBs   */
622 	/*  115 */  CR( 4,  1,  B4, 1,  0,  0,  0),     /*  B4 7 MSBs   */
623 	/*  116 */  CR( 4,  2,  F4, 1,  0,  0,  0),     /*  F4 6 MSBs   */
624 				/* Mode 01 only             */
625 	/*  117 */  CR( 5,  0,  B5, 1,  0,  0,  0),     /*  B5 8 MSBs   */
626 	/*  118 */  CR( 5,  0,  F5, 1,  0,  0,  0),     /*  F5 8 MSBs   */
627 
628 				/* Mode 10 and 11           */
629 	/*  119 */  CR( 4,  2,  AM, 1,  0,  0,  0),     /*  Amplitude   */
630 	/*  120 */  CR( 5,  0,  PR, 1,  0,  0,  0),     /*  Period      */
631 	/*  121 */  CR( 4,  1,  B3, 1,  0,  0,  0),     /*  B3 7 MSBs   */
632 	/*  122 */  CR( 5,  1,  F3, 1,  0,  0,  0),     /*  F3 7 MSBs   */
633 	/*  123 */  CR( 5,  0,  B4, 1,  0,  0,  0),     /*  B4 8 MSBs   */
634 	/*  124 */  CR( 5,  0,  F4, 1,  0,  0,  0),     /*  F4 8 MSBs   */
635 				/* Mode 11 only             */
636 	/*  125 */  CR( 5,  0,  B5, 1,  0,  0,  0),     /*  B5 8 MSBs   */
637 	/*  126 */  CR( 5,  0,  F5, 1,  0,  0,  0),     /*  F5 8 MSBs   */
638 
639 	/* -------------------------------------------------------------------- */
640 	/*  OPCODE 1110: LOAD_E                                                 */
641 	/* -------------------------------------------------------------------- */
642 	/*  127 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
643 	/*  128 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
644 
645 	/* -------------------------------------------------------------------- */
646 	/*  Opcode 0010: LOAD_2  Mode 01 and 11                                 */
647 	/*  Opcode 1100: LOAD_C  Mode 01 and 11                                 */
648 	/* -------------------------------------------------------------------- */
649 				/* LOAD_2, LOAD_C  Mode 01  */
650 	/*  129 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
651 	/*  130 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
652 	/*  131 */  CR( 3,  4,  B0, 0,  0,  0,  0),     /*  B0 (S=0)    */
653 	/*  132 */  CR( 5,  3,  F0, 0,  0,  0,  0),     /*  F0          */
654 	/*  133 */  CR( 3,  4,  B1, 0,  0,  0,  0),     /*  B1 (S=0)    */
655 	/*  134 */  CR( 5,  3,  F1, 0,  0,  0,  0),     /*  F1          */
656 	/*  135 */  CR( 3,  4,  B2, 0,  0,  0,  0),     /*  B2 (S=0)    */
657 	/*  136 */  CR( 5,  3,  F2, 0,  0,  0,  0),     /*  F2          */
658 	/*  137 */  CR( 4,  3,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
659 	/*  138 */  CR( 6,  2,  F3, 0,  0,  0,  0),     /*  F3          */
660 	/*  139 */  CR( 7,  1,  B4, 0,  0,  0,  0),     /*  B4          */
661 	/*  140 */  CR( 6,  2,  F4, 0,  0,  0,  0),     /*  F4          */
662 	/*  141 */  CR( 8,  0,  B5, 0,  0,  0,  0),     /*  B5          */
663 	/*  142 */  CR( 8,  0,  F5, 0,  0,  0,  0),     /*  F5          */
664 				/* LOAD_2 only              */
665 	/*  143 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
666 	/*  144 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
667 
668 				/* LOAD_2, LOAD_C  Mode 11  */
669 	/*  145 */  CR( 6,  2,  AM, 0,  0,  0,  1),     /*  Amplitude   */
670 	/*  146 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
671 	/*  147 */  CR( 6,  1,  B0, 0,  0,  0,  0),     /*  B0 (S=0)    */
672 	/*  148 */  CR( 6,  2,  F0, 0,  0,  0,  0),     /*  F0          */
673 	/*  149 */  CR( 6,  1,  B1, 0,  0,  0,  0),     /*  B1 (S=0)    */
674 	/*  150 */  CR( 6,  2,  F1, 0,  0,  0,  0),     /*  F1          */
675 	/*  151 */  CR( 6,  1,  B2, 0,  0,  0,  0),     /*  B2 (S=0)    */
676 	/*  152 */  CR( 6,  2,  F2, 0,  0,  0,  0),     /*  F2          */
677 	/*  153 */  CR( 6,  1,  B3, 0,  0,  0,  0),     /*  B3 (S=0)    */
678 	/*  154 */  CR( 7,  1,  F3, 0,  0,  0,  0),     /*  F3          */
679 	/*  155 */  CR( 8,  0,  B4, 0,  0,  0,  0),     /*  B4          */
680 	/*  156 */  CR( 8,  0,  F4, 0,  0,  0,  0),     /*  F4          */
681 	/*  157 */  CR( 8,  0,  B5, 0,  0,  0,  0),     /*  B5          */
682 	/*  158 */  CR( 8,  0,  F5, 0,  0,  0,  0),     /*  F5          */
683 				/* LOAD_2 only              */
684 	/*  159 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
685 	/*  160 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
686 
687 	/* -------------------------------------------------------------------- */
688 	/*  Opcode 0011: SETMSB_3                                               */
689 	/*  Opcode 0101: SETMSB_5                                               */
690 	/* -------------------------------------------------------------------- */
691 				/* Mode 00 only             */
692 	/*  161 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
693 				/* Mode 00 and 01           */
694 	/*  162 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
695 	/*  163 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
696 	/*  164 */  CR( 5,  3,  F0, 0,  1,  0,  0),     /*  F0 (5 MSBs) */
697 	/*  165 */  CR( 5,  3,  F1, 0,  1,  0,  0),     /*  F1 (5 MSBs) */
698 	/*  166 */  CR( 5,  3,  F2, 0,  1,  0,  0),     /*  F2 (5 MSBs) */
699 				/* SETMSB_3 only            */
700 	/*  167 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
701 	/*  168 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
702 
703 				/* Mode 10 only             */
704 	/*  169 */  CR( 0,  0,  0,  0,  0,  1,  0),     /*  Clear 5     */
705 				/* Mode 10 and 11           */
706 	/*  170 */  CR( 6,  2,  AM, 0,  0,  0,  0),     /*  Amplitude   */
707 	/*  171 */  CR( 8,  0,  PR, 0,  0,  0,  0),     /*  Period      */
708 	/*  172 */  CR( 6,  2,  F0, 0,  1,  0,  0),     /*  F0 (6 MSBs) */
709 	/*  173 */  CR( 6,  2,  F1, 0,  1,  0,  0),     /*  F1 (6 MSBs) */
710 	/*  174 */  CR( 6,  2,  F2, 0,  1,  0,  0),     /*  F2 (6 MSBs) */
711 				/* SETMSB_3 only            */
712 	/*  175 */  CR( 5,  0,  IA, 0,  0,  0,  0),     /*  Ampl. Intr. */
713 	/*  176 */  CR( 5,  0,  IP, 0,  0,  0,  0),     /*  Per. Intr.  */
714 };
715 
716 static const INT16 sp0256_df_idx[16 * 8] =
717 {
718 	/*  OPCODE 0000 */      -1, -1,     -1, -1,     -1, -1,     -1, -1,
719 	/*  OPCODE 1000 */      -1, -1,     -1, -1,     -1, -1,     -1, -1,
720 	/*  OPCODE 0100 */      17, 22,     17, 24,     25, 30,     25, 32,
721 	/*  OPCODE 1100 */      83, 94,     129,142,    97, 108,    145,158,
722 	/*  OPCODE 0010 */      83, 96,     129,144,    97, 110,    145,160,
723 	/*  OPCODE 1010 */      73, 77,     74, 77,     78, 82,     79, 82,
724 	/*  OPCODE 0110 */      33, 36,     34, 37,     38, 41,     39, 42,
725 	/*  OPCODE 1110 */      127,128,    127,128,    127,128,    127,128,
726 	/*  OPCODE 0001 */      1,  14,     1,  16,     1,  14,     1,  16,
727 	/*  OPCODE 1001 */      45, 56,     45, 58,     59, 70,     59, 72,
728 	/*  OPCODE 0101 */      161,166,    162,166,    169,174,    170,174,
729 	/*  OPCODE 1101 */      111,116,    111,118,    119,124,    119,126,
730 	/*  OPCODE 0011 */      161,168,    162,168,    169,176,    170,176,
731 	/*  OPCODE 1011 */      -1, -1,     -1, -1,     -1, -1,     -1, -1,
732 	/*  OPCODE 0111 */      -1, -1,     -1, -1,     -1, -1,     -1, -1,
733 	/*  OPCODE 1111 */      0,  0,      0,  0,      0,  0,      0,  0
734 };
735 
736 /* ======================================================================== */
737 /*  BITREV32       -- Bit-reverse a 32-bit number.                            */
738 /* ======================================================================== */
bitrev32(UINT32 val)739 static UINT32 bitrev32(UINT32 val)
740 {
741 	val = ((val & 0xFFFF0000) >> 16) | ((val & 0x0000FFFF) << 16);
742 	val = ((val & 0xFF00FF00) >>  8) | ((val & 0x00FF00FF) <<  8);
743 	val = ((val & 0xF0F0F0F0) >>  4) | ((val & 0x0F0F0F0F) <<  4);
744 	val = ((val & 0xCCCCCCCC) >>  2) | ((val & 0x33333333) <<  2);
745 	val = ((val & 0xAAAAAAAA) >>  1) | ((val & 0x55555555) <<  1);
746 
747 	return val;
748 }
749 
750 #if 0
751 /* ======================================================================== */
752 /*  BITREV8       -- Bit-reverse a 8-bit number.                            */
753 /* ======================================================================== */
754 static UINT8 bitrev8(UINT8 val)
755 {
756 	val = ((val & 0xF0) >>  4) | ((val & 0x0F) <<  4);
757 	val = ((val & 0xCC) >>  2) | ((val & 0x33) <<  2);
758 	val = ((val & 0xAA) >>  1) | ((val & 0x55) <<  1);
759 
760 	return val;
761 }
762 
763 /* ======================================================================== */
764 /*  BITREVBUFF       -- Bit-reverse a buffer.                               */
765 /* ======================================================================== */
766 void bitrevbuff(UINT8 *buffer, UINT32 start, UINT32 length)
767 {
768 	for (UINT32 i = start; i < length; i++ )
769 		buffer[i] = bitrev8(buffer[i]);
770 }
771 #endif
772 
773 /* ======================================================================== */
774 /*  SP0256_GETB  -- Get up to 8 bits at the current PC.                     */
775 /* ======================================================================== */
getb(INT32 len)776 static UINT32 getb( INT32 len )
777 {
778 	UINT32 data = 0;
779 
780 	/* -------------------------------------------------------------------- */
781 	/*  Fetch data from the FIFO or from the MASK                           */
782 	/* -------------------------------------------------------------------- */
783 	if (m_fifo_sel)
784 	{
785 		UINT32 d0, d1;
786 		d0 = m_fifo[(m_fifo_tail    ) & 63];
787 		d1 = m_fifo[(m_fifo_tail + 1) & 63];
788 
789 		data = ((d1 << 10) | d0) >> m_fifo_bitp;
790 
791 		LOG_FIFO((0, _T("sp0256: RD_FIFO %.3X %d.%d %d\n"), data & ((1 << len) - 1),
792 				m_fifo_tail, m_fifo_bitp, m_fifo_head));
793 
794 		/* ---------------------------------------------------------------- */
795 		/*  Note the PC doesn't advance when we execute from FIFO.          */
796 		/*  Just the FIFO's bit-pointer advances.   (That's not REALLY      */
797 		/*  what happens, but that's roughly how it behaves.)               */
798 		/* ---------------------------------------------------------------- */
799 		m_fifo_bitp += len;
800 		if (m_fifo_bitp >= 10)
801 		{
802 			m_fifo_tail++;
803 			m_fifo_bitp -= 10;
804 		}
805 	} else
806 	{
807 		/* ---------------------------------------------------------------- */
808 		/*  Figure out which ROMs are being fetched into, and grab two      */
809 		/*  adjacent bytes.  The byte we're interested in is extracted      */
810 		/*  from the appropriate bit-boundary between them.                 */
811 		/* ---------------------------------------------------------------- */
812 		INT32 idx0 = (m_pc    ) >> 3, d0;
813 		INT32 idx1 = (m_pc + 8) >> 3, d1;
814 
815 		d0 = m_rom[idx0 & 0xffff];
816 		d1 = m_rom[idx1 & 0xffff];
817 
818 		data = ((d1 << 8) | d0) >> (m_pc & 7);
819 
820 		m_pc += len;
821 	}
822 
823 	/* -------------------------------------------------------------------- */
824 	/*  Mask data to the requested length.                                  */
825 	/* -------------------------------------------------------------------- */
826 	data &= ((1 << len) - 1);
827 
828 	return data;
829 }
830 
831 /* ======================================================================== */
832 /*  SP0256_MICRO -- Emulate the microsequencer in the SP0256.  Executes     */
833 /*                  instructions either until the repeat count != 0 or      */
834 /*                  the sequencer gets halted by a RTS to 0.                */
835 /* ======================================================================== */
micro()836 static void micro()
837 {
838 	UINT8  immed4;
839 	UINT8  opcode;
840 	UINT16 cr;
841 	INT32 ctrl_xfer = 0;
842 	INT32 repeat    = 0;
843 	INT32 i, idx0, idx1;
844 
845 	/* -------------------------------------------------------------------- */
846 	/*  Only execute instructions while the filter is not busy.             */
847 	/* -------------------------------------------------------------------- */
848 	while (m_filt.rpt <= 0)
849 	{
850 		/* ---------------------------------------------------------------- */
851 		/*  If the CPU is halted, see if we have a new command pending      */
852 		/*  in the Address LoaD buffer.                                     */
853 		/* ---------------------------------------------------------------- */
854 		if (m_halted && !m_lrq)
855 		{
856 			m_pc       = m_ald | (0x1000 << 3);
857 			m_fifo_sel = 0;
858 			m_halted   = 0;
859 			m_lrq      = 0x8000;
860 			m_ald      = 0;
861 			for (i = 0; i < 16; i++)
862 				m_filt.r[i] = 0;
863 			m_drq_cb(1);
864 		}
865 
866 		/* ---------------------------------------------------------------- */
867 		/*  If we're still halted, do nothing.                              */
868 		/* ---------------------------------------------------------------- */
869 		if (m_halted)
870 		{
871 			m_filt.rpt = 1;
872 			m_lrq      = 0x8000;
873 			m_ald      = 0;
874 			for (i = 0; i < 16; i++)
875 				m_filt.r[i] = 0;
876 
877 			SET_SBY(1)
878 
879 			return;
880 		}
881 
882 		/* ---------------------------------------------------------------- */
883 		/*  Fetch the first 8 bits of the opcode, which are always in the   */
884 		/*  same approximate format -- immed4 followed by opcode.           */
885 		/* ---------------------------------------------------------------- */
886 		immed4 = getb(4);
887 		opcode = getb(4);
888 		repeat = 0;
889 		ctrl_xfer = 0;
890 
891 		LOG((0, _T("$%.4X.%.1X: OPCODE %d%d%d%d.%d%d\n"),
892 				(m_pc >> 3) - 1, m_pc & 7,
893 				!!(opcode & 1), !!(opcode & 2),
894 				!!(opcode & 4), !!(opcode & 8),
895 				!!(m_mode&4), !!(m_mode&2)));
896 
897 		/* ---------------------------------------------------------------- */
898 		/*  Handle the special cases for specific opcodes.                  */
899 		/* ---------------------------------------------------------------- */
900 		switch (opcode)
901 		{
902 			/* ------------------------------------------------------------ */
903 			/*  OPCODE 0000:  RTS / SETPAGE                                 */
904 			/* ------------------------------------------------------------ */
905 			case 0x0:
906 			{
907 				/* -------------------------------------------------------- */
908 				/*  If immed4 != 0, then this is a SETPAGE instruction.     */
909 				/* -------------------------------------------------------- */
910 				if (immed4)     /* SETPAGE */
911 				{
912 					m_page = bitrev32(immed4) >> 13;
913 				} else
914 				/* -------------------------------------------------------- */
915 				/*  Otherwise, this is an RTS / HLT.                        */
916 				/* -------------------------------------------------------- */
917 				{
918 					UINT32 btrg;
919 
920 					/* ---------------------------------------------------- */
921 					/*  Figure out our branch target.                       */
922 					/* ---------------------------------------------------- */
923 					btrg = m_stack;
924 
925 					m_stack = 0;
926 
927 					/* ---------------------------------------------------- */
928 					/*  If the branch target is zero, this is a HLT.        */
929 					/*  Otherwise, it's an RTS, so set the PC.              */
930 					/* ---------------------------------------------------- */
931 					if (!btrg)
932 					{
933 						m_halted   = 1;
934 						m_pc       = 0;
935 						ctrl_xfer  = 1;
936 					} else
937 					{
938 						m_pc      = btrg;
939 						ctrl_xfer = 1;
940 					}
941 				}
942 
943 				break;
944 			}
945 
946 			/* ------------------------------------------------------------ */
947 			/*  OPCODE 0111:  JMP          Jump to 12-bit/16-bit Abs Addr   */
948 			/*  OPCODE 1011:  JSR          Jump to Subroutine               */
949 			/* ------------------------------------------------------------ */
950 			case 0xE:
951 			case 0xD:
952 			{
953 				INT32 btrg;
954 
955 				/* -------------------------------------------------------- */
956 				/*  Figure out our branch target.                           */
957 				/* -------------------------------------------------------- */
958 				btrg = m_page                     |
959 						(bitrev32(immed4)  >> 17) |
960 						(bitrev32(getb(8)) >> 21);
961 				ctrl_xfer = 1;
962 
963 				/* -------------------------------------------------------- */
964 				/*  If this is a JSR, push our return address on the        */
965 				/*  stack.  Make sure it's byte aligned.                    */
966 				/* -------------------------------------------------------- */
967 				if (opcode == 0xD)
968 					m_stack = (m_pc + 7) & ~7;
969 
970 				/* -------------------------------------------------------- */
971 				/*  Jump to the new location!                               */
972 				/* -------------------------------------------------------- */
973 				m_pc = btrg;
974 				break;
975 			}
976 
977 			/* ------------------------------------------------------------ */
978 			/*  OPCODE 1000:  SETMODE      Set the Mode and Repeat MSBs     */
979 			/* ------------------------------------------------------------ */
980 			case 0x1:
981 			{
982 				m_mode = ((immed4 & 8) >> 2) | (immed4 & 4) | ((immed4 & 3) << 4);
983 				break;
984 			}
985 
986 			/* ------------------------------------------------------------ */
987 			/*  OPCODE 0001:  LOADALL      Load All Parameters              */
988 			/*  OPCODE 0010:  LOAD_2       Load Per, Ampl, Coefs, Interp.   */
989 			/*  OPCODE 0011:  SETMSB_3     Load Pitch, Ampl, MSBs, & Intrp  */
990 			/*  OPCODE 0100:  LOAD_4       Load Pitch, Ampl, Coeffs         */
991 			/*  OPCODE 0101:  SETMSB_5     Load Pitch, Ampl, and Coeff MSBs */
992 			/*  OPCODE 0110:  SETMSB_6     Load Ampl, and Coeff MSBs.       */
993 			/*  OPCODE 1001:  DELTA_9      Delta update Ampl, Pitch, Coeffs */
994 			/*  OPCODE 1010:  SETMSB_A     Load Ampl and MSBs of 3 Coeffs   */
995 			/*  OPCODE 1100:  LOAD_C       Load Pitch, Ampl, Coeffs         */
996 			/*  OPCODE 1101:  DELTA_D      Delta update Ampl, Pitch, Coeffs */
997 			/*  OPCODE 1110:  LOAD_E       Load Pitch, Amplitude            */
998 			/*  OPCODE 1111:  PAUSE        Silent pause                     */
999 			/* ------------------------------------------------------------ */
1000 			default:
1001 			{
1002 				repeat = immed4 | (m_mode & 0x30);
1003 				break;
1004 			}
1005 		}
1006 		if (opcode != 1) m_mode &= 0xF;
1007 
1008 		/* ---------------------------------------------------------------- */
1009 		/*  If this was a control transfer, handle setting "fifo_sel"       */
1010 		/*  and all that ugliness.                                          */
1011 		/* ---------------------------------------------------------------- */
1012 		if (ctrl_xfer)
1013 		{
1014 			LOG((0, _T("jumping to $%.4X.%.1X: "), m_pc >> 3, m_pc & 7));
1015 
1016 			/* ------------------------------------------------------------ */
1017 			/*  Set our "FIFO Selected" flag based on whether we're going   */
1018 			/*  to the FIFO's address.                                      */
1019 			/* ------------------------------------------------------------ */
1020 			m_fifo_sel = m_pc == FIFO_ADDR;
1021 
1022 			LOG((0, _T("%s "), m_fifo_sel ? "FIFO" : "ROM"));
1023 
1024 			/* ------------------------------------------------------------ */
1025 			/*  Control transfers to the FIFO cause it to discard the       */
1026 			/*  partial decle that's at the front of the FIFO.              */
1027 			/* ------------------------------------------------------------ */
1028 			if (m_fifo_sel && m_fifo_bitp)
1029 			{
1030 				LOG((0, _T("bitp = %d -> Flush"), m_fifo_bitp));
1031 
1032 				/* Discard partially-read decle. */
1033 				if (m_fifo_tail < m_fifo_head) m_fifo_tail++;
1034 				m_fifo_bitp = 0;
1035 			}
1036 
1037 			LOG((0, _T("\n")));
1038 
1039 			continue;
1040 		}
1041 
1042 		/* ---------------------------------------------------------------- */
1043 		/*  Otherwise, if we have a repeat count, then go grab the data     */
1044 		/*  block and feed it to the filter.                                */
1045 		/* ---------------------------------------------------------------- */
1046 		if (!repeat) continue;
1047 
1048 		m_filt.rpt = repeat + 1;
1049 		LOG((0, _T("repeat = %d\n"), repeat));
1050 
1051 		i = (opcode << 3) | (m_mode & 6);
1052 		idx0 = sp0256_df_idx[i++];
1053 		idx1 = sp0256_df_idx[i  ];
1054 
1055 		//assert(idx0 >= 0 && idx1 >= 0 && idx1 >= idx0);
1056 
1057 		/* ---------------------------------------------------------------- */
1058 		/*  Step through control words in the description for data block.   */
1059 		/* ---------------------------------------------------------------- */
1060 		for (i = idx0; i <= idx1; i++)
1061 		{
1062 			INT32 len, shf, delta, field, prm, clra, clr5;
1063 			INT8 value;
1064 
1065 			/* ------------------------------------------------------------ */
1066 			/*  Get the control word and pull out some important fields.    */
1067 			/* ------------------------------------------------------------ */
1068 			cr = sp0256_datafmt[i];
1069 
1070 			len   = CR_LEN(cr);
1071 			shf   = CR_SHF(cr);
1072 			prm   = CR_PRM(cr);
1073 			clra  = cr & CR_CLRA;
1074 			clr5  = cr & CR_CLR5;
1075 			delta = cr & CR_DELTA;
1076 			field = cr & CR_FIELD;
1077 			value = 0;
1078 
1079 			LOG((0, _T("$%.4X.%.1X: len=%2d shf=%2d prm=%2d d=%d f=%d "),
1080 						m_pc >> 3, m_pc & 7, len, shf, prm, !!delta, !!field));
1081 			/* ------------------------------------------------------------ */
1082 			/*  Clear any registers that were requested to be cleared.      */
1083 			/* ------------------------------------------------------------ */
1084 			if (clra)
1085 			{
1086 				for (INT32 j = 0; j < 16; j++)
1087 					m_filt.r[j] = 0;
1088 
1089 				m_silent = 1;
1090 			}
1091 
1092 			if (clr5)
1093 				m_filt.r[B5] = m_filt.r[F5] = 0;
1094 
1095 			/* ------------------------------------------------------------ */
1096 			/*  If this entry has a bitfield with it, grab the bitfield.    */
1097 			/* ------------------------------------------------------------ */
1098 			if (len)
1099 			{
1100 				value = getb(len);
1101 			}
1102 			else
1103 			{
1104 				LOG((0, _T(" (no update)\n")));
1105 				continue;
1106 			}
1107 
1108 			/* ------------------------------------------------------------ */
1109 			/*  Sign extend if this is a delta update.                      */
1110 			/* ------------------------------------------------------------ */
1111 			if (delta)  /* Sign extend */
1112 			{
1113 				if (value & (1 << (len - 1))) value |= -1 << len;
1114 			}
1115 
1116 			/* ------------------------------------------------------------ */
1117 			/*  Shift the value to the appropriate precision.               */
1118 			/* ------------------------------------------------------------ */
1119 			if (shf)
1120 				value <<= shf;
1121 
1122 			LOG((0, _T("v=%.2X (%c%.2X)  "), value & 0xFF,
1123 						value & 0x80 ? '-' : '+',
1124 						0xFF & (value & 0x80 ? -value : value)));
1125 
1126 			m_silent = 0;
1127 
1128 			/* ------------------------------------------------------------ */
1129 			/*  If this is a field-replace, insert the field.               */
1130 			/* ------------------------------------------------------------ */
1131 			if (field)
1132 			{
1133 				LOG((0, _T("--field-> r[%2d] = %.2X -> "), prm, m_filt.r[prm]));
1134 
1135 				m_filt.r[prm] &= ~(~0 << shf); /* Clear the old bits.     */
1136 				m_filt.r[prm] |= value;        /* Merge in the new bits.  */
1137 
1138 				LOG((0, _T("%.2X\n"), m_filt.r[prm]));
1139 
1140 				continue;
1141 			}
1142 
1143 			/* ------------------------------------------------------------ */
1144 			/*  If this is a delta update, add to the appropriate field.    */
1145 			/* ------------------------------------------------------------ */
1146 			if (delta)
1147 			{
1148 				LOG((0, _T("--delta-> r[%2d] = %.2X -> "), prm, m_filt.r[prm]));
1149 
1150 				m_filt.r[prm] += value;
1151 
1152 				LOG((0, _T("%.2X\n"), m_filt.r[prm]));
1153 
1154 				continue;
1155 			}
1156 
1157 			/* ------------------------------------------------------------ */
1158 			/*  Otherwise, just write the new value.                        */
1159 			/* ------------------------------------------------------------ */
1160 			m_filt.r[prm] = value;
1161 			LOG((0, _T("--value-> r[%2d] = %.2X\n"), prm, m_filt.r[prm]));
1162 		}
1163 
1164 		/* ---------------------------------------------------------------- */
1165 		/*  Special case:  Set PAUSE's equivalent period.                   */
1166 		/* ---------------------------------------------------------------- */
1167 		if (opcode == 0xF)
1168 		{
1169 			m_silent = 1;
1170 			m_filt.r[1] = PER_PAUSE;
1171 		}
1172 
1173 		/* ---------------------------------------------------------------- */
1174 		/*  Now that we've updated the registers, go decode them.           */
1175 		/* ---------------------------------------------------------------- */
1176 		lpc12_regdec(&m_filt);
1177 
1178 		/* ---------------------------------------------------------------- */
1179 		/*  Break out since we now have a repeat count.                     */
1180 		/* ---------------------------------------------------------------- */
1181 		break;
1182 	}
1183 }
1184 
sp0256_ald_write(UINT8 data)1185 void sp0256_ald_write(UINT8 data)
1186 {
1187 	/* ---------------------------------------------------------------- */
1188 	/*  Drop writes to the ALD register if we're busy.                  */
1189 	/* ---------------------------------------------------------------- */
1190 
1191 	if (!m_lrq)
1192 	{
1193 		LOG((0, _T("sp0256: Droped ALD write\n")));
1194 		return;
1195 	}
1196 
1197 	/* ---------------------------------------------------------------- */
1198 	/*  Set LRQ to "busy" and load the 8 LSBs of the data into the ALD  */
1199 	/*  reg.  We take the command address, and multiply by 2 bytes to   */
1200 	/*  get the new PC address.                                         */
1201 	/* ---------------------------------------------------------------- */
1202 	m_lrq = 0;
1203 	m_ald = (0xff & data) << 4;
1204 	m_drq_cb(0);
1205 	SET_SBY(0)
1206 
1207 	return;
1208 }
1209 
sp0256_lrq_read()1210 UINT8 sp0256_lrq_read()
1211 {
1212 	// force stream update
1213 	//m_stream->update();
1214 
1215 	return m_lrq == 0x8000;
1216 }
1217 
sp0256_sby_read()1218 UINT8 sp0256_sby_read()
1219 {
1220 	// TODO: force stream update??
1221 
1222 	return m_sby_line;
1223 }
1224 
sp0256_spb640_read(INT32 offset)1225 UINT16 sp0256_spb640_read(INT32 offset)
1226 {
1227 	/* -------------------------------------------------------------------- */
1228 	/*  Offset 0 returns the SP0256 LRQ status on bit 15.                   */
1229 	/* -------------------------------------------------------------------- */
1230 	if (offset == 0)
1231 	{
1232 		return m_lrq;
1233 	}
1234 
1235 	/* -------------------------------------------------------------------- */
1236 	/*  Offset 1 returns the SPB640 FIFO full status on bit 15.             */
1237 	/* -------------------------------------------------------------------- */
1238 	if (offset == 1)
1239 	{
1240 		return (m_fifo_head - m_fifo_tail) >= 64 ? 0x8000 : 0;
1241 	}
1242 
1243 	/* -------------------------------------------------------------------- */
1244 	/*  Just return 255 for all other addresses in our range.               */
1245 	/* -------------------------------------------------------------------- */
1246 	return 0x00ff;
1247 }
1248 
sp0256_spb640_write(UINT16 offset,UINT16 data)1249 void sp0256_spb640_write(UINT16 offset, UINT16 data)
1250 {
1251 	if (offset == 0)
1252 	{
1253 		sp0256_ald_write(data & 0xff);
1254 		return;
1255 	}
1256 
1257 	if (offset == 1)
1258 	{
1259 		/* ---------------------------------------------------------------- */
1260 		/*  If Bit 10 is set, reset the FIFO, and SP0256.                   */
1261 		/* ---------------------------------------------------------------- */
1262 
1263 		if (data & 0x400)
1264 		{
1265 			m_fifo_head = m_fifo_tail = m_fifo_bitp = 0;
1266 			sp0256_reset();
1267 			return;
1268 		}
1269 
1270 		/* ---------------------------------------------------------------- */
1271 		/*  If the FIFO is full, drop the data.                             */
1272 		/* ---------------------------------------------------------------- */
1273 		if ((m_fifo_head - m_fifo_tail) >= 64)
1274 		{
1275 			LOG((0, _T("spb640: Dropped FIFO write\n")));
1276 			return;
1277 		}
1278 
1279 		/* ---------------------------------------------------------------- */
1280 		/*  FIFO up the lower 10 bits of the data.                          */
1281 		/* ---------------------------------------------------------------- */
1282 
1283 		LOG((0, _T("spb640: WR_FIFO %.3X %d.%d %d\n"), data & 0x3ff,
1284 				m_fifo_tail, m_fifo_bitp, m_fifo_head));
1285 
1286 		m_fifo[m_fifo_head++ & 63] = data & 0x3ff;
1287 
1288 		return;
1289 	}
1290 }
1291 
set_lrq_timer_proc()1292 static void set_lrq_timer_proc()
1293 {
1294 	m_lrq = 0x8000;
1295 }
1296 
1297 //-------------------------------------------------
1298 //  sound_stream_update - handle a stream update
1299 //-------------------------------------------------
sp0256_update(INT16 * sndbuff,INT32 samples_len)1300 void sp0256_update(INT16 *sndbuff, INT32 samples_len)
1301 {
1302 	INT32 output_index = 0;
1303 	INT32 length, did_samp;
1304 
1305 	INT32 samples = (samples_from * samples_len) / nBurnSoundLen;
1306 
1307 	memset(mixer_buffer, 0, samples * sizeof(INT16));
1308 
1309 	while (output_index < samples)
1310 	{
1311 		/* ---------------------------------------------------------------- */
1312 		/*  First, drain as much of our scratch buffer as we can into the   */
1313 		/*  sound buffer.                                                  */
1314 		/* ---------------------------------------------------------------- */
1315 
1316 		while (m_sc_tail != m_sc_head)
1317 		{
1318 			mixer_buffer[output_index++] = m_scratch[m_sc_tail++ & SCBUF_MASK];
1319 			m_sc_tail &= SCBUF_MASK;
1320 
1321 			if (output_index > samples)
1322 				break;
1323 		}
1324 
1325 		/* ---------------------------------------------------------------- */
1326 		/*  If output outputs is full, then we're done.                      */
1327 		/* ---------------------------------------------------------------- */
1328 		if (output_index > samples)
1329 			break;
1330 
1331 		length = samples - output_index;
1332 
1333 		/* ---------------------------------------------------------------- */
1334 		/*  Process the current set of filter coefficients as long as the   */
1335 		/*  repeat count holds up and we have room in our scratch buffer.   */
1336 		/* ---------------------------------------------------------------- */
1337 		did_samp = 0;
1338 
1339 		if (length > 0) do
1340 		{
1341 			INT32 do_samp;
1342 
1343 			/* ------------------------------------------------------------ */
1344 			/*  If our repeat count expired, emulate the microsequencer.    */
1345 			/* ------------------------------------------------------------ */
1346 			if (m_filt.rpt <= 0)
1347 				micro();
1348 
1349 			/* ------------------------------------------------------------ */
1350 			/*  Do as many samples as we can.                               */
1351 			/* ------------------------------------------------------------ */
1352 			do_samp = length - did_samp;
1353 			if (m_sc_head + do_samp - m_sc_tail > SCBUF_SIZE)
1354 				do_samp = m_sc_tail + SCBUF_SIZE - m_sc_head;
1355 
1356 			if (do_samp == 0) break;
1357 
1358 			if (m_silent && m_filt.rpt <= 0)
1359 			{
1360 				INT32 y = m_sc_head;
1361 
1362 				for (INT32 x = 0; x < do_samp; x++)
1363 					m_scratch[y++ & SCBUF_MASK] = 0;
1364 				m_sc_head += do_samp;
1365 				did_samp  += do_samp;
1366 			}
1367 			else
1368 			{
1369 				did_samp += lpc12_update(&m_filt, do_samp,
1370 										 m_scratch, &m_sc_head);
1371 			}
1372 			if ((length%READY_TIMER)==(READY_TIMER-1)) set_lrq_timer_proc();
1373 			m_sc_head &= SCBUF_MASK;
1374 
1375 		} while (m_filt.rpt >= 0 && length > did_samp);
1376 	}
1377 
1378 	for (INT32 j = 0; j < samples_len; j++)
1379 	{
1380 		INT32 k = (samples_from * j) / nBurnSoundLen;
1381 
1382 		INT32 lr = mixer_buffer[k];
1383 		sndbuff[0] = BURN_SND_CLIP(sndbuff[0] + lr);
1384 		sndbuff[1] = BURN_SND_CLIP(sndbuff[1] + lr);
1385 		sndbuff += 2;
1386 	}
1387 }
1388