1 // Based on MAME driver by Juergen Buchmueller, Mike Balfour, Howie Cohen, Olivier Galibert, Aaron Giles
2 
3 #include "burnint.h"
4 #include "upd7759.h"
5 #include "downsample.h"
6 #include "timer.h"
7 #include <math.h>
8 #include "biquad.h"
9 
10 #define FRAC_BITS			20
11 #define FRAC_ONE			(1 << FRAC_BITS)
12 #define FRAC_MASK			(FRAC_ONE - 1)
13 
14 static INT32 SlaveMode = 0;
15 
16 /* chip states */
17 enum
18 {
19 	STATE_IDLE,
20 	STATE_DROP_DRQ,
21 	STATE_START,
22 	STATE_FIRST_REQ,
23 	STATE_LAST_SAMPLE,
24 	STATE_DUMMY1,
25 	STATE_ADDR_MSB,
26 	STATE_ADDR_LSB,
27 	STATE_DUMMY2,
28 	STATE_BLOCK_HEADER,
29 	STATE_NIBBLE_COUNT,
30 	STATE_NIBBLE_MSN,
31 	STATE_NIBBLE_LSN
32 };
33 
34 struct upd7759_chip
35 {
36 	INT32		ChipNum; // for callback
37 	/* internal clock to output sample rate mapping */
38 	UINT32		pos;						/* current output sample position */
39 	UINT32		step;						/* step value per output sample */
40 	double      clock_period;
41 	INT32       start_delay;
42 
43 	/* I/O lines */
44 	UINT8		fifo_in;					/* last data written to the sound chip */
45 	UINT8		reset;						/* current state of the RESET line */
46 	UINT8		start;						/* current state of the START line */
47 	UINT8		drq;						/* current state of the DRQ line */
48 	void (*drqcallback)(INT32 param);		/* drq callback */
49 
50 	/* internal state machine */
51 	INT8		state;						/* current overall chip state */
52 	INT32		clocks_left;				/* number of clocks left in this state */
53 	UINT16		nibbles_left;				/* number of ADPCM nibbles left to process */
54 	UINT8		repeat_count;				/* number of repeats remaining in current repeat block */
55 	INT8		post_drq_state;				/* state we will be in after the DRQ line is dropped */
56 	INT32		post_drq_clocks;			/* clocks that will be left after the DRQ line is dropped */
57 	UINT8		req_sample;					/* requested sample number */
58 	UINT8		last_sample;				/* last sample number available */
59 	UINT8		block_header;				/* header byte */
60 	UINT8		sample_rate;				/* number of UPD clocks per ADPCM nibble */
61 	UINT8		first_valid_header;			/* did we get our first valid header yet? */
62 	UINT32		offset;						/* current ROM offset */
63 	UINT32		repeat_offset;				/* current ROM repeat offset */
64 
65 	/* ADPCM processing */
66 	INT8		adpcm_state;				/* ADPCM state index */
67 	UINT8		adpcm_data;					/* current byte of ADPCM data */
68 	INT16		sample;						/* current sample value */
69 	INT32		sample_counts;				// this frame
70 
71 	/* ROM access */
72 	UINT8 *		rom;						/* pointer to ROM data or NULL for slave mode */
73 	UINT8 *		rombase;					/* pointer to ROM data or NULL for slave mode */
74 	UINT32		romoffset;					/* ROM offset to make save/restore easier */
75 
76 	// downsampler
77 	Downsampler resamp;
78 	INT16 *     out_buf;
79 	INT16 *     out_buf_linear;
80 	INT16 *     out_buf_linear_resampled;
81 	INT32       out_buf_size;
82 	INT32       out_pos;
83 
84 	// filter
85 	BIQ biquadL;
86 	BIQ biquadR;
87 
88 	// stream sync
89 	INT32 (*pTotalCyclesCB)();
90 	INT32 nCpuMHZ;
91 
92 	/* route */
93 	double		volume;
94 	INT32		output_dir;
95 };
96 
97 static struct upd7759_chip *Chips[2] = { NULL, NULL }; // more?
98 static struct upd7759_chip *Chip = NULL;
99 
100 static INT32 nNumChips = 0;
101 
102 static const INT32 upd7759_step[16][16] =
103 {
104 	{ 0,  0,  1,  2,  3,   5,   7,  10,  0,   0,  -1,  -2,  -3,   -5,   -7,  -10 },
105 	{ 0,  1,  2,  3,  4,   6,   8,  13,  0,  -1,  -2,  -3,  -4,   -6,   -8,  -13 },
106 	{ 0,  1,  2,  4,  5,   7,  10,  15,  0,  -1,  -2,  -4,  -5,   -7,  -10,  -15 },
107 	{ 0,  1,  3,  4,  6,   9,  13,  19,  0,  -1,  -3,  -4,  -6,   -9,  -13,  -19 },
108 	{ 0,  2,  3,  5,  8,  11,  15,  23,  0,  -2,  -3,  -5,  -8,  -11,  -15,  -23 },
109 	{ 0,  2,  4,  7, 10,  14,  19,  29,  0,  -2,  -4,  -7, -10,  -14,  -19,  -29 },
110 	{ 0,  3,  5,  8, 12,  16,  22,  33,  0,  -3,  -5,  -8, -12,  -16,  -22,  -33 },
111 	{ 1,  4,  7, 10, 15,  20,  29,  43, -1,  -4,  -7, -10, -15,  -20,  -29,  -43 },
112 	{ 1,  4,  8, 13, 18,  25,  35,  53, -1,  -4,  -8, -13, -18,  -25,  -35,  -53 },
113 	{ 1,  6, 10, 16, 22,  31,  43,  64, -1,  -6, -10, -16, -22,  -31,  -43,  -64 },
114 	{ 2,  7, 12, 19, 27,  37,  51,  76, -2,  -7, -12, -19, -27,  -37,  -51,  -76 },
115 	{ 2,  9, 16, 24, 34,  46,  64,  96, -2,  -9, -16, -24, -34,  -46,  -64,  -96 },
116 	{ 3, 11, 19, 29, 41,  57,  79, 117, -3, -11, -19, -29, -41,  -57,  -79, -117 },
117 	{ 4, 13, 24, 36, 50,  69,  96, 143, -4, -13, -24, -36, -50,  -69,  -96, -143 },
118 	{ 4, 16, 29, 44, 62,  85, 118, 175, -4, -16, -29, -44, -62,  -85, -118, -175 },
119 	{ 6, 20, 36, 54, 76, 104, 144, 214, -6, -20, -36, -54, -76, -104, -144, -214 },
120 };
121 
122 static const INT32 upd7759_state[16] = { -1, -1, 0, 0, 1, 2, 2, 3, -1, -1, 0, 0, 1, 2, 2, 3 };
123 
UpdateAdpcm(INT32 Data)124 inline static void UpdateAdpcm(INT32 Data)
125 {
126 	Chip->sample += upd7759_step[Chip->adpcm_state][Data];
127 	Chip->adpcm_state += upd7759_state[Data];
128 
129 	/* clamp the state to 0..15 */
130 	if (Chip->adpcm_state < 0)
131 		Chip->adpcm_state = 0;
132 	else if (Chip->adpcm_state > 15)
133 		Chip->adpcm_state = 15;
134 }
135 
SyncUPD(upd7759_chip * Chippy,INT32 cycles)136 static INT32 SyncUPD(upd7759_chip *Chippy, INT32 cycles)
137 {
138 	return (INT32)((double)cycles * ((double)(Chippy->pTotalCyclesCB()) / ((double)Chippy->nCpuMHZ / (nBurnFPS / 100.0000))));
139 }
140 
141 static void UpdateStream(INT32 chip, INT32 end);
142 
UPD7759AdvanceState()143 static void UPD7759AdvanceState()
144 {
145 	switch (Chip->state)
146 	{
147 		/* Idle state: we stick around here while there's nothing to do */
148 		case STATE_IDLE:
149 			Chip->clocks_left = 4;
150 			break;
151 
152 		/* drop DRQ state: update to the intended state */
153 		case STATE_DROP_DRQ:
154 			Chip->drq = 0;
155 
156 			Chip->clocks_left = Chip->post_drq_clocks;
157 			Chip->state = Chip->post_drq_state;
158 			break;
159 
160 		/* Start state: we begin here as soon as a sample is triggered */
161 		case STATE_START:
162 			Chip->req_sample = (Chip->rom) ? Chip->fifo_in : 0x10;
163 			/* 35+ cycles after we get here, the /DRQ goes low
164              *     (first byte (number of samples in ROM) should be sent in response)
165              *
166              * (35 is the minimum number of cycles I found during heavy tests.
167              * Depending on the state the chip was in just before the /MD was set to 0 (reset, standby
168              * or just-finished-playing-previous-sample) this number can range from 35 up to ~24000).
169              * It also varies slightly from test to test, but not much - a few cycles at most.) */
170 			Chip->clocks_left = 70 + Chip->start_delay;	/* 35 - breaks cotton */
171 			Chip->state = STATE_FIRST_REQ;
172 			break;
173 
174 		/* First request state: issue a request for the first byte */
175 		/* The expected response will be the index of the last sample */
176 		case STATE_FIRST_REQ:
177 			Chip->drq = 1;
178 
179 			/* 44 cycles later, we will latch this value and request another byte */
180 			Chip->clocks_left = 44;
181 			Chip->state = STATE_LAST_SAMPLE;
182 			break;
183 
184 		/* Last sample state: latch the last sample value and issue a request for the second byte */
185 		/* The second byte read will be just a dummy */
186 		case STATE_LAST_SAMPLE:
187 			Chip->last_sample = Chip->rom ? Chip->rom[0] : Chip->fifo_in;
188 
189 			Chip->drq = 1;
190 
191 			/* 28 cycles later, we will latch this value and request another byte */
192 			Chip->clocks_left = 28;	/* 28 - breaks cotton */
193 			Chip->state = (Chip->req_sample > Chip->last_sample) ? STATE_IDLE : STATE_DUMMY1;
194 			break;
195 
196 		/* First dummy state: ignore any data here and issue a request for the third byte */
197 		/* The expected response will be the MSB of the sample address */
198 		case STATE_DUMMY1:
199 			Chip->drq = 1;
200 
201 			/* 32 cycles later, we will latch this value and request another byte */
202 			Chip->clocks_left = 32;
203 			Chip->state = STATE_ADDR_MSB;
204 			break;
205 
206 		/* Address MSB state: latch the MSB of the sample address and issue a request for the fourth byte */
207 		/* The expected response will be the LSB of the sample address */
208 		case STATE_ADDR_MSB:
209 			Chip->offset = ((Chip->rom) ? Chip->rom[Chip->req_sample * 2 + 5] : Chip->fifo_in) << 9;
210 
211 			Chip->drq = 1;
212 
213 			/* 44 cycles later, we will latch this value and request another byte */
214 			Chip->clocks_left = 44;
215 			Chip->state = STATE_ADDR_LSB;
216 			break;
217 
218 		/* Address LSB state: latch the LSB of the sample address and issue a request for the fifth byte */
219 		/* The expected response will be just a dummy */
220 		case STATE_ADDR_LSB:
221 			Chip->offset |= ((Chip->rom) ? Chip->rom[Chip->req_sample * 2 + 6] : Chip->fifo_in) << 1;
222 			Chip->drq = 1;
223 
224 			/* 36 cycles later, we will latch this value and request another byte */
225 			Chip->clocks_left = 36;
226 			Chip->state = STATE_DUMMY2;
227 			break;
228 
229 		/* Second dummy state: ignore any data here and issue a request for the the sixth byte */
230 		/* The expected response will be the first block header */
231 		case STATE_DUMMY2:
232 			Chip->offset++;
233 			Chip->first_valid_header = 0;
234 			Chip->drq = 1;
235 
236 			/* 36?? cycles later, we will latch this value and request another byte */
237 			Chip->clocks_left = 36;
238 			Chip->state = STATE_BLOCK_HEADER;
239 			break;
240 
241 		/* Block header state: latch the header and issue a request for the first byte afterwards */
242 		case STATE_BLOCK_HEADER:
243 
244 			/* if we're in a repeat loop, reset the offset to the repeat point and decrement the count */
245 			if (Chip->repeat_count)
246 			{
247 				Chip->repeat_count--;
248 				Chip->offset = Chip->repeat_offset;
249 			}
250 			Chip->block_header = (Chip->rom) ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in;
251 			Chip->drq = 1;
252 
253 			/* our next step depends on the top two bits */
254 			switch (Chip->block_header & 0xc0)
255 			{
256 				case 0x00:	/* silence */
257 					Chip->clocks_left = 1024 * ((Chip->block_header & 0x3f) + 1);
258 					Chip->state = (Chip->block_header == 0 && Chip->first_valid_header) ? STATE_IDLE : STATE_BLOCK_HEADER;
259 					Chip->sample = 0;
260 					Chip->adpcm_state = 0;
261 					break;
262 
263 				case 0x40:	/* 256 nibbles */
264 					Chip->sample_rate = (Chip->block_header & 0x3f) + 1;
265 					Chip->nibbles_left = 256;
266 					Chip->clocks_left = 36;	/* just a guess */
267 					Chip->state = STATE_NIBBLE_MSN;
268 					break;
269 
270 				case 0x80:	/* n nibbles */
271 					Chip->sample_rate = (Chip->block_header & 0x3f) + 1;
272 					Chip->clocks_left = 36;	/* just a guess */
273 					Chip->state = STATE_NIBBLE_COUNT;
274 					break;
275 
276 				case 0xc0:	/* repeat loop */
277 					Chip->repeat_count = (Chip->block_header & 7) + 1;
278 					Chip->repeat_offset = Chip->offset;
279 					Chip->clocks_left = 36;	/* just a guess */
280 					Chip->state = STATE_BLOCK_HEADER;
281 					break;
282 			}
283 
284 			/* set a flag when we get the first non-zero header */
285 			if (Chip->block_header != 0)
286 				Chip->first_valid_header = 1;
287 			break;
288 
289 		/* Nibble count state: latch the number of nibbles to play and request another byte */
290 		/* The expected response will be the first data byte */
291 		case STATE_NIBBLE_COUNT:
292 			Chip->nibbles_left = ((Chip->rom) ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in) + 1;
293 			Chip->drq = 1;
294 
295 			/* 36?? cycles later, we will latch this value and request another byte */
296 			Chip->clocks_left = 36;	/* just a guess */
297 			Chip->state = STATE_NIBBLE_MSN;
298 			break;
299 
300 		/* MSN state: latch the data for this pair of samples and request another byte */
301 		/* The expected response will be the next sample data or another header */
302 		case STATE_NIBBLE_MSN:
303 			Chip->adpcm_data = (Chip->rom) ? Chip->rom[Chip->offset++ & 0x1ffff] : Chip->fifo_in;
304 			UpdateAdpcm(Chip->adpcm_data >> 4);
305 			Chip->drq = 1;
306 
307 			/* we stay in this state until the time for this sample is complete */
308 			Chip->clocks_left = Chip->sample_rate * 4;
309 			if (--Chip->nibbles_left == 0)
310 				Chip->state = STATE_BLOCK_HEADER;
311 			else
312 				Chip->state = STATE_NIBBLE_LSN;
313 			break;
314 
315 		/* LSN state: process the lower nibble */
316 		case STATE_NIBBLE_LSN:
317 			UpdateAdpcm(Chip->adpcm_data & 15);
318 
319 			/* we stay in this state until the time for this sample is complete */
320 			Chip->clocks_left = Chip->sample_rate * 4;
321 			if (--Chip->nibbles_left == 0)
322 				Chip->state = STATE_BLOCK_HEADER;
323 			else
324 				Chip->state = STATE_NIBBLE_MSN;
325 			break;
326 	}
327 
328 	/* if there's a DRQ, fudge the state */
329 	if (Chip->drq)
330 	{
331 		Chip->post_drq_state = Chip->state;
332 		Chip->post_drq_clocks = Chip->clocks_left - 21;
333 		Chip->state = STATE_DROP_DRQ;
334 		Chip->clocks_left = 21;
335 	}
336 }
337 
UPD7759SlaveModeUpdate()338 static void UPD7759SlaveModeUpdate()
339 {
340 	Chip = Chips[0]; // slave mode only available on Chip 0
341 	UINT8 OldDrq = Chip->drq;
342 
343 	UpdateStream(Chip->ChipNum, 0);
344 
345 	UPD7759AdvanceState();
346 
347 	if (OldDrq != Chip->drq && Chip->drqcallback) {
348 		(*Chip->drqcallback)(Chip->drq);
349 	}
350 
351 	/* set a timer to go off when that is done */
352 
353 	if (Chip->state != STATE_IDLE) {
354 		BurnTimerSetRetrig(0, (double)Chip->clocks_left * Chip->clock_period);
355 	}
356 }
357 
slave_timer_cb(INT32 n,INT32 c)358 INT32 slave_timer_cb(INT32 n, INT32 c)
359 {
360 	UPD7759SlaveModeUpdate();
361 
362 	return 0;
363 }
364 
365 
UPD7759Update(INT32 chip,INT32 nLength)366 void UPD7759Update(INT32 chip, INT32 nLength)
367 {
368 #if defined FBNEO_DEBUG
369 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Update called without init\n"));
370 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759Update called with invalid chip %x\n"), chip);
371 #endif
372 	Chip = Chips[chip];
373 	INT32 ClocksLeft = Chip->clocks_left;
374 	INT16 Sample = Chip->sample;
375 	UINT32 Step = Chip->step;
376 	UINT32 Pos = Chip->pos;
377 
378 	/* loop until done */
379 	if (Chip->state != STATE_IDLE)
380 	{
381 		while (nLength != 0)
382 		{
383 			Chip->out_buf[Chip->out_pos] = Sample * 128;
384 			Chip->out_pos = (Chip->out_pos + 1) % Chip->out_buf_size;
385 
386 			Chip->sample_counts++;
387 
388 			nLength--;
389 
390 			/* advance by the number of clocks/output sample */
391 			Pos += Step;
392 
393 			/* handle clocks, but only in standalone mode */
394 			while (Chip->rom && Pos >= FRAC_ONE)
395 			{
396 				INT32 ClocksThisTime = Pos >> FRAC_BITS;
397 				if (ClocksThisTime > ClocksLeft)
398 					ClocksThisTime = ClocksLeft;
399 
400 				/* clock once */
401 				Pos -= ClocksThisTime * FRAC_ONE;
402 				ClocksLeft -= ClocksThisTime;
403 
404 				/* if we're out of clocks, time to handle the next state */
405 				if (ClocksLeft == 0)
406 				{
407 					/* advance one state; if we hit idle, bail */
408 					UPD7759AdvanceState();
409 					if (Chip->state == STATE_IDLE)
410 						break;
411 
412 					/* reimport the variables that we cached */
413 					ClocksLeft = Chip->clocks_left;
414 					Sample = Chip->sample;
415 				}
416 			}
417 		}
418 	}
419 
420 	while (nLength > 0) { // fill unused with nothing
421 		Chip->out_buf[Chip->out_pos] = 0;
422 		Chip->out_pos = (Chip->out_pos + 1) % Chip->out_buf_size;
423 
424 		Chip->sample_counts++;
425 
426 		nLength--;
427 	}
428 
429 	Chip->clocks_left = ClocksLeft;
430 	Chip->pos = Pos;
431 }
432 
UpdateStream(INT32 chip,INT32 end)433 static void UpdateStream(INT32 chip, INT32 end)
434 {
435 	if (!pBurnSoundOut) return;
436 
437 	Chip = Chips[chip];
438 
439 	INT32 framelen = Chip->resamp.samples_to_source(nBurnSoundLen);
440 	INT32 position = (end) ? framelen : SyncUPD(Chip, framelen);
441 
442 	INT32 samples = position - Chip->sample_counts;
443 
444 	if (samples < 1) return;
445 
446 	UPD7759Update(chip, samples);
447 }
448 
UPD7759Render(INT16 * pSoundBuf,INT32 samples)449 void UPD7759Render(INT16 *pSoundBuf, INT32 samples)
450 {
451 #if defined FBNEO_DEBUG
452 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Render called without init\n"));
453 #endif
454 
455 	for (INT32 i = 0; i <= nNumChips; i++) // first chip 0, second chip 1...
456 	{
457 		UPD7759Render(i, pSoundBuf, samples);
458 	}
459 }
460 
UPD7759Render(INT32 chip,INT16 * pSoundBuf,INT32 samples)461 void UPD7759Render(INT32 chip, INT16 *pSoundBuf, INT32 samples)
462 {
463 #if defined FBNEO_DEBUG
464 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Render called without init\n"));
465 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759Render called with invalid chip %x\n"), chip);
466 #endif
467 
468 	Chip = Chips[chip];
469 
470 	if (Chip->pTotalCyclesCB) UpdateStream(chip, 1); // fill 'er up!
471 
472 	INT32 nFrameLength = Chip->resamp.samples_to_source(nBurnSoundLen);
473 
474 	// copy frame worth of samples out of circular buffer into linear buffer.
475 	for (INT32 i = 0; i < nFrameLength; i++) {
476 		INT32 cpos = (Chip->out_pos + nFrameLength + i) % Chip->out_buf_size;
477 		Chip->out_buf_linear[i] = Chip->out_buf[cpos];
478 	    Chip->out_buf[cpos] = 0;
479 	}
480 
481 	// resample to host rate
482 	Chip->resamp.resample(Chip->out_buf_linear, Chip->out_buf_linear_resampled, samples, Chip->volume, Chip->output_dir);
483 
484 	// filter and mix into pSoundBuf
485 	for (INT32 i = 0; i < samples; i++) {
486 		INT32 l = Chip->biquadL.filter(Chip->out_buf_linear_resampled[i*2 + 0]);
487 		INT32 r = Chip->biquadR.filter(Chip->out_buf_linear_resampled[i*2 + 1]);
488 		pSoundBuf[i*2 + 0] = BURN_SND_CLIP(pSoundBuf[i*2 + 0] + l);
489 		pSoundBuf[i*2 + 1] = BURN_SND_CLIP(pSoundBuf[i*2 + 1] + r);
490 	}
491 
492 	Chip->sample_counts = 0; // ready for next frame!
493 }
494 
UPD7759ResetINT(INT32 chip)495 static void UPD7759ResetINT(INT32 chip)
496 {
497 	upd7759_chip *rChip = Chips[chip];
498 
499 	if (SlaveMode) {
500 		BurnTimerReset();
501 	}
502 
503 	rChip->pos                = 0;
504 	rChip->fifo_in            = 0;
505 	rChip->drq                = 0;
506 	rChip->state              = STATE_IDLE;
507 	rChip->clocks_left        = 0;
508 	rChip->nibbles_left       = 0;
509 	rChip->repeat_count       = 0;
510 	rChip->post_drq_state     = STATE_IDLE;
511 	rChip->post_drq_clocks    = 0;
512 	rChip->req_sample         = 0;
513 	rChip->last_sample        = 0;
514 	rChip->block_header       = 0;
515 	rChip->sample_rate        = 0;
516 	rChip->first_valid_header = 0;
517 	rChip->offset             = 0;
518 	rChip->repeat_offset      = 0;
519 	rChip->adpcm_state        = 0;
520 	rChip->adpcm_data         = 0;
521 	rChip->sample             = 0;
522 }
523 
UPD7759Reset()524 void UPD7759Reset()
525 {
526 #if defined FBNEO_DEBUG
527 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Reset called without init\n"));
528 #endif
529 
530 	if (SlaveMode) {
531 		BurnTimerReset();
532 	}
533 
534 	for (INT32 i = 0; i <= nNumChips; i++) { // first chip 0, second chip 1...
535 		UPD7759ResetINT(i);
536 	}
537 }
538 
UPD7759Init(INT32 chip,INT32 clock,UINT8 * pSoundData)539 void UPD7759Init(INT32 chip, INT32 clock, UINT8* pSoundData)
540 {
541 	DebugSnd_UPD7759Initted = 1;
542 
543 	Chips[chip] = (struct upd7759_chip*)BurnMalloc(sizeof(upd7759_chip));
544 	Chip = Chips[chip];
545 
546 	memset(Chip, 0, sizeof(upd7759_chip));
547 
548 	SlaveMode = 0;
549 
550 	Chip->ChipNum = chip;
551 	// init resampler
552 	Chip->resamp.init(clock / 4, nBurnSoundRate, 0);
553 
554 	// init filter (basically passthru w/these settings)
555 	Chip->biquadL.init(FILT_LOWPASS, nBurnSoundRate, 15000, 0.554, 0.0);
556 	Chip->biquadR.init(FILT_LOWPASS, nBurnSoundRate, 15000, 0.554, 0.0);
557 
558 	Chip->step = (INT32)(4 * FRAC_ONE);
559 	Chip->state = STATE_IDLE;
560 	Chip->clock_period = 1.0 / (double)clock;
561 
562 	// our 16bit (INT16) output buffer is 2 frames in length @ 640,000 kHz
563 	// out_buf - circular buffer @ clock/4 rate
564 	// out_buf_linear - linearized right before resampling and rendering
565 	// out_buf_linear_resampled - resampled and ready to be filtered
566 	Chip->out_buf_size = (clock / 4) * 100 / (nBurnFPS / 2); // word-size (byte size = *2)
567 	Chip->out_buf = (INT16*)BurnMalloc(Chip->out_buf_size * sizeof(INT16));
568 	Chip->out_buf_linear = (INT16*)BurnMalloc(Chip->out_buf_size * sizeof(INT16));
569 	Chip->out_buf_linear_resampled = (INT16*)BurnMalloc(Chip->out_buf_size * sizeof(INT16));
570 	Chip->out_pos = 0;
571 
572 	if (pSoundData) {
573 		Chip->rom = pSoundData;
574 		SlaveMode = 0;
575 	} else {
576 		SlaveMode = 1;
577 		BurnTimerInit(&slave_timer_cb, NULL); // for high-freq timer
578 	}
579 
580 	Chip->reset = 1;
581 	Chip->start = 1;
582 	Chip->volume = 1.00;
583 	Chip->output_dir = BURN_SND_ROUTE_BOTH;
584 
585 	nNumChips = chip;
586 
587 	UPD7759Reset();
588 }
589 
UPD7759SetStartDelay(INT32 chip,INT32 nDelay)590 void UPD7759SetStartDelay(INT32 chip, INT32 nDelay)
591 {
592 	Chip = Chips[chip];
593 
594 	Chip->start_delay = nDelay;
595 }
596 
UPD7759SetFilter(INT32 chip,INT32 nCutOff)597 void UPD7759SetFilter(INT32 chip, INT32 nCutOff)
598 {
599 #if defined FBNEO_DEBUG
600 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetFilter called without init\n"));
601 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetFilter called with invalid chip %i\n"), chip);
602 #endif
603 
604 	Chip = Chips[chip];
605 
606 	Chip->biquadL.init(FILT_LOWPASS, nBurnSoundRate, nCutOff, 0.554, 0.0);
607 	Chip->biquadR.init(FILT_LOWPASS, nBurnSoundRate, nCutOff, 0.554, 0.0);
608 }
609 
UPD7759SetRoute(INT32 chip,double nVolume,INT32 nRouteDir)610 void UPD7759SetRoute(INT32 chip, double nVolume, INT32 nRouteDir)
611 {
612 #if defined FBNEO_DEBUG
613 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetRoute called without init\n"));
614 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetRoute called with invalid chip %i\n"), chip);
615 #endif
616 
617 	Chip = Chips[chip];
618 	Chip->volume = nVolume;
619 	Chip->output_dir = nRouteDir;
620 }
621 
UPD7759SetDrqCallback(INT32 chip,drqcallback Callback)622 void UPD7759SetDrqCallback(INT32 chip, drqcallback Callback)
623 {
624 #if defined FBNEO_DEBUG
625 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetDrqCallback called without init\n"));
626 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetDrqCallback called with invalid chip %x\n"), chip);
627 #endif
628 
629 	Chip = Chips[chip];
630 	Chip->drqcallback = Callback;
631 }
632 
UPD7759SetSyncCallback(INT32 chip,INT32 (* pCPUCyclesCB)(),INT32 nCPUMhz)633 void UPD7759SetSyncCallback(INT32 chip, INT32 (*pCPUCyclesCB)(), INT32 nCPUMhz)
634 {
635 #if defined FBNEO_DEBUG
636 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759SetSyncCallback called without init\n"));
637 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759SetSyncCallback called with invalid chip %x\n"), chip);
638 #endif
639 
640 	Chip = Chips[chip];
641 	Chip->pTotalCyclesCB = pCPUCyclesCB;
642 	Chip->nCpuMHZ = nCPUMhz;
643 }
644 
UPD7759BusyRead(INT32 chip)645 INT32 UPD7759BusyRead(INT32 chip)
646 {
647 #if defined FBNEO_DEBUG
648 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759BusyRead called without init\n"));
649 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759BusyRead called with invalid chip %x\n"), chip);
650 #endif
651 
652 	Chip = Chips[chip];
653 	return (Chip->state == STATE_IDLE);
654 }
655 
UPD7759ResetWrite(INT32 chip,UINT8 Data)656 void UPD7759ResetWrite(INT32 chip, UINT8 Data)
657 {
658 #if defined FBNEO_DEBUG
659 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759ResetWrite called without init\n"));
660 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759ResetWrite called with invalid chip %x\n"), chip);
661 #endif
662 
663 	Chip = Chips[chip];
664 
665 	if (Chip->pTotalCyclesCB) UpdateStream(chip, 0);
666 
667 	UINT8 Oldreset = Chip->reset;
668 	Chip->reset = (Data != 0);
669 
670 	if (Oldreset && !Chip->reset) {
671 		UPD7759ResetINT(chip);
672 	}
673 }
674 
UPD7759StartWrite(INT32 chip,UINT8 Data)675 void UPD7759StartWrite(INT32 chip, UINT8 Data)
676 {
677 #if defined FBNEO_DEBUG
678 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759StartWrite called without init\n"));
679 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759StartWrite called with invalid chip %x\n"), chip);
680 #endif
681 
682 	Chip = Chips[chip];
683 
684 	UINT8 Oldstart = Chip->start;
685 	Chip->start = (Data != 0);
686 
687 	if (Chip->pTotalCyclesCB) UpdateStream(chip, 0);
688 
689 	if (Chip->state == STATE_IDLE && !Oldstart && Chip->start && Chip->reset) {
690 		Chip->state = STATE_START;
691 
692 		if (SlaveMode) UPD7759SlaveModeUpdate();
693 	}
694 }
695 
UPD7759PortWrite(INT32 chip,UINT8 Data)696 void UPD7759PortWrite(INT32 chip, UINT8 Data)
697 {
698 #if defined FBNEO_DEBUG
699 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759PortWrite called without init\n"));
700 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759PortWrite called with invalid chip %x\n"), chip);
701 #endif
702 
703 	Chip = Chips[chip];
704 
705 	Chip->fifo_in = Data;
706 }
707 
UPD7759Scan(INT32 nAction,INT32 * pnMin)708 void UPD7759Scan(INT32 nAction, INT32 *pnMin)
709 {
710 #if defined FBNEO_DEBUG
711 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Scan called without init\n"));
712 #endif
713 
714 	if ((nAction & ACB_DRIVER_DATA) == 0) {
715 		return;
716 	}
717 
718 	if (pnMin != NULL) {
719 		*pnMin = 0x029680;
720 	}
721 
722 	if (SlaveMode) {
723 		BurnTimerScan(nAction, pnMin);
724 	}
725 
726 	for (INT32 i = 0; i <= nNumChips; i++) // first chip 0, second chip 1...
727 	{
728 		upd7759_chip *sChip = Chips[i];
729 
730 		SCAN_VAR(sChip->pos);
731 		SCAN_VAR(sChip->step);
732 		SCAN_VAR(sChip->fifo_in);
733 		SCAN_VAR(sChip->reset);
734 		SCAN_VAR(sChip->start);
735 		SCAN_VAR(sChip->drq);
736 		SCAN_VAR(sChip->state);
737 		SCAN_VAR(sChip->clocks_left);
738 		SCAN_VAR(sChip->nibbles_left);
739 		SCAN_VAR(sChip->repeat_count);
740 		SCAN_VAR(sChip->post_drq_state);
741 		SCAN_VAR(sChip->post_drq_clocks);
742 		SCAN_VAR(sChip->req_sample);
743 		SCAN_VAR(sChip->last_sample);
744 		SCAN_VAR(sChip->block_header);
745 		SCAN_VAR(sChip->sample_rate);
746 		SCAN_VAR(sChip->first_valid_header);
747 		SCAN_VAR(sChip->offset);
748 		SCAN_VAR(sChip->repeat_offset);
749 		SCAN_VAR(sChip->adpcm_state);
750 		SCAN_VAR(sChip->adpcm_data);
751 		SCAN_VAR(sChip->sample);
752 		SCAN_VAR(sChip->romoffset);
753 		SCAN_VAR(sChip->volume);
754 		SCAN_VAR(sChip->output_dir);
755 	}
756 }
757 
UPD7759Exit()758 void UPD7759Exit()
759 {
760 #if defined FBNEO_DEBUG
761 	if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Exit called without init\n"));
762 #endif
763 
764 	for (INT32 i = 0; i <= nNumChips; i++) // first chip 0, second chip 1...
765 	{
766 		Chip = Chips[i];
767 		if (Chip) {
768 			Chip->biquadL.exit();
769 			Chip->biquadR.exit();
770 			BurnFree(Chip->out_buf);
771 			BurnFree(Chip->out_buf_linear);
772 			BurnFree(Chip->out_buf_linear_resampled);
773 			BurnFree(Chips[i]);
774 		}
775 	}
776 
777 	if (SlaveMode) {
778 		BurnTimerExit();
779 	}
780 
781 	SlaveMode = 0;
782 
783 	DebugSnd_UPD7759Initted = 0;
784 	nNumChips = 0;
785 }
786