OXYGENHUB
◆ main openmsx / src / sound / YMF278.cc
33.1 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
// Based on ymf278b.c written by R. Belmont and O. Galibert
2
3
// Improved by Valley Bell, 2018
4
// Thanks to niekniek and l_oliveira for providing recordings from OPL4 hardware.
5
// Thanks to superctr and wouterv for discussing changes.
6
//
7
// Improvements:
8
// - added TL interpolation, recordings show that internal TL levels are 0x00..0xff
9
// - fixed ADSR speeds, attack rate 15 is now instant
10
// - correct clamping of intermediate Rate Correction values
11
// - emulation of "loop glitch" (going out-of-bounds by playing a sample faster than it the loop is long)
12
// - made calculation of sample position cleaner and closer to how the HW works
13
// - increased output resolution from TL (0.375dB) to envelope (0.09375dB)
14
// - fixed volume table -6dB steps are done using bit shifts, steps in between are multiplicators
15
// - made octave -8 freeze the sample
16
// - verified that TL and envelope levels are applied separately, both go silent at -60dB
17
// - implemented pseudo-reverb and damping according to manual
18
// - made pseudo-reverb ignore Rate Correction (real hardware ignores it)
19
// - reimplemented LFO, speed exactly matches the formulas that were probably used when creating the manual
20
// - fixed LFO (tremolo) amplitude modulation
21
// - made LFO vibrato and tremolo accurate to hardware
22
//
23
// Known issues:
24
// - Octave -8 was only tested with fnum 0. Other fnum values might behave differently.
25
26
// This class doesn't model a full YMF278B chip. Instead it only models the
27
// wave part. The FM part in modeled in YMF262 (it's almost 100% compatible,
28
// the small differences are handled in YMF262). The status register and
29
// interaction with the FM registers (e.g. the NEW2 bit) is handled in the
30
// YMF278B class.
31
32
#include "YMF278.hh"
33
34
#include "DeviceConfig.hh"
35
#include "MSXException.hh"
36
#include "MSXMotherBoard.hh"
37
#include "serialize.hh"
38
39
#include "enumerate.hh"
40
#include "narrow.hh"
41
#include "one_of.hh"
42
#include "outer.hh"
43
#include "xrange.hh"
44
45
#include <algorithm>
46
47
namespace openmsx {
48
49
// envelope output entries
50
// fixed to match recordings from actual OPL4 -Valley Bell
51
static constexpr int MAX_ATT_INDEX = 0x280; // makes attack phase right and also goes well with "envelope stops at -60dB"
52
static constexpr int MIN_ATT_INDEX = 0;
53
static constexpr int TL_SHIFT      = 2; // envelope values are 4x as fine as TL levels
54
55
static constexpr unsigned LFO_SHIFT = 18; // LFO period of up to 0x40000 sample
56
static constexpr unsigned LFO_PERIOD = 1 << LFO_SHIFT;
57
58
// Envelope Generator phases
59
static constexpr int EG_ATT = 4;
60
static constexpr int EG_DEC = 3;
61
static constexpr int EG_SUS = 2;
62
static constexpr int EG_REL = 1;
63
static constexpr int EG_OFF = 0;
64
// these 2 are only used in old savestates (and are converted to EG_REL on load)
65
static constexpr int EG_REV = 5; // pseudo reverb
66
static constexpr int EG_DMP = 6; // damp
67
68
// Pan values, units are -3dB, i.e. 8.
69
static constexpr std::array<uint8_t, 16> pan_left = {
70
	0, 8, 16, 24, 32, 40, 48, 255, 255,   0,  0,  0,  0,  0,  0, 0
71
};
72
static constexpr std::array<uint8_t, 16> pan_right = {
73
	0, 0,  0,  0,  0,  0,  0,   0, 255, 255, 48, 40, 32, 24, 16, 8
74
};
75
76
// decay level table (3dB per step)
77
// 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)
78
static constexpr int16_t SC(int dB) { return int16_t(dB / 3 * 0x20); }
79
static constexpr std::array<int16_t, 16> dl_tab = {
80
 SC( 0), SC( 3), SC( 6), SC( 9), SC(12), SC(15), SC(18), SC(21),
81
 SC(24), SC(27), SC(30), SC(33), SC(36), SC(39), SC(42), SC(93)
82
};
83
84
static constexpr uint8_t RATE_STEPS = 8;
85
static constexpr std::array<uint8_t, 15 * RATE_STEPS> eg_inc = {
86
//cycle:0  1   2  3   4  5   6  7
87
	0, 1,  0, 1,  0, 1,  0, 1, //  0  rates 00..12 0 (increment by 0 or 1)
88
	0, 1,  0, 1,  1, 1,  0, 1, //  1  rates 00..12 1
89
	0, 1,  1, 1,  0, 1,  1, 1, //  2  rates 00..12 2
90
	0, 1,  1, 1,  1, 1,  1, 1, //  3  rates 00..12 3
91
92
	1, 1,  1, 1,  1, 1,  1, 1, //  4  rate 13 0 (increment by 1)
93
	1, 1,  1, 2,  1, 1,  1, 2, //  5  rate 13 1
94
	1, 2,  1, 2,  1, 2,  1, 2, //  6  rate 13 2
95
	1, 2,  2, 2,  1, 2,  2, 2, //  7  rate 13 3
96
97
	2, 2,  2, 2,  2, 2,  2, 2, //  8  rate 14 0 (increment by 2)
98
	2, 2,  2, 4,  2, 2,  2, 4, //  9  rate 14 1
99
	2, 4,  2, 4,  2, 4,  2, 4, // 10  rate 14 2
100
	2, 4,  4, 4,  2, 4,  4, 4, // 11  rate 14 3
101
102
	4, 4,  4, 4,  4, 4,  4, 4, // 12  rates 15 0, 15 1, 15 2, 15 3 for decay
103
	8, 8,  8, 8,  8, 8,  8, 8, // 13  rates 15 0, 15 1, 15 2, 15 3 for attack (zero time)
104
	0, 0,  0, 0,  0, 0,  0, 0, // 14  infinity rates for attack and decay(s)
105
};
106
107
[[nodiscard]] static constexpr uint8_t O(int a) { return narrow<uint8_t>(a * RATE_STEPS); }
108
static constexpr std::array<uint8_t, 64> eg_rate_select = {
109
	O(14),O(14),O(14),O(14), // inf rate
110
	O( 0),O( 1),O( 2),O( 3),
111
	O( 0),O( 1),O( 2),O( 3),
112
	O( 0),O( 1),O( 2),O( 3),
113
	O( 0),O( 1),O( 2),O( 3),
114
	O( 0),O( 1),O( 2),O( 3),
115
	O( 0),O( 1),O( 2),O( 3),
116
	O( 0),O( 1),O( 2),O( 3),
117
	O( 0),O( 1),O( 2),O( 3),
118
	O( 0),O( 1),O( 2),O( 3),
119
	O( 0),O( 1),O( 2),O( 3),
120
	O( 0),O( 1),O( 2),O( 3),
121
	O( 0),O( 1),O( 2),O( 3),
122
	O( 4),O( 5),O( 6),O( 7),
123
	O( 8),O( 9),O(10),O(11),
124
	O(12),O(12),O(12),O(12),
125
};
126
127
// rate  0,    1,    2,    3,   4,   5,   6,  7,  8,  9,  10, 11, 12, 13, 14, 15
128
// shift 12,   11,   10,   9,   8,   7,   6,  5,  4,  3,  2,  1,  0,  0,  0,  0
129
// mask  4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3,  1,  0,  0,  0,  0
130
static constexpr std::array<uint8_t, 64> eg_rate_shift = {
131
	 12, 12, 12, 12,
132
	 11, 11, 11, 11,
133
	 10, 10, 10, 10,
134
	  9,  9,  9,  9,
135
	  8,  8,  8,  8,
136
	  7,  7,  7,  7,
137
	  6,  6,  6,  6,
138
	  5,  5,  5,  5,
139
	  4,  4,  4,  4,
140
	  3,  3,  3,  3,
141
	  2,  2,  2,  2,
142
	  1,  1,  1,  1,
143
	  0,  0,  0,  0,
144
	  0,  0,  0,  0,
145
	  0,  0,  0,  0,
146
	  0,  0,  0,  0,
147
};
148
149
150
// number of steps the LFO counter advances per sample
151
//   LFO frequency (Hz) -> LFO counter steps per sample
152
[[nodiscard]] static constexpr int L(double a) { return int((LFO_PERIOD * a) / 44100.0 + 0.5); }
153
static constexpr std::array<int, 8> lfo_period = {
154
	L(0.168), // step:  1, period: 262144 samples
155
	L(2.019), // step: 12, period:  21845 samples
156
	L(3.196), // step: 19, period:  13797 samples
157
	L(4.206), // step: 25, period:  10486 samples
158
	L(5.215), // step: 31, period:   8456 samples
159
	L(5.888), // step: 35, period:   7490 samples
160
	L(6.224), // step: 37, period:   7085 samples
161
	L(7.066), // step: 42, period:   6242 samples
162
};
163
164
165
// formula used by Yamaha docs:
166
//     vib_depth_cents(x) = (log2(0x400 + x) - 10) * 1200
167
static constexpr std::array<int16_t, 8> vib_depth = {
168
	0,      //  0.000 cents
169
	2,      //  3.378 cents
170
	3,      //  5.065 cents
171
	4,      //  6.750 cents
172
	6,      // 10.114 cents
173
	12,     // 20.170 cents
174
	24,     // 40.106 cents
175
	48,     // 79.307 cents
176
};
177
178
179
// formula used by Yamaha docs:
180
//     am_depth_db(x) = (x-1) / 0x40 * 6.0
181
//     They use (x-1), because the depth is multiplied with the AM counter, which has a range of 0..0x7F.
182
//     Thus the maximum attenuation with x=0x80 is (0x7F * 0x80) >> 7 = 0x7F.
183
// reversed formula:
184
//     am_depth(dB) = round(dB / 6.0 * 0x40) + 1
185
static constexpr std::array<uint8_t, 8> am_depth = {
186
	0x00,   //  0.000 dB
187
	0x14,   //  1.781 dB
188
	0x20,   //  2.906 dB
189
	0x28,   //  3.656 dB
190
	0x30,   //  4.406 dB
191
	0x40,   //  5.906 dB
192
	0x50,   //  7.406 dB
193
	0x80,   // 11.910 dB
194
};
195
196
197
YMF278::Slot::Slot()
198
{
199
	reset();
200
}
201
202
// Sign extend a 4-bit value to int8_t
203
// require: x in range [0..15]
204
[[nodiscard]] static constexpr int8_t sign_extend_4(int x)
205
{
206
	return narrow<int8_t>((x ^ 8) - 8);
207
}
208
209
// Params: oct in [-8 ..   +7]
210
//         fn  in [ 0 .. 1023]
211
// We want to interpret oct as a signed 4-bit number and calculate
212
//    ((fn | 1024) + vib) << (5 + sign_extend_4(oct))
213
// Though in this formula the shift can go over a negative distance (in that
214
// case we should shift in the other direction).
215
[[nodiscard]] static constexpr unsigned calcStep(int8_t oct, uint16_t fn, int16_t vib = 0)
216
{
217
	if (oct == -8) return 0;
218
	unsigned t = (fn + 1024 + vib) << (8 + oct); // use '+' iso '|' (generates slightly better code)
219
	return t >> 3; // was shifted 3 positions too far
220
}
221
222
void YMF278::Slot::reset()
223
{
224
	wave = FN = TLdest = TL = pan = vib = AM = 0;
225
	OCT = 0;
226
	DL = 0;
227
	AR = D1R = D2R = RC = RR = 0;
228
	PRVB = keyon = DAMP = false;
229
	stepPtr = 0;
230
	step = calcStep(OCT, FN);
231
	bits = 0;
232
	startAddr = 0;
233
	loopAddr = endAddr = 0;
234
	env_vol = MAX_ATT_INDEX;
235
236
	lfo_active = false;
237
	lfo_cnt = 0;
238
	lfo = 0;
239
240
	state = EG_OFF;
241
242
	// not strictly needed, but avoid UMR on savestate
243
	pos = 0;
244
}
245
246
uint8_t YMF278::Slot::compute_rate(int val) const
247
{
248
	if (val == 0) {
249
		return 0;
250
	} else if (val == 15) {
251
		return 63;
252
	}
253
	int res = val * 4;
254
	if (RC != 15) {
255
		// clamping verified with HW tests -Valley Bell
256
		res += 2 * std::clamp(OCT + RC, 0, 15);
257
		res += (FN & 0x200) ? 1 : 0;
258
	}
259
	return narrow<uint8_t>(std::clamp(res, 0, 63));
260
}
261
262
uint8_t YMF278::Slot::compute_decay_rate(int val) const
263
{
264
	if (DAMP) {
265
		// damping
266
		// The manual lists these values for time and attenuation: (44100 samples/second)
267
		// -12dB at  5.8ms, sample 256
268
		// -48dB at  8.0ms, sample 352
269
		// -72dB at  9.4ms, sample 416
270
		// -96dB at 10.9ms, sample 480
271
		// This results in these durations and rate values for the respective phases:
272
		//   0dB .. -12dB: 256 samples (5.80ms) -> 128 samples per -6dB = rate 48
273
		// -12dB .. -48dB:  96 samples (2.18ms) ->  16 samples per -6dB = rate 63
274
		// -48dB .. -72dB:  64 samples (1.45ms) ->  16 samples per -6dB = rate 63
275
		// -72dB .. -96dB:  64 samples (1.45ms) ->  16 samples per -6dB = rate 63
276
		// Damping was verified to ignore rate correction.
277
		if (env_vol < dl_tab[4]) {
278
			return 48; //   0dB .. -12dB
279
		} else {
280
			return 63; // -12dB .. -96dB
281
		}
282
	}
283
	if (PRVB) {
284
		// pseudo reverb
285
		// activated when reaching -18dB, overrides D1R/D2R/RR with reverb rate 5
286
		//
287
		// The manual is actually a bit unclear and just says "RATE=5",
288
		// referring to the D1R/D2R/RR register value. However, later
289
		// pages use "RATE" to refer to the "internal" rate, which is
290
		// (register * 4) + rate correction. HW recordings prove that
291
		// Rate Correction is ignored, so pseudo reverb just sets the
292
		// "internal" rate to a value of 4*5 = 20.
293
		if (env_vol >= dl_tab[6]) {
294
			return 20;
295
		}
296
	}
297
	return compute_rate(val);
298
}
299
300
int16_t YMF278::Slot::compute_vib() const
301
{
302
	// verified via hardware recording:
303
	//  With LFO speed 0 (period 262144 samples), each vibrato step takes
304
	//  4096 samples.
305
	//  -> 64 steps total
306
	//  Also, with vibrato depth 7 (80 cents) and an F-Num of 0x400, the
307
	//  final F-Nums are: 0x400 .. 0x43C, 0x43C .. 0x400, 0x400 .. 0x3C4,
308
	//  0x3C4 .. 0x400
309
	auto lfo_fm = narrow<int16_t>(lfo_cnt / (LFO_PERIOD / 0x40));
310
	// results in +0x00..+0x0F, +0x0F..+0x00, -0x00..-0x0F, -0x0F..-0x00
311
	if (lfo_fm & 0x10) lfo_fm ^= 0x1F;
312
	if (lfo_fm & 0x20) lfo_fm = narrow<int16_t>(-(lfo_fm & 0x0F));
313
314
	return narrow<int16_t>((lfo_fm * vib_depth[vib]) / 12);
315
}
316
317
uint16_t YMF278::Slot::compute_am() const
318
{
319
	// verified via hardware recording:
320
	//  With LFO speed 0 (period 262144 samples), each tremolo step takes
321
	//  1024 samples.
322
	//  -> 256 steps total
323
	auto lfo_am = narrow<uint16_t>(lfo_cnt / (LFO_PERIOD / 0x100));
324
	// results in 0x00..0x7F, 0x7F..0x00
325
	if (lfo_am >= 0x80) lfo_am ^= 0xFF;
326
327
	return narrow<uint16_t>((lfo_am * am_depth[AM]) >> 7);
328
}
329
330
331
void YMF278::advance()
332
{
333
	eg_cnt++;
334
335
	// modulo counters for volume interpolation
336
	auto tl_int_cnt  =  eg_cnt % 9;      // 0 .. 8
337
	auto tl_int_step = (eg_cnt / 9) % 3; // 0 .. 2
338
339
	for (auto& op : slots) {
340
		// volume interpolation
341
		if (tl_int_cnt == 0) {
342
			if (tl_int_step == 0) {
343
				// decrease volume by one step every 27 samples
344
				if (op.TL < op.TLdest) ++op.TL;
345
			} else {
346
				// increase volume by one step every 13.5 samples
347
				if (op.TL > op.TLdest) --op.TL;
348
			}
349
		}
350
351
		if (op.lfo_active) {
352
			op.lfo_cnt = (op.lfo_cnt + lfo_period[op.lfo]) & (LFO_PERIOD - 1);
353
		}
354
355
		// Envelope Generator
356
		switch (op.state) {
357
		case EG_ATT: { // attack phase
358
			uint8_t rate = op.compute_rate(op.AR);
359
			// Verified by HW recording (and matches Nemesis' tests of the YM2612):
360
			// AR = 0xF during KeyOn results in instant switch to EG_DEC. (see keyOnHelper)
361
			// Setting AR = 0xF while the attack phase is in progress freezes the envelope.
362
			if (rate >= 63) {
363
				break;
364
			}
365
			uint8_t shift = eg_rate_shift[rate];
366
			if (!(eg_cnt & ((1 << shift) - 1))) {
367
				uint8_t select = eg_rate_select[rate];
368
				// >>4 makes the attack phase's shape match the actual chip -Valley Bell
369
				op.env_vol = narrow<int16_t>(op.env_vol + ((~op.env_vol * eg_inc[select + ((eg_cnt >> shift) & 7)]) >> 4));
370
				if (op.env_vol <= MIN_ATT_INDEX) {
371
					op.env_vol = MIN_ATT_INDEX;
372
					// TODO does the real HW skip EG_DEC completely,
373
					//      or is it active for 1 sample?
374
					op.state = op.DL ? EG_DEC : EG_SUS;
375
				}
376
			}
377
			break;
378
		}
379
		case EG_DEC: { // decay phase
380
			uint8_t rate = op.compute_decay_rate(op.D1R);
381
			uint8_t shift = eg_rate_shift[rate];
382
			if (!(eg_cnt & ((1 << shift) - 1))) {
383
				uint8_t select = eg_rate_select[rate];
384
				op.env_vol = narrow<int16_t>(op.env_vol + eg_inc[select + ((eg_cnt >> shift) & 7)]);
385
				if (op.env_vol >= op.DL) {
386
					op.state = (op.env_vol < MAX_ATT_INDEX) ? EG_SUS : EG_OFF;
387
				}
388
			}
389
			break;
390
		}
391
		case EG_SUS: { // sustain phase
392
			uint8_t rate = op.compute_decay_rate(op.D2R);
393
			uint8_t shift = eg_rate_shift[rate];
394
			if (!(eg_cnt & ((1 << shift) - 1))) {
395
				uint8_t select = eg_rate_select[rate];
396
				op.env_vol = narrow<int16_t>(op.env_vol + eg_inc[select + ((eg_cnt >> shift) & 7)]);
397
				if (op.env_vol >= MAX_ATT_INDEX) {
398
					op.env_vol = MAX_ATT_INDEX;
399
					op.state = EG_OFF;
400
				}
401
			}
402
			break;
403
		}
404
		case EG_REL: { // release phase
405
			uint8_t rate = op.compute_decay_rate(op.RR);
406
			uint8_t shift = eg_rate_shift[rate];
407
			if (!(eg_cnt & ((1 << shift) - 1))) {
408
				uint8_t select = eg_rate_select[rate];
409
				op.env_vol = narrow<int16_t>(op.env_vol + eg_inc[select + ((eg_cnt >> shift) & 7)]);
410
				if (op.env_vol >= MAX_ATT_INDEX) {
411
					op.env_vol = MAX_ATT_INDEX;
412
					op.state = EG_OFF;
413
				}
414
			}
415
			break;
416
		}
417
		case EG_OFF:
418
			// nothing
419
			break;
420
421
		default:
422
			UNREACHABLE;
423
		}
424
	}
425
}
426
427
int16_t YMF278::getSample(const Slot& slot, uint16_t pos) const
428
{
429
	// TODO How does this behave when R#2 bit 0 = 1?
430
	//      As-if read returns 0xff? (Like for CPU memory reads.) Or is
431
	//      sound generation blocked at some higher level?
432
	switch (slot.bits) {
433
	case 0: {
434
		// 8 bit
435
		return narrow_cast<int16_t>(readMem(slot.startAddr + pos) << 8);
436
	}
437
	case 1: {
438
		// 12 bit
439
		unsigned addr = slot.startAddr + ((pos / 2) * 3);
440
		if (pos & 1) {
441
			return narrow_cast<int16_t>(
442
				(readMem(addr + 2) << 8) |
443
				(readMem(addr + 1) & 0xF0));
444
		} else {
445
			return narrow_cast<int16_t>(
446
				 (readMem(addr + 0) << 8) |
447
				((readMem(addr + 1) << 4) & 0xF0));
448
		}
449
	}
450
	case 2: {
451
		// 16 bit
452
		unsigned addr = slot.startAddr + (pos * 2);
453
		return narrow_cast<int16_t>(
454
			(readMem(addr + 0) << 8) |
455
			(readMem(addr + 1) << 0));
456
	}
457
	default:
458
		// TODO unspecified
459
		return 0;
460
	}
461
}
462
463
uint16_t YMF278::nextPos(const Slot& slot, uint16_t pos, uint16_t increment)
464
{
465
	// If there is a 4-sample loop and you advance 12 samples per step,
466
	// it may exceed the end offset.
467
	// This is abused by the "Lizard Star" song to generate noise at 0:52. -Valley Bell
468
	pos += increment;
469
	if ((uint32_t(pos) + slot.endAddr) >= 0x10000) // check position >= (negated) end address
470
		pos += narrow_cast<uint16_t>(slot.endAddr + slot.loopAddr); // This is how the actual chip does it.
471
	return pos;
472
}
473
474
bool YMF278::anyActive()
475
{
476
	return std::ranges::any_of(slots, [](auto& op) { return op.state != EG_OFF; });
477
}
478
479
// In: 'envVol', 0=max volume, others -> -3/32 = -0.09375 dB/step
480
// Out: 'x' attenuated by the corresponding factor.
481
// Note: microbenchmarks have shown that re-doing this calculation is about the
482
// same speed as using a 4kB lookup table.
483
static constexpr int vol_factor(int x, unsigned envVol)
484
{
485
	if (envVol >= MAX_ATT_INDEX) return 0; // hardware clips to silence below -60dB
486
	int vol_mul = 0x80 - narrow<int>(envVol & 0x3F); // 0x40 values per 6dB
487
	int vol_shift = 7 + narrow<int>(envVol >> 6);
488
	return (x * ((0x8000 * vol_mul) >> vol_shift)) >> 15;
489
}
490
491
void YMF278::setMixLevel(uint8_t x, EmuTime time)
492
{
493
	static constexpr std::array<float, 8> level = {
494
		(1.00f / 1), //   0dB
495
		(0.75f / 1), //  -3dB (approx)
496
		(1.00f / 2), //  -6dB
497
		(0.75f / 2), //  -9dB (approx)
498
		(1.00f / 4), // -12dB
499
		(0.75f / 4), // -15dB (approx)
500
		(1.00f / 8), // -18dB
501
		 0.00f       // -inf dB
502
	};
503
	setSoftwareVolume(level[x & 7], level[(x >> 3) & 7], time);
504
}
505
506
void YMF278::generateChannels(std::span<float*> bufs, unsigned num)
507
{
508
	if (!anyActive()) {
509
		// TODO update internal state, even if muted
510
		// TODO also mute individual channels
511
		std::ranges::fill(bufs, nullptr);
512
		return;
513
	}
514
515
	for (auto j : xrange(num)) {
516
		for (auto i : xrange(24)) {
517
			auto& sl = slots[i];
518
			if (sl.state == EG_OFF) {
519
				//bufs[i][2 * j + 0] += 0;
520
				//bufs[i][2 * j + 1] += 0;
521
				continue;
522
			}
523
524
			auto sample = narrow_cast<int16_t>(
525
				(getSample(sl, sl.pos) * (0x10000 - sl.stepPtr) +
526
				 getSample(sl, nextPos(sl, sl.pos, 1)) * sl.stepPtr) >> 16);
527
			// TL levels are 00..FF internally (TL register value 7F is mapped to TL level FF)
528
			// Envelope levels have 4x the resolution (000..3FF)
529
			// Volume levels are approximate logarithmic. -6dB result in half volume. Steps in between use linear interpolation.
530
			// A volume of -60dB or lower results in silence. (value 0x280..0x3FF).
531
			// Recordings from actual hardware indicate that TL level and envelope level are applied separately.
532
			// Each of them is clipped to silence below -60dB, but TL+envelope might result in a lower volume. -Valley Bell
533
			auto envVol = narrow_cast<uint16_t>(
534
				std::min(sl.env_vol + ((sl.lfo_active && sl.AM) ? sl.compute_am() : 0),
535
				         MAX_ATT_INDEX));
536
			int smplOut = vol_factor(vol_factor(sample, envVol), sl.TL << TL_SHIFT);
537
538
			// Panning is also done separately. (low-volume TL + low-volume panning goes below -60dB)
539
			// I'll be taking wild guess and assume that -3dB is approximated with 75%. (same as with TL and envelope levels)
540
			// The same applies to the PCM mix level.
541
			int32_t volLeft  = pan_left [sl.pan]; // note: register 0xF9 is handled externally
542
			int32_t volRight = pan_right[sl.pan];
543
			// 0 -> 0x20, 8 -> 0x18, 16 -> 0x10, 24 -> 0x0C, etc. (not using vol_factor here saves array boundary checks)
544
			volLeft  = (0x20 - (volLeft  & 0x0f)) >> (volLeft  >> 4);
545
			volRight = (0x20 - (volRight & 0x0f)) >> (volRight >> 4);
546
547
			bufs[i][2 * j + 0] += narrow_cast<float>((smplOut * volLeft ) >> 5);
548
			bufs[i][2 * j + 1] += narrow_cast<float>((smplOut * volRight) >> 5);
549
550
			unsigned step = (sl.lfo_active && sl.vib)
551
			              ? calcStep(sl.OCT, sl.FN, sl.compute_vib())
552
			              : sl.step;
553
			sl.stepPtr += step;
554
555
			if (sl.stepPtr >= 0x10000) {
556
				sl.pos = nextPos(sl, sl.pos, narrow<uint16_t>(sl.stepPtr >> 16));
557
				sl.stepPtr &= 0xffff;
558
			}
559
		}
560
		advance();
561
	}
562
}
563
564
void YMF278::keyOnHelper(YMF278::Slot& slot) const
565
{
566
	// Unlike FM, the envelope level is reset. (And it makes sense, because you restart the sample.)
567
	slot.env_vol = MAX_ATT_INDEX;
568
	if (slot.compute_rate(slot.AR) < 63) {
569
		slot.state = EG_ATT;
570
	} else {
571
		// Nuke.YKT verified that the FM part does it exactly this way,
572
		// and the OPL4 manual says it's instant as well.
573
		slot.env_vol = MIN_ATT_INDEX;
574
		// see comment in 'case EG_ATT' in YMF278::advance()
575
		slot.state = slot.DL ? EG_DEC : EG_SUS;
576
	}
577
	slot.stepPtr = 0;
578
	slot.pos = 0;
579
}
580
581
void YMF278::writeReg(uint8_t reg, uint8_t data, EmuTime time)
582
{
583
	updateStream(time); // TODO optimize only for regs that directly influence sound
584
	writeRegDirect(reg, data, time);
585
}
586
587
void YMF278::writeRegDirect(uint8_t reg, uint8_t data, EmuTime time)
588
{
589
	// Handle slot registers specifically
590
	if (reg >= 0x08 && reg <= 0xF7) {
591
		int sNum = (reg - 8) % 24;
592
		auto& slot = slots[sNum];
593
		switch ((reg - 8) / 24) {
594
		case 0: {
595
			slot.wave = (slot.wave & 0x100) | data;
596
			int waveTblHdr = (regs[2] >> 2) & 0x7;
597
			int base = (slot.wave < 384 || !waveTblHdr) ?
598
			           (slot.wave * 12) :
599
			           (waveTblHdr * 0x80000 + ((slot.wave - 384) * 12));
600
			std::array<uint8_t, 12> buf;
601
			for (auto i : xrange(12)) {
602
				// TODO What if R#2 bit 0 = 1?
603
				//      See also getSample()
604
				buf[i] = readMem(base + i);
605
			}
606
			slot.bits = (buf[0] & 0xC0) >> 6;
607
			slot.startAddr = buf[2] | (buf[1] << 8) | ((buf[0] & 0x3F) << 16);
608
			slot.loopAddr = uint16_t(buf[4] | (buf[3] << 8));
609
			slot.endAddr  = uint16_t(buf[6] | (buf[5] << 8));
610
			for (auto i : xrange(7, 12)) {
611
				// Verified on real YMF278:
612
				// After tone loading, if you read these
613
				// registers, their value actually has changed.
614
				writeRegDirect(narrow<uint8_t>(8 + sNum + (i - 2) * 24), buf[i], time);
615
			}
616
			if (slot.keyon) {
617
				keyOnHelper(slot);
618
			} else {
619
				slot.stepPtr = 0;
620
				slot.pos = 0;
621
			}
622
			break;
623
		}
624
		case 1: {
625
			slot.wave = uint16_t((slot.wave & 0xFF) | ((data & 0x1) << 8));
626
			slot.FN = (slot.FN & 0x380) | (data >> 1);
627
			slot.step = calcStep(slot.OCT, slot.FN);
628
			break;
629
		}
630
		case 2: {
631
			slot.FN = uint16_t((slot.FN & 0x07F) | ((data & 0x07) << 7));
632
			slot.PRVB = (data & 0x08) != 0;
633
			slot.OCT = sign_extend_4((data & 0xF0) >> 4);
634
			slot.step = calcStep(slot.OCT, slot.FN);
635
			break;
636
		}
637
		case 3: {
638
			uint8_t t = data >> 1;
639
			slot.TLdest = (t != 0x7f) ? t : 0xff; // verified on HW via volume interpolation
640
			if (data & 1) {
641
				// directly change volume
642
				slot.TL = slot.TLdest;
643
			} else {
644
				// interpolate volume
645
			}
646
			break;
647
		}
648
		case 4:
649
			if (data & 0x10) {
650
				// output to DO1 pin:
651
				// this pin is not used in MoonSound
652
				// we emulate this by muting the sound
653
				slot.pan = 8; // both left/right -inf dB
654
			} else {
655
				slot.pan = data & 0x0F;
656
			}
657
658
			if (data & 0x20) {
659
				// LFO reset
660
				slot.lfo_active = false;
661
				slot.lfo_cnt = 0;
662
			} else {
663
				// LFO activate
664
				slot.lfo_active = true;
665
			}
666
667
			slot.DAMP = (data & 0x40) != 0;
668
669
			if (data & 0x80) {
670
				if (!slot.keyon) {
671
					slot.keyon = true;
672
					keyOnHelper(slot);
673
				}
674
			} else {
675
				if (slot.keyon) {
676
					slot.keyon = false;
677
					slot.state = EG_REL;
678
				}
679
			}
680
			break;
681
		case 5:
682
			slot.lfo = (data >> 3) & 0x7;
683
			slot.vib = data & 0x7;
684
			break;
685
		case 6:
686
			slot.AR  = data >> 4;
687
			slot.D1R = data & 0xF;
688
			break;
689
		case 7:
690
			slot.DL  = dl_tab[data >> 4];
691
			slot.D2R = data & 0xF;
692
			break;
693
		case 8:
694
			slot.RC = data >> 4;
695
			slot.RR = data & 0xF;
696
			break;
697
		case 9:
698
			slot.AM = data & 0x7;
699
			break;
700
		}
701
	} else {
702
		// All non-slot registers
703
		switch (reg) {
704
		case 0x00: // TEST
705
		case 0x01:
706
			break;
707
708
		case 0x02:
709
			// wave-table-header / memory-type / memory-access-mode
710
			// Simply store in regs[2]
711
			// Immediately write reg here and update memory pointers
712
			regs[2] = data;
713
			setupMemoryPointers();
714
			break;
715
716
		case 0x03:
717
			// Verified on real YMF278:
718
			// * Don't update the 'memAdr' variable on writes to
719
			//   reg 3 and 4. Only store the value in the 'regs'
720
			//   array for later use.
721
			// * The upper 2 bits are not used to address the
722
			//   external memories (so from a HW pov they don't
723
			//   matter). But if you read back this register, the
724
			//   upper 2 bits always read as '0' (even if you wrote
725
			//   '1'). So we mask the bits here already.
726
			data &= 0x3F;
727
			break;
728
729
		case 0x04:
730
			// See reg 3.
731
			break;
732
733
		case 0x05:
734
			// Verified on real YMF278: (see above)
735
			// Only writes to reg 5 change the (full) 'memAdr'.
736
			memAdr = (regs[3] << 16) | (regs[4] << 8) | data;
737
			break;
738
739
		case 0x06:  // memory data
740
			if (regs[2] & 1) {
741
				writeMem(memAdr, data);
742
				++memAdr; // no need to mask (again) here
743
			} else {
744
				// Verified on real YMF278:
745
				//  - writes are ignored
746
				//  - memAdr is NOT increased
747
			}
748
			break;
749
750
		case 0xf8: // These are implemented in MSXMoonSound.cc
751
		case 0xf9:
752
			break;
753
		}
754
	}
755
756
	regs[reg] = data;
757
}
758
759
uint8_t YMF278::readReg(uint8_t reg)
760
{
761
	// no need to call updateStream(time)
762
	uint8_t result = peekReg(reg);
763
	if (reg == 6) {
764
		// Memory Data Register
765
		if (regs[2] & 1) {
766
			// Verified on real YMF278:
767
			// memAdr is only increased when 'regs[2] & 1'
768
			++memAdr; // no need to mask (again) here
769
		}
770
	}
771
	return result;
772
}
773
774
uint8_t YMF278::peekReg(uint8_t reg) const
775
{
776
	switch (reg) {
777
		case 2: // 3 upper bits are device ID
778
			return (regs[2] & 0x1F) | 0x20;
779
780
		case 6: // Memory Data Register
781
			if (regs[2] & 1) {
782
				return readMem(memAdr);
783
			} else {
784
				// Verified on real YMF278
785
				return 0xff;
786
			}
787
788
		default:
789
			return regs[reg];
790
	}
791
}
792
793
static constexpr unsigned INPUT_RATE = 44100;
794
795
YMF278::YMF278(const std::string& name_, size_t ramSize, DeviceConfig& config,
796
               SetupMemPtrFunc setupMemPtrs_)
797
	: ResampledSoundDevice(config.getMotherBoard(), name_, "OPL4 wave-part",
798
	                       24, INPUT_RATE, true)
799
	, motherBoard(config.getMotherBoard())
800
	, debugRegisters(motherBoard, getName())
801
	, debugMemory   (motherBoard, getName())
802
	, rom(getName() + " ROM", "rom", config)
803
	, ram(config, getName() + " RAM", "YMF278 sample RAM", ramSize)
804
	, setupMemPtrs(std::move(setupMemPtrs_))
805
{
806
	if (rom.size() != 0x200000) { // 2MB
807
		throw MSXException(
808
			"Wrong ROM for OPL4 (YMF278B). The ROM (usually "
809
			"called yrw801.rom) should have a size of exactly 2MB.");
810
	}
811
812
	memAdr = 0; // avoid UMR
813
	std::ranges::fill(regs, 0);
814
815
	registerSound(config);
816
	reset(motherBoard.getCurrentTime()); // must come after registerSound() because of call to setSoftwareVolume() via setMixLevel()
817
}
818
819
YMF278::~YMF278()
820
{
821
	unregisterSound();
822
}
823
824
void YMF278::clearRam()
825
{
826
	ram.clear(0);
827
}
828
829
void YMF278::reset(EmuTime time)
830
{
831
	updateStream(time);
832
833
	eg_cnt = 0;
834
835
	for (auto& op : slots) {
836
		op.reset();
837
	}
838
	regs[2] = 0; // avoid UMR
839
	for (int i = 0xf7; i >= 0; --i) { // reverse order to avoid UMR
840
		writeRegDirect(narrow<uint8_t>(i), 0, time);
841
	}
842
	regs[0xf8] = 0x1b; // FM mix-level, see also YMF262 reset
843
	regs[0xf9] = 0x00; // Wave mix-level
844
	memAdr = 0;
845
	setMixLevel(0, time);
846
847
	setupMemoryPointers();
848
}
849
850
// The YMF278B chip has 10 chip-select output signals named /MCS0 .. /MSC9.
851
// There is a 4MB address space to store samples (e.g. in ROM or RAM). Depending on
852
// which address is accessed, one or more of these /MCSx signals get active. And there
853
// are two modes for this mapping (controlled via bit 1 in R#2):
854
//
855
//              mode=0              mode=1
856
//  /MCS0   0x000000-0x1FFFFF   0x000000-0x1FFFFF
857
//  /MCS1   0x200000-0x3FFFFF   0x000000-0x0FFFFF
858
//  /MCS2   0x000000-0x0FFFFF   0x100000-0x1FFFFF
859
//  /MCS3   0x100000-0x1FFFFF   0x200000-0x2FFFFF
860
//  /MCS4   0x200000-0x2FFFFF   0x200000-0x27FFFF
861
//  /MCS5   0x300000-0x3FFFFF   0x280000-0x2FFFFF
862
//  /MCS6   0x200000-0x27FFFF   0x380000-0x39FFFF
863
//  /MCS7   0x280000-0x2FFFFF   0x3A0000-0x3BFFFF
864
//  /MCS8   0x300000-0x37FFFF   0x3C0000-0x3DFFFF
865
//  /MCS9   0x380000-0x3FFFFF   0x3E0000-0x3FFFFF
866
void YMF278::setupMemoryPointers()
867
{
868
	bool mode0 = (regs[2] & 2) == 0;
869
	setupMemPtrs(mode0, rom, ram, memPtrs);
870
}
871
872
uint8_t YMF278::readMem(unsigned address) const
873
{
874
	// Verified on real YMF278: address space wraps at 4MB.
875
	address &= 0x3F'FFFF;
876
	if (auto chunk = memPtrs[address >> 17].asOptional()) { // 128kB chunk
877
		return (*chunk)[address & 0x1'FFFF];
878
	}
879
	return 0xFF;
880
}
881
882
void YMF278::writeMem(unsigned address, uint8_t value)
883
{
884
	address &= 0x3F'FFFF;
885
	if (auto chunk = memPtrs[address >> 17].asOptional()) { // mapped?
886
		const auto* ptr = chunk->data() + (address & 0x1'ffff);
887
		if ((&ram[0] <= ptr) && (ptr < (&ram[0] + ram.size()))) { // points to RAM?
888
			// this assumes all RAM is emulated via a single contiguous memory block
889
			auto ramOffset = ptr - &ram[0];
890
			ram.write(ramOffset, value);
891
		}
892
	}
893
	// ignore writes to non-mapped, or non-RAM regions
894
}
895
896
// version 1: initial version, some variables were saved as char
897
// version 2: serialization framework was fixed to save/load chars as numbers
898
//            but for backwards compatibility we still load old savestates as
899
//            characters
900
// version 3: 'step' is no longer stored (it is recalculated)
901
// version 4:
902
//  - removed members: 'lfo', 'LD', 'active'
903
//  - new members 'TLdest', 'keyon', 'DAMP' restored from registers instead of serialized
904
//  - store 'OCT' sign-extended
905
//  - store 'endAddr' as 2s complement
906
//  - removed EG_DMP and EG_REV enum values from 'state'
907
// version 5:
908
//  - re-added 'lfo' member. This is not stored in the savestate, instead it's
909
//    restored from register values in YMF278::serialize()
910
//  - removed members 'lfo_step' and ' 'lfo_max'
911
//  - 'lfo_cnt' has changed meaning (but we don't try to translate old to new meaning)
912
// version 6:
913
//  - removed members: 'sample1', 'sample2'
914
template<typename Archive>
915
void YMF278::Slot::serialize(Archive& ar, unsigned version)
916
{
917
	// TODO restore more state from registers
918
	ar.serialize("startaddr", startAddr,
919
	             "loopaddr",  loopAddr,
920
	             "stepptr",   stepPtr,
921
	             "pos",       pos,
922
	             "env_vol",   env_vol,
923
	             "lfo_cnt",   lfo_cnt,
924
	             "DL",        DL,
925
	             "wave",      wave,
926
	             "FN",        FN);
927
	if (ar.versionAtLeast(version, 4)) {
928
		ar.serialize("endaddr", endAddr,
929
		             "OCT",     OCT);
930
	} else {
931
		unsigned e = 0; ar.serialize("endaddr", e); endAddr = uint16_t((e ^ 0xffff) + 1);
932
933
		char O = 0;
934
		if (ar.versionAtLeast(version, 2)) {
935
			ar.serialize("OCT", O);
936
		} else {
937
			ar.serializeChar("OCT", O);
938
		}
939
		OCT = sign_extend_4(O);
940
	}
941
942
	if (ar.versionAtLeast(version, 2)) {
943
		ar.serialize("PRVB", PRVB,
944
		             "TL",   TL,
945
		             "pan",  pan,
946
		             "vib",  vib,
947
		             "AM",   AM,
948
		             "AR",   AR,
949
		             "D1R",  D1R,
950
		             "D2R",  D2R,
951
		             "RC",   RC,
952
		             "RR",   RR);
953
	} else {
954
		// for backwards compatibility with old savestates
955
		char PRVB_ = 0; ar.serializeChar("PRVB", PRVB_); PRVB = PRVB_;
956
		char TL_  = 0; ar.serializeChar("TL",  TL_ ); TL  = TL_;
957
		char pan_ = 0; ar.serializeChar("pan", pan_); pan = pan_;
958
		char vib_ = 0; ar.serializeChar("vib", vib_); vib = vib_;
959
		char AM_  = 0; ar.serializeChar("AM",  AM_ ); AM  = AM_;
960
		char AR_  = 0; ar.serializeChar("AR",  AR_ ); AR  = AR_;
961
		char D1R_ = 0; ar.serializeChar("D1R", D1R_); D1R = D1R_;
962
		char D2R_ = 0; ar.serializeChar("D2R", D2R_); D2R = D2R_;
963
		char RC_  = 0; ar.serializeChar("RC",  RC_ ); RC  = RC_;
964
		char RR_  = 0; ar.serializeChar("RR",  RR_ ); RR  = RR_;
965
	}
966
	ar.serialize("bits",       bits,
967
	             "lfo_active", lfo_active);
968
969
	ar.serialize("state", state);
970
	if (ar.versionBelow(version, 4)) {
971
		assert(Archive::IS_LOADER);
972
		if (state == one_of(EG_REV, EG_DMP)) {
973
			state = EG_REL;
974
		}
975
	}
976
977
	// Recalculate redundant state
978
	if constexpr (Archive::IS_LOADER) {
979
		step = calcStep(OCT, FN);
980
	}
981
982
	// This old comment is NOT completely true:
983
	//    Older version also had "env_vol_step" and "env_vol_lim" but those
984
	//    members were nowhere used, so removed those in the current
985
	//    version (it's ok to remove members from the savestate without
986
	//    updating the version number).
987
	// When you remove member variables without increasing the version
988
	// number, new openMSX executables can still read old savestates. And
989
	// if you try to load a new savestate in an old openMSX version you do
990
	// get a (cryptic) error message. But if the version number is
991
	// increased the error message is much clearer.
992
}
993
994
// version 1: initial version
995
// version 2: loadTime and busyTime moved to MSXMoonSound class
996
// version 3: memAdr cannot be restored from register values
997
// version 4: implement ram via Ram class
998
template<typename Archive>
999
void YMF278::serialize(Archive& ar, unsigned version)
1000
{
1001
	ar.serialize("slots",  slots,
1002
	             "eg_cnt", eg_cnt);
1003
	if (ar.versionAtLeast(version, 4)) {
1004
		ar.serialize("ram", ram);
1005
	} else {
1006
		ar.serialize_blob("ram", ram.getWriteBackdoor());
1007
	}
1008
	ar.serialize_blob("registers", regs);
1009
	if (ar.versionAtLeast(version, 3)) { // must come after 'regs'
1010
		ar.serialize("memadr", memAdr);
1011
	} else {
1012
		assert(Archive::IS_LOADER);
1013
		// Old formats didn't store 'memAdr' so we also can't magically
1014
		// restore the correct value. The best we can do is restore the
1015
		// last set address.
1016
		regs[3] &= 0x3F; // mask upper two bits
1017
		memAdr = (regs[3] << 16) | (regs[4] << 8) | regs[5];
1018
	}
1019
1020
	// TODO restore more state from registers
1021
	if constexpr (Archive::IS_LOADER) {
1022
		for (auto [i, sl] : enumerate(slots)) {
1023
			uint8_t t = regs[0x50 + i] >> 1;
1024
			sl.TLdest = (t != 0x7f) ? t : 0xff;
1025
1026
			sl.keyon = (regs[0x68 + i] & 0x80) != 0;
1027
			sl.DAMP  = (regs[0x68 + i] & 0x40) != 0;
1028
			sl.lfo   = (regs[0x80 + i] >> 3) & 7;
1029
		}
1030
	}
1031
	// subclasses are responsible for calling setupMemoryPointers()
1032
}
1033
INSTANTIATE_SERIALIZE_METHODS(YMF278);
1034
1035
1036
// class DebugRegisters
1037
1038
YMF278::DebugRegisters::DebugRegisters(MSXMotherBoard& motherBoard_,
1039
                                       const std::string& name_)
1040
	: SimpleDebuggable(motherBoard_, name_ + " regs",
1041
	                   "OPL4 registers", 0x100)
1042
{
1043
}
1044
1045
uint8_t YMF278::DebugRegisters::read(unsigned address)
1046
{
1047
	const auto& ymf278 = OUTER(YMF278, debugRegisters);
1048
	return ymf278.peekReg(narrow<uint8_t>(address));
1049
}
1050
1051
void YMF278::DebugRegisters::write(unsigned address, uint8_t value, EmuTime time)
1052
{
1053
	auto& ymf278 = OUTER(YMF278, debugRegisters);
1054
	ymf278.writeReg(narrow<uint8_t>(address), value, time);
1055
}
1056
1057
1058
// class DebugMemory
1059
1060
YMF278::DebugMemory::DebugMemory(MSXMotherBoard& motherBoard_,
1061
                                 const std::string& name_)
1062
	: SimpleDebuggable(motherBoard_, name_ + " mem",
1063
	                   "OPL4 memory (includes both ROM and RAM)", 0x400000) // 4MB
1064
{
1065
}
1066
1067
uint8_t YMF278::DebugMemory::read(unsigned address)
1068
{
1069
	const auto& ymf278 = OUTER(YMF278, debugMemory);
1070
	return ymf278.readMem(address);
1071
}
1072
1073
void YMF278::DebugMemory::write(unsigned address, uint8_t value)
1074
{
1075
	auto& ymf278 = OUTER(YMF278, debugMemory);
1076
	ymf278.writeMem(address, value);
1077
}
1078
1079
} // namespace openmsx