OXYGENHUB
◆ main openmsx / src / sound / YMF262.cc
49.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
/*
2
 *
3
 * File: ymf262.c - software implementation of YMF262
4
 *                  FM sound generator type OPL3
5
 *
6
 * Copyright (C) 2003 Jarek Burczynski
7
 *
8
 * Version 0.2
9
 *
10
 *
11
 * Revision History:
12
 *
13
 * 03-03-2003: initial release
14
 *  - thanks to Olivier Galibert and Chris Hardy for YMF262 and YAC512 chips
15
 *  - thanks to Stiletto for the datasheets
16
 *
17
 *
18
 *
19
 * differences between OPL2 and OPL3 not documented in Yamaha datasheets:
20
 * - sinus table is a little different: the negative part is off by one...
21
 *
22
 * - in order to enable selection of four different waveforms on OPL2
23
 *   one must set bit 5 in register 0x01(test).
24
 *   on OPL3 this bit is ignored and 4-waveform select works *always*.
25
 *   (Don't confuse this with OPL3's 8-waveform select.)
26
 *
27
 * - Envelope Generator: all 15 x rates take zero time on OPL3
28
 *   (on OPL2 15 0 and 15 1 rates take some time while 15 2 and 15 3 rates
29
 *   take zero time)
30
 *
31
 * - channel calculations: output of operator 1 is in perfect sync with
32
 *   output of operator 2 on OPL3; on OPL and OPL2 output of operator 1
33
 *   is always delayed by one sample compared to output of operator 2
34
 *
35
 *
36
 * differences between OPL2 and OPL3 shown in datasheets:
37
 * - YMF262 does not support CSM mode
38
 */
39
40
#include "YMF262.hh"
41
42
#include "DeviceConfig.hh"
43
#include "MSXMotherBoard.hh"
44
#include "serialize.hh"
45
46
#include "Math.hh"
47
#include "cstd.hh"
48
#include "narrow.hh"
49
#include "outer.hh"
50
#include "xrange.hh"
51
52
#include <algorithm>
53
#include <array>
54
#include <cmath>
55
#include <iostream>
56
57
namespace openmsx {
58
59
[[nodiscard]] static constexpr YMF262::FreqIndex fnumToIncrement(unsigned block_fnum)
60
{
61
	// opn phase increment counter = 20bit
62
	// chip works with 10.10 fixed point, while we use 16.16
63
	int block = narrow<int>((block_fnum & 0x1C00) >> 10);
64
	return YMF262::FreqIndex(block_fnum & 0x03FF) >> (11 - block);
65
}
66
67
// envelope output entries
68
static constexpr int ENV_BITS    = 10;
69
static constexpr int ENV_LEN     = 1 << ENV_BITS;
70
static constexpr double ENV_STEP = 128.0 / ENV_LEN;
71
72
static constexpr int MAX_ATT_INDEX = (1 << (ENV_BITS - 1)) - 1; // 511
73
static constexpr int MIN_ATT_INDEX = 0;
74
75
static constexpr int TL_RES_LEN = 256; // 8 bits addressing (real chip)
76
77
// register number to channel number , slot offset
78
static constexpr uint8_t MOD = 0;
79
static constexpr uint8_t CAR = 1;
80
81
82
// mapping of register number (offset) to slot number used by the emulator
83
static constexpr std::array<int, 32> slot_array = {
84
	 0,  2,  4,  1,  3,  5, -1, -1,
85
	 6,  8, 10,  7,  9, 11, -1, -1,
86
	12, 14, 16, 13, 15, 17, -1, -1,
87
	-1, -1, -1, -1, -1, -1, -1, -1
88
};
89
90
91
// key scale level
92
// table is 3dB/octave , DV converts this into 6dB/octave
93
// 0.1875 is bit 0 weight of the envelope counter (volume) expressed
94
// in the 'decibel' scale
95
[[nodiscard]] static constexpr int DV(double x) { return int(x / (0.1875 / 2.0)); }
96
static constexpr std::array<unsigned, 8 * 16> ksl_tab = {
97
	// OCT 0
98
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
99
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
100
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
101
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
102
	// OCT 1
103
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
104
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
105
	DV( 0.000), DV( 0.750), DV( 1.125), DV( 1.500),
106
	DV( 1.875), DV( 2.250), DV( 2.625), DV( 3.000),
107
	// OCT 2
108
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 0.000),
109
	DV( 0.000), DV( 1.125), DV( 1.875), DV( 2.625),
110
	DV( 3.000), DV( 3.750), DV( 4.125), DV( 4.500),
111
	DV( 4.875), DV( 5.250), DV( 5.625), DV( 6.000),
112
	// OCT 3
113
	DV( 0.000), DV( 0.000), DV( 0.000), DV( 1.875),
114
	DV( 3.000), DV( 4.125), DV( 4.875), DV( 5.625),
115
	DV( 6.000), DV( 6.750), DV( 7.125), DV( 7.500),
116
	DV( 7.875), DV( 8.250), DV( 8.625), DV( 9.000),
117
	// OCT 4
118
	DV( 0.000), DV( 0.000), DV( 3.000), DV( 4.875),
119
	DV( 6.000), DV( 7.125), DV( 7.875), DV( 8.625),
120
	DV( 9.000), DV( 9.750), DV(10.125), DV(10.500),
121
	DV(10.875), DV(11.250), DV(11.625), DV(12.000),
122
	// OCT 5
123
	DV( 0.000), DV( 3.000), DV( 6.000), DV( 7.875),
124
	DV( 9.000), DV(10.125), DV(10.875), DV(11.625),
125
	DV(12.000), DV(12.750), DV(13.125), DV(13.500),
126
	DV(13.875), DV(14.250), DV(14.625), DV(15.000),
127
	// OCT 6
128
	DV( 0.000), DV( 6.000), DV( 9.000), DV(10.875),
129
	DV(12.000), DV(13.125), DV(13.875), DV(14.625),
130
	DV(15.000), DV(15.750), DV(16.125), DV(16.500),
131
	DV(16.875), DV(17.250), DV(17.625), DV(18.000),
132
	// OCT 7
133
	DV( 0.000), DV( 9.000), DV(12.000), DV(13.875),
134
	DV(15.000), DV(16.125), DV(16.875), DV(17.625),
135
	DV(18.000), DV(18.750), DV(19.125), DV(19.500),
136
	DV(19.875), DV(20.250), DV(20.625), DV(21.000)
137
};
138
139
// sustain level table (3dB per step)
140
// 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)
141
[[nodiscard]] static constexpr int SC(int db) { return int(db * (2.0 / ENV_STEP)); }
142
static constexpr std::array<int, 16> sl_tab = {
143
	SC( 0), SC( 1), SC( 2), SC(3 ), SC(4 ), SC(5 ), SC(6 ), SC( 7),
144
	SC( 8), SC( 9), SC(10), SC(11), SC(12), SC(13), SC(14), SC(31)
145
};
146
147
148
static constexpr uint8_t RATE_STEPS = 8;
149
static constexpr std::array<uint8_t, 15 * RATE_STEPS> eg_inc = {
150
//cycle:0 1  2 3  4 5  6 7
151
	0,1, 0,1, 0,1, 0,1, //  0  rates 00..12 0 (increment by 0 or 1)
152
	0,1, 0,1, 1,1, 0,1, //  1  rates 00..12 1
153
	0,1, 1,1, 0,1, 1,1, //  2  rates 00..12 2
154
	0,1, 1,1, 1,1, 1,1, //  3  rates 00..12 3
155
156
	1,1, 1,1, 1,1, 1,1, //  4  rate 13 0 (increment by 1)
157
	1,1, 1,2, 1,1, 1,2, //  5  rate 13 1
158
	1,2, 1,2, 1,2, 1,2, //  6  rate 13 2
159
	1,2, 2,2, 1,2, 2,2, //  7  rate 13 3
160
161
	2,2, 2,2, 2,2, 2,2, //  8  rate 14 0 (increment by 2)
162
	2,2, 2,4, 2,2, 2,4, //  9  rate 14 1
163
	2,4, 2,4, 2,4, 2,4, // 10  rate 14 2
164
	2,4, 4,4, 2,4, 4,4, // 11  rate 14 3
165
166
	4,4, 4,4, 4,4, 4,4, // 12  rates 15 0, 15 1, 15 2, 15 3 for decay
167
	8,8, 8,8, 8,8, 8,8, // 13  rates 15 0, 15 1, 15 2, 15 3 for attack (zero time)
168
	0,0, 0,0, 0,0, 0,0, // 14  infinity rates for attack and decay(s)
169
};
170
171
172
// note that there is no O(13) in this table - it's directly in the code
173
[[nodiscard]] static constexpr uint8_t O(int a) { return narrow<uint8_t>(a * RATE_STEPS); }
174
static constexpr std::array<uint8_t, 16 + 64 + 16> eg_rate_select = {
175
	// Envelope Generator rates (16 + 64 rates + 16 RKS)
176
	// 16 infinite time rates
177
	O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
178
	O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
179
180
	// rates 00-12
181
	O( 0), O( 1), O( 2), O( 3),
182
	O( 0), O( 1), O( 2), O( 3),
183
	O( 0), O( 1), O( 2), O( 3),
184
	O( 0), O( 1), O( 2), O( 3),
185
	O( 0), O( 1), O( 2), O( 3),
186
	O( 0), O( 1), O( 2), O( 3),
187
	O( 0), O( 1), O( 2), O( 3),
188
	O( 0), O( 1), O( 2), O( 3),
189
	O( 0), O( 1), O( 2), O( 3),
190
	O( 0), O( 1), O( 2), O( 3),
191
	O( 0), O( 1), O( 2), O( 3),
192
	O( 0), O( 1), O( 2), O( 3),
193
	O( 0), O( 1), O( 2), O( 3),
194
195
	// rate 13
196
	O( 4), O( 5), O( 6), O( 7),
197
198
	// rate 14
199
	O( 8), O( 9), O(10), O(11),
200
201
	// rate 15
202
	O(12), O(12), O(12), O(12),
203
204
	// 16 dummy rates (same as 15 3)
205
	O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
206
	O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
207
};
208
209
// rate  0,    1,    2,    3,   4,   5,   6,  7,  8,  9,  10, 11, 12, 13, 14, 15
210
// shift 12,   11,   10,   9,   8,   7,   6,  5,  4,  3,  2,  1,  0,  0,  0,  0
211
// mask  4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3,  1,  0,  0,  0,  0
212
static constexpr std::array<uint8_t, 16 + 64 + 16> eg_rate_shift =
213
{
214
	// Envelope Generator counter shifts (16 + 64 rates + 16 RKS)
215
	// 16 infinite time rates
216
	 0,  0,  0,  0,  0,  0,  0,  0,
217
	 0,  0,  0,  0,  0,  0,  0,  0,
218
219
	// rates 00-15
220
	12, 12, 12, 12,
221
	11, 11, 11, 11,
222
	10, 10, 10, 10,
223
	 9,  9,  9,  9,
224
	 8,  8,  8,  8,
225
	 7,  7,  7,  7,
226
	 6,  6,  6,  6,
227
	 5,  5,  5,  5,
228
	 4,  4,  4,  4,
229
	 3,  3,  3,  3,
230
	 2,  2,  2,  2,
231
	 1,  1,  1,  1,
232
	 0,  0,  0,  0,
233
	 0,  0,  0,  0,
234
	 0,  0,  0,  0,
235
	 0,  0,  0,  0,
236
237
	// 16 dummy rates (same as 15 3)
238
	 0,  0,  0,  0,  0,  0,  0,  0,
239
	 0,  0,  0,  0,  0,  0,  0,  0,
240
};
241
242
243
// multiple table
244
[[nodiscard]] static constexpr uint8_t ML(double x) { return uint8_t(2 * x); }
245
static constexpr std::array<uint8_t, 16> mul_tab = {
246
	// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15
247
	ML( 0.5), ML( 1.0), ML( 2.0), ML( 3.0),
248
	ML( 4.0), ML( 5.0), ML( 6.0), ML( 7.0),
249
	ML( 8.0), ML( 9.0), ML(10.0), ML(10.0),
250
	ML(12.0), ML(12.0), ML(15.0), ML(15.0)
251
};
252
253
// LFO Amplitude Modulation table (verified on real YM3812)
254
//  27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
255
//
256
// Length: 210 elements
257
//
258
// Each of the elements has to be repeated
259
// exactly 64 times (on 64 consecutive samples).
260
// The whole table takes: 64 * 210 = 13440 samples.
261
//
262
// When AM = 1 data is used directly
263
// When AM = 0 data is divided by 4 before being used (loosing precision is important)
264
265
static constexpr unsigned LFO_AM_TAB_ELEMENTS = 210;
266
static constexpr std::array<uint8_t, LFO_AM_TAB_ELEMENTS> lfo_am_table = {
267
	 0,  0,  0, /**/
268
	 0,  0,  0,  0,
269
	 1,  1,  1,  1,
270
	 2,  2,  2,  2,
271
	 3,  3,  3,  3,
272
	 4,  4,  4,  4,
273
	 5,  5,  5,  5,
274
	 6,  6,  6,  6,
275
	 7,  7,  7,  7,
276
	 8,  8,  8,  8,
277
	 9,  9,  9,  9,
278
	10, 10, 10, 10,
279
	11, 11, 11, 11,
280
	12, 12, 12, 12,
281
	13, 13, 13, 13,
282
	14, 14, 14, 14,
283
	15, 15, 15, 15,
284
	16, 16, 16, 16,
285
	17, 17, 17, 17,
286
	18, 18, 18, 18,
287
	19, 19, 19, 19,
288
	20, 20, 20, 20,
289
	21, 21, 21, 21,
290
	22, 22, 22, 22,
291
	23, 23, 23, 23,
292
	24, 24, 24, 24,
293
	25, 25, 25, 25,
294
	26, 26, 26, /**/
295
	25, 25, 25, 25,
296
	24, 24, 24, 24,
297
	23, 23, 23, 23,
298
	22, 22, 22, 22,
299
	21, 21, 21, 21,
300
	20, 20, 20, 20,
301
	19, 19, 19, 19,
302
	18, 18, 18, 18,
303
	17, 17, 17, 17,
304
	16, 16, 16, 16,
305
	15, 15, 15, 15,
306
	14, 14, 14, 14,
307
	13, 13, 13, 13,
308
	12, 12, 12, 12,
309
	11, 11, 11, 11,
310
	10, 10, 10, 10,
311
	 9,  9,  9,  9,
312
	 8,  8,  8,  8,
313
	 7,  7,  7,  7,
314
	 6,  6,  6,  6,
315
	 5,  5,  5,  5,
316
	 4,  4,  4,  4,
317
	 3,  3,  3,  3,
318
	 2,  2,  2,  2,
319
	 1,  1,  1,  1
320
};
321
322
// LFO Phase Modulation table (verified on real YM3812)
323
static constexpr std::array<int8_t, 8 * 8 * 2> lfo_pm_table = {
324
	// FNUM2/FNUM = 00 0xxxxxxx (0x0000)
325
	0, 0, 0, 0, 0, 0, 0, 0, // LFO PM depth = 0
326
	0, 0, 0, 0, 0, 0, 0, 0, // LFO PM depth = 1
327
328
	// FNUM2/FNUM = 00 1xxxxxxx (0x0080)
329
	0, 0, 0, 0, 0, 0, 0, 0, // LFO PM depth = 0
330
	1, 0, 0, 0,-1, 0, 0, 0, // LFO PM depth = 1
331
332
	// FNUM2/FNUM = 01 0xxxxxxx (0x0100)
333
	1, 0, 0, 0,-1, 0, 0, 0, // LFO PM depth = 0
334
	2, 1, 0,-1,-2,-1, 0, 1, // LFO PM depth = 1
335
336
	// FNUM2/FNUM = 01 1xxxxxxx (0x0180)
337
	1, 0, 0, 0,-1, 0, 0, 0, // LFO PM depth = 0
338
	3, 1, 0,-1,-3,-1, 0, 1, // LFO PM depth = 1
339
340
	// FNUM2/FNUM = 10 0xxxxxxx (0x0200)
341
	2, 1, 0,-1,-2,-1, 0, 1, // LFO PM depth = 0
342
	4, 2, 0,-2,-4,-2, 0, 2, // LFO PM depth = 1
343
344
	// FNUM2/FNUM = 10 1xxxxxxx (0x0280)
345
	2, 1, 0,-1,-2,-1, 0, 1, // LFO PM depth = 0
346
	5, 2, 0,-2,-5,-2, 0, 2, // LFO PM depth = 1
347
348
	// FNUM2/FNUM = 11 0xxxxxxx (0x0300)
349
	3, 1, 0,-1,-3,-1, 0, 1, // LFO PM depth = 0
350
	6, 3, 0,-3,-6,-3, 0, 3, // LFO PM depth = 1
351
352
	// FNUM2/FNUM = 11 1xxxxxxx (0x0380)
353
	3, 1, 0,-1,-3,-1, 0, 1, // LFO PM depth = 0
354
	7, 3, 0,-3,-7,-3, 0, 3  // LFO PM depth = 1
355
};
356
357
// TL_TAB_LEN is calculated as:
358
//  (12+1)=13 - sinus amplitude bits     (Y axis)
359
//  additional 1: to compensate for calculations of negative part of waveform
360
//  (if we don't add it then the greatest possible _negative_ value would be -2
361
//  and we really need -1 for waveform #7)
362
//  2  - sinus sign bit           (Y axis)
363
//  TL_RES_LEN - sinus resolution (X axis)
364
static constexpr int TL_TAB_LEN = 13 * 2 * TL_RES_LEN;
365
static constexpr int ENV_QUIET = TL_TAB_LEN >> 4;
366
367
static constexpr auto tlTab = [] {
368
	std::array<int, TL_TAB_LEN> result = {};
369
	// this _is_ different from OPL2 (verified on real YMF262)
370
	for (auto x : xrange(TL_RES_LEN)) {
371
		double m = (1 << 16) / cstd::exp2<6>((x + 1) * (ENV_STEP / 4.0) / 8.0);
372
373
		// we never reach (1<<16) here due to the (x+1)
374
		// result fits within 16 bits at maximum
375
		auto n = int(m);        // 16 bits here
376
		n >>= 4;                // 12 bits here
377
		n = (n >> 1) + (n & 1); // round to nearest
378
		// 11 bits here (rounded)
379
		n <<= 1; // 12 bits here (as in real chip)
380
		result[x * 2 + 0] = n;
381
		result[x * 2 + 1] = ~result[x * 2 + 0];
382
383
		for (int i : xrange(1, 13)) {
384
			result[x * 2 + 0 + i * 2 * TL_RES_LEN] =
385
			        result[x * 2 + 0] >> i;
386
			result[x * 2 + 1 + i * 2 * TL_RES_LEN] =
387
			        ~result[x * 2 + 0 + i * 2 * TL_RES_LEN];
388
		}
389
	}
390
	return result;
391
}();
392
393
394
// sin waveform table in 'decibel' scale
395
// there are eight waveforms on OPL3 chips
396
struct SinTab {
397
	std::array<std::array<unsigned, YMF262::SIN_LEN>, 8> tab;
398
};
399
400
static constexpr SinTab getSinTab()
401
{
402
	SinTab sin = {};
403
404
	constexpr auto SIN_BITS = YMF262::SIN_BITS;
405
	constexpr auto SIN_LEN  = YMF262::SIN_LEN;
406
	constexpr auto SIN_MASK = YMF262::SIN_MASK;
407
	for (auto i : xrange(SIN_LEN / 4)) {
408
		// non-standard sinus
409
		double m = cstd::sin<2>(((i * 2) + 1) * Math::pi / SIN_LEN); // checked against the real chip
410
		// we never reach zero here due to ((i * 2) + 1)
411
		double o = -8.0 * cstd::log2<11, 3>(m); // convert to 'decibels'
412
		o = o / (double(ENV_STEP) / 4);
413
414
		auto n = int(2 * o);
415
		n = (n >> 1) + (n & 1); // round to nearest
416
		sin.tab[0][i] = 2 * n;
417
	}
418
	for (auto i : xrange(SIN_LEN / 4)) {
419
		sin.tab[0][SIN_LEN / 2 - 1 - i] = sin.tab[0][i];
420
	}
421
	for (auto i : xrange(SIN_LEN / 2)) {
422
		sin.tab[0][SIN_LEN / 2 + i] = sin.tab[0][i] + 1;
423
	}
424
425
	for (auto i : xrange(SIN_LEN)) {
426
		// these 'pictures' represent _two_ cycles
427
		// waveform 1:  __      __
428
		//             /  \____/  \____
429
		// output only first half of the sinus waveform (positive one)
430
		sin.tab[1][i] = (i & (1 << (SIN_BITS - 1)))
431
		              ? TL_TAB_LEN
432
		              : sin.tab[0][i];
433
434
		// waveform 2:  __  __  __  __
435
		//             /  \/  \/  \/  \.
436
		// abs(sin)
437
		sin.tab[2][i] = sin.tab[0][i & (SIN_MASK >> 1)];
438
439
		// waveform 3:  _   _   _   _
440
		//             / |_/ |_/ |_/ |_
441
		// abs(output only first quarter of the sinus waveform)
442
		sin.tab[3][i] = (i & (1 << (SIN_BITS - 2)))
443
		              ? TL_TAB_LEN
444
		              : sin.tab[0][i & (SIN_MASK>>2)];
445
446
		// waveform 4: /\  ____/\  ____
447
		//               \/      \/
448
		// output whole sinus waveform in half the cycle(step=2)
449
		// and output 0 on the other half of cycle
450
		sin.tab[4][i] = (i & (1 << (SIN_BITS - 1)))
451
		              ? TL_TAB_LEN
452
		              : sin.tab[0][i * 2];
453
454
		// waveform 5: /\/\____/\/\____
455
		//
456
		// output abs(whole sinus) waveform in half the cycle(step=2)
457
		// and output 0 on the other half of cycle
458
		sin.tab[5][i] = (i & (1 << (SIN_BITS - 1)))
459
		              ? TL_TAB_LEN
460
		              : sin.tab[0][(i * 2) & (SIN_MASK >> 1)];
461
462
		// waveform 6: ____    ____
463
		//                 ____    ____
464
		// output maximum in half the cycle and output minimum
465
		// on the other half of cycle
466
		sin.tab[6][i] = (i & (1 << (SIN_BITS - 1)))
467
		              ? 1  // negative
468
		              : 0; // positive
469
470
		// waveform 7:|\____  |\____
471
		//                   \|      \|
472
		// output sawtooth waveform
473
		int x = (i & (1 << (SIN_BITS - 1)))
474
		      ? ((SIN_LEN - 1) - i) * 16 + 1  // negative: from 8177 to 1
475
		      : i * 16;                       // positive: from 0 to 8176
476
		x = std::min(x, TL_TAB_LEN); // clip to the allowed range
477
		sin.tab[7][i] = x;
478
	}
479
480
	return sin;
481
}
482
483
static constexpr SinTab sin = getSinTab();
484
485
486
// TODO clean this up
487
static int phase_modulation;  // phase modulation input (SLOT 2)
488
static int phase_modulation2; // phase modulation input (SLOT 3
489
                              // in 4 operator channels)
490
491
492
YMF262::Slot::Slot()
493
	: waveTable(sin.tab[0])
494
{
495
}
496
497
498
void YMF262::callback(uint8_t flag)
499
{
500
	setStatus(flag);
501
}
502
503
// status set and IRQ handling
504
void YMF262::setStatus(uint8_t flag)
505
{
506
	// set status flag masking out disabled IRQs
507
	status |= flag;
508
	if (status & statusMask) {
509
		status |= 0x80;
510
		irq.set();
511
	}
512
}
513
514
// status reset and IRQ handling
515
void YMF262::resetStatus(uint8_t flag)
516
{
517
	// reset status flag
518
	status &= ~flag;
519
	if (!(status & statusMask)) {
520
		status &= 0x7F;
521
		irq.reset();
522
	}
523
}
524
525
// IRQ mask set
526
void YMF262::changeStatusMask(uint8_t flag)
527
{
528
	statusMask = flag;
529
	status &= statusMask;
530
	if (status) {
531
		status |= 0x80;
532
		irq.set();
533
	} else {
534
		status &= 0x7F;
535
		irq.reset();
536
	}
537
}
538
539
void YMF262::Slot::advanceEnvelopeGenerator(unsigned egCnt)
540
{
541
	switch (state) {
542
	using enum EnvelopeState;
543
	case ATTACK:
544
		if (!(egCnt & eg_m_ar)) {
545
			volume += (~volume * eg_inc[eg_sel_ar + ((egCnt >> eg_sh_ar) & 7)]) >> 3;
546
			if (volume <= MIN_ATT_INDEX) {
547
				volume = MIN_ATT_INDEX;
548
				state = DECAY;
549
			}
550
		}
551
		break;
552
553
	case DECAY:
554
		if (!(egCnt & eg_m_dr)) {
555
			volume += eg_inc[eg_sel_dr + ((egCnt >> eg_sh_dr) & 7)];
556
			if (volume >= sl) {
557
				state = SUSTAIN;
558
			}
559
		}
560
		break;
561
562
	case SUSTAIN:
563
		// this is important behaviour:
564
		// one can change percussive/non-percussive
565
		// modes on the fly and the chip will remain
566
		// in sustain phase - verified on real YM3812
567
		if (eg_type) {
568
			// non-percussive mode
569
			// do nothing
570
		} else {
571
			// percussive mode
572
			// during sustain phase chip adds Release Rate (in percussive mode)
573
			if (!(egCnt & eg_m_rr)) {
574
				volume += eg_inc[eg_sel_rr + ((egCnt >> eg_sh_rr) & 7)];
575
				volume = std::min(volume, MAX_ATT_INDEX);
576
			} else {
577
				// do nothing in sustain phase
578
			}
579
		}
580
		break;
581
582
	case RELEASE:
583
		if (!(egCnt & eg_m_rr)) {
584
			volume += eg_inc[eg_sel_rr + ((egCnt >> eg_sh_rr) & 7)];
585
			if (volume >= MAX_ATT_INDEX) {
586
				volume = MAX_ATT_INDEX;
587
				state = OFF;
588
			}
589
		}
590
		break;
591
592
	default:
593
		break;
594
	}
595
}
596
597
void YMF262::Slot::advancePhaseGenerator(const Channel& ch, unsigned lfo_pm)
598
{
599
	if (vib) {
600
		// LFO phase modulation active
601
		unsigned block_fnum = ch.block_fnum;
602
		unsigned fnum_lfo   = (block_fnum & 0x0380) >> 7;
603
		auto lfo_fn_table_index_offset = narrow_cast<int>(lfo_pm_table[lfo_pm + 16 * fnum_lfo]);
604
		Cnt += fnumToIncrement(block_fnum + lfo_fn_table_index_offset) * mul;
605
	} else {
606
		// LFO phase modulation disabled for this operator
607
		Cnt += Incr;
608
	}
609
}
610
611
// advance to next sample
612
void YMF262::advance()
613
{
614
	// Vibrato: 8 output levels (triangle waveform);
615
	// 1 level takes 1024 samples
616
	lfo_pm_cnt.addQuantum();
617
	unsigned lfo_pm = (lfo_pm_cnt.toInt() & 7) | lfo_pm_depth_range;
618
619
	++eg_cnt;
620
	for (auto i : xrange(unsigned(channel.size()))) {
621
		auto& ch = channel[i];
622
		auto& ch2 = isExtended(i) ? getFirstOfPair(i) : ch;
623
		for (auto& op : ch.slot) {
624
			op.advanceEnvelopeGenerator(eg_cnt);
625
			op.advancePhaseGenerator(ch2, lfo_pm);
626
		}
627
	}
628
629
	// The Noise Generator of the YM3812 is 23-bit shift register.
630
	// Period is equal to 2^23-2 samples.
631
	// Register works at sampling frequency of the chip, so output
632
	// can change on every sample.
633
	//
634
	// Output of the register and input to the bit 22 is:
635
	// bit0 XOR bit14 XOR bit15 XOR bit22
636
	//
637
	// Simply use bit 22 as the noise output.
638
	//
639
	// unsigned j = ((noise_rng >>  0) ^ (noise_rng >> 14) ^
640
	//               (noise_rng >> 15) ^ (noise_rng >> 22)) & 1;
641
	// noise_rng = (j << 22) | (noise_rng >> 1);
642
	//
643
	// Instead of doing all the logic operations above, we
644
	// use a trick here (and use bit 0 as the noise output).
645
	// The difference is only that the noise bit changes one
646
	// step ahead. This doesn't matter since we don't know
647
	// what is real state of the noise_rng after the reset.
648
	if (noise_rng & 1) {
649
		noise_rng ^= 0x800302;
650
	}
651
	noise_rng >>= 1;
652
}
653
654
inline int YMF262::Slot::op_calc(unsigned phase, unsigned lfo_am) const
655
{
656
	unsigned env = (TLL + volume + (lfo_am & AMmask)) << 4;
657
	auto p = env + waveTable[phase & SIN_MASK];
658
	return (p < TL_TAB_LEN) ? tlTab[p] : 0;
659
}
660
661
// calculate output of a standard 2 operator channel
662
// (or 1st part of a 4-op channel)
663
void YMF262::Channel::chan_calc(unsigned lfo_am)
664
{
665
	// !! something is wrong with this, it caused bug
666
	// !!    [2823673] MoonSound 4 operator FM fail
667
	// !! optimization disabled for now
668
	// !! TODO investigate
669
	// !!   maybe this micro optimization isn't worth the trouble/risk
670
	// !!
671
	// - mod.connect can point to 'phase_modulation'  or 'ch0-output'
672
	// - car.connect can point to 'phase_modulation2' or 'ch0-output'
673
	//    (see register #C0-#C8 writes)
674
	// - phase_modulation2 is only used in 4op mode
675
	// - mod.connect and car.connect can point to the same thing, so we need
676
	//   an addition for car.connect (and initialize phase_modulation2 to
677
	//   zero). For mod.connect we can directly assign the value.
678
679
	// ?? is this paragraph correct ??
680
	// phase_modulation should be initialized to zero here. But there seems
681
	// to be an optimization bug in gcc-4.2: it *seems* that when we
682
	// initialize phase_modulation to zero in this function, the optimizer
683
	// assumes it still has value zero at the end of this function (where
684
	// it's used to calculate car.connect). As a workaround we initialize
685
	// phase_modulation each time before calling this function.
686
	phase_modulation = 0;
687
	phase_modulation2 = 0;
688
689
	auto& mod = slot[MOD];
690
	int out = mod.fb_shift
691
		? mod.op1_out[0] + mod.op1_out[1]
692
		: 0;
693
	mod.op1_out[0] = mod.op1_out[1];
694
	mod.op1_out[1] = mod.op_calc(mod.Cnt.toInt() + (out >> mod.fb_shift), lfo_am);
695
	*mod.connect += mod.op1_out[1];
696
697
	auto& car = slot[CAR];
698
	*car.connect += car.op_calc(car.Cnt.toInt() + phase_modulation, lfo_am);
699
}
700
701
// calculate output of a 2nd part of 4-op channel
702
void YMF262::Channel::chan_calc_ext(unsigned lfo_am)
703
{
704
	// !! see remark in chan_cal(), something is wrong with this
705
	// !! optimization disabled for now
706
	// !!
707
	// - mod.connect can point to 'phase_modulation' or 'ch3-output'
708
	// - car.connect always points to 'ch3-output'  (always 4op-mode)
709
	//    (see register #C0-#C8 writes)
710
	// - mod.connect and car.connect can point to the same thing, so we need
711
	//   an addition for car.connect. For mod.connect we can directly assign
712
	//   the value.
713
714
	phase_modulation = 0;
715
716
	auto& mod = slot[MOD];
717
	*mod.connect += mod.op_calc(mod.Cnt.toInt() + phase_modulation2, lfo_am);
718
719
	auto& car = slot[CAR];
720
	*car.connect += car.op_calc(car.Cnt.toInt() + phase_modulation, lfo_am);
721
}
722
723
// operators used in the rhythm sounds generation process:
724
//
725
// Envelope Generator:
726
//
727
// channel  operator  register number   Bass  High  Snare Tom  Top
728
// / slot   number    TL ARDR SLRR Wave Drum  Hat   Drum  Tom  Cymbal
729
//  6 / 0   12        50  70   90   f0  +
730
//  6 / 1   15        53  73   93   f3  +
731
//  7 / 0   13        51  71   91   f1        +
732
//  7 / 1   16        54  74   94   f4              +
733
//  8 / 0   14        52  72   92   f2                    +
734
//  8 / 1   17        55  75   95   f5                          +
735
//
736
// Phase Generator:
737
//
738
// channel  operator  register number   Bass  High  Snare Tom  Top
739
// / slot   number    MULTIPLE          Drum  Hat   Drum  Tom  Cymbal
740
//  6 / 0   12        30                +
741
//  6 / 1   15        33                +
742
//  7 / 0   13        31                      +     +           +
743
//  7 / 1   16        34                -----  n o t  u s e d -----
744
//  8 / 0   14        32                                  +
745
//  8 / 1   17        35                      +                 +
746
//
747
// channel  operator  register number   Bass  High  Snare Tom  Top
748
// number   number    BLK/FNUM2 FNUM    Drum  Hat   Drum  Tom  Cymbal
749
//    6     12,15     B6        A6      +
750
//
751
//    7     13,16     B7        A7            +     +           +
752
//
753
//    8     14,17     B8        A8            +           +     +
754
755
// The following formulas can be well optimized.
756
// I leave them in direct form for now (in case I've missed something).
757
758
inline unsigned YMF262::genPhaseHighHat()
759
{
760
	// high hat phase generation (verified on real YM3812):
761
	// phase = d0 or 234 (based on frequency only)
762
	// phase = 34 or 2d0 (based on noise)
763
764
	// base frequency derived from operator 1 in channel 7
765
	int op71phase = channel[7].slot[MOD].Cnt.toInt();
766
	bool bit7 = (op71phase & 0x80) != 0;
767
	bool bit3 = (op71phase & 0x08) != 0;
768
	bool bit2 = (op71phase & 0x04) != 0;
769
	bool res1 = (bit2 ^ bit7) | bit3;
770
	// when res1 = 0 phase = 0x000 | 0xd0;
771
	// when res1 = 1 phase = 0x200 | (0xd0>>2);
772
	unsigned phase = res1 ? (0x200 | (0xd0 >> 2)) : 0xd0;
773
774
	// enable gate based on frequency of operator 2 in channel 8
775
	int op82phase = channel[8].slot[CAR].Cnt.toInt();
776
	bool bit5e= (op82phase & 0x20) != 0;
777
	bool bit3e= (op82phase & 0x08) != 0;
778
	bool res2 = (bit3e ^ bit5e);
779
	// when res2 = 0 pass the phase from calculation above (res1);
780
	// when res2 = 1 phase = 0x200 | (0xd0>>2);
781
	if (res2) {
782
		phase = (0x200 | (0xd0 >> 2));
783
	}
784
785
	// when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0
786
	// when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change
787
	if (phase & 0x200) {
788
		if (noise_rng & 1) {
789
			phase = 0x200 | 0xd0;
790
		}
791
	} else {
792
	// when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2
793
	// when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change
794
		if (noise_rng & 1) {
795
			phase = 0xd0 >> 2;
796
		}
797
	}
798
	return phase;
799
}
800
801
inline unsigned YMF262::genPhaseSnare()
802
{
803
	// verified on real YM3812
804
	// base frequency derived from operator 1 in channel 7
805
	// noise bit XOR'es phase by 0x100
806
	return ((channel[7].slot[MOD].Cnt.toInt() & 0x100) + 0x100)
807
	     ^ ((noise_rng & 1) << 8);
808
}
809
810
inline unsigned YMF262::genPhaseCymbal()
811
{
812
	// verified on real YM3812
813
	// enable gate based on frequency of operator 2 in channel 8
814
	//  NOTE: YM2413_2 uses bit5 | bit3, this core uses bit5 ^ bit3
815
	//        most likely only one of the two is correct
816
	int op82phase = channel[8].slot[CAR].Cnt.toInt();
817
	if ((op82phase ^ (op82phase << 2)) & 0x20) { // bit5 ^ bit3
818
		return 0x300;
819
	} else {
820
		// base frequency derived from operator 1 in channel 7
821
		int op71phase = channel[7].slot[MOD].Cnt.toInt();
822
		bool bit7 = (op71phase & 0x80) != 0;
823
		bool bit3 = (op71phase & 0x08) != 0;
824
		bool bit2 = (op71phase & 0x04) != 0;
825
		return ((bit2 != bit7) || bit3) ? 0x300 : 0x100;
826
	}
827
}
828
829
// calculate rhythm
830
void YMF262::chan_calc_rhythm(unsigned lfo_am)
831
{
832
	// Bass Drum (verified on real YM3812):
833
	//  - depends on the channel 6 'connect' register:
834
	//      when connect = 0 it works the same as in normal (non-rhythm)
835
	//      mode (op1->op2->out)
836
	//      when connect = 1 _only_ operator 2 is present on output
837
	//      (op2->out), operator 1 is ignored
838
	//  - output sample always is multiplied by 2
839
	auto& mod6 = channel[6].slot[MOD];
840
	int out = mod6.fb_shift ? mod6.op1_out[0] + mod6.op1_out[1] : 0;
841
	mod6.op1_out[0] = mod6.op1_out[1];
842
	int pm = mod6.CON ? 0 : mod6.op1_out[0];
843
	mod6.op1_out[1] = mod6.op_calc(mod6.Cnt.toInt() + (out >> mod6.fb_shift), lfo_am);
844
	const auto& car6 = channel[6].slot[CAR];
845
	chanOut[6] += 2 * car6.op_calc(car6.Cnt.toInt() + pm, lfo_am);
846
847
	// Phase generation is based on:
848
	// HH  (13) channel 7->slot 1 combined with channel 8->slot 2
849
	//          (same combination as TOP CYMBAL but different output phases)
850
	// SD  (16) channel 7->slot 1
851
	// TOM (14) channel 8->slot 1
852
	// TOP (17) channel 7->slot 1 combined with channel 8->slot 2
853
	//          (same combination as HIGH HAT but different output phases)
854
	//
855
	// Envelope generation based on:
856
	// HH  channel 7->slot1
857
	// SD  channel 7->slot2
858
	// TOM channel 8->slot1
859
	// TOP channel 8->slot2
860
	const auto& mod7 = channel[7].slot[MOD];
861
	chanOut[7] += 2 * mod7.op_calc(genPhaseHighHat(), lfo_am);
862
	const auto& car7 = channel[7].slot[CAR];
863
	chanOut[7] += 2 * car7.op_calc(genPhaseSnare(),   lfo_am);
864
	const auto& mod8 = channel[8].slot[MOD];
865
	chanOut[8] += 2 * mod8.op_calc(mod8.Cnt.toInt(),  lfo_am);
866
	const auto& car8 = channel[8].slot[CAR];
867
	chanOut[8] += 2 * car8.op_calc(genPhaseCymbal(),  lfo_am);
868
}
869
870
void YMF262::Slot::FM_KEYON(uint8_t key_set)
871
{
872
	if (!key) {
873
		// restart Phase Generator
874
		Cnt = FreqIndex(0);
875
		// phase -> Attack
876
		state = EnvelopeState::ATTACK;
877
	}
878
	key |= key_set;
879
}
880
881
void YMF262::Slot::FM_KEYOFF(uint8_t key_clr)
882
{
883
	if (key) {
884
		key &= ~key_clr;
885
		if (!key) {
886
			// phase -> Release
887
			if (state != EnvelopeState::OFF) {
888
				state = EnvelopeState::RELEASE;
889
			}
890
		}
891
	}
892
}
893
894
void YMF262::Slot::update_ar_dr()
895
{
896
	if ((ar + ksr) < 16 + 60) {
897
		// verified on real YMF262 - all 15 x rates take "zero" time
898
		eg_sh_ar  = eg_rate_shift [ar + ksr];
899
		eg_sel_ar = eg_rate_select[ar + ksr];
900
	} else {
901
		eg_sh_ar  = 0;
902
		eg_sel_ar = 13 * RATE_STEPS;
903
	}
904
	eg_m_ar   = (1 << eg_sh_ar) - 1;
905
	eg_sh_dr  = eg_rate_shift [dr + ksr];
906
	eg_sel_dr = eg_rate_select[dr + ksr];
907
	eg_m_dr   = (1 << eg_sh_dr) - 1;
908
}
909
void YMF262::Slot::update_rr()
910
{
911
	eg_sh_rr  = eg_rate_shift [rr + ksr];
912
	eg_sel_rr = eg_rate_select[rr + ksr];
913
	eg_m_rr   = (1 << eg_sh_rr) - 1;
914
}
915
916
// update phase increment counter of operator (also update the EG rates if necessary)
917
void YMF262::Slot::calc_fc(const Channel& ch)
918
{
919
	// (frequency) phase increment counter
920
	Incr = ch.fc * mul;
921
922
	auto newKsr = narrow<uint8_t>(ch.kcode >> KSR);
923
	if (ksr == newKsr) return;
924
	ksr = newKsr;
925
926
	// calculate envelope generator rates
927
	update_ar_dr();
928
	update_rr();
929
}
930
931
static constexpr std::array<unsigned, 18> channelPairTab = {
932
	0,  1,  2,  0,  1,  2, unsigned(~0), unsigned(~0), unsigned(~0),
933
	9, 10, 11,  9, 10, 11, unsigned(~0), unsigned(~0), unsigned(~0),
934
};
935
inline bool YMF262::isExtended(unsigned ch) const
936
{
937
	assert(ch < 18);
938
	if (!OPL3_mode) return false;
939
	if (channelPairTab[ch] == unsigned(~0)) return false;
940
	return channel[channelPairTab[ch]].extended;
941
}
942
static constexpr unsigned getFirstOfPairNum(unsigned ch)
943
{
944
	assert((ch < 18) && (channelPairTab[ch] != unsigned(~0)));
945
	return channelPairTab[ch];
946
}
947
inline YMF262::Channel& YMF262::getFirstOfPair(unsigned ch)
948
{
949
	return channel[getFirstOfPairNum(ch) + 0];
950
}
951
inline YMF262::Channel& YMF262::getSecondOfPair(unsigned ch)
952
{
953
	return channel[getFirstOfPairNum(ch) + 3];
954
}
955
956
// set multi,am,vib,EG-TYP,KSR,mul
957
void YMF262::set_mul(unsigned sl, uint8_t v)
958
{
959
	unsigned chan_no = sl / 2;
960
	auto& ch = channel[chan_no];
961
	auto& slot = ch.slot[sl & 1];
962
963
	slot.mul     = mul_tab[v & 0x0f];
964
	slot.KSR     = (v & 0x10) ? 0 : 2;
965
	slot.eg_type = (v & 0x20) != 0;
966
	slot.vib     = (v & 0x40) != 0;
967
	slot.AMmask  = (v & 0x80) ? ~0 : 0;
968
969
	if (isExtended(chan_no)) {
970
		// 4op mode
971
		// update this slot using frequency data for 1st channel of a pair
972
		slot.calc_fc(getFirstOfPair(chan_no));
973
	} else {
974
		// normal (OPL2 mode or 2op mode)
975
		slot.calc_fc(ch);
976
	}
977
}
978
979
// set ksl & tl
980
void YMF262::set_ksl_tl(unsigned sl, uint8_t v)
981
{
982
	unsigned chan_no = sl / 2;
983
	auto& ch = channel[chan_no];
984
	auto& slot = ch.slot[sl & 1];
985
986
	// This is indeed {0.0, 3.0, 1.5, 6.0} dB/oct, verified on real YMF262.
987
	// Note the illogical order of 2nd and 3rd element.
988
	static constexpr std::array<uint8_t, 4> ksl_shift = {31, 1, 2, 0};
989
	slot.ksl = ksl_shift[v >> 6];
990
991
	slot.TL  = (v & 0x3F) << (ENV_BITS - 1 - 7); // 7 bits TL (bit 6 = always 0)
992
993
	if (isExtended(chan_no)) {
994
		// update this slot using frequency data for 1st channel of a pair
995
		const auto& ch0 = getFirstOfPair(chan_no);
996
		slot.TLL = slot.TL + (ch0.ksl_base >> slot.ksl);
997
	} else {
998
		// normal
999
		slot.TLL = slot.TL + (ch.ksl_base >> slot.ksl);
1000
	}
1001
}
1002
1003
// set attack rate & decay rate
1004
void YMF262::set_ar_dr(unsigned sl, uint8_t v)
1005
{
1006
	auto& ch = channel[sl / 2];
1007
	auto& slot = ch.slot[sl & 1];
1008
1009
	slot.ar = (v >> 4)   ? narrow<uint8_t>(16 + ((v >> 4)   << 2)) : 0;
1010
	slot.dr = (v & 0x0F) ? narrow<uint8_t>(16 + ((v & 0x0F) << 2)) : 0;
1011
	slot.update_ar_dr();
1012
}
1013
1014
// set sustain level & release rate
1015
void YMF262::set_sl_rr(unsigned sl, uint8_t v)
1016
{
1017
	auto& ch = channel[sl / 2];
1018
	auto& slot = ch.slot[sl & 1];
1019
1020
	slot.sl  = sl_tab[v >> 4];
1021
	slot.rr  = (v & 0x0F) ? uint8_t(16 + ((v & 0x0F) << 2)) : 0;
1022
	slot.update_rr();
1023
}
1024
1025
uint8_t YMF262::readReg(unsigned r) const
1026
{
1027
	// no need to call updateStream(time)
1028
	return peekReg(r);
1029
}
1030
1031
uint8_t YMF262::peekReg(unsigned r) const
1032
{
1033
	return reg[r];
1034
}
1035
1036
void YMF262::writeReg(unsigned r, uint8_t v, EmuTime time)
1037
{
1038
	if (!OPL3_mode && (r != 0x105)) {
1039
		// in OPL2 mode the only accessible in set #2 is register 0x05
1040
		r &= ~0x100;
1041
	}
1042
	writeReg512(r, v, time);
1043
}
1044
void YMF262::writeReg512(unsigned r, uint8_t v, EmuTime time)
1045
{
1046
	updateStream(time); // TODO optimize only for regs that directly influence sound
1047
	writeRegDirect(r, v, time);
1048
}
1049
void YMF262::writeRegDirect(unsigned r, uint8_t v, EmuTime time)
1050
{
1051
	reg[r] = v;
1052
1053
	unsigned ch_offset = (r & 0x100) ? 9 : 0;
1054
	switch (r & 0xE0) {
1055
	case 0x00: // 000-01F,100-11F: control
1056
		switch (r) {
1057
		case 0x000: // test register
1058
		case 0x001: // test register
1059
			break;
1060
1061
		case 0x002: // Timer 1
1062
			timer1->setValue(v);
1063
			break;
1064
1065
		case 0x003: // Timer 2
1066
			timer2->setValue(v);
1067
			break;
1068
1069
		case 0x004: // IRQ clear / mask and Timer enable
1070
			if (v & 0x80) {
1071
				// IRQ flags clear
1072
				resetStatus(0x60);
1073
			} else {
1074
				changeStatusMask((~v) & 0x60);
1075
				timer1->setStart((v & R04_ST1) != 0, time);
1076
				timer2->setStart((v & R04_ST2) != 0, time);
1077
			}
1078
			break;
1079
1080
		case 0x008: // x,NTS,x,x, x,x,x,x
1081
			nts = (v & 0x40) != 0;
1082
			break;
1083
1084
		case 0x100: // test register
1085
		case 0x101: // test register
1086
			break;
1087
1088
		case 0x104:
1089
			// 6 channels enable
1090
			channel[ 0].extended = (v & 0x01) != 0;
1091
			channel[ 1].extended = (v & 0x02) != 0;
1092
			channel[ 2].extended = (v & 0x04) != 0;
1093
			channel[ 9].extended = (v & 0x08) != 0;
1094
			channel[10].extended = (v & 0x10) != 0;
1095
			channel[11].extended = (v & 0x20) != 0;
1096
			return;
1097
1098
		case 0x105:
1099
			// OPL3 mode when bit0=1 otherwise it is OPL2 mode
1100
			OPL3_mode = v & 0x01;
1101
1102
			// Verified on real YMF278: When NEW2 bit is first set, a read
1103
			// from the status register (once) returns bit 1 set (0x02).
1104
			// This only happens once after reset, so clearing NEW2 and
1105
			// setting it again doesn't cause another change in the status
1106
			// register. Also, only bit 1 changes.
1107
			if ((v & 0x02) && !alreadySignaledNEW2 && isYMF278) {
1108
				status2 = 0x02;
1109
				alreadySignaledNEW2 = true;
1110
			}
1111
1112
			// following behaviour was tested on real YMF262,
1113
			// switching OPL3/OPL2 modes on the fly:
1114
			//  - does not change the waveform previously selected
1115
			//    (unless when ....)
1116
			//  - does not update CH.A, CH.B, CH.C and CH.D output
1117
			//    selectors (registers c0-c8) (unless when ....)
1118
			//  - does not disable channels 9-17 on OPL3->OPL2 switch
1119
			//  - does not switch 4 operator channels back to 2
1120
			//    operator channels
1121
			return;
1122
1123
		default:
1124
			break;
1125
		}
1126
		break;
1127
1128
	case 0x20: { // am ON, vib ON, ksr, eg_type, mul
1129
		int slot = slot_array[r & 0x1F];
1130
		if (slot < 0) return;
1131
		set_mul(slot + ch_offset * 2, v);
1132
		break;
1133
	}
1134
	case 0x40: {
1135
		int slot = slot_array[r & 0x1F];
1136
		if (slot < 0) return;
1137
		set_ksl_tl(slot + ch_offset * 2, v);
1138
		break;
1139
	}
1140
	case 0x60: {
1141
		int slot = slot_array[r & 0x1F];
1142
		if (slot < 0) return;
1143
		set_ar_dr(slot + ch_offset * 2, v);
1144
		break;
1145
	}
1146
	case 0x80: {
1147
		int slot = slot_array[r & 0x1F];
1148
		if (slot < 0) return;
1149
		set_sl_rr(slot + ch_offset * 2, v);
1150
		break;
1151
	}
1152
	case 0xA0: {
1153
		// note: not r != 0x1BD, only first register block
1154
		if (r == 0xBD) {
1155
			// am depth, vibrato depth, r,bd,sd,tom,tc,hh
1156
			lfo_am_depth = (v & 0x80) != 0;
1157
			lfo_pm_depth_range = (v & 0x40) ? 8 : 0;
1158
			rhythm = v & 0x3F;
1159
1160
			if (rhythm & 0x20) {
1161
				// BD key on/off
1162
				if (v & 0x10) {
1163
					channel[6].slot[MOD].FM_KEYON (2);
1164
					channel[6].slot[CAR].FM_KEYON (2);
1165
				} else {
1166
					channel[6].slot[MOD].FM_KEYOFF(2);
1167
					channel[6].slot[CAR].FM_KEYOFF(2);
1168
				}
1169
				// HH key on/off
1170
				if (v & 0x01) {
1171
					channel[7].slot[MOD].FM_KEYON (2);
1172
				} else {
1173
					channel[7].slot[MOD].FM_KEYOFF(2);
1174
				}
1175
				// SD key on/off
1176
				if (v & 0x08) {
1177
					channel[7].slot[CAR].FM_KEYON (2);
1178
				} else {
1179
					channel[7].slot[CAR].FM_KEYOFF(2);
1180
				}
1181
				// TOM key on/off
1182
				if (v & 0x04) {
1183
					channel[8].slot[MOD].FM_KEYON (2);
1184
				} else {
1185
					channel[8].slot[MOD].FM_KEYOFF(2);
1186
				}
1187
				// TOP-CY key on/off
1188
				if (v & 0x02) {
1189
					channel[8].slot[CAR].FM_KEYON (2);
1190
				} else {
1191
					channel[8].slot[CAR].FM_KEYOFF(2);
1192
				}
1193
			} else {
1194
				// BD key off
1195
				channel[6].slot[MOD].FM_KEYOFF(2);
1196
				channel[6].slot[CAR].FM_KEYOFF(2);
1197
				// HH key off
1198
				channel[7].slot[MOD].FM_KEYOFF(2);
1199
				// SD key off
1200
				channel[7].slot[CAR].FM_KEYOFF(2);
1201
				// TOM key off
1202
				channel[8].slot[MOD].FM_KEYOFF(2);
1203
				// TOP-CY off
1204
				channel[8].slot[CAR].FM_KEYOFF(2);
1205
			}
1206
			return;
1207
		}
1208
1209
		// keyon,block,fnum
1210
		if ((r & 0x0F) > 8) {
1211
			return;
1212
		}
1213
		unsigned chan_no = (r & 0x0F) + ch_offset;
1214
		auto& ch  = channel[chan_no];
1215
		int block_fnum;
1216
		if (!(r & 0x10)) {
1217
			// a0-a8
1218
			block_fnum  = (ch.block_fnum & 0x1F00) | v;
1219
		} else {
1220
			// b0-b8
1221
			block_fnum = ((v & 0x1F) << 8) | (ch.block_fnum & 0xFF);
1222
			if (isExtended(chan_no)) {
1223
				if (getFirstOfPairNum(chan_no) == chan_no) {
1224
					// keyon/off slots of both channels
1225
					// forming a 4-op channel
1226
					auto& ch0 = getFirstOfPair(chan_no);
1227
					auto& ch3 = getSecondOfPair(chan_no);
1228
					if (v & 0x20) {
1229
						ch0.slot[MOD].FM_KEYON(1);
1230
						ch0.slot[CAR].FM_KEYON(1);
1231
						ch3.slot[MOD].FM_KEYON(1);
1232
						ch3.slot[CAR].FM_KEYON(1);
1233
					} else {
1234
						ch0.slot[MOD].FM_KEYOFF(1);
1235
						ch0.slot[CAR].FM_KEYOFF(1);
1236
						ch3.slot[MOD].FM_KEYOFF(1);
1237
						ch3.slot[CAR].FM_KEYOFF(1);
1238
					}
1239
				} else {
1240
					// do nothing
1241
				}
1242
			} else {
1243
				// 2 operator function keyon/off
1244
				if (v & 0x20) {
1245
					ch.slot[MOD].FM_KEYON (1);
1246
					ch.slot[CAR].FM_KEYON (1);
1247
				} else {
1248
					ch.slot[MOD].FM_KEYOFF(1);
1249
					ch.slot[CAR].FM_KEYOFF(1);
1250
				}
1251
			}
1252
		}
1253
		// update
1254
		if (ch.block_fnum != block_fnum) {
1255
			ch.block_fnum = block_fnum;
1256
			ch.ksl_base = ksl_tab[block_fnum >> 6];
1257
			ch.fc       = fnumToIncrement(block_fnum);
1258
1259
			// BLK 2,1,0 bits -> bits 3,2,1 of kcode
1260
			ch.kcode = (ch.block_fnum & 0x1C00) >> 9;
1261
1262
			// the info below is actually opposite to what is stated
1263
			// in the Manuals (verified on real YMF262)
1264
			// if noteSel == 0 -> lsb of kcode is bit 10 (MSB) of fnum
1265
			// if noteSel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum
1266
			if (nts) {
1267
				ch.kcode |= (ch.block_fnum & 0x100) >> 8; // noteSel == 1
1268
			} else {
1269
				ch.kcode |= (ch.block_fnum & 0x200) >> 9; // noteSel == 0
1270
			}
1271
			if (isExtended(chan_no)) {
1272
				if (getFirstOfPairNum(chan_no) == chan_no) {
1273
					// update slots of both channels
1274
					// forming up 4-op channel
1275
					// refresh Total Level
1276
					auto& ch0 = getFirstOfPair(chan_no);
1277
					auto& ch3 = getSecondOfPair(chan_no);
1278
					ch0.slot[MOD].TLL = ch0.slot[MOD].TL + (ch.ksl_base >> ch0.slot[MOD].ksl);
1279
					ch0.slot[CAR].TLL = ch0.slot[CAR].TL + (ch.ksl_base >> ch0.slot[CAR].ksl);
1280
					ch3.slot[MOD].TLL = ch3.slot[MOD].TL + (ch.ksl_base >> ch3.slot[MOD].ksl);
1281
					ch3.slot[CAR].TLL = ch3.slot[CAR].TL + (ch.ksl_base >> ch3.slot[CAR].ksl);
1282
1283
					// refresh frequency counter
1284
					ch0.slot[MOD].calc_fc(ch);
1285
					ch0.slot[CAR].calc_fc(ch);
1286
					ch3.slot[MOD].calc_fc(ch);
1287
					ch3.slot[CAR].calc_fc(ch);
1288
				} else {
1289
					// nothing
1290
				}
1291
			} else {
1292
				// refresh Total Level in both SLOTs of this channel
1293
				ch.slot[MOD].TLL = ch.slot[MOD].TL + (ch.ksl_base >> ch.slot[MOD].ksl);
1294
				ch.slot[CAR].TLL = ch.slot[CAR].TL + (ch.ksl_base >> ch.slot[CAR].ksl);
1295
1296
				// refresh frequency counter in both SLOTs of this channel
1297
				ch.slot[MOD].calc_fc(ch);
1298
				ch.slot[CAR].calc_fc(ch);
1299
			}
1300
		}
1301
		break;
1302
	}
1303
	case 0xC0: {
1304
		// CH.D, CH.C, CH.B, CH.A, FB(3bits), C
1305
		if ((r & 0xF) > 8) {
1306
			return;
1307
		}
1308
		unsigned chan_no = (r & 0x0F) + ch_offset;
1309
		auto& ch = channel[chan_no];
1310
1311
		unsigned base = chan_no * 4;
1312
		if (OPL3_mode) {
1313
			// OPL3 mode
1314
			pan[base + 0] = (v & 0x10) ? ~0 : 0; // ch.A
1315
			pan[base + 1] = (v & 0x20) ? ~0 : 0; // ch.B
1316
			pan[base + 2] = (v & 0x40) ? ~0 : 0; // ch.C
1317
			pan[base + 3] = (v & 0x80) ? ~0 : 0; // ch.D
1318
		} else {
1319
			// OPL2 mode - always enabled
1320
			pan[base + 0] = ~0; // ch.A
1321
			pan[base + 1] = ~0; // ch.B
1322
			pan[base + 2] = ~0; // ch.C
1323
			pan[base + 3] = ~0; // ch.D
1324
		}
1325
1326
		ch.slot[MOD].setFeedbackShift((v >> 1) & 7);
1327
		ch.slot[MOD].CON = v & 1;
1328
1329
		if (isExtended(chan_no)) {
1330
			unsigned chan_no0 = getFirstOfPairNum(chan_no);
1331
			unsigned chan_no3 = chan_no0 + 3;
1332
			auto& ch0 = getFirstOfPair(chan_no);
1333
			auto& ch3 = getSecondOfPair(chan_no);
1334
			switch ((ch0.slot[MOD].CON ? 2:0) | (ch3.slot[MOD].CON ? 1:0)) {
1335
			case 0:
1336
				// 1 -> 2 -> 3 -> 4 -> out
1337
				ch0.slot[MOD].connect = &phase_modulation;
1338
				ch0.slot[CAR].connect = &phase_modulation2;
1339
				ch3.slot[MOD].connect = &phase_modulation;
1340
				ch3.slot[CAR].connect = &chanOut[chan_no3];
1341
				break;
1342
			case 1:
1343
				// 1 -> 2 -\.
1344
				// 3 -> 4 --+-> out
1345
				ch0.slot[MOD].connect = &phase_modulation;
1346
				ch0.slot[CAR].connect = &chanOut[chan_no0];
1347
				ch3.slot[MOD].connect = &phase_modulation;
1348
				ch3.slot[CAR].connect = &chanOut[chan_no3];
1349
				break;
1350
			case 2:
1351
				// 1 ----------\.
1352
				// 2 -> 3 -> 4 -+-> out
1353
				ch0.slot[MOD].connect = &chanOut[chan_no0];
1354
				ch0.slot[CAR].connect = &phase_modulation2;
1355
				ch3.slot[MOD].connect = &phase_modulation;
1356
				ch3.slot[CAR].connect = &chanOut[chan_no3];
1357
				break;
1358
			case 3:
1359
				// 1 -----\.
1360
				// 2 -> 3 -+-> out
1361
				// 4 -----/
1362
				ch0.slot[MOD].connect = &chanOut[chan_no0];
1363
				ch0.slot[CAR].connect = &phase_modulation2;
1364
				ch3.slot[MOD].connect = &chanOut[chan_no3];
1365
				ch3.slot[CAR].connect = &chanOut[chan_no3];
1366
				break;
1367
			}
1368
		} else {
1369
			// 2 operators mode
1370
			ch.slot[MOD].connect = ch.slot[MOD].CON
1371
			                     ? &chanOut[chan_no]
1372
			                     : &phase_modulation;
1373
			ch.slot[CAR].connect = &chanOut[chan_no];
1374
		}
1375
		break;
1376
	}
1377
	case 0xE0: {
1378
		// waveform select
1379
		int slot = slot_array[r & 0x1f];
1380
		if (slot < 0) return;
1381
		slot += narrow<int>(ch_offset * 2);
1382
		auto& ch = channel[slot / 2];
1383
1384
		// store 3-bit value written regardless of current OPL2 or OPL3
1385
		// mode... (verified on real YMF262)
1386
		v &= 7;
1387
		// ... but select only waveforms 0-3 in OPL2 mode
1388
		if (!OPL3_mode) {
1389
			v &= 3;
1390
		}
1391
		ch.slot[slot & 1].waveTable = sin.tab[v];
1392
		break;
1393
	}
1394
	}
1395
}
1396
1397
1398
void YMF262::reset(EmuTime time)
1399
{
1400
	eg_cnt = 0;
1401
1402
	noise_rng = 1; // noise shift register
1403
	nts = false; // note split
1404
	alreadySignaledNEW2 = false;
1405
	resetStatus(0x60);
1406
1407
	// reset with register write
1408
	writeRegDirect(0x01, 0, time); // test register
1409
	writeRegDirect(0x02, 0, time); // Timer1
1410
	writeRegDirect(0x03, 0, time); // Timer2
1411
	writeRegDirect(0x04, 0, time); // IRQ mask clear
1412
1413
	// FIX IT  registers 101, 104 and 105
1414
	// FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers)
1415
	for (int c = 0xFF; c >= 0x20; c--) {
1416
		writeRegDirect(c, 0, time);
1417
	}
1418
	// FIX IT (dont change CH.D, CH.C, CH.B and CH.A in C0-C8 registers)
1419
	for (int c = 0x1FF; c >= 0x120; c--) {
1420
		writeRegDirect(c, 0, time);
1421
	}
1422
1423
	// reset operator parameters
1424
	for (auto& ch : channel) {
1425
		for (auto& sl : ch.slot) {
1426
			sl.state  = EnvelopeState::OFF;
1427
			sl.volume = MAX_ATT_INDEX;
1428
		}
1429
	}
1430
1431
	setMixLevel(0x1b, time); // -9dB left and right
1432
}
1433
1434
static unsigned calcInputRate(bool isYMF278)
1435
{
1436
	return unsigned(lrintf(isYMF278 ?    33868800.0f / (19 * 36)
1437
	                                : 4 * 3579545.0f / ( 8 * 36)));
1438
}
1439
YMF262::YMF262(const std::string& name_,
1440
               const DeviceConfig& config, bool isYMF278_)
1441
	: ResampledSoundDevice(config.getMotherBoard(), name_, "MoonSound FM-part",
1442
	                       18, calcInputRate(isYMF278_), true)
1443
	, debuggable(config.getMotherBoard(), getName())
1444
	, timer1(isYMF278_
1445
	         ? EmuTimer::createOPL4_1(config.getScheduler(), *this)
1446
	         : EmuTimer::createOPL3_1(config.getScheduler(), *this))
1447
	, timer2(isYMF278_
1448
	         ? EmuTimer::createOPL4_2(config.getScheduler(), *this)
1449
	         : EmuTimer::createOPL3_2(config.getScheduler(), *this))
1450
	, irq(config.getMotherBoard(), getName() + ".IRQ")
1451
	, isYMF278(isYMF278_)
1452
{
1453
	// For debugging: print out tables to be able to compare before/after
1454
	// when the calculation changes.
1455
	if (false) {
1456
		for (const auto& e : tlTab) std::cout << e << '\n';
1457
		std::cout << '\n';
1458
		for (const auto& t : sin.tab) {
1459
			for (const auto& e : t) {
1460
				std::cout << e << '\n';
1461
			}
1462
		}
1463
	}
1464
1465
	registerSound(config);
1466
	reset(config.getMotherBoard().getCurrentTime()); // must come after registerSound() because of call to setSoftwareVolume() via setMixLevel()
1467
}
1468
1469
YMF262::~YMF262()
1470
{
1471
	unregisterSound();
1472
}
1473
1474
uint8_t YMF262::readStatus()
1475
{
1476
	// no need to call updateStream(time)
1477
	uint8_t result = status | status2;
1478
	status2 = 0;
1479
	return result;
1480
}
1481
1482
uint8_t YMF262::peekStatus() const
1483
{
1484
	return status | status2;
1485
}
1486
1487
bool YMF262::checkMuteHelper() const
1488
{
1489
	// TODO this doesn't always mute when possible
1490
	for (const auto& ch : channel) {
1491
		for (const auto& sl : ch.slot) {
1492
			if (!((sl.state == EnvelopeState::OFF) ||
1493
			      ((sl.state == EnvelopeState::RELEASE) &&
1494
			       ((narrow<int>(sl.TLL) + sl.volume) >= ENV_QUIET)))) {
1495
				return false;
1496
			}
1497
		}
1498
	}
1499
	return true;
1500
}
1501
1502
void YMF262::setMixLevel(uint8_t x, EmuTime time)
1503
{
1504
	// Only present on YMF278
1505
	// see mix_level[] and vol_factor() in YMF278.cc
1506
	static constexpr std::array<float, 8> level = {
1507
		(1.00f / 1), //   0dB
1508
		(0.75f / 1), //  -3dB (approx)
1509
		(1.00f / 2), //  -6dB
1510
		(0.75f / 2), //  -9dB (approx)
1511
		(1.00f / 4), // -12dB
1512
		(0.75f / 4), // -15dB (approx)
1513
		(1.00f / 8), // -18dB
1514
		 0.00f       // -inf dB
1515
	};
1516
	setSoftwareVolume(level[x & 7], level[(x >> 3) & 7], time);
1517
}
1518
1519
float YMF262::getAmplificationFactorImpl() const
1520
{
1521
	return 1.0f / 4096.0f;
1522
}
1523
1524
void YMF262::generateChannels(std::span<float*> bufs, unsigned num)
1525
{
1526
	// TODO implement per-channel mute (instead of all-or-nothing)
1527
	// TODO output rhythm on separate channels?
1528
	if (checkMuteHelper()) {
1529
		// TODO update internal state, even if muted
1530
		std::ranges::fill(bufs, nullptr);
1531
		return;
1532
	}
1533
1534
	bool rhythmEnabled = (rhythm & 0x20) != 0;
1535
1536
	for (auto j : xrange(num)) {
1537
		// Amplitude modulation: 27 output levels (triangle waveform);
1538
		// 1 level takes one of: 192, 256 or 448 samples
1539
		// One entry from LFO_AM_TABLE lasts for 64 samples
1540
		lfo_am_cnt.addQuantum();
1541
		if (lfo_am_cnt == LFOAMIndex(LFO_AM_TAB_ELEMENTS)) {
1542
			// lfo_am_table is 210 elements long
1543
			lfo_am_cnt = LFOAMIndex(0);
1544
		}
1545
		unsigned tmp = lfo_am_table[lfo_am_cnt.toInt()];
1546
		unsigned lfo_am = lfo_am_depth ? tmp : tmp / 4;
1547
1548
		// clear channel outputs
1549
		std::ranges::fill(chanOut, 0);
1550
1551
		// channels 0,3 1,4 2,5  9,12 10,13 11,14
1552
		// in either 2op or 4op mode
1553
		for (int k = 0; k <= 9; k += 9) {
1554
			for (auto i : xrange(3)) {
1555
				auto& ch0 = channel[k + i + 0];
1556
				auto& ch3 = channel[k + i + 3];
1557
				// extended 4op ch#0 part 1 or 2op ch#0
1558
				ch0.chan_calc(lfo_am);
1559
				if (ch0.extended) {
1560
					// extended 4op ch#0 part 2
1561
					ch3.chan_calc_ext(lfo_am);
1562
				} else {
1563
					// standard 2op ch#3
1564
					ch3.chan_calc(lfo_am);
1565
				}
1566
			}
1567
		}
1568
1569
		// channels 6,7,8 rhythm or 2op mode
1570
		if (!rhythmEnabled) {
1571
			channel[6].chan_calc(lfo_am);
1572
			channel[7].chan_calc(lfo_am);
1573
			channel[8].chan_calc(lfo_am);
1574
		} else {
1575
			// Rhythm part
1576
			chan_calc_rhythm(lfo_am);
1577
		}
1578
1579
		// channels 15,16,17 are fixed 2-operator channels only
1580
		channel[15].chan_calc(lfo_am);
1581
		channel[16].chan_calc(lfo_am);
1582
		channel[17].chan_calc(lfo_am);
1583
1584
		for (auto i : xrange(18)) {
1585
			bufs[i][2 * j + 0] += narrow_cast<float>(chanOut[i] & pan[4 * i + 0]);
1586
			bufs[i][2 * j + 1] += narrow_cast<float>(chanOut[i] & pan[4 * i + 1]);
1587
			// unused c        += narrow_cast<float>(chanOut[i] & pan[4 * i + 2]);
1588
			// unused d        += narrow_cast<float>(chanOut[i] & pan[4 * i + 3]);
1589
		}
1590
1591
		advance();
1592
	}
1593
}
1594
1595
1596
static constexpr auto envelopeStateInfo = std::to_array<enum_string<YMF262::EnvelopeState>>({
1597
	{ "ATTACK",  YMF262::EnvelopeState::ATTACK  },
1598
	{ "DECAY",   YMF262::EnvelopeState::DECAY   },
1599
	{ "SUSTAIN", YMF262::EnvelopeState::SUSTAIN },
1600
	{ "RELEASE", YMF262::EnvelopeState::RELEASE },
1601
	{ "OFF",     YMF262::EnvelopeState::OFF     },
1602
});
1603
SERIALIZE_ENUM(YMF262::EnvelopeState, envelopeStateInfo);
1604
1605
template<typename Archive>
1606
void YMF262::Slot::serialize(Archive& a, unsigned /*version*/)
1607
{
1608
	// waveTable
1609
	auto waveform = unsigned((waveTable.data() - sin.tab[0].data()) / SIN_LEN);
1610
	a.serialize("waveform", waveform);
1611
	if constexpr (Archive::IS_LOADER) {
1612
		waveTable = sin.tab[waveform];
1613
	}
1614
1615
	// done by rewriting registers:
1616
	//   connect, fb_shift, CON
1617
	// TODO handle more state like this
1618
1619
	a.serialize("Cnt",       Cnt,
1620
	            "Incr",      Incr,
1621
	            "op1_out",   op1_out,
1622
	            "TL",        TL,
1623
	            "TLL",       TLL,
1624
	            "volume",    volume,
1625
	            "sl",        sl,
1626
	            "state",     state,
1627
	            "eg_m_ar",   eg_m_ar,
1628
	            "eg_m_dr",   eg_m_dr,
1629
	            "eg_m_rr",   eg_m_rr,
1630
	            "eg_sh_ar",  eg_sh_ar,
1631
	            "eg_sel_ar", eg_sel_ar,
1632
	            "eg_sh_dr",  eg_sh_dr,
1633
	            "eg_sel_dr", eg_sel_dr,
1634
	            "eg_sh_rr",  eg_sh_rr,
1635
	            "eg_sel_rr", eg_sel_rr,
1636
	            "key",       key,
1637
	            "eg_type",   eg_type,
1638
	            "AMmask",    AMmask,
1639
	            "vib",       vib,
1640
	            "ar",        ar,
1641
	            "dr",        dr,
1642
	            "rr",        rr,
1643
	            "KSR",       KSR,
1644
	            "ksl",       ksl,
1645
	            "ksr",       ksr,
1646
	            "mul",       mul);
1647
}
1648
1649
template<typename Archive>
1650
void YMF262::Channel::serialize(Archive& a, unsigned /*version*/)
1651
{
1652
	a.serialize("slots",      slot,
1653
	            "block_fnum", block_fnum,
1654
	            "fc",         fc,
1655
	            "ksl_base",   ksl_base,
1656
	            "kcode",      kcode,
1657
	            "extended",   extended);
1658
}
1659
1660
// version 1: initial version
1661
// version 2: added alreadySignaledNEW2
1662
template<typename Archive>
1663
void YMF262::serialize(Archive& a, unsigned version)
1664
{
1665
	a.serialize("timer1",  *timer1,
1666
	            "timer2",  *timer2,
1667
	            "irq",     irq,
1668
	            "chanout", chanOut);
1669
	a.serialize_blob("registers", reg);
1670
	a.serialize("channels",           channel,
1671
	            "eg_cnt",             eg_cnt,
1672
	            "noise_rng",          noise_rng,
1673
	            "lfo_am_cnt",         lfo_am_cnt,
1674
	            "lfo_pm_cnt",         lfo_pm_cnt,
1675
	            "lfo_am_depth",       lfo_am_depth,
1676
	            "lfo_pm_depth_range", lfo_pm_depth_range,
1677
	            "rhythm",             rhythm,
1678
	            "nts",                nts,
1679
	            "OPL3_mode",          OPL3_mode,
1680
	            "status",             status,
1681
	            "status2",            status2,
1682
	            "statusMask",         statusMask);
1683
	if (a.versionAtLeast(version, 2)) {
1684
		a.serialize("alreadySignaledNEW2", alreadySignaledNEW2);
1685
	} else {
1686
		assert(Archive::IS_LOADER);
1687
		alreadySignaledNEW2 = true; // we can't know the actual value,
1688
									// but 'true' is the safest value
1689
	}
1690
1691
	// TODO restore more state by rewriting register values
1692
	//   this handles pan
1693
	EmuTime time = timer1->getCurrentTime();
1694
	for (auto i : xrange(0xC0, 0xC9)) {
1695
		writeRegDirect(i + 0x000, reg[i + 0x000], time);
1696
		writeRegDirect(i + 0x100, reg[i + 0x100], time);
1697
	}
1698
}
1699
1700
INSTANTIATE_SERIALIZE_METHODS(YMF262);
1701
1702
1703
// YMF262::Debuggable
1704
1705
YMF262::Debuggable::Debuggable(MSXMotherBoard& motherBoard_,
1706
                               const std::string& name_)
1707
	: SimpleDebuggable(motherBoard_, name_ + " regs",
1708
	                   "MoonSound FM-part registers", 0x200)
1709
{
1710
}
1711
1712
uint8_t YMF262::Debuggable::read(unsigned address)
1713
{
1714
	const auto& ymf262 = OUTER(YMF262, debuggable);
1715
	return ymf262.peekReg(address);
1716
}
1717
1718
void YMF262::Debuggable::write(unsigned address, uint8_t value, EmuTime time)
1719
{
1720
	auto& ymf262 = OUTER(YMF262, debuggable);
1721
	ymf262.writeReg512(address, value, time);
1722
}
1723
1724
} // namespace openmsx