146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2004 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Library General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Library General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Library General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MiNT audio driver 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner using XBIOS functions (MacSound compatible driver) 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Patrice Mandin 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <support.h> 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Mint includes */ 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <mint/osbind.h> 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <mint/falcon.h> 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <mint/cookie.h> 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_audio.h" 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_audio_c.h" 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_sysaudio.h" 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../../video/ataricommon/SDL_atarimxalloc_c.h" 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_mintaudio.h" 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_mintaudio_mcsn.h" 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*--- Defines ---*/ 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define MINT_AUDIO_DRIVER_NAME "mint_mcsn" 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Debug print info */ 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define DEBUG_NAME "audio:mcsn: " 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#if 0 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define DEBUG_PRINT(what) \ 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { \ 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner printf what; \ 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define DEBUG_PRINT(what) 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*--- Static variables ---*/ 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic unsigned long cookie_snd, cookie_mch; 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic cookie_mcsn_t *cookie_mcsn; 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*--- Audio driver functions ---*/ 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_CloseAudio(_THIS); 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_LockAudio(_THIS); 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_UnlockAudio(_THIS); 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* To check/init hardware audio */ 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*--- Audio driver bootstrap functions ---*/ 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int Audio_Available(void) 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner unsigned long dummy; 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner const char *envr = SDL_getenv("SDL_AUDIODRIVER"); 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* We can't use XBIOS in interrupt with Magic, don't know about thread */ 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Getcookie(C_MagX, &dummy) == C_FOUND) { 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check if user asked a different audio driver */ 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Cookie _MCH present ? if not, assume ST machine */ 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cookie_mch = MCH_ST; 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Cookie _SND present ? if not, assume ST machine */ 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cookie_snd = SND_PSG; 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check if we have 16 bits audio */ 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((cookie_snd & SND_16BIT)==0) { 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Cookie MCSN present ? */ 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) { 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n")); 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check if interrupt at end of replay */ 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (cookie_mcsn->pint == 0) { 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n")); 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check if audio is lockable */ 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Locksnd()!=1) { 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Unlocksnd(); 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n")); 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(1); 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Audio_DeleteDevice(SDL_AudioDevice *device) 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(device->hidden); 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(device); 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic SDL_AudioDevice *Audio_CreateDevice(int devindex) 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_AudioDevice *this; 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Initialize all variables that we clean on shutdown */ 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( this ) { 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memset(this, 0, (sizeof *this)); 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->hidden = (struct SDL_PrivateAudioData *) 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_malloc((sizeof *this->hidden)); 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (this == NULL) || (this->hidden == NULL) ) { 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( this ) { 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(this); 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the function pointers */ 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->OpenAudio = Mint_OpenAudio; 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->CloseAudio = Mint_CloseAudio; 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->LockAudio = Mint_LockAudio; 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->UnlockAudio = Mint_UnlockAudio; 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner this->free = Audio_DeleteDevice; 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return this; 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17446be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerAudioBootStrap MINTAUDIO_MCSN_bootstrap = { 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Audio_Available, Audio_CreateDevice 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}; 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_LockAudio(_THIS) 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Stop replay */ 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Buffoper(0); 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_UnlockAudio(_THIS) 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Restart replay */ 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Buffoper(SB_PLA_ENA|SB_PLA_RPT); 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_CloseAudio(_THIS) 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Stop replay */ 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_WaitThread(); 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Buffoper(0); 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (!SDL_MintAudio_mint_present) { 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Uninstall interrupt */ 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Jdisint(MFP_DMASOUND); 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Wait if currently playing sound */ 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while (SDL_MintAudio_mutex != 0) { 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Clear buffers */ 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_MintAudio_audiobuf[0]) { 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Mfree(SDL_MintAudio_audiobuf[0]); 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Unlock sound system */ 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Unlocksnd(); 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner unsigned long masterclock, masterprediv; 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("channels=%d, ", spec->channels)); 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("freq=%d\n", spec->freq)); 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (spec->channels > 2) { 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->channels = 2; /* no more than stereo! */ 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check formats available */ 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MINTAUDIO_freqcount=0; 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch(cookie_mcsn->play) { 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCSN_ST: 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->channels=1; 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->format=8; /* FIXME: is it signed or unsigned ? */ 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1); 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCSN_TT: /* Also STE, Mega STE */ 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->format=AUDIO_S8; 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner masterclock=MASTERCLOCK_STE; 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner masterprediv=MASTERPREDIV_STE; 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((cookie_mch>>16)==MCH_TT) { 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner masterclock=MASTERCLOCK_TT; 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner masterprediv=MASTERPREDIV_TT; 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=0; i<4; i++) { 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner masterclock, 3-i, -1); 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCSN_FALCON: /* Also Mac */ 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=1; i<12; i++) { 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Remove unusable Falcon codec predivisors */ 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((i==6) || (i==8) || (i==10)) { 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CLK25M, i+1, -1); 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (cookie_mcsn->res1 != 0) { 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=1; i<4; i++) { 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_AddFrequency(this, (cookie_mcsn->res1)/(MASTERPREDIV_FALCON*(1<<i)), 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CLKEXT, (1<<i)-1, -1); 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->format |= 0x8000; /* Audio is always signed */ 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ((spec->format & 0x00ff)==16) { 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->format |= 0x1000; /* Audio is always big endian */ 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->channels=2; /* 16 bits always stereo */ 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#if 1 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=0; i<MINTAUDIO_freqcount; i++) { 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MINTAUDIO_frequencies[i].predivisor 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner )); 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("channels=%d, ", spec->channels)); 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT(("freq=%d\n", spec->freq)); 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return 0; 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int channels_mode, prediv, dmaclock; 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner void *buffer; 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Stop currently playing sound */ 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_quit_thread = SDL_FALSE; 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_thread_finished = SDL_TRUE; 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_WaitThread(); 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Buffoper(0); 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set replay tracks */ 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Settracks(0,0); 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Setmontracks(0); 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Select replay format */ 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner channels_mode=STEREO16; 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (spec->format & 0xff) { 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 8: 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (spec->channels==2) { 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner channels_mode=STEREO8; 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner channels_mode=MONO8; 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Setmode(channels_mode)<0) { 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock; 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch(cookie_mcsn->play) { 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCSN_TT: 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1); 33146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Soundcmd(SETPRESCALE, prediv); 33246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n")); 33346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 33446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCSN_FALCON: 33546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Devconnect(DMAPLAY, DAC, dmaclock, prediv, 1); 33646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "Falcon prescaler selected\n")); 33746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 33846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 33946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set buffer */ 34146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; 34246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Setbuffer(0, buffer, buffer + spec->size)<0) { 34346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); 34446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_MintAudio_mint_present) { 34746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); 34846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 34946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Install interrupt */ 35046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Jdisint(MFP_DMASOUND); 35146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); 35246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Jenabint(MFP_DMASOUND); 35346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 35446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { 35546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); 35646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 35746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 35846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 35946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Go */ 36046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Buffoper(SB_PLA_ENA|SB_PLA_RPT); 36146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); 36246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 36346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 36446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) 36546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 36646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Lock sound system */ 36746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Locksnd()!=1) { 36846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Mint_OpenAudio: Audio system already in use"); 36946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 37046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_device = this; 37346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Check audio capabilities */ 37546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (Mint_CheckAudio(this, spec)==-1) { 37646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 37746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CalculateAudioSpec(spec); 38046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Allocate memory for audio buffers in DMA-able RAM */ 38246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); 38346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); 38546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_MintAudio_audiobuf[0]==NULL) { 38646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); 38746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return (-1); 38846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; 39046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_numbuf=0; 39146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); 39246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_audiosize = spec->size; 39346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_mutex = 0; 39446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 39546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); 39646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); 39746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 39846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_MintAudio_CheckFpu(); 39946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Setup audio hardware */ 40146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Mint_InitAudio(this, spec); 40246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(1); /* We don't use SDL threaded audio */ 40446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 405