Atari MiNT: added more audio drivers
authorPatrice Mandin <patmandin@gmail.com>
Mon, 07 Jul 2003 19:16:03 +0000
changeset 644 594422ab8f9f
parent 643 564716cfb502
child 645 5bcfbd1abac6
Atari MiNT: added more audio drivers
README.MiNT
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/mint/Makefile.am
src/audio/mint/SDL_mintaudio.c
src/audio/mint/SDL_mintaudio.h
src/audio/mint/SDL_mintaudio_dma8.c
src/audio/mint/SDL_mintaudio_dma8.h
src/audio/mint/SDL_mintaudio_gsxb.c
src/audio/mint/SDL_mintaudio_gsxb.h
src/audio/mint/SDL_mintaudio_it.S
src/audio/mint/SDL_mintaudio_mcsn.c
src/audio/mint/SDL_mintaudio_mcsn.h
src/audio/mint/SDL_mintaudio_stfa.c
src/audio/mint/SDL_mintaudio_stfa.h
src/audio/mint/SDL_mintaudio_xbios.c
--- a/README.MiNT	Tue Jul 01 16:35:54 2003 +0000
+++ b/README.MiNT	Mon Jul 07 19:16:03 2003 +0000
@@ -49,18 +49,18 @@
 Video (XBIOS (Fullscreen), GEM (Windowed and Fullscreen))
 Timer (VBL vector, GNU pth library)
 Joystick and joypad support (Ikbd, Hardware)
-Audio support (Hardware, XBIOS, GSXB, /dev/audio if threads enabled)
+Audio support (Hardware, XBIOS, GSXB, MCSN, STFA, /dev/audio if threads enabled)
 Threads support (Multitasking OS only via GNU pth library)
 
 - What is missing:
 CDROM support (Metados, /dev/cdrom)
 
 - Driver combinations:
-Video	Kbd	Mouse	Timer	Jstick	Joypads
-xbios	ikbd	ikbd	vbl(2)	ikbd	hardware
-xbios	gemdos	xbios	vbl(2)	xbios	hardware
-xbios	bios	xbios	vbl(2)	xbios	hardware
-gem	gem	gem(1)	vbl(2)	xbios	hardware
+Video	Kbd	Mouse	Timer	Joystick
+xbios	ikbd	ikbd	vbl(2)	ikbd
+xbios	gemdos	xbios	vbl(2)	xbios
+xbios	bios	xbios	vbl(2)	xbios
+gem	gem	gem(1)	vbl(2)	xbios
 
 (1) GEM does not report relative mouse motion, so xbios mouse driver is used
 to report this type event.
@@ -76,7 +76,11 @@
 	Set to 'gem' to force gem video driver
 
 SDL_AUDIODRIVER:
-	Set to 'mint' to force Atari audio driver
+	Set to 'mint_gsxb' to force Atari GSXB audio driver
+	Set to 'mint_mcsn' to force Atari MCSN audio driver
+	Set to 'mint_stfa' to force Atari STFA audio driver
+	Set to 'mint_xbios' to force Atari Xbios audio driver
+	Set to 'mint_dma8' to force Atari 8 bits DMA audio driver
 	Set to 'audio' to force Sun /dev/audio audio driver
 	Set to 'disk' to force disk-writing audio driver
 
@@ -163,17 +167,30 @@
 VBL timer driver:
 	Available on all machines (I think).
 
-Audio driver:
-	Cookie _SND is used to detect supported audio capabilities
+Audio drivers:
+	Cookies _SND, MCSN, STFA and GSXB used to detect supported audio
+	capabilities.
 
 	STE, Mega STE, TT:
 		8 bits DMA (hardware access)
-
-	Falcon, machines with GSXB driver:
+		STFA, MCSN or GSXB driver if installed
+	Falcon:
+		8 bits DMA (hardware access)
 		Xbios functions
-
+		STFA, MCSN or GSXB driver if installed
 	Other machines:
-		Not supported
+		STFA, MCSN or GSXB driver if installed
+
+	STFA driver:
+		http://removers.free.fr/softs/stfa.html
+	GSXB driver:
+		http://assemsoft.atari.org/gsxb/
+	MacSound driver:
+		http://jf.omnis.ch/software/tos/
+	MagicSound driver (MCSN,GSXB compatible):
+		http://perso.wanadoo.fr/didierm/
+	X-Sound driver (GSXB compatible):
+		http://www.uni-ulm.de/~s_thuth/atari/xsound_e.html
 
 -- 
 Patrice Mandin <pmandin@caramail.com>
--- a/src/audio/SDL_audio.c	Tue Jul 01 16:35:54 2003 +0000
+++ b/src/audio/SDL_audio.c	Mon Jul 07 19:16:03 2003 +0000
@@ -84,7 +84,11 @@
 	&AHI_bootstrap,
 #endif
 #ifdef MINTAUDIO_SUPPORT
-	&MINTAUDIO_bootstrap,
+	&MINTAUDIO_GSXB_bootstrap,
+	&MINTAUDIO_MCSN_bootstrap,
+	&MINTAUDIO_STFA_bootstrap,
+	&MINTAUDIO_XBIOS_bootstrap,
+	&MINTAUDIO_DMA8_bootstrap,
 #endif
 #ifdef DISKAUD_SUPPORT
 	&DISKAUD_bootstrap,
--- a/src/audio/SDL_sysaudio.h	Tue Jul 01 16:35:54 2003 +0000
+++ b/src/audio/SDL_sysaudio.h	Mon Jul 07 19:16:03 2003 +0000
@@ -148,7 +148,11 @@
 extern AudioBootStrap AHI_bootstrap;
 #endif
 #ifdef MINTAUDIO_SUPPORT
-extern AudioBootStrap MINTAUDIO_bootstrap;
+extern AudioBootStrap MINTAUDIO_GSXB_bootstrap;
+extern AudioBootStrap MINTAUDIO_MCSN_bootstrap;
+extern AudioBootStrap MINTAUDIO_STFA_bootstrap;
+extern AudioBootStrap MINTAUDIO_XBIOS_bootstrap;
+extern AudioBootStrap MINTAUDIO_DMA8_bootstrap;
 #endif
 #ifdef DISKAUD_SUPPORT
 extern AudioBootStrap DISKAUD_bootstrap;
--- a/src/audio/mint/Makefile.am	Tue Jul 01 16:35:54 2003 +0000
+++ b/src/audio/mint/Makefile.am	Mon Jul 07 19:16:03 2003 +0000
@@ -1,14 +1,19 @@
-
 ## Makefile.am for SDL using Xbios/Dma/whatever available audio functions
 
 noinst_LTLIBRARIES = libaudio_mintaudio.la
 libaudio_mintaudio_la_SOURCES = $(SRCS)
 
 # The SDL audio driver sources
-SRCS =	SDL_mintaudio.c	\
+SRCS = \
+	SDL_mintaudio.c	\
 	SDL_mintaudio.h	\
-	SDL_mintaudiointerrupt.S \
-	SDL_mintaudiointerrupt_s.h \
-	SDL_mintaudiodma.h \
-	SDL_mintaudiogsxb.h
-
+	SDL_mintaudio_dma8.c	\
+	SDL_mintaudio_dma8.h	\
+	SDL_mintaudio_gsxb.c	\
+	SDL_mintaudio_gsxb.h	\
+	SDL_mintaudio_it.S	\
+	SDL_mintaudio_mcsn.c	\
+	SDL_mintaudio_mcsn.h	\
+	SDL_mintaudio_stfa.c	\
+	SDL_mintaudio_stfa.h	\
+	SDL_mintaudio_xbios.c
--- a/src/audio/mint/SDL_mintaudio.c	Tue Jul 01 16:35:54 2003 +0000
+++ b/src/audio/mint/SDL_mintaudio.c	Mon Jul 07 19:16:03 2003 +0000
@@ -1,628 +1,93 @@
 /*
- * MiNT audio driver
- * 
- * Patrice Mandin
- */
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
 
-#include <stdlib.h>
-#include <stdio.h>
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	Audio interrupt variables and callback function
+
+	Patrice Mandin
+*/
+
 #include <string.h>
 
-/* Mint includes */
-#include <mint/osbind.h>
-#include <mint/falcon.h>
-#include <mint/cookie.h>
-
-#include "SDL_endian.h"
+#include "SDL_types.h"
 #include "SDL_audio.h"
-#include "SDL_audio_c.h"
-#include "SDL_audiomem.h"
-#include "SDL_sysaudio.h"
 
 #include "SDL_mintaudio.h"
-#include "SDL_mintaudiodma.h"
-#include "SDL_mintaudiogsxb.h"
-#include "SDL_mintaudiointerrupt_s.h"
-
-#include "SDL_atarimxalloc_c.h"
-
-/*--- Defines ---*/
-
-#define MINT_AUDIO_DRIVER_NAME "mint"
-
-/* Master clocks for replay frequencies */
-#define MASTERCLOCK_STE		8010666		/* Not sure of this one */
-#define MASTERCLOCK_TT		16107953	/* Not sure of this one */
-#define MASTERCLOCK_FALCON1	25175000
-#define MASTERCLOCK_FALCON2	32000000	/* Only usable for DSP56K */
-#define MASTERCLOCK_FALCONEXT	-1		/* Clock on DSP56K port, unknown */
-#define MASTERCLOCK_MILAN1	22579200	/* Standard clock for 44.1 Khz */
-#define MASTERCLOCK_MILAN2	24576000	/* Standard clock for 48 Khz */
-
-/* Master clock predivisors */
-#define MASTERPREDIV_STE	160
-#define MASTERPREDIV_TT		320
-#define MASTERPREDIV_FALCON	256
-#define MASTERPREDIV_MILAN	256
-
-/* Values>>16 in _MCH cookie */
-enum {
-	MCH_ST=0,
-	MCH_STE,
-	MCH_TT,
-	MCH_F30
-};
+#include "SDL_mintaudio_stfa.h"
 
-/* MFP 68901 interrupt sources */
-enum {
-	MFP_PARALLEL=0,
-	MFP_DCD,
-	MFP_CTS,
-	MFP_BITBLT,
-	MFP_TIMERD,
-	MFP_BAUDRATE=MFP_TIMERD,
-	MFP_TIMERC,
-	MFP_200HZ=MFP_TIMERC,
-	MFP_ACIA,
-	MFP_DISK,
-	MFP_TIMERB,
-	MFP_HBLANK=MFP_TIMERB,
-	MFP_TERR,
-	MFP_TBE,
-	MFP_RERR,
-	MFP_RBF,
-	MFP_TIMERA,
-	MFP_DMASOUND=MFP_TIMERA,
-	MFP_RING,
-	MFP_MONODETECT
-};
-
-/* Xbtimer() timers */
-enum {
-	XB_TIMERA=0,
-	XB_TIMERB,
-	XB_TIMERC,
-	XB_TIMERD
-};
-
-/*--- Static variables ---*/
-
-static unsigned long cookie_snd, cookie_mch, cookie_gsxb;
-static Uint16 hardfreq[16];
-static Uint16 numfreq;
-static SDL_AudioDevice *SDL_MintAudio_device;
-
-/*--- Audio driver functions ---*/
-
-static void Mint_CloseAudio(_THIS);
-static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
-static void Mint_LockAudio(_THIS);
-static void Mint_UnlockAudio(_THIS);
-
-/*--- Audio driver bootstrap functions ---*/
-
-static int Audio_Available(void)
-{
-	const char *envr = getenv("SDL_AUDIODRIVER");
-
-	/* Check if user asked a different audio driver */
-	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
-		return 0;
-	}
-
-	/* Cookie _SND present ? if not, assume ST machine */
-	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
-		cookie_snd = SND_PSG;
-	}
+/* The audio device */
 
-	/* Cookie _MCH present ? if not, assume ST machine */
-	if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
-		cookie_mch = MCH_ST << 16;
-	}
-
-	/* Cookie GSXB present ? */
-	cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
-
-	/* Check if we have xbios functions (Falcon, clones) */
-	if ((cookie_snd & SND_16BIT)!=0) {
-		/* Check if audio is lockable */
-		if (Locksnd()==1) {
-			Unlocksnd();
-		} else {
-			/* Already in use */
-			return(0);
-		}
-
-		return(1);
-	}
-
-	/* Check if we have 8 bits DMA audio (STE, TT) */
-	if ((cookie_snd & SND_8BIT)!=0) {
-		return(1);
-	}
-
-    return(0);
-}
-
-static void Audio_DeleteDevice(SDL_AudioDevice *device)
-{
-    free(device->hidden);
-    free(device);
-}
-
-static SDL_AudioDevice *Audio_CreateDevice(int devindex)
-{
-    SDL_AudioDevice *this;
+SDL_AudioDevice *SDL_MintAudio_device;
+Uint8 *SDL_MintAudio_audiobuf[2];	/* Pointers to buffers */
+long SDL_MintAudio_audiosize;		/* Length of audio buffer=spec->size */
+long SDL_MintAudio_numbuf;		/* Buffer to play */
+long SDL_MintAudio_mutex;
+cookie_stfa_t	*SDL_MintAudio_stfa;
 
-    /* Initialize all variables that we clean on shutdown */
-    this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
-    if ( this ) {
-        memset(this, 0, (sizeof *this));
-    }
-    if ( this == NULL ) {
-        SDL_OutOfMemory();
-        if ( this ) {
-            free(this);
-        }
-        return(0);
-    }
-
-    /* Set the function pointers */
-    this->OpenAudio   = Mint_OpenAudio;
-    this->CloseAudio  = Mint_CloseAudio;
-    this->LockAudio   = Mint_LockAudio;
-    this->UnlockAudio = Mint_UnlockAudio;
-    this->free        = Audio_DeleteDevice;
-
-    return this;
-}
-
-AudioBootStrap MINTAUDIO_bootstrap = {
-	MINT_AUDIO_DRIVER_NAME, "MiNT audio driver",
-	Audio_Available, Audio_CreateDevice
-};
+/* The callback function, called by each driver whenever needed */
 
-static void Mint_LockAudio(_THIS)
-{
-	void *oldpile;
-
-	/* Stop replay */
-	if ((cookie_snd & SND_16BIT)!=0) {
-		Buffoper(0);
-	} else if ((cookie_snd & SND_8BIT)!=0) {
-		oldpile=(void *)Super(0);
-		DMAAUDIO_IO.control=0;
-		Super(oldpile);
-	}
-}
-
-static void Mint_UnlockAudio(_THIS)
-{
-	void *oldpile;
-
-	/* Restart replay */
-	if ((cookie_snd & SND_16BIT)!=0) {
-		Buffoper(SB_PLA_ENA|SB_PLA_RPT);
-	} else if ((cookie_snd & SND_8BIT)!=0) {
-		oldpile=(void *)Super(0);
-		DMAAUDIO_IO.control=3;
-		Super(oldpile);
-	}
-}
-
-/* This is called from the interrupt routine */
 void SDL_MintAudio_Callback(void)
 {
-	SDL_AudioDevice *audio;
 	Uint8 *buffer;
 
-	audio = SDL_MintAudio_device;
  	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
+	memset(buffer, SDL_MintAudio_device->spec.silence, SDL_MintAudio_device->spec.size);
 
-	if ( ! audio->paused ) {
-		if ( audio->convert.needed ) {
-			audio->spec.callback(audio->spec.userdata,
-				(Uint8 *)audio->convert.buf,audio->convert.len);
-			SDL_ConvertAudio(&audio->convert);
-			memcpy(buffer, audio->convert.buf, audio->convert.len_cvt);
+	if ( ! SDL_MintAudio_device->paused ) {
+		if ( SDL_MintAudio_device->convert.needed ) {
+			SDL_MintAudio_device->spec.callback(SDL_MintAudio_device->spec.userdata,
+				(Uint8 *)SDL_MintAudio_device->convert.buf,SDL_MintAudio_device->convert.len);
+			SDL_ConvertAudio(&SDL_MintAudio_device->convert);
+			memcpy(buffer, SDL_MintAudio_device->convert.buf, SDL_MintAudio_device->convert.len_cvt);
 		} else {
-			audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size);
+			SDL_MintAudio_device->spec.callback(SDL_MintAudio_device->spec.userdata, buffer, SDL_MintAudio_device->spec.size);
 		}
 	}
 }
 
-static void Mint_StopAudio_Dma8(void)
-{
-	void *oldpile;
-	
-	oldpile=(void *)Super(0);
-	DMAAUDIO_IO.control=0;
-	Super(oldpile);
-
-	Jdisint(MFP_DMASOUND);
-}
-
-static void Mint_StopAudio_Xbios(void)
-{
-	Buffoper(0);
-	Jdisint(MFP_DMASOUND);
-}
-
-static void Mint_StopAudio_Gsxb(void)
-{
-	Buffoper(0);
-}
-
-static void Mint_CloseAudio(_THIS)
-{
-	if (cookie_gsxb && ((cookie_snd & (SND_GSXB|SND_16BIT))==(SND_GSXB|SND_16BIT)) ) {
-		Mint_StopAudio_Gsxb();
-	} else if ((cookie_snd & SND_16BIT)!=0) {
-		Mint_StopAudio_Xbios();
-	} else if ((cookie_snd & SND_8BIT)!=0) {
-		Mint_StopAudio_Dma8();
-	}
-
-	/* Clear buffers */
-	if (SDL_MintAudio_audiobuf[0]) {
-		Mfree(SDL_MintAudio_audiobuf[0]);
-		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
-	}
-
-	/* Unlock sound system */
-	if ((cookie_snd & SND_16BIT)!=0) {
-		Unlocksnd();
-	}
-}
-
-static void Mint_CheckAudio_Dma8(SDL_AudioSpec *spec)
+/* Simple function to search for the nearest frequency */
+int SDL_MintAudio_SearchFrequency(_THIS, int falcon_codec, int desired_freq)
 {
 	int i;
 
-	spec->format = AUDIO_S8;
-
-	switch(cookie_mch>>16) {
-		case MCH_STE:
-			/* STE replay frequencies */
-			for (i=0;i<4;i++) {
-				hardfreq[i]=MASTERCLOCK_STE/(MASTERPREDIV_STE*(i+1));
-			}
-
-			if (spec->freq>=(hardfreq[0]+hardfreq[1])>>1) {
-				numfreq=3;		/* 50066 */
-			} else if (spec->freq>=(hardfreq[1]+hardfreq[2])>>1) {
-				numfreq=2;		/* 25033 */
-			} else if (spec->freq>=(hardfreq[2]+hardfreq[3])>>1) {
-				numfreq=1;		/* 12517 */
-			} else {
-				numfreq=0;		/* 6258 */
-			}
-
-			spec->freq=hardfreq[numfreq];
-			break;
-		case MCH_TT:
-			/* TT replay frequencies */
-			for (i=0;i<4;i++) {
-				hardfreq[i]=MASTERCLOCK_TT/(MASTERPREDIV_TT*(i+1));
-			}
-
-			if (spec->freq>=(hardfreq[0]+hardfreq[1])>>1) {
-				numfreq=3;		/* 50337 */
-			} else if (spec->freq>=(hardfreq[1]+hardfreq[2])>>1) {
-				numfreq=2;		/* 25169 */
-			} else if (spec->freq>=(hardfreq[2]+hardfreq[3])>>1) {
-				numfreq=1;		/* 12584 */
-			} else {
-				numfreq=0;		/* 6292 */
-			}
-			spec->freq=hardfreq[numfreq];
-			break;
-	}
-}
-
-static void Mint_CheckAudio_Xbios(SDL_AudioSpec *spec)
-{
-	int i;
-
-	/* Check conversions needed */
-	switch (spec->format & 0xff) {
-		case 8:
-			spec->format = AUDIO_S8;
-			break;
-		case 16:
-			spec->format = AUDIO_S16MSB;
-			break;
-	}
-	
-	/* Check hardware channels */
-	if ((spec->channels==1) && ((spec->format & 0xff)==16)) {
-		spec->channels=2;
-	}
-
-	/* Falcon replay frequencies */
-	for (i=0;i<16;i++) {
-		hardfreq[i]=MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1));
+	/* Only 1 freq ? */
+	if (MINTAUDIO_nfreq==1) {
+		return(MINTAUDIO_sfreq);
 	}
 
-	/* The Falcon CODEC only support some frequencies */
-	if (spec->freq>=(hardfreq[CLK50K]+hardfreq[CLK33K])>>1) {
-		numfreq=CLK50K;		/* 49170 */
-	} else if (spec->freq>=(hardfreq[CLK33K]+hardfreq[CLK25K])>>1) {
-		numfreq=CLK33K;		/* 32780 */
-	} else if (spec->freq>=(hardfreq[CLK25K]+hardfreq[CLK20K])>>1) {
-		numfreq=CLK25K;		/* 24585 */
-	} else if (spec->freq>=(hardfreq[CLK20K]+hardfreq[CLK16K])>>1) {
-		numfreq=CLK20K;		/* 19668 */
-	} else if (spec->freq>=(hardfreq[CLK16K]+hardfreq[CLK12K])>>1) {
-		numfreq=CLK16K;		/* 16390 */
-	} else if (spec->freq>=(hardfreq[CLK12K]+hardfreq[CLK10K])>>1) {
-		numfreq=CLK12K;		/* 12292 */
-	} else if (spec->freq>=(hardfreq[CLK10K]+hardfreq[CLK8K])>>1) {
-		numfreq=CLK10K;		/* 9834 */
-	} else {
-		numfreq=CLK8K;		/* 8195 */
-	}				
-
-	spec->freq=hardfreq[numfreq];
-}
-
-static int Mint_CheckAudio_Gsxb(SDL_AudioSpec *spec)
-{
-	long snd_format;
-	int i, resolution, format_signed, format_bigendian;
-
-	resolution = spec->format & 0x00ff;
-	format_signed = ((spec->format & 0x8000)!=0);
-	format_bigendian = ((spec->format & 0x1000)!=0);
+	/* Check the array */
+	for (i=MINTAUDIO_sfreq; i<MINTAUDIO_nfreq-1; i++) {
+		/* Remove unusable falcon codec frequencies */
+		if (falcon_codec) {
+			if ((i==6) || (i==8) || (i==10)) {
+				continue;
+			}
+		}
 
-	/* Check formats available */
-	snd_format = Sndstatus(SND_QUERYFORMATS);
-	switch (resolution) {
-		case 8:
-			if ((snd_format & SND_FORMAT8)==0) {
-				SDL_SetError("Mint_CheckAudio: 8 bits samples not supported");
-				return -1;
-			}
-			snd_format = Sndstatus(SND_QUERY8BIT);
-			break;
-		case 16:
-			if ((snd_format & SND_FORMAT16)==0) {
-				SDL_SetError("Mint_CheckAudio: 16 bits samples not supported");
-				return -1;
-			}
-			snd_format = Sndstatus(SND_QUERY16BIT);
-			break;
-		default:
-			SDL_SetError("Mint_CheckAudio: Unsupported sample resolution");
-			return -1;
-			break;
-	}
-
-	/* Check signed/unsigned format */
-	if (format_signed) {
-		if (snd_format & SND_FORMATSIGNED) {
-			/* Ok */
-		} else if (snd_format & SND_FORMATUNSIGNED) {
-			/* Give unsigned format */
-			spec->format = spec->format & (~0x8000);
-		}
-	} else {
-		if (snd_format & SND_FORMATUNSIGNED) {
-			/* Ok */
-		} else if (snd_format & SND_FORMATSIGNED) {
-			/* Give signed format */
-			spec->format |= 0x8000;
+		if (desired_freq >= ((MINTAUDIO_hardfreq[i]+MINTAUDIO_hardfreq[i+1])>>1)) {
+			return i;
 		}
 	}
 
-	if (format_bigendian) {
-		if (snd_format & SND_FORMATBIGENDIAN) {
-			/* Ok */
-		} else if (snd_format & SND_FORMATLITTLEENDIAN) {
-			/* Give little endian format */
-			spec->format = spec->format & (~0x1000);
-		}
-	} else {
-		if (snd_format & SND_FORMATBIGENDIAN) {
-			/* Ok */
-		} else if (snd_format & SND_FORMATLITTLEENDIAN) {
-			/* Give big endian format */
-			spec->format |= 0x1000;
-		}
-	}
-	
-	/* Only xbios functions available = clone with PC board */
-	for (i=0;i<8;i++) {
-		hardfreq[i]=MASTERCLOCK_MILAN1/(MASTERPREDIV_MILAN*(i+1));
-	}
-
-	if (spec->freq>=(hardfreq[CLK_44K]+hardfreq[CLK_22K])>>1) {
-		numfreq = CLK_44K;	/* 44100 */
-	} else if (spec->freq>=(hardfreq[CLK_22K]+hardfreq[CLK_11K])>>1) {
-		numfreq = CLK_22K;	/* 22050 */
-	} else {
-		numfreq = CLK_11K;	/* 11025 */
-	}				
-
-	spec->freq=hardfreq[numfreq];
-
-	return 0;
-}
-
-static void Mint_InitAudio_Dma8(SDL_AudioSpec *spec)
-{
-	void *oldpile;
-	unsigned long buffer;
-	unsigned char mode;
-	
-	oldpile=(void *)Super(0);
-
-	/* Stop currently playing sound */
-	DMAAUDIO_IO.control=0;
-
-	/* 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;
-
-	mode = numfreq;
-	if (spec->channels==1) {
-		mode |= 1<<7;
-	}
-	DMAAUDIO_IO.mode = mode;	
-
-	/* Set interrupt */
-	Jdisint(MFP_DMASOUND);
-	Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_IntDma);
-	Jenabint(MFP_DMASOUND);
-
-	/* Go */
-	DMAAUDIO_IO.control = 3;	/* playback + repeat */
-
-	Super(oldpile);
+	/* Not in the array, give the latest */
+	return MINTAUDIO_nfreq-1;
 }
-
-static void Mint_InitAudio_Xbios(SDL_AudioSpec *spec)
-{
-	int channels_mode;
-	void *buffer;
-
-	/* Stop currently playing sound */
-	Buffoper(0);
-
-	Settracks(0,0);
-	Setmontracks(0);
-
-	switch (spec->format & 0xff) {
-		case 8:
-			if (spec->channels==2) {
-				channels_mode=STEREO8;
-			} else {
-				channels_mode=MONO8;
-			}
-			break;
-		case 16:
-		default:
-			channels_mode=STEREO16;
-			break;
-	}
-	Setmode(channels_mode);
-
-	Devconnect(DMAPLAY, DAC, CLK25M, numfreq, 1);
-
-	/* Set buffer */
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	Setbuffer(0, buffer, buffer+SDL_MintAudio_audiosize);
-	
-	/* Install interrupt */
-	Setinterrupt(SI_TIMERA, SI_PLAY);
-
-	Jdisint(MFP_DMASOUND);
-	Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_IntXbios);
-	Jenabint(MFP_DMASOUND);
-
-	/* Go */
-	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
-}
-
-static void Mint_InitAudio_Gsxb(SDL_AudioSpec *spec)
-{
-	int channels_mode;
-	void *buffer;
-
-	/* Stop currently playing sound */
-	Buffoper(0);
-
-	switch (spec->format & 0xff) {
-		case 8:
-			if (spec->channels==2) {
-				channels_mode=STEREO8;
-			} else {
-				channels_mode=MONO8;
-			}
-			break;
-		case 16:
-			if (spec->channels==2) {
-				channels_mode=STEREO16;
-			} else {
-				channels_mode=MONO16;
-			}
-			break;
-		default:
-			channels_mode=STEREO16;
-			break;
-	}
-	Setmode(channels_mode);
-
-	Devconnect(0, 0, CLKEXT, numfreq, 1);
-
-	/* Set buffer */
-	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
-	Setbuffer(0, buffer, buffer+SDL_MintAudio_audiosize);
-	
-	/* Install interrupt */
-	NSetinterrupt(2, SI_PLAY, SDL_MintAudio_IntGsxb);
-		
-	/* Go */
-	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
-}
-
-static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
-{
-	/* Lock sound system */
-	if ((cookie_snd & SND_16BIT)!=0) {
-		if (Locksnd()!=1) {
-    	    SDL_SetError("Mint_OpenAudio: Audio system already in use");
-	        return(-1);
-		}
-	}
-
-	/* Check audio capabilities */
-	if (cookie_gsxb && ((cookie_snd & (SND_GSXB|SND_16BIT))==(SND_GSXB|SND_16BIT)) ) {
-		if (Mint_CheckAudio_Gsxb(spec)==-1) {
-			return -1;
-		}
-	} else if ((cookie_snd & SND_16BIT)!=0) {
-		Mint_CheckAudio_Xbios(spec);
-	} else if ((cookie_snd & SND_8BIT)!=0) {
-		Mint_CheckAudio_Dma8(spec);
-	}
-
-	SDL_CalculateAudioSpec(spec);
-
-	/* Allocate memory for audio buffers in DMA-able RAM */
-	spec->size = spec->samples;
-	spec->size *= spec->channels;
-	spec->size *= (spec->format & 0xFF)/8;
-
-	SDL_MintAudio_audiosize = spec->size;
-
-	SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(SDL_MintAudio_audiosize *2, MX_STRAM);
-	if (SDL_MintAudio_audiobuf[0]==NULL) {
-		SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
-		return (-1);
-	}
-	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize;
-	SDL_MintAudio_numbuf=0;
-	memset(SDL_MintAudio_audiobuf[0], 0, SDL_MintAudio_audiosize * 2);
-	SDL_MintAudio_mutex = 0;
-
-	SDL_MintAudio_device = this;
-
-	/* Setup audio hardware */
-	if (cookie_gsxb && ((cookie_snd & (SND_GSXB|SND_16BIT))==(SND_GSXB|SND_16BIT)) ) {
-		Mint_InitAudio_Gsxb(spec);
-	} else if ((cookie_snd & SND_16BIT)!=0) {
-		Mint_InitAudio_Xbios(spec);
-	} else if ((cookie_snd & SND_8BIT)!=0) {
-		Mint_InitAudio_Dma8(spec);
-	}
-
-    return 1;
-}
--- a/src/audio/mint/SDL_mintaudio.h	Tue Jul 01 16:35:54 2003 +0000
+++ b/src/audio/mint/SDL_mintaudio.h	Mon Jul 07 19:16:03 2003 +0000
@@ -1,15 +1,125 @@
 /*
- * MiNT audio driver
- * 
- * Patrice Mandin
- */
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+
+	Patrice Mandin
+*/
 
 #ifndef _SDL_mintaudio_h
 #define _SDL_mintaudio_h
 
 #include "SDL_sysaudio.h"
+#include "SDL_mintaudio_stfa.h"
 
 /* Hidden "this" pointer for the audio functions */
 #define _THIS	SDL_AudioDevice *this
 
+struct SDL_PrivateAudioData {
+	Uint32	hardfreq[16];	/* Array of replay freqs of the hardware */
+	int		sfreq;			/* First number of freq to use in the array */
+	int 	nfreq;			/* Number of freqs to use in the array */
+	int		numfreq;		/* Number of selected frequency */
+};
+
+/* Old variable names */
+#define MINTAUDIO_hardfreq		(this->hidden->hardfreq)
+#define MINTAUDIO_sfreq			(this->hidden->sfreq)
+#define MINTAUDIO_nfreq			(this->hidden->nfreq)
+#define MINTAUDIO_numfreq		(this->hidden->numfreq)
+
+/* _MCH cookie (values>>16) */
+enum {
+	MCH_ST=0,
+	MCH_STE,
+	MCH_TT,
+	MCH_F30
+};
+
+/* Master clocks for replay frequencies */
+#define MASTERCLOCK_STE		8010666		/* Not sure of this one */
+#define MASTERCLOCK_TT		16107953	/* Not sure of this one */
+#define MASTERCLOCK_FALCON1	25175000
+#define MASTERCLOCK_FALCON2	32000000	/* Only usable for DSP56K */
+#define MASTERCLOCK_FALCONEXT	-1		/* Clock on DSP56K port, unknown */
+#define MASTERCLOCK_44K		22579200	/* Standard clock for 44.1 Khz */
+#define MASTERCLOCK_48K		24576000	/* Standard clock for 48 Khz */
+
+/* Master clock predivisors */
+#define MASTERPREDIV_STE	160
+#define MASTERPREDIV_TT		320
+#define MASTERPREDIV_FALCON	256
+#define MASTERPREDIV_MILAN	256
+
+/* MFP 68901 interrupt sources */
+enum {
+	MFP_PARALLEL=0,
+	MFP_DCD,
+	MFP_CTS,
+	MFP_BITBLT,
+	MFP_TIMERD,
+	MFP_BAUDRATE=MFP_TIMERD,
+	MFP_TIMERC,
+	MFP_200HZ=MFP_TIMERC,
+	MFP_ACIA,
+	MFP_DISK,
+	MFP_TIMERB,
+	MFP_HBLANK=MFP_TIMERB,
+	MFP_TERR,
+	MFP_TBE,
+	MFP_RERR,
+	MFP_RBF,
+	MFP_TIMERA,
+	MFP_DMASOUND=MFP_TIMERA,
+	MFP_RING,
+	MFP_MONODETECT
+};
+
+/* Xbtimer() timers */
+enum {
+	XB_TIMERA=0,
+	XB_TIMERB,
+	XB_TIMERC,
+	XB_TIMERD
+};
+
+/* Variables */
+extern SDL_AudioDevice *SDL_MintAudio_device;
+extern Uint8 *SDL_MintAudio_audiobuf[2];	/* Pointers to buffers */
+extern long SDL_MintAudio_audiosize;		/* Length of audio buffer=spec->size */
+extern long SDL_MintAudio_numbuf;		/* Buffer to play */
+extern long SDL_MintAudio_mutex;
+extern cookie_stfa_t *SDL_MintAudio_stfa;
+
+/* Functions */
+void SDL_MintAudio_Callback(void);
+int SDL_MintAudio_SearchFrequency(_THIS, int falcon_codec, int desired_freq);
+
+/* ASM interrupt functions */
+void SDL_MintAudio_GsxbInterrupt(void);
+void SDL_MintAudio_EmptyGsxbInterrupt(void);
+void SDL_MintAudio_XbiosInterrupt(void);
+void SDL_MintAudio_Dma8Interrupt(void);
+void SDL_MintAudio_StfaInterrupt(void);
+
 #endif /* _SDL_mintaudio_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_dma8.c	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,354 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+	using DMA 8bits (hardware access)
+
+	Patrice Mandin
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#include "SDL_audio.h"
+#include "SDL_audio_c.h"
+#include "SDL_audiomem.h"
+#include "SDL_sysaudio.h"
+
+#include "SDL_atarimxalloc_c.h"
+
+#include "SDL_mintaudio.h"
+#include "SDL_mintaudio_dma8.h"
+
+/*--- Defines ---*/
+
+#define MINT_AUDIO_DRIVER_NAME "mint_dma8"
+
+/* Debug print info */
+#define DEBUG_NAME "audio:dma8: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/*--- Static variables ---*/
+
+static unsigned long cookie_snd, cookie_mch;
+
+/*--- Audio driver functions ---*/
+
+static void Mint_CloseAudio(_THIS);
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_LockAudio(_THIS);
+static void Mint_UnlockAudio(_THIS);
+
+/* To check/init hardware audio */
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+
+/*--- Audio driver bootstrap functions ---*/
+
+static int Audio_Available(void)
+{
+	const char *envr = getenv("SDL_AUDIODRIVER");
+
+	/* Check if user asked a different audio driver */
+	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
+		DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
+		return 0;
+	}
+
+	/* Cookie _MCH present ? if not, assume ST machine */
+	if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+		cookie_mch = MCH_ST;
+	}
+
+	/* Cookie _SND present ? if not, assume ST machine */
+	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+		cookie_snd = SND_PSG;
+	}
+
+	/* Check if we have 8 bits audio */
+	if ((cookie_snd & SND_8BIT)==0) {
+		DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
+	    return(0);
+	}
+
+	if ((cookie_mch>>16)>MCH_F30) {
+		DEBUG_PRINT((DEBUG_NAME "unknown 8 bits audio chip\n"));
+		return 0;
+	}
+
+	/* Check if audio is lockable */
+	if ((cookie_mch>>16) == MCH_F30) {
+		if (Locksnd()!=1) {
+			DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
+			return(0);
+		}
+
+		Unlocksnd();
+	}
+
+	DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
+	return(1);
+}
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+{
+    free(device->hidden);
+    free(device);
+}
+
+static SDL_AudioDevice *Audio_CreateDevice(int devindex)
+{
+	SDL_AudioDevice *this;
+
+	/* Initialize all variables that we clean on shutdown */
+	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+    if ( this ) {
+        memset(this, 0, (sizeof *this));
+        this->hidden = (struct SDL_PrivateAudioData *)
+                malloc((sizeof *this->hidden));
+    }
+    if ( (this == NULL) || (this->hidden == NULL) ) {
+        SDL_OutOfMemory();
+        if ( this ) {
+            free(this);
+        }
+        return(0);
+    }
+    memset(this->hidden, 0, (sizeof *this->hidden));
+
+    /* Set the function pointers */
+    this->OpenAudio   = Mint_OpenAudio;
+    this->CloseAudio  = Mint_CloseAudio;
+    this->LockAudio   = Mint_LockAudio;
+    this->UnlockAudio = Mint_UnlockAudio;
+    this->free        = Audio_DeleteDevice;
+
+    return this;
+}
+
+AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
+	MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver",
+	Audio_Available, Audio_CreateDevice
+};
+
+static void Mint_LockAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Stop replay */
+	oldpile=(void *)Super(0);
+	DMAAUDIO_IO.control=0;
+	Super(oldpile);
+}
+
+static void Mint_UnlockAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Restart replay */
+	oldpile=(void *)Super(0);
+	DMAAUDIO_IO.control=3;
+	Super(oldpile);
+}
+
+static void Mint_CloseAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Stop replay */
+	oldpile=(void *)Super(0);
+	DMAAUDIO_IO.control=0;
+	Super(oldpile);
+
+	DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
+
+	/* Disable interrupt */
+	Jdisint(MFP_DMASOUND);
+
+	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"));
+}
+
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int i, masterprediv;
+	unsigned long masterclock;
+
+	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	/* Check formats available */
+	spec->format = AUDIO_S8;
+	
+	/* Calculate and select the closest frequency */
+	MINTAUDIO_nfreq=4;
+	MINTAUDIO_sfreq=0;
+	masterclock=MASTERCLOCK_STE;
+	masterprediv=MASTERPREDIV_STE;
+	switch(cookie_mch>>16) {
+/*
+		case MCH_STE:
+			masterclock=MASTERCLOCK_STE;
+			masterprediv=MASTERPREDIV_STE;
+			break;
+*/
+		case MCH_TT:
+			masterclock=MASTERCLOCK_TT;
+			masterprediv=MASTERPREDIV_TT;
+			break;
+		case MCH_F30:
+			masterclock=MASTERCLOCK_FALCON1;
+			masterprediv=MASTERPREDIV_FALCON<<1;
+			MINTAUDIO_nfreq=3;
+			MINTAUDIO_sfreq=1;
+			break;
+	}
+	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+		MINTAUDIO_hardfreq[i]=masterclock/(masterprediv*(1<<i));
+		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+	}
+
+	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 0, spec->freq);
+	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
+
+	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	return 0;
+}
+
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
+{
+	void *oldpile;
+	unsigned long buffer;
+	unsigned char mode;
+	
+	/* Set replay tracks */
+	if (cookie_snd & SND_16BIT) {
+		Settracks(0,0);
+		Setmontracks(0);
+	}
+
+	oldpile=(void *)Super(0);
+
+	/* Stop currently playing sound */
+	DMAAUDIO_IO.control=0;
+
+	/* 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;
+
+	mode = 3-MINTAUDIO_numfreq;
+	if (spec->channels==1) {
+		mode |= 1<<7;
+	}
+	DMAAUDIO_IO.mode = mode;	
+
+	/* Set interrupt */
+	Jdisint(MFP_DMASOUND);
+	Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
+	Jenabint(MFP_DMASOUND);
+
+	/* Go */
+	DMAAUDIO_IO.control = 3;	/* playback + repeat */
+
+	Super(oldpile);
+}
+
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
+{
+	SDL_MintAudio_device = this;
+
+	/* Check audio capabilities */
+	if (Mint_CheckAudio(this, spec)==-1) {
+		return -1;
+	}
+
+	SDL_CalculateAudioSpec(spec);
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	spec->size = spec->samples;
+	spec->size *= spec->channels;
+	spec->size *= (spec->format & 0xFF)/8;
+
+	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);
+	}
+	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
+	SDL_MintAudio_numbuf=0;
+	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]));
+
+	/* Setup audio hardware */
+	Mint_InitAudio(this, spec);
+
+    return(1);	/* We don't use threaded audio */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_dma8.h	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,65 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	DMA 8bits audio definitions
+
+	Patrice Mandin
+*/
+
+#ifndef _SDL_mintaudio_dma8_h
+#define _SDL_mintaudio_dma8_h
+
+#define DMAAUDIO_IO_BASE (0xffff8900)
+struct DMAAUDIO_IO_S {
+	unsigned char int_ctrl;
+	unsigned char control;
+
+	unsigned char dummy1;
+	unsigned char start_high;
+	unsigned char dummy2;
+	unsigned char start_mid;
+	unsigned char dummy3;
+	unsigned char start_low;
+
+	unsigned char dummy4;
+	unsigned char cur_high;
+	unsigned char dummy5;
+	unsigned char cur_mid;
+	unsigned char dummy6;
+	unsigned char cur_low;
+
+	unsigned char dummy7;
+	unsigned char end_high;
+	unsigned char dummy8;
+	unsigned char end_mid;
+	unsigned char dummy9;
+	unsigned char end_low;
+
+	unsigned char dummy10[12];
+
+	unsigned char track_select; /* CODEC only */
+	unsigned char mode;
+};
+#define DMAAUDIO_IO ((*(volatile struct DMAAUDIO_IO_S *)DMAAUDIO_IO_BASE))
+
+#endif /* _SDL_mintaudio_dma8_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,395 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+	using XBIOS functions (GSXB compatible driver)
+
+	Patrice Mandin
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#include "SDL_audio.h"
+#include "SDL_audio_c.h"
+#include "SDL_audiomem.h"
+#include "SDL_sysaudio.h"
+
+#include "SDL_atarimxalloc_c.h"
+
+#include "SDL_mintaudio.h"
+#include "SDL_mintaudio_gsxb.h"
+
+/*--- Defines ---*/
+
+#define MINT_AUDIO_DRIVER_NAME "mint_gsxb"
+
+/* Debug print info */
+#define DEBUG_NAME "audio:gsxb: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/*--- Static variables ---*/
+
+static unsigned long cookie_snd, cookie_gsxb;
+
+/*--- Audio driver functions ---*/
+
+static void Mint_CloseAudio(_THIS);
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_LockAudio(_THIS);
+static void Mint_UnlockAudio(_THIS);
+
+/* To check/init hardware audio */
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+
+/*--- Audio driver bootstrap functions ---*/
+
+static int Audio_Available(void)
+{
+	const char *envr = getenv("SDL_AUDIODRIVER");
+
+	/* Check if user asked a different audio driver */
+	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
+		DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
+		return(0);
+	}
+
+	/* Cookie _SND present ? if not, assume ST machine */
+	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+		cookie_snd = SND_PSG;
+	}
+
+	/* Check if we have 16 bits audio */
+	if ((cookie_snd & SND_16BIT)==0) {
+		DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
+	    return(0);
+	}
+
+	/* Cookie GSXB present ? */
+	cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
+
+	/* Is it GSXB ? */
+	if (((cookie_snd & SND_GSXB)==0) || (cookie_gsxb==0)) {
+		DEBUG_PRINT((DEBUG_NAME "no GSXB audio\n"));
+		return(0);
+	}
+
+	/* Check if audio is lockable */
+	if (Locksnd()!=1) {
+		DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
+		return(0);
+	}
+
+	Unlocksnd();
+
+	DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
+	return(1);
+}
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+{
+    free(device->hidden);
+    free(device);
+}
+
+static SDL_AudioDevice *Audio_CreateDevice(int devindex)
+{
+	SDL_AudioDevice *this;
+
+	/* Initialize all variables that we clean on shutdown */
+	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+    if ( this ) {
+        memset(this, 0, (sizeof *this));
+        this->hidden = (struct SDL_PrivateAudioData *)
+                malloc((sizeof *this->hidden));
+    }
+    if ( (this == NULL) || (this->hidden == NULL) ) {
+        SDL_OutOfMemory();
+        if ( this ) {
+            free(this);
+        }
+        return(0);
+    }
+    memset(this->hidden, 0, (sizeof *this->hidden));
+
+    /* Set the function pointers */
+    this->OpenAudio   = Mint_OpenAudio;
+    this->CloseAudio  = Mint_CloseAudio;
+    this->LockAudio   = Mint_LockAudio;
+    this->UnlockAudio = Mint_UnlockAudio;
+    this->free        = Audio_DeleteDevice;
+
+    return this;
+}
+
+AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
+	MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver",
+	Audio_Available, Audio_CreateDevice
+};
+
+static void Mint_LockAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+}
+
+static void Mint_UnlockAudio(_THIS)
+{
+	/* Restart replay */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+}
+
+static void Mint_CloseAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+
+	DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
+
+	/* Uninstall interrupt */
+	if (NSetinterrupt(2, SI_NONE, SDL_MintAudio_EmptyGsxbInterrupt)<0) {
+		DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
+	}
+
+	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"));
+
+	/* Unlock sound system */
+	Unlocksnd();
+}
+
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
+{
+	long snd_format;
+	int i, resolution, format_signed, format_bigendian;
+
+	resolution = spec->format & 0x00ff;
+	format_signed = ((spec->format & 0x8000)!=0);
+	format_bigendian = ((spec->format & 0x1000)!=0);
+	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",resolution));
+	DEBUG_PRINT(("signed=%d, ", format_signed));
+	DEBUG_PRINT(("big endian=%d, ", format_bigendian));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	/* Check formats available */
+	snd_format = Sndstatus(SND_QUERYFORMATS);
+	switch (resolution) {
+		case 8:
+			if ((snd_format & SND_FORMAT8)==0) {
+				SDL_SetError("Mint_CheckAudio: 8 bits samples not supported");
+				return -1;
+			}
+			snd_format = Sndstatus(SND_QUERY8BIT);
+			break;
+		case 16:
+			if ((snd_format & SND_FORMAT16)==0) {
+				SDL_SetError("Mint_CheckAudio: 16 bits samples not supported");
+				return -1;
+			}
+			snd_format = Sndstatus(SND_QUERY16BIT);
+			break;
+		default:
+			SDL_SetError("Mint_CheckAudio: Unsupported sample resolution");
+			return -1;
+			break;
+	}
+
+	/* Check signed/unsigned format */
+	if (format_signed) {
+		if (snd_format & SND_FORMATSIGNED) {
+			/* Ok */
+		} else if (snd_format & SND_FORMATUNSIGNED) {
+			/* Give unsigned format */
+			spec->format = spec->format & (~0x8000);
+		}
+	} else {
+		if (snd_format & SND_FORMATUNSIGNED) {
+			/* Ok */
+		} else if (snd_format & SND_FORMATSIGNED) {
+			/* Give signed format */
+			spec->format |= 0x8000;
+		}
+	}
+
+	if (format_bigendian) {
+		if (snd_format & SND_FORMATBIGENDIAN) {
+			/* Ok */
+		} else if (snd_format & SND_FORMATLITTLEENDIAN) {
+			/* Give little endian format */
+			spec->format = spec->format & (~0x1000);
+		}
+	} else {
+		if (snd_format & SND_FORMATBIGENDIAN) {
+			/* Ok */
+		} else if (snd_format & SND_FORMATLITTLEENDIAN) {
+			/* Give big endian format */
+			spec->format |= 0x1000;
+		}
+	}
+	
+	/* Calculate and select the closest frequency */
+	MINTAUDIO_sfreq=1;
+	MINTAUDIO_nfreq=12;
+	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+		MINTAUDIO_hardfreq[i]=MASTERCLOCK_44K/(MASTERPREDIV_MILAN*(i+1));
+		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+	}
+
+	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 1, spec->freq);
+	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
+
+	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	return 0;
+}
+
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int channels_mode;
+	void *buffer;
+
+	/* Stop currently playing sound */
+	Buffoper(0);
+
+	/* Set replay tracks */
+	Settracks(0,0);
+	Setmontracks(0);
+
+	/* Select replay format */
+	switch (spec->format & 0xff) {
+		case 8:
+			if (spec->channels==2) {
+				channels_mode=STEREO8;
+			} else {
+				channels_mode=MONO8;
+			}
+			break;
+		case 16:
+			if (spec->channels==2) {
+				channels_mode=STEREO16;
+			} else {
+				channels_mode=MONO16;
+			}
+			break;
+		default:
+			channels_mode=STEREO16;
+			break;
+	}
+	if (Setmode(channels_mode)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
+	}
+
+	Devconnect(DMAPLAY, DAC, CLKEXT, MINTAUDIO_numfreq, 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"));
+	}
+	
+	/* Install interrupt */
+	if (NSetinterrupt(2, SI_PLAY, SDL_MintAudio_GsxbInterrupt)<0) {
+		DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n"));
+	}
+
+	/* Go */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+	DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
+}
+
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
+{
+	/* Lock sound system */
+	if (Locksnd()!=1) {
+   	    SDL_SetError("Mint_OpenAudio: Audio system already in use");
+        return(-1);
+	}
+
+	SDL_MintAudio_device = this;
+
+	/* Check audio capabilities */
+	if (Mint_CheckAudio(this, spec)==-1) {
+		return -1;
+	}
+
+	SDL_CalculateAudioSpec(spec);
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	spec->size = spec->samples;
+	spec->size *= spec->channels;
+	spec->size *= (spec->format & 0xFF)/8;
+
+	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);
+	}
+	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
+	SDL_MintAudio_numbuf=0;
+	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]));
+
+	/* Setup audio hardware */
+	Mint_InitAudio(this, spec);
+
+    return(1);	/* We don't use threaded audio */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_gsxb.h	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,85 @@
+/*
+ * GSXB audio definitions
+ * 
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_mintaudio_gsxb_h
+#define _SDL_mintaudio_gsxb_h
+
+#include <mint/falcon.h>	/* for trap_14_xxx macros */
+
+/* GSXB Cookie */
+
+#define C_GSXB		0x47535842L
+
+/* Bit 5 in cookie _SND */
+
+#define SND_GSXB	(1<<5)
+
+/* NSoundcmd modes */
+
+#define SETRATE			7	/* Set sample rate */
+#define SET8BITFORMAT	8	/* 8 bits format */
+#define SET16BITFORMAT	9	/* 16 bits format */
+#define SET24BITFORMAT	10	/* 24 bits format */
+#define SET32BITFORMAT	11	/* 32 bits format */
+#define LTATTEN_MASTER	12	/* Attenuation */
+#define RTATTEN_MASTER	13
+#define LTATTEN_MICIN	14
+#define RTATTEN_MICIN	15
+#define LTATTEN_FMGEN	16
+#define RTATTEN_FMGEN	17
+#define LTATTEN_LINEIN	18
+#define RTATTEN_LINEIN	19
+#define LTATTEN_CDIN	20
+#define RTATTEN_CDIN	21
+#define LTATTEN_VIDIN	22
+#define RTATTEN_VIDIN	23
+#define LTATTEN_AUXIN	24
+#define RTATTEN_AUXIN	25
+
+/* Setmode modes */
+
+#define MONO16		3
+#define STEREO24	4
+#define STEREO32	5
+#define MONO24		6
+#define MONO32		7
+
+/* Sndstatus modes */
+
+#define SND_QUERYFORMATS	2
+#define SND_QUERYMIXERS		3
+#define SND_QUERYSOURCES	4
+#define SND_QUERYDUPLEX		5
+#define SND_QUERY8BIT		8
+#define SND_QUERY16BIT		9
+#define SND_QUERY24BIT		10
+#define SND_QUERY32BIT		11
+
+#define SND_FORMAT8		(1<<0)
+#define SND_FORMAT16	(1<<1)
+#define SND_FORMAT24	(1<<2)
+#define SND_FORMAT32	(1<<3)
+
+#define SND_FORMATSIGNED		(1<<0)
+#define SND_FORMATUNSIGNED		(1<<1)
+#define SND_FORMATBIGENDIAN		(1<<2)
+#define SND_FORMATLITTLEENDIAN	(1<<3)
+
+/* Devconnect prescalers */
+
+#define CLK_44K		1
+#define CLK_22K		3
+#define CLK_11K		7
+
+/* Extra xbios functions */
+
+#define NSoundcmd(mode,data,data2)	\
+	(long)trap_14_wwl((short)130,(short)(mode),(short)(data),(long)(data2))
+#define NSetinterrupt(src_inter,cause,inth_addr)	\
+	(long)trap_14_wwwl((short)135,(short)(src_inter),(short)(cause),	\
+		(long)(inth_addr))
+
+#endif /* _SDL_mintaudio_gsxb_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_it.S	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,242 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	Audio interrupts
+
+	Patrice Mandin
+ */
+
+	.text
+
+	.globl	_SDL_MintAudio_Callback
+
+	.globl	_SDL_MintAudio_GsxbInterrupt
+	.globl	_SDL_MintAudio_EmptyGsxbInterrupt
+	.globl	_SDL_MintAudio_XbiosInterrupt
+	.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_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
+*/
+
+/*--- GSXB interrupt vector ---*/
+
+	.text
+_SDL_MintAudio_GsxbInterrupt:
+
+	/* Check if we are not already running */
+	tstw	_SDL_MintAudio_mutex
+	bnes	_SDL_MintAudio_EmptyGsxbInterrupt
+	notw	_SDL_MintAudio_mutex
+	
+	/* Swap buffers */
+	moveml	d0-d2/a0-a2,sp@-
+
+	movel	_SDL_MintAudio_numbuf,d0
+	movel	_SDL_MintAudio_audiobuf,a0
+	eorl	#1,d0
+	beqs	SDL_MintAudio_GsxbBuffer0
+	movel	_SDL_MintAudio_audiobuf+4,a0
+SDL_MintAudio_GsxbBuffer0:
+	movel	d0,_SDL_MintAudio_numbuf
+
+	/* Callback */
+	movel	a0,sp@-
+	jsr	_SDL_MintAudio_Callback
+	movel	sp@+,a0
+
+	/* Setbuffer xbios function */
+	movel	_SDL_MintAudio_audiosize,d1
+	lea	a0@(0,d1:l),a1
+
+	movel	a1,sp@-
+	movel	a0,sp@-
+	clrw	sp@-
+	movew	#131,sp@-
+	trap	#14
+	lea	sp@(12),sp
+
+	moveml	sp@+,d0-d2/a0-a2
+
+	clrw	_SDL_MintAudio_mutex
+_SDL_MintAudio_EmptyGsxbInterrupt:
+	rts
+
+/*--- Xbios interrupt vector ---*/
+
+_SDL_MintAudio_XbiosInterrupt:
+
+	/* Reenable interrupts, so other interrupts can work */
+	movew	#0x2300,sr
+
+	/* Clear service bit, so other MFP interrupts can work */
+	bclr	#5,0xfffffa0f:w
+
+	/* Check if we are not already running */
+	tstw	_SDL_MintAudio_mutex
+	bnes	SDL_MintAudio_XbiosEnd
+	notw	_SDL_MintAudio_mutex
+	
+	/* Swap buffers */
+	moveml	d0-d2/a0-a2,sp@-
+
+	movel	_SDL_MintAudio_numbuf,d0
+	movel	_SDL_MintAudio_audiobuf,a0
+	eorl	#1,d0
+	beqs	SDL_MintAudio_XbiosBuffer0
+	movel	_SDL_MintAudio_audiobuf+4,a0
+SDL_MintAudio_XbiosBuffer0:
+	movel	d0,_SDL_MintAudio_numbuf
+
+	/* Callback */
+	movel	a0,sp@-
+	jsr	_SDL_MintAudio_Callback
+	movel	sp@+,a0
+
+	/* Setbuffer xbios function */
+	movel	_SDL_MintAudio_audiosize,d1
+	lea	a0@(0,d1:l),a1
+
+	movel	a1,sp@-
+	movel	a0,sp@-
+	clrw	sp@-
+	movew	#131,sp@-
+	trap	#14
+	lea	sp@(12),sp
+
+	moveml	sp@+,d0-d2/a0-a2
+
+	clrw	_SDL_MintAudio_mutex
+SDL_MintAudio_XbiosEnd:
+	rte
+
+/*--- DMA 8 bits interrupt vector ---*/
+
+_SDL_MintAudio_Dma8Interrupt:
+
+	/* Reenable interrupts, so other interrupts can work */
+	movew	#0x2300,sr
+
+	/* Clear service bit, so other MFP interrupts can work */
+	bclr	#5,0xfffffa0f:w
+
+	/* Check if we are not already running */
+	tstw	_SDL_MintAudio_mutex
+	bnes	SDL_MintAudio_Dma8End
+	notw	_SDL_MintAudio_mutex
+	
+	/* Swap buffers */
+	moveml	d0-d1/a0-a1,sp@-
+
+	movel	_SDL_MintAudio_numbuf,d0
+	movel	_SDL_MintAudio_audiobuf,d1
+	eorl	#1,d0
+	beqs	SDL_MintAudio_Dma8Buffer0
+	movel	_SDL_MintAudio_audiobuf+4,d1
+SDL_MintAudio_Dma8Buffer0:
+	movel	d0,_SDL_MintAudio_numbuf
+
+	/* Callback */
+	movel	d1,sp@-
+	jsr	_SDL_MintAudio_Callback
+	movel	sp@+,d1
+
+	/* Modify DMA addresses */
+	lea	0xffff8900:w,a0
+
+	moveb	d1,a0@(0x07)	/* Start address */
+	rorl	#8,d1
+	moveb	d1,a0@(0x05)
+	rorl	#8,d1
+	moveb	d1,a0@(0x03)
+	swap	d1
+
+	addl	_SDL_MintAudio_audiosize,d1
+
+	moveb	d1,a0@(0x13)	/* End address */
+	rorl	#8,d1
+	moveb	d1,a0@(0x11)
+	rorl	#8,d1
+	moveb	d1,a0@(0x0f)
+
+	moveml	sp@+,d0-d1/a0-a1
+
+	clrw	_SDL_MintAudio_mutex
+SDL_MintAudio_Dma8End:
+	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
+	bnes	SDL_MintAudio_StfaEnd
+	notw	_SDL_MintAudio_mutex
+	
+	/* Swap buffers */
+	moveml	d0-d1/a0-a1,sp@-
+
+	movel	_SDL_MintAudio_numbuf,d0
+	movel	_SDL_MintAudio_audiobuf,d1
+	eorl	#1,d0
+	beqs	SDL_MintAudio_StfaBuffer0
+	movel	_SDL_MintAudio_audiobuf+4,d1
+SDL_MintAudio_StfaBuffer0:
+	movel	d0,_SDL_MintAudio_numbuf
+
+	/* Callback */
+	movel	d1,sp@-
+	jsr	_SDL_MintAudio_Callback
+	movel	sp@+,d1
+
+	/* Modify STFA replay buffers */
+	movel	_SDL_MintAudio_stfa,a0
+	movel	d1,a0@(STFA_SOUND_START)
+	addl	_SDL_MintAudio_audiosize,d1
+	movel	d1,a0@(STFA_SOUND_END)
+
+	moveml	sp@+,d0-d1/a0-a1
+
+	clrw	_SDL_MintAudio_mutex
+SDL_MintAudio_StfaEnd:
+	rte
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,379 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+	using XBIOS functions (MacSound compatible driver)
+
+	Patrice Mandin
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#include "SDL_audio.h"
+#include "SDL_audio_c.h"
+#include "SDL_audiomem.h"
+#include "SDL_sysaudio.h"
+
+#include "SDL_atarimxalloc_c.h"
+
+#include "SDL_mintaudio.h"
+#include "SDL_mintaudio_mcsn.h"
+
+/*--- Defines ---*/
+
+#define MINT_AUDIO_DRIVER_NAME "mint_mcsn"
+
+/* Debug print info */
+#define DEBUG_NAME "audio:mcsn: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/*--- Static variables ---*/
+
+static unsigned long cookie_snd, cookie_mch;
+static cookie_mcsn_t *cookie_mcsn;
+
+/*--- Audio driver functions ---*/
+
+static void Mint_CloseAudio(_THIS);
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_LockAudio(_THIS);
+static void Mint_UnlockAudio(_THIS);
+
+/* To check/init hardware audio */
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+
+/*--- Audio driver bootstrap functions ---*/
+
+static int Audio_Available(void)
+{
+	const char *envr = getenv("SDL_AUDIODRIVER");
+
+	/* Check if user asked a different audio driver */
+	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
+		DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
+		return(0);
+	}
+
+	/* Cookie _MCH present ? if not, assume ST machine */
+	if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+		cookie_mch = MCH_ST;
+	}
+
+	/* Cookie _SND present ? if not, assume ST machine */
+	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+		cookie_snd = SND_PSG;
+	}
+
+	/* Check if we have 16 bits audio */
+	if ((cookie_snd & SND_16BIT)==0) {
+		DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
+	    return(0);
+	}
+
+	/* Cookie MCSN present ? */
+	if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
+		DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n"));
+		return(0);
+	}
+
+	/* Check if interrupt at end of replay */
+	if (cookie_mcsn->pint == 0) {
+		DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n"));
+		return(0);
+	}
+
+	/* Check if audio is lockable */
+	if (Locksnd()!=1) {
+		DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
+		return(0);
+	}
+
+	Unlocksnd();
+
+	DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
+	return(1);
+}
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+{
+    free(device->hidden);
+    free(device);
+}
+
+static SDL_AudioDevice *Audio_CreateDevice(int devindex)
+{
+	SDL_AudioDevice *this;
+
+	/* Initialize all variables that we clean on shutdown */
+	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+    if ( this ) {
+        memset(this, 0, (sizeof *this));
+        this->hidden = (struct SDL_PrivateAudioData *)
+                malloc((sizeof *this->hidden));
+    }
+    if ( (this == NULL) || (this->hidden == NULL) ) {
+        SDL_OutOfMemory();
+        if ( this ) {
+            free(this);
+        }
+        return(0);
+    }
+    memset(this->hidden, 0, (sizeof *this->hidden));
+
+    /* Set the function pointers */
+    this->OpenAudio   = Mint_OpenAudio;
+    this->CloseAudio  = Mint_CloseAudio;
+    this->LockAudio   = Mint_LockAudio;
+    this->UnlockAudio = Mint_UnlockAudio;
+    this->free        = Audio_DeleteDevice;
+
+    return this;
+}
+
+AudioBootStrap MINTAUDIO_MCSN_bootstrap = {
+	MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver",
+	Audio_Available, Audio_CreateDevice
+};
+
+static void Mint_LockAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+}
+
+static void Mint_UnlockAudio(_THIS)
+{
+	/* Restart replay */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+}
+
+static void Mint_CloseAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+
+	/* Uninstall interrupt */
+	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;
+	}
+
+	/* Unlock sound system */
+	Unlocksnd();
+}
+
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int i;
+	unsigned long masterclock, masterprediv;
+
+	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	/* Check formats available */
+	MINTAUDIO_nfreq=4;
+	MINTAUDIO_sfreq=0;
+	switch(cookie_mcsn->play) {
+		case MCSN_ST:
+			spec->channels=1;
+			spec->format=8; /* FIXME: is it signed or unsigned ? */
+			MINTAUDIO_nfreq=1;
+			MINTAUDIO_hardfreq[0]=12500;
+			break;
+		case MCSN_TT:	/* Also STE, Mega STE */
+			spec->format=AUDIO_S8;
+			masterclock=MASTERCLOCK_STE;
+			masterprediv=MASTERPREDIV_STE;
+			if ((cookie_mch>>16)==MCH_TT) {
+				masterclock=MASTERCLOCK_TT;
+				masterprediv=MASTERPREDIV_TT;
+			}
+			for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+				MINTAUDIO_hardfreq[i]=masterclock/(masterprediv*(1<<i));
+				DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+			}
+			break;
+		case MCSN_FALCON:	/* Also Mac */
+			MINTAUDIO_nfreq=12;
+			MINTAUDIO_sfreq=1;
+			masterclock=MASTERCLOCK_FALCON1;
+			if (cookie_mcsn->res1 != 0) {
+				masterclock=cookie_mcsn->res1;
+			}
+			for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+				MINTAUDIO_hardfreq[i]=masterclock/(MASTERPREDIV_FALCON*(i+1));
+				DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+			}
+			spec->format |= 0x8000;	/* Audio is always signed */
+			if ((spec->format & 0x00ff)==16) {
+				spec->format |= 0x1000;	/* Audio is always big endian */
+				spec->channels=2;	/* 16 bits always stereo */
+			}
+			break;
+	}
+
+	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, (cookie_mch>>16)==MCH_F30, spec->freq);
+	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
+
+	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	return 0;
+}
+
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int channels_mode;
+	void *buffer;
+
+	/* Stop currently playing sound */
+	Buffoper(0);
+
+	/* Set replay tracks */
+	Settracks(0,0);
+	Setmontracks(0);
+
+	/* Select replay format */
+	channels_mode=STEREO16;
+	switch (spec->format & 0xff) {
+		case 8:
+			if (spec->channels==2) {
+				channels_mode=STEREO8;
+			} else {
+				channels_mode=MONO8;
+			}
+			break;
+	}
+	if (Setmode(channels_mode)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
+	}
+
+	switch(cookie_mcsn->play) {
+		case MCSN_TT:
+			Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1);
+			Soundcmd(SETPRESCALE, 3-MINTAUDIO_numfreq);
+			DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n"));
+			break;
+		case MCSN_FALCON:
+			if (cookie_mcsn->res1 != 0) {
+				Devconnect(DMAPLAY, DAC, CLKEXT, MINTAUDIO_numfreq, 1);
+				DEBUG_PRINT((DEBUG_NAME "External clock selected, prescaler %d\n", MINTAUDIO_numfreq));
+			} else {
+				Devconnect(DMAPLAY, DAC, CLK25M, MINTAUDIO_numfreq, 1);
+				DEBUG_PRINT((DEBUG_NAME "25.175 MHz clock selected, prescaler %d\n", MINTAUDIO_numfreq));
+			}
+			break;
+	}
+
+	/* Set buffer */
+	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
+	if (Setbuffer(0, buffer, buffer + spec->size)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
+	}
+	
+	/* Install interrupt */
+	Jdisint(MFP_DMASOUND);
+	Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);
+	Jenabint(MFP_DMASOUND);
+
+	if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n"));
+	}
+
+	/* Go */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+	DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
+}
+
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
+{
+	/* Lock sound system */
+	if (Locksnd()!=1) {
+   	    SDL_SetError("Mint_OpenAudio: Audio system already in use");
+        return(-1);
+	}
+
+	SDL_MintAudio_device = this;
+
+	/* Check audio capabilities */
+	if (Mint_CheckAudio(this, spec)==-1) {
+		return -1;
+	}
+
+	SDL_CalculateAudioSpec(spec);
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	spec->size = spec->samples;
+	spec->size *= spec->channels;
+	spec->size *= (spec->format & 0xFF)/8;
+
+	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);
+	}
+	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
+	SDL_MintAudio_numbuf=0;
+	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]));
+
+	/* Setup audio hardware */
+	Mint_InitAudio(this, spec);
+
+    return(1);	/* We don't use threaded audio */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_mcsn.h	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,58 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MCSN control structure
+
+	Patrice Mandin
+*/
+
+#ifndef _SDL_mintaudio_mcsh_h
+#define _SDL_mintaudio_mcsh_h
+
+typedef struct {
+	unsigned short version;	/* Version */
+	unsigned short size;	/* Size of structure */
+
+	unsigned short play;	/* Replay capability */
+	unsigned short record;	/* Record capability */
+	unsigned short dsp;		/* DSP56K present */
+	unsigned short pint;	/* Interrupt at end of replay */
+	unsigned short rint;	/* Interrupt at end of record */
+
+	unsigned long res1;		/* Frequency of external clock */
+	unsigned long res2;
+	unsigned long res3;
+	unsigned long res4;
+} cookie_mcsn_t __attribute__((packed));
+
+enum {
+	MCSN_ST=0,
+	MCSN_TT,
+	MCSN_STE=MCSN_TT,
+	MCSN_FALCON,
+	MCSN_MAC=MCSN_FALCON
+};
+
+#define SETSMPFREQ	7	/* Set sample frequency */
+
+#endif /* _SDL_mintaudio_mcsh_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_stfa.c	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,319 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+	using XBIOS functions (STFA driver)
+
+	Patrice Mandin
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#include "SDL_audio.h"
+#include "SDL_audio_c.h"
+#include "SDL_audiomem.h"
+#include "SDL_sysaudio.h"
+
+#include "SDL_atarimxalloc_c.h"
+
+#include "SDL_mintaudio.h"
+#include "SDL_mintaudio_stfa.h"
+
+/*--- Defines ---*/
+
+#define MINT_AUDIO_DRIVER_NAME "mint_stfa"
+
+/* Debug print info */
+#define DEBUG_NAME "audio:stfa: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/*--- Static variables ---*/
+
+static unsigned long cookie_snd, cookie_mch;
+static cookie_stfa_t *cookie_stfa;
+
+static const int freqs[16]={
+	4995,	6269,	7493,	8192,
+	9830,	10971,	12538,	14985,
+	16384,	19819,	21943,	24576,
+	30720,	32336,	43885,	49152
+};
+
+/*--- Audio driver functions ---*/
+
+static void Mint_CloseAudio(_THIS);
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_LockAudio(_THIS);
+static void Mint_UnlockAudio(_THIS);
+
+/* To check/init hardware audio */
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+
+/*--- Audio driver bootstrap functions ---*/
+
+static int Audio_Available(void)
+{
+	const char *envr = getenv("SDL_AUDIODRIVER");
+
+	/* Check if user asked a different audio driver */
+	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
+		DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
+		return(0);
+	}
+
+	/* Cookie _MCH present ? if not, assume ST machine */
+	if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+		cookie_mch = MCH_ST;
+	}
+
+	/* Cookie _SND present ? if not, assume ST machine */
+	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+		cookie_snd = SND_PSG;
+	}
+
+	/* Cookie STFA present ? */
+	if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) {
+		DEBUG_PRINT((DEBUG_NAME "no STFA audio\n"));
+		return(0);
+	}
+
+	SDL_MintAudio_stfa = cookie_stfa;
+
+	DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
+	return(1);
+}
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+{
+    free(device->hidden);
+    free(device);
+}
+
+static SDL_AudioDevice *Audio_CreateDevice(int devindex)
+{
+	SDL_AudioDevice *this;
+
+	/* Initialize all variables that we clean on shutdown */
+	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+    if ( this ) {
+        memset(this, 0, (sizeof *this));
+        this->hidden = (struct SDL_PrivateAudioData *)
+                malloc((sizeof *this->hidden));
+    }
+    if ( (this == NULL) || (this->hidden == NULL) ) {
+        SDL_OutOfMemory();
+        if ( this ) {
+            free(this);
+        }
+        return(0);
+    }
+    memset(this->hidden, 0, (sizeof *this->hidden));
+
+    /* Set the function pointers */
+    this->OpenAudio   = Mint_OpenAudio;
+    this->CloseAudio  = Mint_CloseAudio;
+    this->LockAudio   = Mint_LockAudio;
+    this->UnlockAudio = Mint_UnlockAudio;
+    this->free        = Audio_DeleteDevice;
+
+    return this;
+}
+
+AudioBootStrap MINTAUDIO_STFA_bootstrap = {
+	MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver",
+	Audio_Available, Audio_CreateDevice
+};
+
+static void Mint_LockAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Stop replay */
+	oldpile=(void *)Super(0);
+	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
+	Super(oldpile);
+}
+
+static void Mint_UnlockAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Restart replay */
+	oldpile=(void *)Super(0);
+	cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT;
+	Super(oldpile);
+}
+
+static void Mint_CloseAudio(_THIS)
+{
+	void *oldpile;
+
+	/* Stop replay */
+	oldpile=(void *)Super(0);
+	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
+	Super(oldpile);
+
+	/* 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;
+	}
+}
+
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int i;
+
+	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	/* Check formats available */
+	MINTAUDIO_nfreq=16;
+	MINTAUDIO_sfreq=0;
+	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+		MINTAUDIO_hardfreq[i]=freqs[15-i];
+		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+	}
+
+	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 0, spec->freq);
+	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
+
+	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	return 0;
+}
+
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
+{
+	void *buffer;
+	void *oldpile;
+
+	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
+
+	oldpile=(void *)Super(0);
+
+	/* Stop replay */
+	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
+
+	/* Select replay format */
+	cookie_stfa->sound_control = 15-MINTAUDIO_numfreq;
+	if ((spec->format & 0xff)==8) {
+		cookie_stfa->sound_control |= STFA_FORMAT_8BIT;
+	} else {
+		cookie_stfa->sound_control |= STFA_FORMAT_16BIT;
+	}
+	if (spec->channels==2) {
+		cookie_stfa->sound_control |= STFA_FORMAT_STEREO;
+	} else {
+		cookie_stfa->sound_control |= STFA_FORMAT_MONO;
+	}
+	if (spec->format & 0x8000) {
+		cookie_stfa->sound_control |= STFA_FORMAT_SIGNED;
+	} else {
+		cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED;
+	}
+	if (spec->format & 0x1000) {
+		cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN;
+	} else {
+		cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN;
+	}
+
+	/* Set buffer */
+	cookie_stfa->sound_start = (unsigned long) buffer;
+	cookie_stfa->sound_end = (unsigned long) (buffer + spec->size);
+
+	/* Set interrupt */
+	cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt;
+
+	/* Restart replay */
+	cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT;
+
+	Super(oldpile);
+
+	DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
+}
+
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
+{
+	SDL_MintAudio_device = this;
+
+	/* Check audio capabilities */
+	if (Mint_CheckAudio(this, spec)==-1) {
+		return -1;
+	}
+
+	SDL_CalculateAudioSpec(spec);
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	spec->size = spec->samples;
+	spec->size *= spec->channels;
+	spec->size *= (spec->format & 0xFF)/8;
+
+	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);
+	}
+	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
+	SDL_MintAudio_numbuf=0;
+	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]));
+
+	/* Setup audio hardware */
+	Mint_InitAudio(this, spec);
+
+    return(1);	/* We don't use threaded audio */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_stfa.h	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,99 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	STFA control structure
+
+	Patrice Mandin
+*/
+
+#ifndef _SDL_mintaudio_stfa_h
+#define _SDL_mintaudio_stfa_h
+
+/*--- Defines ---*/
+
+#define C_STFA	0x53544641L	/* Sound treiber für atari (seb/The removers) */
+
+#define STFA_PLAY_ENABLE	(1<<0)
+#define STFA_PLAY_DISABLE	(0<<0)
+#define STFA_PLAY_REPEAT	(1<<1)
+#define STFA_PLAY_SINGLE	(0<<1)
+
+#define STFA_FORMAT_SIGNED		(1<<15)
+#define STFA_FORMAT_UNSIGNED	(0<<15)
+#define STFA_FORMAT_STEREO		(1<<14)
+#define STFA_FORMAT_MONO		(0<<14)
+#define STFA_FORMAT_16BIT		(1<<13)
+#define STFA_FORMAT_8BIT		(0<<13)
+#define STFA_FORMAT_LITENDIAN	(1<<9)
+#define STFA_FORMAT_BIGENDIAN	(0<<9)
+#define STFA_FORMAT_FREQ_MASK	0x0f
+enum {
+	STFA_FORMAT_F4995=0,
+	STFA_FORMAT_F6269,
+	STFA_FORMAT_F7493,
+	STFA_FORMAT_F8192,
+
+	STFA_FORMAT_F9830,
+	STFA_FORMAT_F10971,
+	STFA_FORMAT_F12538,
+	STFA_FORMAT_F14985,
+
+	STFA_FORMAT_F16384,
+	STFA_FORMAT_F19819,
+	STFA_FORMAT_F21943,
+	STFA_FORMAT_F24576,
+
+	STFA_FORMAT_F30720,
+	STFA_FORMAT_F32336,
+	STFA_FORMAT_F43885,
+	STFA_FORMAT_F49152
+};
+
+/*--- Types ---*/
+
+typedef struct {
+	unsigned short sound_enable;
+	unsigned short sound_control;
+	unsigned short sound_output;
+	unsigned long sound_start;
+	unsigned long sound_current;
+	unsigned long sound_end;
+	unsigned short version;
+	void *old_vbl;
+	void *old_timera;
+	unsigned long old_mfp_status;
+	void *new_vbl;
+	void *drivers_list;
+	void *play_stop;
+	unsigned short frequency;
+	void *set_frequency;
+	
+	unsigned short frequency_threshold;
+	unsigned short *custom_freq_table;
+	unsigned short stfa_on_off;
+	void *new_drivers_list;
+	unsigned long old_bit_2_of_cookie_snd;
+	void (*stfa_it)(void);
+} cookie_stfa_t __attribute__((packed));
+
+#endif /* _SDL_mintaudio_stfa_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/mint/SDL_mintaudio_xbios.c	Mon Jul 07 19:16:03 2003 +0000
@@ -0,0 +1,319 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/*
+	MiNT audio driver
+	using XBIOS functions (Falcon)
+
+	Patrice Mandin
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#include "SDL_audio.h"
+#include "SDL_audio_c.h"
+#include "SDL_audiomem.h"
+#include "SDL_sysaudio.h"
+
+#include "SDL_atarimxalloc_c.h"
+
+#include "SDL_mintaudio.h"
+
+/*--- Defines ---*/
+
+#define MINT_AUDIO_DRIVER_NAME "mint_xbios"
+
+/* Debug print info */
+#define DEBUG_NAME "audio:xbios: "
+#if 0
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
+#else
+#define DEBUG_PRINT(what)
+#endif
+
+/*--- Static variables ---*/
+
+static unsigned long cookie_snd;
+
+/*--- Audio driver functions ---*/
+
+static void Mint_CloseAudio(_THIS);
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_LockAudio(_THIS);
+static void Mint_UnlockAudio(_THIS);
+
+/* To check/init hardware audio */
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
+
+/*--- Audio driver bootstrap functions ---*/
+
+static int Audio_Available(void)
+{
+	const char *envr = getenv("SDL_AUDIODRIVER");
+
+	/* Check if user asked a different audio driver */
+	if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
+		DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
+		return(0);
+	}
+
+	/* Cookie _SND present ? if not, assume ST machine */
+	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+		cookie_snd = SND_PSG;
+	}
+
+	/* Check if we have 16 bits audio */
+	if ((cookie_snd & SND_16BIT)==0) {
+		DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
+	    return(0);
+	}
+
+	/* Check if audio is lockable */
+	if (Locksnd()!=1) {
+		DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
+		return(0);
+	}
+
+	Unlocksnd();
+
+	DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n"));
+	return(1);
+}
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+{
+    free(device->hidden);
+    free(device);
+}
+
+static SDL_AudioDevice *Audio_CreateDevice(int devindex)
+{
+	SDL_AudioDevice *this;
+
+	/* Initialize all variables that we clean on shutdown */
+	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+    if ( this ) {
+        memset(this, 0, (sizeof *this));
+        this->hidden = (struct SDL_PrivateAudioData *)
+                malloc((sizeof *this->hidden));
+    }
+    if ( (this == NULL) || (this->hidden == NULL) ) {
+        SDL_OutOfMemory();
+        if ( this ) {
+            free(this);
+        }
+        return(0);
+    }
+    memset(this->hidden, 0, (sizeof *this->hidden));
+
+    /* Set the function pointers */
+    this->OpenAudio   = Mint_OpenAudio;
+    this->CloseAudio  = Mint_CloseAudio;
+    this->LockAudio   = Mint_LockAudio;
+    this->UnlockAudio = Mint_UnlockAudio;
+    this->free        = Audio_DeleteDevice;
+
+    return this;
+}
+
+AudioBootStrap MINTAUDIO_XBIOS_bootstrap = {
+	MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver",
+	Audio_Available, Audio_CreateDevice
+};
+
+static void Mint_LockAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+}
+
+static void Mint_UnlockAudio(_THIS)
+{
+	/* Restart replay */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+}
+
+static void Mint_CloseAudio(_THIS)
+{
+	/* Stop replay */
+	Buffoper(0);
+
+	/* Uninstall interrupt */
+	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;
+	}
+
+	/* Unlock sound system */
+	Unlocksnd();
+}
+
+static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int i;
+
+	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	spec->format |= 0x8000;	/* Audio is always signed */
+	if ((spec->format & 0x00ff)==16) {
+		spec->format |= 0x1000;	/* Audio is always big endian */
+		spec->channels=2;	/* 16 bits always stereo */
+	}
+
+	/* FIXME: check for an external clock */
+	MINTAUDIO_sfreq=1;
+	MINTAUDIO_nfreq=12;
+	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
+		MINTAUDIO_hardfreq[i]=MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1));
+		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
+	}
+
+	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 1, spec->freq);
+	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
+
+	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
+	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
+	DEBUG_PRINT(("channels=%d, ", spec->channels));
+	DEBUG_PRINT(("freq=%d\n", spec->freq));
+
+	return 0;
+}
+
+static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
+{
+	int channels_mode;
+	void *buffer;
+
+	/* Stop currently playing sound */
+	Buffoper(0);
+
+	/* Set replay tracks */
+	Settracks(0,0);
+	Setmontracks(0);
+
+	/* Select replay format */
+	channels_mode=STEREO16;
+	switch (spec->format & 0xff) {
+		case 8:
+			if (spec->channels==2) {
+				channels_mode=STEREO8;
+			} else {
+				channels_mode=MONO8;
+			}
+			break;
+	}
+	if (Setmode(channels_mode)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
+	}
+
+	/* FIXME: select an external clock */
+
+	Devconnect(DMAPLAY, DAC, CLK25M, MINTAUDIO_numfreq, 1);
+	DEBUG_PRINT((DEBUG_NAME "25.175 MHz clock selected, prescaler %d\n", MINTAUDIO_numfreq));
+
+	/* Set buffer */
+	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
+	if (Setbuffer(0, buffer, buffer + spec->size)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
+	}
+	
+	/* Install interrupt */
+	Jdisint(MFP_DMASOUND);
+	Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);
+	Jenabint(MFP_DMASOUND);
+
+	if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) {
+		DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n"));
+	}
+
+	/* Go */
+	Buffoper(SB_PLA_ENA|SB_PLA_RPT);
+	DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
+}
+
+static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
+{
+	/* Lock sound system */
+	if (Locksnd()!=1) {
+   	    SDL_SetError("Mint_OpenAudio: Audio system already in use");
+        return(-1);
+	}
+
+	SDL_MintAudio_device = this;
+
+	/* Check audio capabilities */
+	if (Mint_CheckAudio(this, spec)==-1) {
+		return -1;
+	}
+
+	SDL_CalculateAudioSpec(spec);
+
+	/* Allocate memory for audio buffers in DMA-able RAM */
+	spec->size = spec->samples;
+	spec->size *= spec->channels;
+	spec->size *= (spec->format & 0xFF)/8;
+
+	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);
+	}
+	SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
+	SDL_MintAudio_numbuf=0;
+	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]));
+
+	/* Setup audio hardware */
+	Mint_InitAudio(this, spec);
+
+    return(1);	/* We don't use threaded audio */
+}