~ubuntu-branches/ubuntu/raring/vice/raring

« back to all changes in this revision

Viewing changes to src/sid/resid-fp.cc

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-03-31 00:37:15 UTC
  • mfrom: (1.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: james.westby@ubuntu.com-20090331003715-mzclchtl0dp7fcl0
Tags: upstream-2.1.dfsg
ImportĀ upstreamĀ versionĀ 2.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * resid-fp.cc - reSID-fp interface code.
 
3
 *
 
4
 * Written by
 
5
 *  Teemu Rantanen <tvr@cs.hut.fi>
 
6
 *  Dag Lem <resid@nimrod.no>
 
7
 *  Andreas Boose <viceteam@t-online.de>
 
8
 *  Antti S. Lankila <alankila@bel.fi>
 
9
 *
 
10
 * This file is part of VICE, the Versatile Commodore Emulator.
 
11
 * See README for copyright notice.
 
12
 *
 
13
 *  This program is free software; you can redistribute it and/or modify
 
14
 *  it under the terms of the GNU General Public License as published by
 
15
 *  the Free Software Foundation; either version 2 of the License, or
 
16
 *  (at your option) any later version.
 
17
 *
 
18
 *  This program is distributed in the hope that it will be useful,
 
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
 *  GNU General Public License for more details.
 
22
 *
 
23
 *  You should have received a copy of the GNU General Public License
 
24
 *  along with this program; if not, write to the Free Software
 
25
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
26
 *  02111-1307  USA.
 
27
 *
 
28
 */
 
29
 
 
30
/* resid itself is always compiled with C64DTV support */
 
31
#include "resid-fp/sid.h"
 
32
 
 
33
extern "C" {
 
34
 
 
35
/* QNX has problems with const and inline definitions
 
36
   in its string.h file when using g++ */
 
37
 
 
38
#ifndef __QNX__
 
39
#include <string.h>
 
40
#endif
 
41
 
 
42
#include "sid/sid.h" /* sid_engine_t */
 
43
#include "lib.h"
 
44
#include "log.h"
 
45
#include "resid-fp.h"
 
46
#include "resources.h"
 
47
#include "sid-snapshot.h"
 
48
#include "types.h"
 
49
 
 
50
struct sound_s
 
51
{
 
52
    /* resid sid implementation */
 
53
    SIDFP *sid;
 
54
};
 
55
 
 
56
typedef struct sound_s sound_t;
 
57
 
 
58
static sound_t *residfp_open(BYTE *sidstate)
 
59
{
 
60
    sound_t *psid;
 
61
    int i;
 
62
 
 
63
    psid = new sound_t;
 
64
    psid->sid = new SIDFP;
 
65
 
 
66
    for (i = 0x00; i <= 0x18; i++) {
 
67
        psid->sid->write(i, sidstate[i]);
 
68
    }
 
69
 
 
70
    return psid;
 
71
}
 
72
 
 
73
static int residfp_init(sound_t *psid, int speed, int cycles_per_sec)
 
74
{
 
75
    sampling_method method;
 
76
    char model_text[100];
 
77
    char method_text[100];
 
78
    float  passband;
 
79
    int filters_enabled, model, sampling, passband_percentage;
 
80
 
 
81
    if (resources_get_int("SidFilters", &filters_enabled) < 0)
 
82
        return 0;
 
83
 
 
84
    if (resources_get_int("SidModel", &model) < 0)
 
85
        return 0;
 
86
 
 
87
    if (resources_get_int("SidResidSampling", &sampling) < 0)
 
88
        return 0;
 
89
 
 
90
    if (resources_get_int("SidResidPassband", &passband_percentage) < 0)
 
91
        return 0;
 
92
 
 
93
    passband = speed * passband_percentage / 200.f;
 
94
 
 
95
    /* Some mostly-common settings for all modes abstracted here. */
 
96
    psid->sid->input(0);
 
97
 
 
98
    /* Model numbers 8-15 are reserved for distorted 6581s. */
 
99
    if (model < 8 || model > 15) {
 
100
      psid->sid->set_chip_model(MOS8580FP);
 
101
      psid->sid->set_voice_nonlinearity(1.0f);
 
102
      psid->sid->get_filter().set_distortion_properties(0.f, 0.f, 0.f);
 
103
    } else {
 
104
      psid->sid->set_chip_model(MOS6581FP);
 
105
      psid->sid->set_voice_nonlinearity(0.96f);
 
106
      psid->sid->get_filter().set_distortion_properties(3.7e-3f, 2048.f, 1.2e-4f);
 
107
    }
 
108
 
 
109
    switch (model) {
 
110
 
 
111
    case SID_MODEL_8580R5_3691:
 
112
      psid->sid->get_filter().set_type4_properties(6.55f, 20.0f);
 
113
      strcpy(model_text, "8580R5 3691");
 
114
      break;
 
115
    case SID_MODEL_8580R5_3691D:
 
116
      psid->sid->get_filter().set_type4_properties(6.55f, 20.0f);
 
117
      psid->sid->input(-32768);
 
118
      strcpy(model_text, "8580R5 3691 + digi boost");
 
119
      break;
 
120
 
 
121
    case SID_MODEL_8580R5_1489:
 
122
      psid->sid->get_filter().set_type4_properties(5.7f, 20.0f);
 
123
      strcpy(model_text, "8580R5 1489");
 
124
      break;
 
125
    case SID_MODEL_8580R5_1489D:
 
126
      psid->sid->get_filter().set_type4_properties(5.7f, 20.0f);
 
127
      psid->sid->input(-32768);
 
128
      strcpy(model_text, "8580R5 1489 + digi boost");
 
129
      break;
 
130
 
 
131
    case SID_MODEL_6581R3_4885:
 
132
      psid->sid->get_filter().set_type3_properties(8.5e5f, 2.2e6f, 1.0075f, 1.8e4f);
 
133
      strcpy(model_text, "6581R3 4885");
 
134
      break;
 
135
    case SID_MODEL_6581R3_0486S:
 
136
      psid->sid->get_filter().set_type3_properties(1.1e6f, 1.5e7f, 1.006f, 1e4f);
 
137
      strcpy(model_text, "6581R3 0486S");
 
138
      break;
 
139
    case SID_MODEL_6581R3_3984:
 
140
      psid->sid->get_filter().set_type3_properties(1.8e6f, 3.5e7f, 1.0051f, 1.45e4f);
 
141
      strcpy(model_text, "6581R3 3984");
 
142
      break;
 
143
    default:
 
144
    case SID_MODEL_6581R4AR_3789:
 
145
      psid->sid->get_filter().set_type3_properties(1.40e6f, 1.47e8f, 1.0059f, 1.55e4f);
 
146
      strcpy(model_text, "6581R4AR 3789");
 
147
      break;
 
148
    case SID_MODEL_6581R3_4485:
 
149
      psid->sid->get_filter().set_type3_properties(1.3e6f, 5.2e8f, 1.0053f, 1.1e4f);
 
150
      strcpy(model_text, "6581R3 4485");
 
151
      break;
 
152
    case SID_MODEL_6581R4_1986S:
 
153
      psid->sid->get_filter().set_type3_properties(1.33e6f, 2.2e9f, 1.0056f, 7e3f);
 
154
      strcpy(model_text, "6581R4 1986S");
 
155
      break;
 
156
    }
 
157
 
 
158
    psid->sid->enable_filter(filters_enabled ? true : false);
 
159
    psid->sid->enable_external_filter(filters_enabled ? true : false);
 
160
 
 
161
    switch (sampling) {
 
162
      default:
 
163
      case 1:
 
164
        method = SAMPLE_INTERPOLATE;
 
165
        strcpy(method_text, "interpolation");
 
166
        break;
 
167
      case 2:
 
168
      case 3:
 
169
        method = SAMPLE_RESAMPLE_INTERPOLATE;
 
170
        sprintf(method_text, "%sresampling, cutoff %d Hz",
 
171
                             (psid->sid->sse_enabled() ? "SSE " : ""),
 
172
                             (int) (passband > 20000.f ? 20000.f : passband));
 
173
        break;
 
174
    }
 
175
 
 
176
    //! \todo FIXME: These casts have to go away
 
177
    if (!psid->sid->set_sampling_parameters((float)cycles_per_sec, method,
 
178
                                            (float)speed, passband)) {
 
179
        log_warning(LOG_DEFAULT,
 
180
                    "ReSID-FP: unable to set sampling mode; try increasing sampling frequency to 44.1-48 kHz and keep passband around 80-90 %%.");
 
181
        return 0;
 
182
    }
 
183
 
 
184
    log_message(LOG_DEFAULT,
 
185
                "ReSID-FP: %s, filter %s, sampling rate %d Hz with %s",
 
186
                model_text,
 
187
                filters_enabled ? "on" : "off",
 
188
                speed,
 
189
                method_text);
 
190
    return 1;
 
191
}
 
192
 
 
193
static void residfp_close(sound_t *psid)
 
194
{
 
195
    delete psid->sid;
 
196
    delete psid;
 
197
}
 
198
 
 
199
static BYTE residfp_read(sound_t *psid, WORD addr)
 
200
{
 
201
    return psid->sid->read(addr);
 
202
}
 
203
 
 
204
static void residfp_store(sound_t *psid, WORD addr, BYTE byte)
 
205
{
 
206
    psid->sid->write(addr, byte);
 
207
}
 
208
 
 
209
static void residfp_reset(sound_t *psid, CLOCK cpu_clk)
 
210
{
 
211
    psid->sid->reset();
 
212
}
 
213
 
 
214
static int residfp_calculate_samples(sound_t *psid, SWORD *pbuf, int nr,
 
215
                                   int interleave, int *delta_t)
 
216
{
 
217
    return psid->sid->clock(*delta_t, pbuf, nr, interleave);
 
218
}
 
219
 
 
220
static void residfp_prevent_clk_overflow(sound_t *psid, CLOCK sub)
 
221
{
 
222
}
 
223
 
 
224
static char *residfp_dump_state(sound_t *psid)
 
225
{
 
226
    return lib_stralloc("");
 
227
}
 
228
 
 
229
static void residfp_state_read(sound_t *psid, sid_snapshot_state_t *sid_state)
 
230
{
 
231
    SIDFP::State state;
 
232
    unsigned int i;
 
233
 
 
234
    state = psid->sid->read_state();
 
235
 
 
236
    for (i = 0; i < 0x20; i++) {
 
237
        sid_state->sid_register[i] = (BYTE)state.sid_register[i];
 
238
    }
 
239
 
 
240
    sid_state->bus_value = (BYTE)state.bus_value;
 
241
    sid_state->bus_value_ttl = (DWORD)state.bus_value_ttl;
 
242
    for (i = 0; i < 3; i++) {
 
243
        sid_state->accumulator[i] = (DWORD)state.accumulator[i];
 
244
        sid_state->shift_register[i] = (DWORD)state.shift_register[i];
 
245
        sid_state->rate_counter[i] = (WORD)state.rate_counter[i];
 
246
        sid_state->rate_counter_period[i] = (WORD)state.rate_counter_period[i];
 
247
        sid_state->exponential_counter[i] = (WORD)state.exponential_counter[i];
 
248
        sid_state->exponential_counter_period[i] = (WORD)state.exponential_counter_period[i];
 
249
        sid_state->envelope_counter[i] = (BYTE)state.envelope_counter[i];
 
250
        sid_state->envelope_state[i] = (BYTE)state.envelope_state[i];
 
251
        sid_state->hold_zero[i] = (BYTE)state.hold_zero[i];
 
252
    }
 
253
}
 
254
 
 
255
static void residfp_state_write(sound_t *psid, sid_snapshot_state_t *sid_state)
 
256
{
 
257
    SIDFP::State state;
 
258
    unsigned int i;
 
259
 
 
260
    for (i = 0; i < 0x20; i++) {
 
261
        state.sid_register[i] = (char)sid_state->sid_register[i];
 
262
    }
 
263
 
 
264
    state.bus_value = (reg8)sid_state->bus_value;
 
265
    state.bus_value_ttl = (cycle_count)sid_state->bus_value_ttl;
 
266
    for (i = 0; i < 3; i++) {
 
267
        state.accumulator[i] = (reg24)sid_state->accumulator[i];
 
268
        state.shift_register[i] = (reg24)sid_state->shift_register[i];
 
269
        state.rate_counter[i] = (reg16)sid_state->rate_counter[i];
 
270
        if (sid_state->rate_counter_period[i])
 
271
            state.rate_counter_period[i] = (reg16)sid_state->rate_counter_period[i];
 
272
        state.exponential_counter[i] = (reg16)sid_state->exponential_counter[i];
 
273
        if (sid_state->exponential_counter_period[i])
 
274
            state.exponential_counter_period[i] = (reg16)sid_state->exponential_counter_period[i];
 
275
        state.envelope_counter[i] = (reg8)sid_state->envelope_counter[i];
 
276
        state.envelope_state[i] = (EnvelopeGeneratorFP::State)sid_state->envelope_state[i];
 
277
        state.hold_zero[i] = (sid_state->hold_zero[i] != 0);
 
278
    }
 
279
 
 
280
    psid->sid->write_state((const SIDFP::State)state);
 
281
}
 
282
 
 
283
sid_engine_t residfp_hooks =
 
284
{
 
285
    residfp_open,
 
286
    residfp_init,
 
287
    residfp_close,
 
288
    residfp_read,
 
289
    residfp_store,
 
290
    residfp_reset,
 
291
    residfp_calculate_samples,
 
292
    residfp_prevent_clk_overflow,
 
293
    residfp_dump_state,
 
294
    residfp_state_read,
 
295
    residfp_state_write
 
296
};
 
297
 
 
298
} // extern "C"