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