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

Latest commit

 

History

History
348 lines (279 loc) · 9.31 KB

SDL_mintaudio_dma8.c

File metadata and controls

348 lines (279 loc) · 9.31 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Dec 8, 2008
Dec 8, 2008
3
Copyright (C) 1997-2009 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
#define DEBUG_PRINT(what) \
{ \
printf what; \
}
#else
#define DEBUG_PRINT(what)
#endif
/*--- Static variables ---*/
static unsigned long cookie_snd, cookie_mch;
Jul 10, 2006
Jul 10, 2006
64
static void
Oct 17, 2006
Oct 17, 2006
65
MINTDMA8_LockDevice(_THIS)
66
{
Jul 10, 2006
Jul 10, 2006
67
void *oldpile;
68
Jul 10, 2006
Jul 10, 2006
69
70
71
72
/* Stop replay */
oldpile = (void *) Super(0);
DMAAUDIO_IO.control = 0;
Super(oldpile);
73
74
}
Jul 10, 2006
Jul 10, 2006
75
static void
Oct 17, 2006
Oct 17, 2006
76
MINTDMA8_UnlockDevice(_THIS)
77
{
Jul 10, 2006
Jul 10, 2006
78
void *oldpile;
79
Jul 10, 2006
Jul 10, 2006
80
81
82
83
/* Restart replay */
oldpile = (void *) Super(0);
DMAAUDIO_IO.control = 3;
Super(oldpile);
84
85
}
Jul 10, 2006
Jul 10, 2006
86
static void
Oct 17, 2006
Oct 17, 2006
87
MINTDMA8_CloseDevice(_THIS)
88
{
Oct 17, 2006
Oct 17, 2006
89
90
91
if (this->hidden != NULL) {
/* Stop replay */
void *oldpile = (void *) Super(0);
92
Oct 17, 2006
Oct 17, 2006
93
94
DMAAUDIO_IO.control = 0;
Super(oldpile);
95
Oct 17, 2006
Oct 17, 2006
96
DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
97
Oct 17, 2006
Oct 17, 2006
98
99
/* Disable interrupt */
Jdisint(MFP_DMASOUND);
100
Oct 17, 2006
Oct 17, 2006
101
DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
102
Oct 17, 2006
Oct 17, 2006
103
/* Wait if currently playing sound */
Oct 28, 2006
Oct 28, 2006
104
105
while (SDL_MintAudio_mutex != 0) {
}
106
Oct 17, 2006
Oct 17, 2006
107
DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
108
Oct 17, 2006
Oct 17, 2006
109
110
111
112
113
/* Clear buffers */
if (SDL_MintAudio_audiobuf[0]) {
Mfree(SDL_MintAudio_audiobuf[0]);
SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
}
114
Oct 17, 2006
Oct 17, 2006
115
DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
Jul 13, 2007
Jul 13, 2007
116
117
SDL_free(this->hidden);
this->hidden = NULL;
Oct 17, 2006
Oct 17, 2006
118
}
119
120
}
Jul 10, 2006
Jul 10, 2006
121
static int
Oct 17, 2006
Oct 17, 2006
122
MINTDMA8_CheckAudio(_THIS)
123
{
Jul 10, 2006
Jul 10, 2006
124
125
126
int i, masterprediv, sfreq;
unsigned long masterclock;
Sep 24, 2006
Sep 24, 2006
127
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
Oct 17, 2006
Oct 17, 2006
128
129
130
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)));
Oct 28, 2006
Oct 28, 2006
131
132
DEBUG_PRINT(("big endian=%d, ",
SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
Oct 17, 2006
Oct 17, 2006
133
134
135
136
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
if (this->spec.channels > 2) {
Oct 28, 2006
Oct 28, 2006
137
this->spec.channels = 2; /* no more than stereo! */
Sep 1, 2006
Sep 1, 2006
138
139
}
Jul 10, 2006
Jul 10, 2006
140
/* Check formats available */
Oct 17, 2006
Oct 17, 2006
141
this->spec.format = AUDIO_S8;
Jul 10, 2006
Jul 10, 2006
142
143
144
145
146
147
/* Calculate and select the closest frequency */
sfreq = 0;
masterclock = MASTERCLOCK_STE;
masterprediv = MASTERPREDIV_STE;
switch (cookie_mch >> 16) {
148
149
150
151
152
153
/*
case MCH_STE:
masterclock=MASTERCLOCK_STE;
masterprediv=MASTERPREDIV_STE;
break;
*/
Jul 10, 2006
Jul 10, 2006
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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);
}
172
Oct 29, 2004
Oct 29, 2004
173
#if 1
Jul 10, 2006
Jul 10, 2006
174
175
176
177
178
179
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
180
181
#endif
Oct 17, 2006
Oct 17, 2006
182
183
MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
184
Sep 24, 2006
Sep 24, 2006
185
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
Oct 17, 2006
Oct 17, 2006
186
187
188
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)));
Oct 28, 2006
Oct 28, 2006
189
190
DEBUG_PRINT(("big endian=%d, ",
SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
Oct 17, 2006
Oct 17, 2006
191
192
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
193
Jul 10, 2006
Jul 10, 2006
194
return 0;
195
196
}
Jul 10, 2006
Jul 10, 2006
197
static void
Oct 17, 2006
Oct 17, 2006
198
MINTDMA8_InitAudio(_THIS)
199
{
Jul 10, 2006
Jul 10, 2006
200
201
202
203
204
205
206
207
208
void *oldpile;
unsigned long buffer;
unsigned char mode;
/* Set replay tracks */
if (cookie_snd & SND_16BIT) {
Settracks(0, 0);
Setmontracks(0);
}
209
Jul 10, 2006
Jul 10, 2006
210
oldpile = (void *) Super(0);
211
Jul 10, 2006
Jul 10, 2006
212
213
/* Stop currently playing sound */
DMAAUDIO_IO.control = 0;
214
Jul 10, 2006
Jul 10, 2006
215
216
217
218
219
/* 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;
220
Jul 10, 2006
Jul 10, 2006
221
222
223
224
buffer += SDL_MintAudio_audiosize;
DMAAUDIO_IO.end_high = (buffer >> 16) & 255;
DMAAUDIO_IO.end_mid = (buffer >> 8) & 255;
DMAAUDIO_IO.end_low = buffer & 255;
225
Jul 10, 2006
Jul 10, 2006
226
mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
Oct 17, 2006
Oct 17, 2006
227
if (this->spec.channels == 1) {
Jul 10, 2006
Jul 10, 2006
228
229
230
mode |= 1 << 7;
}
DMAAUDIO_IO.sound_ctrl = mode;
231
Jul 10, 2006
Jul 10, 2006
232
233
234
235
/* Set interrupt */
Jdisint(MFP_DMASOUND);
Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
Jenabint(MFP_DMASOUND);
236
Jul 10, 2006
Jul 10, 2006
237
238
239
240
241
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
242
Jul 10, 2006
Jul 10, 2006
243
244
/* Go */
DMAAUDIO_IO.control = 3; /* playback + repeat */
245
Jul 10, 2006
Jul 10, 2006
246
Super(oldpile);
247
248
}
Jul 10, 2006
Jul 10, 2006
249
static int
Oct 17, 2006
Oct 17, 2006
250
MINTDMA8_OpenDevice(_THIS, const char *devname, int iscapture)
251
{
Jul 10, 2006
Jul 10, 2006
252
SDL_MintAudio_device = this;
253
Jul 10, 2006
Jul 10, 2006
254
/* Check audio capabilities */
Oct 17, 2006
Oct 17, 2006
255
256
if (MINTDMA8_CheckAudio(this) == -1) {
return 0;
Jul 10, 2006
Jul 10, 2006
257
}
258
Oct 17, 2006
Oct 17, 2006
259
260
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
Oct 28, 2006
Oct 28, 2006
261
SDL_malloc((sizeof *this->hidden));
Oct 17, 2006
Oct 17, 2006
262
263
264
265
266
267
268
if (this->hidden == NULL) {
SDL_OutOfMemory();
return 0;
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
SDL_CalculateAudioSpec(&this->spec);
269
Jul 10, 2006
Jul 10, 2006
270
/* Allocate memory for audio buffers in DMA-able RAM */
Oct 17, 2006
Oct 17, 2006
271
DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
272
Oct 28, 2006
Oct 28, 2006
273
274
SDL_MintAudio_audiobuf[0] =
Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
Jul 10, 2006
Jul 10, 2006
275
if (SDL_MintAudio_audiobuf[0] == NULL) {
Oct 17, 2006
Oct 17, 2006
276
277
278
279
SDL_free(this->hidden);
this->hidden = NULL;
SDL_OutOfMemory();
return 0;
Jul 10, 2006
Jul 10, 2006
280
}
Oct 17, 2006
Oct 17, 2006
281
SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
Jul 10, 2006
Jul 10, 2006
282
SDL_MintAudio_numbuf = 0;
Oct 28, 2006
Oct 28, 2006
283
284
SDL_memset(SDL_MintAudio_audiobuf[0], this->spec.silence,
this->spec.size * 2);
Oct 17, 2006
Oct 17, 2006
285
SDL_MintAudio_audiosize = this->spec.size;
Jul 10, 2006
Jul 10, 2006
286
SDL_MintAudio_mutex = 0;
287
Jul 10, 2006
Jul 10, 2006
288
289
290
291
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]));
292
Sep 16, 2006
Sep 16, 2006
293
294
SDL_MintAudio_CheckFpu();
Jul 10, 2006
Jul 10, 2006
295
/* Setup audio hardware */
Oct 17, 2006
Oct 17, 2006
296
MINTDMA8_InitAudio(this);
297
Oct 28, 2006
Oct 28, 2006
298
return 1; /* good to go. */
299
}
Jul 10, 2006
Jul 10, 2006
300
Oct 17, 2006
Oct 17, 2006
301
static int
Oct 28, 2006
Oct 28, 2006
302
MINTDMA8_Init(SDL_AudioDriverImpl * impl)
Oct 17, 2006
Oct 17, 2006
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
{
/* Cookie _MCH present ? if not, assume ST machine */
if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
cookie_mch = MCH_ST;
}
/* Cookie _SND present ? if not, assume ST machine */
if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
cookie_snd = SND_PSG;
}
/* Check if we have 8 bits audio */
if ((cookie_snd & SND_8BIT) == 0) {
SDL_SetError(DEBUG_NAME "no 8 bits sound");
return 0;
}
/* Check if audio is lockable */
if (cookie_snd & SND_16BIT) {
if (Locksnd() != 1) {
SDL_SetError(DEBUG_NAME "audio locked by other application");
return 0;
}
Unlocksnd();
}
DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
/* Set the function pointers */
impl->OpenDevice = MINTDMA8_OpenDevice;
impl->CloseDevice = MINTDMA8_CloseDevice;
Jul 13, 2007
Jul 13, 2007
335
336
impl->LockDevice = MINTDMA8_LockDevice;
impl->UnlockDevice = MINTDMA8_UnlockDevice;
Oct 17, 2006
Oct 17, 2006
337
338
339
340
impl->OnlyHasDefaultOutputDevice = 1;
impl->ProvidesOwnCallbackThread = 1;
impl->SkipMixerLock = 1;
Jan 1, 2009
Jan 1, 2009
341
return 2; /* 2 == definitely has an audio device. */
Oct 17, 2006
Oct 17, 2006
342
343
344
345
346
347
}
AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", MINTDMA8_Init, 0
};
Jul 10, 2006
Jul 10, 2006
348
/* vi: set ts=4 sw=4 expandtab: */