openMSX
AY8910.hh
Go to the documentation of this file.
1 #ifndef AY8910_HH
2 #define AY8910_HH
3 
5 #include "FloatSetting.hh"
6 #include "SimpleDebuggable.hh"
7 #include "TclCallback.hh"
8 #include "openmsx.hh"
9 
10 namespace openmsx {
11 
12 class AY8910Periphery;
13 class DeviceConfig;
14 
19 class AY8910 final : public ResampledSoundDevice
20 {
21 public:
22  AY8910(const std::string& name, AY8910Periphery& periphery,
23  const DeviceConfig& config, EmuTime::param time);
24  ~AY8910();
25 
26  byte readRegister(unsigned reg, EmuTime::param time);
27  byte peekRegister(unsigned reg, EmuTime::param time) const;
28  void writeRegister(unsigned reg, byte value, EmuTime::param time);
29  void reset(EmuTime::param time);
30 
31  template<typename Archive>
32  void serialize(Archive& ar, unsigned version);
33 
34 private:
35  class Generator {
36  public:
37  inline void reset(unsigned output);
38  inline void setPeriod(int value);
41  inline unsigned getOutput() const;
42 
43  inline unsigned getNextEventTime() const;
44  inline void advanceFast(unsigned duration);
45 
46  template<typename Archive>
47  void serialize(Archive& ar, unsigned version);
48 
49  protected:
50  Generator();
51 
57  int period;
62  int count;
66  unsigned output;
67  };
68 
69  class ToneGenerator : public Generator {
70  public:
71  ToneGenerator();
75  inline void advance(int duration);
76 
77  inline void doNextEvent(AY8910& ay8910);
78 
79  template<typename Archive>
80  void serialize(Archive& ar, unsigned version);
81 
82  private:
83  int getDetune(AY8910& ay8910);
84 
87  unsigned vibratoCount;
88  unsigned detuneCount;
89  };
90 
91  class NoiseGenerator : public Generator {
92  public:
93  NoiseGenerator();
94 
95  inline void reset();
99  inline void advance(int duration);
100 
101  inline void doNextEvent();
102 
103  template<typename Archive>
104  void serialize(Archive& ar, unsigned version);
105 
106  private:
107  int random;
108  };
109 
110  class Amplitude {
111  public:
112  explicit Amplitude(const DeviceConfig& config);
113  const unsigned* getEnvVolTable() const;
114  inline unsigned getVolume(unsigned chan) const;
115  inline void setChannelVolume(unsigned chan, unsigned value);
116  inline void setMasterVolume(int volume);
117  inline bool followsEnvelope(unsigned chan) const;
118 
119  private:
120  unsigned volTable[16];
121  unsigned envVolTable[32];
122  unsigned vol[3];
123  bool envChan[3];
124  const bool isAY8910;
125  };
126 
127  class Envelope {
128  public:
129  explicit inline Envelope(const unsigned* envVolTable);
130  inline void reset();
131  inline void setPeriod(int value);
132  inline void setShape(unsigned shape);
133  inline bool isChanging() const;
134  inline void advance(int duration);
135  inline unsigned getVolume() const;
136 
137  inline unsigned getNextEventTime() const;
138  inline void advanceFast(unsigned duration);
139  inline void doNextEvent();
140 
141  template<typename Archive>
142  void serialize(Archive& ar, unsigned version);
143 
144  private:
145  inline void doSteps(int steps);
146 
147  const unsigned* envVolTable;
148  int period;
149  int count;
150  int step;
151  int attack;
152  bool hold, alternate, holding;
153  };
154 
155  // SoundDevice
156  void generateChannels(int** bufs, unsigned num) override;
157 
158  // Observer<Setting>
159  void update(const Setting& setting) override;
160 
161  void wrtReg(unsigned reg, byte value, EmuTime::param time);
162 
163  AY8910Periphery& periphery;
164 
165  struct Debuggable final : SimpleDebuggable {
166  Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
167  byte read(unsigned address, EmuTime::param time) override;
168  void write(unsigned address, byte value, EmuTime::param time) override;
169  } debuggable;
170 
171  FloatSetting vibratoPercent;
172  FloatSetting vibratoFrequency;
173  FloatSetting detunePercent;
174  FloatSetting detuneFrequency;
175  TclCallback directionsCallback;
176  ToneGenerator tone[3];
177  NoiseGenerator noise;
178  Amplitude amplitude;
179  Envelope envelope;
180  byte regs[16];
181  const bool isAY8910;
182  bool doDetune;
183  bool detuneInitialized;
184 };
185 
186 } // namespace openmsx
187 
188 #endif // AY8910_HH
A Setting with a floating point value.
Definition: FloatSetting.hh:10
This class implements the AY-3-8910 sound chip.
Definition: AY8910.hh:19
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void serialize(Archive &ar, unsigned version)
Definition: AY8910.cc:968
void advance(octet_iterator &it, distance_type n, octet_iterator end)
byte peekRegister(unsigned reg, EmuTime::param time) const
Definition: AY8910.cc:549
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
byte readRegister(unsigned reg, EmuTime::param time)
Definition: AY8910.cc:524
AY8910(const std::string &name, AY8910Periphery &periphery, const DeviceConfig &config, EmuTime::param time)
Definition: AY8910.cc:463
void reset(EmuTime::param time)
Definition: AY8910.cc:511
Models the general purpose I/O ports of the AY8910.
void writeRegister(unsigned reg, byte value, EmuTime::param time)
Definition: AY8910.cc:568