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

Latest commit

 

History

History
343 lines (274 loc) · 9.18 KB

SDL_mintaudio_dma8.c

File metadata and controls

343 lines (274 loc) · 9.18 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
#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
104
/* Wait if currently playing sound */
while (SDL_MintAudio_mutex != 0) {}
105
Oct 17, 2006
Oct 17, 2006
106
DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
107
Oct 17, 2006
Oct 17, 2006
108
109
110
111
112
/* Clear buffers */
if (SDL_MintAudio_audiobuf[0]) {
Mfree(SDL_MintAudio_audiobuf[0]);
SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
}
113
Oct 17, 2006
Oct 17, 2006
114
115
116
117
DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
SDL_free(this->buffer);
this->buffer = NULL;
}
118
119
}
Jul 10, 2006
Jul 10, 2006
120
static int
Oct 17, 2006
Oct 17, 2006
121
MINTDMA8_CheckAudio(_THIS)
122
{
Jul 10, 2006
Jul 10, 2006
123
124
125
int i, masterprediv, sfreq;
unsigned long masterclock;
Sep 24, 2006
Sep 24, 2006
126
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
Oct 17, 2006
Oct 17, 2006
127
128
129
130
131
132
133
134
135
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
136
137
}
Jul 10, 2006
Jul 10, 2006
138
/* Check formats available */
Oct 17, 2006
Oct 17, 2006
139
this->spec.format = AUDIO_S8;
Jul 10, 2006
Jul 10, 2006
140
141
142
143
144
145
/* Calculate and select the closest frequency */
sfreq = 0;
masterclock = MASTERCLOCK_STE;
masterprediv = MASTERPREDIV_STE;
switch (cookie_mch >> 16) {
146
147
148
149
150
151
/*
case MCH_STE:
masterclock=MASTERCLOCK_STE;
masterprediv=MASTERPREDIV_STE;
break;
*/
Jul 10, 2006
Jul 10, 2006
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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);
}
170
Oct 29, 2004
Oct 29, 2004
171
#if 1
Jul 10, 2006
Jul 10, 2006
172
173
174
175
176
177
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
178
179
#endif
Oct 17, 2006
Oct 17, 2006
180
181
MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
182
Sep 24, 2006
Sep 24, 2006
183
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
Oct 17, 2006
Oct 17, 2006
184
185
186
187
188
189
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));
190
Jul 10, 2006
Jul 10, 2006
191
return 0;
192
193
}
Jul 10, 2006
Jul 10, 2006
194
static void
Oct 17, 2006
Oct 17, 2006
195
MINTDMA8_InitAudio(_THIS)
196
{
Jul 10, 2006
Jul 10, 2006
197
198
199
200
201
202
203
204
205
void *oldpile;
unsigned long buffer;
unsigned char mode;
/* Set replay tracks */
if (cookie_snd & SND_16BIT) {
Settracks(0, 0);
Setmontracks(0);
}
206
Jul 10, 2006
Jul 10, 2006
207
oldpile = (void *) Super(0);
208
Jul 10, 2006
Jul 10, 2006
209
210
/* Stop currently playing sound */
DMAAUDIO_IO.control = 0;
211
Jul 10, 2006
Jul 10, 2006
212
213
214
215
216
/* 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;
217
Jul 10, 2006
Jul 10, 2006
218
219
220
221
buffer += SDL_MintAudio_audiosize;
DMAAUDIO_IO.end_high = (buffer >> 16) & 255;
DMAAUDIO_IO.end_mid = (buffer >> 8) & 255;
DMAAUDIO_IO.end_low = buffer & 255;
222
Jul 10, 2006
Jul 10, 2006
223
mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
Oct 17, 2006
Oct 17, 2006
224
if (this->spec.channels == 1) {
Jul 10, 2006
Jul 10, 2006
225
226
227
mode |= 1 << 7;
}
DMAAUDIO_IO.sound_ctrl = mode;
228
Jul 10, 2006
Jul 10, 2006
229
230
231
232
/* Set interrupt */
Jdisint(MFP_DMASOUND);
Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
Jenabint(MFP_DMASOUND);
233
Jul 10, 2006
Jul 10, 2006
234
235
236
237
238
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
239
Jul 10, 2006
Jul 10, 2006
240
241
/* Go */
DMAAUDIO_IO.control = 3; /* playback + repeat */
242
Jul 10, 2006
Jul 10, 2006
243
Super(oldpile);
244
245
}
Jul 10, 2006
Jul 10, 2006
246
static int
Oct 17, 2006
Oct 17, 2006
247
MINTDMA8_OpenDevice(_THIS, const char *devname, int iscapture)
248
{
Jul 10, 2006
Jul 10, 2006
249
SDL_MintAudio_device = this;
250
Jul 10, 2006
Jul 10, 2006
251
/* Check audio capabilities */
Oct 17, 2006
Oct 17, 2006
252
253
if (MINTDMA8_CheckAudio(this) == -1) {
return 0;
Jul 10, 2006
Jul 10, 2006
254
}
255
Oct 17, 2006
Oct 17, 2006
256
257
258
259
260
261
262
263
264
265
/* 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);
266
Jul 10, 2006
Jul 10, 2006
267
/* Allocate memory for audio buffers in DMA-able RAM */
Oct 17, 2006
Oct 17, 2006
268
DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
269
Oct 17, 2006
Oct 17, 2006
270
SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
Jul 10, 2006
Jul 10, 2006
271
if (SDL_MintAudio_audiobuf[0] == NULL) {
Oct 17, 2006
Oct 17, 2006
272
273
274
275
SDL_free(this->hidden);
this->hidden = NULL;
SDL_OutOfMemory();
return 0;
Jul 10, 2006
Jul 10, 2006
276
}
Oct 17, 2006
Oct 17, 2006
277
SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
Jul 10, 2006
Jul 10, 2006
278
SDL_MintAudio_numbuf = 0;
Oct 17, 2006
Oct 17, 2006
279
280
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
281
SDL_MintAudio_mutex = 0;
282
Jul 10, 2006
Jul 10, 2006
283
284
285
286
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]));
287
Sep 16, 2006
Sep 16, 2006
288
289
SDL_MintAudio_CheckFpu();
Jul 10, 2006
Jul 10, 2006
290
/* Setup audio hardware */
Oct 17, 2006
Oct 17, 2006
291
MINTDMA8_InitAudio(this);
292
Oct 17, 2006
Oct 17, 2006
293
return 1; /* good to go. */
294
}
Jul 10, 2006
Jul 10, 2006
295
Oct 17, 2006
Oct 17, 2006
296
297
298
299
300
301
302
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
335
336
337
338
339
340
341
342
static int
MINTDMA8_Init(SDL_AudioDriverImpl *impl)
{
/* 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;
impl->LockAudio = MINTDMA8_LockAudio;
impl->UnlockAudio = MINTDMA8_UnlockAudio;
impl->OnlyHasDefaultOutputDevice = 1;
impl->ProvidesOwnCallbackThread = 1;
impl->SkipMixerLock = 1;
return 1;
}
AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", MINTDMA8_Init, 0
};
Jul 10, 2006
Jul 10, 2006
343
/* vi: set ts=4 sw=4 expandtab: */