Mercurial > hg > xmms-sid
comparison src/xs_sidplay1.cc @ 660:b0743dc9165d
Change tabs to 4 spaces, everywhere.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 02 Apr 2008 22:10:05 +0300 |
parents | acaba070cf49 |
children | c21908e9e7d7 |
comparison
equal
deleted
inserted
replaced
659:04ea91a61225 | 660:b0743dc9165d |
---|---|
32 #include <sidplay/myendian.h> | 32 #include <sidplay/myendian.h> |
33 #include <sidplay/fformat.h> | 33 #include <sidplay/fformat.h> |
34 | 34 |
35 | 35 |
36 /* Maximum audio frequency supported by libSIDPlay v1 */ | 36 /* Maximum audio frequency supported by libSIDPlay v1 */ |
37 #define SIDPLAY1_MAX_FREQ (48000) | 37 #define SIDPLAY1_MAX_FREQ (48000) |
38 | 38 |
39 | 39 |
40 typedef struct { | 40 typedef struct { |
41 emuEngine *currEng; | 41 emuEngine *currEng; |
42 emuConfig currConfig; | 42 emuConfig currConfig; |
43 sidTune *currTune; | 43 sidTune *currTune; |
44 guint8 *buf; | 44 guint8 *buf; |
45 size_t bufSize; | 45 size_t bufSize; |
46 } xs_sidplay1_t; | 46 } xs_sidplay1_t; |
47 | 47 |
48 | 48 |
49 /* We need to 'export' all this pseudo-C++ crap */ | 49 /* We need to 'export' all this pseudo-C++ crap */ |
50 extern "C" { | 50 extern "C" { |
51 | 51 |
52 | 52 |
53 /* Return song information | 53 /* Return song information |
54 */ | 54 */ |
55 #define TFUNCTION xs_sidplay1_getinfo | 55 #define TFUNCTION xs_sidplay1_getinfo |
56 #define TFUNCTION2 xs_sidplay1_updateinfo | 56 #define TFUNCTION2 xs_sidplay1_updateinfo |
57 #define TTUNEINFO sidTuneInfo | 57 #define TTUNEINFO sidTuneInfo |
58 #define TTUNE sidTune | 58 #define TTUNE sidTune |
59 #define TENGINE xs_sidplay1_t | 59 #define TENGINE xs_sidplay1_t |
60 #include "xs_sidplay.h" | 60 #include "xs_sidplay.h" |
61 | 61 |
62 | 62 |
63 /* Check if we can play the given file | 63 /* Check if we can play the given file |
64 */ | 64 */ |
65 gboolean xs_sidplay1_probe(xs_file_t *f) | 65 gboolean xs_sidplay1_probe(xs_file_t *f) |
66 { | 66 { |
67 gchar tmpBuf[4]; | 67 gchar tmpBuf[4]; |
68 | 68 |
69 if (!f) return FALSE; | 69 if (!f) return FALSE; |
70 | 70 |
71 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4) | 71 if (xs_fread(tmpBuf, sizeof(gchar), 4, f) != 4) |
72 return FALSE; | 72 return FALSE; |
73 | 73 |
74 if (!strncmp(tmpBuf, "PSID", 4)) | 74 if (!strncmp(tmpBuf, "PSID", 4)) |
75 return TRUE; | 75 return TRUE; |
76 else | 76 else |
77 return FALSE; | 77 return FALSE; |
78 } | 78 } |
79 | 79 |
80 | 80 |
81 /* Initialize SIDPlay1 | 81 /* Initialize SIDPlay1 |
82 */ | 82 */ |
83 gboolean xs_sidplay1_init(xs_status_t * myStatus) | 83 gboolean xs_sidplay1_init(xs_status_t * myStatus) |
84 { | 84 { |
85 gint tmpFreq; | 85 gint tmpFreq; |
86 xs_sidplay1_t *myEngine; | 86 xs_sidplay1_t *myEngine; |
87 assert(myStatus); | 87 assert(myStatus); |
88 | 88 |
89 /* Allocate internal structures */ | 89 /* Allocate internal structures */ |
90 myEngine = (xs_sidplay1_t *) g_malloc0(sizeof(xs_sidplay1_t)); | 90 myEngine = (xs_sidplay1_t *) g_malloc0(sizeof(xs_sidplay1_t)); |
91 if (!myEngine) return FALSE; | 91 if (!myEngine) return FALSE; |
92 | 92 |
93 /* Initialize engine */ | 93 /* Initialize engine */ |
94 myEngine->currEng = new emuEngine(); | 94 myEngine->currEng = new emuEngine(); |
95 if (!myEngine->currEng) { | 95 if (!myEngine->currEng) { |
96 xs_error("[SIDPlay1] Could not initialize emulation engine.\n"); | 96 xs_error("[SIDPlay1] Could not initialize emulation engine.\n"); |
97 g_free(myEngine); | 97 g_free(myEngine); |
98 return FALSE; | 98 return FALSE; |
99 } | 99 } |
100 | 100 |
101 /* Verify endianess */ | 101 /* Verify endianess */ |
102 if (!myEngine->currEng->verifyEndianess()) { | 102 if (!myEngine->currEng->verifyEndianess()) { |
103 xs_error("[SIDPlay1] Endianess verification failed.\n"); | 103 xs_error("[SIDPlay1] Endianess verification failed.\n"); |
104 delete myEngine->currEng; | 104 delete myEngine->currEng; |
105 g_free(myEngine); | 105 g_free(myEngine); |
106 return FALSE; | 106 return FALSE; |
107 } | 107 } |
108 | 108 |
109 myStatus->sidEngine = myEngine; | 109 myStatus->sidEngine = myEngine; |
110 | 110 |
111 /* Get current configuration */ | 111 /* Get current configuration */ |
112 myEngine->currEng->getConfig(myEngine->currConfig); | 112 myEngine->currEng->getConfig(myEngine->currConfig); |
113 | 113 |
114 /* Configure channel parameters */ | 114 /* Configure channel parameters */ |
115 switch (myStatus->audioChannels) { | 115 switch (myStatus->audioChannels) { |
116 | 116 |
117 case XS_CHN_AUTOPAN: | 117 case XS_CHN_AUTOPAN: |
118 myEngine->currConfig.channels = SIDEMU_STEREO; | 118 myEngine->currConfig.channels = SIDEMU_STEREO; |
119 myEngine->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; | 119 myEngine->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; |
120 myEngine->currConfig.volumeControl = SIDEMU_FULLPANNING; | 120 myEngine->currConfig.volumeControl = SIDEMU_FULLPANNING; |
121 break; | 121 break; |
122 | 122 |
123 case XS_CHN_STEREO: | 123 case XS_CHN_STEREO: |
124 myEngine->currConfig.channels = SIDEMU_STEREO; | 124 myEngine->currConfig.channels = SIDEMU_STEREO; |
125 myEngine->currConfig.autoPanning = SIDEMU_NONE; | 125 myEngine->currConfig.autoPanning = SIDEMU_NONE; |
126 myEngine->currConfig.volumeControl = SIDEMU_NONE; | 126 myEngine->currConfig.volumeControl = SIDEMU_NONE; |
127 break; | 127 break; |
128 | 128 |
129 case XS_CHN_MONO: | 129 case XS_CHN_MONO: |
130 default: | 130 default: |
131 myEngine->currConfig.channels = SIDEMU_MONO; | 131 myEngine->currConfig.channels = SIDEMU_MONO; |
132 myEngine->currConfig.autoPanning = SIDEMU_NONE; | 132 myEngine->currConfig.autoPanning = SIDEMU_NONE; |
133 myEngine->currConfig.volumeControl = SIDEMU_NONE; | 133 myEngine->currConfig.volumeControl = SIDEMU_NONE; |
134 myStatus->audioChannels = XS_CHN_MONO; | 134 myStatus->audioChannels = XS_CHN_MONO; |
135 break; | 135 break; |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 /* Memory mode settings */ | 139 /* Memory mode settings */ |
140 switch (xs_cfg.memoryMode) { | 140 switch (xs_cfg.memoryMode) { |
141 case XS_MPU_TRANSPARENT_ROM: | 141 case XS_MPU_TRANSPARENT_ROM: |
142 myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM; | 142 myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM; |
143 break; | 143 break; |
144 | 144 |
145 case XS_MPU_PLAYSID_ENVIRONMENT: | 145 case XS_MPU_PLAYSID_ENVIRONMENT: |
146 myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; | 146 myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; |
147 break; | 147 break; |
148 | 148 |
149 case XS_MPU_BANK_SWITCHING: | 149 case XS_MPU_BANK_SWITCHING: |
150 default: | 150 default: |
151 myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; | 151 myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; |
152 xs_cfg.memoryMode = XS_MPU_BANK_SWITCHING; | 152 xs_cfg.memoryMode = XS_MPU_BANK_SWITCHING; |
153 break; | 153 break; |
154 } | 154 } |
155 | 155 |
156 | 156 |
157 /* Audio parameters sanity checking and setup */ | 157 /* Audio parameters sanity checking and setup */ |
158 myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; | 158 myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; |
159 tmpFreq = myStatus->audioFrequency; | 159 tmpFreq = myStatus->audioFrequency; |
160 | 160 |
161 if (myStatus->oversampleEnable) { | 161 if (myStatus->oversampleEnable) { |
162 if ((tmpFreq * myStatus->oversampleFactor) > SIDPLAY1_MAX_FREQ) { | 162 if ((tmpFreq * myStatus->oversampleFactor) > SIDPLAY1_MAX_FREQ) { |
163 myStatus->oversampleEnable = FALSE; | 163 myStatus->oversampleEnable = FALSE; |
164 } else { | 164 } else { |
165 tmpFreq = (tmpFreq * myStatus->oversampleFactor); | 165 tmpFreq = (tmpFreq * myStatus->oversampleFactor); |
166 } | 166 } |
167 } else { | 167 } else { |
168 if (tmpFreq > SIDPLAY1_MAX_FREQ) | 168 if (tmpFreq > SIDPLAY1_MAX_FREQ) |
169 tmpFreq = SIDPLAY1_MAX_FREQ; | 169 tmpFreq = SIDPLAY1_MAX_FREQ; |
170 } | 170 } |
171 | 171 |
172 myEngine->currConfig.frequency = tmpFreq; | 172 myEngine->currConfig.frequency = tmpFreq; |
173 | 173 |
174 switch (myStatus->audioBitsPerSample) { | 174 switch (myStatus->audioBitsPerSample) { |
175 case XS_RES_8BIT: | 175 case XS_RES_8BIT: |
176 switch (myStatus->audioFormat) { | 176 switch (myStatus->audioFormat) { |
177 case FMT_S8: | 177 case FMT_S8: |
178 myStatus->audioFormat = FMT_S8; | 178 myStatus->audioFormat = FMT_S8; |
179 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; | 179 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; |
180 break; | 180 break; |
181 | 181 |
182 case FMT_U8: | 182 case FMT_U8: |
183 default: | 183 default: |
184 myStatus->audioFormat = FMT_U8; | 184 myStatus->audioFormat = FMT_U8; |
185 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; | 185 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; |
186 break; | 186 break; |
187 } | 187 } |
188 break; | 188 break; |
189 | 189 |
190 case XS_RES_16BIT: | 190 case XS_RES_16BIT: |
191 default: | 191 default: |
192 switch (myStatus->audioFormat) { | 192 switch (myStatus->audioFormat) { |
193 case FMT_U16_NE: | 193 case FMT_U16_NE: |
194 case FMT_U16_LE: | 194 case FMT_U16_LE: |
195 case FMT_U16_BE: | 195 case FMT_U16_BE: |
196 myStatus->audioFormat = FMT_U16_NE; | 196 myStatus->audioFormat = FMT_U16_NE; |
197 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; | 197 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; |
198 break; | 198 break; |
199 | 199 |
200 case FMT_S16_NE: | 200 case FMT_S16_NE: |
201 case FMT_S16_LE: | 201 case FMT_S16_LE: |
202 case FMT_S16_BE: | 202 case FMT_S16_BE: |
203 default: | 203 default: |
204 myStatus->audioFormat = FMT_S16_NE; | 204 myStatus->audioFormat = FMT_S16_NE; |
205 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; | 205 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; |
206 break; | 206 break; |
207 } | 207 } |
208 break; | 208 break; |
209 } | 209 } |
210 | 210 |
211 /* Clockspeed settings */ | 211 /* Clockspeed settings */ |
212 switch (xs_cfg.clockSpeed) { | 212 switch (xs_cfg.clockSpeed) { |
213 case XS_CLOCK_NTSC: | 213 case XS_CLOCK_NTSC: |
214 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; | 214 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; |
215 break; | 215 break; |
216 | 216 |
217 case XS_CLOCK_PAL: | 217 case XS_CLOCK_PAL: |
218 default: | 218 default: |
219 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; | 219 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; |
220 xs_cfg.clockSpeed = XS_CLOCK_PAL; | 220 xs_cfg.clockSpeed = XS_CLOCK_PAL; |
221 break; | 221 break; |
222 } | 222 } |
223 | 223 |
224 myEngine->currConfig.forceSongSpeed = xs_cfg.forceSpeed; | 224 myEngine->currConfig.forceSongSpeed = xs_cfg.forceSpeed; |
225 | 225 |
226 | 226 |
227 /* Configure rest of the emulation */ | 227 /* Configure rest of the emulation */ |
228 /* if (xs_cfg.forceModel) */ | 228 /* if (xs_cfg.forceModel) */ |
229 myEngine->currConfig.mos8580 = xs_cfg.mos8580; | 229 myEngine->currConfig.mos8580 = xs_cfg.mos8580; |
230 myEngine->currConfig.emulateFilter = xs_cfg.emulateFilters; | 230 myEngine->currConfig.emulateFilter = xs_cfg.emulateFilters; |
231 myEngine->currConfig.filterFs = xs_cfg.sid1FilterFs; | 231 myEngine->currConfig.filterFs = xs_cfg.sid1FilterFs; |
232 myEngine->currConfig.filterFm = xs_cfg.sid1FilterFm; | 232 myEngine->currConfig.filterFm = xs_cfg.sid1FilterFm; |
233 myEngine->currConfig.filterFt = xs_cfg.sid1FilterFt; | 233 myEngine->currConfig.filterFt = xs_cfg.sid1FilterFt; |
234 | 234 |
235 | 235 |
236 /* Now set the emulator configuration */ | 236 /* Now set the emulator configuration */ |
237 if (!myEngine->currEng->setConfig(myEngine->currConfig)) { | 237 if (!myEngine->currEng->setConfig(myEngine->currConfig)) { |
238 xs_error("[SIDPlay1] Emulator engine configuration failed!\n"); | 238 xs_error("[SIDPlay1] Emulator engine configuration failed!\n"); |
239 return FALSE; | 239 return FALSE; |
240 } | 240 } |
241 | 241 |
242 /* Create sidtune object */ | 242 /* Create sidtune object */ |
243 myEngine->currTune = new sidTune(0); | 243 myEngine->currTune = new sidTune(0); |
244 if (!myEngine->currTune) { | 244 if (!myEngine->currTune) { |
245 xs_error("[SIDPlay1] Could not initialize SIDTune object.\n"); | 245 xs_error("[SIDPlay1] Could not initialize SIDTune object.\n"); |
246 return FALSE; | 246 return FALSE; |
247 } | 247 } |
248 | 248 |
249 return TRUE; | 249 return TRUE; |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 /* Close SIDPlay1 engine | 253 /* Close SIDPlay1 engine |
254 */ | 254 */ |
255 void xs_sidplay1_close(xs_status_t * myStatus) | 255 void xs_sidplay1_close(xs_status_t * myStatus) |
256 { | 256 { |
257 xs_sidplay1_t *myEngine; | 257 xs_sidplay1_t *myEngine; |
258 assert(myStatus); | 258 assert(myStatus); |
259 | 259 |
260 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; | 260 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; |
261 | 261 |
262 /* Free internals */ | 262 /* Free internals */ |
263 if (myEngine->currEng) { | 263 if (myEngine->currEng) { |
264 delete myEngine->currEng; | 264 delete myEngine->currEng; |
265 myEngine->currEng = NULL; | 265 myEngine->currEng = NULL; |
266 } | 266 } |
267 | 267 |
268 if (myEngine->currTune) { | 268 if (myEngine->currTune) { |
269 delete myEngine->currTune; | 269 delete myEngine->currTune; |
270 myEngine->currTune = NULL; | 270 myEngine->currTune = NULL; |
271 } | 271 } |
272 | 272 |
273 xs_sidplay1_delete(myStatus); | 273 xs_sidplay1_delete(myStatus); |
274 | 274 |
275 g_free(myEngine); | 275 g_free(myEngine); |
276 myStatus->sidEngine = NULL; | 276 myStatus->sidEngine = NULL; |
277 } | 277 } |
278 | 278 |
279 | 279 |
280 /* Initialize current song and sub-tune | 280 /* Initialize current song and sub-tune |
281 */ | 281 */ |
282 gboolean xs_sidplay1_initsong(xs_status_t * myStatus) | 282 gboolean xs_sidplay1_initsong(xs_status_t * myStatus) |
283 { | 283 { |
284 xs_sidplay1_t *myEngine; | 284 xs_sidplay1_t *myEngine; |
285 assert(myStatus); | 285 assert(myStatus); |
286 | 286 |
287 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; | 287 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; |
288 if (!myEngine) return FALSE; | 288 if (!myEngine) return FALSE; |
289 | 289 |
290 if (!myEngine->currTune) { | 290 if (!myEngine->currTune) { |
291 xs_error("[SIDPlay1] SID-tune struct pointer was NULL. This should not happen, report to XMMS-SID author.\n"); | 291 xs_error("[SIDPlay1] SID-tune struct pointer was NULL. This should not happen, report to XMMS-SID author.\n"); |
292 return FALSE; | 292 return FALSE; |
293 } | 293 } |
294 | 294 |
295 if (!myEngine->currTune->getStatus()) { | 295 if (!myEngine->currTune->getStatus()) { |
296 xs_error("[SIDPlay1] SID-tune status check failed. This should not happen, report to XMMS-SID author.\n"); | 296 xs_error("[SIDPlay1] SID-tune status check failed. This should not happen, report to XMMS-SID author.\n"); |
297 return FALSE; | 297 return FALSE; |
298 } | 298 } |
299 | 299 |
300 myStatus->isInitialized = TRUE; | 300 myStatus->isInitialized = TRUE; |
301 | 301 |
302 return sidEmuInitializeSong(*myEngine->currEng, *myEngine->currTune, myStatus->currSong); | 302 return sidEmuInitializeSong(*myEngine->currEng, *myEngine->currTune, myStatus->currSong); |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 /* Emulate and render audio data to given buffer | 306 /* Emulate and render audio data to given buffer |
307 */ | 307 */ |
308 guint xs_sidplay1_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize) | 308 guint xs_sidplay1_fillbuffer(xs_status_t * myStatus, gchar * audioBuffer, guint audioBufSize) |
309 { | 309 { |
310 xs_sidplay1_t *myEngine; | 310 xs_sidplay1_t *myEngine; |
311 assert(myStatus); | 311 assert(myStatus); |
312 | 312 |
313 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; | 313 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; |
314 if (!myEngine) return 0; | 314 if (!myEngine) return 0; |
315 | 315 |
316 sidEmuFillBuffer(*myEngine->currEng, *myEngine->currTune, audioBuffer, audioBufSize); | 316 sidEmuFillBuffer(*myEngine->currEng, *myEngine->currTune, audioBuffer, audioBufSize); |
317 | 317 |
318 return audioBufSize; | 318 return audioBufSize; |
319 } | 319 } |
320 | 320 |
321 | 321 |
322 /* Load a given SID-tune file | 322 /* Load a given SID-tune file |
323 */ | 323 */ |
324 gboolean xs_sidplay1_load(xs_status_t * myStatus, gchar * filename) | 324 gboolean xs_sidplay1_load(xs_status_t * myStatus, gchar * filename) |
325 { | 325 { |
326 xs_sidplay1_t *myEngine; | 326 xs_sidplay1_t *myEngine; |
327 assert(myStatus); | 327 assert(myStatus); |
328 myStatus->isInitialized = FALSE; | 328 myStatus->isInitialized = FALSE; |
329 | 329 |
330 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; | 330 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; |
331 if (!myEngine) return FALSE; | 331 if (!myEngine) return FALSE; |
332 | 332 |
333 /* Try to get the tune */ | 333 /* Try to get the tune */ |
334 if (!filename) return FALSE; | 334 if (!filename) return FALSE; |
335 | 335 |
336 if (xs_fload_buffer(filename, &(myEngine->buf), &(myEngine->bufSize)) != 0) | 336 if (xs_fload_buffer(filename, &(myEngine->buf), &(myEngine->bufSize)) != 0) |
337 return FALSE; | 337 return FALSE; |
338 | 338 |
339 if (!myEngine->currTune->load(myEngine->buf, myEngine->bufSize)) | 339 if (!myEngine->currTune->load(myEngine->buf, myEngine->bufSize)) |
340 return FALSE; | 340 return FALSE; |
341 | 341 |
342 return TRUE; | 342 return TRUE; |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 /* Delete INTERNAL information | 346 /* Delete INTERNAL information |
347 */ | 347 */ |
348 void xs_sidplay1_delete(xs_status_t * myStatus) | 348 void xs_sidplay1_delete(xs_status_t * myStatus) |
349 { | 349 { |
350 xs_sidplay1_t *myEngine; | 350 xs_sidplay1_t *myEngine; |
351 assert(myStatus); | 351 assert(myStatus); |
352 | 352 |
353 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; | 353 myEngine = (xs_sidplay1_t *) myStatus->sidEngine; |
354 if (!myEngine) return; | 354 if (!myEngine) return; |
355 | 355 |
356 g_free(myEngine->buf); | 356 g_free(myEngine->buf); |
357 myEngine->buf = NULL; | 357 myEngine->buf = NULL; |
358 myEngine->bufSize = 0; | 358 myEngine->bufSize = 0; |
359 } | 359 } |
360 | 360 |
361 | 361 |
362 } /* extern "C" */ | 362 } /* extern "C" */ |
363 #endif /* HAVE_SIDPLAY1 */ | 363 #endif /* HAVE_SIDPLAY1 */ |