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