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