Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Device / gateway.c
blobb6fc97c7cade49139be2d795575fb84e5a7b2bf3
1 /*
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,
18 MA 02139, USA.
21 #include <config.h>
22 #include <exec/types.h>
23 #include <clib/alib_protos.h>
25 #if defined( __MORPHOS__ )
26 # define EMUL_NOQUICKMODE
27 # include <emul/emulregs.h>
28 #endif
30 #include <proto/exec.h>
32 #include "ahi_def.h"
34 #include "audioctrl.h"
35 #include "database.h"
36 #include "devcommands.h"
37 #include "device.h"
38 #include "header.h"
39 #include "misc.h"
40 #include "mixer.h"
41 #include "modeinfo.h"
42 #include "requester.h"
43 #include "sound.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 *****************************************************/
61 static LONG
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? */
88 static ULONG
89 gw_HookEntry( void )
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 ************************************************************/
107 static BOOL
108 gw_PreTimer( void )
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 ***********************************************************/
123 static void
124 gw_PostTimer( void )
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 *****************************************************/
147 static LONG
148 gw_IndexToFrequency( struct Gadget *gad, WORD level ) __attribute__((regparm(3)));
150 static LONG
151 gw_IndexToFrequency( struct Gadget *gad, WORD level )
153 return IndexToFrequency( gad, level );
156 struct
158 UWORD movel_4sp_d0[2];
159 UWORD movew_10sp_a0[2];
160 UWORD movel_a0_d1;
161 UWORD jmp;
162 ULONG addr;
163 } m68k_IndexToFrequency =
165 {0x202F,0x0004},
166 {0x306F,0x000A},
167 0x2208,
168 0x4EF9, (ULONG) gw_IndexToFrequency + 1
172 /* m68k_DevProc **************************************************************/
174 struct
176 UWORD nop; // Just to 32-bit align the long word
177 UWORD jmp;
178 ULONG addr;
179 } m68k_DevProc =
181 0x4E71,
182 0x4EF9, (ULONG) DevProc + 1
186 /* m68k_PreTimer ************************************************************/
188 static BOOL
189 gw_PreTimer( struct AHIPrivAudioCtrl* audioctrl ) __attribute__((regparm(3)));
191 static BOOL
192 gw_PreTimer( struct AHIPrivAudioCtrl* audioctrl )
194 return 0; //PreTimer( audioctrl );
197 static struct
199 UWORD nop;
200 UWORD movel_4sp_d0[2];
201 UWORD jmp;
202 ULONG addr;
203 } m68k_PreTimer =
205 0x4E71,
206 {0x202F, 0x0004},
207 0x4EF9, (ULONG) gw_PreTimer + 1
211 /* m68k_PostTimer ***********************************************************/
213 static void
214 gw_PostTimer( struct _Regs* regs ) __attribute__((regparm(3)));
216 static void
217 gw_PostTimer( struct _Regs* regs )
219 struct AHIPrivAudioCtrl* audioctrl = (struct AHIPrivAudioCtrl*) GET_LONG( regs->a2 );
221 PostTimer( audioctrl );
224 static struct
226 UWORD nop;
227 UWORD movel_4sp_d0[2];
228 UWORD jmp;
229 ULONG addr;
230 } m68k_PostTimer =
232 0x4E71,
233 {0x202F, 0x0004},
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>
245 #endif
247 /* m68k_IndexToFrequency *****************************************************/
249 LONG
250 m68k_IndexToFrequency( struct Gadget *gad, WORD level )
252 return IndexToFrequency( gad, level );
256 /* m68k_DevProc **************************************************************/
258 AROS_UFH0( void,
259 m68k_DevProc )
261 AROS_USERFUNC_INIT
262 DevProc();
263 AROS_USERFUNC_EXIT
267 /* m68k_PreTimer ************************************************************/
269 AROS_UFH1( BOOL,
270 m68k_PreTimer,
271 AROS_UFHA( struct AHIPrivAudioCtrl*, audioctrl, A2 ) )
273 AROS_USERFUNC_INIT
274 return PreTimer( audioctrl );
275 AROS_USERFUNC_EXIT
279 /* m68k_PostTimer ***********************************************************/
281 AROS_UFH1( void,
282 m68k_PostTimer,
283 AROS_UFHA( struct AHIPrivAudioCtrl*, audioctrl, A2 ) )
285 AROS_USERFUNC_INIT
286 PostTimer( audioctrl );
287 AROS_USERFUNC_EXIT
290 #elif defined( __AMIGAOS4__ )
292 /******************************************************************************
293 ** AmigaOS 4.x gateway functions **********************************************
294 ******************************************************************************/
296 /* m68k_IndexToFrequency *****************************************************/
298 LONG STDARGS SAVEDS
299 m68k_IndexToFrequency( struct Gadget *gad, WORD level )
301 return IndexToFrequency( gad, level );
305 /* m68k_DevProc **************************************************************/
307 void
308 m68k_DevProc( void )
310 DevProc();
314 /* m68k_PreTimer ************************************************************/
316 BOOL
317 m68k_PreTimer( REG(a2, struct AHIPrivAudioCtrl* audioctrl ) )
319 return PreTimer( audioctrl );
323 /* m68k_PostTimer ***********************************************************/
325 void
326 m68k_PostTimer( REG(a2, struct AHIPrivAudioCtrl* audioctrl ) )
328 PostTimer( audioctrl );
332 UWORD PreTimerPreserveAllRegs[] = {
333 0x206A, 0x0054,
334 0x93C9,
335 0x2F28, 0x0008,
336 0x4E75
339 UWORD PostTimerPreserveAllRegs[] = {
340 0x206A, 0x0058,
341 0x93C9,
342 0x2F28, 0x0008,
343 0x4E75
347 __asm__(" \n\
348 /* -------------------- HookEntry ---------------------------*/ \n\
350 .globl hookEntry \n\
351 .type hookEntry, @function \n\
352 .globl HookEntry \n\
353 .type HookEntry, @function \n\
354 .globl HookEntryPreserveAllRegs \n\
355 .type HookEntryPreserveAllRegs, @function \n\
356 .section .data \n\
358 HookEntry: \n\
359 HookEntryPreserveAllRegs: \n\
360 hookEntry: \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\
366 .byte 5 \n\
367 .byte 1,60 \n\
368 .byte 3,32 \n\
369 .byte 4,40 \n\
370 .byte 5,36 \n\
371 .byte 6,56 \n\
372 .align 2 \n\
374 .section .text \n\
375 HookEntryPPC: \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\
384 mtlr 12 \n\
385 blrl \n\
387 lwz 11,12(1) \n\
388 mtlr 11 \n\
390 lwz 1, 0(1) /* Cleanup stack frame */ \n\
392 blrl /* Return to emulation */ \n\
393 .long HookExit \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\
400 .align 4 \n\
402 .section .data \n\
403 HookExit: \n\
404 .short 0x4e75 /* RTS */ \n\
407 #include <stdarg.h>
409 struct AHIAudioCtrl * __attribute__((linearvarargs)) _AHI_AllocAudio(
411 struct AHIBase *AHIBase, ...
414 va_list ap;
415 struct TagItem * varargs;
416 va_startlinear(ap, AHIBase);
417 varargs = va_getlinearva(ap, struct TagItem *);
418 return _AHI_AllocAudioA(
419 varargs, AHIBase);
425 ULONG __attribute__((linearvarargs)) _AHI_ControlAudio(
427 struct AHIAudioCtrl * AudioCtrl,
428 struct AHIBase *AHIBase, ...
431 va_list ap;
432 struct TagItem * varargs;
433 va_startlinear(ap, AHIBase);
434 varargs = va_getlinearva(ap, struct TagItem *);
435 return _AHI_ControlAudioA(
436 (struct AHIPrivAudioCtrl*) AudioCtrl,
437 varargs, AHIBase);
441 BOOL __attribute__((linearvarargs)) _AHI_GetAudioAttrs(
443 ULONG ID,
444 struct AHIAudioCtrl * Audioctrl,
445 struct AHIBase *AHIBase,
449 va_list ap;
450 struct TagItem * varargs;
451 va_startlinear(ap, AHIBase);
452 varargs = va_getlinearva(ap, struct TagItem *);
454 return _AHI_GetAudioAttrsA(
456 (struct AHIPrivAudioCtrl*) Audioctrl,
457 varargs, AHIBase);
461 ULONG __attribute__((linearvarargs)) _AHI_BestAudioID(
463 struct AHIBase *AHIBase, ...
466 va_list ap;
467 struct TagItem * varargs;
468 va_startlinear(ap, AHIBase);
469 varargs = va_getlinearva(ap, struct TagItem *);
470 return _AHI_BestAudioIDA(
471 varargs, AHIBase);
475 struct AHIAudioModeRequester * __attribute__((linearvarargs)) _AHI_AllocAudioRequest(
477 struct AHIBase *AHIBase, ...
480 va_list ap;
481 struct TagItem * varargs;
482 va_startlinear(ap, AHIBase);
483 varargs = va_getlinearva(ap, struct TagItem *);
484 return _AHI_AllocAudioRequestA(
485 varargs, AHIBase);
489 BOOL __attribute__((linearvarargs)) _AHI_AudioRequest(
491 struct AHIAudioModeRequester * Requester,
492 struct AHIBase *AHIBase, ...
495 va_list ap;
496 struct TagItem * varargs;
497 va_startlinear(ap, AHIBase);
498 varargs = va_getlinearva(ap, struct TagItem *);
499 return _AHI_AudioRequestA(
500 Requester,
501 varargs, AHIBase);
505 void __attribute__((linearvarargs)) _AHI_Play(
507 struct AHIAudioCtrl * Audioctrl,
508 struct AHIBase *AHIBase, ...
511 va_list ap;
512 struct TagItem * varargs;
513 va_startlinear(ap, AHIBase);
514 varargs = va_getlinearva(ap, struct TagItem *);
515 _AHI_PlayA(
516 (struct AHIPrivAudioCtrl*) Audioctrl,
517 varargs, AHIBase);
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 **************************************************************/
537 void
538 m68k_DevProc( void )
540 DevProc();
544 /* m68k_PreTimer ************************************************************/
546 BOOL
547 m68k_PreTimer( struct AHIPrivAudioCtrl* audioctrl __asm("a2") )
549 return PreTimer( audioctrl );
553 /* m68k_PostTimer ***********************************************************/
555 void
556 m68k_PostTimer( struct AHIPrivAudioCtrl* audioctrl __asm("a2") )
558 PostTimer( audioctrl );
561 #endif
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
574 #else
576 #ifndef __mc68000__
577 # pragma pack(2) // Make sure the compiler does not insert pads
578 #endif
580 const struct
582 UWORD pushm_d0_d1_a0_a1[2];
583 UWORD jsr;
584 ULONG addr;
585 UWORD popm_d0_d1_a0_a1[2];
586 UWORD rts;
587 } HookEntryPreserveAllRegs __attribute__ ((aligned (4))) =
589 {0x48E7, 0xC0C0},
590 0x4EB9, (ULONG) HookEntry,
591 {0x4CDF, 0x0303},
592 0x4E75
596 const struct
598 UWORD pushm_d1_a0_a1[2];
599 UWORD jsr;
600 ULONG addr;
601 UWORD popm_d1_a0_a1[2];
602 UWORD extl_d0;
603 UWORD rts;
604 } PreTimerPreserveAllRegs __attribute__ ((aligned (4))) =
606 {0x48E7, 0x40C0},
607 0x4EB9, (ULONG) &m68k_PreTimer,
608 {0x4CDF, 0x0302},
609 0x48C0,
610 0x4E75
614 const struct
616 UWORD pushm_d0_d1_a0_a1[2];
617 UWORD jsr;
618 ULONG addr;
619 UWORD popm_d0_d1_a0_a1[2];
620 UWORD rts;
621 } PostTimerPreserveAllRegs __attribute__ ((aligned (4))) =
623 {0x48E7, 0xC0C0},
624 0x4EB9, (ULONG) &m68k_PostTimer,
625 {0x4CDF, 0x0303},
626 0x4E75
629 #endif /* defined( __AROS__ ) / defined( __AMIGAOS4__ ) */