Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
401 lines (334 loc) · 11.6 KB

SDL_mintaudio_mcsn.c

File metadata and controls

401 lines (334 loc) · 11.6 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Jan 4, 2004
Jan 4, 2004
3
Copyright (C) 1997-2004 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
25
26
27
28
29
30
/*
MiNT audio driver
using XBIOS functions (MacSound compatible driver)
Patrice Mandin
*/
Aug 10, 2005
Aug 10, 2005
31
#include <support.h>
32
33
34
35
36
37
38
/* Mint includes */
#include <mint/osbind.h>
#include <mint/falcon.h>
#include <mint/cookie.h>
#include "SDL_audio.h"
Feb 16, 2006
Feb 16, 2006
39
40
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
41
Feb 21, 2006
Feb 21, 2006
42
#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
43
44
45
46
47
48
49
50
51
52
#include "SDL_mintaudio.h"
#include "SDL_mintaudio_mcsn.h"
/*--- Defines ---*/
#define MINT_AUDIO_DRIVER_NAME "mint_mcsn"
/* Debug print info */
#define DEBUG_NAME "audio:mcsn: "
Oct 29, 2004
Oct 29, 2004
53
#if 0
54
55
56
57
58
59
60
61
62
63
#define DEBUG_PRINT(what) \
{ \
printf what; \
}
#else
#define DEBUG_PRINT(what)
#endif
/*--- Static variables ---*/
Oct 7, 2006
Oct 7, 2006
64
65
66
static unsigned long cookie_snd = 0;
static unsigned long cookie_mch = 0;
static cookie_mcsn_t *cookie_mcsn = NULL;
67
Jul 10, 2006
Jul 10, 2006
68
static int
Oct 7, 2006
Oct 7, 2006
69
MINTMCSN_Available(void)
70
{
Oct 7, 2006
Oct 7, 2006
71
unsigned long dummy = 0;
72
Jul 10, 2006
Jul 10, 2006
73
SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
Jul 20, 2005
Jul 20, 2005
74
Jul 10, 2006
Jul 10, 2006
75
76
77
78
/* We can't use XBIOS in interrupt with Magic, don't know about thread */
if (Getcookie(C_MagX, &dummy) == C_FOUND) {
return (0);
}
Jul 29, 2005
Jul 29, 2005
79
Jul 10, 2006
Jul 10, 2006
80
81
82
83
/* Cookie _MCH present ? if not, assume ST machine */
if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
cookie_mch = MCH_ST;
}
84
Jul 10, 2006
Jul 10, 2006
85
86
87
88
/* Cookie _SND present ? if not, assume ST machine */
if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
cookie_snd = SND_PSG;
}
89
Jul 10, 2006
Jul 10, 2006
90
91
92
93
94
/* Check if we have 16 bits audio */
if ((cookie_snd & SND_16BIT) == 0) {
DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
return (0);
}
95
Jul 10, 2006
Jul 10, 2006
96
97
98
99
100
/* Cookie MCSN present ? */
if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n"));
return (0);
}
101
Jul 10, 2006
Jul 10, 2006
102
103
104
105
106
/* Check if interrupt at end of replay */
if (cookie_mcsn->pint == 0) {
DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n"));
return (0);
}
107
Jul 10, 2006
Jul 10, 2006
108
109
110
111
112
/* Check if audio is lockable */
if (Locksnd() != 1) {
DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
return (0);
}
113
Jul 10, 2006
Jul 10, 2006
114
Unlocksnd();
115
Jul 10, 2006
Jul 10, 2006
116
117
DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
return (1);
118
119
}
Jul 10, 2006
Jul 10, 2006
120
static void
Oct 7, 2006
Oct 7, 2006
121
MINTMCSN_LockDevice(_THIS)
122
{
Jul 10, 2006
Jul 10, 2006
123
124
/* Stop replay */
Buffoper(0);
125
126
}
Jul 10, 2006
Jul 10, 2006
127
static void
Oct 7, 2006
Oct 7, 2006
128
MINTMCSN_UnlockDevice(_THIS)
129
{
Jul 10, 2006
Jul 10, 2006
130
131
/* Restart replay */
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
132
133
}
Jul 10, 2006
Jul 10, 2006
134
static void
Oct 7, 2006
Oct 7, 2006
135
MINTMCSN_CloseDevice(_THIS)
136
{
Oct 7, 2006
Oct 7, 2006
137
138
139
140
141
142
143
144
145
if (this->hidden != NULL) {
/* Stop replay */
SDL_MintAudio_WaitThread();
Buffoper(0);
if (!SDL_MintAudio_mint_present) {
/* Uninstall interrupt */
Jdisint(MFP_DMASOUND);
}
146
Oct 7, 2006
Oct 7, 2006
147
148
/* Wait if currently playing sound */
while (SDL_MintAudio_mutex != 0) {}
149
Oct 7, 2006
Oct 7, 2006
150
151
152
153
154
/* Clear buffers */
if (SDL_MintAudio_audiobuf[0]) {
Mfree(SDL_MintAudio_audiobuf[0]);
SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
}
155
Oct 7, 2006
Oct 7, 2006
156
157
/* Unlock sound system */
Unlocksnd();
158
Oct 7, 2006
Oct 7, 2006
159
160
161
SDL_free(this->hidden);
this->hidden = NULL;
}
162
163
}
Jul 10, 2006
Jul 10, 2006
164
static int
Oct 7, 2006
Oct 7, 2006
165
MINTMCSN_CheckAudio(_THIS)
166
{
Jul 10, 2006
Jul 10, 2006
167
168
169
int i;
unsigned long masterclock, masterprediv;
Sep 24, 2006
Sep 24, 2006
170
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
Oct 7, 2006
Oct 7, 2006
171
172
173
174
175
176
177
178
179
SDL_AUDIO_BITSIZE(this->spec.format)));
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
if (this->spec.channels > 2) {
this->spec.channels = 2; /* no more than stereo! */
Sep 1, 2006
Sep 1, 2006
180
181
}
Jul 10, 2006
Jul 10, 2006
182
183
184
185
/* Check formats available */
MINTAUDIO_freqcount = 0;
switch (cookie_mcsn->play) {
case MCSN_ST:
Oct 7, 2006
Oct 7, 2006
186
187
this->spec.channels = 1;
this->spec.format = AUDIO_S8; /* FIXME: is it signed or unsigned ? */
Jul 10, 2006
Jul 10, 2006
188
189
190
SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1);
break;
case MCSN_TT: /* Also STE, Mega STE */
Oct 7, 2006
Oct 7, 2006
191
this->spec.format = AUDIO_S8;
Jul 10, 2006
Jul 10, 2006
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
masterclock = MASTERCLOCK_STE;
masterprediv = MASTERPREDIV_STE;
if ((cookie_mch >> 16) == MCH_TT) {
masterclock = MASTERCLOCK_TT;
masterprediv = MASTERPREDIV_TT;
}
for (i = 0; i < 4; i++) {
SDL_MintAudio_AddFrequency(this,
masterclock / (masterprediv *
(1 << i)),
masterclock, 3 - i, -1);
}
break;
case MCSN_FALCON: /* Also Mac */
for (i = 1; i < 12; i++) {
/* Remove unusable Falcon codec predivisors */
if ((i == 6) || (i == 8) || (i == 10)) {
continue;
}
SDL_MintAudio_AddFrequency(this,
MASTERCLOCK_FALCON1 /
(MASTERPREDIV_FALCON * (i + 1)),
CLK25M, i + 1, -1);
}
if (cookie_mcsn->res1 != 0) {
for (i = 1; i < 4; i++) {
SDL_MintAudio_AddFrequency(this,
(cookie_mcsn->res1) /
(MASTERPREDIV_FALCON *
(1 << i)), CLKEXT,
(1 << i) - 1, -1);
}
}
Oct 7, 2006
Oct 7, 2006
225
226
227
228
this->spec.format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */
if ((SDL_AUDIO_BITSIZE(this->spec.format)) == 16) {
this->spec.format |= SDL_AUDIO_MASK_ENDIAN; /* Audio is always big endian */
this->spec.channels = 2; /* 16 bits always stereo */
Jul 10, 2006
Jul 10, 2006
229
230
231
}
break;
}
232
Oct 29, 2004
Oct 29, 2004
233
#if 1
Jul 10, 2006
Jul 10, 2006
234
235
236
237
238
239
for (i = 0; i < MINTAUDIO_freqcount; i++) {
DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
i, MINTAUDIO_frequencies[i].frequency,
MINTAUDIO_frequencies[i].masterclock,
MINTAUDIO_frequencies[i].predivisor));
}
Oct 29, 2004
Oct 29, 2004
240
241
#endif
Oct 7, 2006
Oct 7, 2006
242
243
MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
244
Sep 24, 2006
Sep 24, 2006
245
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
Oct 7, 2006
Oct 7, 2006
246
247
248
249
250
251
SDL_AUDIO_BITSIZE(this->spec.format)));
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
252
Jul 10, 2006
Jul 10, 2006
253
return 0;
254
255
}
Jul 10, 2006
Jul 10, 2006
256
static void
Oct 7, 2006
Oct 7, 2006
257
MINTMCSN_InitAudio(_THIS)
258
{
Jul 10, 2006
Jul 10, 2006
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
int channels_mode, prediv, dmaclock;
void *buffer;
/* Stop currently playing sound */
SDL_MintAudio_quit_thread = SDL_FALSE;
SDL_MintAudio_thread_finished = SDL_TRUE;
SDL_MintAudio_WaitThread();
Buffoper(0);
/* Set replay tracks */
Settracks(0, 0);
Setmontracks(0);
/* Select replay format */
channels_mode = STEREO16;
Oct 7, 2006
Oct 7, 2006
274
switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
Jul 10, 2006
Jul 10, 2006
275
case 8:
Oct 7, 2006
Oct 7, 2006
276
if (this->spec.channels == 2) {
Jul 10, 2006
Jul 10, 2006
277
278
279
280
281
282
283
284
285
channels_mode = STEREO8;
} else {
channels_mode = MONO8;
}
break;
}
if (Setmode(channels_mode) < 0) {
DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
}
286
Jul 10, 2006
Jul 10, 2006
287
288
289
290
291
292
293
294
295
296
297
298
299
dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock;
prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
switch (cookie_mcsn->play) {
case MCSN_TT:
Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1);
Soundcmd(SETPRESCALE, prediv);
DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n"));
break;
case MCSN_FALCON:
Devconnect(DMAPLAY, DAC, dmaclock, prediv, 1);
DEBUG_PRINT((DEBUG_NAME "Falcon prescaler selected\n"));
break;
}
300
Jul 10, 2006
Jul 10, 2006
301
302
/* Set buffer */
buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
Oct 7, 2006
Oct 7, 2006
303
if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) {
Jul 10, 2006
Jul 10, 2006
304
305
DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
}
306
Jul 10, 2006
Jul 10, 2006
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
if (SDL_MintAudio_mint_present) {
SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0);
} else {
/* Install interrupt */
Jdisint(MFP_DMASOUND);
Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);
Jenabint(MFP_DMASOUND);
if (Setinterrupt(SI_TIMERA, SI_PLAY) < 0) {
DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n"));
}
}
/* Go */
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
323
324
}
Jul 10, 2006
Jul 10, 2006
325
static int
Oct 7, 2006
Oct 7, 2006
326
MINTMCSN_OpenDevice(_THIS, const char *devname, int iscapture)
327
{
Jul 10, 2006
Jul 10, 2006
328
329
/* Lock sound system */
if (Locksnd() != 1) {
Oct 7, 2006
Oct 7, 2006
330
331
SDL_SetError("MINTMCSN_OpenDevice: Audio system already in use");
return 0;
Jul 10, 2006
Jul 10, 2006
332
}
333
Jul 10, 2006
Jul 10, 2006
334
SDL_MintAudio_device = this;
335
Jul 10, 2006
Jul 10, 2006
336
/* Check audio capabilities */
Oct 7, 2006
Oct 7, 2006
337
338
if (MINTMCSN_CheckAudio(this) == -1) {
return 0;
Jul 10, 2006
Jul 10, 2006
339
}
340
Oct 7, 2006
Oct 7, 2006
341
342
343
344
345
346
347
348
349
350
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden));
if (this->hidden == NULL) {
SDL_OutOfMemory();
return 0;
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
SDL_CalculateAudioSpec(&this->spec);
351
Jul 10, 2006
Jul 10, 2006
352
/* Allocate memory for audio buffers in DMA-able RAM */
Oct 7, 2006
Oct 7, 2006
353
DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
354
Oct 7, 2006
Oct 7, 2006
355
SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
Jul 10, 2006
Jul 10, 2006
356
if (SDL_MintAudio_audiobuf[0] == NULL) {
Oct 7, 2006
Oct 7, 2006
357
358
359
360
SDL_free(this->hidden);
this->hidden = NULL;
SDL_OutOfMemory();
return 0;
Jul 10, 2006
Jul 10, 2006
361
}
Oct 7, 2006
Oct 7, 2006
362
SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
Jul 10, 2006
Jul 10, 2006
363
SDL_MintAudio_numbuf = 0;
Oct 7, 2006
Oct 7, 2006
364
365
SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2);
SDL_MintAudio_audiosize = this->spec.size;
Jul 10, 2006
Jul 10, 2006
366
SDL_MintAudio_mutex = 0;
367
Jul 10, 2006
Jul 10, 2006
368
369
370
371
DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
SDL_MintAudio_audiobuf[0]));
DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n",
SDL_MintAudio_audiobuf[1]));
372
Sep 16, 2006
Sep 16, 2006
373
374
SDL_MintAudio_CheckFpu();
Jul 10, 2006
Jul 10, 2006
375
/* Setup audio hardware */
Oct 7, 2006
Oct 7, 2006
376
MINTMCSN_InitAudio(this);
377
Oct 7, 2006
Oct 7, 2006
378
return 1; /* good to go. */
379
}
Jul 10, 2006
Jul 10, 2006
380
Oct 7, 2006
Oct 7, 2006
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
static int
MINTMCSN_Init(SDL_AudioDriverImpl *impl)
{
/* Set the function pointers */
impl->OpenDevice = MINTMCSN_OpenDevice;
impl->CloseDevice = MINTMCSN_CloseDevice;
impl->LockAudio = MINTMCSN_LockAudio;
impl->UnlockAudio = MINTMCSN_UnlockAudio;
impl->OnlyHasDefaultOutputDevice = 1;
impl->ProvidesOwnCallbackThread = 1;
impl->SkipMixerLock = 1;
return 1;
}
AudioBootStrap MINTAUDIO_MCSN_bootstrap = {
MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver",
MINTMCSN_Available, MINTMCSN_Init, 0
};
Jul 10, 2006
Jul 10, 2006
401
/* vi: set ts=4 sw=4 expandtab: */