openMSX
YMF262.hh
Go to the documentation of this file.
1 #ifndef YMF262_HH
2 #define YMF262_HH
3 
5 #include "SimpleDebuggable.hh"
6 #include "EmuTimer.hh"
7 #include "EmuTime.hh"
8 #include "FixedPoint.hh"
9 #include "IRQHelper.hh"
10 #include "openmsx.hh"
11 #include "serialize_meta.hh"
12 #include <string>
13 #include <memory>
14 
15 namespace openmsx {
16 
17 class DeviceConfig;
18 
19 class YMF262 final : private ResampledSoundDevice, private EmuTimerCallback
20 {
21 public:
22  YMF262(const std::string& name, const DeviceConfig& config,
23  bool isYMF278);
24  ~YMF262();
25 
26  void reset(EmuTime::param time);
27  void writeReg (unsigned r, byte v, EmuTime::param time);
28  void writeReg512(unsigned r, byte v, EmuTime::param time);
29  byte readReg(unsigned reg);
30  byte peekReg(unsigned reg) const;
31  byte readStatus();
32  byte peekStatus() const;
33 
34  void setMixLevel(uint8_t x, EmuTime::param time);
35 
36  template<typename Archive>
37  void serialize(Archive& ar, unsigned version);
38 
39 public:
42 
45  };
46 
47 private:
48  class Channel;
49 
50  class Slot {
51  public:
52  Slot();
53  inline int op_calc(unsigned phase, unsigned lfo_am) const;
54  inline void FM_KEYON(byte key_set);
55  inline void FM_KEYOFF(byte key_clr);
56  inline void advanceEnvelopeGenerator(unsigned egCnt);
57  inline void advancePhaseGenerator(Channel& ch, unsigned lfo_pm);
58  void update_ar_dr();
59  void update_rr();
60  void calc_fc(const Channel& ch);
61 
64  void setFeedbackShift(byte value) {
65  fb_shift = value ? 9 - value : 0;
66  }
67 
68  template<typename Archive>
69  void serialize(Archive& ar, unsigned version);
70 
71  // Phase Generator
72  FreqIndex Cnt; // frequency counter
73  FreqIndex Incr; // frequency counter step
74  int* connect; // slot output pointer
75  int op1_out[2]; // slot1 output for feedback
76 
77  // Envelope Generator
78  unsigned TL; // total level: TL << 2
79  int TLL; // adjusted now TL
80  int volume; // envelope counter
81  int sl; // sustain level: sl_tab[SL]
82 
83  const unsigned* wavetable; // waveform select
84 
85  EnvelopeState state; // EG: phase type
86  unsigned eg_m_ar;// (attack state)
87  unsigned eg_m_dr;// (decay state)
88  unsigned eg_m_rr;// (release state)
89  byte eg_sh_ar; // (attack state)
90  byte eg_sel_ar; // (attack state)
91  byte eg_sh_dr; // (decay state)
92  byte eg_sel_dr; // (decay state)
93  byte eg_sh_rr; // (release state)
94  byte eg_sel_rr; // (release state)
95 
96  byte key; // 0 = KEY OFF, >0 = KEY ON
97 
98  byte fb_shift; // PG: feedback shift value
99  bool CON; // PG: connection (algorithm) type
100  bool eg_type; // EG: percussive/non-percussive mode
101 
102  // LFO
103  byte AMmask; // LFO Amplitude Modulation enable mask
104  bool vib; // LFO Phase Modulation enable flag (active high)
105 
106  byte ar; // attack rate: AR<<2
107  byte dr; // decay rate: DR<<2
108  byte rr; // release rate:RR<<2
109  byte KSR; // key scale rate
110  byte ksl; // keyscale level
111  byte ksr; // key scale rate: kcode>>KSR
112  byte mul; // multiple: mul_tab[ML]
113  };
114 
115  class Channel {
116  public:
117  Channel();
118  void chan_calc(unsigned lfo_am);
119  void chan_calc_ext(unsigned lfo_am);
120 
121  template<typename Archive>
122  void serialize(Archive& ar, unsigned version);
123 
124  Slot slot[2];
125 
126  int block_fnum; // block+fnum
127  FreqIndex fc; // Freq. Increment base
128  int ksl_base; // KeyScaleLevel Base step
129  byte kcode; // key code (for key scaling)
130 
131  // there are 12 2-operator channels which can be combined in pairs
132  // to form six 4-operator channel, they are:
133  // 0 and 3,
134  // 1 and 4,
135  // 2 and 5,
136  // 9 and 12,
137  // 10 and 13,
138  // 11 and 14
139  bool extended; // set if this channel forms up a 4op channel with
140  // another channel (only used by first of pair of
141  // channels, ie 0,1,2 and 9,10,11)
142  };
143 
144  // SoundDevice
145  int getAmplificationFactorImpl() const override;
146  void generateChannels(int** bufs, unsigned num) override;
147 
148  void callback(byte flag) override;
149 
150  void writeRegDirect(unsigned r, byte v, EmuTime::param time);
151  void init_tables();
152  void setStatus(byte flag);
153  void resetStatus(byte flag);
154  void changeStatusMask(byte flag);
155  void advance();
156 
157  inline int genPhaseHighHat();
158  inline int genPhaseSnare();
159  inline int genPhaseCymbal();
160 
161  void chan_calc_rhythm(unsigned lfo_am);
162  void set_mul(unsigned sl, byte v);
163  void set_ksl_tl(unsigned sl, byte v);
164  void set_ar_dr(unsigned sl, byte v);
165  void set_sl_rr(unsigned sl, byte v);
166  bool checkMuteHelper();
167 
168  inline bool isExtended(unsigned ch) const;
169  inline Channel& getFirstOfPair(unsigned ch);
170  inline Channel& getSecondOfPair(unsigned ch);
171 
172  struct Debuggable final : SimpleDebuggable {
173  Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
174  byte read(unsigned address) override;
175  void write(unsigned address, byte value, EmuTime::param time) override;
176  } debuggable;
177 
178  // Bitmask for register 0x04
179  static const int R04_ST1 = 0x01; // Timer1 Start
180  static const int R04_ST2 = 0x02; // Timer2 Start
181  static const int R04_MASK_T2 = 0x20; // Mask Timer2 flag
182  static const int R04_MASK_T1 = 0x40; // Mask Timer1 flag
183  static const int R04_IRQ_RESET = 0x80; // IRQ RESET
184 
185  // Bitmask for status register
186  static const int STATUS_T2 = R04_MASK_T2;
187  static const int STATUS_T1 = R04_MASK_T1;
188  // Timers (see EmuTimer class for details about timing)
189  const std::unique_ptr<EmuTimer> timer1; // 80.8us OPL4 ( 80.5us OPL3)
190  const std::unique_ptr<EmuTimer> timer2; // 323.1us OPL4 (321.8us OPL3)
191 
192  IRQHelper irq;
193 
194  int chanout[18]; // 18 channels
195 
196  byte reg[512];
197  Channel channel[18]; // OPL3 chips have 18 channels
198 
199  unsigned pan[18 * 4]; // channels output masks 4 per channel
200  // 0xffffffff = enable
201  unsigned eg_cnt; // global envelope generator counter
202  unsigned noise_rng; // 23 bit noise shift register
203 
204  // LFO
205  using LFOAMIndex = FixedPoint< 6>;
206  using LFOPMIndex = FixedPoint<10>;
207  LFOAMIndex lfo_am_cnt;
208  LFOPMIndex lfo_pm_cnt;
209  bool lfo_am_depth;
210  byte lfo_pm_depth_range;
211 
212  byte rhythm; // Rhythm mode
213  bool nts; // NTS (note select)
214  bool OPL3_mode; // OPL3 extension enable flag
215 
216  byte status; // status flag
217  byte status2;
218  byte statusMask; // status mask
219 
220  bool alreadySignaledNEW2;
221  const bool isYMF278; // true iff this is actually a YMF278
222  // ATM only used for NEW2 bit
223 };
225 
226 } // namespace openmsx
227 
228 #endif
void serialize(Archive &ar, unsigned version)
Definition: YMF262.cc:1698
void setMixLevel(uint8_t x, EmuTime::param time)
Definition: YMF262.cc:1534
byte peekStatus() const
Definition: YMF262.cc:1514
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void writeReg(unsigned r, byte v, EmuTime::param time)
Definition: YMF262.cc:1062
byte peekReg(unsigned reg) const
Definition: YMF262.cc:1057
void writeReg512(unsigned r, byte v, EmuTime::param time)
Definition: YMF262.cc:1070
byte readStatus()
Definition: YMF262.cc:1506
YMF262(const std::string &name, const DeviceConfig &config, bool isYMF278)
Definition: YMF262.cc:1459
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void reset(EmuTime::param time)
Definition: YMF262.cc:1423
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
byte readReg(unsigned reg)
Definition: YMF262.cc:1051