From df10913d3d7a26de74d6ba17d18cb3736e1b5bd0 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 10 Aug 2005 13:29:49 +0000 Subject: [PATCH] Use MiNT thread to update DMA pointers instead of unusable MFP interrupt --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401112 --- src/audio/mint/SDL_mintaudio.c | 64 ++++++++++++++++++++++++++++ src/audio/mint/SDL_mintaudio.h | 10 +++++ src/audio/mint/SDL_mintaudio_mcsn.c | 36 ++++++++++------ src/audio/mint/SDL_mintaudio_xbios.c | 36 ++++++++++------ 4 files changed, 118 insertions(+), 28 deletions(-) diff --git a/src/audio/mint/SDL_mintaudio.c b/src/audio/mint/SDL_mintaudio.c index 18d4641e4..a148fcf4d 100644 --- a/src/audio/mint/SDL_mintaudio.c +++ b/src/audio/mint/SDL_mintaudio.c @@ -27,6 +27,11 @@ */ #include +#include + +#include +#include +#include #include "SDL_types.h" #include "SDL_audio.h" @@ -44,6 +49,12 @@ unsigned short SDL_MintAudio_mutex; unsigned long SDL_MintAudio_clocktics; cookie_stfa_t *SDL_MintAudio_stfa; +/* MiNT thread variables */ +SDL_bool SDL_MintAudio_mint_present; +SDL_bool SDL_MintAudio_quit_thread; +SDL_bool SDL_MintAudio_thread_finished; +long SDL_MintAudio_thread_pid; + /* The callback function, called by each driver whenever needed */ void SDL_MintAudio_Callback(void) @@ -129,3 +140,56 @@ int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) /* Not in the array, give the latest */ return MINTAUDIO_freqcount-1; } + +/* The thread function, used under MiNT with xbios */ +int SDL_MintAudio_Thread(long param) +{ + SndBufPtr pointers; + SDL_bool buffers_filled[2] = {SDL_FALSE, SDL_FALSE}; + + SDL_MintAudio_thread_finished = SDL_FALSE; + while (!SDL_MintAudio_quit_thread) { + if (Buffptr(&pointers)!=0) + continue; + + if (( (unsigned long)pointers.play>=(unsigned long)SDL_MintAudio_audiobuf[0]) + && ( (unsigned long)pointers.play<=(unsigned long)SDL_MintAudio_audiobuf[1])) + { + /* DMA is reading buffer #0, setup buffer #1 if not already done */ + if (!buffers_filled[1]) { + SDL_MintAudio_numbuf = 1; + SDL_MintAudio_Callback(); + Setbuffer(0, SDL_MintAudio_audiobuf[1], SDL_MintAudio_audiobuf[1] + SDL_MintAudio_audiosize); + buffers_filled[1]=SDL_TRUE; + buffers_filled[0]=SDL_FALSE; + } + } else { + /* DMA is reading buffer #1, setup buffer #0 if not already done */ + if (!buffers_filled[0]) { + SDL_MintAudio_numbuf = 0; + SDL_MintAudio_Callback(); + Setbuffer(0, SDL_MintAudio_audiobuf[0], SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize); + buffers_filled[0]=SDL_TRUE; + buffers_filled[1]=SDL_FALSE; + } + } + + usleep(1000); + } + SDL_MintAudio_thread_finished = SDL_TRUE; + return 0; +} + +void SDL_MintAudio_WaitThread(void) +{ + if (!SDL_MintAudio_mint_present) + return; + + if (SDL_MintAudio_thread_finished) + return; + + SDL_MintAudio_quit_thread = SDL_TRUE; + while (!SDL_MintAudio_thread_finished) { + Syield(); + } +} diff --git a/src/audio/mint/SDL_mintaudio.h b/src/audio/mint/SDL_mintaudio.h index 81f381d8a..3a0d320d4 100644 --- a/src/audio/mint/SDL_mintaudio.h +++ b/src/audio/mint/SDL_mintaudio.h @@ -123,12 +123,22 @@ extern unsigned short SDL_MintAudio_mutex; extern cookie_stfa_t *SDL_MintAudio_stfa; extern unsigned long SDL_MintAudio_clocktics; +/* MiNT thread variables */ +extern SDL_bool SDL_MintAudio_mint_present; +extern SDL_bool SDL_MintAudio_quit_thread; +extern SDL_bool SDL_MintAudio_thread_finished; +extern long SDL_MintAudio_thread_pid; + /* Functions */ void SDL_MintAudio_Callback(void); void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, Uint32 prediv, int gpio_bits); int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq); +/* MiNT thread functions */ +int SDL_MintAudio_Thread(long param); +void SDL_MintAudio_WaitThread(void); + /* ASM interrupt functions */ void SDL_MintAudio_GsxbInterrupt(void); void SDL_MintAudio_EmptyGsxbInterrupt(void); diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c index 3871165f3..4b7d61d71 100644 --- a/src/audio/mint/SDL_mintaudio_mcsn.c +++ b/src/audio/mint/SDL_mintaudio_mcsn.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Mint includes */ #include @@ -85,12 +86,9 @@ static int Audio_Available(void) unsigned long dummy; const char *envr = getenv("SDL_AUDIODRIVER"); - /* We can't use XBIOS in interrupt under MiNT */ - if (Getcookie(C_MiNT, &dummy) == C_FOUND) { - return(0); - } + SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); - /* nor with Magic */ + /* We can't use XBIOS in interrupt with Magic, don't know about thread */ if (Getcookie(C_MagX, &dummy) == C_FOUND) { return(0); } @@ -197,10 +195,13 @@ static void Mint_UnlockAudio(_THIS) static void Mint_CloseAudio(_THIS) { /* Stop replay */ + SDL_MintAudio_WaitThread(); Buffoper(0); - /* Uninstall interrupt */ - Jdisint(MFP_DMASOUND); + if (!SDL_MintAudio_mint_present) { + /* Uninstall interrupt */ + Jdisint(MFP_DMASOUND); + } /* Wait if currently playing sound */ while (SDL_MintAudio_mutex != 0) { @@ -298,6 +299,9 @@ static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) void *buffer; /* Stop currently playing sound */ + SDL_MintAudio_quit_thread = SDL_FALSE; + SDL_MintAudio_thread_finished = SDL_TRUE; + SDL_MintAudio_WaitThread(); Buffoper(0); /* Set replay tracks */ @@ -339,13 +343,17 @@ static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); } - /* Install interrupt */ - Jdisint(MFP_DMASOUND); - Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); - Jenabint(MFP_DMASOUND); + if (SDL_MintAudio_mint_present) { + SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); + } else { + /* Install interrupt */ + Jdisint(MFP_DMASOUND); + Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); + Jenabint(MFP_DMASOUND); - if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { - DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); + if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { + DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); + } } /* Go */ @@ -390,5 +398,5 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) /* Setup audio hardware */ Mint_InitAudio(this, spec); - return(1); /* We don't use threaded audio */ + return(1); /* We don't use SDL threaded audio */ } diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c index babd13f15..47e8a7941 100644 --- a/src/audio/mint/SDL_mintaudio_xbios.c +++ b/src/audio/mint/SDL_mintaudio_xbios.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Mint includes */ #include @@ -85,12 +86,9 @@ static int Audio_Available(void) unsigned long dummy; const char *envr = getenv("SDL_AUDIODRIVER"); - /* We can't use XBIOS in interrupt under MiNT */ - if (Getcookie(C_MiNT, &dummy) == C_FOUND) { - return(0); - } + SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); - /* nor with Magic */ + /* We can't use XBIOS in interrupt with Magic, don't know about thread */ if (Getcookie(C_MagX, &dummy) == C_FOUND) { return(0); } @@ -180,10 +178,13 @@ static void Mint_UnlockAudio(_THIS) static void Mint_CloseAudio(_THIS) { /* Stop replay */ + SDL_MintAudio_WaitThread(); Buffoper(0); - /* Uninstall interrupt */ - Jdisint(MFP_DMASOUND); + if (!SDL_MintAudio_mint_present) { + /* Uninstall interrupt */ + Jdisint(MFP_DMASOUND); + } /* Wait if currently playing sound */ while (SDL_MintAudio_mutex != 0) { @@ -391,6 +392,9 @@ static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) void *buffer; /* Stop currently playing sound */ + SDL_MintAudio_quit_thread = SDL_FALSE; + SDL_MintAudio_thread_finished = SDL_TRUE; + SDL_MintAudio_WaitThread(); Buffoper(0); /* Set replay tracks */ @@ -428,13 +432,17 @@ static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); } - /* Install interrupt */ - Jdisint(MFP_DMASOUND); - Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); - Jenabint(MFP_DMASOUND); + if (SDL_MintAudio_mint_present) { + SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); + } else { + /* Install interrupt */ + Jdisint(MFP_DMASOUND); + Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); + Jenabint(MFP_DMASOUND); - if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { - DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); + if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { + DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); + } } /* Go */ @@ -479,5 +487,5 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) /* Setup audio hardware */ Mint_InitAudio(this, spec); - return(1); /* We don't use threaded audio */ + return(1); /* We don't use SDL threaded audio */ }