1 /*! \file resid/sid.h */
2
3 // ---------------------------------------------------------------------------
4 // This file is part of reSID, a MOS6581 SID emulator engine.
5 // Copyright (C) 2010 Dag Lem <resid@nimrod.no>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // ---------------------------------------------------------------------------
21
22 #ifndef RESID_SID_H
23 #define RESID_SID_H
24
25 #include "resid-config.h"
26 #include "voice.h"
27 #if NEW_8580_FILTER
28 #include "filter8580new.h"
29 #else
30 #include "filter.h"
31 #endif
32 #include "extfilt.h"
33 #include "pot.h"
34
35 namespace reSID
36 {
37
38 class SID
39 {
40 public:
41 SID();
42 ~SID();
43
44 void set_chip_model(chip_model model);
45 void set_voice_mask(reg4 mask);
46 void enable_filter(bool enable);
47 void adjust_filter_bias(double dac_bias);
48 void enable_external_filter(bool enable);
49 bool set_sampling_parameters(double clock_freq, sampling_method method,
50 double sample_freq, double pass_freq = -1,
51 double filter_scale = 0.97);
52 void adjust_sampling_frequency(double sample_freq);
53
54 void clock();
55 void clock(cycle_count delta_t);
56 int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1);
57 void reset();
58
59 // Read/write registers.
60 reg8 read(reg8 offset);
61 void write(reg8 offset, reg8 value);
62
63 // Read/write state.
64 class State
65 {
66 public:
67 State();
68
69 char sid_register[0x20];
70
71 reg8 bus_value;
72 cycle_count bus_value_ttl;
73 cycle_count write_pipeline;
74 reg8 write_address;
75 reg4 voice_mask;
76
77 reg24 accumulator[3];
78 reg24 shift_register[3];
79 cycle_count shift_register_reset[3];
80 cycle_count shift_pipeline[3];
81 reg16 pulse_output[3];
82 cycle_count floating_output_ttl[3];
83
84 reg16 rate_counter[3];
85 reg16 rate_counter_period[3];
86 reg16 exponential_counter[3];
87 reg16 exponential_counter_period[3];
88 reg8 envelope_counter[3];
89 EnvelopeGenerator::State envelope_state[3];
90 bool hold_zero[3];
91 cycle_count envelope_pipeline[3];
92 };
93
94 State read_state();
95 void write_state(const State& state);
96
97 // 16-bit input (EXT IN).
98 void input(short sample);
99
100 // 16-bit output (AUDIO OUT).
101 int output();
102
103 protected:
104 static double I0(double x);
105 int clock_fast(cycle_count& delta_t, short* buf, int n, int interleave);
106 int clock_interpolate(cycle_count& delta_t, short* buf, int n, int interleave);
107 int clock_resample(cycle_count& delta_t, short* buf, int n, int interleave);
108 int clock_resample_fastmem(cycle_count& delta_t, short* buf, int n, int interleave);
109 void write();
110
111 chip_model sid_model;
112 Voice voice[3];
113 Filter filter;
114 ExternalFilter extfilt;
115 Potentiometer potx;
116 Potentiometer poty;
117
118 reg8 bus_value;
119 cycle_count bus_value_ttl;
120
121 // The data bus TTL for the selected chip model
122 cycle_count databus_ttl;
123
124 // Pipeline for writes on the MOS8580.
125 cycle_count write_pipeline;
126 reg8 write_address;
127
128 double clock_frequency;
129
130 enum {
131 // Resampling constants.
132 // The error in interpolated lookup is bounded by 1.234/L^2,
133 // while the error in non-interpolated lookup is bounded by
134 // 0.7854/L + 0.4113/L^2, see
135 // http://www-ccrma.stanford.edu/~jos/resample/Choice_Table_Size.html
136 // For a resolution of 16 bits this yields L >= 285 and L >= 51473,
137 // respectively.
138 FIR_N = 125,
139 FIR_RES = 285,
140 FIR_RES_FASTMEM = 51473,
141 FIR_SHIFT = 15,
142
143 RINGSIZE = 1 << 14,
144 RINGMASK = RINGSIZE - 1,
145
146 // Fixed point constants (16.16 bits).
147 FIXP_SHIFT = 16,
148 FIXP_MASK = 0xffff
149 };
150
151 // Sampling variables.
152 sampling_method sampling;
153 cycle_count cycles_per_sample;
154 cycle_count sample_offset;
155 int sample_index;
156 short sample_prev, sample_now;
157 int fir_N;
158 int fir_RES;
159 double fir_beta;
160 double fir_f_cycles_per_sample;
161 double fir_filter_scale;
162
163 // Ring buffer with overflow for contiguous storage of RINGSIZE samples.
164 short* sample;
165
166 // FIR_RES filter tables (FIR_N*FIR_RES).
167 short* fir;
168 };
169
170
171 // ----------------------------------------------------------------------------
172 // Inline functions.
173 // The following functions are defined inline because they are called every
174 // time a sample is calculated.
175 // ----------------------------------------------------------------------------
176
177 #if RESID_INLINING || defined(RESID_SID_CC)
178
179 // ----------------------------------------------------------------------------
180 // Read 16-bit sample from audio output.
181 // ----------------------------------------------------------------------------
182 RESID_INLINE
output()183 int SID::output()
184 {
185 return extfilt.output();
186 }
187
188
189 // ----------------------------------------------------------------------------
190 // SID clocking - 1 cycle.
191 // ----------------------------------------------------------------------------
192 RESID_INLINE
clock()193 void SID::clock()
194 {
195 int i;
196
197 // Clock amplitude modulators.
198 for (i = 0; i < 3; i++) {
199 voice[i].envelope.clock();
200 }
201
202 // Clock oscillators.
203 for (i = 0; i < 3; i++) {
204 voice[i].wave.clock();
205 }
206
207 // Synchronize oscillators.
208 for (i = 0; i < 3; i++) {
209 voice[i].wave.synchronize();
210 }
211
212 // Calculate waveform output.
213 for (i = 0; i < 3; i++) {
214 voice[i].wave.set_waveform_output();
215 }
216
217 // Clock filter.
218 filter.clock(voice[0].output(), voice[1].output(), voice[2].output());
219
220 // Clock external filter.
221 extfilt.clock(filter.output());
222
223 // Pipelined writes on the MOS8580.
224 if (unlikely(write_pipeline)) {
225 write();
226 }
227
228 // Age bus value.
229 if (unlikely(!--bus_value_ttl)) {
230 bus_value = 0;
231 }
232 }
233
234 #endif // RESID_INLINING || defined(RESID_SID_CC)
235
236 } // namespace reSID
237
238 #endif // not RESID_SID_H
239