summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio/SDL_audio.c6
-rw-r--r--src/audio/SDL_sysaudio.h6
-rw-r--r--src/audio/mint/Makefile.am19
-rw-r--r--src/audio/mint/SDL_mintaudio.c649
-rw-r--r--src/audio/mint/SDL_mintaudio.h118
-rw-r--r--src/audio/mint/SDL_mintaudio_dma8.c354
-rw-r--r--src/audio/mint/SDL_mintaudio_dma8.h65
-rw-r--r--src/audio/mint/SDL_mintaudio_gsxb.c395
-rw-r--r--src/audio/mint/SDL_mintaudio_gsxb.h85
-rw-r--r--src/audio/mint/SDL_mintaudio_it.S242
-rw-r--r--src/audio/mint/SDL_mintaudio_mcsn.c379
-rw-r--r--src/audio/mint/SDL_mintaudio_mcsn.h58
-rw-r--r--src/audio/mint/SDL_mintaudio_stfa.c319
-rw-r--r--src/audio/mint/SDL_mintaudio_stfa.h99
-rw-r--r--src/audio/mint/SDL_mintaudio_xbios.c319
15 files changed, 2508 insertions, 605 deletions
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index ce066d6ec..23ebbdaa5 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -84,7 +84,11 @@ static AudioBootStrap *bootstrap[] = {
&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,
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index 35e096d30..4a745dcc6 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -148,7 +148,11 @@ extern AudioBootStrap SNDMGR_bootstrap;
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;
diff --git a/src/audio/mint/Makefile.am b/src/audio/mint/Makefile.am
index 57ca3e7f6..21d910d94 100644
--- a/src/audio/mint/Makefile.am
+++ b/src/audio/mint/Makefile.am
@@ -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
diff --git a/src/audio/mint/SDL_mintaudio.c b/src/audio/mint/SDL_mintaudio.c
index abec45412..99a99c614 100644
--- a/src/audio/mint/SDL_mintaudio.c
+++ b/src/audio/mint/SDL_mintaudio.c
@@ -1,628 +1,93 @@
/*
- * MiNT audio driver
- *
- * Patrice Mandin
- */
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-#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_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
-};
-
-/* 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 ---*/
+ 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.
-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;
- }
+ 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.
- /* 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);
-}
+ 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
-static SDL_AudioDevice *Audio_CreateDevice(int devindex)
-{
- SDL_AudioDevice *this;
+ Sam Lantinga
+ slouken@libsdl.org
+*/
- /* 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);
- }
+/*
+ Audio interrupt variables and callback function
- /* Set the function pointers */
- this->OpenAudio = Mint_OpenAudio;
- this->CloseAudio = Mint_CloseAudio;
- this->LockAudio = Mint_LockAudio;
- this->UnlockAudio = Mint_UnlockAudio;
- this->free = Audio_DeleteDevice;
+ Patrice Mandin
+*/
- return this;
-}
+#include <string.h>
-AudioBootStrap MINTAUDIO_bootstrap = {
- MINT_AUDIO_DRIVER_NAME, "MiNT audio driver",
- Audio_Available, Audio_CreateDevice
-};
+#include "SDL_types.h"
+#include "SDL_audio.h"
-static void Mint_LockAudio(_THIS)
-{
- void *oldpile;
+#include "SDL_mintaudio.h"
+#include "SDL_mintaudio_stfa.h"
- /* 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);
- }
-}
+/* The audio device */
-static void Mint_UnlockAudio(_THIS)
-{
- void *oldpile;
+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;
- /* 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);
- }
-}
+/* The callback function, called by each driver whenever needed */
-/* 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];
-
- 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);
+ memset(buffer, SDL_MintAudio_device->spec.silence, SDL_MintAudio_device->spec.size);
+
+ 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 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;
+ /* 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;
}
- 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;
+ if (desired_freq >= ((MINTAUDIO_hardfreq[i]+MINTAUDIO_hardfreq[i+1])>>1)) {
+ return i;
}
}
-
- /* 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);
-}
-
-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;
+ /* Not in the array, give the latest */
+ return MINTAUDIO_nfreq-1;
}
diff --git a/src/audio/mint/SDL_mintaudio.h b/src/audio/mint/SDL_mintaudio.h
index 18cf7a447..5e6a0a7e6 100644
--- a/src/audio/mint/SDL_mintaudio.h
+++ b/src/audio/mint/SDL_mintaudio.h
@@ -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 */
diff --git a/src/audio/mint/SDL_mintaudio_dma8.c b/src/audio/mint/SDL_mintaudio_dma8.c
new file mode 100644
index 000000000..e285128e4
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_dma8.c
@@ -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 */
+}
diff --git a/src/audio/mint/SDL_mintaudio_dma8.h b/src/audio/mint/SDL_mintaudio_dma8.h
new file mode 100644
index 000000000..7d05d88c1
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_dma8.h
@@ -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 */
diff --git a/src/audio/mint/SDL_mintaudio_gsxb.c b/src/audio/mint/SDL_mintaudio_gsxb.c
new file mode 100644
index 000000000..0caf28e2e
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c
@@ -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 */
+}
diff --git a/src/audio/mint/SDL_mintaudio_gsxb.h b/src/audio/mint/SDL_mintaudio_gsxb.h
new file mode 100644
index 000000000..21bb96f36
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_gsxb.h
@@ -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 */
diff --git a/src/audio/mint/SDL_mintaudio_it.S b/src/audio/mint/SDL_mintaudio_it.S
new file mode 100644
index 000000000..a6a999f83
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_it.S
@@ -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
+
diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c
new file mode 100644
index 000000000..e27f727bb
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c
@@ -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 */
+}
diff --git a/src/audio/mint/SDL_mintaudio_mcsn.h b/src/audio/mint/SDL_mintaudio_mcsn.h
new file mode 100644
index 000000000..ea82301ac
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_mcsn.h
@@ -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 */
diff --git a/src/audio/mint/SDL_mintaudio_stfa.c b/src/audio/mint/SDL_mintaudio_stfa.c
new file mode 100644
index 000000000..33a0ec90d
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_stfa.c
@@ -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 */
+}
diff --git a/src/audio/mint/SDL_mintaudio_stfa.h b/src/audio/mint/SDL_mintaudio_stfa.h
new file mode 100644
index 000000000..d37c4efde
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_stfa.h
@@ -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 */
diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c
new file mode 100644
index 000000000..708666edd
--- /dev/null
+++ b/src/audio/mint/SDL_mintaudio_xbios.c
@@ -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 */
+}