1 // copyright-holders:Aaron Giles
2 /*********************************************************
3 
4     Konami 054539 (TOP) PCM Sound Chip
5 
6     A lot of information comes from Amuse.
7     Big thanks to them.
8 
9 *********************************************************/
10 
11 // IRQ handling is disabled (handled in driver) for now...
12 
13 // Jan 19, 2018: added cubic resampling.
14 
15 #include "burnint.h"
16 #include "math.h"
17 #include "k054539.h"
18 
19 static INT32 nNumChips = 0;
20 
21 typedef struct _k054539_interface k054539_interface;
22 struct _k054539_interface
23 {
24 	const char *rgnoverride;
25 	void (*apan)(double, double);
26 //	void (*irq)(running_machine *);
27 };
28 
29 struct k054539_channel {
30 	UINT32 pos;
31 	UINT32 pfrac;
32 	INT32 val;
33 	INT32 pval;
34 	double lvol;
35 	double rvol;
36 };
37 
38 struct k054539_info {
39 	k054539_interface intf;
40 	double voltab[256];
41 	double pantab[0xf];
42 
43 	double k054539_gain[8];
44 	UINT8 k054539_posreg_latch[8][3];
45 	INT32 k054539_flags;
46 
47 	UINT8 regs[0x230];
48 	UINT8 *ram;
49 	INT32 reverb_pos;
50 
51 	INT32 cur_ptr;
52 	INT32 cur_limit;
53 	UINT8 *cur_zone;
54 	UINT8 *rom;
55 	UINT32 rom_size;
56 	UINT32 rom_mask;
57 
58 	INT32 clock;
59 
60 	double volume[2];
61 	INT32 output_dir[2];
62 
63 	k054539_channel channels[8];
64 };
65 
66 static k054539_info Chips[2];
67 static k054539_info *info;
68 
69 // for resampling
70 static INT16 *soundbuf[2] = { NULL, NULL };
71 static UINT32 nSampleSize;
72 static INT32 nFractionalPosition[2];
73 static INT32 nPosition[2];
74 
K054539_init_flags(INT32 chip,INT32 flags)75 void K054539_init_flags(INT32 chip, INT32 flags)
76 {
77 #if defined FBA_DEBUG
78 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539_init_flags called without init\n"));
79 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539_init_flags called with invalid chip %x\n"), chip);
80 #endif
81 
82 	info = &Chips[chip];
83 	info->k054539_flags = flags;
84 }
85 
K054539_set_gain(INT32 chip,INT32 channel,double gain)86 void K054539_set_gain(INT32 chip, INT32 channel, double gain)
87 {
88 #if defined FBA_DEBUG
89 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539_set_gain called without init\n"));
90 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539_set_gain called with invalid chip %x\n"), chip);
91 #endif
92 
93 	info = &Chips[chip];
94 	if (gain >= 0) info->k054539_gain[channel] = gain;
95 }
96 
k054539_regupdate()97 static INT32 k054539_regupdate()
98 {
99 #if defined FBA_DEBUG
100 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539_regupdate called without init\n"));
101 #endif
102 
103 	return !(info->regs[0x22f] & 0x80);
104 }
105 
k054539_keyon(INT32 channel)106 static void k054539_keyon(INT32 channel)
107 {
108 #if defined FBA_DEBUG
109 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539_keyon called without init\n"));
110 #endif
111 
112 	if(k054539_regupdate())
113 		info->regs[0x22c] |= 1 << channel;
114 }
115 
k054539_keyoff(INT32 channel)116 static void k054539_keyoff(INT32 channel)
117 {
118 #if defined FBA_DEBUG
119 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539_keyoff called without init\n"));
120 #endif
121 
122 	if(k054539_regupdate())
123 		info->regs[0x22c] &= ~(1 << channel);
124 }
125 
K054539Write(INT32 chip,INT32 offset,UINT8 data)126 void K054539Write(INT32 chip, INT32 offset, UINT8 data)
127 {
128 #if defined FBA_DEBUG
129 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Write called without init\n"));
130 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539Write called with invalid chip %x\n"), chip);
131 #endif
132 
133 	info = &Chips[chip];
134 
135 	INT32 latch, offs, ch, pan;
136 	UINT8 *regbase, *regptr, *posptr;
137 
138 	regbase = info->regs;
139 	latch = (info->k054539_flags & K054539_UPDATE_AT_KEYON) && (regbase[0x22f] & 1);
140 
141 	if (latch && offset < 0x100)
142 	{
143 		offs = (offset & 0x1f) - 0xc;
144 		ch = offset >> 5;
145 
146 		if (offs >= 0 && offs <= 2)
147 		{
148 			// latch writes to the position index registers
149 			info->k054539_posreg_latch[ch][offs] = data;
150 			return;
151 		}
152 	}
153 
154 	else switch(offset)
155 	{
156 		case 0x13f:
157 			pan = data >= 0x11 && data <= 0x1f ? data - 0x11 : 0x18 - 0x11;
158 			if(info->intf.apan)
159 				info->intf.apan(info->pantab[pan], info->pantab[0xe - pan]);
160 		break;
161 
162 		case 0x214:
163 			if (latch)
164 			{
165 				for(ch=0; ch<8; ch++)
166 				{
167 					if(data & (1<<ch))
168 					{
169 						posptr = &info->k054539_posreg_latch[ch][0];
170 						regptr = regbase + (ch<<5) + 0xc;
171 
172 						// update the chip at key-on
173 						regptr[0] = posptr[0];
174 						regptr[1] = posptr[1];
175 						regptr[2] = posptr[2];
176 
177 						k054539_keyon(ch);
178 					}
179 				}
180 			}
181 			else
182 			{
183 				for(ch=0; ch<8; ch++)
184 					if(data & (1<<ch))
185 						k054539_keyon(ch);
186 			}
187 		break;
188 
189 		case 0x215:
190 			for(ch=0; ch<8; ch++)
191 				if(data & (1<<ch))
192 					k054539_keyoff(ch);
193 		break;
194 
195 		case 0x22d:
196 			if(regbase[0x22e] == 0x80)
197 				info->cur_zone[info->cur_ptr] = data;
198 			info->cur_ptr++;
199 			if(info->cur_ptr == info->cur_limit)
200 				info->cur_ptr = 0;
201 		break;
202 
203 		case 0x22e:
204 			info->cur_zone =
205 				data == 0x80 ? info->ram :
206 				info->rom + 0x20000*data;
207 			info->cur_limit = data == 0x80 ? 0x4000 : 0x20000;
208 			info->cur_ptr = 0;
209 		break;
210 
211 		default:
212 		break;
213 	}
214 
215 	regbase[offset] = data;
216 }
217 
K054539Read(INT32 chip,INT32 offset)218 UINT8 K054539Read(INT32 chip, INT32 offset)
219 {
220 #if defined FBA_DEBUG
221 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Read called without init\n"));
222 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539Read called with invalid chip %x\n"), chip);
223 #endif
224 
225 	info = &Chips[chip];
226 
227 	switch(offset) {
228 	case 0x22d:
229 		if(info->regs[0x22f] & 0x10) {
230 			UINT8 res = info->cur_zone[info->cur_ptr];
231 			info->cur_ptr++;
232 			if(info->cur_ptr == info->cur_limit)
233 				info->cur_ptr = 0;
234 			return res;
235 		} else
236 			return 0;
237 
238 	case 0x22c:
239 		break;
240 
241 	default:
242 		break;
243 	}
244 
245 	return info->regs[offset];
246 }
247 
K054539Reset(INT32 chip)248 void K054539Reset(INT32 chip)
249 {
250 #if defined FBA_DEBUG
251 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Reset called without init\n"));
252 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539Reset called with invalid chip %x\n"), chip);
253 #endif
254 
255 	info = &Chips[chip];
256 
257 	info->reverb_pos = 0;
258 	info->cur_ptr = 0;
259 	info->cur_zone = info->rom;
260 	memset(info->ram, 0, 0x4000*2+info->clock/50*2);
261 	memset(info->regs, 0, sizeof(info->regs));
262 	memset(info->k054539_posreg_latch, 0, sizeof(info->k054539_posreg_latch));
263 	memset(info->channels, 0, sizeof(info->channels));
264 	memset(soundbuf[0], 0, (800 * sizeof(INT16) * 2) * 4);
265 	memset(soundbuf[1], 0, (800 * sizeof(INT16) * 2) * 4);
266 }
267 
k054539_init_chip(INT32 clock,UINT8 * rom,INT32 nLen)268 static void k054539_init_chip(INT32 clock, UINT8 *rom, INT32 nLen)
269 {
270 	memset(info->regs, 0, sizeof(info->regs));
271 	memset(info->k054539_posreg_latch, 0, sizeof(info->k054539_posreg_latch));
272 	info->k054539_flags |= K054539_UPDATE_AT_KEYON; // make it default until proven otherwise
273 
274 	// Real size of 0x4000, the addon is to simplify the reverb buffer computations
275 	info->ram = (UINT8*)BurnMalloc(0x4000*2+clock/50*2);
276 	info->reverb_pos = 0;
277 	info->cur_ptr = 0;
278 	memset(info->ram, 0, 0x4000*2+clock/50*2);
279 
280 	info->rom = rom;
281 	info->rom_size = nLen;
282 	info->rom_mask = 0xffffffffU;
283 	for (INT32 i = 0; i < 32; i++) {
284 		if((1U<<i) >= info->rom_size) {
285 			info->rom_mask = (1U<<i) - 1;
286 			break;
287 		}
288 	}
289 
290 	info->volume[BURN_SND_K054539_ROUTE_1] = 1.00;
291 	info->volume[BURN_SND_K054539_ROUTE_2] = 1.00;
292 	info->output_dir[BURN_SND_K054539_ROUTE_1] = BURN_SND_ROUTE_BOTH;
293 	info->output_dir[BURN_SND_K054539_ROUTE_2] = BURN_SND_ROUTE_BOTH;
294 
295 	//	if(info->intf->irq)
296 //		timer_pulse(ATTOTIME_IN_HZ(480), info, 0, k054539_irq); // 10% of usual clock...
297 }
298 
K054539SetApanCallback(INT32 chip,void (* ApanCB)(double,double))299 void K054539SetApanCallback(INT32 chip, void (*ApanCB)(double, double))
300 {
301 	info = &Chips[chip];
302 	info->intf.apan = ApanCB;
303 }
304 
K054539Init(INT32 chip,INT32 clock,UINT8 * rom,INT32 nLen)305 void K054539Init(INT32 chip, INT32 clock, UINT8 *rom, INT32 nLen)
306 {
307 	DebugSnd_K054539Initted = 1;
308 
309 	INT32 i;
310 
311 	memset(&Chips[chip], 0, sizeof(k054539_info));
312 
313 	info = &Chips[chip];
314 
315 	info->clock = clock;
316 
317 	nSampleSize = (UINT32)48000 * (1 << 16) / nBurnSoundRate;
318 	nFractionalPosition[chip] = 0;
319 	nPosition[chip] = 0;
320 
321 	for (i = 0; i < 8; i++)
322 		info->k054539_gain[i] = 1.0;
323 
324 	info->k054539_flags = K054539_RESET_FLAGS;
325 
326 	for(i=0; i<256; i++)
327 		info->voltab[i] = pow(10.0, (-36.0 * (double)i / (double)0x40) / 20.0) / 4.0;
328 
329 	for(i=0; i<0xf; i++)
330 		info->pantab[i] = sqrt((double)i)  / sqrt((double)0xe);
331 
332 	k054539_init_chip(clock, rom, nLen);
333 
334 	if (soundbuf[0] == NULL) soundbuf[0] = (INT16*)BurnMalloc((800 * sizeof(INT16) * 2) * 4);
335 	if (soundbuf[1] == NULL) soundbuf[1] = (INT16*)BurnMalloc((800 * sizeof(INT16) * 2) * 4);
336 
337 	nNumChips = chip;
338 }
339 
K054539SetRoute(INT32 chip,INT32 nIndex,double nVolume,INT32 nRouteDir)340 void K054539SetRoute(INT32 chip, INT32 nIndex, double nVolume, INT32 nRouteDir)
341 {
342 #if defined FBA_DEBUG
343 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539SetRoute called without init\n"));
344 	if (chip >nNumChips) bprintf(PRINT_ERROR, _T("K054539SetRoute called with invalid chip %x\n"), chip);
345 	if (nIndex < 0 || nIndex > 1) bprintf(PRINT_ERROR, _T("K054539SetRoute called with invalid index %i\n"), nIndex);
346 #endif
347 
348 	info = &Chips[chip];
349 
350 	info->volume[nIndex] = nVolume;
351 	info->output_dir[nIndex] = nRouteDir;
352 }
353 
K054539Exit()354 void K054539Exit()
355 {
356 #if defined FBA_DEBUG
357 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Exit called without init\n"));
358 #endif
359 
360 	if (!DebugSnd_K054539Initted) return;
361 
362 	BurnFree (soundbuf[0]);
363 	BurnFree (soundbuf[1]);
364 	soundbuf[0] = NULL;
365 	soundbuf[1] = NULL;
366 
367 	for (INT32 i = 0; i < 2; i++) {
368 		info = &Chips[i];
369 		BurnFree (info->ram);
370 	}
371 
372 	DebugSnd_K054539Initted = 0;
373 	nNumChips = 0;
374 }
375 
signdiff(INT32 a,INT32 b)376 static INT32 signdiff(INT32 a, INT32 b)
377 {
378 	return ((a >= 0 && b < 0) || (a < 0 && b >= 0));
379 }
380 
K054539Update(INT32 chip,INT16 * outputs,INT32 samples_len)381 void K054539Update(INT32 chip, INT16 *outputs, INT32 samples_len)
382 {
383 #if defined FBA_DEBUG
384 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Update called without init\n"));
385 	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("K054539Update called with invalid chip %x\n"), chip);
386 #endif
387 
388 	info = &Chips[chip];
389 #define VOL_CAP 1.80
390 
391 	static const INT16 dpcm[16] = {
392 		0<<8, 1<<8, 4<<8, 9<<8, 16<<8, 25<<8, 36<<8, 49<<8,
393 		0, -49<<8, -36<<8, -25<<8, -16<<8, -9<<8, -4<<8, -1<<8
394 		//-64<<8, -49<<8, -36<<8, -25<<8, -16<<8, -9<<8, -4<<8, -1<<8
395 	};
396 
397 	INT16 *rbase = (INT16 *)(info->ram);
398 	UINT8 *rom = info->rom;
399 	UINT32 rom_mask = info->rom_mask;
400 
401 	if(!(info->regs[0x22f] & 1))
402 		return;
403 
404 	// re-sampleizer pt.1
405 	INT32 nSamplesNeeded = ((((((48000 * 1000) / nBurnFPS) * samples_len) / nBurnSoundLen)) / 10);
406 	if (nBurnSoundRate < 44100) nSamplesNeeded += 2; // so we don't end up with negative nPosition[chip] below
407 
408 	INT16 *pBufL = soundbuf[chip] + 0 * 4096 + 5 + nPosition[chip];
409 	INT16 *pBufR = soundbuf[chip] + 1 * 4096 + 5 + nPosition[chip];
410 
411 	for (INT32 sample = 0; sample < (nSamplesNeeded - nPosition[chip]); sample++) {
412 		double lval, rval;
413 
414 		if(!(info->k054539_flags & K054539_DISABLE_REVERB))
415 			lval = rval = rbase[info->reverb_pos];
416 		else
417 			lval = rval = 0;
418 		rbase[info->reverb_pos] = 0;
419 
420 		for(INT32 ch=0; ch<8; ch++)
421 			if(info->regs[0x22c] & (1<<ch)) {
422 				UINT8 *base1 = info->regs + 0x20*ch;
423 				UINT8 *base2 = info->regs + 0x200 + 0x2*ch;
424 				struct k054539_channel *chan = info->channels + ch;
425 
426 				INT32 delta = base1[0x00] | (base1[0x01] << 8) | (base1[0x02] << 16);
427 
428 				INT32 vol = base1[0x03];
429 
430 				INT32 bval = vol + base1[0x04];
431 				if (bval > 255)
432 					bval = 255;
433 
434 				INT32 pan = base1[0x05];
435 				// DJ Main: 81-87 right, 88 middle, 89-8f left
436 				if (pan >= 0x81 && pan <= 0x8f)
437 					pan -= 0x81;
438 				else if (pan >= 0x11 && pan <= 0x1f)
439 					pan -= 0x11;
440 				else
441 					pan = 0x18 - 0x11;
442 
443 				double cur_gain = info->k054539_gain[ch];
444 
445 				double lvol = info->voltab[vol] * info->pantab[pan] * cur_gain;
446 				if (lvol > VOL_CAP)
447 					lvol = VOL_CAP;
448 
449 				double rvol = info->voltab[vol] * info->pantab[0xe - pan] * cur_gain;
450 				if (rvol > VOL_CAP)
451 					rvol = VOL_CAP;
452 
453 				double rbvol= info->voltab[bval] * cur_gain / 2;
454 				if (rbvol > VOL_CAP)
455 					rbvol = VOL_CAP;
456 
457 				INT32 rdelta = (base1[6] | (base1[7] << 8)) >> 3;
458 				rdelta = (rdelta + info->reverb_pos) & 0x3fff;
459 
460 				INT32 cur_pos = (base1[0x0c] | (base1[0x0d] << 8) | (base1[0x0e] << 16)) & rom_mask;
461 
462 				INT32 fdelta, pdelta;
463 				if(base2[0] & 0x20) {
464 					delta = -delta;
465 					fdelta = +0x10000;
466 					pdelta = -1;
467 				} else {
468 					fdelta = -0x10000;
469 					pdelta = +1;
470 				}
471 
472 				INT32 cur_pfrac, cur_val, cur_pval, cur_pval2;
473 				if(cur_pos != (INT32)chan->pos) {
474 					chan->pos = cur_pos;
475 					cur_pfrac = 0;
476 					cur_val = 0;
477 					cur_pval = 0;
478 				} else {
479 					cur_pfrac = chan->pfrac;
480 					cur_val = chan->val;
481 					cur_pval = chan->pval;
482 				}
483 
484 				switch(base2[0] & 0xc) {
485 				case 0x0: { // 8bit pcm
486 					cur_pfrac += delta;
487 					while(cur_pfrac & ~0xffff) {
488 						cur_pfrac += fdelta;
489 						cur_pos += pdelta;
490 
491 						cur_pval = cur_val;
492 						cur_val = (INT16)(rom[cur_pos] << 8);
493 						if(cur_val == (INT16)0x8000 && (base2[1] & 1)) {
494 							cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
495 							cur_val = (INT16)(rom[cur_pos] << 8);
496 						}
497 						if(cur_val == (INT16)0x8000) {
498 							k054539_keyoff(ch);
499 							cur_val = 0;
500 							break;
501 						}
502 					}
503 					break;
504 				}
505 
506 				case 0x4: { // 16bit pcm lsb first
507 					pdelta <<= 1;
508 
509 					cur_pfrac += delta;
510 					while(cur_pfrac & ~0xffff) {
511 						cur_pfrac += fdelta;
512 						cur_pos += pdelta;
513 
514 						cur_pval = cur_val;
515 						cur_val = (INT16)(rom[cur_pos] | rom[cur_pos+1]<<8);
516 						if(cur_val == (INT16)0x8000 && (base2[1] & 1)) {
517 							cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
518 							cur_val = (INT16)(rom[cur_pos] | rom[cur_pos+1]<<8);
519 						}
520 						if(cur_val == (INT16)0x8000) {
521 							k054539_keyoff(ch);
522 							cur_val = 0;
523 							break;
524 						}
525 					}
526 					break;
527 				}
528 
529 				case 0x8: { // 4bit dpcm
530 					cur_pos <<= 1;
531 					cur_pfrac <<= 1;
532 					if(cur_pfrac & 0x10000) {
533 						cur_pfrac &= 0xffff;
534 						cur_pos |= 1;
535 					}
536 
537 					cur_pfrac += delta;
538 					while(cur_pfrac & ~0xffff) {
539 						cur_pfrac += fdelta;
540 						cur_pos += pdelta;
541 
542 						cur_pval2 = cur_pval;
543 						cur_pval = cur_val;
544 						cur_val = rom[cur_pos>>1];
545 						if(cur_val == 0x88 && (base2[1] & 1)) {
546 							cur_pos = ((base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask) << 1;
547 							cur_val = rom[cur_pos>>1];
548 						}
549 						if(cur_val == 0x88) {
550 							k054539_keyoff(ch);
551 							//bprintf(0, _T("4bit dpcm off ch %X. cur_val %X cur_pval %X cur_pval2 %X\n"), ch, cur_val, cur_pval, cur_pval2);
552 							// at the end of the sample: if there's a huge jump between pval and pval2, use pval2
553 							if (signdiff(cur_pval, cur_pval2))
554 								cur_pval = cur_pval2;
555 							cur_val = cur_pval;
556 							break;
557 						}
558 						if(cur_pos & 1)
559 							cur_val >>= 4;
560 						else
561 							cur_val &= 15;
562 						cur_val = cur_pval + dpcm[cur_val];
563 						if(cur_val < -32768)
564 							cur_val = -32768;
565 						else if(cur_val > 32767)
566 							cur_val = 32767;
567 					}
568 
569 					cur_pfrac >>= 1;
570 					if(cur_pos & 1)
571 						cur_pfrac |= 0x8000;
572 					cur_pos >>= 1;
573 					break;
574 				}
575 				default:
576 					//LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
577 					break;
578 				}
579 				lval += cur_val * lvol;
580 				rval += cur_val * rvol;
581 				rbase[(rdelta + info->reverb_pos) & 0x1fff] += INT16(cur_val*rbvol);
582 
583 				chan->lvol = lvol;
584 				chan->rvol = rvol;
585 
586 				chan->pos = cur_pos;
587 				chan->pfrac = cur_pfrac;
588 				chan->pval = cur_pval;
589 				chan->val = cur_val;
590 
591 				if(k054539_regupdate()) {
592 					base1[0x0c] = cur_pos     & 0xff;
593 					base1[0x0d] = cur_pos>> 8 & 0xff;
594 					base1[0x0e] = cur_pos>>16 & 0xff;
595 				}
596 			} else { // get rampy to remove dc offset clicks -dink [Dec. 1, 2017]
597 				struct k054539_channel *chan = info->channels + ch;
598 
599 				if (chan->val > 0) {
600 					chan->val -= ((chan->val >  4) ? 4 : 1);
601 				} else {
602 					chan->val += ((chan->val < -4) ? 4 : 1);
603 				}
604 
605 				lval += chan->val * chan->lvol;
606 				rval += chan->val * chan->rvol;
607 			}
608 		info->reverb_pos = (info->reverb_pos + 1) & 0x1fff;
609 
610 		INT32 nLeftSample = 0, nRightSample = 0;
611 
612 		if ((info->output_dir[BURN_SND_K054539_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
613 			nLeftSample += (INT32)(lval * info->volume[BURN_SND_K054539_ROUTE_1]);
614 		}
615 		if ((info->output_dir[BURN_SND_K054539_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
616 			nRightSample += (INT32)(rval * info->volume[BURN_SND_K054539_ROUTE_1]);
617 		}
618 
619 		if ((info->output_dir[BURN_SND_K054539_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
620 			nLeftSample += (INT32)(lval * info->volume[BURN_SND_K054539_ROUTE_2]);
621 		}
622 		if ((info->output_dir[BURN_SND_K054539_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
623 			nRightSample += (INT32)(rval * info->volume[BURN_SND_K054539_ROUTE_2]);
624 		}
625 
626 		pBufL[0] = BURN_SND_CLIP(nLeftSample);  pBufL++;
627 		pBufR[0] = BURN_SND_CLIP(nRightSample); pBufR++;
628 	}
629 
630 	pBufL = soundbuf[chip] + 0 * 4096 + 5;
631 	pBufR = soundbuf[chip] + 1 * 4096 + 5;
632 
633 	for (INT32 i = (nFractionalPosition[chip] & 0xFFFF0000) >> 15; i < (samples_len << 1); i += 2, nFractionalPosition[chip] += nSampleSize) {
634 		INT32 nLeftSample[4] = {0, 0, 0, 0};
635 		INT32 nRightSample[4] = {0, 0, 0, 0};
636 		INT32 nTotalLeftSample, nTotalRightSample;
637 
638 		nLeftSample[0] += (INT32)(pBufL[(nFractionalPosition[chip] >> 16) - 3]);
639 		nLeftSample[1] += (INT32)(pBufL[(nFractionalPosition[chip] >> 16) - 2]);
640 		nLeftSample[2] += (INT32)(pBufL[(nFractionalPosition[chip] >> 16) - 1]);
641 		nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition[chip] >> 16) - 0]);
642 
643 		nRightSample[0] += (INT32)(pBufR[(nFractionalPosition[chip] >> 16) - 3]);
644 		nRightSample[1] += (INT32)(pBufR[(nFractionalPosition[chip] >> 16) - 2]);
645 		nRightSample[2] += (INT32)(pBufR[(nFractionalPosition[chip] >> 16) - 1]);
646 		nRightSample[3] += (INT32)(pBufR[(nFractionalPosition[chip] >> 16) - 0]);
647 
648 		nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition[chip] >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
649 		nTotalRightSample = INTERPOLATE4PS_16BIT((nFractionalPosition[chip] >> 4) & 0x0fff, nRightSample[0], nRightSample[1], nRightSample[2], nRightSample[3]);
650 
651 		nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample);
652 		nTotalRightSample = BURN_SND_CLIP(nTotalRightSample);
653 
654 		outputs[i + 0] = BURN_SND_CLIP(outputs[i + 0] + nTotalLeftSample);
655 		outputs[i + 1] = BURN_SND_CLIP(outputs[i + 1] + nTotalRightSample);
656 	}
657 
658 	if (samples_len >= nBurnSoundLen) {
659 		INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition[chip] >> 16);
660 		//if (nExtraSamples) bprintf(0, _T("%X, "), nExtraSamples);
661 
662 		for (INT32 i = -4; i < nExtraSamples; i++) {
663 			pBufL[i] = pBufL[(nFractionalPosition[chip] >> 16) + i];
664 			pBufR[i] = pBufR[(nFractionalPosition[chip] >> 16) + i];
665 		}
666 
667 		nFractionalPosition[chip] &= 0xFFFF;
668 
669 		nPosition[chip] = nExtraSamples;
670 	}
671 	//  -4 -3 -2 -1 0 +1 +2 +3 +4
672 }
673 
K054539Scan(INT32 nAction,INT32 *)674 void K054539Scan(INT32 nAction, INT32 *)
675 {
676 #if defined FBA_DEBUG
677 	if (!DebugSnd_K054539Initted) bprintf(PRINT_ERROR, _T("K054539Scan called without init\n"));
678 #endif
679 
680 	struct BurnArea ba;
681 	char szName[32];
682 
683 	if ((nAction & ACB_DRIVER_DATA) == 0) {
684 		return;
685 	}
686 
687 	for (INT32 i = 0; i < nNumChips+1; i++) {
688 		info = &Chips[i];
689 
690 		memset(&ba, 0, sizeof(ba));
691 		sprintf(szName, "K054539 Latch %d", i);
692 		ba.Data		= info->k054539_posreg_latch;
693 		ba.nLen		= sizeof(info->k054539_posreg_latch);
694 		ba.nAddress = 0;
695 		ba.szName	= szName;
696 		BurnAcb(&ba);
697 
698 		sprintf(szName, "K054539 Regs # %d", i);
699 		ba.Data		= info->regs;
700 		ba.nLen		= sizeof(info->regs);
701 		ba.nAddress = 0;
702 		ba.szName	= szName;
703 		BurnAcb(&ba);
704 
705 		sprintf(szName, "K054539 Ram # %d", i);
706 		ba.Data		= info->ram;
707 		ba.nLen		= 0x4000*2+info->clock/50*2;
708 		ba.nAddress = 0;
709 		ba.szName	= szName;
710 		BurnAcb(&ba);
711 
712 		sprintf(szName, "K054539 Channels # %d", i);
713 		ba.Data		= &info->channels;
714 		ba.nLen		= sizeof(info->channels);
715 		ba.nAddress = 0;
716 		ba.szName	= szName;
717 		BurnAcb(&ba);
718 
719 		SCAN_VAR(info->reverb_pos);
720 		SCAN_VAR(info->cur_ptr);
721 		SCAN_VAR(info->cur_limit);
722 
723 		if (nAction & ACB_WRITE) {
724 			INT32 data = info->regs[0x22e];
725 			info->cur_zone =
726 				data == 0x80 ? info->ram :
727 				info->rom + 0x20000*data;
728 			info->cur_limit = data == 0x80 ? 0x4000 : 0x20000;
729 
730 			for (INT32 chip = 0; chip < 2; chip++) {
731 				nFractionalPosition[chip] = 0;
732 				nPosition[chip] = 0;
733 			}
734 			memset(soundbuf[0], 0, (800 * sizeof(INT16) * 2) * 4);
735 			memset(soundbuf[1], 0, (800 * sizeof(INT16) * 2) * 4);
736 		}
737 	}
738 }
739