49
69
22f: enable pcm (b0), disable register ram updating (b7)
51
71
The chip has a 0x4000 bytes reverb buffer (the ram from 0x22e).
52
The reverb delay is actually an offset in this buffer. This driver
53
uses some tricks (doubling the buffer size so that the longest
54
reverbs don't fold over the sound to output, and adding a space at
55
the end to fold back overflows in) to be able to do frame-based
56
rendering instead of sample-based.
72
The reverb delay is actually an offset in this buffer.
59
typedef struct _k054539_channel k054539_channel;
60
struct _k054539_channel {
67
typedef struct _k054539_state k054539_state;
68
struct _k054539_state {
69
const k054539_interface *intf;
74
double k054539_gain[8];
75
UINT8 k054539_posreg_latch[8][3];
78
unsigned char regs[0x230];
84
unsigned char *cur_zone;
88
sound_stream * stream;
90
k054539_channel channels[8];
93
INLINE k054539_state *get_safe_token(device_t *device)
95
assert(device != NULL);
96
assert(device->type() == K054539);
97
return (k054539_state *)downcast<legacy_device_base *>(device)->token();
102
void k054539_init_flags(device_t *device, int flags)
104
k054539_state *info = get_safe_token(device);
105
info->k054539_flags = flags;
108
void k054539_set_gain(device_t *device, int channel, double gain)
110
k054539_state *info = get_safe_token(device);
111
if (gain >= 0) info->k054539_gain[channel] = gain;
115
static int k054539_regupdate(k054539_state *info)
117
return !(info->regs[0x22f] & 0x80);
120
static void k054539_keyon(k054539_state *info, int channel)
122
if(k054539_regupdate(info))
123
info->regs[0x22c] |= 1 << channel;
126
static void k054539_keyoff(k054539_state *info, int channel)
128
if(k054539_regupdate(info))
129
info->regs[0x22c] &= ~(1 << channel);
132
static STREAM_UPDATE( k054539_update )
134
k054539_state *info = (k054539_state *)param;
75
void k054539_device::init_flags(int _flags)
80
void k054539_device::set_gain(int channel, double _gain)
83
gain[channel] = _gain;
87
bool k054539_device::regupdate()
89
return !(regs[0x22f] & 0x80);
92
void k054539_device::keyon(int channel)
95
regs[0x22c] |= 1 << channel;
98
void k054539_device::keyoff(int channel)
101
regs[0x22c] &= ~(1 << channel);
104
void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
135
106
#define VOL_CAP 1.80
137
108
static const INT16 dpcm[16] = {
139
110
-64<<8, -49<<8, -36<<8, -25<<8, -16<<8, -9<<8, -4<<8, -1<<8
147
unsigned char *base1, *base2;
148
k054539_channel *chan;
149
stream_sample_t *bufl, *bufr;
150
int cur_pos, cur_pfrac, cur_val, cur_pval;
151
int delta, rdelta, fdelta, pdelta;
152
int vol, bval, pan, i;
154
double gain, lvol, rvol, rbvol;
156
reverb_pos = info->reverb_pos;
157
rbase = (short *)(info->ram);
159
memset(outputs[0], 0, samples*sizeof(*outputs[0]));
160
memset(outputs[1], 0, samples*sizeof(*outputs[1]));
163
rom_mask = info->rom_mask;
165
if(!(info->regs[0x22f] & 1)) return;
167
info->reverb_pos = (reverb_pos + samples) & 0x3fff;
170
for(ch=0; ch<8; ch++)
171
if(info->regs[0x22c] & (1<<ch)) {
172
base1 = info->regs + 0x20*ch;
173
base2 = info->regs + 0x200 + 0x2*ch;
174
chan = info->channels + ch;
176
delta = base1[0x00] | (base1[0x01] << 8) | (base1[0x02] << 16);
180
bval = vol + base1[0x04];
181
if (bval > 255) bval = 255;
184
// DJ Main: 81-87 right, 88 middle, 89-8f left
185
if (pan >= 0x81 && pan <= 0x8f)
188
if (pan >= 0x11 && pan <= 0x1f) pan -= 0x11; else pan = 0x18 - 0x11;
190
gain = info->k054539_gain[ch];
192
lvol = info->voltab[vol] * info->pantab[pan] * gain;
193
if (lvol > VOL_CAP) lvol = VOL_CAP;
195
rvol = info->voltab[vol] * info->pantab[0xe - pan] * gain;
196
if (rvol > VOL_CAP) rvol = VOL_CAP;
198
rbvol= info->voltab[bval] * gain / 2;
199
if (rbvol > VOL_CAP) rbvol = VOL_CAP;
202
INT x FLOAT could be interpreted as INT x (int)FLOAT instead of (float)INT x FLOAT on some compilers
203
causing precision loss. (rdelta - 0x2000) wraps around on zero reverb and the scale factor should
204
actually be 1/freq_ratio because the target is an offset to the reverb buffer not sample source.
206
rdelta = (base1[6] | (base1[7] << 8)) >> 3;
207
// rdelta = (reverb_pos + (int)((rdelta - 0x2000) * info->freq_ratio)) & 0x3fff;
208
rdelta = (int)(rdelta + reverb_pos) & 0x3fff;
210
cur_pos = (base1[0x0c] | (base1[0x0d] << 8) | (base1[0x0e] << 16)) & rom_mask;
216
if(base2[0] & 0x20) {
225
if(cur_pos != chan->pos) {
231
cur_pfrac = chan->pfrac;
233
cur_pval = chan->pval;
236
#define UPDATE_CHANNELS \
238
*bufl++ += (INT16)(cur_val*lvol); \
239
*bufr++ += (INT16)(cur_val*rvol); \
240
rbase[rdelta++] += (INT16)(cur_val*rbvol); \
244
switch(base2[0] & 0xc) {
245
case 0x0: { // 8bit pcm
246
for(i=0; i<samples; i++) {
114
INT16 *rbase = (INT16 *)ram;
116
if(!(regs[0x22f] & 1))
119
for(int sample = 0; sample != samples; sample++) {
121
if(!(flags & DISABLE_REVERB))
122
lval = rval = rbase[reverb_pos];
125
rbase[reverb_pos] = 0;
127
for(int ch=0; ch<8; ch++)
128
if(regs[0x22c] & (1<<ch)) {
129
unsigned char *base1 = regs + 0x20*ch;
130
unsigned char *base2 = regs + 0x200 + 0x2*ch;
131
channel *chan = channels + ch;
133
int delta = base1[0x00] | (base1[0x01] << 8) | (base1[0x02] << 16);
135
int vol = base1[0x03];
137
int bval = vol + base1[0x04];
141
int pan = base1[0x05];
142
// DJ Main: 81-87 right, 88 middle, 89-8f left
143
if (pan >= 0x81 && pan <= 0x8f)
145
else if (pan >= 0x11 && pan <= 0x1f)
150
double cur_gain = gain[ch];
152
double lvol = voltab[vol] * pantab[pan] * cur_gain;
156
double rvol = voltab[vol] * pantab[0xe - pan] * cur_gain;
160
double rbvol= voltab[bval] * cur_gain / 2;
164
int rdelta = (base1[6] | (base1[7] << 8)) >> 3;
165
rdelta = (rdelta + reverb_pos) & 0x3fff;
167
int cur_pos = (base1[0x0c] | (base1[0x0d] << 8) | (base1[0x0e] << 16)) & rom_mask;
170
if(base2[0] & 0x20) {
179
int cur_pfrac, cur_val, cur_pval;
180
if(cur_pos != chan->pos) {
186
cur_pfrac = chan->pfrac;
188
cur_pval = chan->pval;
191
switch(base2[0] & 0xc) {
192
case 0x0: { // 8bit pcm
247
193
cur_pfrac += delta;
248
194
while(cur_pfrac & ~0xffff) {
249
195
cur_pfrac += fdelta;
347
LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
351
chan->pfrac = cur_pfrac;
352
chan->pval = cur_pval;
354
if(k054539_regupdate(info)) {
355
base1[0x0c] = cur_pos & 0xff;
356
base1[0x0d] = cur_pos>> 8 & 0xff;
357
base1[0x0e] = cur_pos>>16 & 0xff;
361
//* drivers should be given the option to disable reverb when things go terribly wrong
362
if(!(info->k054539_flags & K054539_DISABLE_REVERB))
364
for(i=0; i<samples; i++) {
365
short val = rbase[(i+reverb_pos) & 0x3fff];
366
outputs[0][i] += val;
367
outputs[1][i] += val;
371
if(reverb_pos + samples > 0x4000) {
372
i = 0x4000 - reverb_pos;
373
memset(rbase + reverb_pos, 0, i*2);
374
memset(rbase, 0, (samples-i)*2);
376
memset(rbase + reverb_pos, 0, samples*2);
380
static const char gc_msg[32] = "chip : ";
381
static int gc_active=0, gc_chip=0, gc_pos[2]={0,0};
385
int gc_i, gc_j, gc_k, gc_l;
387
if (device->machine().input().code_pressed_once(KEYCODE_DEL_PAD))
390
if (!gc_active) popmessage(NULL);
395
if (device->machine().input().code_pressed_once(KEYCODE_0_PAD)) gc_chip ^= 1;
397
gc_i = gc_pos[gc_chip];
399
if (device->machine().input().code_pressed_once(KEYCODE_4_PAD)) { gc_i--; gc_j = 1; }
400
if (device->machine().input().code_pressed_once(KEYCODE_6_PAD)) { gc_i++; gc_j = 1; }
401
if (gc_j) { gc_i &= 7; gc_pos[gc_chip] = gc_i; }
403
if (device->machine().input().code_pressed_once(KEYCODE_5_PAD))
404
info->k054539_gain[gc_i] = 1.0;
407
gc_fptr = &info->k054539_gain[gc_i];
410
if (device->machine().input().code_pressed_once(KEYCODE_2_PAD)) { gc_f0 -= 0.1; gc_j = 1; }
411
if (device->machine().input().code_pressed_once(KEYCODE_8_PAD)) { gc_f0 += 0.1; gc_j = 1; }
412
if (gc_j) { if (gc_f0 < 0) gc_f0 = 0; *gc_fptr = gc_f0; }
415
gc_fptr = &info->k054539_gain[0] + 8;
416
gc_cptr = gc_msg + 7;
417
for (gc_j=-8; gc_j; gc_j++)
419
gc_k = (int)(gc_fptr[gc_j] * 10);
422
gc_cptr[0] = gc_l + '0';
423
gc_cptr[1] = gc_k + '0';
426
gc_i = (gc_i + gc_i*2 + 6);
427
gc_msg[4] = gc_chip + '0';
429
gc_msg[gc_i+3] = ']';
430
popmessage("%s", gc_msg);
431
gc_msg[gc_i+3] = gc_msg[gc_i] = ' ';
438
static TIMER_CALLBACK( k054539_irq )
440
k054539_state *info = (k054539_state *)ptr;
441
if(info->regs[0x22f] & 0x20)
442
info->intf->irq(info->device);
445
static void k054539_init_chip(device_t *device, k054539_state *info)
449
memset(info->regs, 0, sizeof(info->regs));
450
memset(info->k054539_posreg_latch, 0, sizeof(info->k054539_posreg_latch)); //*
451
info->k054539_flags |= K054539_UPDATE_AT_KEYON; //* make it default until proven otherwise
453
// Real size of 0x4000, the addon is to simplify the reverb buffer computations
454
info->ram = auto_alloc_array(device->machine(), unsigned char, 0x4000*2+device->clock()/50*2);
455
info->reverb_pos = 0;
457
memset(info->ram, 0, 0x4000*2+device->clock()/50*2);
459
const memory_region *region = (info->intf->rgnoverride != NULL) ? device->machine().region(info->intf->rgnoverride) : device->region();
461
info->rom_size = region->bytes();
462
info->rom_mask = 0xffffffffU;
464
if((1U<<i) >= info->rom_size) {
465
info->rom_mask = (1U<<i) - 1;
278
LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
281
lval += cur_val * lvol;
282
rval += cur_val * rvol;
283
rbase[(rdelta + reverb_pos) & 0x1fff] += INT16(cur_val*rbvol);
286
chan->pfrac = cur_pfrac;
287
chan->pval = cur_pval;
291
base1[0x0c] = cur_pos & 0xff;
292
base1[0x0d] = cur_pos>> 8 & 0xff;
293
base1[0x0e] = cur_pos>>16 & 0xff;
296
reverb_pos = (reverb_pos + 1) & 0x1fff;
297
outputs[0][sample] = INT16(lval);
298
outputs[1][sample] = INT16(rval);
303
void k054539_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
305
if(regs[0x22f] & 0x20)
309
void k054539_device::init_chip()
311
memset(regs, 0, sizeof(regs));
312
memset(posreg_latch, 0, sizeof(posreg_latch)); //*
313
flags |= UPDATE_AT_KEYON; //* make it default until proven otherwise
315
ram = auto_alloc_array(machine(), unsigned char, 0x4000);
318
memset(ram, 0, 0x4000);
320
memory_region *reg = (rgnoverride != NULL) ? machine().root_device().memregion(rgnoverride) : region();
322
rom_size = reg->bytes();
323
rom_mask = 0xffffffffU;
324
for(int i=0; i<32; i++)
325
if((1U<<i) >= rom_size) {
326
rom_mask = (1U<<i) - 1;
470
331
// One or more of the registers must be the timer period
471
332
// And anyway, this particular frequency is probably wrong
472
333
// 480 hz is TRUSTED by gokuparo disco stage - the looping sample doesn't line up otherwise
473
device->machine().scheduler().timer_pulse(attotime::from_hz(480), FUNC(k054539_irq), 0, info);
475
info->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock(), info, k054539_update);
477
device->save_item(NAME(info->regs));
478
device->save_pointer(NAME(info->ram), 0x4000);
479
device->save_item(NAME(info->cur_ptr));
334
emu_timer *tm = timer_alloc();
335
tm->adjust(attotime::from_hz(480), 0, attotime::from_hz(480));
338
// If the clock is anything else than 48000, things are going to go wrong.
339
stream = stream_alloc(0, 2, clock());
341
save_item(NAME(regs));
342
save_pointer(NAME(ram), 0x4000);
343
save_item(NAME(cur_ptr));
482
WRITE8_DEVICE_HANDLER( k054539_w )
346
WRITE8_MEMBER(k054539_device::write)
484
k054539_state *info = get_safe_token(device);
489
/* The K054539 has behavior like many other wavetable chips including
490
the Ensoniq 550x and Gravis GF-1: if a voice is active, writing
491
to it's current position is silently ignored.
493
Dadandaan depends on this or the vocals go wrong.
497
voice = offset / 0x20;
498
reg = offset & ~0x20;
500
if(info->regs[0x22c] & (1<<voice))
351
/* The K054539 has behavior like many other wavetable chips including
352
the Ensoniq 550x and Gravis GF-1: if a voice is active, writing
353
to it's current position is silently ignored.
355
Dadandaan depends on this or the vocals go wrong.
502
if (reg >= 0xc && reg <= 0xe)
359
voice = offset / 0x20;
360
reg = offset & ~0x20;
362
if(regs[0x22c] & (1<<voice))
363
if (reg >= 0xc && reg <= 0xe)
510
int latch, offs, ch, pan;
511
UINT8 *regbase, *regptr, *posptr;
513
regbase = info->regs;
514
latch = (info->k054539_flags & K054539_UPDATE_AT_KEYON) && (regbase[0x22f] & 1);
368
bool latch = (flags & UPDATE_AT_KEYON) && (regs[0x22f] & 1);
516
370
if (latch && offset < 0x100)
518
offs = (offset & 0x1f) - 0xc;
372
int offs = (offset & 0x1f) - 0xc;
373
int ch = offset >> 5;
521
375
if (offs >= 0 && offs <= 2)
523
377
// latch writes to the position index registers
524
info->k054539_posreg_latch[ch][offs] = data;
378
posreg_latch[ch][offs] = data;
532
pan = data >= 0x11 && data <= 0x1f ? data - 0x11 : 0x18 - 0x11;
534
info->intf->apan(info->device, info->pantab[pan], info->pantab[0xe - pan]);
386
int pan = data >= 0x11 && data <= 0x1f ? data - 0x11 : 0x18 - 0x11;
388
apan(this, pantab[pan], pantab[0xe - pan]);
540
for(ch=0; ch<8; ch++)
395
for(int ch=0; ch<8; ch++)
542
397
if(data & (1<<ch))
544
posptr = &info->k054539_posreg_latch[ch][0];
545
regptr = regbase + (ch<<5) + 0xc;
399
UINT8 *posptr = &posreg_latch[ch][0];
400
UINT8 *regptr = regs + (ch<<5) + 0xc;
547
402
// update the chip at key-on
548
403
regptr[0] = posptr[0];
549
404
regptr[1] = posptr[1];
550
405
regptr[2] = posptr[2];
552
k054539_keyon(info, ch);
558
for(ch=0; ch<8; ch++)
413
for(int ch=0; ch<8; ch++)
559
414
if(data & (1<<ch))
560
k054539_keyon(info, ch);
565
for(ch=0; ch<8; ch++)
420
for(int ch=0; ch<8; ch++)
566
421
if(data & (1<<ch))
567
k054539_keyoff(info, ch);
571
if(regbase[0x22e] == 0x80)
572
info->cur_zone[info->cur_ptr] = data;
574
if(info->cur_ptr == info->cur_limit)
426
if(regs[0x22e] == 0x80)
427
cur_zone[cur_ptr] = data;
429
if(cur_ptr == cur_limit)
580
data == 0x80 ? info->ram :
581
info->rom + 0x20000*data;
582
info->cur_limit = data == 0x80 ? 0x4000 : 0x20000;
437
cur_limit = data == 0x80 ? 0x4000 : 0x20000;
588
if(regbase[offset] != data) {
443
if(regs[offset] != data) {
589
444
if((offset & 0xff00) == 0) {
590
445
chanoff = offset & 0x1f;
591
446
if(chanoff < 4 || chanoff == 5 ||
662
506
// Factor the 1/4 for the number of channels in the volume (1/8 is too harsh, 1/2 gives clipping)
663
507
// vol=0 -> no attenuation, vol=0x40 -> -36dB
665
info->voltab[i] = pow(10.0, (-36.0 * (double)i / (double)0x40) / 20.0) / 4.0;
508
for(int i=0; i<256; i++)
509
voltab[i] = pow(10.0, (-36.0 * (double)i / (double)0x40) / 20.0) / 4.0;
667
511
// Pan table for the left channel
668
512
// Right channel is identical with inverted index
669
513
// Formula is such that pan[i]**2+pan[0xe-i]**2 = 1 (constant output power)
670
514
// and pan[0xe] = 1 (full panning)
672
info->pantab[i] = sqrt((double)i) / sqrt((double)0xe);
674
k054539_init_chip(device, info);
676
device->machine().save().register_postload(save_prepost_delegate(FUNC(reset_zones), info));
515
for(int i=0; i<0xf; i++)
516
pantab[i] = sqrt((double)i) / sqrt((double)0xe);
520
machine().save().register_postload(save_prepost_delegate(FUNC(k054539_device::reset_zones), this));
682
/**************************************************************************
684
**************************************************************************/
686
DEVICE_GET_INFO( k054539 )
523
void k054539_device::device_reset()
690
/* --- the following bits of info are returned as 64-bit signed integers --- */
691
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(k054539_state); break;
693
/* --- the following bits of info are returned as pointers to data or functions --- */
694
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( k054539 ); break;
695
case DEVINFO_FCT_STOP: /* nothing */ break;
696
case DEVINFO_FCT_RESET: /* nothing */ break;
698
/* --- the following bits of info are returned as NULL-terminated strings --- */
699
case DEVINFO_STR_NAME: strcpy(info->s, "K054539"); break;
700
case DEVINFO_STR_FAMILY: strcpy(info->s, "Konami custom"); break;
701
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
702
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
703
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
708
DEFINE_LEGACY_SOUND_DEVICE(K054539, k054539);