openMSX
YM2151.hh
Go to the documentation of this file.
1 /*
2  **
3  ** File: ym2151.h - header file for software implementation of YM2151
4  ** FM Operator Type-M(OPM)
5  **
6  ** (c) 1997-2002 Jarek Burczynski (s0246@poczta.onet.pl, bujar@mame.net)
7  ** Some of the optimizing ideas by Tatsuyuki Satoh
8  **
9  ** Version 2.150 final beta May, 11th 2002
10  **
11  **
12  ** I would like to thank following people for making this project possible:
13  **
14  ** Beauty Planets - for making a lot of real YM2151 samples and providing
15  ** additional informations about the chip. Also for the time spent making
16  ** the samples and the speed of replying to my endless requests.
17  **
18  ** Shigeharu Isoda - for general help, for taking time to scan his YM2151
19  ** Japanese Manual first of all, and answering MANY of my questions.
20  **
21  ** Nao - for giving me some info about YM2151 and pointing me to Shigeharu.
22  ** Also for creating fmemu (which I still use to test the emulator).
23  **
24  ** Aaron Giles and Chris Hardy - they made some samples of one of my favourite
25  ** arcade games so I could compare it to my emulator.
26  **
27  ** Bryan McPhail and Tim (powerjaw) - for making some samples.
28  **
29  ** Ishmair - for the datasheet and motivation.
30  */
31 
32 #ifndef YM2151_HH
33 #define YM2151_HH
34 
35 #include "ResampledSoundDevice.hh"
36 #include "EmuTimer.hh"
37 #include "EmuTime.hh"
38 #include "IRQHelper.hh"
39 #include "openmsx.hh"
40 #include <string>
41 #include <memory>
42 
43 namespace openmsx {
44 
45 class DeviceConfig;
46 
47 class YM2151 final : public ResampledSoundDevice, private EmuTimerCallback
48 {
49 public:
50  YM2151(const std::string& name, const std::string& desc,
51  const DeviceConfig& config, EmuTime::param time);
52  ~YM2151();
53 
54  void reset(EmuTime::param time);
55  void writeReg(byte r, byte v, EmuTime::param time);
56  byte readStatus() const;
57 
58  template<typename Archive>
59  void serialize(Archive& ar, unsigned version);
60 
61 private:
62  // a single operator
63  struct YM2151Operator {
64  template<typename Archive>
65  void serialize(Archive& ar, unsigned version);
66 
67  int* connect; // operator output 'direction'
68  int* mem_connect; // where to put the delayed sample (MEM)
69 
70  unsigned phase; // accumulated operator phase
71  unsigned freq; // operator frequency count
72  int dt1; // current DT1 (detune 1 phase inc/decrement) value
73  unsigned mul; // frequency count multiply
74  unsigned dt1_i; // DT1 index * 32
75  unsigned dt2; // current DT2 (detune 2) value
76 
77  int mem_value; // delayed sample (MEM) value
78 
79  // channel specific data
80  // note: each operator number 0 contains channel specific data
81  unsigned fb_shift; // feedback shift value for operators 0 in each channel
82  int fb_out_curr; // operator feedback value (used only by operators 0)
83  int fb_out_prev; // previous feedback value (used only by operators 0)
84  unsigned kc; // channel KC (copied to all operators)
85  unsigned kc_i; // just for speedup
86  unsigned pms; // channel PMS
87  unsigned ams; // channel AMS
88 
89  unsigned AMmask; // LFO Amplitude Modulation enable mask
90  unsigned state; // Envelope state: 4-attack(AR)
91  // 3-decay(D1R)
92  // 2-sustain(D2R)
93  // 1-release(RR)
94  // 0-off
95  unsigned tl; // Total attenuation Level
96  int volume; // current envelope attenuation level
97  unsigned d1l; // envelope switches to sustain state after
98 
99  unsigned key; // 0=last key was KEY OFF, 1=last key was KEY ON
100 
101  unsigned ks; // key scale
102  unsigned ar; // attack rate
103  unsigned d1r; // decay rate
104  unsigned d2r; // sustain rate
105  unsigned rr; // release rate
106 
107  byte eg_sh_ar; // (attack state)
108  byte eg_sel_ar; // (attack state)
109  byte eg_sh_d1r; // (decay state)
110  byte eg_sel_d1r; // (decay state)
111  // reaching this level
112  byte eg_sh_d2r; // (sustain state)
113  byte eg_sel_d2r; // (sustain state)
114  byte eg_sh_rr; // (release state)
115  byte eg_sel_rr; // (release state)
116  };
117 
118  void setConnect(YM2151Operator* om1, int cha, int v);
119 
120  // SoundDevice
121  void generateChannels(int** bufs, unsigned num) override;
122 
123  void callback(byte flag) override;
124  void setStatus(byte flags);
125  void resetStatus(byte flags);
126 
127  void initTables();
128  void initChipTables();
129 
130  // operator methods
131  void envelopeKONKOFF(YM2151Operator* op, int v);
132  static void refreshEG(YM2151Operator* op);
133  int opCalc(YM2151Operator* op, unsigned env, int pm);
134  int opCalc1(YM2151Operator* op, unsigned env, int pm);
135  inline unsigned volumeCalc(YM2151Operator* op, unsigned AM);
136  inline void keyOn(YM2151Operator* op, unsigned keySet);
137  inline void keyOff(YM2151Operator* op, unsigned keyClear);
138 
139  // general chip mehods
140  void chanCalc(unsigned chan);
141  void chan7Calc();
142 
143  void advanceEG();
144  void advance();
145 
146  bool checkMuteHelper();
147 
148  IRQHelper irq;
149 
150  // Timers (see EmuTimer class for details about timing)
151  const std::unique_ptr<EmuTimer> timer1;
152  const std::unique_ptr<EmuTimer> timer2;
153 
154  YM2151Operator oper[32]; // the 32 operators
155 
156  unsigned pan[16]; // channels output masks (0xffffffff = enable)
157 
158  unsigned eg_cnt; // global envelope generator counter
159  unsigned eg_timer; // global envelope generator counter
160  // works at frequency = chipclock/64/3
161  unsigned lfo_phase; // accumulated LFO phase (0 to 255)
162  unsigned lfo_timer; // LFO timer
163  unsigned lfo_overflow; // LFO generates new output when lfo_timer
164  // reaches this value
165  unsigned lfo_counter; // LFO phase increment counter
166  unsigned lfo_counter_add;// step of lfo_counter
167  unsigned lfa; // LFO current AM output
168  int lfp; // LFO current PM output
169 
170  unsigned noise; // noise enable/period register
171  // bit 7 - noise enable, bits 4-0 - noise period
172  unsigned noise_rng; // 17 bit noise shift register
173  int noise_p; // current noise 'phase'
174  unsigned noise_f; // current noise period
175 
176  unsigned csm_req; // CSM KEY ON / KEY OFF sequence request
177 
178  unsigned irq_enable; // IRQ enable for timer B (bit 3) and timer A
179  // (bit 2); bit 7 - CSM mode (keyon to all
180  // slots, everytime timer A overflows)
181  unsigned status; // chip status (BUSY, IRQ Flags)
182 
183  // Frequency-deltas to get the closest frequency possible.
184  // There are 11 octaves because of DT2 (max 950 cents over base frequency)
185  // and LFO phase modulation (max 800 cents below AND over base frequency)
186  // Summary: octave explanation
187  // 0 note code - LFO PM
188  // 1 note code
189  // 2 note code
190  // 3 note code
191  // 4 note code
192  // 5 note code
193  // 6 note code
194  // 7 note code
195  // 8 note code
196  // 9 note code + DT2 + LFO PM
197  // 10 note code + DT2 + LFO PM
198  unsigned freq[11 * 768]; // 11 octaves, 768 'cents' per octave // No Save
199 
200  // Frequency deltas for DT1. These deltas alter operator frequency
201  // after it has been taken from frequency-deltas table.
202  int dt1_freq[8 * 32]; // 8 DT1 levels, 32 KC values // No Save
203  unsigned noise_tab[32]; // 17bit Noise Generator periods // No Save
204 
205  int chanout[8];
206  int m2, c1, c2; // Phase Modulation input for operators 2,3,4
207  int mem; // one sample delay memory
208 
209  word timer_A_val;
210 
211  byte lfo_wsel; // LFO waveform (0-saw, 1-square, 2-triangle,
212  // 3-random noise)
213  byte amd; // LFO Amplitude Modulation Depth
214  signed char pmd; // LFO Phase Modulation Depth
215 
216  byte test; // TEST register
217  byte ct; // output control pins (bit1-CT2, bit0-CT1)
218 
219  byte regs[256]; // only used for serialization ATM
220 };
221 
222 } // namespace openmsx
223 
224 #endif
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void writeReg(byte r, byte v, EmuTime::param time)
Definition: YM2151.cc:619
byte readStatus() const
Definition: YM2151.cc:1502
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void serialize(Archive &ar, unsigned version)
Definition: YM2151.cc:1565
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
YM2151(const std::string &name, const std::string &desc, const DeviceConfig &config, EmuTime::param time)
Definition: YM2151.cc:835
void reset(EmuTime::param time)
Definition: YM2151.cc:869