| /* |
| SDL - Simple DirectMedia Layer |
| Copyright (C) 1997-2012 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, Didier Méquignon |
| */ |
| |
| .text |
| |
| .globl _SDL_MintAudio_Callback |
| |
| .globl _SDL_MintAudio_XbiosInterrupt |
| .globl _SDL_MintAudio_XbiosInterruptMeasureClock |
| .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_clocktics |
| .globl _SDL_MintAudio_hasfpu |
| |
| .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 |
| */ |
| |
| #define savptr 0x4a2 |
| #define savamt 0x46 |
| |
| /*--- Save/restore FPU context ---*/ |
| |
| #if defined(__mcoldfire__) |
| |
| #define SAVE_FPU_CONTEXT \ |
| lea sp@(-216),sp; \ |
| fsave sp@; \ |
| fmovel fpiar,sp@-; \ |
| lea sp@(-64),sp; \ |
| fmovemd fp0-fp7,sp@ |
| |
| #define RESTORE_FPU_CONTEXT \ |
| fmovemd sp@,fp0-fp7; \ |
| lea sp@(64),sp; \ |
| fmovel sp@+,fpiar; \ |
| frestore sp@; \ |
| lea sp@(216),sp |
| |
| #else |
| |
| #define SAVE_FPU_CONTEXT \ |
| .chip 68k/68881; \ |
| fsave sp@-; \ |
| fmoveml fpcr/fpsr/fpiar,sp@-; \ |
| fmovemx fp0-fp7,sp@-; \ |
| .chip 68k |
| |
| #define RESTORE_FPU_CONTEXT \ |
| .chip 68k/68881; \ |
| fmovemx sp@+,fp0-fp7; \ |
| fmoveml sp@+,fpcr/fpsr/fpiar; \ |
| frestore sp@+; \ |
| .chip 68k |
| |
| #endif |
| |
| /*--- Xbios interrupt vector to measure Falcon external clock ---*/ |
| |
| _SDL_MintAudio_XbiosInterruptMeasureClock: /* 1 mS */ |
| #if defined(__mcoldfire__) |
| movel d0,sp@- |
| |
| moveql #0,d0 |
| btst d0,0xFFFF8901:w /* state DMA sound */ |
| #else |
| btst #0,0xFFFF8901:w /* state DMA sound */ |
| #endif |
| beqs SDL_MintAudio_EndIntMeasure |
| addql #1,_SDL_MintAudio_clocktics |
| SDL_MintAudio_EndIntMeasure: |
| #if defined(__mcoldfire__) |
| moveql #5,d0 |
| bclr d0,0xFFFFFA0F:w /* Clear service bit */ |
| |
| movel sp@+,d0 |
| #else |
| bclr #5,0xFFFFFA0F:w /* Clear service bit */ |
| #endif |
| rte |
| |
| /*--- Xbios interrupt vector ---*/ |
| |
| _SDL_MintAudio_XbiosInterrupt: |
| #if defined(__mcoldfire__) |
| lea sp@(-60),sp |
| moveml d0-d7/a0-a6,sp@ |
| #else |
| moveml d0-d7/a0-a6,sp@- |
| #endif |
| |
| /* Reenable interrupts, so other interrupts can work */ |
| movew #0x2300,sr |
| |
| /* Clear service bit, so other MFP interrupts can work */ |
| #if defined(__mcoldfire__) |
| moveql #5,d0 |
| bclr d0,0xfffffa0f:w |
| #else |
| bclr #5,0xfffffa0f:w |
| #endif |
| |
| /* Check if we are not already running */ |
| tstw _SDL_MintAudio_mutex |
| bne SDL_MintAudio_XbiosEnd |
| |
| #if defined(__mcoldfire__) |
| movew _SDL_MintAudio_mutex,d0 |
| notl d0 |
| movew d0,_SDL_MintAudio_mutex |
| |
| movew _SDL_MintAudio_numbuf,d1 |
| eorl #1,d1 |
| movew d1,_SDL_MintAudio_numbuf |
| #else |
| notw _SDL_MintAudio_mutex |
| |
| /* Swap buffers */ |
| eorw #1,_SDL_MintAudio_numbuf |
| #endif |
| |
| /* Save FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Xbios_nofpu1 |
| SAVE_FPU_CONTEXT |
| SDL_MintAudio_Xbios_nofpu1: |
| |
| /* Callback */ |
| jsr _SDL_MintAudio_Callback |
| |
| /* Restore FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Xbios_nofpu2 |
| RESTORE_FPU_CONTEXT |
| SDL_MintAudio_Xbios_nofpu2: |
| |
| /* Reserve space for registers */ |
| #if defined(__mcoldfire__) |
| movel #savamt,d0 |
| subl d0,savptr |
| #else |
| subl #savamt,savptr |
| #endif |
| |
| /* Set new buffer */ |
| |
| moveq #0,d0 |
| movel _SDL_MintAudio_audiosize,d1 |
| |
| movew _SDL_MintAudio_numbuf,d0 |
| lsll #2,d0 |
| lea _SDL_MintAudio_audiobuf,a0 |
| movel a0@(d0:l),a1 |
| |
| lea a1@(d1:l),a2 |
| |
| movel a2,sp@- |
| movel a1,sp@- |
| clrw sp@- |
| movew #131,sp@- |
| trap #14 |
| lea sp@(12),sp |
| |
| /* Restore registers space */ |
| #if defined(__mcoldfire__) |
| movel #savamt,d0 |
| addl d0,savptr |
| #else |
| addl #savamt,savptr |
| #endif |
| |
| clrw _SDL_MintAudio_mutex |
| SDL_MintAudio_XbiosEnd: |
| #if defined(__mcoldfire__) |
| moveml sp@,d0-d7/a0-a6 |
| lea sp@(60),sp |
| #else |
| moveml sp@+,d0-d7/a0-a6 |
| #endif |
| rte |
| |
| /*--- DMA 8 bits interrupt vector ---*/ |
| |
| _SDL_MintAudio_Dma8Interrupt: |
| #if defined(__mcoldfire__) |
| lea sp@(-16),sp |
| moveml d0-d1/a0-a1,sp@ |
| #else |
| moveml d0-d1/a0-a1,sp@- |
| #endif |
| |
| /* Reenable interrupts, so other interrupts can work */ |
| movew #0x2300,sr |
| |
| /* Clear service bit, so other MFP interrupts can work */ |
| #if defined(__mcoldfire__) |
| moveql #5,d0 |
| bclr d0,0xfffffa0f:w |
| #else |
| bclr #5,0xfffffa0f:w |
| #endif |
| /* Check if we are not already running */ |
| tstw _SDL_MintAudio_mutex |
| bne SDL_MintAudio_Dma8End |
| |
| #if defined(__mcoldfire__) |
| movew _SDL_MintAudio_mutex,d0 |
| notl d0 |
| movew d0,_SDL_MintAudio_mutex |
| |
| movew _SDL_MintAudio_numbuf,d1 |
| eorl #1,d1 |
| movew d1,_SDL_MintAudio_numbuf |
| #else |
| notw _SDL_MintAudio_mutex |
| |
| /* Swap buffers */ |
| eorw #1,_SDL_MintAudio_numbuf |
| #endif |
| |
| /* Save FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Dma8_nofpu1 |
| SAVE_FPU_CONTEXT |
| SDL_MintAudio_Dma8_nofpu1: |
| |
| /* Callback */ |
| jsr _SDL_MintAudio_Callback |
| |
| /* Restore FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Dma8_nofpu2 |
| RESTORE_FPU_CONTEXT |
| SDL_MintAudio_Dma8_nofpu2: |
| |
| /* Set new buffer */ |
| |
| moveq #0,d0 |
| |
| movew _SDL_MintAudio_numbuf,d0 |
| lsll #2,d0 |
| lea _SDL_MintAudio_audiobuf,a0 |
| movel a0@(d0:l),d1 |
| |
| /* Modify DMA addresses */ |
| lea 0xffff8900:w,a0 |
| |
| movel d1,d0 |
| |
| moveb d0,a0@(0x07) /* Start address */ |
| lsrl #8,d0 |
| moveb d0,a0@(0x05) |
| lsrl #8,d0 |
| moveb d0,a0@(0x03) |
| |
| addl _SDL_MintAudio_audiosize,d1 |
| |
| movel d1,d0 |
| |
| moveb d0,a0@(0x13) /* End address */ |
| lsrl #8,d0 |
| moveb d0,a0@(0x11) |
| lsrl #8,d0 |
| moveb d0,a0@(0x0f) |
| |
| clrw _SDL_MintAudio_mutex |
| SDL_MintAudio_Dma8End: |
| #if defined(__mcoldfire__) |
| moveml sp@,d0-d1/a0-a1 |
| lea sp@(16),sp |
| #else |
| moveml sp@+,d0-d1/a0-a1 |
| #endif |
| 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 |
| |
| #if defined(__mcoldfire__) |
| bne SDL_MintAudio_StfaEnd |
| |
| lea sp@(-60),sp |
| moveml d0-d7/a0-a6,sp@ |
| |
| movew _SDL_MintAudio_mutex,d0 |
| notl d0 |
| movew d0,_SDL_MintAudio_mutex |
| |
| movew _SDL_MintAudio_numbuf,d1 |
| eorl #1,d1 |
| movew d1,_SDL_MintAudio_numbuf |
| #else |
| bnes SDL_MintAudio_StfaEnd |
| |
| moveml d0-d7/a0-a6,sp@- |
| |
| notw _SDL_MintAudio_mutex |
| |
| /* Swap buffers */ |
| eorw #1,_SDL_MintAudio_numbuf |
| #endif |
| |
| /* Save FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Stfa_nofpu1 |
| SAVE_FPU_CONTEXT |
| SDL_MintAudio_Stfa_nofpu1: |
| |
| /* Callback */ |
| jsr _SDL_MintAudio_Callback |
| |
| /* Restore FPU if needed */ |
| tstw _SDL_MintAudio_hasfpu |
| beqs SDL_MintAudio_Stfa_nofpu2 |
| RESTORE_FPU_CONTEXT |
| SDL_MintAudio_Stfa_nofpu2: |
| |
| /* Set new buffer */ |
| |
| moveq #0,d0 |
| movel _SDL_MintAudio_stfa,a1 |
| |
| movew _SDL_MintAudio_numbuf,d0 |
| lsll #2,d0 |
| lea _SDL_MintAudio_audiobuf,a0 |
| movel a0@(d0:l),d1 |
| |
| /* Modify STFA replay buffers */ |
| movel d1,a1@(STFA_SOUND_START) |
| addl _SDL_MintAudio_audiosize,d1 |
| movel d1,a1@(STFA_SOUND_END) |
| |
| #if defined(__mcoldfire__) |
| moveml sp@,d0-d7/a0-a6 |
| lea sp@(60),sp |
| #else |
| moveml sp@+,d0-d7/a0-a6 |
| #endif |
| clrw _SDL_MintAudio_mutex |
| SDL_MintAudio_StfaEnd: |
| rte |