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

Latest commit

 

History

History
385 lines (307 loc) · 10.1 KB

SDL_mintaudio_dma8.c

File metadata and controls

385 lines (307 loc) · 10.1 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
31
32
33
34
35
36
/*
MiNT audio driver
using DMA 8bits (hardware access)
Patrice Mandin
*/
/* Mint includes */
#include <mint/osbind.h>
#include <mint/falcon.h>
#include <mint/cookie.h>
#include "SDL_audio.h"
Feb 16, 2006
Feb 16, 2006
37
38
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
39
Feb 21, 2006
Feb 21, 2006
40
#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
41
42
43
44
45
46
47
48
49
50
#include "SDL_mintaudio.h"
#include "SDL_mintaudio_dma8.h"
/*--- Defines ---*/
#define MINT_AUDIO_DRIVER_NAME "mint_dma8"
/* Debug print info */
#define DEBUG_NAME "audio:dma8: "
Oct 29, 2004
Oct 29, 2004
51
#if 0
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define DEBUG_PRINT(what) \
{ \
printf what; \
}
#else
#define DEBUG_PRINT(what)
#endif
/*--- Static variables ---*/
static unsigned long cookie_snd, cookie_mch;
/*--- Audio driver functions ---*/
static void Mint_CloseAudio(_THIS);
Jul 10, 2006
Jul 10, 2006
67
static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
68
69
70
71
static void Mint_LockAudio(_THIS);
static void Mint_UnlockAudio(_THIS);
/* To check/init hardware audio */
Jul 10, 2006
Jul 10, 2006
72
73
static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
74
75
76
/*--- Audio driver bootstrap functions ---*/
Jul 10, 2006
Jul 10, 2006
77
78
static int
Audio_Available(void)
79
{
Jul 10, 2006
Jul 10, 2006
80
const char *envr = SDL_getenv("SDL_AUDIODRIVER");
81
Jul 10, 2006
Jul 10, 2006
82
83
84
85
86
/* Check if user asked a different audio driver */
if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
return 0;
}
87
Jul 10, 2006
Jul 10, 2006
88
89
90
91
/* Cookie _MCH present ? if not, assume ST machine */
if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
cookie_mch = MCH_ST;
}
92
Jul 10, 2006
Jul 10, 2006
93
94
95
96
/* Cookie _SND present ? if not, assume ST machine */
if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
cookie_snd = SND_PSG;
}
97
Jul 10, 2006
Jul 10, 2006
98
99
100
101
102
/* Check if we have 8 bits audio */
if ((cookie_snd & SND_8BIT) == 0) {
DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
return (0);
}
103
Jul 10, 2006
Jul 10, 2006
104
105
106
107
108
109
/* Check if audio is lockable */
if (cookie_snd & SND_16BIT) {
if (Locksnd() != 1) {
DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
return (0);
}
110
Jul 10, 2006
Jul 10, 2006
111
112
Unlocksnd();
}
113
Jul 10, 2006
Jul 10, 2006
114
115
DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
return (1);
116
117
}
Jul 10, 2006
Jul 10, 2006
118
119
static void
Audio_DeleteDevice(SDL_AudioDevice * device)
120
{
Feb 7, 2006
Feb 7, 2006
121
122
SDL_free(device->hidden);
SDL_free(device);
123
124
}
Jul 10, 2006
Jul 10, 2006
125
126
static SDL_AudioDevice *
Audio_CreateDevice(int devindex)
127
{
Jul 10, 2006
Jul 10, 2006
128
SDL_AudioDevice *this;
129
Jul 10, 2006
Jul 10, 2006
130
131
132
/* Initialize all variables that we clean on shutdown */
this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
if (this) {
Feb 7, 2006
Feb 7, 2006
133
SDL_memset(this, 0, (sizeof *this));
134
this->hidden = (struct SDL_PrivateAudioData *)
Jul 10, 2006
Jul 10, 2006
135
SDL_malloc((sizeof *this->hidden));
136
}
Jul 10, 2006
Jul 10, 2006
137
if ((this == NULL) || (this->hidden == NULL)) {
138
SDL_OutOfMemory();
Jul 10, 2006
Jul 10, 2006
139
if (this) {
Feb 7, 2006
Feb 7, 2006
140
SDL_free(this);
141
}
Jul 10, 2006
Jul 10, 2006
142
return (0);
143
}
Feb 7, 2006
Feb 7, 2006
144
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
145
146
/* Set the function pointers */
Jul 10, 2006
Jul 10, 2006
147
148
149
this->OpenAudio = Mint_OpenAudio;
this->CloseAudio = Mint_CloseAudio;
this->LockAudio = Mint_LockAudio;
150
this->UnlockAudio = Mint_UnlockAudio;
Jul 10, 2006
Jul 10, 2006
151
this->free = Audio_DeleteDevice;
152
Oct 4, 2006
Oct 4, 2006
153
154
155
156
157
/* Uses interrupt driven audio, without thread */
#if SDL_THREADS_DISABLED
this->SkipMixerLock = 1;
#endif
158
159
160
161
return this;
}
AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
Jul 10, 2006
Jul 10, 2006
162
163
MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver",
Audio_Available, Audio_CreateDevice
164
165
};
Jul 10, 2006
Jul 10, 2006
166
167
static void
Mint_LockAudio(_THIS)
168
{
Jul 10, 2006
Jul 10, 2006
169
void *oldpile;
170
Jul 10, 2006
Jul 10, 2006
171
172
173
174
/* Stop replay */
oldpile = (void *) Super(0);
DMAAUDIO_IO.control = 0;
Super(oldpile);
175
176
}
Jul 10, 2006
Jul 10, 2006
177
178
static void
Mint_UnlockAudio(_THIS)
179
{
Jul 10, 2006
Jul 10, 2006
180
void *oldpile;
181
Jul 10, 2006
Jul 10, 2006
182
183
184
185
/* Restart replay */
oldpile = (void *) Super(0);
DMAAUDIO_IO.control = 3;
Super(oldpile);
186
187
}
Jul 10, 2006
Jul 10, 2006
188
189
static void
Mint_CloseAudio(_THIS)
190
{
Jul 10, 2006
Jul 10, 2006
191
void *oldpile;
192
Jul 10, 2006
Jul 10, 2006
193
194
195
196
/* Stop replay */
oldpile = (void *) Super(0);
DMAAUDIO_IO.control = 0;
Super(oldpile);
197
Jul 10, 2006
Jul 10, 2006
198
DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
199
Jul 10, 2006
Jul 10, 2006
200
201
/* Disable interrupt */
Jdisint(MFP_DMASOUND);
202
Jul 10, 2006
Jul 10, 2006
203
DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
204
Jul 10, 2006
Jul 10, 2006
205
206
207
/* Wait if currently playing sound */
while (SDL_MintAudio_mutex != 0) {
}
208
Jul 10, 2006
Jul 10, 2006
209
DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
210
Jul 10, 2006
Jul 10, 2006
211
212
213
214
215
/* Clear buffers */
if (SDL_MintAudio_audiobuf[0]) {
Mfree(SDL_MintAudio_audiobuf[0]);
SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
}
216
Jul 10, 2006
Jul 10, 2006
217
DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
218
219
}
Jul 10, 2006
Jul 10, 2006
220
221
static int
Mint_CheckAudio(_THIS, SDL_AudioSpec * spec)
222
{
Jul 10, 2006
Jul 10, 2006
223
224
225
int i, masterprediv, sfreq;
unsigned long masterclock;
Sep 24, 2006
Sep 24, 2006
226
227
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
SDL_AUDIO_BITSIZE(spec->format)));
Sep 1, 2006
Sep 1, 2006
228
229
230
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
Jul 10, 2006
Jul 10, 2006
231
232
233
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
Sep 1, 2006
Sep 1, 2006
234
if (spec->channels > 2) {
Sep 24, 2006
Sep 24, 2006
235
spec->channels = 2; /* no more than stereo! */
Sep 1, 2006
Sep 1, 2006
236
237
}
Jul 10, 2006
Jul 10, 2006
238
239
240
241
242
243
244
245
/* Check formats available */
spec->format = AUDIO_S8;
/* Calculate and select the closest frequency */
sfreq = 0;
masterclock = MASTERCLOCK_STE;
masterprediv = MASTERPREDIV_STE;
switch (cookie_mch >> 16) {
246
247
248
249
250
251
/*
case MCH_STE:
masterclock=MASTERCLOCK_STE;
masterprediv=MASTERPREDIV_STE;
break;
*/
Jul 10, 2006
Jul 10, 2006
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
case MCH_TT:
masterclock = MASTERCLOCK_TT;
masterprediv = MASTERPREDIV_TT;
break;
case MCH_F30:
case MCH_ARANYM:
masterclock = MASTERCLOCK_FALCON1;
masterprediv = MASTERPREDIV_FALCON;
sfreq = 1;
break;
}
MINTAUDIO_freqcount = 0;
for (i = sfreq; i < 4; i++) {
SDL_MintAudio_AddFrequency(this,
masterclock / (masterprediv * (1 << i)),
masterclock, i - sfreq, -1);
}
270
Oct 29, 2004
Oct 29, 2004
271
#if 1
Jul 10, 2006
Jul 10, 2006
272
273
274
275
276
277
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
278
279
#endif
Jul 10, 2006
Jul 10, 2006
280
281
MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq);
spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
282
Sep 24, 2006
Sep 24, 2006
283
284
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
SDL_AUDIO_BITSIZE(spec->format)));
Sep 1, 2006
Sep 1, 2006
285
286
287
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
Jul 10, 2006
Jul 10, 2006
288
289
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
290
Jul 10, 2006
Jul 10, 2006
291
return 0;
292
293
}
Jul 10, 2006
Jul 10, 2006
294
295
static void
Mint_InitAudio(_THIS, SDL_AudioSpec * spec)
296
{
Jul 10, 2006
Jul 10, 2006
297
298
299
300
301
302
303
304
305
void *oldpile;
unsigned long buffer;
unsigned char mode;
/* Set replay tracks */
if (cookie_snd & SND_16BIT) {
Settracks(0, 0);
Setmontracks(0);
}
306
Jul 10, 2006
Jul 10, 2006
307
oldpile = (void *) Super(0);
308
Jul 10, 2006
Jul 10, 2006
309
310
/* Stop currently playing sound */
DMAAUDIO_IO.control = 0;
311
Jul 10, 2006
Jul 10, 2006
312
313
314
315
316
/* Set buffer */
buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
DMAAUDIO_IO.start_high = (buffer >> 16) & 255;
DMAAUDIO_IO.start_mid = (buffer >> 8) & 255;
DMAAUDIO_IO.start_low = buffer & 255;
317
Jul 10, 2006
Jul 10, 2006
318
319
320
321
buffer += SDL_MintAudio_audiosize;
DMAAUDIO_IO.end_high = (buffer >> 16) & 255;
DMAAUDIO_IO.end_mid = (buffer >> 8) & 255;
DMAAUDIO_IO.end_low = buffer & 255;
322
Jul 10, 2006
Jul 10, 2006
323
324
325
326
327
mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
if (spec->channels == 1) {
mode |= 1 << 7;
}
DMAAUDIO_IO.sound_ctrl = mode;
328
Jul 10, 2006
Jul 10, 2006
329
330
331
332
/* Set interrupt */
Jdisint(MFP_DMASOUND);
Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
Jenabint(MFP_DMASOUND);
333
Jul 10, 2006
Jul 10, 2006
334
335
336
337
338
if (cookie_snd & SND_16BIT) {
if (Setinterrupt(SI_TIMERA, SI_PLAY) < 0) {
DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n"));
}
}
Jul 20, 2005
Jul 20, 2005
339
Jul 10, 2006
Jul 10, 2006
340
341
/* Go */
DMAAUDIO_IO.control = 3; /* playback + repeat */
342
Jul 10, 2006
Jul 10, 2006
343
Super(oldpile);
344
345
}
Jul 10, 2006
Jul 10, 2006
346
347
static int
Mint_OpenAudio(_THIS, SDL_AudioSpec * spec)
348
{
Jul 10, 2006
Jul 10, 2006
349
SDL_MintAudio_device = this;
350
Jul 10, 2006
Jul 10, 2006
351
352
353
354
/* Check audio capabilities */
if (Mint_CheckAudio(this, spec) == -1) {
return -1;
}
355
Jul 10, 2006
Jul 10, 2006
356
SDL_CalculateAudioSpec(spec);
357
Jul 10, 2006
Jul 10, 2006
358
359
/* Allocate memory for audio buffers in DMA-able RAM */
DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
360
Jul 10, 2006
Jul 10, 2006
361
362
363
364
365
366
367
368
369
370
SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM);
if (SDL_MintAudio_audiobuf[0] == NULL) {
SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
return (-1);
}
SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size;
SDL_MintAudio_numbuf = 0;
SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2);
SDL_MintAudio_audiosize = spec->size;
SDL_MintAudio_mutex = 0;
371
Jul 10, 2006
Jul 10, 2006
372
373
374
375
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]));
376
Sep 16, 2006
Sep 16, 2006
377
378
SDL_MintAudio_CheckFpu();
Jul 10, 2006
Jul 10, 2006
379
380
/* Setup audio hardware */
Mint_InitAudio(this, spec);
381
Jul 10, 2006
Jul 10, 2006
382
return (1); /* We don't use threaded audio */
383
}
Jul 10, 2006
Jul 10, 2006
384
385
/* vi: set ts=4 sw=4 expandtab: */