/*
**      $VER: StartUp.c 37.10 (1.4.97)
**
**      Library startup-code and function table definition
**
**      (C) Copyright 1996-97 Andreas R. Kleinert
**      All Rights Reserved.
*/

#define __USE_SYSBASE        // perhaps only recognized by SAS/C

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <exec/resident.h>
#include <exec/initializers.h>


#ifdef __MAXON__
#include <pragma/exec_lib.h>
#include <linkerfunc.h>
#else
#include <proto/exec.h>    // all other compilers
#endif
#include "compiler.h"

#ifdef __GNUC__
#include "examplebase.h"  // GNUC can not handle relativ pathnames.
                          // The full path must be given in the makefile
#else
#include "/include/example/examplebase.h"
#endif
#include "SampleFuncs.h"

extern ULONG __saveds __stdargs L_OpenLibs(void);
extern void  __saveds __stdargs L_CloseLibs(void);

struct ExampleBase * __saveds ASM InitLib( register __a6 struct ExecBase *sysbase GNUCREG("a6"),
                    register __a0 APTR           *seglist GNUCREG("a0"),
                    register __d0 struct ExampleBase *exb GNUCREG("d0"));
struct ExampleBase * __saveds ASM OpenLib( register __a6 struct ExampleBase *ExampleBase GNUCREG("a6"));
APTR __saveds ASM CloseLib( register __a6 struct ExampleBase *ExampleBase GNUCREG("a6"));
APTR __saveds ASM ExpungeLib( register __a6 struct ExampleBase *exb GNUCREG("a6"));
ULONG ASM ExtFuncLib(void);

LONG ASM LibStart(void)
{
 return(-1);
}

extern APTR FuncTab [];
extern struct MyDataInit DataTab;

struct InitTable                       /* do not change */
{
 ULONG              LibBaseSize;
 APTR              *FunctionTable;
 struct MyDataInit *DataTable;
 APTR               InitLibTable;
} InitTab =
{
 sizeof(struct ExampleBase),
 &FuncTab[0],
 &DataTab,
 InitLib
};

APTR FuncTab [] =                      
{
 OpenLib,
 CloseLib,
 ExpungeLib,
 ExtFuncLib,

 EXF_TestRequest,  /* add your own functions here */

 (APTR) ((LONG)-1)
};


extern struct ExampleBase *ExampleBase;

struct ExampleBase * __saveds ASM InitLib( register __a6 struct ExecBase      *sysbase GNUCREG("a6"),
                    register __a0 APTR           *seglist GNUCREG("a0"),
                    register __d0 struct ExampleBase *exb GNUCREG("d0"))
{
 ExampleBase = exb;

 ExampleBase->exb_SysBase = sysbase;
 ExampleBase->exb_SegList = seglist;

 if(L_OpenLibs()) return(ExampleBase);

 L_CloseLibs();

 return(NULL);
}

struct ExampleBase * __saveds ASM OpenLib( register __a6 struct ExampleBase *ExampleBase GNUCREG("a6"))
{
 #ifdef __MAXON__
 GetBaseReg();
 InitModules();
 #endif

 ExampleBase->exb_LibNode.lib_OpenCnt++;

 ExampleBase->exb_LibNode.lib_Flags &= ~LIBF_DELEXP;

 return(ExampleBase);
}

APTR __saveds ASM CloseLib( register __a6 struct ExampleBase *ExampleBase GNUCREG("a6"))
{
 ExampleBase->exb_LibNode.lib_OpenCnt--;

 if(!ExampleBase->exb_LibNode.lib_OpenCnt)
  {
   if(ExampleBase->exb_LibNode.lib_Flags & LIBF_DELEXP)
    {
     return( ExpungeLib(ExampleBase) );
    }
  }

 return(NULL);
}

APTR __saveds ASM ExpungeLib( register __a6 struct ExampleBase *exb GNUCREG("a6"))
{
 struct ExampleBase *ExampleBase = exb;
 APTR seglist;

 if(!ExampleBase->exb_LibNode.lib_OpenCnt)
  {
   ULONG negsize, possize, fullsize;
   UBYTE *negptr = (UBYTE *) ExampleBase;

   seglist = ExampleBase->exb_SegList;

   Remove((struct Node *)ExampleBase);

   L_CloseLibs();

   negsize  = ExampleBase->exb_LibNode.lib_NegSize;
   possize  = ExampleBase->exb_LibNode.lib_PosSize;
   fullsize = negsize + possize;
   negptr  -= negsize;

   FreeMem(negptr, fullsize);

   #ifdef __MAXON__
   CleanupModules();
   #endif

   return(seglist);
  }
  
 ExampleBase->exb_LibNode.lib_Flags |= LIBF_DELEXP;

 return(NULL);
}

ULONG ASM ExtFuncLib(void)
{
 return(NULL);
}

struct ExampleBase *ExampleBase = NULL;

#ifdef __SASC

#ifdef ARK_OLD_STDIO_FIX

ULONG XCEXIT       = NULL; /* these symbols may be referenced by    */
ULONG _XCEXIT      = NULL; /* some functions of sc.lib, but should  */
ULONG ONBREAK      = NULL; /* never be used inside a shared library */
ULONG _ONBREAK     = NULL;
ULONG base         = NULL;
ULONG _base        = NULL;
ULONG ProgramName  = NULL;
ULONG _ProgramName = NULL;
ULONG StackPtr     = NULL;
ULONG _StackPtr    = NULL;
ULONG oserr        = NULL;
ULONG _oserr       = NULL;
ULONG OSERR        = NULL;
ULONG _OSERR       = NULL;

#endif /* ARK_OLD_STDIO_FIX */

void __regargs __chkabort(void) { }  /* a shared library cannot be    */
void __regargs _CXBRK(void)     { }  /* CTRL-C aborted when doing I/O */

#endif /* __SASC */
