Subversion Repositories pentevo

Rev

Rev 1147 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1099 galstaff 1
// This file is taken from the openMSX project. 
2
// The file has been modified to be built in the blueMSX environment.
3
 
4
// $Id: OpenMsxYMF278.cpp,v 1.3 2005/09/24 00:09:50 dvik Exp $
5
 
6
#include "../std.h"
1156 lvd 7
#include "../emul.h"
8
#include "../vars.h"
9
#include "../util.h"
1099 galstaff 10
 
11
#include "ymf278.h"
12
#include <cmath>
13
 
14
const int EG_SH = 16;   // 16.16 fixed point (EG timing)
15
const unsigned int EG_TIMER_OVERFLOW = 1 << EG_SH;
16
 
17
// envelope output entries
18
const int ENV_BITS      = 10;
19
const int ENV_LEN       = 1 << ENV_BITS;
20
const double ENV_STEP   = 128.0 / ENV_LEN;
21
const int MAX_ATT_INDEX = (1 << (ENV_BITS - 1)) - 1; //511
22
const int MIN_ATT_INDEX = 0;
23
 
24
// Envelope Generator phases
25
const int EG_ATT = 4;
26
const int EG_DEC = 3;
27
const int EG_SUS = 2;
28
const int EG_REL = 1;
29
const int EG_OFF = 0;
30
 
31
const int EG_REV = 5;   //pseudo reverb
32
const int EG_DMP = 6;   //damp
33
 
34
// Pan values, units are -3dB, i.e. 8.
35
const int pan_left[16]  = {
36
        0, 8, 16, 24, 32, 40, 48, 256, 256,   0,  0,  0,  0,  0,  0, 0
37
};
38
const int pan_right[16] = {
39
        0, 0,  0,  0,  0,  0,  0,   0, 256, 256, 48, 40, 32, 24, 16, 8
40
};
41
 
42
// Mixing levels, units are -3dB, and add some marging to avoid clipping
43
const int mix_level[8] = {
44
        8, 16, 24, 32, 40, 48, 56, 256
45
};
46
 
47
// decay level table (3dB per step)
48
// 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)
49
#define SC(db) (unsigned int)(db * (2.0 / ENV_STEP))
50
const unsigned int dl_tab[16] = {
51
 SC( 0), SC( 1), SC( 2), SC(3 ), SC(4 ), SC(5 ), SC(6 ), SC( 7),
52
 SC( 8), SC( 9), SC(10), SC(11), SC(12), SC(13), SC(14), SC(31)
53
};
54
#undef SC
55
 
56
const u8 RATE_STEPS = 8;
57
const u8 eg_inc[15 * RATE_STEPS] = {
58
//cycle:0 1  2 3  4 5  6 7
59
        0, 1,  0, 1,  0, 1,  0, 1, //  0  rates 00..12 0 (increment by 0 or 1)
60
        0, 1,  0, 1,  1, 1,  0, 1, //  1  rates 00..12 1
61
        0, 1,  1, 1,  0, 1,  1, 1, //  2  rates 00..12 2
62
        0, 1,  1, 1,  1, 1,  1, 1, //  3  rates 00..12 3
63
 
64
        1, 1,  1, 1,  1, 1,  1, 1, //  4  rate 13 0 (increment by 1)
65
        1, 1,  1, 2,  1, 1,  1, 2, //  5  rate 13 1
66
        1, 2,  1, 2,  1, 2,  1, 2, //  6  rate 13 2
67
        1, 2,  2, 2,  1, 2,  2, 2, //  7  rate 13 3
68
 
69
        2, 2,  2, 2,  2, 2,  2, 2, //  8  rate 14 0 (increment by 2)
70
        2, 2,  2, 4,  2, 2,  2, 4, //  9  rate 14 1
71
        2, 4,  2, 4,  2, 4,  2, 4, // 10  rate 14 2
72
        2, 4,  4, 4,  2, 4,  4, 4, // 11  rate 14 3
73
 
74
        4, 4,  4, 4,  4, 4,  4, 4, // 12  rates 15 0, 15 1, 15 2, 15 3 for decay
75
        8, 8,  8, 8,  8, 8,  8, 8, // 13  rates 15 0, 15 1, 15 2, 15 3 for attack (zero time)
76
        0, 0,  0, 0,  0, 0,  0, 0, // 14  infinity rates for attack and decay(s)
77
};
78
 
79
#define O(a) (a * RATE_STEPS)
80
const u8 eg_rate_select[64] = {
81
        O( 0),O( 1),O( 2),O( 3),
82
        O( 0),O( 1),O( 2),O( 3),
83
        O( 0),O( 1),O( 2),O( 3),
84
        O( 0),O( 1),O( 2),O( 3),
85
        O( 0),O( 1),O( 2),O( 3),
86
        O( 0),O( 1),O( 2),O( 3),
87
        O( 0),O( 1),O( 2),O( 3),
88
        O( 0),O( 1),O( 2),O( 3),
89
        O( 0),O( 1),O( 2),O( 3),
90
        O( 0),O( 1),O( 2),O( 3),
91
        O( 0),O( 1),O( 2),O( 3),
92
        O( 0),O( 1),O( 2),O( 3),
93
        O( 0),O( 1),O( 2),O( 3),
94
        O( 4),O( 5),O( 6),O( 7),
95
        O( 8),O( 9),O(10),O(11),
96
        O(12),O(12),O(12),O(12),
97
};
98
#undef O
99
 
100
//rate  0,    1,    2,    3,   4,   5,   6,  7,  8,  9,  10, 11, 12, 13, 14, 15
101
//shift 12,   11,   10,   9,   8,   7,   6,  5,  4,  3,  2,  1,  0,  0,  0,  0
102
//mask  4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3,  1,  0,  0,  0,  0
103
#define O(a) (a)
104
const u8 eg_rate_shift[64] = {
105
        O(12),O(12),O(12),O(12),
106
        O(11),O(11),O(11),O(11),
107
        O(10),O(10),O(10),O(10),
108
        O( 9),O( 9),O( 9),O( 9),
109
        O( 8),O( 8),O( 8),O( 8),
110
        O( 7),O( 7),O( 7),O( 7),
111
        O( 6),O( 6),O( 6),O( 6),
112
        O( 5),O( 5),O( 5),O( 5),
113
        O( 4),O( 4),O( 4),O( 4),
114
        O( 3),O( 3),O( 3),O( 3),
115
        O( 2),O( 2),O( 2),O( 2),
116
        O( 1),O( 1),O( 1),O( 1),
117
        O( 0),O( 0),O( 0),O( 0),
118
        O( 0),O( 0),O( 0),O( 0),
119
        O( 0),O( 0),O( 0),O( 0),
120
        O( 0),O( 0),O( 0),O( 0),
121
};
122
#undef O
123
 
124
 
125
//number of steps to take in quarter of lfo frequency
126
//TODO check if frequency matches real chip
127
#define O(a) ((int)((EG_TIMER_OVERFLOW / a) / 6))
128
const int lfo_period[8] = {
129
        O(0.168), O(2.019), O(3.196), O(4.206),
130
        O(5.215), O(5.888), O(6.224), O(7.066)
131
};
132
#undef O
133
 
134
 
135
#define O(a) ((int)(a * 65536))
136
const int vib_depth[8] = {
137
        O(0),      O(3.378),  O(5.065),  O(6.750),
138
        O(10.114), O(20.170), O(40.106), O(79.307)
139
};
140
#undef O
141
 
142
 
143
#define SC(db) (unsigned int) (db * (2.0 / ENV_STEP))
144
const int am_depth[8] = {
145
        SC(0),     SC(1.781), SC(2.906), SC(3.656),
146
        SC(4.406), SC(5.906), SC(7.406), SC(11.91)
147
};
148
#undef SC
149
 
150
 
151
YMF278Slot::YMF278Slot()
152
{
153
        reset();
154
}
155
 
156
void YMF278Slot::reset()
157
{
158
        wave = FN = OCT = PRVB = LD = TL = pan = lfo = vib = AM = 0;
159
        AR = D1R = DL = D2R = RC = RR = 0;
160
        step = stepptr = 0;
161
        bits = startaddr = loopaddr = endaddr = 0;
162
        env_vol = MAX_ATT_INDEX;
163
        //env_vol_step = env_vol_lim = 0;
164
 
165
        lfo_active = false;
166
        lfo_cnt = lfo_step = 0;
167
        lfo_max = lfo_period[0];
168
 
169
        state = EG_OFF;
170
        active = false;
171
}
172
 
173
int YMF278Slot::compute_rate(int val)
174
{
175
        if (val == 0) {
176
                return 0;
177
        } else if (val == 15) {
178
                return 63;
179
        }
180
        int res;
181
        if (RC != 15) {
182
                int oct = OCT;
183
                if (oct & 8) {
184
                        oct |= -8;
185
                }
186
                res = (oct + RC) * 2 + (FN & 0x200 ? 1 : 0) + val * 4;
187
        } else {
188
                res = val * 4;
189
        }
190
        if (res < 0) {
191
                res = 0;
192
        } else if (res > 63) {
193
                res = 63;
194
        }
195
        return res;
196
}
197
 
198
int YMF278Slot::compute_vib()
199
{
200
        return (((lfo_step << 8) / lfo_max) * vib_depth[(int)vib]) >> 24;
201
}
202
 
203
 
204
int YMF278Slot::compute_am()
205
{
206
        if (lfo_active && AM) {
207
                return (((lfo_step << 8) / lfo_max) * am_depth[(int)AM]) >> 12;
208
        } else {
209
                return 0;
210
        }
211
}
212
 
213
void YMF278Slot::set_lfo(int newlfo)
214
{
215
        lfo_step = (((lfo_step << 8) / lfo_max) * newlfo) >> 8;
216
        lfo_cnt  = (((lfo_cnt  << 8) / lfo_max) * newlfo) >> 8;
217
 
218
        lfo = newlfo;
219
        lfo_max = lfo_period[(int)lfo];
220
}
221
 
222
 
223
void YMF278::advance()
224
{
225
        eg_timer += eg_timer_add;
226
 
227
    if (eg_timer > 4 * EG_TIMER_OVERFLOW) {
228
        eg_timer = EG_TIMER_OVERFLOW;
229
    }
230
 
231
        while (eg_timer >= EG_TIMER_OVERFLOW) {
232
                eg_timer -= EG_TIMER_OVERFLOW;
233
                eg_cnt++;
234
 
235
                for (int i = 0; i < 24; i++) {
236
                        YMF278Slot &op = slots[i];
237
 
238
                        if (op.lfo_active) {
239
                                op.lfo_cnt++;
240
                                if (op.lfo_cnt < op.lfo_max) {
241
                                        op.lfo_step++;
242
                                } else if (op.lfo_cnt < (op.lfo_max * 3)) {
243
                                        op.lfo_step--;
244
                                } else {
245
                                        op.lfo_step++;
246
                                        if (op.lfo_cnt == (op.lfo_max * 4)) {
247
                                                op.lfo_cnt = 0;
248
                                        }
249
                                }
250
                        }
251
 
252
                        // Envelope Generator
253
                        switch(op.state) {
254
                        case EG_ATT: {  // attack phase
255
                                u8 rate = op.compute_rate(op.AR);
256
                                if (rate < 4) {
257
                                        break;
258
                                }
259
                                u8 shift = eg_rate_shift[rate];
260
                                if (!(eg_cnt & ((1 << shift) -1))) {
261
                                        u8 select = eg_rate_select[rate];
262
                                        op.env_vol += (~op.env_vol * eg_inc[select + ((eg_cnt >> shift) & 7)]) >> 3;
263
                                        if (op.env_vol <= MIN_ATT_INDEX) {
264
                                                op.env_vol = MIN_ATT_INDEX;
265
                        if (op.DL == 0) {
266
                                                op.state = EG_SUS;
267
                        }
268
                        else {
269
                                                op.state = EG_DEC;
270
                        }
271
                                        }
272
                                }
273
                                break;
274
                        }
275
                        case EG_DEC: {  // decay phase 
276
                                u8 rate = op.compute_rate(op.D1R);
277
                                if (rate < 4) {
278
                                        break;
279
                                }
280
                                u8 shift = eg_rate_shift[rate];
281
                                if (!(eg_cnt & ((1 << shift) -1))) {
282
                                        u8 select = eg_rate_select[rate];
283
                                        op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
284
 
285
                                        if (((unsigned int)op.env_vol > dl_tab[6]) && op.PRVB) {
286
                                                op.state = EG_REV;
287
                                        } else {
288
                                                if (op.env_vol >= op.DL) {
289
                                                        op.state = EG_SUS;
290
                                                }
291
                                        }
292
                                }
293
                                break;
294
                        }
295
                        case EG_SUS: {  // sustain phase 
296
                                u8 rate = op.compute_rate(op.D2R);
297
                                if (rate < 4) {
298
                                        break;
299
                                }
300
                                u8 shift = eg_rate_shift[rate];
301
                                if (!(eg_cnt & ((1 << shift) -1))) {
302
                                        u8 select = eg_rate_select[rate];
303
                                        op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
304
 
305
                                        if (((unsigned int)op.env_vol > dl_tab[6]) && op.PRVB) {
306
                                                op.state = EG_REV;
307
                                        } else {
308
                                                if (op.env_vol >= MAX_ATT_INDEX) {
309
                                                        op.env_vol = MAX_ATT_INDEX;
310
                                                        op.active = false;
311
                                                        checkMute();
312
                                                }
313
                                        }
314
                                }
315
                                break;
316
                        }
317
                        case EG_REL: {  // release phase 
318
                                u8 rate = op.compute_rate(op.RR);
319
                                if (rate < 4) {
320
                                        break;
321
                                }
322
                                u8 shift = eg_rate_shift[rate];
323
                                if (!(eg_cnt & ((1 << shift) -1))) {
324
                                        u8 select = eg_rate_select[rate];
325
                                        op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
326
 
327
                                        if (((unsigned int)op.env_vol > dl_tab[6]) && op.PRVB) {
328
                                                op.state = EG_REV;
329
                                        } else {
330
                                                if (op.env_vol >= MAX_ATT_INDEX) {
331
                                                        op.env_vol = MAX_ATT_INDEX;
332
                                                        op.active = false;
333
                                                        checkMute();
334
                                                }
335
                                        }
336
                                }
337
                                break;
338
                        }
339
                        case EG_REV: {  //pseudo reverb
340
                                //TODO improve env_vol update
341
                                u8 rate = op.compute_rate(5);
342
                                //if (rate < 4) {
343
                                //      break;
344
                                //}
345
                                u8 shift = eg_rate_shift[rate];
346
                                if (!(eg_cnt & ((1 << shift) - 1))) {
347
                                        u8 select = eg_rate_select[rate];
348
                                        op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
349
 
350
                                        if (op.env_vol >= MAX_ATT_INDEX) {
351
                                                op.env_vol = MAX_ATT_INDEX;
352
                                                op.active = false;
353
                                                checkMute();
354
                                        }
355
                                }
356
                                break;
357
                        }
358
                        case EG_DMP: {  //damping
359
                                //TODO improve env_vol update, damp is just fastest decay now
360
                                u8 rate = 56;
361
                                u8 shift = eg_rate_shift[rate];
362
                                if (!(eg_cnt & ((1 << shift) - 1))) {
363
                                        u8 select = eg_rate_select[rate];
364
                                        op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
365
 
366
                                        if (op.env_vol >= MAX_ATT_INDEX) {
367
                                                op.env_vol = MAX_ATT_INDEX;
368
                                                op.active = false;
369
                                                checkMute();
370
                                        }
371
                                }
372
                                break;
373
                        }
374
                        case EG_OFF:
375
                                // nothing
376
                                break;
377
 
378
                        default:
379
                                break;
380
                        }
381
                }
382
        }
383
}
384
 
385
short YMF278::getSample(YMF278Slot &op)
386
{
387
        short sample;
388
        switch (op.bits) {
389
        case 0: {
390
                // 8 bit
391
                sample = readMem(op.startaddr + op.pos) << 8;
392
                break;
393
        }
394
        case 1: {
395
                // 12 bit
396
                int addr = op.startaddr + ((op.pos / 2) * 3);
397
                if (op.pos & 1) {
398
                        sample = readMem(addr + 2) << 8 |
399
                                 ((readMem(addr + 1) << 4) & 0xF0);
400
                } else {
401
                        sample = readMem(addr + 0) << 8 |
402
                                 (readMem(addr + 1) & 0xF0);
403
                }
404
                break;
405
        }
406
        case 2: {
407
                // 16 bit
408
                int addr = op.startaddr + (op.pos * 2);
409
                sample = (readMem(addr + 0) << 8) |
410
                         (readMem(addr + 1));
411
                break;
412
        }
413
        default:
414
                // TODO unspecified
415
                sample = 0;
416
        }
417
        return sample;
418
}
419
 
420
void YMF278::checkMute()
421
{
422
        setInternalMute(!anyActive());
423
}
424
 
425
bool YMF278::anyActive()
426
{
427
        for (int i = 0; i < 24; i++) {
428
                if (slots[i].active) {
429
                        return true;
430
                }
431
        }
432
        return false;
433
}
434
 
435
int* YMF278::updateBuffer(int length)
436
{
437
        if (isInternalMuted()) {
438
                return NULL;
439
        }
440
 
441
        int vl = mix_level[pcm_l];
442
        int vr = mix_level[pcm_r];
443
        int *buf = buffer;
444
        while (length--) {
445
                int left = 0;
446
                int right = 0;
447
        int cnt = oplOversampling;
448
        while (cnt--) {
449
                    for (int i = 0; i < 24; i++) {
450
                            YMF278Slot &sl = slots[i];
451
                            if (!sl.active) {
452
                                    continue;
453
                            }
454
 
455
                            short sample = (sl.sample1 * (0x10000 - sl.stepptr) +
456
                                            sl.sample2 * sl.stepptr) >> 16;
457
                            int vol = sl.TL + (sl.env_vol >> 2) + sl.compute_am();
458
 
459
                            int volLeft  = vol + pan_left [(int)sl.pan] + vl;
460
                            int volRight = vol + pan_right[(int)sl.pan] + vr;
461
 
462
                            // TODO prob doesn't happen in real chip
463
                            if (volLeft < 0) {
464
                                    volLeft = 0;
465
                            }
466
                            if (volRight < 0) {
467
                                    volRight = 0;
468
                            }
469
 
470
                            left  += (sample * volume[volLeft] ) >> 10;
471
                            right += (sample * volume[volRight]) >> 10;
472
 
473
                            if (sl.lfo_active && sl.vib) {
474
                                    int oct = sl.OCT;
475
                                    if (oct & 8) {
476
                                            oct |= -8;
477
                                    }
478
                                    oct += 5;
479
                                    sl.stepptr += (oct >= 0 ? ((sl.FN | 1024) + sl.compute_vib()) << oct
480
                                                       : ((sl.FN | 1024) + sl.compute_vib()) >> -oct) / oplOversampling;
481
                            } else {
482
                                    sl.stepptr += sl.step / oplOversampling;
483
                            }
484
 
485
                int count = (sl.stepptr >> 16) & 0x0f;
486
                sl.stepptr &= 0xffff;
487
                            while (count--) {
488
                                    sl.sample1 = sl.sample2;
489
                                    sl.pos++;
490
                                    if (sl.pos >= sl.endaddr) {
491
                                            sl.pos = sl.loopaddr;
492
                                    }
493
                                    sl.sample2 = getSample(sl);
494
                            }          
495
                    }
496
                    advance();
497
        }
498
                *buf++ = left / oplOversampling;
499
                *buf++ = right / oplOversampling;
500
        }
501
        return buffer;
502
}
503
 
504
void YMF278::keyOnHelper(YMF278Slot& slot)
505
{
506
        slot.active = true;
507
        setInternalMute(false);
508
 
509
        int oct = slot.OCT;
510
        if (oct & 8) {
511
                oct |= -8;
512
        }
513
        oct += 5;
514
        slot.step = oct >= 0 ? (slot.FN | 1024) << oct : (slot.FN | 1024) >> -oct;
515
        slot.state = EG_ATT;
516
        slot.stepptr = 0;
517
        slot.pos = 0;
518
        slot.sample1 = getSample(slot);
519
        slot.pos = 1;
520
        slot.sample2 = getSample(slot);
521
}
522
 
523
void YMF278::writeRegOPL4(u8 reg, u8 data, const EmuTime &time)
524
{
525
        BUSY_Time = time + 88 * 6 / 9;
526
 
527
        // Handle slot registers specifically
528
        if (reg >= 0x08 && reg <= 0xF7) {
529
                int snum = (reg - 8) % 24;
530
                YMF278Slot& slot = slots[snum];
531
                switch ((reg - 8) / 24) {
532
                case 0: {
533
                        LD_Time = time;
534
                        slot.wave = (slot.wave & 0x100) | data;
535
                        int base = (slot.wave < 384 || !wavetblhdr) ?
536
                                   (slot.wave * 12) :
537
                                   (wavetblhdr * 0x80000 + ((slot.wave - 384) * 12));
538
                        u8 buf[12];
539
                        for (int i = 0; i < 12; i++) {
540
                                buf[i] = readMem(base + i);
541
                        }
542
                        slot.bits = (buf[0] & 0xC0) >> 6;
543
                        slot.set_lfo((buf[7] >> 3) & 7);
544
                        slot.vib  = buf[7] & 7;
545
                        slot.AR   = buf[8] >> 4;
546
                        slot.D1R  = buf[8] & 0xF;
547
                        slot.DL   = dl_tab[buf[9] >> 4];
548
                        slot.D2R  = buf[9] & 0xF;
549
                        slot.RC   = buf[10] >> 4;
550
                        slot.RR   = buf[10] & 0xF;
551
                        slot.AM   = buf[11] & 7;
552
                        slot.startaddr = buf[2] | (buf[1] << 8) |
553
                                         ((buf[0] & 0x3F) << 16);
554
                        slot.loopaddr = buf[4] + (buf[3] << 8);
555
                        slot.endaddr  = (((buf[6] + (buf[5] << 8)) ^ 0xFFFF) + 1);
556
                        if ((regs[reg + 4] & 0x080)) {
557
                                keyOnHelper(slot);
558
                        }
559
                        break;
560
                }
561
                case 1: {
562
                        slot.wave = (slot.wave & 0xFF) | ((data & 0x1) << 8);
563
                        slot.FN = (slot.FN & 0x380) | (data >> 1);
564
                        int oct = slot.OCT;
565
                        if (oct & 8) {
566
                                oct |= -8;
567
                        }
568
                oct += 5;
569
                slot.step = oct >= 0 ? (slot.FN | 1024) << oct : (slot.FN | 1024) >> -oct;
570
                        break;
571
                }
572
                case 2: {
573
                        slot.FN = (slot.FN & 0x07F) | ((data & 0x07) << 7);
574
                        slot.PRVB = ((data & 0x08) >> 3);
575
                        slot.OCT =  ((data & 0xF0) >> 4);
576
                        int oct = slot.OCT;
577
                        if (oct & 8) {
578
                                oct |= -8;
579
                        }
580
                oct += 5;
581
                slot.step = oct >= 0 ? (slot.FN | 1024) << oct : (slot.FN | 1024) >> -oct;
582
            break;
583
                }
584
                case 3:
585
                        slot.TL = data >> 1;
586
                        slot.LD = data & 0x1;
587
 
588
                        // TODO
589
                        if (slot.LD) {
590
                                // directly change volume
591
                        } else {
592
                                // interpolate volume
593
                        }
594
                        break;
595
                case 4:
596
                        slot.pan = data & 0x0F;
597
 
598
                        if (data & 0x020) {
599
                                // LFO reset
600
                                slot.lfo_active = false;
601
                                slot.lfo_cnt = 0;
602
                                slot.lfo_max = lfo_period[(int)slot.vib];
603
                                slot.lfo_step = 0;
604
                        } else {
605
                                // LFO activate
606
                                slot.lfo_active = true;
607
                        }
608
 
609
                        switch (data >> 6) {
610
                        case 0: //tone off, no damp
611
                                if (slot.active && (slot.state != EG_REV) ) {
612
                                        slot.state = EG_REL;
613
                                }
614
                                break;
615
                        case 1: //tone off, damp
616
                                slot.state = EG_DMP;
617
                                break;
618
                        case 2: //tone on, no damp
619
                                if (!(regs[reg] & 0x080)) {
620
                                        keyOnHelper(slot);
621
                                }
622
                                break;
623
                        case 3: //tone on, damp
624
                                slot.state = EG_DMP;
625
                                break;
626
                        }
627
                        break;
628
                case 5:
629
                        slot.vib = data & 0x7;
630
                        slot.set_lfo((data >> 3) & 0x7);
631
                        break;
632
                case 6:
633
                        slot.AR  = data >> 4;
634
                        slot.D1R = data & 0xF;
635
                        break;
636
                case 7:
637
                        slot.DL  = dl_tab[data >> 4];
638
                        slot.D2R = data & 0xF;
639
                        break;
640
                case 8:
641
                        slot.RC = data >> 4;
642
                        slot.RR = data & 0xF;
643
                        break;
644
                case 9:
645
                        slot.AM = data & 0x7;
646
                        break;
647
                }
648
        } else {
649
                // All non-slot registers
650
                switch (reg) {
651
                case 0x00:      // TEST
652
                case 0x01:
653
                        break;
654
 
655
                case 0x02:
656
                        wavetblhdr = (data >> 2) & 0x7;
657
                        memmode = data & 1;
658
                        break;
659
 
660
                case 0x03:
661
                        memadr = (memadr & 0x00FFFF) | (data << 16);
662
                        break;
663
 
664
                case 0x04:
665
                        memadr = (memadr & 0xFF00FF) | (data << 8);
666
                        break;
667
 
668
                case 0x05:
669
                        memadr = (memadr & 0xFFFF00) | data;
670
                        break;
671
 
672
                case 0x06:  // memory data
673
                        BUSY_Time += 28 * 6 / 9;
674
                        writeMem(memadr, data);
675
                        memadr = (memadr + 1) & 0xFFFFFF;
676
                        break;
677
 
678
                case 0xF8:
679
                        // TODO use these
680
                        fm_l = data & 0x7;
681
                        fm_r = (data >> 3) & 0x7;
682
                        break;
683
 
684
                case 0xF9:
685
                        pcm_l = data & 0x7;
686
                        pcm_r = (data >> 3) & 0x7;
687
                        break;
688
                }
689
        }
690
 
691
        regs[reg] = data;
692
}
693
 
694
u8 YMF278::peekRegOPL4(u8 reg, const EmuTime &time)
695
{
696
        BUSY_Time = time;
697
 
698
        u8 result;
699
        switch(reg) {
700
                case 2: // 3 upper bits are device ID
701
                        result = (regs[2] & 0x1F) | 0x20;
702
                        break;
703
 
704
                case 6: // Memory Data Register
705
                        result = readMem(memadr);
706
                        break;
707
 
708
                default:
709
                        result = regs[reg];
710
                        break;
711
        }
712
        return result;
713
}
714
 
715
u8 YMF278::readRegOPL4(u8 reg, const EmuTime &time)
716
{
717
        BUSY_Time = time;
718
 
719
        u8 result;
720
        switch(reg) {
721
                case 2: // 3 upper bits are device ID
722
                        result = (regs[2] & 0x1F) | 0x20;
723
                        break;
724
 
725
                case 6: // Memory Data Register
726
                        BUSY_Time += 38 * 6 / 9;
727
                        result = readMem(memadr);
728
                        memadr = (memadr + 1) & 0xFFFFFF;
729
                        break;
730
 
731
                default:
732
                        result = regs[reg];
733
                        break;
734
        }
735
        return result;
736
}
737
 
738
u8 YMF278::peekStatus(const EmuTime &time)
739
{
740
        u8 result = 0;
741
        if (time - BUSY_Time < 88 * 6 / 9) {
742
                result |= 0x01;
743
        }
744
        if (time - LD_Time < 10000 * 6 / 9) {
745
                result |= 0x02;
746
        }
747
        return result;
748
}
749
 
750
u8 YMF278::readStatus(const EmuTime &time)
751
{
752
        u8 result = 0;
753
        if (time - BUSY_Time < 88 * 6 / 9) {
754
                result |= 0x01;
755
        }
756
        if (time - LD_Time < 10000 * 6 / 9) {
757
                result |= 0x02;
758
        }
759
        return result;
760
}
761
 
1156 lvd 762
YMF278::YMF278(short volume, size_t ramSizeKb, size_t romSizeKb,
1099 galstaff 763
               const EmuTime &time)
764
{
1156 lvd 765
        ramSize = ramSizeKb * 1024;
766
        romSize = romSizeKb * 1024;
767
 
1099 galstaff 768
        endRom = romSize;
1156 lvd 769
        endRam = endRom + ramSize;
1099 galstaff 770
 
1156 lvd 771
        rom_alloc_attempted = false;
772
        ram_alloc_attempted = false;
1099 galstaff 773
 
1156 lvd 774
        rom = nullptr; // delayed allocation
775
        ram = nullptr; //
1147 lvd 776
 
777
 
1156 lvd 778
        LD_Time = 0;
779
        BUSY_Time = 0;
1147 lvd 780
 
1156 lvd 781
        memadr = 0;     // avoid UMR
1099 galstaff 782
 
1156 lvd 783
        oplOversampling = 1;
1099 galstaff 784
 
785
        reset(time);
786
}
787
 
788
YMF278::~YMF278()
789
{
1147 lvd 790
        if(ram)
791
                free(ram);
792
        if(rom)
793
                free(rom);
1099 galstaff 794
}
795
 
796
void YMF278::reset(const EmuTime &time)
797
{
798
        eg_timer = 0;
799
        eg_cnt   = 0;
800
 
801
    int i;
802
        for (i = 0; i < 24; i++) {
803
                slots[i].reset();
804
        }
805
        for (i = 255; i >= 0; i--) { // reverse order to avoid UMR
806
                writeRegOPL4(i, 0, time);
807
        }
808
        setInternalMute(true);
809
        wavetblhdr = memmode = memadr = 0;
810
        fm_l = fm_r = pcm_l = pcm_r = 0;
811
        BUSY_Time = time;
812
        LD_Time = time;
813
}
814
 
815
void YMF278::setSampleRate(int sampleRate, int Oversampling)
816
{
817
    oplOversampling = Oversampling;
818
        eg_timer_add = (unsigned int)((1 << EG_SH) / oplOversampling);
819
}
820
 
821
void YMF278::setInternalVolume(short newVolume)
822
{
823
    newVolume /= 32;
824
        // Volume table, 1 = -0.375dB, 8 = -3dB, 256 = -96dB
825
    int i;
826
        for (i = 0; i < 256; i++) {
827
                volume[i] = (int)(4.0 * (double)newVolume * pow(2.0, (-0.375 / 6) * i));
828
        }
829
        for (i = 256; i < 256 * 4; i++) {
830
                volume[i] = 0;
831
        }
832
}
833
 
834
u8 YMF278::readMem(unsigned int address)
835
{
1156 lvd 836
        if (address < endRom)
837
                return rom ? rom[address] : 0xFF; // ROM will be allocated only in getRom() or getRomSize() as to be prepared for loading
838
        else if (address < endRam)
839
                return ram ? ram[address - endRom] : 0x00; // RAM will be allocated only during first write attempt
840
 
841
        return 255;     // TODO check
1099 galstaff 842
}
843
 
844
void YMF278::writeMem(unsigned int address, u8 value)
845
{
1156 lvd 846
        if(endRom <= address && address < endRam)
847
        {
848
                if(!ram && !ram_alloc_attempted)
849
                        attempt_alloc_ram();
850
 
851
                if(ram) ram[address - endRom] = value;
1099 galstaff 852
        }
853
}
1156 lvd 854
 
855
u8 * YMF278::getRom()
856
{
857
        if(!rom && !rom_alloc_attempted)
858
                attempt_alloc_rom();
859
 
860
        return rom; // might be null
861
}
862
 
863
size_t YMF278::getRomSize()
864
{
865
        if(!rom && !rom_alloc_attempted)
866
                attempt_alloc_rom();
867
 
868
        return rom ? romSize : 0; // might be 0
869
}
870
 
871
void YMF278::attempt_alloc_rom()
872
{
873
        if(rom_alloc_attempted) return;
874
 
875
        if(romSize>0)
876
        {
877
                if( (rom = (u8 *)malloc(romSize)) )
878
                        memset(rom, 0xFF, romSize);
879
                else
880
                        errmsg("Can't allocate moonsound ROM!");
881
        }
882
        else
883
                errmsg("moonsound ROM size is zero!");
884
 
885
        rom_alloc_attempted = true;
886
}
887
 
888
void YMF278::attempt_alloc_ram()
889
{
890
        if(ram_alloc_attempted) return;
891
 
892
        if(ramSize>0)
893
        {
894
                if( (ram = (u8 *)malloc(ramSize)) )
895
                        memset(ram, 0x00, ramSize);
896
                else
897
                        errmsg("Can't allocate moonsound RAM!");
898
        }
899
        else
900
                errmsg("moonsound RAM size is zero!");
901
 
902
        ram_alloc_attempted = true;
903
}
904