diff options
Diffstat (limited to 'apps/plugins/sdl/src/audio/mint')
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c | 215 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h | 121 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c | 357 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h | 85 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c | 436 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h | 104 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S | 386 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c | 405 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h | 59 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c | 326 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h | 97 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c | 490 |
12 files changed, 3081 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c new file mode 100644 index 0000000000..46ba690c3e --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | Audio interrupt variables and callback function | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #include <unistd.h> | ||
31 | |||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/mintbind.h> | ||
35 | #include <mint/cookie.h> | ||
36 | |||
37 | #include "SDL_audio.h" | ||
38 | #include "SDL_mintaudio.h" | ||
39 | #include "SDL_mintaudio_stfa.h" | ||
40 | |||
41 | /* The audio device */ | ||
42 | |||
43 | SDL_AudioDevice *SDL_MintAudio_device; | ||
44 | Uint8 *SDL_MintAudio_audiobuf[2]; /* Pointers to buffers */ | ||
45 | unsigned long SDL_MintAudio_audiosize; /* Length of audio buffer=spec->size */ | ||
46 | volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ | ||
47 | volatile unsigned short SDL_MintAudio_mutex; | ||
48 | volatile unsigned long SDL_MintAudio_clocktics; | ||
49 | cookie_stfa_t *SDL_MintAudio_stfa; | ||
50 | unsigned short SDL_MintAudio_hasfpu; | ||
51 | |||
52 | /* MiNT thread variables */ | ||
53 | SDL_bool SDL_MintAudio_mint_present; | ||
54 | SDL_bool SDL_MintAudio_quit_thread; | ||
55 | SDL_bool SDL_MintAudio_thread_finished; | ||
56 | long SDL_MintAudio_thread_pid; | ||
57 | |||
58 | /* The callback function, called by each driver whenever needed */ | ||
59 | |||
60 | void SDL_MintAudio_Callback(void) | ||
61 | { | ||
62 | Uint8 *buffer; | ||
63 | SDL_AudioDevice *audio = SDL_MintAudio_device; | ||
64 | |||
65 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
66 | SDL_memset(buffer, audio->spec.silence, audio->spec.size); | ||
67 | |||
68 | if (audio->paused) | ||
69 | return; | ||
70 | |||
71 | if (audio->convert.needed) { | ||
72 | int silence; | ||
73 | |||
74 | if ( audio->convert.src_format == AUDIO_U8 ) { | ||
75 | silence = 0x80; | ||
76 | } else { | ||
77 | silence = 0; | ||
78 | } | ||
79 | SDL_memset(audio->convert.buf, silence, audio->convert.len); | ||
80 | audio->spec.callback(audio->spec.userdata, | ||
81 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
82 | SDL_ConvertAudio(&audio->convert); | ||
83 | SDL_memcpy(buffer, audio->convert.buf, audio->convert.len_cvt); | ||
84 | } else { | ||
85 | audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Add a new frequency/clock/predivisor to the current list */ | ||
90 | void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, | ||
91 | Uint32 prediv, int gpio_bits) | ||
92 | { | ||
93 | int i, p; | ||
94 | |||
95 | if (MINTAUDIO_freqcount==MINTAUDIO_maxfreqs) { | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | /* Search where to insert the frequency (highest first) */ | ||
100 | for (p=0; p<MINTAUDIO_freqcount; p++) { | ||
101 | if (frequency > MINTAUDIO_frequencies[p].frequency) { | ||
102 | break; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* Put all following ones farer */ | ||
107 | if (MINTAUDIO_freqcount>0) { | ||
108 | for (i=MINTAUDIO_freqcount; i>p; i--) { | ||
109 | SDL_memcpy(&MINTAUDIO_frequencies[i], &MINTAUDIO_frequencies[i-1], sizeof(mint_frequency_t)); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* And insert new one */ | ||
114 | MINTAUDIO_frequencies[p].frequency = frequency; | ||
115 | MINTAUDIO_frequencies[p].masterclock = clock; | ||
116 | MINTAUDIO_frequencies[p].predivisor = prediv; | ||
117 | MINTAUDIO_frequencies[p].gpio_bits = gpio_bits; | ||
118 | |||
119 | MINTAUDIO_freqcount++; | ||
120 | } | ||
121 | |||
122 | /* Search for the nearest frequency */ | ||
123 | int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) | ||
124 | { | ||
125 | int i; | ||
126 | |||
127 | /* Only 1 freq ? */ | ||
128 | if (MINTAUDIO_freqcount==1) { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | /* Check the array */ | ||
133 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
134 | if (desired_freq >= ((MINTAUDIO_frequencies[i].frequency+ | ||
135 | MINTAUDIO_frequencies[i+1].frequency)>>1)) { | ||
136 | return i; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* Not in the array, give the latest */ | ||
141 | return MINTAUDIO_freqcount-1; | ||
142 | } | ||
143 | |||
144 | /* Check if FPU is present */ | ||
145 | void SDL_MintAudio_CheckFpu(void) | ||
146 | { | ||
147 | long cookie_fpu; | ||
148 | |||
149 | SDL_MintAudio_hasfpu = 0; | ||
150 | if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) { | ||
151 | return; | ||
152 | } | ||
153 | switch ((cookie_fpu>>16)&0xfffe) { | ||
154 | case 2: | ||
155 | case 4: | ||
156 | case 6: | ||
157 | case 8: | ||
158 | case 16: | ||
159 | SDL_MintAudio_hasfpu = 1; | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* The thread function, used under MiNT with xbios */ | ||
165 | int SDL_MintAudio_Thread(long param) | ||
166 | { | ||
167 | SndBufPtr pointers; | ||
168 | SDL_bool buffers_filled[2] = {SDL_FALSE, SDL_FALSE}; | ||
169 | |||
170 | SDL_MintAudio_thread_finished = SDL_FALSE; | ||
171 | while (!SDL_MintAudio_quit_thread) { | ||
172 | if (Buffptr(&pointers)!=0) | ||
173 | continue; | ||
174 | |||
175 | if (( (unsigned long)pointers.play>=(unsigned long)SDL_MintAudio_audiobuf[0]) | ||
176 | && ( (unsigned long)pointers.play<=(unsigned long)SDL_MintAudio_audiobuf[1])) | ||
177 | { | ||
178 | /* DMA is reading buffer #0, setup buffer #1 if not already done */ | ||
179 | if (!buffers_filled[1]) { | ||
180 | SDL_MintAudio_numbuf = 1; | ||
181 | SDL_MintAudio_Callback(); | ||
182 | Setbuffer(0, SDL_MintAudio_audiobuf[1], SDL_MintAudio_audiobuf[1] + SDL_MintAudio_audiosize); | ||
183 | buffers_filled[1]=SDL_TRUE; | ||
184 | buffers_filled[0]=SDL_FALSE; | ||
185 | } | ||
186 | } else { | ||
187 | /* DMA is reading buffer #1, setup buffer #0 if not already done */ | ||
188 | if (!buffers_filled[0]) { | ||
189 | SDL_MintAudio_numbuf = 0; | ||
190 | SDL_MintAudio_Callback(); | ||
191 | Setbuffer(0, SDL_MintAudio_audiobuf[0], SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize); | ||
192 | buffers_filled[0]=SDL_TRUE; | ||
193 | buffers_filled[1]=SDL_FALSE; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | usleep(100); | ||
198 | } | ||
199 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | void SDL_MintAudio_WaitThread(void) | ||
204 | { | ||
205 | if (!SDL_MintAudio_mint_present) | ||
206 | return; | ||
207 | |||
208 | if (SDL_MintAudio_thread_finished) | ||
209 | return; | ||
210 | |||
211 | SDL_MintAudio_quit_thread = SDL_TRUE; | ||
212 | while (!SDL_MintAudio_thread_finished) { | ||
213 | Syield(); | ||
214 | } | ||
215 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h new file mode 100644 index 0000000000..ba6056ee3a --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_h | ||
31 | #define _SDL_mintaudio_h | ||
32 | |||
33 | #include "../SDL_sysaudio.h" | ||
34 | #include "SDL_mintaudio_stfa.h" | ||
35 | |||
36 | /* Hidden "this" pointer for the audio functions */ | ||
37 | #define _THIS SDL_AudioDevice *this | ||
38 | |||
39 | /* 16 predivisors with 3 clocks max. */ | ||
40 | #define MINTAUDIO_maxfreqs (16*3) | ||
41 | |||
42 | typedef struct { | ||
43 | Uint32 frequency; | ||
44 | Uint32 masterclock; | ||
45 | Uint32 predivisor; | ||
46 | int gpio_bits; /* in case of external clock */ | ||
47 | } mint_frequency_t; | ||
48 | |||
49 | struct SDL_PrivateAudioData { | ||
50 | mint_frequency_t frequencies[MINTAUDIO_maxfreqs]; | ||
51 | int freq_count; /* Number of frequencies in the array */ | ||
52 | int numfreq; /* Number of selected frequency */ | ||
53 | }; | ||
54 | |||
55 | /* Old variable names */ | ||
56 | |||
57 | #define MINTAUDIO_frequencies (this->hidden->frequencies) | ||
58 | #define MINTAUDIO_freqcount (this->hidden->freq_count) | ||
59 | #define MINTAUDIO_numfreq (this->hidden->numfreq) | ||
60 | |||
61 | /* _MCH cookie (values>>16) */ | ||
62 | enum { | ||
63 | MCH_ST=0, | ||
64 | MCH_STE, | ||
65 | MCH_TT, | ||
66 | MCH_F30, | ||
67 | MCH_CLONE, | ||
68 | MCH_ARANYM | ||
69 | }; | ||
70 | |||
71 | /* Master clocks for replay frequencies */ | ||
72 | #define MASTERCLOCK_STE 8010666 /* Not sure of this one */ | ||
73 | #define MASTERCLOCK_TT 16107953 /* Not sure of this one */ | ||
74 | #define MASTERCLOCK_FALCON1 25175000 | ||
75 | #define MASTERCLOCK_FALCON2 32000000 /* Only usable for DSP56K */ | ||
76 | #define MASTERCLOCK_FALCONEXT -1 /* Clock on DSP56K port, unknown */ | ||
77 | #define MASTERCLOCK_44K 22579200 /* Standard clock for 44.1 Khz */ | ||
78 | #define MASTERCLOCK_48K 24576000 /* Standard clock for 48 Khz */ | ||
79 | |||
80 | /* Master clock predivisors */ | ||
81 | #define MASTERPREDIV_STE 160 | ||
82 | #define MASTERPREDIV_TT 320 | ||
83 | #define MASTERPREDIV_FALCON 256 | ||
84 | #define MASTERPREDIV_MILAN 256 | ||
85 | |||
86 | /* Variables */ | ||
87 | extern SDL_AudioDevice *SDL_MintAudio_device; | ||
88 | extern Uint8 *SDL_MintAudio_audiobuf[2]; /* Pointers to buffers */ | ||
89 | extern unsigned long SDL_MintAudio_audiosize; /* Length of audio buffer=spec->size */ | ||
90 | extern volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ | ||
91 | extern volatile unsigned short SDL_MintAudio_mutex; | ||
92 | extern cookie_stfa_t *SDL_MintAudio_stfa; | ||
93 | extern volatile unsigned long SDL_MintAudio_clocktics; | ||
94 | extern unsigned short SDL_MintAudio_hasfpu; /* To preserve fpu registers if needed */ | ||
95 | |||
96 | /* MiNT thread variables */ | ||
97 | extern SDL_bool SDL_MintAudio_mint_present; | ||
98 | extern SDL_bool SDL_MintAudio_quit_thread; | ||
99 | extern SDL_bool SDL_MintAudio_thread_finished; | ||
100 | extern long SDL_MintAudio_thread_pid; | ||
101 | |||
102 | /* Functions */ | ||
103 | void SDL_MintAudio_Callback(void); | ||
104 | void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, | ||
105 | Uint32 prediv, int gpio_bits); | ||
106 | int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq); | ||
107 | void SDL_MintAudio_CheckFpu(void); | ||
108 | |||
109 | /* MiNT thread functions */ | ||
110 | int SDL_MintAudio_Thread(long param); | ||
111 | void SDL_MintAudio_WaitThread(void); | ||
112 | |||
113 | /* ASM interrupt functions */ | ||
114 | void SDL_MintAudio_GsxbInterrupt(void); | ||
115 | void SDL_MintAudio_EmptyGsxbInterrupt(void); | ||
116 | void SDL_MintAudio_XbiosInterruptMeasureClock(void); | ||
117 | void SDL_MintAudio_XbiosInterrupt(void); | ||
118 | void SDL_MintAudio_Dma8Interrupt(void); | ||
119 | void SDL_MintAudio_StfaInterrupt(void); | ||
120 | |||
121 | #endif /* _SDL_mintaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c new file mode 100644 index 0000000000..61feba3d64 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | using DMA 8bits (hardware access) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | |||
42 | #include "SDL_mintaudio.h" | ||
43 | #include "SDL_mintaudio_dma8.h" | ||
44 | |||
45 | /*--- Defines ---*/ | ||
46 | |||
47 | #define MINT_AUDIO_DRIVER_NAME "mint_dma8" | ||
48 | |||
49 | /* Debug print info */ | ||
50 | #define DEBUG_NAME "audio:dma8: " | ||
51 | #if 0 | ||
52 | #define DEBUG_PRINT(what) \ | ||
53 | { \ | ||
54 | printf what; \ | ||
55 | } | ||
56 | #else | ||
57 | #define DEBUG_PRINT(what) | ||
58 | #endif | ||
59 | |||
60 | /*--- Static variables ---*/ | ||
61 | |||
62 | static long cookie_snd, cookie_mch; | ||
63 | |||
64 | /*--- Audio driver functions ---*/ | ||
65 | |||
66 | static void Mint_CloseAudio(_THIS); | ||
67 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
68 | static void Mint_LockAudio(_THIS); | ||
69 | static void Mint_UnlockAudio(_THIS); | ||
70 | |||
71 | /* To check/init hardware audio */ | ||
72 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
73 | |||
74 | /* Functions called in supervisor mode */ | ||
75 | static void Mint_InitDma(void); | ||
76 | static void Mint_StopReplay(void); | ||
77 | static void Mint_StartReplay(void); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | /* Check if user asked a different audio driver */ | ||
86 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
87 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
92 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
93 | cookie_mch = MCH_ST; | ||
94 | } | ||
95 | |||
96 | /* Cookie _SND present ? if not, assume ST machine */ | ||
97 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
98 | cookie_snd = SND_PSG; | ||
99 | } | ||
100 | |||
101 | /* Check if we have 8 bits audio */ | ||
102 | if ((cookie_snd & SND_8BIT)==0) { | ||
103 | DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n")); | ||
104 | return(0); | ||
105 | } | ||
106 | |||
107 | /* Check if audio is lockable */ | ||
108 | if (cookie_snd & SND_16BIT) { | ||
109 | if (Locksnd()!=1) { | ||
110 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
111 | return(0); | ||
112 | } | ||
113 | |||
114 | Unlocksnd(); | ||
115 | } | ||
116 | |||
117 | DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n")); | ||
118 | return(1); | ||
119 | } | ||
120 | |||
121 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
122 | { | ||
123 | SDL_free(device->hidden); | ||
124 | SDL_free(device); | ||
125 | } | ||
126 | |||
127 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
128 | { | ||
129 | SDL_AudioDevice *this; | ||
130 | |||
131 | /* Initialize all variables that we clean on shutdown */ | ||
132 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
133 | if ( this ) { | ||
134 | SDL_memset(this, 0, (sizeof *this)); | ||
135 | this->hidden = (struct SDL_PrivateAudioData *) | ||
136 | SDL_malloc((sizeof *this->hidden)); | ||
137 | } | ||
138 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
139 | SDL_OutOfMemory(); | ||
140 | if ( this ) { | ||
141 | SDL_free(this); | ||
142 | } | ||
143 | return(0); | ||
144 | } | ||
145 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
146 | |||
147 | /* Set the function pointers */ | ||
148 | this->OpenAudio = Mint_OpenAudio; | ||
149 | this->CloseAudio = Mint_CloseAudio; | ||
150 | this->LockAudio = Mint_LockAudio; | ||
151 | this->UnlockAudio = Mint_UnlockAudio; | ||
152 | this->free = Audio_DeleteDevice; | ||
153 | |||
154 | return this; | ||
155 | } | ||
156 | |||
157 | AudioBootStrap MINTAUDIO_DMA8_bootstrap = { | ||
158 | MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", | ||
159 | Audio_Available, Audio_CreateDevice | ||
160 | }; | ||
161 | |||
162 | static void Mint_LockAudio(_THIS) | ||
163 | { | ||
164 | Supexec(Mint_StopReplay); | ||
165 | } | ||
166 | |||
167 | static void Mint_UnlockAudio(_THIS) | ||
168 | { | ||
169 | Supexec(Mint_StartReplay); | ||
170 | } | ||
171 | |||
172 | static void Mint_CloseAudio(_THIS) | ||
173 | { | ||
174 | Supexec(Mint_StopReplay); | ||
175 | |||
176 | DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n")); | ||
177 | |||
178 | /* Disable interrupt */ | ||
179 | Jdisint(MFP_DMASOUND); | ||
180 | |||
181 | DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n")); | ||
182 | |||
183 | /* Wait if currently playing sound */ | ||
184 | while (SDL_MintAudio_mutex != 0) { | ||
185 | } | ||
186 | |||
187 | DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n")); | ||
188 | |||
189 | /* Clear buffers */ | ||
190 | if (SDL_MintAudio_audiobuf[0]) { | ||
191 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
192 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
193 | } | ||
194 | |||
195 | DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n")); | ||
196 | } | ||
197 | |||
198 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
199 | { | ||
200 | int i, masterprediv, sfreq; | ||
201 | unsigned long masterclock; | ||
202 | |||
203 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
204 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
205 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
206 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
207 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
208 | |||
209 | if (spec->channels > 2) | ||
210 | spec->channels = 2; | ||
211 | |||
212 | /* Check formats available */ | ||
213 | spec->format = AUDIO_S8; | ||
214 | |||
215 | /* Calculate and select the closest frequency */ | ||
216 | sfreq=0; | ||
217 | masterclock=MASTERCLOCK_STE; | ||
218 | masterprediv=MASTERPREDIV_STE; | ||
219 | switch(cookie_mch>>16) { | ||
220 | /* | ||
221 | case MCH_STE: | ||
222 | masterclock=MASTERCLOCK_STE; | ||
223 | masterprediv=MASTERPREDIV_STE; | ||
224 | break; | ||
225 | */ | ||
226 | case MCH_TT: | ||
227 | masterclock=MASTERCLOCK_TT; | ||
228 | masterprediv=MASTERPREDIV_TT; | ||
229 | break; | ||
230 | case MCH_F30: | ||
231 | case MCH_ARANYM: | ||
232 | masterclock=MASTERCLOCK_FALCON1; | ||
233 | masterprediv=MASTERPREDIV_FALCON; | ||
234 | sfreq=1; | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | MINTAUDIO_freqcount=0; | ||
239 | for (i=sfreq;i<4;i++) { | ||
240 | SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), | ||
241 | masterclock, i-sfreq, -1); | ||
242 | } | ||
243 | |||
244 | #if 1 | ||
245 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
246 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
247 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
248 | MINTAUDIO_frequencies[i].predivisor | ||
249 | )); | ||
250 | } | ||
251 | #endif | ||
252 | |||
253 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
254 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
255 | |||
256 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
257 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
258 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
259 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
260 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
266 | { | ||
267 | SDL_MintAudio_device = this; | ||
268 | |||
269 | /* Check audio capabilities */ | ||
270 | if (Mint_CheckAudio(this, spec)==-1) { | ||
271 | return -1; | ||
272 | } | ||
273 | |||
274 | SDL_CalculateAudioSpec(spec); | ||
275 | |||
276 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
277 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
278 | |||
279 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
280 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
281 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
282 | return (-1); | ||
283 | } | ||
284 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
285 | SDL_MintAudio_numbuf=0; | ||
286 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
287 | SDL_MintAudio_audiosize = spec->size; | ||
288 | SDL_MintAudio_mutex = 0; | ||
289 | |||
290 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
291 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
292 | |||
293 | SDL_MintAudio_CheckFpu(); | ||
294 | |||
295 | /* Set replay tracks */ | ||
296 | if (cookie_snd & SND_16BIT) { | ||
297 | Settracks(0,0); | ||
298 | Setmontracks(0); | ||
299 | } | ||
300 | |||
301 | Supexec(Mint_InitDma); | ||
302 | |||
303 | /* Set interrupt */ | ||
304 | Jdisint(MFP_DMASOUND); | ||
305 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); | ||
306 | Jenabint(MFP_DMASOUND); | ||
307 | |||
308 | if (cookie_snd & SND_16BIT) { | ||
309 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
310 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | Supexec(Mint_StartReplay); | ||
315 | |||
316 | return(1); /* We don't use threaded audio */ | ||
317 | } | ||
318 | |||
319 | /* Functions called in supervisor mode */ | ||
320 | |||
321 | static void Mint_InitDma(void) | ||
322 | { | ||
323 | unsigned long buffer; | ||
324 | unsigned char mode; | ||
325 | SDL_AudioDevice *this = SDL_MintAudio_device; | ||
326 | |||
327 | Mint_StopReplay(); | ||
328 | |||
329 | /* Set buffer */ | ||
330 | buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
331 | DMAAUDIO_IO.start_high = (buffer>>16) & 255; | ||
332 | DMAAUDIO_IO.start_mid = (buffer>>8) & 255; | ||
333 | DMAAUDIO_IO.start_low = buffer & 255; | ||
334 | |||
335 | buffer += SDL_MintAudio_audiosize; | ||
336 | DMAAUDIO_IO.end_high = (buffer>>16) & 255; | ||
337 | DMAAUDIO_IO.end_mid = (buffer>>8) & 255; | ||
338 | DMAAUDIO_IO.end_low = buffer & 255; | ||
339 | |||
340 | mode = 3-MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
341 | if (this->spec.channels==1) { | ||
342 | mode |= 1<<7; | ||
343 | } | ||
344 | DMAAUDIO_IO.sound_ctrl = mode; | ||
345 | } | ||
346 | |||
347 | static void Mint_StopReplay(void) | ||
348 | { | ||
349 | /* Stop replay */ | ||
350 | DMAAUDIO_IO.control=0; | ||
351 | } | ||
352 | |||
353 | static void Mint_StartReplay(void) | ||
354 | { | ||
355 | /* Start replay */ | ||
356 | DMAAUDIO_IO.control=3; | ||
357 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h new file mode 100644 index 0000000000..a52e5db7a5 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | DMA 8bits and Falcon Codec audio definitions | ||
26 | |||
27 | Patrice Mandin, Didier Méquignon | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_dma8_h | ||
31 | #define _SDL_mintaudio_dma8_h | ||
32 | |||
33 | #define DMAAUDIO_IO_BASE (0xffff8900) | ||
34 | struct DMAAUDIO_IO_S { | ||
35 | unsigned char int_ctrl; | ||
36 | unsigned char control; | ||
37 | |||
38 | unsigned char dummy1; | ||
39 | unsigned char start_high; | ||
40 | unsigned char dummy2; | ||
41 | unsigned char start_mid; | ||
42 | unsigned char dummy3; | ||
43 | unsigned char start_low; | ||
44 | |||
45 | unsigned char dummy4; | ||
46 | unsigned char cur_high; | ||
47 | unsigned char dummy5; | ||
48 | unsigned char cur_mid; | ||
49 | unsigned char dummy6; | ||
50 | unsigned char cur_low; | ||
51 | |||
52 | unsigned char dummy7; | ||
53 | unsigned char end_high; | ||
54 | unsigned char dummy8; | ||
55 | unsigned char end_mid; | ||
56 | unsigned char dummy9; | ||
57 | unsigned char end_low; | ||
58 | |||
59 | unsigned char dummy10[12]; | ||
60 | |||
61 | unsigned char track_ctrl; /* CODEC only */ | ||
62 | unsigned char sound_ctrl; | ||
63 | unsigned short sound_data; | ||
64 | unsigned short sound_mask; | ||
65 | |||
66 | unsigned char dummy11[10]; | ||
67 | |||
68 | unsigned short dev_ctrl; | ||
69 | unsigned short dest_ctrl; | ||
70 | unsigned short sync_div; | ||
71 | unsigned char track_rec; | ||
72 | unsigned char adderin_input; | ||
73 | unsigned char channel_input; | ||
74 | unsigned char channel_amplification; | ||
75 | unsigned char channel_reduction; | ||
76 | |||
77 | unsigned char dummy12[6]; | ||
78 | |||
79 | unsigned char data_direction; | ||
80 | unsigned char dummy13; | ||
81 | unsigned char dev_data; | ||
82 | }; | ||
83 | #define DMAAUDIO_IO ((*(volatile struct DMAAUDIO_IO_S *)DMAAUDIO_IO_BASE)) | ||
84 | |||
85 | #endif /* _SDL_mintaudio_dma8_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c new file mode 100644 index 0000000000..8d7716a137 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c | |||
@@ -0,0 +1,436 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (GSXB compatible driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | |||
42 | #include "SDL_mintaudio.h" | ||
43 | #include "SDL_mintaudio_gsxb.h" | ||
44 | |||
45 | /*--- Defines ---*/ | ||
46 | |||
47 | #define MINT_AUDIO_DRIVER_NAME "mint_gsxb" | ||
48 | |||
49 | /* Debug print info */ | ||
50 | #define DEBUG_NAME "audio:gsxb: " | ||
51 | #if 0 | ||
52 | #define DEBUG_PRINT(what) \ | ||
53 | { \ | ||
54 | printf what; \ | ||
55 | } | ||
56 | #else | ||
57 | #define DEBUG_PRINT(what) | ||
58 | #endif | ||
59 | |||
60 | /*--- Static variables ---*/ | ||
61 | |||
62 | static long cookie_snd, cookie_gsxb; | ||
63 | |||
64 | /*--- Audio driver functions ---*/ | ||
65 | |||
66 | static void Mint_CloseAudio(_THIS); | ||
67 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
68 | static void Mint_LockAudio(_THIS); | ||
69 | static void Mint_UnlockAudio(_THIS); | ||
70 | |||
71 | /* To check/init hardware audio */ | ||
72 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
73 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
74 | |||
75 | /* GSXB callbacks */ | ||
76 | static void Mint_GsxbInterrupt(void); | ||
77 | static void Mint_GsxbNullInterrupt(void); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | /* Check if user asked a different audio driver */ | ||
86 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
87 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
88 | return(0); | ||
89 | } | ||
90 | |||
91 | /* Cookie _SND present ? if not, assume ST machine */ | ||
92 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
93 | cookie_snd = SND_PSG; | ||
94 | } | ||
95 | |||
96 | /* Check if we have 16 bits audio */ | ||
97 | if ((cookie_snd & SND_16BIT)==0) { | ||
98 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
99 | return(0); | ||
100 | } | ||
101 | |||
102 | /* Cookie GSXB present ? */ | ||
103 | cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND); | ||
104 | |||
105 | /* Is it GSXB ? */ | ||
106 | if (((cookie_snd & SND_GSXB)==0) || (cookie_gsxb==0)) { | ||
107 | DEBUG_PRINT((DEBUG_NAME "no GSXB audio\n")); | ||
108 | return(0); | ||
109 | } | ||
110 | |||
111 | /* Check if audio is lockable */ | ||
112 | if (Locksnd()!=1) { | ||
113 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
114 | return(0); | ||
115 | } | ||
116 | |||
117 | Unlocksnd(); | ||
118 | |||
119 | DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n")); | ||
120 | return(1); | ||
121 | } | ||
122 | |||
123 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
124 | { | ||
125 | SDL_free(device->hidden); | ||
126 | SDL_free(device); | ||
127 | } | ||
128 | |||
129 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
130 | { | ||
131 | SDL_AudioDevice *this; | ||
132 | |||
133 | /* Initialize all variables that we clean on shutdown */ | ||
134 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
135 | if ( this ) { | ||
136 | SDL_memset(this, 0, (sizeof *this)); | ||
137 | this->hidden = (struct SDL_PrivateAudioData *) | ||
138 | SDL_malloc((sizeof *this->hidden)); | ||
139 | } | ||
140 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
141 | SDL_OutOfMemory(); | ||
142 | if ( this ) { | ||
143 | SDL_free(this); | ||
144 | } | ||
145 | return(0); | ||
146 | } | ||
147 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
148 | |||
149 | /* Set the function pointers */ | ||
150 | this->OpenAudio = Mint_OpenAudio; | ||
151 | this->CloseAudio = Mint_CloseAudio; | ||
152 | this->LockAudio = Mint_LockAudio; | ||
153 | this->UnlockAudio = Mint_UnlockAudio; | ||
154 | this->free = Audio_DeleteDevice; | ||
155 | |||
156 | return this; | ||
157 | } | ||
158 | |||
159 | AudioBootStrap MINTAUDIO_GSXB_bootstrap = { | ||
160 | MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver", | ||
161 | Audio_Available, Audio_CreateDevice | ||
162 | }; | ||
163 | |||
164 | static void Mint_LockAudio(_THIS) | ||
165 | { | ||
166 | /* Stop replay */ | ||
167 | Buffoper(0); | ||
168 | } | ||
169 | |||
170 | static void Mint_UnlockAudio(_THIS) | ||
171 | { | ||
172 | /* Restart replay */ | ||
173 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
174 | } | ||
175 | |||
176 | static void Mint_CloseAudio(_THIS) | ||
177 | { | ||
178 | /* Stop replay */ | ||
179 | Buffoper(0); | ||
180 | |||
181 | /* Uninstall interrupt */ | ||
182 | if (NSetinterrupt(2, SI_NONE, Mint_GsxbNullInterrupt)<0) { | ||
183 | DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n")); | ||
184 | } | ||
185 | |||
186 | /* Wait if currently playing sound */ | ||
187 | while (SDL_MintAudio_mutex != 0) { | ||
188 | } | ||
189 | |||
190 | /* Clear buffers */ | ||
191 | if (SDL_MintAudio_audiobuf[0]) { | ||
192 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
193 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
194 | } | ||
195 | |||
196 | /* Unlock sound system */ | ||
197 | Unlocksnd(); | ||
198 | } | ||
199 | |||
200 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
201 | { | ||
202 | long snd_format = 0; | ||
203 | int i, resolution, format_signed, format_bigendian; | ||
204 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
205 | int valid_datatype = 0; | ||
206 | |||
207 | resolution = spec->format & 0x00ff; | ||
208 | format_signed = ((spec->format & 0x8000)!=0); | ||
209 | format_bigendian = ((spec->format & 0x1000)!=0); | ||
210 | |||
211 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
212 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
213 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
214 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
215 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
216 | |||
217 | if (spec->channels > 2) { | ||
218 | spec->channels = 2; /* no more than stereo! */ | ||
219 | } | ||
220 | |||
221 | while ((!valid_datatype) && (test_format)) { | ||
222 | /* Check formats available */ | ||
223 | snd_format = Sndstatus(SND_QUERYFORMATS); | ||
224 | spec->format = test_format; | ||
225 | resolution = spec->format & 0xff; | ||
226 | format_signed = (spec->format & (1<<15)); | ||
227 | format_bigendian = (spec->format & (1<<12)); | ||
228 | switch (test_format) { | ||
229 | case AUDIO_U8: | ||
230 | case AUDIO_S8: | ||
231 | if (snd_format & SND_FORMAT8) { | ||
232 | valid_datatype = 1; | ||
233 | snd_format = Sndstatus(SND_QUERY8BIT); | ||
234 | } | ||
235 | break; | ||
236 | |||
237 | case AUDIO_U16LSB: | ||
238 | case AUDIO_S16LSB: | ||
239 | case AUDIO_U16MSB: | ||
240 | case AUDIO_S16MSB: | ||
241 | if (snd_format & SND_FORMAT16) { | ||
242 | valid_datatype = 1; | ||
243 | snd_format = Sndstatus(SND_QUERY16BIT); | ||
244 | } | ||
245 | break; | ||
246 | |||
247 | default: | ||
248 | test_format = SDL_NextAudioFormat(); | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | if (!valid_datatype) { | ||
254 | SDL_SetError("Unsupported audio format"); | ||
255 | return (-1); | ||
256 | } | ||
257 | |||
258 | /* Check signed/unsigned format */ | ||
259 | if (format_signed) { | ||
260 | if (snd_format & SND_FORMATSIGNED) { | ||
261 | /* Ok */ | ||
262 | } else if (snd_format & SND_FORMATUNSIGNED) { | ||
263 | /* Give unsigned format */ | ||
264 | spec->format = spec->format & (~0x8000); | ||
265 | } | ||
266 | } else { | ||
267 | if (snd_format & SND_FORMATUNSIGNED) { | ||
268 | /* Ok */ | ||
269 | } else if (snd_format & SND_FORMATSIGNED) { | ||
270 | /* Give signed format */ | ||
271 | spec->format |= 0x8000; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | if (format_bigendian) { | ||
276 | if (snd_format & SND_FORMATBIGENDIAN) { | ||
277 | /* Ok */ | ||
278 | } else if (snd_format & SND_FORMATLITTLEENDIAN) { | ||
279 | /* Give little endian format */ | ||
280 | spec->format = spec->format & (~0x1000); | ||
281 | } | ||
282 | } else { | ||
283 | if (snd_format & SND_FORMATLITTLEENDIAN) { | ||
284 | /* Ok */ | ||
285 | } else if (snd_format & SND_FORMATBIGENDIAN) { | ||
286 | /* Give big endian format */ | ||
287 | spec->format |= 0x1000; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* Calculate and select the closest frequency */ | ||
292 | MINTAUDIO_freqcount=0; | ||
293 | for (i=1;i<4;i++) { | ||
294 | SDL_MintAudio_AddFrequency(this, | ||
295 | MASTERCLOCK_44K/(MASTERPREDIV_MILAN*(1<<i)), MASTERCLOCK_44K, | ||
296 | (1<<i)-1, -1); | ||
297 | } | ||
298 | |||
299 | #if 1 | ||
300 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
301 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
302 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
303 | MINTAUDIO_frequencies[i].predivisor | ||
304 | )); | ||
305 | } | ||
306 | #endif | ||
307 | |||
308 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
309 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
310 | |||
311 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
312 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
313 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
314 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
315 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
321 | { | ||
322 | int channels_mode, prediv; | ||
323 | void *buffer; | ||
324 | |||
325 | /* Stop currently playing sound */ | ||
326 | Buffoper(0); | ||
327 | |||
328 | /* Set replay tracks */ | ||
329 | Settracks(0,0); | ||
330 | Setmontracks(0); | ||
331 | |||
332 | /* Select replay format */ | ||
333 | switch (spec->format & 0xff) { | ||
334 | case 8: | ||
335 | if (spec->channels==2) { | ||
336 | channels_mode=STEREO8; | ||
337 | } else { | ||
338 | channels_mode=MONO8; | ||
339 | } | ||
340 | break; | ||
341 | case 16: | ||
342 | if (spec->channels==2) { | ||
343 | channels_mode=STEREO16; | ||
344 | } else { | ||
345 | channels_mode=MONO16; | ||
346 | } | ||
347 | break; | ||
348 | default: | ||
349 | channels_mode=STEREO16; | ||
350 | break; | ||
351 | } | ||
352 | if (Setmode(channels_mode)<0) { | ||
353 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
354 | } | ||
355 | |||
356 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
357 | Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1); | ||
358 | |||
359 | /* Set buffer */ | ||
360 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
361 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
362 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
363 | } | ||
364 | |||
365 | /* Install interrupt */ | ||
366 | if (NSetinterrupt(2, SI_PLAY, Mint_GsxbInterrupt)<0) { | ||
367 | DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n")); | ||
368 | } | ||
369 | |||
370 | /* Go */ | ||
371 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
372 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
373 | } | ||
374 | |||
375 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
376 | { | ||
377 | /* Lock sound system */ | ||
378 | if (Locksnd()!=1) { | ||
379 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
380 | return(-1); | ||
381 | } | ||
382 | |||
383 | SDL_MintAudio_device = this; | ||
384 | |||
385 | /* Check audio capabilities */ | ||
386 | if (Mint_CheckAudio(this, spec)==-1) { | ||
387 | return -1; | ||
388 | } | ||
389 | |||
390 | SDL_CalculateAudioSpec(spec); | ||
391 | |||
392 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
393 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
394 | |||
395 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
396 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
397 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
398 | return (-1); | ||
399 | } | ||
400 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
401 | SDL_MintAudio_numbuf=0; | ||
402 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
403 | SDL_MintAudio_audiosize = spec->size; | ||
404 | SDL_MintAudio_mutex = 0; | ||
405 | |||
406 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
407 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
408 | |||
409 | SDL_MintAudio_CheckFpu(); | ||
410 | |||
411 | /* Setup audio hardware */ | ||
412 | Mint_InitAudio(this, spec); | ||
413 | |||
414 | return(1); /* We don't use threaded audio */ | ||
415 | } | ||
416 | |||
417 | static void Mint_GsxbInterrupt(void) | ||
418 | { | ||
419 | Uint8 *newbuf; | ||
420 | |||
421 | if (SDL_MintAudio_mutex) | ||
422 | return; | ||
423 | |||
424 | SDL_MintAudio_mutex=1; | ||
425 | |||
426 | SDL_MintAudio_numbuf ^= 1; | ||
427 | SDL_MintAudio_Callback(); | ||
428 | newbuf = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
429 | Setbuffer(0, newbuf, newbuf + SDL_MintAudio_audiosize); | ||
430 | |||
431 | SDL_MintAudio_mutex=0; | ||
432 | } | ||
433 | |||
434 | static void Mint_GsxbNullInterrupt(void) | ||
435 | { | ||
436 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h new file mode 100644 index 0000000000..aee26b7ee3 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | * GSXB audio definitions | ||
26 | * | ||
27 | * Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_gsxb_h | ||
31 | #define _SDL_mintaudio_gsxb_h | ||
32 | |||
33 | #include <mint/falcon.h> /* for trap_14_xxx macros */ | ||
34 | |||
35 | /* Bit 5 in cookie _SND */ | ||
36 | |||
37 | #define SND_GSXB (1<<5) | ||
38 | |||
39 | /* NSoundcmd modes */ | ||
40 | |||
41 | #define SETRATE 7 /* Set sample rate */ | ||
42 | #define SET8BITFORMAT 8 /* 8 bits format */ | ||
43 | #define SET16BITFORMAT 9 /* 16 bits format */ | ||
44 | #define SET24BITFORMAT 10 /* 24 bits format */ | ||
45 | #define SET32BITFORMAT 11 /* 32 bits format */ | ||
46 | #define LTATTEN_MASTER 12 /* Attenuation */ | ||
47 | #define RTATTEN_MASTER 13 | ||
48 | #define LTATTEN_MICIN 14 | ||
49 | #define RTATTEN_MICIN 15 | ||
50 | #define LTATTEN_FMGEN 16 | ||
51 | #define RTATTEN_FMGEN 17 | ||
52 | #define LTATTEN_LINEIN 18 | ||
53 | #define RTATTEN_LINEIN 19 | ||
54 | #define LTATTEN_CDIN 20 | ||
55 | #define RTATTEN_CDIN 21 | ||
56 | #define LTATTEN_VIDIN 22 | ||
57 | #define RTATTEN_VIDIN 23 | ||
58 | #define LTATTEN_AUXIN 24 | ||
59 | #define RTATTEN_AUXIN 25 | ||
60 | |||
61 | /* Setmode modes */ | ||
62 | |||
63 | #define MONO16 3 | ||
64 | #define STEREO24 4 | ||
65 | #define STEREO32 5 | ||
66 | #define MONO24 6 | ||
67 | #define MONO32 7 | ||
68 | |||
69 | /* Sndstatus modes */ | ||
70 | |||
71 | #define SND_QUERYFORMATS 2 | ||
72 | #define SND_QUERYMIXERS 3 | ||
73 | #define SND_QUERYSOURCES 4 | ||
74 | #define SND_QUERYDUPLEX 5 | ||
75 | #define SND_QUERY8BIT 8 | ||
76 | #define SND_QUERY16BIT 9 | ||
77 | #define SND_QUERY24BIT 10 | ||
78 | #define SND_QUERY32BIT 11 | ||
79 | |||
80 | #define SND_FORMAT8 (1<<0) | ||
81 | #define SND_FORMAT16 (1<<1) | ||
82 | #define SND_FORMAT24 (1<<2) | ||
83 | #define SND_FORMAT32 (1<<3) | ||
84 | |||
85 | #define SND_FORMATSIGNED (1<<0) | ||
86 | #define SND_FORMATUNSIGNED (1<<1) | ||
87 | #define SND_FORMATBIGENDIAN (1<<2) | ||
88 | #define SND_FORMATLITTLEENDIAN (1<<3) | ||
89 | |||
90 | /* Devconnect prescalers */ | ||
91 | |||
92 | #define CLK_44K 1 | ||
93 | #define CLK_22K 3 | ||
94 | #define CLK_11K 7 | ||
95 | |||
96 | /* Extra xbios functions */ | ||
97 | |||
98 | #define NSoundcmd(mode,data,data2) \ | ||
99 | (long)trap_14_wwl((short)130,(short)(mode),(short)(data),(long)(data2)) | ||
100 | #define NSetinterrupt(src_inter,cause,inth_addr) \ | ||
101 | (long)trap_14_wwwl((short)135,(short)(src_inter),(short)(cause), \ | ||
102 | (long)(inth_addr)) | ||
103 | |||
104 | #endif /* _SDL_mintaudio_gsxb_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S new file mode 100644 index 0000000000..a2ecac4c65 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | Audio interrupts | ||
25 | |||
26 | Patrice Mandin, Didier Méquignon | ||
27 | */ | ||
28 | |||
29 | .text | ||
30 | |||
31 | .globl _SDL_MintAudio_Callback | ||
32 | |||
33 | .globl _SDL_MintAudio_XbiosInterrupt | ||
34 | .globl _SDL_MintAudio_XbiosInterruptMeasureClock | ||
35 | .globl _SDL_MintAudio_Dma8Interrupt | ||
36 | .globl _SDL_MintAudio_StfaInterrupt | ||
37 | |||
38 | .globl _SDL_MintAudio_mutex | ||
39 | .globl _SDL_MintAudio_audiobuf | ||
40 | .globl _SDL_MintAudio_numbuf | ||
41 | .globl _SDL_MintAudio_audiosize | ||
42 | .globl _SDL_MintAudio_clocktics | ||
43 | .globl _SDL_MintAudio_hasfpu | ||
44 | |||
45 | .globl _SDL_MintAudio_stfa | ||
46 | |||
47 | /* | ||
48 | How it works: | ||
49 | - Audio is playing buffer #0 (resp. #1) | ||
50 | - We must calculate a sample in buffer #1 (resp. #0) | ||
51 | so we first call the callback to do it | ||
52 | - Then we swap the buffers | ||
53 | */ | ||
54 | |||
55 | #define savptr 0x4a2 | ||
56 | #define savamt 0x46 | ||
57 | |||
58 | /*--- Save/restore FPU context ---*/ | ||
59 | |||
60 | #if defined(__mcoldfire__) | ||
61 | |||
62 | #define SAVE_FPU_CONTEXT \ | ||
63 | lea sp@(-216),sp; \ | ||
64 | fsave sp@; \ | ||
65 | fmovel fpiar,sp@-; \ | ||
66 | lea sp@(-64),sp; \ | ||
67 | fmovemd fp0-fp7,sp@ | ||
68 | |||
69 | #define RESTORE_FPU_CONTEXT \ | ||
70 | fmovemd sp@,fp0-fp7; \ | ||
71 | lea sp@(64),sp; \ | ||
72 | fmovel sp@+,fpiar; \ | ||
73 | frestore sp@; \ | ||
74 | lea sp@(216),sp | ||
75 | |||
76 | #else | ||
77 | |||
78 | #define SAVE_FPU_CONTEXT \ | ||
79 | .chip 68k/68881; \ | ||
80 | fsave sp@-; \ | ||
81 | fmoveml fpcr/fpsr/fpiar,sp@-; \ | ||
82 | fmovemx fp0-fp7,sp@-; \ | ||
83 | .chip 68k | ||
84 | |||
85 | #define RESTORE_FPU_CONTEXT \ | ||
86 | .chip 68k/68881; \ | ||
87 | fmovemx sp@+,fp0-fp7; \ | ||
88 | fmoveml sp@+,fpcr/fpsr/fpiar; \ | ||
89 | frestore sp@+; \ | ||
90 | .chip 68k | ||
91 | |||
92 | #endif | ||
93 | |||
94 | /*--- Xbios interrupt vector to measure Falcon external clock ---*/ | ||
95 | |||
96 | _SDL_MintAudio_XbiosInterruptMeasureClock: /* 1 mS */ | ||
97 | #if defined(__mcoldfire__) | ||
98 | movel d0,sp@- | ||
99 | |||
100 | moveql #0,d0 | ||
101 | btst d0,0xFFFF8901:w /* state DMA sound */ | ||
102 | #else | ||
103 | btst #0,0xFFFF8901:w /* state DMA sound */ | ||
104 | #endif | ||
105 | beqs SDL_MintAudio_EndIntMeasure | ||
106 | addql #1,_SDL_MintAudio_clocktics | ||
107 | SDL_MintAudio_EndIntMeasure: | ||
108 | #if defined(__mcoldfire__) | ||
109 | moveql #5,d0 | ||
110 | bclr d0,0xFFFFFA0F:w /* Clear service bit */ | ||
111 | |||
112 | movel sp@+,d0 | ||
113 | #else | ||
114 | bclr #5,0xFFFFFA0F:w /* Clear service bit */ | ||
115 | #endif | ||
116 | rte | ||
117 | |||
118 | /*--- Xbios interrupt vector ---*/ | ||
119 | |||
120 | _SDL_MintAudio_XbiosInterrupt: | ||
121 | #if defined(__mcoldfire__) | ||
122 | lea sp@(-60),sp | ||
123 | moveml d0-d7/a0-a6,sp@ | ||
124 | #else | ||
125 | moveml d0-d7/a0-a6,sp@- | ||
126 | #endif | ||
127 | |||
128 | /* Reenable interrupts, so other interrupts can work */ | ||
129 | movew #0x2300,sr | ||
130 | |||
131 | /* Clear service bit, so other MFP interrupts can work */ | ||
132 | #if defined(__mcoldfire__) | ||
133 | moveql #5,d0 | ||
134 | bclr d0,0xfffffa0f:w | ||
135 | #else | ||
136 | bclr #5,0xfffffa0f:w | ||
137 | #endif | ||
138 | |||
139 | /* Check if we are not already running */ | ||
140 | tstw _SDL_MintAudio_mutex | ||
141 | bne SDL_MintAudio_XbiosEnd | ||
142 | |||
143 | #if defined(__mcoldfire__) | ||
144 | movew _SDL_MintAudio_mutex,d0 | ||
145 | notl d0 | ||
146 | movew d0,_SDL_MintAudio_mutex | ||
147 | |||
148 | movew _SDL_MintAudio_numbuf,d1 | ||
149 | eorl #1,d1 | ||
150 | movew d1,_SDL_MintAudio_numbuf | ||
151 | #else | ||
152 | notw _SDL_MintAudio_mutex | ||
153 | |||
154 | /* Swap buffers */ | ||
155 | eorw #1,_SDL_MintAudio_numbuf | ||
156 | #endif | ||
157 | |||
158 | /* Save FPU if needed */ | ||
159 | tstw _SDL_MintAudio_hasfpu | ||
160 | beqs SDL_MintAudio_Xbios_nofpu1 | ||
161 | SAVE_FPU_CONTEXT | ||
162 | SDL_MintAudio_Xbios_nofpu1: | ||
163 | |||
164 | /* Callback */ | ||
165 | jsr _SDL_MintAudio_Callback | ||
166 | |||
167 | /* Restore FPU if needed */ | ||
168 | tstw _SDL_MintAudio_hasfpu | ||
169 | beqs SDL_MintAudio_Xbios_nofpu2 | ||
170 | RESTORE_FPU_CONTEXT | ||
171 | SDL_MintAudio_Xbios_nofpu2: | ||
172 | |||
173 | /* Reserve space for registers */ | ||
174 | #if defined(__mcoldfire__) | ||
175 | movel #savamt,d0 | ||
176 | subl d0,savptr | ||
177 | #else | ||
178 | subl #savamt,savptr | ||
179 | #endif | ||
180 | |||
181 | /* Set new buffer */ | ||
182 | |||
183 | moveq #0,d0 | ||
184 | movel _SDL_MintAudio_audiosize,d1 | ||
185 | |||
186 | movew _SDL_MintAudio_numbuf,d0 | ||
187 | lsll #2,d0 | ||
188 | lea _SDL_MintAudio_audiobuf,a0 | ||
189 | movel a0@(d0:l),a1 | ||
190 | |||
191 | lea a1@(d1:l),a2 | ||
192 | |||
193 | movel a2,sp@- | ||
194 | movel a1,sp@- | ||
195 | clrw sp@- | ||
196 | movew #131,sp@- | ||
197 | trap #14 | ||
198 | lea sp@(12),sp | ||
199 | |||
200 | /* Restore registers space */ | ||
201 | #if defined(__mcoldfire__) | ||
202 | movel #savamt,d0 | ||
203 | addl d0,savptr | ||
204 | #else | ||
205 | addl #savamt,savptr | ||
206 | #endif | ||
207 | |||
208 | clrw _SDL_MintAudio_mutex | ||
209 | SDL_MintAudio_XbiosEnd: | ||
210 | #if defined(__mcoldfire__) | ||
211 | moveml sp@,d0-d7/a0-a6 | ||
212 | lea sp@(60),sp | ||
213 | #else | ||
214 | moveml sp@+,d0-d7/a0-a6 | ||
215 | #endif | ||
216 | rte | ||
217 | |||
218 | /*--- DMA 8 bits interrupt vector ---*/ | ||
219 | |||
220 | _SDL_MintAudio_Dma8Interrupt: | ||
221 | #if defined(__mcoldfire__) | ||
222 | lea sp@(-16),sp | ||
223 | moveml d0-d1/a0-a1,sp@ | ||
224 | #else | ||
225 | moveml d0-d1/a0-a1,sp@- | ||
226 | #endif | ||
227 | |||
228 | /* Reenable interrupts, so other interrupts can work */ | ||
229 | movew #0x2300,sr | ||
230 | |||
231 | /* Clear service bit, so other MFP interrupts can work */ | ||
232 | #if defined(__mcoldfire__) | ||
233 | moveql #5,d0 | ||
234 | bclr d0,0xfffffa0f:w | ||
235 | #else | ||
236 | bclr #5,0xfffffa0f:w | ||
237 | #endif | ||
238 | /* Check if we are not already running */ | ||
239 | tstw _SDL_MintAudio_mutex | ||
240 | bne SDL_MintAudio_Dma8End | ||
241 | |||
242 | #if defined(__mcoldfire__) | ||
243 | movew _SDL_MintAudio_mutex,d0 | ||
244 | notl d0 | ||
245 | movew d0,_SDL_MintAudio_mutex | ||
246 | |||
247 | movew _SDL_MintAudio_numbuf,d1 | ||
248 | eorl #1,d1 | ||
249 | movew d1,_SDL_MintAudio_numbuf | ||
250 | #else | ||
251 | notw _SDL_MintAudio_mutex | ||
252 | |||
253 | /* Swap buffers */ | ||
254 | eorw #1,_SDL_MintAudio_numbuf | ||
255 | #endif | ||
256 | |||
257 | /* Save FPU if needed */ | ||
258 | tstw _SDL_MintAudio_hasfpu | ||
259 | beqs SDL_MintAudio_Dma8_nofpu1 | ||
260 | SAVE_FPU_CONTEXT | ||
261 | SDL_MintAudio_Dma8_nofpu1: | ||
262 | |||
263 | /* Callback */ | ||
264 | jsr _SDL_MintAudio_Callback | ||
265 | |||
266 | /* Restore FPU if needed */ | ||
267 | tstw _SDL_MintAudio_hasfpu | ||
268 | beqs SDL_MintAudio_Dma8_nofpu2 | ||
269 | RESTORE_FPU_CONTEXT | ||
270 | SDL_MintAudio_Dma8_nofpu2: | ||
271 | |||
272 | /* Set new buffer */ | ||
273 | |||
274 | moveq #0,d0 | ||
275 | |||
276 | movew _SDL_MintAudio_numbuf,d0 | ||
277 | lsll #2,d0 | ||
278 | lea _SDL_MintAudio_audiobuf,a0 | ||
279 | movel a0@(d0:l),d1 | ||
280 | |||
281 | /* Modify DMA addresses */ | ||
282 | lea 0xffff8900:w,a0 | ||
283 | |||
284 | movel d1,d0 | ||
285 | |||
286 | moveb d0,a0@(0x07) /* Start address */ | ||
287 | lsrl #8,d0 | ||
288 | moveb d0,a0@(0x05) | ||
289 | lsrl #8,d0 | ||
290 | moveb d0,a0@(0x03) | ||
291 | |||
292 | addl _SDL_MintAudio_audiosize,d1 | ||
293 | |||
294 | movel d1,d0 | ||
295 | |||
296 | moveb d0,a0@(0x13) /* End address */ | ||
297 | lsrl #8,d0 | ||
298 | moveb d0,a0@(0x11) | ||
299 | lsrl #8,d0 | ||
300 | moveb d0,a0@(0x0f) | ||
301 | |||
302 | clrw _SDL_MintAudio_mutex | ||
303 | SDL_MintAudio_Dma8End: | ||
304 | #if defined(__mcoldfire__) | ||
305 | moveml sp@,d0-d1/a0-a1 | ||
306 | lea sp@(16),sp | ||
307 | #else | ||
308 | moveml sp@+,d0-d1/a0-a1 | ||
309 | #endif | ||
310 | rte | ||
311 | |||
312 | /*--- STFA interrupt vector ---*/ | ||
313 | |||
314 | STFA_SOUND_START = 6 | ||
315 | STFA_SOUND_END = STFA_SOUND_START+8 | ||
316 | |||
317 | _SDL_MintAudio_StfaInterrupt: | ||
318 | /* Reenable interrupts, so other interrupts can work */ | ||
319 | movew #0x2300,sr | ||
320 | |||
321 | /* Check if we are not already running */ | ||
322 | tstw _SDL_MintAudio_mutex | ||
323 | |||
324 | #if defined(__mcoldfire__) | ||
325 | bne SDL_MintAudio_StfaEnd | ||
326 | |||
327 | lea sp@(-60),sp | ||
328 | moveml d0-d7/a0-a6,sp@ | ||
329 | |||
330 | movew _SDL_MintAudio_mutex,d0 | ||
331 | notl d0 | ||
332 | movew d0,_SDL_MintAudio_mutex | ||
333 | |||
334 | movew _SDL_MintAudio_numbuf,d1 | ||
335 | eorl #1,d1 | ||
336 | movew d1,_SDL_MintAudio_numbuf | ||
337 | #else | ||
338 | bnes SDL_MintAudio_StfaEnd | ||
339 | |||
340 | moveml d0-d7/a0-a6,sp@- | ||
341 | |||
342 | notw _SDL_MintAudio_mutex | ||
343 | |||
344 | /* Swap buffers */ | ||
345 | eorw #1,_SDL_MintAudio_numbuf | ||
346 | #endif | ||
347 | |||
348 | /* Save FPU if needed */ | ||
349 | tstw _SDL_MintAudio_hasfpu | ||
350 | beqs SDL_MintAudio_Stfa_nofpu1 | ||
351 | SAVE_FPU_CONTEXT | ||
352 | SDL_MintAudio_Stfa_nofpu1: | ||
353 | |||
354 | /* Callback */ | ||
355 | jsr _SDL_MintAudio_Callback | ||
356 | |||
357 | /* Restore FPU if needed */ | ||
358 | tstw _SDL_MintAudio_hasfpu | ||
359 | beqs SDL_MintAudio_Stfa_nofpu2 | ||
360 | RESTORE_FPU_CONTEXT | ||
361 | SDL_MintAudio_Stfa_nofpu2: | ||
362 | |||
363 | /* Set new buffer */ | ||
364 | |||
365 | moveq #0,d0 | ||
366 | movel _SDL_MintAudio_stfa,a1 | ||
367 | |||
368 | movew _SDL_MintAudio_numbuf,d0 | ||
369 | lsll #2,d0 | ||
370 | lea _SDL_MintAudio_audiobuf,a0 | ||
371 | movel a0@(d0:l),d1 | ||
372 | |||
373 | /* Modify STFA replay buffers */ | ||
374 | movel d1,a1@(STFA_SOUND_START) | ||
375 | addl _SDL_MintAudio_audiosize,d1 | ||
376 | movel d1,a1@(STFA_SOUND_END) | ||
377 | |||
378 | #if defined(__mcoldfire__) | ||
379 | moveml sp@,d0-d7/a0-a6 | ||
380 | lea sp@(60),sp | ||
381 | #else | ||
382 | moveml sp@+,d0-d7/a0-a6 | ||
383 | #endif | ||
384 | clrw _SDL_MintAudio_mutex | ||
385 | SDL_MintAudio_StfaEnd: | ||
386 | rte | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c new file mode 100644 index 0000000000..387609b168 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (MacSound compatible driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | #include <support.h> | ||
32 | |||
33 | /* Mint includes */ | ||
34 | #include <mint/osbind.h> | ||
35 | #include <mint/falcon.h> | ||
36 | #include <mint/cookie.h> | ||
37 | |||
38 | #include "SDL_audio.h" | ||
39 | #include "../SDL_audio_c.h" | ||
40 | #include "../SDL_sysaudio.h" | ||
41 | |||
42 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
43 | |||
44 | #include "SDL_mintaudio.h" | ||
45 | #include "SDL_mintaudio_mcsn.h" | ||
46 | |||
47 | /*--- Defines ---*/ | ||
48 | |||
49 | #define MINT_AUDIO_DRIVER_NAME "mint_mcsn" | ||
50 | |||
51 | /* Debug print info */ | ||
52 | #define DEBUG_NAME "audio:mcsn: " | ||
53 | #if 0 | ||
54 | #define DEBUG_PRINT(what) \ | ||
55 | { \ | ||
56 | printf what; \ | ||
57 | } | ||
58 | #else | ||
59 | #define DEBUG_PRINT(what) | ||
60 | #endif | ||
61 | |||
62 | /*--- Static variables ---*/ | ||
63 | |||
64 | static long cookie_snd, cookie_mch; | ||
65 | static cookie_mcsn_t *cookie_mcsn; | ||
66 | |||
67 | /*--- Audio driver functions ---*/ | ||
68 | |||
69 | static void Mint_CloseAudio(_THIS); | ||
70 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
71 | static void Mint_LockAudio(_THIS); | ||
72 | static void Mint_UnlockAudio(_THIS); | ||
73 | |||
74 | /* To check/init hardware audio */ | ||
75 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
76 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | |||
78 | /*--- Audio driver bootstrap functions ---*/ | ||
79 | |||
80 | static int Audio_Available(void) | ||
81 | { | ||
82 | long dummy; | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); | ||
86 | |||
87 | /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | ||
88 | if (Getcookie(C_MagX, &dummy) == C_FOUND) { | ||
89 | return(0); | ||
90 | } | ||
91 | |||
92 | /* Check if user asked a different audio driver */ | ||
93 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
94 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
95 | return(0); | ||
96 | } | ||
97 | |||
98 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
99 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
100 | cookie_mch = MCH_ST; | ||
101 | } | ||
102 | |||
103 | /* Cookie _SND present ? if not, assume ST machine */ | ||
104 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
105 | cookie_snd = SND_PSG; | ||
106 | } | ||
107 | |||
108 | /* Check if we have 16 bits audio */ | ||
109 | if ((cookie_snd & SND_16BIT)==0) { | ||
110 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
111 | return(0); | ||
112 | } | ||
113 | |||
114 | /* Cookie MCSN present ? */ | ||
115 | if (Getcookie(C_McSn, &dummy) != C_FOUND) { | ||
116 | DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n")); | ||
117 | return(0); | ||
118 | } | ||
119 | cookie_mcsn = (cookie_mcsn_t *) dummy; | ||
120 | |||
121 | /* Check if interrupt at end of replay */ | ||
122 | if (cookie_mcsn->pint == 0) { | ||
123 | DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n")); | ||
124 | return(0); | ||
125 | } | ||
126 | |||
127 | /* Check if audio is lockable */ | ||
128 | if (Locksnd()!=1) { | ||
129 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
130 | return(0); | ||
131 | } | ||
132 | |||
133 | Unlocksnd(); | ||
134 | |||
135 | DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n")); | ||
136 | return(1); | ||
137 | } | ||
138 | |||
139 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
140 | { | ||
141 | SDL_free(device->hidden); | ||
142 | SDL_free(device); | ||
143 | } | ||
144 | |||
145 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
146 | { | ||
147 | SDL_AudioDevice *this; | ||
148 | |||
149 | /* Initialize all variables that we clean on shutdown */ | ||
150 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
151 | if ( this ) { | ||
152 | SDL_memset(this, 0, (sizeof *this)); | ||
153 | this->hidden = (struct SDL_PrivateAudioData *) | ||
154 | SDL_malloc((sizeof *this->hidden)); | ||
155 | } | ||
156 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
157 | SDL_OutOfMemory(); | ||
158 | if ( this ) { | ||
159 | SDL_free(this); | ||
160 | } | ||
161 | return(0); | ||
162 | } | ||
163 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
164 | |||
165 | /* Set the function pointers */ | ||
166 | this->OpenAudio = Mint_OpenAudio; | ||
167 | this->CloseAudio = Mint_CloseAudio; | ||
168 | this->LockAudio = Mint_LockAudio; | ||
169 | this->UnlockAudio = Mint_UnlockAudio; | ||
170 | this->free = Audio_DeleteDevice; | ||
171 | |||
172 | return this; | ||
173 | } | ||
174 | |||
175 | AudioBootStrap MINTAUDIO_MCSN_bootstrap = { | ||
176 | MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", | ||
177 | Audio_Available, Audio_CreateDevice | ||
178 | }; | ||
179 | |||
180 | static void Mint_LockAudio(_THIS) | ||
181 | { | ||
182 | /* Stop replay */ | ||
183 | Buffoper(0); | ||
184 | } | ||
185 | |||
186 | static void Mint_UnlockAudio(_THIS) | ||
187 | { | ||
188 | /* Restart replay */ | ||
189 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
190 | } | ||
191 | |||
192 | static void Mint_CloseAudio(_THIS) | ||
193 | { | ||
194 | /* Stop replay */ | ||
195 | SDL_MintAudio_WaitThread(); | ||
196 | Buffoper(0); | ||
197 | |||
198 | if (!SDL_MintAudio_mint_present) { | ||
199 | /* Uninstall interrupt */ | ||
200 | Jdisint(MFP_DMASOUND); | ||
201 | } | ||
202 | |||
203 | /* Wait if currently playing sound */ | ||
204 | while (SDL_MintAudio_mutex != 0) { | ||
205 | } | ||
206 | |||
207 | /* Clear buffers */ | ||
208 | if (SDL_MintAudio_audiobuf[0]) { | ||
209 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
210 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
211 | } | ||
212 | |||
213 | /* Unlock sound system */ | ||
214 | Unlocksnd(); | ||
215 | } | ||
216 | |||
217 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
218 | { | ||
219 | int i; | ||
220 | unsigned long masterclock, masterprediv; | ||
221 | |||
222 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
223 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
224 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
225 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
226 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
227 | |||
228 | if (spec->channels > 2) { | ||
229 | spec->channels = 2; /* no more than stereo! */ | ||
230 | } | ||
231 | |||
232 | /* Check formats available */ | ||
233 | MINTAUDIO_freqcount=0; | ||
234 | switch(cookie_mcsn->play) { | ||
235 | case MCSN_ST: | ||
236 | spec->channels=1; | ||
237 | spec->format=8; /* FIXME: is it signed or unsigned ? */ | ||
238 | SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1); | ||
239 | break; | ||
240 | case MCSN_TT: /* Also STE, Mega STE */ | ||
241 | spec->format=AUDIO_S8; | ||
242 | masterclock=MASTERCLOCK_STE; | ||
243 | masterprediv=MASTERPREDIV_STE; | ||
244 | if ((cookie_mch>>16)==MCH_TT) { | ||
245 | masterclock=MASTERCLOCK_TT; | ||
246 | masterprediv=MASTERPREDIV_TT; | ||
247 | } | ||
248 | for (i=0; i<4; i++) { | ||
249 | SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), | ||
250 | masterclock, 3-i, -1); | ||
251 | } | ||
252 | break; | ||
253 | case MCSN_FALCON: /* Also Mac */ | ||
254 | for (i=1; i<12; i++) { | ||
255 | /* Remove unusable Falcon codec predivisors */ | ||
256 | if ((i==6) || (i==8) || (i==10)) { | ||
257 | continue; | ||
258 | } | ||
259 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), | ||
260 | CLK25M, i+1, -1); | ||
261 | } | ||
262 | if (cookie_mcsn->res1 != 0) { | ||
263 | for (i=1; i<4; i++) { | ||
264 | SDL_MintAudio_AddFrequency(this, (cookie_mcsn->res1)/(MASTERPREDIV_FALCON*(1<<i)), | ||
265 | CLKEXT, (1<<i)-1, -1); | ||
266 | } | ||
267 | } | ||
268 | spec->format |= 0x8000; /* Audio is always signed */ | ||
269 | if ((spec->format & 0x00ff)==16) { | ||
270 | spec->format |= 0x1000; /* Audio is always big endian */ | ||
271 | spec->channels=2; /* 16 bits always stereo */ | ||
272 | } | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | #if 0 | ||
277 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
278 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
279 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
280 | MINTAUDIO_frequencies[i].predivisor | ||
281 | )); | ||
282 | } | ||
283 | #endif | ||
284 | |||
285 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
286 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
287 | |||
288 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
289 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
290 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
291 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
292 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
298 | { | ||
299 | int channels_mode, prediv, dmaclock; | ||
300 | void *buffer; | ||
301 | |||
302 | /* Stop currently playing sound */ | ||
303 | SDL_MintAudio_quit_thread = SDL_FALSE; | ||
304 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
305 | SDL_MintAudio_WaitThread(); | ||
306 | Buffoper(0); | ||
307 | |||
308 | /* Set replay tracks */ | ||
309 | Settracks(0,0); | ||
310 | Setmontracks(0); | ||
311 | |||
312 | /* Select replay format */ | ||
313 | channels_mode=STEREO16; | ||
314 | switch (spec->format & 0xff) { | ||
315 | case 8: | ||
316 | if (spec->channels==2) { | ||
317 | channels_mode=STEREO8; | ||
318 | } else { | ||
319 | channels_mode=MONO8; | ||
320 | } | ||
321 | break; | ||
322 | } | ||
323 | if (Setmode(channels_mode)<0) { | ||
324 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
325 | } | ||
326 | |||
327 | dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock; | ||
328 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
329 | switch(cookie_mcsn->play) { | ||
330 | case MCSN_TT: | ||
331 | Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1); | ||
332 | Soundcmd(SETPRESCALE, prediv); | ||
333 | DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n")); | ||
334 | break; | ||
335 | case MCSN_FALCON: | ||
336 | Devconnect(DMAPLAY, DAC, dmaclock, prediv, 1); | ||
337 | DEBUG_PRINT((DEBUG_NAME "Falcon prescaler selected\n")); | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | /* Set buffer */ | ||
342 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
343 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
344 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
345 | } | ||
346 | |||
347 | if (SDL_MintAudio_mint_present) { | ||
348 | SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | ||
349 | } else { | ||
350 | /* Install interrupt */ | ||
351 | Jdisint(MFP_DMASOUND); | ||
352 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); | ||
353 | Jenabint(MFP_DMASOUND); | ||
354 | |||
355 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
356 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* Go */ | ||
361 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
362 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
363 | } | ||
364 | |||
365 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
366 | { | ||
367 | /* Lock sound system */ | ||
368 | if (Locksnd()!=1) { | ||
369 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
370 | return(-1); | ||
371 | } | ||
372 | |||
373 | SDL_MintAudio_device = this; | ||
374 | |||
375 | /* Check audio capabilities */ | ||
376 | if (Mint_CheckAudio(this, spec)==-1) { | ||
377 | return -1; | ||
378 | } | ||
379 | |||
380 | SDL_CalculateAudioSpec(spec); | ||
381 | |||
382 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
383 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
384 | |||
385 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
386 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
387 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
388 | return (-1); | ||
389 | } | ||
390 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
391 | SDL_MintAudio_numbuf=0; | ||
392 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
393 | SDL_MintAudio_audiosize = spec->size; | ||
394 | SDL_MintAudio_mutex = 0; | ||
395 | |||
396 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
397 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
398 | |||
399 | SDL_MintAudio_CheckFpu(); | ||
400 | |||
401 | /* Setup audio hardware */ | ||
402 | Mint_InitAudio(this, spec); | ||
403 | |||
404 | return(1); /* We don't use SDL threaded audio */ | ||
405 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h new file mode 100644 index 0000000000..b772fdab03 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MCSN control structure | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_mcsh_h | ||
31 | #define _SDL_mintaudio_mcsh_h | ||
32 | |||
33 | typedef struct { | ||
34 | unsigned short version; /* Version */ | ||
35 | unsigned short size; /* Size of structure */ | ||
36 | |||
37 | unsigned short play; /* Replay capability */ | ||
38 | unsigned short record; /* Record capability */ | ||
39 | unsigned short dsp; /* DSP56K present */ | ||
40 | unsigned short pint; /* Interrupt at end of replay */ | ||
41 | unsigned short rint; /* Interrupt at end of record */ | ||
42 | |||
43 | unsigned long res1; /* Frequency of external clock */ | ||
44 | unsigned long res2; | ||
45 | unsigned long res3; | ||
46 | unsigned long res4; | ||
47 | } cookie_mcsn_t; | ||
48 | |||
49 | enum { | ||
50 | MCSN_ST=0, | ||
51 | MCSN_TT, | ||
52 | MCSN_STE=MCSN_TT, | ||
53 | MCSN_FALCON, | ||
54 | MCSN_MAC=MCSN_FALCON | ||
55 | }; | ||
56 | |||
57 | #define SETSMPFREQ 7 /* Set sample frequency */ | ||
58 | |||
59 | #endif /* _SDL_mintaudio_mcsh_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c new file mode 100644 index 0000000000..4a581e0351 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (STFA driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | #include "../../video/ataricommon/SDL_atarisuper.h" | ||
42 | |||
43 | #include "SDL_mintaudio.h" | ||
44 | #include "SDL_mintaudio_stfa.h" | ||
45 | |||
46 | /*--- Defines ---*/ | ||
47 | |||
48 | #define MINT_AUDIO_DRIVER_NAME "mint_stfa" | ||
49 | |||
50 | /* Debug print info */ | ||
51 | #define DEBUG_NAME "audio:stfa: " | ||
52 | #if 0 | ||
53 | #define DEBUG_PRINT(what) \ | ||
54 | { \ | ||
55 | printf what; \ | ||
56 | } | ||
57 | #else | ||
58 | #define DEBUG_PRINT(what) | ||
59 | #endif | ||
60 | |||
61 | /*--- Static variables ---*/ | ||
62 | |||
63 | static long cookie_snd, cookie_mch; | ||
64 | static cookie_stfa_t *cookie_stfa; | ||
65 | |||
66 | static const int freqs[16]={ | ||
67 | 4995, 6269, 7493, 8192, | ||
68 | 9830, 10971, 12538, 14985, | ||
69 | 16384, 19819, 21943, 24576, | ||
70 | 30720, 32336, 43885, 49152 | ||
71 | }; | ||
72 | |||
73 | /*--- Audio driver functions ---*/ | ||
74 | |||
75 | static void Mint_CloseAudio(_THIS); | ||
76 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | static void Mint_LockAudio(_THIS); | ||
78 | static void Mint_UnlockAudio(_THIS); | ||
79 | |||
80 | /* To check/init hardware audio */ | ||
81 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
82 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
83 | |||
84 | /*--- Audio driver bootstrap functions ---*/ | ||
85 | |||
86 | static int Audio_Available(void) | ||
87 | { | ||
88 | long dummy; | ||
89 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
90 | |||
91 | /* Check if user asked a different audio driver */ | ||
92 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
93 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
94 | return(0); | ||
95 | } | ||
96 | |||
97 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
98 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
99 | cookie_mch = MCH_ST; | ||
100 | } | ||
101 | |||
102 | /* Cookie _SND present ? if not, assume ST machine */ | ||
103 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
104 | cookie_snd = SND_PSG; | ||
105 | } | ||
106 | |||
107 | /* Cookie STFA present ? */ | ||
108 | if (Getcookie(C_STFA, &dummy) != C_FOUND) { | ||
109 | DEBUG_PRINT((DEBUG_NAME "no STFA audio\n")); | ||
110 | return(0); | ||
111 | } | ||
112 | cookie_stfa = (cookie_stfa_t *) dummy; | ||
113 | |||
114 | SDL_MintAudio_stfa = cookie_stfa; | ||
115 | |||
116 | DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); | ||
117 | return(1); | ||
118 | } | ||
119 | |||
120 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
121 | { | ||
122 | SDL_free(device->hidden); | ||
123 | SDL_free(device); | ||
124 | } | ||
125 | |||
126 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
127 | { | ||
128 | SDL_AudioDevice *this; | ||
129 | |||
130 | /* Initialize all variables that we clean on shutdown */ | ||
131 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
132 | if ( this ) { | ||
133 | SDL_memset(this, 0, (sizeof *this)); | ||
134 | this->hidden = (struct SDL_PrivateAudioData *) | ||
135 | SDL_malloc((sizeof *this->hidden)); | ||
136 | } | ||
137 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
138 | SDL_OutOfMemory(); | ||
139 | if ( this ) { | ||
140 | SDL_free(this); | ||
141 | } | ||
142 | return(0); | ||
143 | } | ||
144 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
145 | |||
146 | /* Set the function pointers */ | ||
147 | this->OpenAudio = Mint_OpenAudio; | ||
148 | this->CloseAudio = Mint_CloseAudio; | ||
149 | this->LockAudio = Mint_LockAudio; | ||
150 | this->UnlockAudio = Mint_UnlockAudio; | ||
151 | this->free = Audio_DeleteDevice; | ||
152 | |||
153 | return this; | ||
154 | } | ||
155 | |||
156 | AudioBootStrap MINTAUDIO_STFA_bootstrap = { | ||
157 | MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", | ||
158 | Audio_Available, Audio_CreateDevice | ||
159 | }; | ||
160 | |||
161 | static void Mint_LockAudio(_THIS) | ||
162 | { | ||
163 | void *oldpile; | ||
164 | |||
165 | /* Stop replay */ | ||
166 | oldpile=(void *)Super(0); | ||
167 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
168 | SuperToUser(oldpile); | ||
169 | } | ||
170 | |||
171 | static void Mint_UnlockAudio(_THIS) | ||
172 | { | ||
173 | void *oldpile; | ||
174 | |||
175 | /* Restart replay */ | ||
176 | oldpile=(void *)Super(0); | ||
177 | cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT; | ||
178 | SuperToUser(oldpile); | ||
179 | } | ||
180 | |||
181 | static void Mint_CloseAudio(_THIS) | ||
182 | { | ||
183 | void *oldpile; | ||
184 | |||
185 | /* Stop replay */ | ||
186 | oldpile=(void *)Super(0); | ||
187 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
188 | SuperToUser(oldpile); | ||
189 | |||
190 | /* Wait if currently playing sound */ | ||
191 | while (SDL_MintAudio_mutex != 0) { | ||
192 | } | ||
193 | |||
194 | /* Clear buffers */ | ||
195 | if (SDL_MintAudio_audiobuf[0]) { | ||
196 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
197 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
202 | { | ||
203 | int i; | ||
204 | |||
205 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
206 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
207 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
208 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
209 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
210 | |||
211 | if (spec->channels > 2) { | ||
212 | spec->channels = 2; /* no more than stereo! */ | ||
213 | } | ||
214 | |||
215 | /* Check formats available */ | ||
216 | MINTAUDIO_freqcount=0; | ||
217 | for (i=0;i<16;i++) { | ||
218 | SDL_MintAudio_AddFrequency(this, freqs[i], 0, i, -1); | ||
219 | } | ||
220 | |||
221 | #if 1 | ||
222 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
223 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
224 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
225 | MINTAUDIO_frequencies[i].predivisor | ||
226 | )); | ||
227 | } | ||
228 | #endif | ||
229 | |||
230 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
231 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
232 | |||
233 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
234 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
235 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
236 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
237 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
243 | { | ||
244 | void *buffer; | ||
245 | void *oldpile; | ||
246 | |||
247 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
248 | |||
249 | oldpile=(void *)Super(0); | ||
250 | |||
251 | /* Stop replay */ | ||
252 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
253 | |||
254 | /* Select replay format */ | ||
255 | cookie_stfa->sound_control = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
256 | if ((spec->format & 0xff)==8) { | ||
257 | cookie_stfa->sound_control |= STFA_FORMAT_8BIT; | ||
258 | } else { | ||
259 | cookie_stfa->sound_control |= STFA_FORMAT_16BIT; | ||
260 | } | ||
261 | if (spec->channels==2) { | ||
262 | cookie_stfa->sound_control |= STFA_FORMAT_STEREO; | ||
263 | } else { | ||
264 | cookie_stfa->sound_control |= STFA_FORMAT_MONO; | ||
265 | } | ||
266 | if ((spec->format & 0x8000)!=0) { | ||
267 | cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; | ||
268 | } else { | ||
269 | cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; | ||
270 | } | ||
271 | if ((spec->format & 0x1000)!=0) { | ||
272 | cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; | ||
273 | } else { | ||
274 | cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; | ||
275 | } | ||
276 | |||
277 | /* Set buffer */ | ||
278 | cookie_stfa->sound_start = (unsigned long) buffer; | ||
279 | cookie_stfa->sound_end = (unsigned long) (buffer + spec->size); | ||
280 | |||
281 | /* Set interrupt */ | ||
282 | cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; | ||
283 | |||
284 | /* Restart replay */ | ||
285 | cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT; | ||
286 | |||
287 | SuperToUser(oldpile); | ||
288 | |||
289 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
290 | } | ||
291 | |||
292 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
293 | { | ||
294 | SDL_MintAudio_device = this; | ||
295 | |||
296 | /* Check audio capabilities */ | ||
297 | if (Mint_CheckAudio(this, spec)==-1) { | ||
298 | return -1; | ||
299 | } | ||
300 | |||
301 | SDL_CalculateAudioSpec(spec); | ||
302 | |||
303 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
304 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
305 | |||
306 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
307 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
308 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
309 | return (-1); | ||
310 | } | ||
311 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
312 | SDL_MintAudio_numbuf=0; | ||
313 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
314 | SDL_MintAudio_audiosize = spec->size; | ||
315 | SDL_MintAudio_mutex = 0; | ||
316 | |||
317 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
318 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
319 | |||
320 | SDL_MintAudio_CheckFpu(); | ||
321 | |||
322 | /* Setup audio hardware */ | ||
323 | Mint_InitAudio(this, spec); | ||
324 | |||
325 | return(1); /* We don't use threaded audio */ | ||
326 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h new file mode 100644 index 0000000000..1789b4bb41 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | STFA control structure | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_stfa_h | ||
31 | #define _SDL_mintaudio_stfa_h | ||
32 | |||
33 | /*--- Defines ---*/ | ||
34 | |||
35 | #define STFA_PLAY_ENABLE (1<<0) | ||
36 | #define STFA_PLAY_DISABLE (0<<0) | ||
37 | #define STFA_PLAY_REPEAT (1<<1) | ||
38 | #define STFA_PLAY_SINGLE (0<<1) | ||
39 | |||
40 | #define STFA_FORMAT_SIGNED (1<<15) | ||
41 | #define STFA_FORMAT_UNSIGNED (0<<15) | ||
42 | #define STFA_FORMAT_STEREO (1<<14) | ||
43 | #define STFA_FORMAT_MONO (0<<14) | ||
44 | #define STFA_FORMAT_16BIT (1<<13) | ||
45 | #define STFA_FORMAT_8BIT (0<<13) | ||
46 | #define STFA_FORMAT_LITENDIAN (1<<9) | ||
47 | #define STFA_FORMAT_BIGENDIAN (0<<9) | ||
48 | #define STFA_FORMAT_FREQ_MASK 0x0f | ||
49 | enum { | ||
50 | STFA_FORMAT_F4995=0, | ||
51 | STFA_FORMAT_F6269, | ||
52 | STFA_FORMAT_F7493, | ||
53 | STFA_FORMAT_F8192, | ||
54 | |||
55 | STFA_FORMAT_F9830, | ||
56 | STFA_FORMAT_F10971, | ||
57 | STFA_FORMAT_F12538, | ||
58 | STFA_FORMAT_F14985, | ||
59 | |||
60 | STFA_FORMAT_F16384, | ||
61 | STFA_FORMAT_F19819, | ||
62 | STFA_FORMAT_F21943, | ||
63 | STFA_FORMAT_F24576, | ||
64 | |||
65 | STFA_FORMAT_F30720, | ||
66 | STFA_FORMAT_F32336, | ||
67 | STFA_FORMAT_F43885, | ||
68 | STFA_FORMAT_F49152 | ||
69 | }; | ||
70 | |||
71 | /*--- Types ---*/ | ||
72 | |||
73 | typedef struct { | ||
74 | unsigned short sound_enable; | ||
75 | unsigned short sound_control; | ||
76 | unsigned short sound_output; | ||
77 | unsigned long sound_start; | ||
78 | unsigned long sound_current; | ||
79 | unsigned long sound_end; | ||
80 | unsigned short version; | ||
81 | void *old_vbl; | ||
82 | void *old_timera; | ||
83 | unsigned long old_mfp_status; | ||
84 | void *new_vbl; | ||
85 | void *drivers_list; | ||
86 | void *play_stop; | ||
87 | unsigned short frequency; | ||
88 | void *set_frequency; | ||
89 | unsigned short frequency_threshold; | ||
90 | unsigned short *custom_freq_table; | ||
91 | unsigned short stfa_on_off; | ||
92 | void *new_drivers_list; | ||
93 | unsigned long old_bit_2_of_cookie_snd; | ||
94 | void (*stfa_it)(void); | ||
95 | } cookie_stfa_t; | ||
96 | |||
97 | #endif /* _SDL_mintaudio_stfa_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c new file mode 100644 index 0000000000..42a0d4a2f9 --- /dev/null +++ b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c | |||
@@ -0,0 +1,490 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (Falcon) | ||
27 | |||
28 | Patrice Mandin, Didier Méquignon | ||
29 | */ | ||
30 | |||
31 | #include <unistd.h> | ||
32 | #include <support.h> | ||
33 | |||
34 | /* Mint includes */ | ||
35 | #include <mint/osbind.h> | ||
36 | #include <mint/falcon.h> | ||
37 | #include <mint/cookie.h> | ||
38 | |||
39 | #include "SDL_audio.h" | ||
40 | #include "../SDL_audio_c.h" | ||
41 | #include "../SDL_sysaudio.h" | ||
42 | |||
43 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
44 | #include "../../video/ataricommon/SDL_atarisuper.h" | ||
45 | |||
46 | #include "SDL_mintaudio.h" | ||
47 | #include "SDL_mintaudio_dma8.h" | ||
48 | |||
49 | /*--- Defines ---*/ | ||
50 | |||
51 | #define MINT_AUDIO_DRIVER_NAME "mint_xbios" | ||
52 | |||
53 | /* Debug print info */ | ||
54 | #define DEBUG_NAME "audio:xbios: " | ||
55 | #if 0 | ||
56 | #define DEBUG_PRINT(what) \ | ||
57 | { \ | ||
58 | printf what; \ | ||
59 | } | ||
60 | #else | ||
61 | #define DEBUG_PRINT(what) | ||
62 | #endif | ||
63 | |||
64 | /*--- Static variables ---*/ | ||
65 | |||
66 | static long cookie_snd; | ||
67 | |||
68 | /*--- Audio driver functions ---*/ | ||
69 | |||
70 | static void Mint_CloseAudio(_THIS); | ||
71 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
72 | static void Mint_LockAudio(_THIS); | ||
73 | static void Mint_UnlockAudio(_THIS); | ||
74 | |||
75 | /* To check/init hardware audio */ | ||
76 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | /* unsigned long dummy;*/ | ||
84 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
85 | |||
86 | /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);*/ | ||
87 | SDL_MintAudio_mint_present = SDL_FALSE; | ||
88 | |||
89 | /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | ||
90 | /*if (Getcookie(C_MagX, &dummy) == C_FOUND) { | ||
91 | return(0); | ||
92 | }*/ | ||
93 | |||
94 | /* Check if user asked a different audio driver */ | ||
95 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
96 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
97 | return(0); | ||
98 | } | ||
99 | |||
100 | /* Cookie _SND present ? if not, assume ST machine */ | ||
101 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
102 | cookie_snd = SND_PSG; | ||
103 | } | ||
104 | |||
105 | /* Check if we have 16 bits audio */ | ||
106 | if ((cookie_snd & SND_16BIT)==0) { | ||
107 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
108 | return(0); | ||
109 | } | ||
110 | |||
111 | /* Check if audio is lockable */ | ||
112 | if (Locksnd()!=1) { | ||
113 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
114 | return(0); | ||
115 | } | ||
116 | |||
117 | Unlocksnd(); | ||
118 | |||
119 | DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n")); | ||
120 | return(1); | ||
121 | } | ||
122 | |||
123 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
124 | { | ||
125 | SDL_free(device->hidden); | ||
126 | SDL_free(device); | ||
127 | } | ||
128 | |||
129 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
130 | { | ||
131 | SDL_AudioDevice *this; | ||
132 | |||
133 | /* Initialize all variables that we clean on shutdown */ | ||
134 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
135 | if ( this ) { | ||
136 | SDL_memset(this, 0, (sizeof *this)); | ||
137 | this->hidden = (struct SDL_PrivateAudioData *) | ||
138 | SDL_malloc((sizeof *this->hidden)); | ||
139 | } | ||
140 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
141 | SDL_OutOfMemory(); | ||
142 | if ( this ) { | ||
143 | SDL_free(this); | ||
144 | } | ||
145 | return(0); | ||
146 | } | ||
147 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
148 | |||
149 | /* Set the function pointers */ | ||
150 | this->OpenAudio = Mint_OpenAudio; | ||
151 | this->CloseAudio = Mint_CloseAudio; | ||
152 | this->LockAudio = Mint_LockAudio; | ||
153 | this->UnlockAudio = Mint_UnlockAudio; | ||
154 | this->free = Audio_DeleteDevice; | ||
155 | |||
156 | return this; | ||
157 | } | ||
158 | |||
159 | AudioBootStrap MINTAUDIO_XBIOS_bootstrap = { | ||
160 | MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver", | ||
161 | Audio_Available, Audio_CreateDevice | ||
162 | }; | ||
163 | |||
164 | static void Mint_LockAudio(_THIS) | ||
165 | { | ||
166 | /* Stop replay */ | ||
167 | Buffoper(0); | ||
168 | } | ||
169 | |||
170 | static void Mint_UnlockAudio(_THIS) | ||
171 | { | ||
172 | /* Restart replay */ | ||
173 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
174 | } | ||
175 | |||
176 | static void Mint_CloseAudio(_THIS) | ||
177 | { | ||
178 | /* Stop replay */ | ||
179 | SDL_MintAudio_WaitThread(); | ||
180 | Buffoper(0); | ||
181 | |||
182 | if (!SDL_MintAudio_mint_present) { | ||
183 | /* Uninstall interrupt */ | ||
184 | Jdisint(MFP_DMASOUND); | ||
185 | } | ||
186 | |||
187 | /* Wait if currently playing sound */ | ||
188 | while (SDL_MintAudio_mutex != 0) { | ||
189 | } | ||
190 | |||
191 | /* Clear buffers */ | ||
192 | if (SDL_MintAudio_audiobuf[0]) { | ||
193 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
194 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
195 | } | ||
196 | |||
197 | /* Unlock sound system */ | ||
198 | Unlocksnd(); | ||
199 | } | ||
200 | |||
201 | /* Falcon XBIOS implementation of Devconnect() is buggy with external clock */ | ||
202 | static void Devconnect2(int src, int dst, int sclk, int pre) | ||
203 | { | ||
204 | static const unsigned short MASK1[3] = { 0, 0x6000, 0 }; | ||
205 | static const unsigned short MASK2[4] = { 0xFFF0, 0xFF8F, 0xF0FF, 0x0FFF }; | ||
206 | static const unsigned short INDEX1[4] = { 1, 3, 5, 7 }; | ||
207 | static const unsigned short INDEX2[4] = { 0, 2, 4, 6 }; | ||
208 | unsigned short sync_div,dev_ctrl,dest_ctrl; | ||
209 | void *oldstack; | ||
210 | |||
211 | if (dst==0) { | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | oldstack=(void *)Super(0); | ||
216 | |||
217 | dev_ctrl = DMAAUDIO_IO.dev_ctrl; | ||
218 | dest_ctrl = DMAAUDIO_IO.dest_ctrl; | ||
219 | dev_ctrl &= MASK2[src]; | ||
220 | |||
221 | if (src==ADC) { | ||
222 | dev_ctrl |= MASK1[sclk]; | ||
223 | } else { | ||
224 | dev_ctrl |= (INDEX1[sclk] << (src<<4)); | ||
225 | } | ||
226 | |||
227 | if (dst & DMAREC) { | ||
228 | dest_ctrl &= 0xFFF0; | ||
229 | dest_ctrl |= INDEX1[src]; | ||
230 | } | ||
231 | |||
232 | if (dst & DSPRECV) { | ||
233 | dest_ctrl &= 0xFF8F; | ||
234 | dest_ctrl |= (INDEX1[src]<<4); | ||
235 | } | ||
236 | |||
237 | if (dst & EXTOUT) { | ||
238 | dest_ctrl &= 0xF0FF; | ||
239 | dest_ctrl |= (INDEX1[src]<<8); | ||
240 | } | ||
241 | |||
242 | if (dst & DAC) { | ||
243 | dev_ctrl &= 0x0FFF; | ||
244 | dev_ctrl |= MASK1[sclk]; | ||
245 | dest_ctrl &= 0x0FFF; | ||
246 | dest_ctrl |= (INDEX2[src]<<12); | ||
247 | } | ||
248 | |||
249 | sync_div = DMAAUDIO_IO.sync_div; | ||
250 | if (sclk==CLKEXT) { | ||
251 | pre<<=8; | ||
252 | sync_div &= 0xF0FF; | ||
253 | } else { | ||
254 | sync_div &= 0xFFF0; | ||
255 | } | ||
256 | sync_div |= pre; | ||
257 | |||
258 | DMAAUDIO_IO.dev_ctrl = dev_ctrl; | ||
259 | DMAAUDIO_IO.dest_ctrl = dest_ctrl; | ||
260 | DMAAUDIO_IO.sync_div = sync_div; | ||
261 | |||
262 | SuperToUser(oldstack); | ||
263 | } | ||
264 | |||
265 | static void Mint_CheckExternalClock(_THIS) | ||
266 | { | ||
267 | #define SIZE_BUF_CLOCK_MEASURE (44100/10) | ||
268 | |||
269 | char *buffer; | ||
270 | int i, j; | ||
271 | |||
272 | /* DSP present with its GPIO port ? */ | ||
273 | if ((cookie_snd & SND_DSP)==0) { | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | buffer = Atari_SysMalloc(SIZE_BUF_CLOCK_MEASURE, MX_STRAM); | ||
278 | if (buffer==NULL) { | ||
279 | DEBUG_PRINT((DEBUG_NAME "Not enough memory for the measure\n")); | ||
280 | return; | ||
281 | } | ||
282 | SDL_memset(buffer, 0, SIZE_BUF_CLOCK_MEASURE); | ||
283 | |||
284 | Buffoper(0); | ||
285 | Settracks(0,0); | ||
286 | Setmontracks(0); | ||
287 | Setmode(MONO8); | ||
288 | Jdisint(MFP_TIMERA); | ||
289 | |||
290 | for (i=0; i<2; i++) { | ||
291 | Gpio(GPIO_SET,7); /* DSP port gpio outputs */ | ||
292 | Gpio(GPIO_WRITE,2+i); /* 22.5792/24.576 MHz for 44.1/48KHz */ | ||
293 | Devconnect2(DMAPLAY, DAC, CLKEXT, CLK50K); /* Matrix and clock source */ | ||
294 | Setbuffer(0, buffer, buffer + SIZE_BUF_CLOCK_MEASURE); /* Set buffer */ | ||
295 | Xbtimer(XB_TIMERA, 5, 38, SDL_MintAudio_XbiosInterruptMeasureClock); /* delay mode timer A, prediv /64, 1KHz */ | ||
296 | Jenabint(MFP_TIMERA); | ||
297 | SDL_MintAudio_clocktics = 0; | ||
298 | Buffoper(SB_PLA_ENA); | ||
299 | usleep(110000); | ||
300 | |||
301 | if((Buffoper(-1) & 1)==0) { | ||
302 | if (SDL_MintAudio_clocktics) { | ||
303 | unsigned long khz; | ||
304 | |||
305 | khz = ((SIZE_BUF_CLOCK_MEASURE/SDL_MintAudio_clocktics) +1) & 0xFFFFFFFE; | ||
306 | DEBUG_PRINT((DEBUG_NAME "measure %d: freq=%lu KHz\n", i+1, khz)); | ||
307 | |||
308 | if(khz==44) { | ||
309 | for (j=1; j<4; j++) { | ||
310 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_44K/(MASTERPREDIV_FALCON*(1<<j)), MASTERCLOCK_44K, (1<<j)-1, 2+i); | ||
311 | } | ||
312 | } else if (khz==48) { | ||
313 | for (j=1; j<4; j++) { | ||
314 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_48K/(MASTERPREDIV_FALCON*(1<<j)), MASTERCLOCK_48K, (1<<j)-1, 2+i); | ||
315 | } | ||
316 | } | ||
317 | } else { | ||
318 | DEBUG_PRINT((DEBUG_NAME "No measure\n")); | ||
319 | } | ||
320 | } else { | ||
321 | DEBUG_PRINT((DEBUG_NAME "No SDMA clock\n")); | ||
322 | } | ||
323 | |||
324 | Buffoper(0); /* stop */ | ||
325 | Jdisint(MFP_TIMERA); /* Uninstall interrupt */ | ||
326 | } | ||
327 | |||
328 | Mfree(buffer); | ||
329 | } | ||
330 | |||
331 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
332 | { | ||
333 | int i; | ||
334 | |||
335 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
336 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
337 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
338 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
339 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
340 | |||
341 | if (spec->channels > 2) { | ||
342 | spec->channels = 2; /* no more than stereo! */ | ||
343 | } | ||
344 | |||
345 | spec->format |= 0x8000; /* Audio is always signed */ | ||
346 | if ((spec->format & 0x00ff)==16) { | ||
347 | spec->format |= 0x1000; /* Audio is always big endian */ | ||
348 | spec->channels=2; /* 16 bits always stereo */ | ||
349 | } | ||
350 | |||
351 | MINTAUDIO_freqcount=0; | ||
352 | |||
353 | /* Add external clocks if present */ | ||
354 | Mint_CheckExternalClock(this); | ||
355 | |||
356 | /* Standard clocks */ | ||
357 | for (i=1;i<12;i++) { | ||
358 | /* Remove unusable Falcon codec predivisors */ | ||
359 | if ((i==6) || (i==8) || (i==10)) { | ||
360 | continue; | ||
361 | } | ||
362 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), MASTERCLOCK_FALCON1, i, -1); | ||
363 | } | ||
364 | |||
365 | #if 1 | ||
366 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
367 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
368 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
369 | MINTAUDIO_frequencies[i].predivisor | ||
370 | )); | ||
371 | } | ||
372 | #endif | ||
373 | |||
374 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
375 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
376 | |||
377 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
378 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
379 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
380 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
381 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
387 | { | ||
388 | int channels_mode, prediv; | ||
389 | void *buffer; | ||
390 | |||
391 | /* Stop currently playing sound */ | ||
392 | SDL_MintAudio_quit_thread = SDL_FALSE; | ||
393 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
394 | SDL_MintAudio_WaitThread(); | ||
395 | Buffoper(0); | ||
396 | |||
397 | /* Set replay tracks */ | ||
398 | Settracks(0,0); | ||
399 | Setmontracks(0); | ||
400 | |||
401 | /* Select replay format */ | ||
402 | channels_mode=STEREO16; | ||
403 | switch (spec->format & 0xff) { | ||
404 | case 8: | ||
405 | if (spec->channels==2) { | ||
406 | channels_mode=STEREO8; | ||
407 | } else { | ||
408 | channels_mode=MONO8; | ||
409 | } | ||
410 | break; | ||
411 | } | ||
412 | if (Setmode(channels_mode)<0) { | ||
413 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
414 | } | ||
415 | |||
416 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
417 | if (MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits != -1) { | ||
418 | Gpio(GPIO_SET,7); /* DSP port gpio outputs */ | ||
419 | Gpio(GPIO_WRITE, MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits); | ||
420 | Devconnect2(DMAPLAY, DAC|EXTOUT, CLKEXT, prediv); | ||
421 | } else { | ||
422 | Devconnect2(DMAPLAY, DAC, CLK25M, prediv); | ||
423 | } | ||
424 | |||
425 | /* Set buffer */ | ||
426 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
427 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
428 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
429 | } | ||
430 | |||
431 | if (SDL_MintAudio_mint_present) { | ||
432 | SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | ||
433 | } else { | ||
434 | /* Install interrupt */ | ||
435 | Jdisint(MFP_DMASOUND); | ||
436 | /*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);*/ | ||
437 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); | ||
438 | Jenabint(MFP_DMASOUND); | ||
439 | |||
440 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
441 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* Go */ | ||
446 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
447 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
448 | } | ||
449 | |||
450 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
451 | { | ||
452 | /* Lock sound system */ | ||
453 | if (Locksnd()!=1) { | ||
454 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
455 | return(-1); | ||
456 | } | ||
457 | |||
458 | SDL_MintAudio_device = this; | ||
459 | |||
460 | /* Check audio capabilities */ | ||
461 | if (Mint_CheckAudio(this, spec)==-1) { | ||
462 | return -1; | ||
463 | } | ||
464 | |||
465 | SDL_CalculateAudioSpec(spec); | ||
466 | |||
467 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
468 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
469 | |||
470 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
471 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
472 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
473 | return (-1); | ||
474 | } | ||
475 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
476 | SDL_MintAudio_numbuf=0; | ||
477 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
478 | SDL_MintAudio_audiosize = spec->size; | ||
479 | SDL_MintAudio_mutex = 0; | ||
480 | |||
481 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
482 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
483 | |||
484 | SDL_MintAudio_CheckFpu(); | ||
485 | |||
486 | /* Setup audio hardware */ | ||
487 | Mint_InitAudio(this, spec); | ||
488 | |||
489 | return(1); /* We don't use SDL threaded audio */ | ||
490 | } | ||