~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/emu/sound/k054539.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Emmanuel Kasper, Jordi Mallach
  • Date: 2012-06-05 20:02:23 UTC
  • mfrom: (0.3.1) (0.1.4)
  • Revision ID: package-import@ubuntu.com-20120605200223-gnlpogjrg6oqe9md
Tags: 0.146-1
[ Emmanuel Kasper ]
* New upstream release
* Drop patch to fix man pages section and patches to link with flac 
  and jpeg system lib: all this has been pushed upstream by Cesare Falco
* Add DM-Upload-Allowed: yes field.

[ Jordi Mallach ]
* Create a "gnu" TARGETOS stanza that defines NO_AFFINITY_NP.
* Stop setting TARGETOS to "unix" in d/rules. It should be autodetected,
  and set to the appropriate value.
* mame_manpage_section.patch: Change mame's manpage section to 6 (games),
  in the TH declaration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "emu.h"
21
21
#include "k054539.h"
22
22
 
 
23
const device_type K054539 = &device_creator<k054539_device>;
 
24
 
23
25
#define CHANNEL_DEBUG 0
24
26
#define VERBOSE 0
25
27
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
26
28
 
 
29
k054539_device::k054539_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
 
30
        : device_t(mconfig, K054539, "K054539", "k054539", tag, owner, clock),
 
31
          device_sound_interface(mconfig, *this)
 
32
{
 
33
}
 
34
 
 
35
 
 
36
//-------------------------------------------------
 
37
//  static_set_interface - configuration helper
 
38
//  to set the interface
 
39
//-------------------------------------------------
 
40
 
 
41
void k054539_device::static_set_interface(device_t &device, const k054539_interface &interface)
 
42
{
 
43
        k054539_device &k = downcast<k054539_device &>(device);
 
44
        static_cast<k054539_interface &>(k) = interface;
 
45
}
 
46
 
27
47
/* Registers:
28
48
   00..ff: 20 bytes/channel, 8 channels
29
49
     00..02: pitch (lsb, mid, msb)
49
69
   22f: enable pcm (b0), disable register ram updating (b7)
50
70
 
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.
57
73
*/
58
74
 
59
 
typedef struct _k054539_channel k054539_channel;
60
 
struct _k054539_channel {
61
 
        UINT32 pos;
62
 
        UINT32 pfrac;
63
 
        INT32 val;
64
 
        INT32 pval;
65
 
};
66
 
 
67
 
typedef struct _k054539_state k054539_state;
68
 
struct _k054539_state {
69
 
        const k054539_interface *intf;
70
 
        device_t *device;
71
 
        double voltab[256];
72
 
        double pantab[0xf];
73
 
 
74
 
        double k054539_gain[8];
75
 
        UINT8 k054539_posreg_latch[8][3];
76
 
        int k054539_flags;
77
 
 
78
 
        unsigned char regs[0x230];
79
 
        unsigned char *ram;
80
 
        int reverb_pos;
81
 
 
82
 
        INT32 cur_ptr;
83
 
        int cur_limit;
84
 
        unsigned char *cur_zone;
85
 
        unsigned char *rom;
86
 
        UINT32 rom_size;
87
 
        UINT32 rom_mask;
88
 
        sound_stream * stream;
89
 
 
90
 
        k054539_channel channels[8];
91
 
};
92
 
 
93
 
INLINE k054539_state *get_safe_token(device_t *device)
94
 
{
95
 
        assert(device != NULL);
96
 
        assert(device->type() == K054539);
97
 
        return (k054539_state *)downcast<legacy_device_base *>(device)->token();
98
 
}
99
 
 
100
 
//*
101
 
 
102
 
void k054539_init_flags(device_t *device, int flags)
103
 
{
104
 
        k054539_state *info = get_safe_token(device);
105
 
        info->k054539_flags = flags;
106
 
}
107
 
 
108
 
void k054539_set_gain(device_t *device, int channel, double gain)
109
 
{
110
 
        k054539_state *info = get_safe_token(device);
111
 
        if (gain >= 0) info->k054539_gain[channel] = gain;
112
 
}
113
 
//*
114
 
 
115
 
static int k054539_regupdate(k054539_state *info)
116
 
{
117
 
        return !(info->regs[0x22f] & 0x80);
118
 
}
119
 
 
120
 
static void k054539_keyon(k054539_state *info, int channel)
121
 
{
122
 
        if(k054539_regupdate(info))
123
 
                info->regs[0x22c] |= 1 << channel;
124
 
}
125
 
 
126
 
static void k054539_keyoff(k054539_state *info, int channel)
127
 
{
128
 
        if(k054539_regupdate(info))
129
 
                info->regs[0x22c] &= ~(1 << channel);
130
 
}
131
 
 
132
 
static STREAM_UPDATE( k054539_update )
133
 
{
134
 
        k054539_state *info = (k054539_state *)param;
 
75
void k054539_device::init_flags(int _flags)
 
76
{
 
77
        flags = _flags;
 
78
}
 
79
 
 
80
void k054539_device::set_gain(int channel, double _gain)
 
81
{
 
82
        if(_gain >= 0)
 
83
                gain[channel] = _gain;
 
84
}
 
85
//*
 
86
 
 
87
bool k054539_device::regupdate()
 
88
{
 
89
        return !(regs[0x22f] & 0x80);
 
90
}
 
91
 
 
92
void k054539_device::keyon(int channel)
 
93
{
 
94
        if(regupdate())
 
95
                regs[0x22c] |= 1 << channel;
 
96
}
 
97
 
 
98
void k054539_device::keyoff(int channel)
 
99
{
 
100
        if(regupdate())
 
101
                regs[0x22c] &= ~(1 << channel);
 
102
}
 
103
 
 
104
void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
 
105
{
135
106
#define VOL_CAP 1.80
136
107
 
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
140
111
        };
141
112
 
142
 
        int ch, reverb_pos;
143
 
        short *rbase;
144
 
        unsigned char *rom;
145
 
        UINT32 rom_mask;
146
 
 
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;
153
 
 
154
 
        double gain, lvol, rvol, rbvol;
155
 
 
156
 
        reverb_pos = info->reverb_pos;
157
 
        rbase = (short *)(info->ram);
158
 
 
159
 
        memset(outputs[0], 0, samples*sizeof(*outputs[0]));
160
 
        memset(outputs[1], 0, samples*sizeof(*outputs[1]));
161
 
 
162
 
        rom = info->rom;
163
 
        rom_mask = info->rom_mask;
164
 
 
165
 
        if(!(info->regs[0x22f] & 1)) return;
166
 
 
167
 
        info->reverb_pos = (reverb_pos + samples) & 0x3fff;
168
 
 
169
 
 
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;
175
 
//*
176
 
                        delta = base1[0x00] | (base1[0x01] << 8) | (base1[0x02] << 16);
177
 
 
178
 
                        vol = base1[0x03];
179
 
 
180
 
                        bval = vol + base1[0x04];
181
 
                        if (bval > 255) bval = 255;
182
 
 
183
 
                        pan = base1[0x05];
184
 
// DJ Main: 81-87 right, 88 middle, 89-8f left
185
 
if (pan >= 0x81 && pan <= 0x8f)
186
 
pan -= 0x81;
187
 
else
188
 
                        if (pan >= 0x11 && pan <= 0x1f) pan -= 0x11; else pan = 0x18 - 0x11;
189
 
 
190
 
                        gain = info->k054539_gain[ch];
191
 
 
192
 
                        lvol = info->voltab[vol] * info->pantab[pan] * gain;
193
 
                        if (lvol > VOL_CAP) lvol = VOL_CAP;
194
 
 
195
 
                        rvol = info->voltab[vol] * info->pantab[0xe - pan] * gain;
196
 
                        if (rvol > VOL_CAP) rvol = VOL_CAP;
197
 
 
198
 
                        rbvol= info->voltab[bval] * gain / 2;
199
 
                        if (rbvol > VOL_CAP) rbvol = VOL_CAP;
200
 
 
201
 
/*
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.
205
 
*/
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;
209
 
 
210
 
                        cur_pos = (base1[0x0c] | (base1[0x0d] << 8) | (base1[0x0e] << 16)) & rom_mask;
211
 
 
212
 
                        bufl = outputs[0];
213
 
                        bufr = outputs[1];
214
 
//*
215
 
 
216
 
                        if(base2[0] & 0x20) {
217
 
                                delta = -delta;
218
 
                                fdelta = +0x10000;
219
 
                                pdelta = -1;
220
 
                        } else {
221
 
                                fdelta = -0x10000;
222
 
                                pdelta = +1;
223
 
                        }
224
 
 
225
 
                        if(cur_pos != chan->pos) {
226
 
                                chan->pos = cur_pos;
227
 
                                cur_pfrac = 0;
228
 
                                cur_val = 0;
229
 
                                cur_pval = 0;
230
 
                        } else {
231
 
                                cur_pfrac = chan->pfrac;
232
 
                                cur_val = chan->val;
233
 
                                cur_pval = chan->pval;
234
 
                        }
235
 
 
236
 
#define UPDATE_CHANNELS                                                                                                                                 \
237
 
                        do {                                                                                                                                            \
238
 
                                *bufl++ += (INT16)(cur_val*lvol);                                                                               \
239
 
                                *bufr++ += (INT16)(cur_val*rvol);                                                                               \
240
 
                                rbase[rdelta++] += (INT16)(cur_val*rbvol);                                                                              \
241
 
                                rdelta &= 0x3fff;                                                                               \
242
 
                        } while(0)
243
 
 
244
 
                        switch(base2[0] & 0xc) {
245
 
                        case 0x0: { // 8bit pcm
246
 
                                for(i=0; i<samples; i++) {
 
113
 
 
114
        INT16 *rbase = (INT16 *)ram;
 
115
 
 
116
        if(!(regs[0x22f] & 1))
 
117
                return;
 
118
 
 
119
        for(int sample = 0; sample != samples; sample++) {
 
120
                double lval, rval;
 
121
                if(!(flags & DISABLE_REVERB))
 
122
                        lval = rval = rbase[reverb_pos];
 
123
                else
 
124
                        lval = rval = 0;
 
125
                rbase[reverb_pos] = 0;
 
126
 
 
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;
 
132
 
 
133
                                int delta = base1[0x00] | (base1[0x01] << 8) | (base1[0x02] << 16);
 
134
 
 
135
                                int vol = base1[0x03];
 
136
 
 
137
                                int bval = vol + base1[0x04];
 
138
                                if (bval > 255)
 
139
                                        bval = 255;
 
140
 
 
141
                                int pan = base1[0x05];
 
142
                                // DJ Main: 81-87 right, 88 middle, 89-8f left
 
143
                                if (pan >= 0x81 && pan <= 0x8f)
 
144
                                        pan -= 0x81;
 
145
                                else if (pan >= 0x11 && pan <= 0x1f)
 
146
                                        pan -= 0x11;
 
147
                                else
 
148
                                        pan = 0x18 - 0x11;
 
149
 
 
150
                                double cur_gain = gain[ch];
 
151
 
 
152
                                double lvol = voltab[vol] * pantab[pan] * cur_gain;
 
153
                                if (lvol > VOL_CAP)
 
154
                                        lvol = VOL_CAP;
 
155
 
 
156
                                double rvol = voltab[vol] * pantab[0xe - pan] * cur_gain;
 
157
                                if (rvol > VOL_CAP)
 
158
                                        rvol = VOL_CAP;
 
159
 
 
160
                                double rbvol= voltab[bval] * cur_gain / 2;
 
161
                                if (rbvol > VOL_CAP)
 
162
                                        rbvol = VOL_CAP;
 
163
 
 
164
                                int rdelta = (base1[6] | (base1[7] << 8)) >> 3;
 
165
                                rdelta = (rdelta + reverb_pos) & 0x3fff;
 
166
 
 
167
                                int cur_pos = (base1[0x0c] | (base1[0x0d] << 8) | (base1[0x0e] << 16)) & rom_mask;
 
168
 
 
169
                                int fdelta, pdelta;
 
170
                                if(base2[0] & 0x20) {
 
171
                                        delta = -delta;
 
172
                                        fdelta = +0x10000;
 
173
                                        pdelta = -1;
 
174
                                } else {
 
175
                                        fdelta = -0x10000;
 
176
                                        pdelta = +1;
 
177
                                }
 
178
 
 
179
                                int cur_pfrac, cur_val, cur_pval;
 
180
                                if(cur_pos != chan->pos) {
 
181
                                        chan->pos = cur_pos;
 
182
                                        cur_pfrac = 0;
 
183
                                        cur_val = 0;
 
184
                                        cur_pval = 0;
 
185
                                } else {
 
186
                                        cur_pfrac = chan->pfrac;
 
187
                                        cur_val = chan->val;
 
188
                                        cur_pval = chan->pval;
 
189
                                }
 
190
 
 
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;
251
197
 
252
198
                                                cur_pval = cur_val;
253
199
                                                cur_val = (INT16)(rom[cur_pos] << 8);
 
200
                                                if(cur_val == (INT16)0x8000 && (base2[1] & 1)) {
 
201
                                                        cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
 
202
                                                        cur_val = (INT16)(rom[cur_pos] << 8);
 
203
                                                }
254
204
                                                if(cur_val == (INT16)0x8000) {
255
 
                                                        if(base2[1] & 1) {
256
 
                                                                cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
257
 
                                                                cur_val = (INT16)(rom[cur_pos] << 8);
258
 
                                                                if(cur_val != (INT16)0x8000)
259
 
                                                                        continue;
260
 
                                                        }
261
 
                                                        k054539_keyoff(info, ch);
262
 
                                                        goto end_channel_0;
 
205
                                                        keyoff(ch);
 
206
                                                        cur_val = 0;
 
207
                                                        break;
263
208
                                                }
264
209
                                        }
265
 
 
266
 
                                        UPDATE_CHANNELS;
 
210
                                        break;
267
211
                                }
268
 
                        end_channel_0:
269
 
                                break;
270
 
                        }
271
 
                        case 0x4: { // 16bit pcm lsb first
272
 
                                pdelta <<= 1;
273
 
 
274
 
                                for(i=0; i<samples; i++) {
 
212
 
 
213
                                case 0x4: { // 16bit pcm lsb first
 
214
                                        pdelta <<= 1;
 
215
 
275
216
                                        cur_pfrac += delta;
276
217
                                        while(cur_pfrac & ~0xffff) {
277
218
                                                cur_pfrac += fdelta;
279
220
 
280
221
                                                cur_pval = cur_val;
281
222
                                                cur_val = (INT16)(rom[cur_pos] | rom[cur_pos+1]<<8);
 
223
                                                if(cur_val == (INT16)0x8000 && (base2[1] & 1)) {
 
224
                                                        cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
 
225
                                                        cur_val = (INT16)(rom[cur_pos] | rom[cur_pos+1]<<8);
 
226
                                                }
282
227
                                                if(cur_val == (INT16)0x8000) {
283
 
                                                        if(base2[1] & 1) {
284
 
                                                                cur_pos = (base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask;
285
 
                                                                cur_val = (INT16)(rom[cur_pos] | rom[cur_pos+1]<<8);
286
 
                                                                if(cur_val != (INT16)0x8000)
287
 
                                                                        continue;
288
 
                                                        }
289
 
                                                        k054539_keyoff(info, ch);
290
 
                                                        goto end_channel_4;
 
228
                                                        keyoff(ch);
 
229
                                                        cur_val = 0;
 
230
                                                        break;
291
231
                                                }
292
232
                                        }
293
 
 
294
 
                                        UPDATE_CHANNELS;
295
 
                                }
296
 
                        end_channel_4:
297
 
                                break;
298
 
                        }
299
 
                        case 0x8: { // 4bit dpcm
300
 
                                cur_pos <<= 1;
301
 
                                cur_pfrac <<= 1;
302
 
                                if(cur_pfrac & 0x10000) {
303
 
                                        cur_pfrac &= 0xffff;
304
 
                                        cur_pos |= 1;
305
 
                                }
306
 
 
307
 
                                for(i=0; i<samples; i++) {
 
233
                                        break;
 
234
                                }
 
235
 
 
236
                                case 0x8: { // 4bit dpcm
 
237
                                        cur_pos <<= 1;
 
238
                                        cur_pfrac <<= 1;
 
239
                                        if(cur_pfrac & 0x10000) {
 
240
                                                cur_pfrac &= 0xffff;
 
241
                                                cur_pos |= 1;
 
242
                                        }
 
243
 
308
244
                                        cur_pfrac += delta;
309
245
                                        while(cur_pfrac & ~0xffff) {
310
246
                                                cur_pfrac += fdelta;
312
248
 
313
249
                                                cur_pval = cur_val;
314
250
                                                cur_val = rom[cur_pos>>1];
 
251
                                                if(cur_val == 0x88 && (base2[1] & 1)) {
 
252
                                                        cur_pos = ((base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask) << 1;
 
253
                                                        cur_val = rom[cur_pos>>1];
 
254
                                                }
315
255
                                                if(cur_val == 0x88) {
316
 
                                                        if(base2[1] & 1) {
317
 
                                                                cur_pos = ((base1[0x08] | (base1[0x09] << 8) | (base1[0x0a] << 16)) & rom_mask) << 1;
318
 
                                                                cur_val = rom[cur_pos>>1];
319
 
                                                                if(cur_val != 0x88)
320
 
                                                                        goto next_iter;
321
 
                                                        }
322
 
                                                        k054539_keyoff(info, ch);
323
 
                                                        goto end_channel_8;
 
256
                                                        keyoff(ch);
 
257
                                                        cur_val = 0;
 
258
                                                        break;
324
259
                                                }
325
 
                                        next_iter:
326
260
                                                if(cur_pos & 1)
327
261
                                                        cur_val >>= 4;
328
262
                                                else
334
268
                                                        cur_val = 32767;
335
269
                                        }
336
270
 
337
 
                                        UPDATE_CHANNELS;
338
 
                                }
339
 
                        end_channel_8:
340
 
                                cur_pfrac >>= 1;
341
 
                                if(cur_pos & 1)
342
 
                                        cur_pfrac |= 0x8000;
343
 
                                cur_pos >>= 1;
344
 
                                break;
345
 
                        }
346
 
                        default:
347
 
                                LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
348
 
                                break;
349
 
                        }
350
 
                        chan->pos = cur_pos;
351
 
                        chan->pfrac = cur_pfrac;
352
 
                        chan->pval = cur_pval;
353
 
                        chan->val = cur_val;
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;
358
 
                        }
359
 
                }
360
 
 
361
 
        //* drivers should be given the option to disable reverb when things go terribly wrong
362
 
        if(!(info->k054539_flags & K054539_DISABLE_REVERB))
363
 
        {
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;
368
 
                }
369
 
        }
370
 
 
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);
375
 
        } else
376
 
                memset(rbase + reverb_pos, 0, samples*2);
377
 
 
378
 
        #if CHANNEL_DEBUG
379
 
        {
380
 
                static const char gc_msg[32] = "chip :                         ";
381
 
                static int gc_active=0, gc_chip=0, gc_pos[2]={0,0};
382
 
                double *gc_fptr;
383
 
                char *gc_cptr;
384
 
                double gc_f0;
385
 
                int gc_i, gc_j, gc_k, gc_l;
386
 
 
387
 
                if (device->machine().input().code_pressed_once(KEYCODE_DEL_PAD))
388
 
                {
389
 
                        gc_active ^= 1;
390
 
                        if (!gc_active) popmessage(NULL);
391
 
                }
392
 
 
393
 
                if (gc_active)
394
 
                {
395
 
                        if (device->machine().input().code_pressed_once(KEYCODE_0_PAD)) gc_chip ^= 1;
396
 
 
397
 
                        gc_i = gc_pos[gc_chip];
398
 
                        gc_j = 0;
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; }
402
 
 
403
 
                        if (device->machine().input().code_pressed_once(KEYCODE_5_PAD))
404
 
                                info->k054539_gain[gc_i] = 1.0;
405
 
                        else
406
 
                        {
407
 
                                gc_fptr = &info->k054539_gain[gc_i];
408
 
                                gc_f0 = *gc_fptr;
409
 
                                gc_j = 0;
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; }
413
 
                        }
414
 
 
415
 
                        gc_fptr = &info->k054539_gain[0] + 8;
416
 
                        gc_cptr = gc_msg + 7;
417
 
                        for (gc_j=-8; gc_j; gc_j++)
418
 
                        {
419
 
                                gc_k = (int)(gc_fptr[gc_j] * 10);
420
 
                                gc_l = gc_k / 10;
421
 
                                gc_k = gc_k % 10;
422
 
                                gc_cptr[0] = gc_l + '0';
423
 
                                gc_cptr[1] = gc_k + '0';
424
 
                                gc_cptr += 3;
425
 
                        }
426
 
                        gc_i = (gc_i + gc_i*2 + 6);
427
 
                        gc_msg[4] = gc_chip + '0';
428
 
                        gc_msg[gc_i  ] = '[';
429
 
                        gc_msg[gc_i+3] = ']';
430
 
                        popmessage("%s", gc_msg);
431
 
                        gc_msg[gc_i+3] = gc_msg[gc_i] = ' ';
432
 
                }
433
 
        }
434
 
        #endif
435
 
}
436
 
 
437
 
 
438
 
static TIMER_CALLBACK( k054539_irq )
439
 
{
440
 
        k054539_state *info = (k054539_state *)ptr;
441
 
        if(info->regs[0x22f] & 0x20)
442
 
                info->intf->irq(info->device);
443
 
}
444
 
 
445
 
static void k054539_init_chip(device_t *device, k054539_state *info)
446
 
{
447
 
        int i;
448
 
 
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
452
 
 
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;
456
 
        info->cur_ptr = 0;
457
 
        memset(info->ram, 0, 0x4000*2+device->clock()/50*2);
458
 
 
459
 
        const memory_region *region = (info->intf->rgnoverride != NULL) ? device->machine().region(info->intf->rgnoverride) : device->region();
460
 
        info->rom = *region;
461
 
        info->rom_size = region->bytes();
462
 
        info->rom_mask = 0xffffffffU;
463
 
        for(i=0; i<32; i++)
464
 
                if((1U<<i) >= info->rom_size) {
465
 
                        info->rom_mask = (1U<<i) - 1;
 
271
                                        cur_pfrac >>= 1;
 
272
                                        if(cur_pos & 1)
 
273
                                                cur_pfrac |= 0x8000;
 
274
                                        cur_pos >>= 1;
 
275
                                        break;
 
276
                                }
 
277
                                default:
 
278
                                        LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
 
279
                                        break;
 
280
                                }
 
281
                                lval += cur_val * lvol;
 
282
                                rval += cur_val * rvol;
 
283
                                rbase[(rdelta + reverb_pos) & 0x1fff] += INT16(cur_val*rbvol);
 
284
 
 
285
                                chan->pos = cur_pos;
 
286
                                chan->pfrac = cur_pfrac;
 
287
                                chan->pval = cur_pval;
 
288
                                chan->val = cur_val;
 
289
 
 
290
                                if(regupdate()) {
 
291
                                        base1[0x0c] = cur_pos     & 0xff;
 
292
                                        base1[0x0d] = cur_pos>> 8 & 0xff;
 
293
                                        base1[0x0e] = cur_pos>>16 & 0xff;
 
294
                                }
 
295
                        }
 
296
                reverb_pos = (reverb_pos + 1) & 0x1fff;
 
297
                outputs[0][sample] = INT16(lval);
 
298
                outputs[1][sample] = INT16(rval);
 
299
        }
 
300
}
 
301
 
 
302
 
 
303
void k054539_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
 
304
{
 
305
        if(regs[0x22f] & 0x20)
 
306
                irq(this);
 
307
}
 
308
 
 
309
void k054539_device::init_chip()
 
310
{
 
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
 
314
 
 
315
        ram = auto_alloc_array(machine(), unsigned char, 0x4000);
 
316
        reverb_pos = 0;
 
317
        cur_ptr = 0;
 
318
        memset(ram, 0, 0x4000);
 
319
 
 
320
        memory_region *reg = (rgnoverride != NULL) ? machine().root_device().memregion(rgnoverride) : region();
 
321
        rom = *reg;
 
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;
466
327
                        break;
467
328
                }
468
329
 
469
 
        if(info->intf->irq)
 
330
        if(irq) {
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);
474
 
 
475
 
        info->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock(), info, k054539_update);
476
 
 
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));
 
336
        }
 
337
 
 
338
        // If the clock is anything else than 48000, things are going to go wrong.
 
339
        stream = stream_alloc(0, 2, clock());
 
340
 
 
341
        save_item(NAME(regs));
 
342
        save_pointer(NAME(ram), 0x4000);
 
343
        save_item(NAME(cur_ptr));
480
344
}
481
345
 
482
 
WRITE8_DEVICE_HANDLER( k054539_w )
 
346
WRITE8_MEMBER(k054539_device::write)
483
347
{
484
 
        k054539_state *info = get_safe_token(device);
485
 
 
486
 
#if 0
487
 
        int voice, reg;
488
 
 
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.
492
 
 
493
 
       Dadandaan depends on this or the vocals go wrong.
494
 
       */
495
 
        if (offset < 8*0x20)
496
 
        {
497
 
                voice = offset / 0x20;
498
 
                reg = offset & ~0x20;
499
 
 
500
 
                if(info->regs[0x22c] & (1<<voice))
 
348
        if(0) {
 
349
                int voice, reg;
 
350
 
 
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.
 
354
 
 
355
           Dadandaan depends on this or the vocals go wrong.
 
356
        */
 
357
                if (offset < 8*0x20)
501
358
                {
502
 
                        if (reg >= 0xc && reg <= 0xe)
503
 
                        {
504
 
                                return;
505
 
                        }
 
359
                        voice = offset / 0x20;
 
360
                        reg = offset & ~0x20;
 
361
 
 
362
                        if(regs[0x22c] & (1<<voice))
 
363
                                if (reg >= 0xc && reg <= 0xe)
 
364
                                        return;
506
365
                }
507
366
        }
508
 
#endif
509
 
 
510
 
        int latch, offs, ch, pan;
511
 
        UINT8 *regbase, *regptr, *posptr;
512
 
 
513
 
        regbase = info->regs;
514
 
        latch = (info->k054539_flags & K054539_UPDATE_AT_KEYON) && (regbase[0x22f] & 1);
 
367
 
 
368
        bool latch = (flags & UPDATE_AT_KEYON) && (regs[0x22f] & 1);
515
369
 
516
370
        if (latch && offset < 0x100)
517
371
        {
518
 
                offs = (offset & 0x1f) - 0xc;
519
 
                ch = offset >> 5;
 
372
                int offs = (offset & 0x1f) - 0xc;
 
373
                int ch = offset >> 5;
520
374
 
521
375
                if (offs >= 0 && offs <= 2)
522
376
                {
523
377
                        // latch writes to the position index registers
524
 
                        info->k054539_posreg_latch[ch][offs] = data;
 
378
                        posreg_latch[ch][offs] = data;
525
379
                        return;
526
380
                }
527
381
        }
528
382
 
529
 
        else switch(offset)
530
 
        {
531
 
                case 0x13f:
532
 
                        pan = data >= 0x11 && data <= 0x1f ? data - 0x11 : 0x18 - 0x11;
533
 
                        if(info->intf->apan)
534
 
                                info->intf->apan(info->device, info->pantab[pan], info->pantab[0xe - pan]);
535
 
                break;
 
383
        else
 
384
                switch(offset) {
 
385
                case 0x13f: {
 
386
                        int pan = data >= 0x11 && data <= 0x1f ? data - 0x11 : 0x18 - 0x11;
 
387
                        if(apan)
 
388
                                apan(this, pantab[pan], pantab[0xe - pan]);
 
389
                        break;
 
390
                }
536
391
 
537
392
                case 0x214:
538
393
                        if (latch)
539
394
                        {
540
 
                                for(ch=0; ch<8; ch++)
 
395
                                for(int ch=0; ch<8; ch++)
541
396
                                {
542
397
                                        if(data & (1<<ch))
543
398
                                        {
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;
546
401
 
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];
551
406
 
552
 
                                                k054539_keyon(info, ch);
 
407
                                                keyon(ch);
553
408
                                        }
554
409
                                }
555
410
                        }
556
411
                        else
557
412
                        {
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);
 
415
                                                keyon(ch);
561
416
                        }
562
417
                break;
563
418
 
564
419
                case 0x215:
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);
 
422
                                        keyoff(ch);
568
423
                break;
569
424
 
570
425
                case 0x22d:
571
 
                        if(regbase[0x22e] == 0x80)
572
 
                                info->cur_zone[info->cur_ptr] = data;
573
 
                        info->cur_ptr++;
574
 
                        if(info->cur_ptr == info->cur_limit)
575
 
                                info->cur_ptr = 0;
 
426
                        if(regs[0x22e] == 0x80)
 
427
                                cur_zone[cur_ptr] = data;
 
428
                        cur_ptr++;
 
429
                        if(cur_ptr == cur_limit)
 
430
                                cur_ptr = 0;
576
431
                break;
577
432
 
578
433
                case 0x22e:
579
 
                        info->cur_zone =
580
 
                                data == 0x80 ? info->ram :
581
 
                                info->rom + 0x20000*data;
582
 
                        info->cur_limit = data == 0x80 ? 0x4000 : 0x20000;
583
 
                        info->cur_ptr = 0;
 
434
                        cur_zone =
 
435
                                data == 0x80 ? ram :
 
436
                                rom + 0x20000*data;
 
437
                        cur_limit = data == 0x80 ? 0x4000 : 0x20000;
 
438
                        cur_ptr = 0;
584
439
                break;
585
440
 
586
441
                default:
587
442
#if 0
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 ||
601
456
                break;
602
457
        }
603
458
 
604
 
        regbase[offset] = data;
605
 
}
606
 
 
607
 
static void reset_zones(k054539_state *info)
608
 
{
609
 
        int data = info->regs[0x22e];
610
 
        info->cur_zone =
611
 
                data == 0x80 ? info->ram :
612
 
                info->rom + 0x20000*data;
613
 
        info->cur_limit = data == 0x80 ? 0x4000 : 0x20000;
614
 
}
615
 
 
616
 
READ8_DEVICE_HANDLER( k054539_r )
617
 
{
618
 
        k054539_state *info = get_safe_token(device);
 
459
        regs[offset] = data;
 
460
}
 
461
 
 
462
void k054539_device::reset_zones()
 
463
{
 
464
        int data = regs[0x22e];
 
465
        cur_zone = data == 0x80 ? ram : rom + 0x20000*data;
 
466
        cur_limit = data == 0x80 ? 0x4000 : 0x20000;
 
467
}
 
468
 
 
469
READ8_MEMBER(k054539_device::read)
 
470
{
619
471
        switch(offset) {
620
472
        case 0x22d:
621
 
                if(info->regs[0x22f] & 0x10) {
622
 
                        UINT8 res = info->cur_zone[info->cur_ptr];
623
 
                        info->cur_ptr++;
624
 
                        if(info->cur_ptr == info->cur_limit)
625
 
                                info->cur_ptr = 0;
 
473
                if(regs[0x22f] & 0x10) {
 
474
                        UINT8 res = cur_zone[cur_ptr];
 
475
                        cur_ptr++;
 
476
                        if(cur_ptr == cur_limit)
 
477
                                cur_ptr = 0;
626
478
                        return res;
627
479
                } else
628
480
                        return 0;
632
484
                LOG(("K054539 read %03x\n", offset));
633
485
                break;
634
486
        }
635
 
        return info->regs[offset];
 
487
        return regs[offset];
636
488
}
637
489
 
638
 
static DEVICE_START( k054539 )
 
490
void k054539_device::device_start()
639
491
{
640
 
        static const k054539_interface defintrf = { 0 };
641
 
        int i;
642
 
        k054539_state *info = get_safe_token(device);
643
 
 
644
 
        info->device = device;
645
 
 
646
 
        for (i = 0; i < 8; i++)
647
 
                info->k054539_gain[i] = 1.0;
648
 
        info->k054539_flags = K054539_RESET_FLAGS;
649
 
 
650
 
        info->intf = (device->static_config() != NULL) ? (const k054539_interface *)device->static_config() : &defintrf;
 
492
        for (int i = 0; i < 8; i++)
 
493
                gain[i] = 1.0;
 
494
        flags = RESET_FLAGS;
651
495
 
652
496
        /*
653
497
        I've tried various equations on volume control but none worked consistently.
661
505
    */
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
664
 
        for(i=0; i<256; i++)
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;
666
510
 
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)
671
 
        for(i=0; i<0xf; i++)
672
 
                info->pantab[i] = sqrt((double)i) / sqrt((double)0xe);
673
 
 
674
 
        k054539_init_chip(device, info);
675
 
 
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);
 
517
 
 
518
        init_chip();
 
519
 
 
520
        machine().save().register_postload(save_prepost_delegate(FUNC(k054539_device::reset_zones), this));
677
521
}
678
522
 
679
 
 
680
 
 
681
 
 
682
 
/**************************************************************************
683
 
 * Generic get_info
684
 
 **************************************************************************/
685
 
 
686
 
DEVICE_GET_INFO( k054539 )
 
523
void k054539_device::device_reset()
687
524
{
688
 
        switch (state)
689
 
        {
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;
692
 
 
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;
697
 
 
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;
704
 
        }
705
525
}
706
 
 
707
 
 
708
 
DEFINE_LEGACY_SOUND_DEVICE(K054539, k054539);