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
15namespace openmsx {
16
17class DeviceConfig;
18
19class YMF262 final : private ResampledSoundDevice, private EmuTimerCallback
20{
21public:
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 [[nodiscard]] byte readReg(unsigned reg);
30 [[nodiscard]] byte peekReg(unsigned reg) const;
31 [[nodiscard]] byte readStatus();
32 [[nodiscard]] 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
39public:
42
45 };
46
47private:
48 class Channel;
49
50 class Slot {
51 public:
52 Slot();
53 [[nodiscard]] 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 [[nodiscard]] float getAmplificationFactorImpl() const override;
146 void generateChannels(float** 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 [[nodiscard]] inline int genPhaseHighHat();
158 [[nodiscard]] inline int genPhaseSnare();
159 [[nodiscard]] 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 [[nodiscard]] inline bool isExtended(unsigned ch) const;
169 [[nodiscard]] inline Channel& getFirstOfPair(unsigned ch);
170 [[nodiscard]] inline Channel& getSecondOfPair(unsigned ch);
171
172 struct Debuggable final : SimpleDebuggable {
173 Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
174 [[nodiscard]] 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 constexpr int R04_ST1 = 0x01; // Timer1 Start
180 static constexpr int R04_ST2 = 0x02; // Timer2 Start
181 static constexpr int R04_MASK_T2 = 0x20; // Mask Timer2 flag
182 static constexpr int R04_MASK_T1 = 0x40; // Mask Timer1 flag
183 static constexpr int R04_IRQ_RESET = 0x80; // IRQ RESET
184
185 // Bitmask for status register
186 static constexpr int STATUS_T2 = R04_MASK_T2;
187 static constexpr 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
Debuggable(const Debuggable &)=delete
virtual byte read(unsigned address, EmuTime::param time)
void write(unsigned address, byte value) override
void reset(EmuTime::param time)
Definition: YMF262.cc:1410
void setMixLevel(uint8_t x, EmuTime::param time)
Definition: YMF262.cc:1521
byte readStatus()
Definition: YMF262.cc:1493
void writeReg512(unsigned r, byte v, EmuTime::param time)
Definition: YMF262.cc:1059
YMF262(const std::string &name, const DeviceConfig &config, bool isYMF278)
Definition: YMF262.cc:1451
byte readReg(unsigned reg)
Definition: YMF262.cc:1040
void writeReg(unsigned r, byte v, EmuTime::param time)
Definition: YMF262.cc:1051
byte peekReg(unsigned reg) const
Definition: YMF262.cc:1046
FixedPoint< 16 > FreqIndex
16.16 fixed point type for frequency calculations
Definition: YMF262.hh:41
void serialize(Archive &ar, unsigned version)
Definition: YMF262.cc:1682
byte peekStatus() const
Definition: YMF262.cc:1501
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:127
IntHelper< IRQSource > IRQHelper
Definition: IRQHelper.hh:122