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