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