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