atari: Do not use system interrupt for handling audio. Do it from userspace, like RISCOS backend. SDL-1.2
authorPatrice Mandin <patmandin@gmail.com>
Mon, 28 Jul 2014 21:15:42 +0200
branchSDL-1.2
changeset 9022 de368e497138
parent 9021 1691f05e9531
child 9024 372ca9a5be7c
atari: Do not use system interrupt for handling audio. Do it from userspace, like RISCOS backend.
src/audio/mint/SDL_mintaudio.c
src/audio/mint/SDL_mintaudio.h
src/audio/mint/SDL_mintaudio_dma8.c
src/audio/mint/SDL_mintaudio_gsxb.c
src/audio/mint/SDL_mintaudio_it.S
src/audio/mint/SDL_mintaudio_mcsn.c
src/audio/mint/SDL_mintaudio_stfa.c
src/audio/mint/SDL_mintaudio_xbios.c
src/video/ataricommon/SDL_atarievents.c
--- a/src/audio/mint/SDL_mintaudio.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio.c	Mon Jul 28 21:15:42 2014 +0200
@@ -35,19 +35,24 @@
 #include <mint/cookie.h>
 
 #include "SDL_audio.h"
+#include "../SDL_audio_c.h"
+#include "../SDL_sysaudio.h"
+
+#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
+
 #include "SDL_mintaudio.h"
-#include "SDL_mintaudio_stfa.h"
 
 /* The audio device */
 
+#define MAX_DMA_BUF	8
+
 SDL_AudioDevice *SDL_MintAudio_device;
-Uint8 *SDL_MintAudio_audiobuf[2];	/* Pointers to buffers */
-unsigned long SDL_MintAudio_audiosize;		/* Length of audio buffer=spec->size */
-volatile unsigned short SDL_MintAudio_numbuf;		/* Buffer to play */
-volatile unsigned short SDL_MintAudio_mutex;
-volatile unsigned long SDL_MintAudio_clocktics;
-cookie_stfa_t	*SDL_MintAudio_stfa;
-unsigned short SDL_MintAudio_hasfpu;
+
+static int SDL_MintAudio_num_upd;	/* Number of calls to update function */
+static int SDL_MintAudio_max_buf;	/* Number of buffers to use */
+static int SDL_MintAudio_numbuf;	/* Buffer to play */
+
+static void SDL_MintAudio_Callback(void);
 
 /* MiNT thread variables */
 SDL_bool SDL_MintAudio_mint_present;
@@ -55,34 +60,129 @@
 SDL_bool SDL_MintAudio_thread_finished;
 long SDL_MintAudio_thread_pid;
 
+/* Debug print info */
+#define DEBUG_NAME "audio:mint: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/* Initialize DMA buffers */
+
+int SDL_MintAudio_InitBuffers(SDL_AudioSpec *spec)
+{
+	SDL_AudioDevice *this = SDL_MintAudio_device;
+
+	SDL_CalculateAudioSpec(spec);
+	MINTAUDIO_audiosize = spec->size * MAX_DMA_BUF;
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	MINTAUDIO_audiobuf[0] = Atari_SysMalloc(2 * MINTAUDIO_audiosize, MX_STRAM);
+	if (MINTAUDIO_audiobuf[0]==NULL) {
+		SDL_SetError("SDL_MintAudio_OpenAudio: Not enough memory for audio buffer");
+		return (0);
+	}
+	MINTAUDIO_audiobuf[1] = MINTAUDIO_audiobuf[0] + MINTAUDIO_audiosize;
+	SDL_memset(MINTAUDIO_audiobuf[0], spec->silence, 2 * MINTAUDIO_audiosize);
+
+	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%p\n", MINTAUDIO_audiobuf[0]));
+	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%p\n", MINTAUDIO_audiobuf[1]));
+
+	SDL_MintAudio_numbuf = SDL_MintAudio_num_its = SDL_MintAudio_num_upd = 0;
+	SDL_MintAudio_max_buf = MAX_DMA_BUF;
+
+	return (1);
+}
+
+/* Destroy DMA buffers */
+
+void SDL_MintAudio_FreeBuffers(void)
+{
+	SDL_AudioDevice *this = SDL_MintAudio_device;
+
+	if (MINTAUDIO_audiobuf[0]) {
+		Mfree(MINTAUDIO_audiobuf[0]);
+		MINTAUDIO_audiobuf[0] = MINTAUDIO_audiobuf[1] = NULL;
+	}
+}
+
+/* Update buffers */
+
+void SDL_AtariMint_UpdateAudio(void)
+{
+	SDL_AudioDevice *this = SDL_MintAudio_device;
+
+	++SDL_MintAudio_num_upd;
+
+	/* No interrupt triggered? still playing current buffer */
+	if (SDL_MintAudio_num_its==0) {
+		return;
+	}
+
+	if (SDL_MintAudio_num_upd < (SDL_MintAudio_num_its<<2)) {
+		/* Too many interrupts per update, increase latency */
+		if (SDL_MintAudio_max_buf < MAX_DMA_BUF) {
+			SDL_MintAudio_max_buf <<= 1;
+		}
+	} else if (SDL_MintAudio_num_its < (SDL_MintAudio_num_upd<<2)) {
+		/* Too many updates per interrupt, decrease latency */
+		if (SDL_MintAudio_max_buf > 1) {
+			SDL_MintAudio_max_buf >>= 1;
+		}
+	}
+	MINTAUDIO_audiosize = this->spec.size * SDL_MintAudio_max_buf;
+
+	SDL_MintAudio_num_its = 0;
+	SDL_MintAudio_num_upd = 0;
+
+	SDL_MintAudio_numbuf ^= 1;
+
+	/* Fill new buffer */
+	SDL_MintAudio_Callback();
+
+	/* And swap to it */
+	(*MINTAUDIO_swapbuf)(MINTAUDIO_audiobuf[SDL_MintAudio_numbuf], MINTAUDIO_audiosize);
+}
+
 /* The callback function, called by each driver whenever needed */
 
-void SDL_MintAudio_Callback(void)
+static void SDL_MintAudio_Callback(void)
 {
+	SDL_AudioDevice *this = SDL_MintAudio_device;
 	Uint8 *buffer;
-	SDL_AudioDevice *audio = SDL_MintAudio_device;
+	int i;
 
- 	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	SDL_memset(buffer, audio->spec.silence, audio->spec.size);
+ 	buffer = MINTAUDIO_audiobuf[SDL_MintAudio_numbuf];
+	SDL_memset(buffer, this->spec.silence, this->spec.size * SDL_MintAudio_max_buf);
 
-	if (audio->paused)
+	if (this->paused)
 		return;
 
-	if (audio->convert.needed) {
-		int silence;
+	for (i=0; i<SDL_MintAudio_max_buf; i++) {
+		if (this->convert.needed) {
+			int silence;
 
-		if ( audio->convert.src_format == AUDIO_U8 ) {
-			silence = 0x80;
+			if ( this->convert.src_format == AUDIO_U8 ) {
+				silence = 0x80;
+			} else {
+				silence = 0;
+			}
+			SDL_memset(this->convert.buf, silence, this->convert.len);
+			this->spec.callback(this->spec.userdata,
+				(Uint8 *)this->convert.buf,this->convert.len);
+			SDL_ConvertAudio(&this->convert);
+			SDL_memcpy(buffer, this->convert.buf, this->convert.len_cvt);
+
+			buffer += this->convert.len_cvt;
 		} else {
-			silence = 0;
+			this->spec.callback(this->spec.userdata, buffer, this->spec.size);
+
+			buffer += this->spec.size;
 		}
-		SDL_memset(audio->convert.buf, silence, audio->convert.len);
-		audio->spec.callback(audio->spec.userdata,
-			(Uint8 *)audio->convert.buf,audio->convert.len);
-		SDL_ConvertAudio(&audio->convert);
-		SDL_memcpy(buffer, audio->convert.buf, audio->convert.len_cvt);
-	} else {
-		audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size);
 	}
 }
 
@@ -141,45 +241,26 @@
 	return MINTAUDIO_freqcount-1;
 }
 
-/* Check if FPU is present */
-void SDL_MintAudio_CheckFpu(void)
-{
-	long cookie_fpu;
-
-	SDL_MintAudio_hasfpu = 0;
-	if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) {
-		return;
-	}
-	switch ((cookie_fpu>>16)&0xfffe) {
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-		case 16:
-			SDL_MintAudio_hasfpu = 1;
-			break;
-	}
-}
-
 /* The thread function, used under MiNT with xbios */
 int SDL_MintAudio_Thread(long param)
 {
 	SndBufPtr	pointers;
 	SDL_bool	buffers_filled[2] = {SDL_FALSE, SDL_FALSE};
+	SDL_AudioDevice *this = SDL_MintAudio_device;
 
 	SDL_MintAudio_thread_finished = SDL_FALSE;
 	while (!SDL_MintAudio_quit_thread) {
 		if (Buffptr(&pointers)!=0)
 			continue;
 
-		if (( (unsigned long)pointers.play>=(unsigned long)SDL_MintAudio_audiobuf[0])
-			&& ( (unsigned long)pointers.play<=(unsigned long)SDL_MintAudio_audiobuf[1])) 
+		if (( (unsigned long)pointers.play>=(unsigned long)MINTAUDIO_audiobuf[0])
+			&& ( (unsigned long)pointers.play<=(unsigned long)MINTAUDIO_audiobuf[1])) 
 		{
 			/* DMA is reading buffer #0, setup buffer #1 if not already done */
 			if (!buffers_filled[1]) {
 				SDL_MintAudio_numbuf = 1;
 				SDL_MintAudio_Callback();
-				Setbuffer(0, SDL_MintAudio_audiobuf[1], SDL_MintAudio_audiobuf[1] + SDL_MintAudio_audiosize);
+				Setbuffer(0, MINTAUDIO_audiobuf[1], MINTAUDIO_audiobuf[1] + MINTAUDIO_audiosize);
 				buffers_filled[1]=SDL_TRUE;
 				buffers_filled[0]=SDL_FALSE;
 			}
@@ -188,7 +269,7 @@
 			if (!buffers_filled[0]) {
 				SDL_MintAudio_numbuf = 0;
 				SDL_MintAudio_Callback();
-				Setbuffer(0, SDL_MintAudio_audiobuf[0], SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize);
+				Setbuffer(0, MINTAUDIO_audiobuf[0], MINTAUDIO_audiobuf[0] + MINTAUDIO_audiosize);
 				buffers_filled[0]=SDL_TRUE;
 				buffers_filled[1]=SDL_FALSE;
 			}
--- a/src/audio/mint/SDL_mintaudio.h	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio.h	Mon Jul 28 21:15:42 2014 +0200
@@ -48,15 +48,23 @@
 
 struct SDL_PrivateAudioData {
 	mint_frequency_t	frequencies[MINTAUDIO_maxfreqs];
-	int 	freq_count;		/* Number of frequencies in the array */
-	int		numfreq;		/* Number of selected frequency */
+	int	freq_count;	/* Number of frequencies in the array */
+	int	numfreq;	/* Number of selected frequency */
+
+	Uint8	*audiobuf[2];	/* DMA buffers */
+	int	audiosize;	/* and their size, variable depending on latency */
+
+	void (*swapbuf)(Uint8 *nextbuf, int nextsize);	/* Routine to swap DMA buffers */
 };
 
 /* Old variable names */
 
 #define MINTAUDIO_frequencies	(this->hidden->frequencies)
-#define MINTAUDIO_freqcount		(this->hidden->freq_count)
-#define MINTAUDIO_numfreq		(this->hidden->numfreq)
+#define MINTAUDIO_freqcount	(this->hidden->freq_count)
+#define MINTAUDIO_numfreq	(this->hidden->numfreq)
+#define MINTAUDIO_swapbuf	(this->hidden->swapbuf)
+#define MINTAUDIO_audiobuf	(this->hidden->audiobuf)
+#define MINTAUDIO_audiosize	(this->hidden->audiosize)
 
 /* _MCH cookie (values>>16) */
 enum {
@@ -85,13 +93,6 @@
 
 /* Variables */
 extern SDL_AudioDevice *SDL_MintAudio_device;
-extern Uint8 *SDL_MintAudio_audiobuf[2];	/* Pointers to buffers */
-extern unsigned long SDL_MintAudio_audiosize;		/* Length of audio buffer=spec->size */
-extern volatile unsigned short SDL_MintAudio_numbuf;		/* Buffer to play */
-extern volatile unsigned short SDL_MintAudio_mutex;
-extern cookie_stfa_t *SDL_MintAudio_stfa;
-extern volatile unsigned long SDL_MintAudio_clocktics;
-extern unsigned short SDL_MintAudio_hasfpu;	/* To preserve fpu registers if needed */
 
 /* MiNT thread variables */
 extern SDL_bool	SDL_MintAudio_mint_present;
@@ -100,19 +101,25 @@
 extern long SDL_MintAudio_thread_pid;
 
 /* Functions */
-void SDL_MintAudio_Callback(void);
+void SDL_AtariMint_UpdateAudio(void);
+
+int SDL_MintAudio_InitBuffers(SDL_AudioSpec *spec);
+void SDL_MintAudio_FreeBuffers(void);
 void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock,
 	Uint32 prediv, int gpio_bits);
 int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq);
-void SDL_MintAudio_CheckFpu(void);
 
 /* MiNT thread functions */
 int SDL_MintAudio_Thread(long param);
 void SDL_MintAudio_WaitThread(void);
 
-/* ASM interrupt functions */
-void SDL_MintAudio_GsxbInterrupt(void);
-void SDL_MintAudio_EmptyGsxbInterrupt(void);
+/*--- SDL_mintaudio_it.S stuff ---*/
+
+/* Variables */
+extern volatile unsigned long SDL_MintAudio_clocktics;
+extern volatile unsigned long SDL_MintAudio_num_its;
+
+/* Functions */
 void SDL_MintAudio_XbiosInterruptMeasureClock(void);
 void SDL_MintAudio_XbiosInterrupt(void);
 void SDL_MintAudio_Dma8Interrupt(void);
--- a/src/audio/mint/SDL_mintaudio_dma8.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_dma8.c	Mon Jul 28 21:15:42 2014 +0200
@@ -37,7 +37,7 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_sysaudio.h"
 
-#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
+#include "../../video/ataricommon/SDL_atarisuper.h"
 
 #include "SDL_mintaudio.h"
 #include "SDL_mintaudio_dma8.h"
@@ -70,8 +70,10 @@
 
 /* To check/init hardware audio */
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize);
 
 /* Functions called in supervisor mode */
+static void Mint_SwapBuffersSuper(Uint8 *nextbuf, int nextsize);
 static void Mint_InitDma(void);
 static void Mint_StopReplay(void);
 static void Mint_StartReplay(void);
@@ -180,19 +182,7 @@
 
 	DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
 
-	/* Wait if currently playing sound */
-	while (SDL_MintAudio_mutex != 0) {
-	}
-
-	DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
-
-	DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
+	SDL_MintAudio_FreeBuffers();
 }
 
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
@@ -271,26 +261,11 @@
 		return -1;
 	}
 
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
+	if (!SDL_MintAudio_InitBuffers(spec)) {
+		return -1;
 	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
-	SDL_MintAudio_numbuf=0;
-	SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
-	SDL_MintAudio_audiosize = spec->size;
-	SDL_MintAudio_mutex = 0;
 
-	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
-	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
-
-	SDL_MintAudio_CheckFpu();
+	MINTAUDIO_swapbuf = Mint_SwapBuffers;
 
 	/* Set replay tracks */
 	if (cookie_snd & SND_16BIT) {
@@ -316,26 +291,44 @@
     return(1);	/* We don't use threaded audio */
 }
 
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize)
+{
+	void *old_stack;
+
+	/* Set first ticks value */
+	old_stack = (void *)Super(0);
+
+	Mint_SwapBuffersSuper(nextbuf, nextsize);
+
+	SuperToUser(old_stack);
+}
+
 /* Functions called in supervisor mode */
 
+static void Mint_SwapBuffersSuper(Uint8 *nextbuf, int nextsize)
+{
+	unsigned long buffer;
+
+	buffer = (unsigned long) nextbuf;
+	DMAAUDIO_IO.start_high = (buffer>>16) & 255;
+	DMAAUDIO_IO.start_mid = (buffer>>8) & 255;
+	DMAAUDIO_IO.start_low = buffer & 255;
+
+	buffer += nextsize;
+	DMAAUDIO_IO.end_high = (buffer>>16) & 255;
+	DMAAUDIO_IO.end_mid = (buffer>>8) & 255;
+	DMAAUDIO_IO.end_low = buffer & 255;
+}
+
 static void Mint_InitDma(void)
 {
-	unsigned long buffer;
+	SDL_AudioDevice *this = SDL_MintAudio_device;
 	unsigned char mode;
-	SDL_AudioDevice *this = SDL_MintAudio_device;
 
 	Mint_StopReplay();
 
 	/* Set buffer */
-	buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	DMAAUDIO_IO.start_high = (buffer>>16) & 255;
-	DMAAUDIO_IO.start_mid = (buffer>>8) & 255;
-	DMAAUDIO_IO.start_low = buffer & 255;
-
-	buffer += SDL_MintAudio_audiosize;
-	DMAAUDIO_IO.end_high = (buffer>>16) & 255;
-	DMAAUDIO_IO.end_mid = (buffer>>8) & 255;
-	DMAAUDIO_IO.end_low = buffer & 255;
+	Mint_SwapBuffersSuper(MINTAUDIO_audiobuf[0], MINTAUDIO_audiosize);
 
 	mode = 3-MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
 	if (this->spec.channels==1) {
--- a/src/audio/mint/SDL_mintaudio_gsxb.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c	Mon Jul 28 21:15:42 2014 +0200
@@ -37,8 +37,6 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_sysaudio.h"
 
-#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
-
 #include "SDL_mintaudio.h"
 #include "SDL_mintaudio_gsxb.h"
 
@@ -71,6 +69,7 @@
 /* To check/init hardware audio */
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize);
 
 /* GSXB callbacks */
 static void Mint_GsxbInterrupt(void);
@@ -183,15 +182,7 @@
 		DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
 	}
 
-	/* Wait if currently playing sound */
-	while (SDL_MintAudio_mutex != 0) {
-	}
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
+	SDL_MintAudio_FreeBuffers();
 
 	/* Unlock sound system */
 	Unlocksnd();
@@ -200,11 +191,11 @@
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
 {
 	long snd_format = 0;
-	int i, resolution, format_signed, format_bigendian;
+	int i, /*resolution,*/ format_signed, format_bigendian;
     Uint16 test_format = SDL_FirstAudioFormat(spec->format);
     int valid_datatype = 0;
 
-	resolution = spec->format & 0x00ff;
+	/*resolution = spec->format & 0x00ff;*/
 	format_signed = ((spec->format & 0x8000)!=0);
 	format_bigendian = ((spec->format & 0x1000)!=0);
 
@@ -222,7 +213,7 @@
         /* Check formats available */
         snd_format = Sndstatus(SND_QUERYFORMATS);
         spec->format = test_format;
-        resolution = spec->format & 0xff;
+        /*resolution = spec->format & 0xff;*/
         format_signed = (spec->format & (1<<15));
         format_bigendian = (spec->format & (1<<12));
         switch (test_format) {
@@ -320,7 +311,6 @@
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
 {
 	int channels_mode, prediv;
-	void *buffer;
 
 	/* Stop currently playing sound */
 	Buffoper(0);
@@ -357,10 +347,7 @@
 	Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1);
 
 	/* Set buffer */
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	if (Setbuffer(0, buffer, buffer + spec->size)<0) {
-		DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
-	}
+	Mint_SwapBuffers(MINTAUDIO_audiobuf[0], MINTAUDIO_audiosize);
 	
 	/* Install interrupt */
 	if (NSetinterrupt(2, SI_PLAY, Mint_GsxbInterrupt)<0) {
@@ -387,48 +374,27 @@
 		return -1;
 	}
 
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
+	if (!SDL_MintAudio_InitBuffers(spec)) {
+		return -1;
 	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
-	SDL_MintAudio_numbuf=0;
-	SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
-	SDL_MintAudio_audiosize = spec->size;
-	SDL_MintAudio_mutex = 0;
-
-	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
-	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
-
-	SDL_MintAudio_CheckFpu();
 
 	/* Setup audio hardware */
+	MINTAUDIO_swapbuf = Mint_SwapBuffers;
 	Mint_InitAudio(this, spec);
 
     return(1);	/* We don't use threaded audio */
 }
 
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize)
+{
+	unsigned long buffer = (unsigned long) nextbuf;
+
+	Setbuffer(0, buffer, buffer + nextsize);
+}
+
 static void Mint_GsxbInterrupt(void)
 {
-	Uint8 *newbuf;
-
-	if (SDL_MintAudio_mutex)
-		return;
-
-	SDL_MintAudio_mutex=1;
-
-	SDL_MintAudio_numbuf ^= 1;
-	SDL_MintAudio_Callback();
-	newbuf = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	Setbuffer(0, newbuf, newbuf + SDL_MintAudio_audiosize);
-
-	SDL_MintAudio_mutex=0;
+	++SDL_MintAudio_num_its;
 }
 
 static void Mint_GsxbNullInterrupt(void)
--- a/src/audio/mint/SDL_mintaudio_it.S	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_it.S	Mon Jul 28 21:15:42 2014 +0200
@@ -28,359 +28,69 @@
 
 	.text
 
-	.globl	_SDL_MintAudio_Callback
+	.globl	_SDL_MintAudio_XbiosInterruptMeasureClock
+	.globl	_SDL_MintAudio_clocktics
 
 	.globl	_SDL_MintAudio_XbiosInterrupt
-	.globl	_SDL_MintAudio_XbiosInterruptMeasureClock
 	.globl	_SDL_MintAudio_Dma8Interrupt
 	.globl	_SDL_MintAudio_StfaInterrupt
 
-	.globl	_SDL_MintAudio_mutex
-	.globl	_SDL_MintAudio_audiobuf
-	.globl	_SDL_MintAudio_numbuf
-	.globl	_SDL_MintAudio_audiosize
-	.globl	_SDL_MintAudio_clocktics
-	.globl	_SDL_MintAudio_hasfpu
-
-	.globl	_SDL_MintAudio_stfa
-
-/*
-	How it works:
-	- Audio is playing buffer #0 (resp. #1)
-	- We must calculate a sample in buffer #1 (resp. #0)
-	  so we first call the callback to do it
-	- Then we swap the buffers
-*/
-
-#define	savptr	0x4a2
-#define	savamt	0x46
-
-/*--- Save/restore FPU context ---*/
-
-#if defined(__mcoldfire__)
-
-#define SAVE_FPU_CONTEXT \
-	lea		sp@(-216),sp;	\
-	fsave		sp@;	\
-	fmovel		fpiar,sp@-;	\
-	lea		sp@(-64),sp;	\
-	fmovemd	fp0-fp7,sp@
-
-#define RESTORE_FPU_CONTEXT	\
-	fmovemd		sp@,fp0-fp7;	\
-	lea		sp@(64),sp;	\
-	fmovel		sp@+,fpiar;	\
-	frestore	sp@;	\
-	lea		sp@(216),sp
-
-#else
-
-#define SAVE_FPU_CONTEXT	\
-	.chip	68k/68881;	\
-	fsave	sp@-;	\
-	fmoveml fpcr/fpsr/fpiar,sp@-;	\
-	fmovemx	fp0-fp7,sp@-;	\
-	.chip	68k
-
-#define RESTORE_FPU_CONTEXT	\
-	.chip	68k/68881;	\
-	fmovemx	sp@+,fp0-fp7;	\
-	fmoveml	sp@+,fpcr/fpsr/fpiar;	\
-	frestore	sp@+;	\
-	.chip	68k
-
-#endif
+	.globl	_SDL_MintAudio_num_its
 
 /*--- Xbios interrupt vector to measure Falcon external clock ---*/
 
 _SDL_MintAudio_XbiosInterruptMeasureClock:          /* 1 mS */
+
+	/* state DMA sound */
 #if defined(__mcoldfire__)
 	movel	d0,sp@-
 	
 	moveql	#0,d0
-	btst	d0,0xFFFF8901:w	/* state DMA sound */
+	btst	d0,0xFFFF8901:w
 #else
-	btst	#0,0xFFFF8901:w	/* state DMA sound */
+	btst	#0,0xFFFF8901:w
 #endif
 	beqs	SDL_MintAudio_EndIntMeasure
 	addql	#1,_SDL_MintAudio_clocktics
 SDL_MintAudio_EndIntMeasure:
+
+	/* Clear service bit */
 #if defined(__mcoldfire__)
 	moveql	#5,d0
-	bclr	d0,0xFFFFFA0F:w	/* Clear service bit */
+	bclr	d0,0xFFFFFA0F:w
 
 	movel	sp@+,d0
 #else
-	bclr	#5,0xFFFFFA0F:w	/* Clear service bit */
+	bclr	#5,0xFFFFFA0F:w
 #endif
 	rte
 
-/*--- Xbios interrupt vector ---*/
+/*--- Interrupt vectors ---*/
+/*    Xbios, DMA 8 bits: need to set ISR on MFP */
+/*    STFA: do not touch MFP */
 
 _SDL_MintAudio_XbiosInterrupt:
-#if defined(__mcoldfire__)
-	lea	sp@(-60),sp
-	moveml	d0-d7/a0-a6,sp@
-#else
-	moveml	d0-d7/a0-a6,sp@-
-#endif
-
-	/* Reenable interrupts, so other interrupts can work */
-	movew	#0x2300,sr
+_SDL_MintAudio_Dma8Interrupt:
 
 	/* Clear service bit, so other MFP interrupts can work */
 #if defined(__mcoldfire__)
+	movel	d0,sp@-
+
 	moveql	#5,d0
 	bclr	d0,0xfffffa0f:w
+
+	movel	sp@+,d0
 #else
 	bclr	#5,0xfffffa0f:w
 #endif
 
-	/* Check if we are not already running */
-	tstw	_SDL_MintAudio_mutex
-	bne	SDL_MintAudio_XbiosEnd
-
-#if defined(__mcoldfire__)
-	movew	_SDL_MintAudio_mutex,d0
-	notl	d0
-	movew	d0,_SDL_MintAudio_mutex
-
-	movew	_SDL_MintAudio_numbuf,d1
-	eorl	#1,d1
-	movew	d1,_SDL_MintAudio_numbuf
-#else
-	notw	_SDL_MintAudio_mutex
-
-	/* Swap buffers */
-	eorw	#1,_SDL_MintAudio_numbuf
-#endif
-	
-	/* Save FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Xbios_nofpu1
-	SAVE_FPU_CONTEXT
-SDL_MintAudio_Xbios_nofpu1:
-
-	/* Callback */
-	jsr	_SDL_MintAudio_Callback
-
-	/* Restore FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Xbios_nofpu2
-	RESTORE_FPU_CONTEXT
-SDL_MintAudio_Xbios_nofpu2:
+_SDL_MintAudio_StfaInterrupt:
+	addql	#1,_SDL_MintAudio_num_its
 
-	/* Reserve space for registers */
-#if defined(__mcoldfire__)
-	movel	#savamt,d0
-	subl	d0,savptr
-#else
-	subl	#savamt,savptr
-#endif
-
-	/* Set new buffer */
-
-	moveq	#0,d0
-	movel	_SDL_MintAudio_audiosize,d1
-
-	movew	_SDL_MintAudio_numbuf,d0
-	lsll	#2,d0
-	lea	_SDL_MintAudio_audiobuf,a0
-	movel	a0@(d0:l),a1
-
-	lea	a1@(d1:l),a2
-
-	movel	a2,sp@-
-	movel	a1,sp@-
-	clrw	sp@-
-	movew	#131,sp@-
-	trap	#14
-	lea	sp@(12),sp
-
-	/* Restore registers space */
-#if defined(__mcoldfire__)
-	movel	#savamt,d0
-	addl	d0,savptr
-#else
-	addl	#savamt,savptr
-#endif
-
-	clrw	_SDL_MintAudio_mutex
-SDL_MintAudio_XbiosEnd:
-#if defined(__mcoldfire__)
-	moveml	sp@,d0-d7/a0-a6
-	lea	sp@(60),sp
-#else
-	moveml	sp@+,d0-d7/a0-a6
-#endif
 	rte
 
-/*--- DMA 8 bits interrupt vector ---*/
-
-_SDL_MintAudio_Dma8Interrupt:
-#if defined(__mcoldfire__)
-	lea	sp@(-16),sp
-	moveml	d0-d1/a0-a1,sp@
-#else
-	moveml	d0-d1/a0-a1,sp@-
-#endif
-
-	/* Reenable interrupts, so other interrupts can work */
-	movew	#0x2300,sr
-
-	/* Clear service bit, so other MFP interrupts can work */
-#if defined(__mcoldfire__)
-	moveql	#5,d0
-	bclr	d0,0xfffffa0f:w
-#else
-	bclr	#5,0xfffffa0f:w
-#endif
-	/* Check if we are not already running */
-	tstw	_SDL_MintAudio_mutex
-	bne	SDL_MintAudio_Dma8End
-
-#if defined(__mcoldfire__)
-	movew	_SDL_MintAudio_mutex,d0
-	notl	d0
-	movew	d0,_SDL_MintAudio_mutex
-
-	movew	_SDL_MintAudio_numbuf,d1
-	eorl	#1,d1
-	movew	d1,_SDL_MintAudio_numbuf
-#else
-	notw	_SDL_MintAudio_mutex
-
-	/* Swap buffers */
-	eorw	#1,_SDL_MintAudio_numbuf
-#endif
-
-	/* Save FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Dma8_nofpu1
-	SAVE_FPU_CONTEXT
-SDL_MintAudio_Dma8_nofpu1:
-
-	/* Callback */
-	jsr	_SDL_MintAudio_Callback
-
-	/* Restore FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Dma8_nofpu2
-	RESTORE_FPU_CONTEXT
-SDL_MintAudio_Dma8_nofpu2:
-
-	/* Set new buffer */
-
-	moveq	#0,d0
-
-	movew	_SDL_MintAudio_numbuf,d0
-	lsll	#2,d0
-	lea	_SDL_MintAudio_audiobuf,a0
-	movel	a0@(d0:l),d1
-
-	/* Modify DMA addresses */
-	lea	0xffff8900:w,a0
-
-	movel	d1,d0
-
-	moveb	d0,a0@(0x07)	/* Start address */
-	lsrl	#8,d0
-	moveb	d0,a0@(0x05)
-	lsrl	#8,d0
-	moveb	d0,a0@(0x03)
-
-	addl	_SDL_MintAudio_audiosize,d1
-
-	movel	d1,d0
-
-	moveb	d0,a0@(0x13)	/* End address */
-	lsrl	#8,d0
-	moveb	d0,a0@(0x11)
-	lsrl	#8,d0
-	moveb	d0,a0@(0x0f)
+	.bss
 
-	clrw	_SDL_MintAudio_mutex
-SDL_MintAudio_Dma8End:
-#if defined(__mcoldfire__)
-	moveml	sp@,d0-d1/a0-a1
-	lea	sp@(16),sp
-#else
-	moveml	sp@+,d0-d1/a0-a1
-#endif
-	rte
-
-/*--- STFA interrupt vector ---*/
-
-STFA_SOUND_START	=	6
-STFA_SOUND_END		=	STFA_SOUND_START+8
-
-_SDL_MintAudio_StfaInterrupt:
-	/* Reenable interrupts, so other interrupts can work */
-	movew	#0x2300,sr
-
-	/* Check if we are not already running */
-	tstw	_SDL_MintAudio_mutex
-
-#if defined(__mcoldfire__)
-	bne	SDL_MintAudio_StfaEnd
-
-	lea	sp@(-60),sp
-	moveml	d0-d7/a0-a6,sp@
-
-	movew	_SDL_MintAudio_mutex,d0
-	notl	d0
-	movew	d0,_SDL_MintAudio_mutex
-
-	movew	_SDL_MintAudio_numbuf,d1
-	eorl	#1,d1
-	movew	d1,_SDL_MintAudio_numbuf
-#else
-	bnes	SDL_MintAudio_StfaEnd
-
-	moveml	d0-d7/a0-a6,sp@-
-
-	notw	_SDL_MintAudio_mutex
-
-	/* Swap buffers */
-	eorw	#1,_SDL_MintAudio_numbuf
-#endif
-	
-	/* Save FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Stfa_nofpu1
-	SAVE_FPU_CONTEXT
-SDL_MintAudio_Stfa_nofpu1:
-
-	/* Callback */
-	jsr	_SDL_MintAudio_Callback
-
-	/* Restore FPU if needed */
-	tstw	_SDL_MintAudio_hasfpu
-	beqs	SDL_MintAudio_Stfa_nofpu2
-	RESTORE_FPU_CONTEXT
-SDL_MintAudio_Stfa_nofpu2:
-
-	/* Set new buffer */
-
-	moveq	#0,d0
-	movel	_SDL_MintAudio_stfa,a1
-
-	movew	_SDL_MintAudio_numbuf,d0
-	lsll	#2,d0
-	lea	_SDL_MintAudio_audiobuf,a0
-	movel	a0@(d0:l),d1
-
-	/* Modify STFA replay buffers */
-	movel	d1,a1@(STFA_SOUND_START)
-	addl	_SDL_MintAudio_audiosize,d1
-	movel	d1,a1@(STFA_SOUND_END)
-
-#if defined(__mcoldfire__)
-	moveml	sp@,d0-d7/a0-a6
-	lea	sp@(60),sp
-#else
-	moveml	sp@+,d0-d7/a0-a6
-#endif
-	clrw	_SDL_MintAudio_mutex
-SDL_MintAudio_StfaEnd:
-	rte
+	.even
+	.comm	_SDL_MintAudio_clocktics,4
+	.comm	_SDL_MintAudio_num_its,4
--- a/src/audio/mint/SDL_mintaudio_mcsn.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c	Mon Jul 28 21:15:42 2014 +0200
@@ -39,8 +39,6 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_sysaudio.h"
 
-#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
-
 #include "SDL_mintaudio.h"
 #include "SDL_mintaudio_mcsn.h"
 
@@ -74,6 +72,7 @@
 /* To check/init hardware audio */
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize);
 
 /*--- Audio driver bootstrap functions ---*/
 
@@ -200,15 +199,7 @@
 		Jdisint(MFP_DMASOUND);
 	}
 
-	/* Wait if currently playing sound */
-	while (SDL_MintAudio_mutex != 0) {
-	}
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
+	SDL_MintAudio_FreeBuffers();
 
 	/* Unlock sound system */
 	Unlocksnd();
@@ -297,7 +288,6 @@
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
 {
 	int channels_mode, prediv, dmaclock;
-	void *buffer;
 
 	/* Stop currently playing sound */
 	SDL_MintAudio_quit_thread = SDL_FALSE;
@@ -339,10 +329,7 @@
 	}
 
 	/* Set buffer */
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	if (Setbuffer(0, buffer, buffer + spec->size)<0) {
-		DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
-	}
+	Mint_SwapBuffers(MINTAUDIO_audiobuf[0], MINTAUDIO_audiosize);
 	
 	if (SDL_MintAudio_mint_present) {
 		SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0);
@@ -377,29 +364,20 @@
 		return -1;
 	}
 
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
+	if (!SDL_MintAudio_InitBuffers(spec)) {
+		return -1;
 	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
-	SDL_MintAudio_numbuf=0;
-	SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
-	SDL_MintAudio_audiosize = spec->size;
-	SDL_MintAudio_mutex = 0;
-
-	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
-	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
-
-	SDL_MintAudio_CheckFpu();
 
 	/* Setup audio hardware */
+	MINTAUDIO_swapbuf = Mint_SwapBuffers;
 	Mint_InitAudio(this, spec);
 
     return(1);	/* We don't use SDL threaded audio */
 }
+
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize)
+{
+	unsigned long buffer = (unsigned long) nextbuf;
+
+	Setbuffer(0, buffer, buffer + nextsize);
+}
--- a/src/audio/mint/SDL_mintaudio_stfa.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_stfa.c	Mon Jul 28 21:15:42 2014 +0200
@@ -37,8 +37,6 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_sysaudio.h"
 
-#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
-
 #include "SDL_mintaudio.h"
 #include "SDL_mintaudio_stfa.h"
 
@@ -79,6 +77,7 @@
 /* To check/init hardware audio */
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize);
 
 /*--- Audio driver bootstrap functions ---*/
 
@@ -110,8 +109,6 @@
 	}
 	cookie_stfa = (cookie_stfa_t *) dummy;
 
-	SDL_MintAudio_stfa = cookie_stfa;
-
 	DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
 	return(1);
 }
@@ -171,15 +168,7 @@
 {
 	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
 
-	/* Wait if currently playing sound */
-	while (SDL_MintAudio_mutex != 0) {
-	}
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
+	SDL_MintAudio_FreeBuffers();
 }
 
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
@@ -225,10 +214,6 @@
 
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
 {
-	void *buffer;
-
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-
 	/* Stop replay */
 	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
 
@@ -256,8 +241,7 @@
 	}
 
 	/* Set buffer */
-	cookie_stfa->sound_start = (unsigned long) buffer;
-	cookie_stfa->sound_end = (unsigned long) (buffer + spec->size);
+	Mint_SwapBuffers(MINTAUDIO_audiobuf[0], MINTAUDIO_audiosize);
 
 	/* Set interrupt */
 	cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt;
@@ -277,29 +261,19 @@
 		return -1;
 	}
 
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
+	if (!SDL_MintAudio_InitBuffers(spec)) {
+		return -1;
 	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
-	SDL_MintAudio_numbuf=0;
-	SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
-	SDL_MintAudio_audiosize = spec->size;
-	SDL_MintAudio_mutex = 0;
-
-	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
-	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
-
-	SDL_MintAudio_CheckFpu();
 
 	/* Setup audio hardware */
+	MINTAUDIO_swapbuf = Mint_SwapBuffers;
 	Mint_InitAudio(this, spec);
 
     return(1);	/* We don't use threaded audio */
 }
+
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize)
+{
+	cookie_stfa->sound_start = (unsigned long) nextbuf;
+	cookie_stfa->sound_end = cookie_stfa->sound_start + nextsize;
+}
--- a/src/audio/mint/SDL_mintaudio_xbios.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/audio/mint/SDL_mintaudio_xbios.c	Mon Jul 28 21:15:42 2014 +0200
@@ -75,6 +75,7 @@
 /* To check/init hardware audio */
 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize);
 
 /*--- Audio driver bootstrap functions ---*/
 
@@ -184,15 +185,7 @@
 		Jdisint(MFP_DMASOUND);
 	}
 
-	/* Wait if currently playing sound */
-	while (SDL_MintAudio_mutex != 0) {
-	}
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
+	SDL_MintAudio_FreeBuffers();
 
 	/* Unlock sound system */
 	Unlocksnd();
@@ -386,7 +379,6 @@
 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
 {
 	int channels_mode, prediv;
-	void *buffer;
 
 	/* Stop currently playing sound */
 	SDL_MintAudio_quit_thread = SDL_FALSE;
@@ -423,18 +415,15 @@
 	}
 
 	/* Set buffer */
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	if (Setbuffer(0, buffer, buffer + spec->size)<0) {
-		DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
-	}
+	Mint_SwapBuffers(MINTAUDIO_audiobuf[0], MINTAUDIO_audiosize);
 	
 	if (SDL_MintAudio_mint_present) {
 		SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0);
 	} else {
 		/* Install interrupt */
 		Jdisint(MFP_DMASOUND);
-		/*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);*/
-		Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
+		Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);
+		/*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);*/
 		Jenabint(MFP_DMASOUND);
 
 		if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) {
@@ -462,29 +451,20 @@
 		return -1;
 	}
 
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
+	if (!SDL_MintAudio_InitBuffers(spec)) {
+		return -1;
 	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
-	SDL_MintAudio_numbuf=0;
-	SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
-	SDL_MintAudio_audiosize = spec->size;
-	SDL_MintAudio_mutex = 0;
-
-	DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
-	DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
-
-	SDL_MintAudio_CheckFpu();
 
 	/* Setup audio hardware */
+	MINTAUDIO_swapbuf = Mint_SwapBuffers;
 	Mint_InitAudio(this, spec);
 
     return(1);	/* We don't use SDL threaded audio */
 }
+
+static void Mint_SwapBuffers(Uint8 *nextbuf, int nextsize)
+{
+	unsigned long buffer = (unsigned long) nextbuf;
+
+	Setbuffer(0, buffer, buffer + nextsize);
+}
--- a/src/video/ataricommon/SDL_atarievents.c	Mon Jul 28 20:40:41 2014 +0200
+++ b/src/video/ataricommon/SDL_atarievents.c	Mon Jul 28 21:15:42 2014 +0200
@@ -42,6 +42,8 @@
 #include "SDL_gemdosevents_c.h"
 #include "SDL_ikbdevents_c.h"
 
+/* from src/audio/mint/SDL_mintaudio.c */
+void SDL_AtariMint_UpdateAudio(void);
 /* from src/timer/mint/SDL_systimer.c */
 void SDL_AtariMint_CheckTimer(void);
 
@@ -239,5 +241,6 @@
 
 void SDL_AtariMint_BackgroundTasks(void)
 {
+	SDL_AtariMint_UpdateAudio();
 	if (SDL_timer_running) SDL_AtariMint_CheckTimer();
 }