/******************************************************************************/ /* */ /* our include */ /* */ /******************************************************************************/ #include "libinit.h" /******************************************************************************/ /* */ /* *** FIRST *** function - prevents a crash when called from CLI! */ /* */ /******************************************************************************/ LONG safefail(VOID) { return -1; } /******************************************************************************/ /* */ /* a do nothing stub (required!) */ /* */ /******************************************************************************/ LONG LibExtFunc(VOID) { return 0; } /******************************************************************************/ /* */ /* remove library from memory if possible */ /* */ /* !!! CAUTION: This function runs in a forbidden state !!! */ /* */ /******************************************************************************/ LONG LibExpunge(REG(a6,__LIB lib)) { LONG SegList = 0; /* set delayed expunge flag */ lib->LibNode.lib_Flags |= LIBF_DELEXP; /* still in use? */ if (!lib->LibNode.lib_OpenCnt) { APTR SysBase = lib->SysBase; /* remove library from SysBase->LibList */ Remove((struct Node *)lib); /* now call user-exit */ __UserLibCleanup(lib->DataSeg); /* return the seglist for UnLoadSeg() */ SegList = lib->SegList; /* free library */ FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); } return SegList; } /******************************************************************************/ /* */ /* LibClose() will be called for every CloseLibrary() */ /* */ /* !!! CAUTION: This function runs in a forbidden state !!! */ /* */ /******************************************************************************/ LONG LibClose(REG(a6,__LIB lib)) { LONG SegList = 0; /* one less user */ if (!--lib->LibNode.lib_OpenCnt && (lib->LibNode.lib_Flags & LIBF_DELEXP)) SegList = LibExpunge(lib); /* SegList or NULL (still in use) */ return SegList; } /******************************************************************************/ /* */ /* LibOpen() will be called for every OpenLibrary() */ /* */ /* !!! CAUTION: This function runs in a forbidden state !!! */ /* */ /******************************************************************************/ APTR LibOpen(REG(a6,__LIB lib)) { /* clear delayed expunge flag */ lib->LibNode.lib_Flags &= ~LIBF_DELEXP; /* one new user */ lib->LibNode.lib_OpenCnt++; /* return basePtr */ return lib; } /******************************************************************************/ /* */ /* initialization function called by MakeLibrary() */ /* */ /******************************************************************************/ #ifdef __BASEREL__ static __inline APTR __GetDataSeg(void) { APTR res; __asm("lea ___a4_init,%0" : "=a" (res)); return res; } static __inline ULONG __BSize(void) { ULONG res; __asm("movel #___bss_size,%0" : "=d" (res)); return res; } static __inline APTR __GetBssStart(void) { APTR res; __asm("lea __edata,%0" : "=a" (res)); return res; } #endif //__BASEREL APTR LibInit(REG(a0,LONG SegList),REG(d0,__LIB lib),REG(a6,struct Library *SysBase)) { ULONG size; /* set up header data */ lib->LibNode.lib_Node.ln_Type = NT_LIBRARY; lib->LibNode.lib_Node.ln_Name = (char *)LibName; lib->LibNode.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED; lib->LibNode.lib_Version = (UWORD)LibVersion; lib->LibNode.lib_Revision = (UWORD)LibRevision; lib->LibNode.lib_IdString = (char *)LibIdString; /* setup private data */ lib->SegList = SegList; lib->SysBase = SysBase; #ifdef __BASEREL__ lib->DataSeg = __GetDataSeg(); /* clear the bss part */ if ((size=__BSize())) { ULONG *p = __GetBssStart(); do { *p++ = 0; } while ((size-=sizeof(*p))); } #endif /* now call user-init */ if (__UserLibInit(&lib->LibNode,lib->DataSeg)) { FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); lib = NULL; } /* this will be added to SysBase->LibList or NULL (init error) */ return lib; } /******************************************************************************/ /* */ /* autoinit table for use with initial MakeLibrary() */ /* */ /******************************************************************************/ static const APTR InitTab[] = { (APTR)sizeof(struct libBase), (APTR)&__FuncTable__[1], (APTR)NULL, (APTR)&LibInit }; /******************************************************************************/ /* */ /* resident structure */ /* */ /******************************************************************************/ static const struct Resident RomTag = { RTC_MATCHWORD, (struct Resident *)&RomTag, (struct Resident *)&RomTag+1, RTF_AUTOINIT, 0, NT_LIBRARY, 0, (char *)LibName, (char *)LibIdString, (APTR)&InitTab }; /******************************************************************************/ /* */ /* add these functions to 'funclist' */ /* */ /******************************************************************************/ __attribute__((section(".list___FuncTable__,\"aw\""))) APTR __FuncTable__[] = {0}; ADD2LIST(LibOpen,__FuncTable__,22); ADD2LIST(LibClose,__FuncTable__,22); ADD2LIST(LibExpunge,__FuncTable__,22); ADD2LIST(LibExtFunc,__FuncTable__,22); /******************************************************************************/ /* */ /* end of libinit.c */ /* */ /******************************************************************************/