2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
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.
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.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
22 #include <exec/types.h>
23 #include <clib/alib_protos.h>
25 #if defined( __MORPHOS__ )
26 # define EMUL_NOQUICKMODE
27 # include <emul/emulregs.h>
30 #include <proto/exec.h>
34 #include "audioctrl.h"
36 #include "devcommands.h"
42 #include "requester.h"
47 * All these functions are supposed to be called by the m68k "processor",
48 * with the arguments in m68k registers d0-d7/a0-a6.
49 * The functions relay each call to a standard C function.
53 #if defined( __MORPHOS__ )
55 /******************************************************************************
56 ** MorphOS gateway functions **************************************************
57 ******************************************************************************/
59 /* m68k_IndexToFrequency *****************************************************/
62 gw_IndexToFrequency( void )
64 struct Gadget
* gad
= (struct Gadget
*) REG_A1
;
65 WORD level
= (WORD
) REG_D0
;
67 return IndexToFrequency( gad
, level
);
70 struct EmulLibEntry m68k_IndexToFrequency
=
72 TRAP_LIB
, 0, (void (*)(void)) gw_IndexToFrequency
76 /* m68k_DevProc **************************************************************/
78 struct EmulLibEntry m68k_DevProc
=
80 TRAP_LIB
, 0, (void (*)(void)) DevProc
84 /* HookEntry *****************************************************************/
86 /* Should be in libamiga, but isn't? */
91 struct Hook
* h
= (struct Hook
*) REG_A0
;
92 void* o
= (void*) REG_A2
;
93 void* msg
= (void*) REG_A1
;
95 return ( ( (ULONG(*)(struct Hook
*, void*, void*)) *h
->h_SubEntry
)( h
, o
, msg
) );
98 struct EmulLibEntry _HookEntry
=
100 TRAP_LIB
, 0, (void (*)(void)) &gw_HookEntry
103 __asm( ".globl HookEntry;HookEntry=_HookEntry" );
105 /* m68k_PreTimer ************************************************************/
110 struct AHIPrivAudioCtrl
* audioctrl
= (struct AHIPrivAudioCtrl
*) REG_A2
;
112 return PreTimer( audioctrl
);
115 static struct EmulLibEntry m68k_PreTimer
=
117 TRAP_LIB
, 0, (void (*)(void)) &gw_PreTimer
121 /* m68k_PostTimer ***********************************************************/
126 struct AHIPrivAudioCtrl
* audioctrl
= (struct AHIPrivAudioCtrl
*) REG_A2
;
128 PostTimer( audioctrl
);
131 static struct EmulLibEntry m68k_PostTimer
=
133 TRAP_LIBNR
, 0, (void (*)(void)) &gw_PostTimer
136 #elif defined( __amithlon__ )
138 /******************************************************************************
139 ** Amithlon gateway functions *************************************************
140 ******************************************************************************/
142 // A handy macro for fetching a little endian long integer from memory
143 #define GET_LONG(a) ({ long r; __asm__("movl %1,%0":"=r"(r) :"m"(a)); r; })
145 /* m68k_IndexToFrequency *****************************************************/
148 gw_IndexToFrequency( struct Gadget
*gad
, WORD level
) __attribute__((regparm(3)));
151 gw_IndexToFrequency( struct Gadget
*gad
, WORD level
)
153 return IndexToFrequency( gad
, level
);
158 UWORD movel_4sp_d0
[2];
159 UWORD movew_10sp_a0
[2];
163 } m68k_IndexToFrequency
=
168 0x4EF9, (ULONG
) gw_IndexToFrequency
+ 1
172 /* m68k_DevProc **************************************************************/
176 UWORD nop
; // Just to 32-bit align the long word
182 0x4EF9, (ULONG
) DevProc
+ 1
186 /* m68k_PreTimer ************************************************************/
189 gw_PreTimer( struct AHIPrivAudioCtrl
* audioctrl
) __attribute__((regparm(3)));
192 gw_PreTimer( struct AHIPrivAudioCtrl
* audioctrl
)
194 return 0; //PreTimer( audioctrl );
200 UWORD movel_4sp_d0
[2];
207 0x4EF9, (ULONG
) gw_PreTimer
+ 1
211 /* m68k_PostTimer ***********************************************************/
214 gw_PostTimer( struct _Regs
* regs
) __attribute__((regparm(3)));
217 gw_PostTimer( struct _Regs
* regs
)
219 struct AHIPrivAudioCtrl
* audioctrl
= (struct AHIPrivAudioCtrl
*) GET_LONG( regs
->a2
);
221 PostTimer( audioctrl
);
227 UWORD movel_4sp_d0
[2];
234 0x4EF9, (ULONG
) gw_PostTimer
+ 1
237 #elif defined( __AROS__ )
239 /******************************************************************************
240 ** AROS gateway functions *****************************************************
241 ******************************************************************************/
243 #ifndef AROS_LIBCALL_H
244 # include <aros/libcall.h>
247 /* m68k_IndexToFrequency *****************************************************/
250 m68k_IndexToFrequency( struct Gadget
*gad
, WORD level
)
252 return IndexToFrequency( gad
, level
);
256 /* m68k_DevProc **************************************************************/
267 /* m68k_PreTimer ************************************************************/
271 AROS_UFHA( struct AHIPrivAudioCtrl
*, audioctrl
, A2
) )
274 return PreTimer( audioctrl
);
279 /* m68k_PostTimer ***********************************************************/
283 AROS_UFHA( struct AHIPrivAudioCtrl
*, audioctrl
, A2
) )
286 PostTimer( audioctrl
);
290 #elif defined( __AMIGAOS4__ )
292 /******************************************************************************
293 ** AmigaOS 4.x gateway functions **********************************************
294 ******************************************************************************/
296 /* m68k_IndexToFrequency *****************************************************/
299 m68k_IndexToFrequency( struct Gadget
*gad
, WORD level
)
301 return IndexToFrequency( gad
, level
);
305 /* m68k_DevProc **************************************************************/
314 /* m68k_PreTimer ************************************************************/
317 m68k_PreTimer( REG(a2
, struct AHIPrivAudioCtrl
* audioctrl
) )
319 return PreTimer( audioctrl
);
323 /* m68k_PostTimer ***********************************************************/
326 m68k_PostTimer( REG(a2
, struct AHIPrivAudioCtrl
* audioctrl
) )
328 PostTimer( audioctrl
);
332 UWORD PreTimerPreserveAllRegs
[] = {
339 UWORD PostTimerPreserveAllRegs
[] = {
348 /* -------------------- HookEntry ---------------------------*/ \n\
351 .type hookEntry, @function \n\
353 .type HookEntry, @function \n\
354 .globl HookEntryPreserveAllRegs \n\
355 .type HookEntryPreserveAllRegs, @function \n\
359 HookEntryPreserveAllRegs: \n\
361 .short 0x4ef8 /* JMP.w */ \n\
362 .short 0 /* Indicate switch */ \n\
363 .short 1 /* Trap type */ \n\
364 .long HookEntryPPC \n\
365 /* Register mapping */ \n\
376 addi 12, 1, -16 /* Calculate stackframe size */ \n\
377 rlwinm 12, 12, 0, 0, 27 /* Align it */ \n\
378 stw 1, 0(12) /* Store backchain pointer */ \n\
379 mr 1, 12 /* Set real stack pointer */ \n\
381 stw 11,12(1) /* Store Enter68kQuick vector */\n\
383 lwz 12,12(3) /* Get the sub entry */ \n\
390 lwz 1, 0(1) /* Cleanup stack frame */ \n\
392 blrl /* Return to emulation */ \n\
394 .byte 0 /* Flags */ \n\
395 .byte 2 /* Two registers (a7 and d0) */ \n\
396 .byte 1 /* Map r1 */ \n\
397 .byte 60 /* to A7 */ \n\
398 .byte 3 /* Map r3 */ \n\
399 .byte 0 /* to D0 */ \n\
404 .short 0x4e75 /* RTS */ \n\
409 struct AHIAudioCtrl
* __attribute__((linearvarargs
)) _AHI_AllocAudio(
411 struct AHIBase
*AHIBase
, ...
415 struct TagItem
* varargs
;
416 va_startlinear(ap
, AHIBase
);
417 varargs
= va_getlinearva(ap
, struct TagItem
*);
418 return _AHI_AllocAudioA(
425 ULONG
__attribute__((linearvarargs
)) _AHI_ControlAudio(
427 struct AHIAudioCtrl
* AudioCtrl
,
428 struct AHIBase
*AHIBase
, ...
432 struct TagItem
* varargs
;
433 va_startlinear(ap
, AHIBase
);
434 varargs
= va_getlinearva(ap
, struct TagItem
*);
435 return _AHI_ControlAudioA(
436 (struct AHIPrivAudioCtrl
*) AudioCtrl
,
441 BOOL
__attribute__((linearvarargs
)) _AHI_GetAudioAttrs(
444 struct AHIAudioCtrl
* Audioctrl
,
445 struct AHIBase
*AHIBase
,
450 struct TagItem
* varargs
;
451 va_startlinear(ap
, AHIBase
);
452 varargs
= va_getlinearva(ap
, struct TagItem
*);
454 return _AHI_GetAudioAttrsA(
456 (struct AHIPrivAudioCtrl
*) Audioctrl
,
461 ULONG
__attribute__((linearvarargs
)) _AHI_BestAudioID(
463 struct AHIBase
*AHIBase
, ...
467 struct TagItem
* varargs
;
468 va_startlinear(ap
, AHIBase
);
469 varargs
= va_getlinearva(ap
, struct TagItem
*);
470 return _AHI_BestAudioIDA(
475 struct AHIAudioModeRequester
* __attribute__((linearvarargs
)) _AHI_AllocAudioRequest(
477 struct AHIBase
*AHIBase
, ...
481 struct TagItem
* varargs
;
482 va_startlinear(ap
, AHIBase
);
483 varargs
= va_getlinearva(ap
, struct TagItem
*);
484 return _AHI_AllocAudioRequestA(
489 BOOL
__attribute__((linearvarargs
)) _AHI_AudioRequest(
491 struct AHIAudioModeRequester
* Requester
,
492 struct AHIBase
*AHIBase
, ...
496 struct TagItem
* varargs
;
497 va_startlinear(ap
, AHIBase
);
498 varargs
= va_getlinearva(ap
, struct TagItem
*);
499 return _AHI_AudioRequestA(
505 void __attribute__((linearvarargs
)) _AHI_Play(
507 struct AHIAudioCtrl
* Audioctrl
,
508 struct AHIBase
*AHIBase
, ...
512 struct TagItem
* varargs
;
513 va_startlinear(ap
, AHIBase
);
514 varargs
= va_getlinearva(ap
, struct TagItem
*);
516 (struct AHIPrivAudioCtrl
*) Audioctrl
,
520 #else // Not MorphOS, not Amithlon, not AROS, not AmigaOS 4.x
522 /******************************************************************************
523 ** AmigaOS 2.x/3.x gateway functions ******************************************
524 ******************************************************************************/
526 /* m68k_IndexToFrequency *****************************************************/
528 LONG
__attribute__((stkparm
)) __attribute__((saveds
))
529 m68k_IndexToFrequency( struct Gadget
*gad
, WORD level
)
531 return IndexToFrequency( gad
, level
);
535 /* m68k_DevProc **************************************************************/
544 /* m68k_PreTimer ************************************************************/
547 m68k_PreTimer( struct AHIPrivAudioCtrl
* audioctrl
__asm("a2") )
549 return PreTimer( audioctrl
);
553 /* m68k_PostTimer ***********************************************************/
556 m68k_PostTimer( struct AHIPrivAudioCtrl
* audioctrl
__asm("a2") )
558 PostTimer( audioctrl
);
564 /*** Some special wrappers ***************************************************/
566 #if defined( __AROS__ ) && !defined( __mc68000__ )
568 // We're not binary compatible!
570 #elif defined( __AMIGAOS4__ )
572 // No need to do this
577 # pragma pack(2) // Make sure the compiler does not insert pads
582 UWORD pushm_d0_d1_a0_a1
[2];
585 UWORD popm_d0_d1_a0_a1
[2];
587 } HookEntryPreserveAllRegs
__attribute__ ((aligned (4))) =
590 0x4EB9, (ULONG
) HookEntry
,
598 UWORD pushm_d1_a0_a1
[2];
601 UWORD popm_d1_a0_a1
[2];
604 } PreTimerPreserveAllRegs
__attribute__ ((aligned (4))) =
607 0x4EB9, (ULONG
) &m68k_PreTimer
,
616 UWORD pushm_d0_d1_a0_a1
[2];
619 UWORD popm_d0_d1_a0_a1
[2];
621 } PostTimerPreserveAllRegs
__attribute__ ((aligned (4))) =
624 0x4EB9, (ULONG
) &m68k_PostTimer
,
629 #endif /* defined( __AROS__ ) / defined( __AMIGAOS4__ ) */