1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 23 /* 24 Audio interrupts 25 26 Patrice Mandin, Didier Mquignon 27 */ 28 29 .text 30 31 .globl _SDL_MintAudio_Callback 32 33 .globl _SDL_MintAudio_XbiosInterrupt 34 .globl _SDL_MintAudio_XbiosInterruptMeasureClock 35 .globl _SDL_MintAudio_Dma8Interrupt 36 .globl _SDL_MintAudio_StfaInterrupt 37 38 .globl _SDL_MintAudio_mutex 39 .globl _SDL_MintAudio_audiobuf 40 .globl _SDL_MintAudio_numbuf 41 .globl _SDL_MintAudio_audiosize 42 .globl _SDL_MintAudio_clocktics 43 .globl _SDL_MintAudio_hasfpu 44 45 .globl _SDL_MintAudio_stfa 46 47 /* 48 How it works: 49 - Audio is playing buffer #0 (resp. #1) 50 - We must calculate a sample in buffer #1 (resp. #0) 51 so we first call the callback to do it 52 - Then we swap the buffers 53 */ 54 55 #define savptr 0x4a2 56 #define savamt 0x46 57 58 /*--- Save/restore FPU context ---*/ 59 60 #if defined(__mcoldfire__) 61 62 #define SAVE_FPU_CONTEXT \ 63 lea sp@(-216),sp; \ 64 fsave sp@; \ 65 fmovel fpiar,sp@-; \ 66 lea sp@(-64),sp; \ 67 fmovemd fp0-fp7,sp@ 68 69 #define RESTORE_FPU_CONTEXT \ 70 fmovemd sp@,fp0-fp7; \ 71 lea sp@(64),sp; \ 72 fmovel sp@+,fpiar; \ 73 frestore sp@; \ 74 lea sp@(216),sp 75 76 #else 77 78 #define SAVE_FPU_CONTEXT \ 79 .chip 68k/68881; \ 80 fsave sp@-; \ 81 fmoveml fpcr/fpsr/fpiar,sp@-; \ 82 fmovemx fp0-fp7,sp@-; \ 83 .chip 68k 84 85 #define RESTORE_FPU_CONTEXT \ 86 .chip 68k/68881; \ 87 fmovemx sp@+,fp0-fp7; \ 88 fmoveml sp@+,fpcr/fpsr/fpiar; \ 89 frestore sp@+; \ 90 .chip 68k 91 92 #endif 93 94 /*--- Xbios interrupt vector to measure Falcon external clock ---*/ 95 96 _SDL_MintAudio_XbiosInterruptMeasureClock: /* 1 mS */ 97 #if defined(__mcoldfire__) 98 movel d0,sp@- 99 100 moveql #0,d0 101 btst d0,0xFFFF8901:w /* state DMA sound */ 102 #else 103 btst #0,0xFFFF8901:w /* state DMA sound */ 104 #endif 105 beqs SDL_MintAudio_EndIntMeasure 106 addql #1,_SDL_MintAudio_clocktics 107 SDL_MintAudio_EndIntMeasure: 108 #if defined(__mcoldfire__) 109 moveql #5,d0 110 bclr d0,0xFFFFFA0F:w /* Clear service bit */ 111 112 movel sp@+,d0 113 #else 114 bclr #5,0xFFFFFA0F:w /* Clear service bit */ 115 #endif 116 rte 117 118 /*--- Xbios interrupt vector ---*/ 119 120 _SDL_MintAudio_XbiosInterrupt: 121 #if defined(__mcoldfire__) 122 lea sp@(-60),sp 123 moveml d0-d7/a0-a6,sp@ 124 #else 125 moveml d0-d7/a0-a6,sp@- 126 #endif 127 128 /* Reenable interrupts, so other interrupts can work */ 129 movew #0x2300,sr 130 131 /* Clear service bit, so other MFP interrupts can work */ 132 #if defined(__mcoldfire__) 133 moveql #5,d0 134 bclr d0,0xfffffa0f:w 135 #else 136 bclr #5,0xfffffa0f:w 137 #endif 138 139 /* Check if we are not already running */ 140 tstw _SDL_MintAudio_mutex 141 bne SDL_MintAudio_XbiosEnd 142 143 #if defined(__mcoldfire__) 144 movew _SDL_MintAudio_mutex,d0 145 notl d0 146 movew d0,_SDL_MintAudio_mutex 147 148 movew _SDL_MintAudio_numbuf,d1 149 eorl #1,d1 150 movew d1,_SDL_MintAudio_numbuf 151 #else 152 notw _SDL_MintAudio_mutex 153 154 /* Swap buffers */ 155 eorw #1,_SDL_MintAudio_numbuf 156 #endif 157 158 /* Save FPU if needed */ 159 tstw _SDL_MintAudio_hasfpu 160 beqs SDL_MintAudio_Xbios_nofpu1 161 SAVE_FPU_CONTEXT 162 SDL_MintAudio_Xbios_nofpu1: 163 164 /* Callback */ 165 jsr _SDL_MintAudio_Callback 166 167 /* Restore FPU if needed */ 168 tstw _SDL_MintAudio_hasfpu 169 beqs SDL_MintAudio_Xbios_nofpu2 170 RESTORE_FPU_CONTEXT 171 SDL_MintAudio_Xbios_nofpu2: 172 173 /* Reserve space for registers */ 174 #if defined(__mcoldfire__) 175 movel #savamt,d0 176 subl d0,savptr 177 #else 178 subl #savamt,savptr 179 #endif 180 181 /* Set new buffer */ 182 183 moveq #0,d0 184 movel _SDL_MintAudio_audiosize,d1 185 186 movew _SDL_MintAudio_numbuf,d0 187 lsll #2,d0 188 lea _SDL_MintAudio_audiobuf,a0 189 movel a0@(d0:l),a1 190 191 lea a1@(d1:l),a2 192 193 movel a2,sp@- 194 movel a1,sp@- 195 clrw sp@- 196 movew #131,sp@- 197 trap #14 198 lea sp@(12),sp 199 200 /* Restore registers space */ 201 #if defined(__mcoldfire__) 202 movel #savamt,d0 203 addl d0,savptr 204 #else 205 addl #savamt,savptr 206 #endif 207 208 clrw _SDL_MintAudio_mutex 209 SDL_MintAudio_XbiosEnd: 210 #if defined(__mcoldfire__) 211 moveml sp@,d0-d7/a0-a6 212 lea sp@(60),sp 213 #else 214 moveml sp@+,d0-d7/a0-a6 215 #endif 216 rte 217 218 /*--- DMA 8 bits interrupt vector ---*/ 219 220 _SDL_MintAudio_Dma8Interrupt: 221 #if defined(__mcoldfire__) 222 lea sp@(-16),sp 223 moveml d0-d1/a0-a1,sp@ 224 #else 225 moveml d0-d1/a0-a1,sp@- 226 #endif 227 228 /* Reenable interrupts, so other interrupts can work */ 229 movew #0x2300,sr 230 231 /* Clear service bit, so other MFP interrupts can work */ 232 #if defined(__mcoldfire__) 233 moveql #5,d0 234 bclr d0,0xfffffa0f:w 235 #else 236 bclr #5,0xfffffa0f:w 237 #endif 238 /* Check if we are not already running */ 239 tstw _SDL_MintAudio_mutex 240 bne SDL_MintAudio_Dma8End 241 242 #if defined(__mcoldfire__) 243 movew _SDL_MintAudio_mutex,d0 244 notl d0 245 movew d0,_SDL_MintAudio_mutex 246 247 movew _SDL_MintAudio_numbuf,d1 248 eorl #1,d1 249 movew d1,_SDL_MintAudio_numbuf 250 #else 251 notw _SDL_MintAudio_mutex 252 253 /* Swap buffers */ 254 eorw #1,_SDL_MintAudio_numbuf 255 #endif 256 257 /* Save FPU if needed */ 258 tstw _SDL_MintAudio_hasfpu 259 beqs SDL_MintAudio_Dma8_nofpu1 260 SAVE_FPU_CONTEXT 261 SDL_MintAudio_Dma8_nofpu1: 262 263 /* Callback */ 264 jsr _SDL_MintAudio_Callback 265 266 /* Restore FPU if needed */ 267 tstw _SDL_MintAudio_hasfpu 268 beqs SDL_MintAudio_Dma8_nofpu2 269 RESTORE_FPU_CONTEXT 270 SDL_MintAudio_Dma8_nofpu2: 271 272 /* Set new buffer */ 273 274 moveq #0,d0 275 276 movew _SDL_MintAudio_numbuf,d0 277 lsll #2,d0 278 lea _SDL_MintAudio_audiobuf,a0 279 movel a0@(d0:l),d1 280 281 /* Modify DMA addresses */ 282 lea 0xffff8900:w,a0 283 284 movel d1,d0 285 286 moveb d0,a0@(0x07) /* Start address */ 287 lsrl #8,d0 288 moveb d0,a0@(0x05) 289 lsrl #8,d0 290 moveb d0,a0@(0x03) 291 292 addl _SDL_MintAudio_audiosize,d1 293 294 movel d1,d0 295 296 moveb d0,a0@(0x13) /* End address */ 297 lsrl #8,d0 298 moveb d0,a0@(0x11) 299 lsrl #8,d0 300 moveb d0,a0@(0x0f) 301 302 clrw _SDL_MintAudio_mutex 303 SDL_MintAudio_Dma8End: 304 #if defined(__mcoldfire__) 305 moveml sp@,d0-d1/a0-a1 306 lea sp@(16),sp 307 #else 308 moveml sp@+,d0-d1/a0-a1 309 #endif 310 rte 311 312 /*--- STFA interrupt vector ---*/ 313 314 STFA_SOUND_START = 6 315 STFA_SOUND_END = STFA_SOUND_START+8 316 317 _SDL_MintAudio_StfaInterrupt: 318 /* Reenable interrupts, so other interrupts can work */ 319 movew #0x2300,sr 320 321 /* Check if we are not already running */ 322 tstw _SDL_MintAudio_mutex 323 324 #if defined(__mcoldfire__) 325 bne SDL_MintAudio_StfaEnd 326 327 lea sp@(-60),sp 328 moveml d0-d7/a0-a6,sp@ 329 330 movew _SDL_MintAudio_mutex,d0 331 notl d0 332 movew d0,_SDL_MintAudio_mutex 333 334 movew _SDL_MintAudio_numbuf,d1 335 eorl #1,d1 336 movew d1,_SDL_MintAudio_numbuf 337 #else 338 bnes SDL_MintAudio_StfaEnd 339 340 moveml d0-d7/a0-a6,sp@- 341 342 notw _SDL_MintAudio_mutex 343 344 /* Swap buffers */ 345 eorw #1,_SDL_MintAudio_numbuf 346 #endif 347 348 /* Save FPU if needed */ 349 tstw _SDL_MintAudio_hasfpu 350 beqs SDL_MintAudio_Stfa_nofpu1 351 SAVE_FPU_CONTEXT 352 SDL_MintAudio_Stfa_nofpu1: 353 354 /* Callback */ 355 jsr _SDL_MintAudio_Callback 356 357 /* Restore FPU if needed */ 358 tstw _SDL_MintAudio_hasfpu 359 beqs SDL_MintAudio_Stfa_nofpu2 360 RESTORE_FPU_CONTEXT 361 SDL_MintAudio_Stfa_nofpu2: 362 363 /* Set new buffer */ 364 365 moveq #0,d0 366 movel _SDL_MintAudio_stfa,a1 367 368 movew _SDL_MintAudio_numbuf,d0 369 lsll #2,d0 370 lea _SDL_MintAudio_audiobuf,a0 371 movel a0@(d0:l),d1 372 373 /* Modify STFA replay buffers */ 374 movel d1,a1@(STFA_SOUND_START) 375 addl _SDL_MintAudio_audiosize,d1 376 movel d1,a1@(STFA_SOUND_END) 377 378 #if defined(__mcoldfire__) 379 moveml sp@,d0-d7/a0-a6 380 lea sp@(60),sp 381 #else 382 moveml sp@+,d0-d7/a0-a6 383 #endif 384 clrw _SDL_MintAudio_mutex 385 SDL_MintAudio_StfaEnd: 386 rte 387