Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Device / header.c
blob4eb75a8cff9acd11979079468faaa438ddec86c4
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>
23 #include <exec/memory.h>
24 #include <exec/resident.h>
25 #include <exec/alerts.h>
26 #include <exec/execbase.h>
27 #include <proto/dos.h>
28 #include <proto/exec.h>
29 #include <proto/gadtools.h>
30 #include <proto/graphics.h>
31 #include <proto/iffparse.h>
32 #if defined(__AROS__)
33 #include <proto/stdc.h>
34 #endif
35 #include "ahi_def.h"
37 #include "header.h"
38 #include "gateway.h"
39 #include "gatestubs.h"
40 #include "localize.h"
41 #include "misc.h"
42 #include "version.h"
44 #ifdef __amithlon__
45 # define RTF_NATIVE (1<<3)
46 # define FUNCARRAY_32BIT_NATIVE 0xfffefffe
47 #endif
49 #if !defined( __AROS__ ) && !defined( __amithlon__ )
50 extern void _etext;
51 #else
52 # define _etext RomTag+1 // Fake it
53 #endif
55 /******************************************************************************
56 ** Function prototypes ********************************************************
57 ******************************************************************************/
59 static BOOL
60 OpenLibs ( void );
62 static void
63 CloseLibs ( void );
65 #define GetSymbol( name ) AHIGetELFSymbol( #name, (void*) &name ## Ptr )
67 #undef Req
68 #define Req( msg ) ReqA( msg, NULL )
70 /******************************************************************************
71 ** Device entry ***************************************************************
72 ******************************************************************************/
74 #if defined( __amithlon__ )
75 __asm( "\n\
76 .text;\n\
77 .byte 0x4e, 0xfa, 0x00, 0x03\n\
78 jmp _start" );
79 #endif
81 int
82 _start( void )
84 return -1;
87 #if defined( __MORPHOS__ )
88 ULONG __abox__=1;
89 ULONG __amigappc__=1; // deprecated, used in MOS 0.4
90 #endif
92 /******************************************************************************
93 ** Device resident structure **************************************************
94 ******************************************************************************/
96 #if defined( __AMIGAOS4__ )
97 static const struct TagItem InitTable[];
98 #else
99 static const APTR InitTable[4];
100 #endif
102 // This structure must reside in the text segment or the read-only
103 // data segment! "const" makes it happen.
104 const struct Resident RomTag __attribute__((used)) =
106 RTC_MATCHWORD,
107 (struct Resident *) &RomTag,
108 (struct Resident *) &_etext,
109 #if defined( __MORPHOS__ )
110 RTF_EXTENDED | RTF_PPC | RTF_AUTOINIT,
111 #elif defined( __AROS__ )
112 RTF_EXTENDED | RTF_AUTOINIT,
113 #elif defined( __amithlon__ )
114 RTF_NATIVE | RTF_AUTOINIT,
115 #elif defined( __AMIGAOS4__ )
116 RTF_NATIVE | RTF_AUTOINIT,
117 #else
118 RTF_AUTOINIT,
119 #endif
120 VERSION,
121 NT_DEVICE,
122 0, /* priority */
123 (BYTE *) &DevName[0],
124 (BYTE *) &IDString[6],
125 (APTR) &InitTable
126 #if defined( __MORPHOS__ ) || defined( __AROS__ )
127 , REVISION, NULL
128 #endif
132 /******************************************************************************
133 ** Globals ********************************************************************
134 ******************************************************************************/
136 const ULONG DriverVersion = 2;
137 const ULONG Version = VERSION;
138 const ULONG Revision = REVISION;
140 const char DevName[] = AHINAME;
141 const char IDString[] = "$VER: " AHINAME " " VERS
142 " ©1994-2005 Martin Blom. " CPU " version.\r\n";
145 struct ExecBase *SysBase = NULL;
146 struct DosLibrary *DOSBase = NULL;
147 struct GfxBase *GfxBase = NULL;
148 struct AHIBase *AHIBase = NULL;
149 struct Library *GadToolsBase = NULL;
150 struct Library *IFFParseBase = NULL;
151 struct IntuitionBase *IntuitionBase = NULL;
152 struct LocaleBase *LocaleBase = NULL;
153 struct Device *TimerBase = NULL;
154 struct UtilityBase *UtilityBase = NULL;
155 #if defined (__AROS__)
156 struct StdCBase *StdCBase = NULL;
157 #endif
159 #if defined( __AMIGAOS4__ )
160 struct ExecIFace *IExec = NULL;
161 struct DOSIFace *IDOS = NULL;
162 struct GadToolsIFace *IGadTools = NULL;
163 struct GraphicsIFace *IGraphics = NULL;
164 struct IFFParseIFace *IIFFParse = NULL;
165 struct IntuitionIFace *IIntuition = NULL;
166 struct LocaleIFace *ILocale = NULL;
167 struct TimerIFace *ITimer = NULL;
168 struct UtilityIFace *IUtility = NULL;
169 #endif
171 struct Resident *MorphOSRes = NULL;
172 static struct timerequest *TimerIO = NULL;
174 #if defined( ENABLE_WARPUP )
175 struct Library *PowerPCBase = NULL;
176 void *PPCObject = NULL;
177 const ULONG __LIB_Version = VERSION;
178 const ULONG __LIB_Revision = REVISION;
179 #endif
181 enum MixBackend_t MixBackend = MB_NATIVE;
183 ADDFUNC* AddByteMonoPtr = AddByteMono;
184 ADDFUNC* AddByteStereoPtr = AddByteStereo;
185 ADDFUNC* AddByte71Ptr = AddByte71;
186 ADDFUNC* AddBytesMonoPtr = AddBytesMono;
187 ADDFUNC* AddBytesStereoPtr = AddBytesStereo;
188 ADDFUNC* AddBytes71Ptr = AddBytes71;
189 ADDFUNC* AddWordMonoPtr = AddWordMono;
190 ADDFUNC* AddWordStereoPtr = AddWordStereo;
191 ADDFUNC* AddWord71Ptr = AddWord71;
192 ADDFUNC* AddWordsMonoPtr = AddWordsMono;
193 ADDFUNC* AddWordsStereoPtr = AddWordsStereo;
194 ADDFUNC* AddWords71Ptr = AddWords71;
195 ADDFUNC* AddLongMonoPtr = AddLongMono;
196 ADDFUNC* AddLongStereoPtr = AddLongStereo;
197 ADDFUNC* AddLong71Ptr = AddLong71;
198 ADDFUNC* AddLongsMonoPtr = AddLongsMono;
199 ADDFUNC* AddLongsStereoPtr = AddLongsStereo;
200 ADDFUNC* Add71MonoPtr = Add71Mono;
201 ADDFUNC* Add71StereoPtr = Add71Stereo;
202 ADDFUNC* AddLongs71Ptr = AddLongs71;
203 ADDFUNC* Add7171Ptr = Add7171;
205 ADDFUNC* AddByteMonoBPtr = AddByteMonoB;
206 ADDFUNC* AddByteStereoBPtr = AddByteStereoB;
207 ADDFUNC* AddByte71BPtr = AddByte71B;
208 ADDFUNC* AddBytesMonoBPtr = AddBytesMonoB;
209 ADDFUNC* AddBytesStereoBPtr = AddBytesStereoB;
210 ADDFUNC* AddBytes71BPtr = AddBytes71B;
211 ADDFUNC* AddWordMonoBPtr = AddWordMonoB;
212 ADDFUNC* AddWordStereoBPtr = AddWordStereoB;
213 ADDFUNC* AddWord71BPtr = AddWord71B;
214 ADDFUNC* AddWordsMonoBPtr = AddWordsMonoB;
215 ADDFUNC* AddWordsStereoBPtr = AddWordsStereoB;
216 ADDFUNC* AddWords71BPtr = AddWords71B;
217 ADDFUNC* AddLongMonoBPtr = AddLongMonoB;
218 ADDFUNC* AddLongStereoBPtr = AddLongStereoB;
219 ADDFUNC* AddLong71BPtr = AddLong71B;
220 ADDFUNC* AddLongsMonoBPtr = AddLongsMonoB;
221 ADDFUNC* AddLongsStereoBPtr = AddLongsStereoB;
222 ADDFUNC* AddLongs71BPtr = AddLongs71B;
223 ADDFUNC* Add71MonoBPtr = Add71MonoB;
224 ADDFUNC* Add71StereoBPtr = Add71StereoB;
225 ADDFUNC* Add7171BPtr = Add7171B;
227 ADDFUNC* AddLofiByteMonoPtr = AddLofiByteMono;
228 ADDFUNC* AddLofiByteStereoPtr = AddLofiByteStereo;
229 ADDFUNC* AddLofiBytesMonoPtr = AddLofiBytesMono;
230 ADDFUNC* AddLofiBytesStereoPtr = AddLofiBytesStereo;
231 ADDFUNC* AddLofiWordMonoPtr = AddLofiWordMono;
232 ADDFUNC* AddLofiWordStereoPtr = AddLofiWordStereo;
233 ADDFUNC* AddLofiWordsMonoPtr = AddLofiWordsMono;
234 ADDFUNC* AddLofiWordsStereoPtr = AddLofiWordsStereo;
235 ADDFUNC* AddLofiLongMonoPtr = AddLofiLongMono;
236 ADDFUNC* AddLofiLongStereoPtr = AddLofiLongStereo;
237 ADDFUNC* AddLofiLongsMonoPtr = AddLofiLongsMono;
238 ADDFUNC* AddLofiLongsStereoPtr = AddLofiLongsStereo;
239 ADDFUNC* AddLofiByteMonoBPtr = AddLofiByteMonoB;
240 ADDFUNC* AddLofiByteStereoBPtr = AddLofiByteStereoB;
241 ADDFUNC* AddLofiBytesMonoBPtr = AddLofiBytesMonoB;
242 ADDFUNC* AddLofiBytesStereoBPtr = AddLofiBytesStereoB;
243 ADDFUNC* AddLofiWordMonoBPtr = AddLofiWordMonoB;
244 ADDFUNC* AddLofiWordStereoBPtr = AddLofiWordStereoB;
245 ADDFUNC* AddLofiWordsMonoBPtr = AddLofiWordsMonoB;
246 ADDFUNC* AddLofiWordsStereoBPtr = AddLofiWordsStereoB;
247 ADDFUNC* AddLofiLongMonoBPtr = AddLofiLongMonoB;
248 ADDFUNC* AddLofiLongStereoBPtr = AddLofiLongStereoB;
249 ADDFUNC* AddLofiLongsMonoBPtr = AddLofiLongsMonoB;
250 ADDFUNC* AddLofiLongsStereoBPtr = AddLofiLongsStereoB;
252 /******************************************************************************
253 ** Device code ****************************************************************
254 ******************************************************************************/
256 #ifndef __AMIGAOS4__
257 static inline void DeleteLibrary(struct Library *base) {
258 FreeMem((APTR)(((char*)base)-base->lib_NegSize),base->lib_NegSize+base->lib_PosSize);
260 #endif
262 struct AHIBase*
263 _DevInit( struct AHIBase* device,
264 APTR seglist,
265 struct ExecBase* sysbase )
267 AHIBase = device;
268 SysBase = sysbase;
270 #ifdef __AMIGAOS4__
271 IExec = (struct ExecIFace*) SysBase->MainInterface;
272 #endif
274 device->ahib_Library.lib_Revision = REVISION;
276 device->ahib_SysLib = sysbase;
277 device->ahib_SegList = (BPTR) seglist;
279 #if defined( __mc68000__ )
280 // Make sure we're running on a M68020 or better
282 if( ( sysbase->AttnFlags & AFF_68020 ) == 0 )
284 Alert( ( AN_Unknown | ACPU_InstErr ) & (~AT_DeadEnd) );
285 DeleteLibrary( &device->ahib_Library );
286 return NULL;
288 #endif
290 InitSemaphore( &device->ahib_Lock );
292 if( !OpenLibs() )
294 CloseLibs();
295 DeleteLibrary( &device->ahib_Library );
296 return NULL;
299 return device;
303 BPTR
304 _DevExpunge( struct AHIBase* device )
306 BPTR seglist = 0;
308 //DebugPrintF("AHI: _DevExpunge\n");
310 if( device->ahib_Library.lib_OpenCnt == 0)
312 seglist = device->ahib_SegList;
314 Remove( (struct Node *) device );
316 CloseLibs();
318 DeleteLibrary( &device->ahib_Library );
320 else
322 device->ahib_Library.lib_Flags |= LIBF_DELEXP;
325 return seglist;
328 ULONG
329 _DevNull( void ) {
330 return 0;
334 #ifndef __AMIGAOS4__
336 static const APTR FuncTable[] =
338 #if defined( __MORPHOS__ ) || defined( __amithlon__ )
339 (APTR) FUNCARRAY_32BIT_NATIVE,
340 #endif
342 gwDevOpen,
343 gwDevClose,
344 gwDevExpunge,
345 gwDevNull,
347 gwDevBeginIO,
348 gwDevAbortIO,
350 gwAHI_AllocAudioA,
351 gwAHI_FreeAudio,
352 gwAHI_KillAudio,
353 gwAHI_ControlAudioA,
354 gwAHI_SetVol,
355 gwAHI_SetFreq,
356 gwAHI_SetSound,
357 gwAHI_SetEffect,
358 gwAHI_LoadSound,
359 gwAHI_UnloadSound,
360 gwAHI_NextAudioID,
361 gwAHI_GetAudioAttrsA,
362 gwAHI_BestAudioIDA,
363 gwAHI_AllocAudioRequestA,
364 gwAHI_AudioRequestA,
365 gwAHI_FreeAudioRequest,
366 gwAHI_PlayA,
367 gwAHI_SampleFrameSize,
368 gwAHI_AddAudioMode,
369 gwAHI_RemoveAudioMode,
370 gwAHI_LoadModeFile,
372 (APTR) -1
376 static const APTR InitTable[4] =
378 (APTR) sizeof( struct AHIBase ),
379 (APTR) &FuncTable,
380 NULL,
381 #if defined( __MORPHOS__ ) || defined( __amithlon__ )
382 (APTR) _DevInit
383 #else
384 (APTR) gwDevInit
385 #endif
388 #else // __AMIGAOS4__
390 static ULONG generic_Obtain(struct Interface *Self)
392 return Self->Data.RefCount++;
395 static ULONG generic_Release(struct Interface *Self)
397 return Self->Data.RefCount--;
401 static const CONST_APTR DevManagerVectors[] =
403 generic_Obtain,
404 generic_Release,
405 NULL,
406 NULL,
408 gwDevOpen,
409 gwDevClose,
410 gwDevExpunge,
411 NULL,
412 gwDevBeginIO,
413 gwDevAbortIO,
415 (CONST_APTR) -1
418 static const struct TagItem DevManagerTags[] =
420 { MIT_Name, (ULONG) "__device" },
421 { MIT_VectorTable, (ULONG) DevManagerVectors },
422 { MIT_Version, 1 },
423 { TAG_DONE, 0 }
427 static const CONST_APTR MainVectors[] = {
428 generic_Obtain,
429 generic_Release,
430 NULL,
431 NULL,
433 gwAHI_AllocAudioA,
434 gwAHI_AllocAudio,
435 gwAHI_FreeAudio,
436 gwAHI_KillAudio,
437 gwAHI_ControlAudioA,
438 gwAHI_ControlAudio,
439 gwAHI_SetVol,
440 gwAHI_SetFreq,
441 gwAHI_SetSound,
442 gwAHI_SetEffect,
443 gwAHI_LoadSound,
444 gwAHI_UnloadSound,
445 gwAHI_NextAudioID,
446 gwAHI_GetAudioAttrsA,
447 gwAHI_GetAudioAttrs,
448 gwAHI_BestAudioIDA,
449 gwAHI_BestAudioID,
450 gwAHI_AllocAudioRequestA,
451 gwAHI_AllocAudioRequest,
452 gwAHI_AudioRequestA,
453 gwAHI_AudioRequest,
454 gwAHI_FreeAudioRequest,
455 gwAHI_PlayA,
456 gwAHI_Play,
457 gwAHI_SampleFrameSize,
458 gwAHI_AddAudioMode,
459 gwAHI_RemoveAudioMode,
460 gwAHI_LoadModeFile,
462 (CONST_APTR) -1
465 static const struct TagItem MainTags[] =
467 { MIT_Name, (ULONG) "main" },
468 { MIT_VectorTable, (ULONG) MainVectors },
469 { MIT_Version, 1 },
470 { TAG_DONE, 0 }
474 /* MLT_INTERFACES array */
475 static const CONST_APTR Interfaces[] =
477 DevManagerTags,
478 MainTags,
479 NULL
482 /* m68k library vectors */
483 static const CONST_APTR VecTable68K[] = {
484 (CONST_APTR) &m68kgwDevOpen,
485 (CONST_APTR) &m68kgwDevClose,
486 (CONST_APTR) &m68kgwDevExpunge,
487 (CONST_APTR) &m68kgwDevNull,
489 (CONST_APTR) &m68kgwDevBeginIO,
490 (CONST_APTR) &m68kgwDevAbortIO,
491 (CONST_APTR) &m68kgwAHI_AllocAudioA,
492 (CONST_APTR) &m68kgwAHI_FreeAudio,
493 (CONST_APTR) &m68kgwAHI_KillAudio,
494 (CONST_APTR) &m68kgwAHI_ControlAudioA,
495 (CONST_APTR) &m68kgwAHI_SetVol,
496 (CONST_APTR) &m68kgwAHI_SetFreq,
497 (CONST_APTR) &m68kgwAHI_SetSound,
498 (CONST_APTR) &m68kgwAHI_SetEffect,
499 (CONST_APTR) &m68kgwAHI_LoadSound,
500 (CONST_APTR) &m68kgwAHI_UnloadSound,
501 (CONST_APTR) &m68kgwAHI_NextAudioID,
502 (CONST_APTR) &m68kgwAHI_GetAudioAttrsA,
503 (CONST_APTR) &m68kgwAHI_BestAudioIDA,
504 (CONST_APTR) &m68kgwAHI_AllocAudioRequestA,
505 (CONST_APTR) &m68kgwAHI_AudioRequestA,
506 (CONST_APTR) &m68kgwAHI_FreeAudioRequest,
507 (CONST_APTR) &m68kgwAHI_PlayA,
508 (CONST_APTR) &m68kgwAHI_SampleFrameSize,
509 (CONST_APTR) &m68kgwAHI_AddAudioMode,
510 (CONST_APTR) &m68kgwAHI_RemoveAudioMode,
511 (CONST_APTR) &m68kgwAHI_LoadModeFile,
513 (CONST_APTR) -1
516 /* CreateLibrary() tag list */
517 static const struct TagItem InitTable[] =
519 { CLT_DataSize, sizeof(struct AHIBase) },
520 { CLT_Interfaces, (ULONG) Interfaces },
521 { CLT_Vector68K, (ULONG) VecTable68K },
522 { CLT_InitFunc, (ULONG) gwDevInit },
523 { TAG_DONE, 0 }
526 #endif // __AMIGAOS4__
529 /******************************************************************************
530 ** OpenLibs *******************************************************************
531 ******************************************************************************/
533 // This function is called by the device startup code when the device is
534 // first loaded into memory.
536 static BOOL
537 OpenLibs ( void )
539 /* Intuition Library */
541 IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 37 );
543 if( IntuitionBase == NULL)
545 Alert(AN_Unknown|AG_OpenLib|AO_Intuition);
546 return FALSE;
549 /* DOS Library */
551 DOSBase = (struct DosLibrary *) OpenLibrary( "dos.library", 37 );
553 if( DOSBase == NULL)
555 Req( "Unable to open 'dos.library'." );
556 return FALSE;
559 /* Graphics Library */
561 GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 37 );
563 if( GfxBase == NULL)
565 Req( "Unable to open 'graphics.library'." );
566 return FALSE;
569 /* GadTools Library */
571 GadToolsBase = OpenLibrary( "gadtools.library", 37 );
573 if( GadToolsBase == NULL)
575 Req( "Unable to open 'gadtools.library'." );
576 return FALSE;
579 /* IFFParse Library */
581 IFFParseBase = OpenLibrary( "iffparse.library", 37 );
583 if( IFFParseBase == NULL)
585 Req( "Unable to open 'iffparse.library'." );
586 return FALSE;
589 /* Locale Library */
591 LocaleBase = (struct LocaleBase*) OpenLibrary( "locale.library", 38 );
593 /* Timer Device */
595 TimerIO = (struct timerequest *) AllocMem( sizeof(struct timerequest),
596 MEMF_PUBLIC | MEMF_CLEAR );
598 if( TimerIO == NULL)
600 Req( "Out of memory." );
601 return FALSE;
604 if( OpenDevice( "timer.device",
605 UNIT_VBLANK,
606 (struct IORequest *)
607 TimerIO,
608 0) != 0 )
610 Req( "Unable to open 'timer.device'." );
611 // return FALSE;
613 else
615 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
618 /* Utility Library */
620 UtilityBase = (struct UtilityBase *) OpenLibrary( "utility.library", 37 );
622 if( UtilityBase == NULL)
624 Req( "Unable to open 'utility.library'." );
625 return FALSE;
628 #if defined(__AROS__)
629 /* StdC library */
631 StdCBase = (struct StdCBase *) OpenLibrary( "stdc.library", 0 );
633 if( StdCBase == NULL)
635 Req( "Unable to open 'stdc.library'." );
636 return FALSE;
638 #endif
640 #ifdef __AMIGAOS4__
641 if ((IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL)) == NULL)
643 Req("Couldn't open IIntuition interface!\n");
644 return FALSE;
647 if ((IDOS = (struct DOSIFace *) GetInterface((struct Library *) DOSBase, "main", 1, NULL)) == NULL)
649 Req("Couldn't open IDOS interface!\n");
650 return FALSE;
653 if ((IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL)) == NULL)
655 Req("Couldn't open Graphics interface!\n");
656 return FALSE;
659 if ((IGadTools = (struct GadToolsIFace *) GetInterface((struct Library *) GadToolsBase, "main", 1, NULL)) == NULL)
661 Req("Couldn't open IGadTools interface!\n");
662 return FALSE;
665 if ((IIFFParse = (struct IFFParseIFace *) GetInterface((struct Library *) IFFParseBase, "main", 1, NULL)) == NULL)
667 Req("Couldn't open IFFParse interface!\n");
668 return FALSE;
671 if ((ILocale = (struct LocaleIFace *) GetInterface((struct Library *) LocaleBase, "main", 1, NULL)) == NULL)
673 Req("Couldn't open ILocale interface!\n");
674 return FALSE;
677 if ((ITimer = (struct TimerIFace *) GetInterface((struct Library *) TimerBase, "main", 1, NULL)) == NULL)
679 Req("Couldn't open Timer interface!\n");
680 return FALSE;
683 if ((IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL)) == NULL)
685 Req("Couldn't open Utility interface!\n");
686 return FALSE;
689 if ((IAHI = (struct AHIIFace *) GetInterface((struct Library *) AHIBase, "main", 1, NULL)) == NULL)
691 Req("Couldn't open AHI interface!\n");
692 return FALSE;
694 #endif
697 /* MorphOS/PowerUp/WarpOS loading
699 Strategy:
701 1) If MorphOS is running, use it.
702 2) If PowerUp is running, but not WarpUp, use the m68k core
703 3) If neither of them are running, try WarpUp.
707 // Check if MorpOS/PowerUp/WarpUp is running.
709 #if defined( ENABLE_WARPUP )
710 struct Library* ppclib = NULL;
711 struct Library* powerpclib = NULL;
712 #endif
714 Forbid();
715 MorphOSRes = FindResident( "MorphOS" );
717 #if defined( ENABLE_WARPUP )
718 powerpclib = (struct Library *) FindName( &SysBase->LibList,
719 "powerpc.library" );
720 ppclib = (struct Library *) FindName( &SysBase->LibList,
721 "ppc.library" );
722 #endif
724 Permit();
726 #if defined( ENABLE_WARPUP )
727 if( MorphOSRes == NULL && ! ( ppclib != NULL && powerpclib == NULL ) )
729 // Open WarpUp (but not if MorphOS or PowerUp is active)
731 PowerPCBase = OpenLibrary( "powerpc.library", 15 );
733 #endif
736 if( MorphOSRes != NULL )
738 MixBackend = MB_NATIVE;
741 #if defined( ENABLE_WARPUP )
743 else if( PowerPCBase != NULL )
745 MixBackend = MB_WARPUP;
747 /* Load our code to PPC.. */
749 PPCObject = AHILoadObject( "DEVS:ahi.device.elf" );
751 if( PPCObject != NULL )
753 ULONG* version = NULL;
754 ULONG* revision = NULL;
756 int r = ~0;
758 AHIGetELFSymbol( "__LIB_Version", (void*) &version );
759 AHIGetELFSymbol( "__LIB_Revision", (void*) &revision );
761 if( version != NULL && revision != NULL )
763 if( *version == VERSION && *revision == REVISION )
765 r &= GetSymbol( AddByteMono );
766 r &= GetSymbol( AddByteStereo );
767 r &= GetSymbol( AddBytesMono );
768 r &= GetSymbol( AddBytesStereo );
769 r &= GetSymbol( AddWordMono );
770 r &= GetSymbol( AddWordStereo );
771 r &= GetSymbol( AddWordsMono );
772 r &= GetSymbol( AddWordsStereo );
773 r &= GetSymbol( AddLongMono );
774 r &= GetSymbol( AddLongStereo );
775 r &= GetSymbol( AddLongsMono );
776 r &= GetSymbol( AddLongsStereo );
777 r &= GetSymbol( AddByteMonoB );
778 r &= GetSymbol( AddByteStereoB );
779 r &= GetSymbol( AddBytesMonoB );
780 r &= GetSymbol( AddBytesStereoB );
781 r &= GetSymbol( AddWordMonoB );
782 r &= GetSymbol( AddWordStereoB );
783 r &= GetSymbol( AddWordsMonoB );
784 r &= GetSymbol( AddWordsStereoB );
785 r &= GetSymbol( AddLongMonoB );
786 r &= GetSymbol( AddLongStereoB );
787 r &= GetSymbol( AddLongsMonoB );
788 r &= GetSymbol( AddLongsStereoB );
790 r &= GetSymbol( AddLofiByteMono );
791 r &= GetSymbol( AddLofiByteStereo );
792 r &= GetSymbol( AddLofiBytesMono );
793 r &= GetSymbol( AddLofiBytesStereo );
794 r &= GetSymbol( AddLofiWordMono );
795 r &= GetSymbol( AddLofiWordStereo );
796 r &= GetSymbol( AddLofiWordsMono );
797 r &= GetSymbol( AddLofiWordsStereo );
798 r &= GetSymbol( AddLofiLongMono );
799 r &= GetSymbol( AddLofiLongStereo );
800 r &= GetSymbol( AddLofiLongsMono );
801 r &= GetSymbol( AddLofiLongsStereo );
802 r &= GetSymbol( AddLofiByteMonoB );
803 r &= GetSymbol( AddLofiByteStereoB );
804 r &= GetSymbol( AddLofiBytesMonoB );
805 r &= GetSymbol( AddLofiBytesStereoB );
806 r &= GetSymbol( AddLofiWordMonoB );
807 r &= GetSymbol( AddLofiWordStereoB );
808 r &= GetSymbol( AddLofiWordsMonoB );
809 r &= GetSymbol( AddLofiWordsStereoB );
810 r &= GetSymbol( AddLofiLongMonoB );
811 r &= GetSymbol( AddLofiLongStereoB );
812 r &= GetSymbol( AddLofiLongsMonoB );
813 r &= GetSymbol( AddLofiLongsStereoB );
815 if( r != 0 )
817 char buffer[ 2 ] = "0";
819 GetVar( "PowerPC/UseDisable", buffer, sizeof buffer, 0 );
821 if( buffer[ 0 ] == '1' )
823 // OK, then...
825 else
827 Req( "The WarpUp variable 'PowerPC/UseDisable' must be '1'." );
829 AHIUnloadObject( PPCObject );
830 PPCObject = NULL;
831 MixBackend = MB_NATIVE;
834 else
836 Req( "Unable to fetch all symbols from ELF object." );
838 AHIUnloadObject( PPCObject );
839 PPCObject = NULL;
840 MixBackend = MB_NATIVE;
843 else
845 Req( "'ahi.device.elf' version %ld.%ld doesn't match "
846 "'ahi.device' version %ld.%ld.",
847 *version, *revision, VERSION, REVISION );
849 AHIUnloadObject( PPCObject );
850 PPCObject = NULL;
851 MixBackend = MB_NATIVE;
854 else
856 Req( "Unable to fetch version information from 'ahi.device.elf'." );
858 AHIUnloadObject( PPCObject );
859 PPCObject = NULL;
860 MixBackend = MB_NATIVE;
863 else
865 MixBackend = MB_NATIVE;
869 #endif
871 else
873 //MixBackend = MB_NATIVE;
876 OpenahiCatalog(NULL, NULL);
878 return TRUE;
882 /******************************************************************************
883 ** CloseLibs *******************************************************************
884 ******************************************************************************/
886 // This function is called by DevExpunge() when the device is about to be
887 // flushed
889 static void
890 CloseLibs ( void )
892 CloseahiCatalog();
894 #if defined( ENABLE_WARPUP )
895 if( PPCObject != NULL )
897 AHIUnloadObject( PPCObject );
900 CloseLibrary( PowerPCBase );
901 #endif
903 #ifdef __AMIGAOS4__
904 DropInterface((struct Interface *) IUtility );
905 DropInterface((struct Interface *) ITimer );
906 DropInterface((struct Interface *) ILocale );
907 DropInterface((struct Interface *) IIFFParse );
908 DropInterface((struct Interface *) IGadTools );
909 DropInterface((struct Interface *) IGraphics );
910 DropInterface((struct Interface *) IDOS );
911 DropInterface((struct Interface *) IIntuition );
912 DropInterface((struct Interface *) IAHI );
913 #endif
915 #if defined(__AROS__)
916 CloseLibrary( (struct Library *) StdCBase );
917 #endif
918 CloseLibrary( (struct Library *) UtilityBase );
920 if( TimerIO != NULL )
922 if( TimerBase != NULL )
924 CloseDevice( (struct IORequest *) TimerIO );
927 FreeMem( TimerIO, sizeof(struct timerequest) );
930 CloseLibrary( (struct Library *) LocaleBase );
931 CloseLibrary( IFFParseBase );
932 CloseLibrary( GadToolsBase );
933 CloseLibrary( (struct Library *) GfxBase );
934 CloseLibrary( (struct Library *) DOSBase );
935 CloseLibrary( (struct Library *) IntuitionBase );