From 68a8207cf67929a40a3668cc95b400b5318c7abb Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 16:59:46 +0000 Subject: [PATCH] Save/restore FPU registers in interrupt --- src/audio/mint/SDL_mintaudio.c | 20 +++++++++ src/audio/mint/SDL_mintaudio.h | 2 + src/audio/mint/SDL_mintaudio_dma8.c | 2 + src/audio/mint/SDL_mintaudio_gsxb.c | 2 + src/audio/mint/SDL_mintaudio_it.S | 65 +++++++++++++++++++++++++++- src/audio/mint/SDL_mintaudio_mcsn.c | 2 + src/audio/mint/SDL_mintaudio_stfa.c | 2 + src/audio/mint/SDL_mintaudio_xbios.c | 2 + 8 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/audio/mint/SDL_mintaudio.c b/src/audio/mint/SDL_mintaudio.c index 515b07393..a864904c2 100644 --- a/src/audio/mint/SDL_mintaudio.c +++ b/src/audio/mint/SDL_mintaudio.c @@ -145,6 +145,26 @@ SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) return MINTAUDIO_freqcount - 1; } +/* Check if FPU is present */ +void SDL_MintAudio_CheckFpu(void) +{ + unsigned long cookie_fpu; + + SDL_MintAudio_hasfpu = 0; + if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) { + return; + } + switch ((cookie_fpu>>16)&0xfffe) { + case 2: + case 4: + case 6: + case 8: + case 16: + SDL_MintAudio_hasfpu = 1; + break; + } +} + /* The thread function, used under MiNT with xbios */ int SDL_MintAudio_Thread(long param) diff --git a/src/audio/mint/SDL_mintaudio.h b/src/audio/mint/SDL_mintaudio.h index 5a95f5189..eedf0a684 100644 --- a/src/audio/mint/SDL_mintaudio.h +++ b/src/audio/mint/SDL_mintaudio.h @@ -128,6 +128,7 @@ extern volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ extern volatile unsigned short SDL_MintAudio_mutex; extern cookie_stfa_t *SDL_MintAudio_stfa; extern volatile unsigned long SDL_MintAudio_clocktics; +extern unsigned short SDL_MintAudio_hasfpu; /* To preserve fpu registers if needed */ /* MiNT thread variables */ extern SDL_bool SDL_MintAudio_mint_present; @@ -140,6 +141,7 @@ 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); +void SDL_MintAudio_CheckFpu(void); /* MiNT thread functions */ int SDL_MintAudio_Thread(long param); diff --git a/src/audio/mint/SDL_mintaudio_dma8.c b/src/audio/mint/SDL_mintaudio_dma8.c index 04afa8c04..3cc81667f 100644 --- a/src/audio/mint/SDL_mintaudio_dma8.c +++ b/src/audio/mint/SDL_mintaudio_dma8.c @@ -367,6 +367,8 @@ Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_gsxb.c b/src/audio/mint/SDL_mintaudio_gsxb.c index 3475007f3..c015393f2 100644 --- a/src/audio/mint/SDL_mintaudio_gsxb.c +++ b/src/audio/mint/SDL_mintaudio_gsxb.c @@ -438,6 +438,8 @@ Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_it.S b/src/audio/mint/SDL_mintaudio_it.S index e9eab5922..a73c19e3c 100644 --- a/src/audio/mint/SDL_mintaudio_it.S +++ b/src/audio/mint/SDL_mintaudio_it.S @@ -40,6 +40,7 @@ .globl _SDL_MintAudio_numbuf .globl _SDL_MintAudio_audiosize .globl _SDL_MintAudio_clocktics + .globl _SDL_MintAudio_hasfpu .globl _SDL_MintAudio_stfa @@ -85,9 +86,29 @@ _SDL_MintAudio_XbiosInterrupt: moveml d0-d7/a0-a6,sp@- + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Xbios_nofpu1 + .chip 68060 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- + .chip 68000 +SDL_MintAudio_Xbios_nofpu1: + /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Xbios_nofpu2 + .chip 68060 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ + .chip 68000 +SDL_MintAudio_Xbios_nofpu2: + /* Reserve space for registers */ subl #savamt,savptr @@ -137,11 +158,31 @@ _SDL_MintAudio_Dma8Interrupt: /* Swap buffers */ eorw #1,_SDL_MintAudio_numbuf - moveml d0-d7/a0-a6,sp@- + moveml d0-d1/a0-a1,sp@- + + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Dma8_nofpu1 + .chip 68060 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- + .chip 68000 +SDL_MintAudio_Dma8_nofpu1: /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Dma8_nofpu2 + .chip 68060 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ + .chip 68000 +SDL_MintAudio_Dma8_nofpu2: + /* Set new buffer */ moveq #0,d0 @@ -169,7 +210,7 @@ _SDL_MintAudio_Dma8Interrupt: rorl #8,d1 moveb d1,a0@(0x0f) - moveml sp@+,d0-d7/a0-a6 + moveml sp@+,d0-d1/a0-a1 clrw _SDL_MintAudio_mutex SDL_MintAudio_Dma8End: @@ -195,9 +236,29 @@ _SDL_MintAudio_StfaInterrupt: moveml d0-d7/a0-a6,sp@- + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Stfa_nofpu1 + .chip 68060 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- + .chip 68000 +SDL_MintAudio_Stfa_nofpu1: + /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Stfa_nofpu2 + .chip 68060 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ + .chip 68000 +SDL_MintAudio_Stfa_nofpu2: + /* Set new buffer */ moveq #0,d0 diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c index e043fa295..910de5981 100644 --- a/src/audio/mint/SDL_mintaudio_mcsn.c +++ b/src/audio/mint/SDL_mintaudio_mcsn.c @@ -415,6 +415,8 @@ Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_stfa.c b/src/audio/mint/SDL_mintaudio_stfa.c index 2b10a009f..7a0b7777e 100644 --- a/src/audio/mint/SDL_mintaudio_stfa.c +++ b/src/audio/mint/SDL_mintaudio_stfa.c @@ -332,6 +332,8 @@ Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c index 3d15efb17..5925e2dca 100644 --- a/src/audio/mint/SDL_mintaudio_xbios.c +++ b/src/audio/mint/SDL_mintaudio_xbios.c @@ -519,6 +519,8 @@ Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec);