/*
**      $VER: SP_StartUp.c 3.3 (4.1.97)
**
**      Library startup-code and function table definition
**
**      (C) Copyright 1994-97 Andreas R. Kleinert
**      All Rights Reserved.
*/

#define _STDLIB_H
#define SPOBJECTS_SPOBJECTBASE_H  /* we need the internal version here */

#include "spobject.h"
#include "spobjectbase.h"

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

extern ULONG __saveds __stdargs SPLI_OpenLibs(void);
extern void  __saveds __stdargs SPLI_CloseLibs(void);
extern void  __saveds __stdargs SPLI_InitSPOList(void);

struct SPObjectBase * __saveds __asm InitLib( register __a6 struct ExecBase      *sysbase,
                                               register __a0 struct SegList       *seglist,
                                               register __d0 struct SPObjectBase *spb);

struct SPObjectBase * __saveds __asm OpenLib( register __a6 struct SPObjectBase *SPObjectBase);
struct SegList * __saveds __asm CloseLib( register __a6 struct SPObjectBase *SPObjectBase);
struct SegList * __saveds __asm ExpungeLib( register __a6 struct SPObjectBase *spb);
ULONG __saveds __asm ExtFuncLib(void);


LONG __saveds __asm LibStart(void)
{
 return(-1);
}

extern APTR FuncTab [];
extern struct MyDataInit DataTab;

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

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

 SPO_AllocHandle,
 SPO_FreeHandle,
 SPO_Read,
 SPO_StartReplay,
 SPO_Write,
 SPO_StopReplay,
 SPO_FreeResources,
 SPO_SetAccessMode,
 SPO_SetWriteSubType,
 SPO_SetWriteName,
 SPO_SetReadName,
 SPO_FileInfoRequest,
 SPO_CheckFileType,
 SPO_SetReqIOWindow,
 SPO_ContinueReplay,
 SPO_FastForward,
 SPO_FastBackward,
 SPO_GetSampleBuffer,
 SPO_GetSampleInfo,
 SPO_GetSampleList,
 SPO_SetSampleList,

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


extern struct SPObjectBase *SPObjectBase;


struct SPObjectBase * __saveds __asm InitLib( register __a6 struct ExecBase      *sysbase,
                                               register __a0 struct SegList       *seglist,
                                               register __d0 struct SPObjectBase *spb)
{
 SPObjectBase = spb;

 SPObjectBase->spb_SysBase = sysbase;
 SPObjectBase->spb_SegList = seglist;

 if(SPLI_OpenLibs())
  {
   SPLI_InitSPOList();

   return(SPObjectBase);
  }

 SPLI_CloseLibs();

  {
   ULONG negsize, possize, fullsize;
   UBYTE *negptr = (UBYTE *) SPObjectBase;

   negsize  = SPObjectBase->spb_LibNode.lib_NegSize;
   possize  = SPObjectBase->spb_LibNode.lib_PosSize;
   fullsize = negsize + possize;
   negptr  -= negsize;

   FreeMem(negptr, fullsize);
  }

 return(N);
}

struct SPObjectBase * __saveds __asm OpenLib( register __a6 struct SPObjectBase *SPObjectBase)
{
 SPObjectBase->spb_LibNode.lib_OpenCnt++;

 SPObjectBase->spb_LibNode.lib_Flags &= ~LIBF_DELEXP;

 return(SPObjectBase);
}

struct SegList * __saveds __asm CloseLib( register __a6 struct SPObjectBase *SPObjectBase)
{
 SPObjectBase->spb_LibNode.lib_OpenCnt--;

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

 return(N);
}

struct SegList * __saveds __asm ExpungeLib( register __a6 struct SPObjectBase *spb)
{
 struct SPObjectBase *SPObjectBase = spb;
 struct SegList       *seglist;

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

   seglist = SPObjectBase->spb_SegList;

   Remove(SPObjectBase);

   SPLI_CloseLibs();

   negsize  = SPObjectBase->spb_LibNode.lib_NegSize;
   possize  = SPObjectBase->spb_LibNode.lib_PosSize;
   fullsize = negsize + possize;
   negptr  -= negsize;

   FreeMem(negptr, fullsize);

   return(seglist);
  }

 SPObjectBase->spb_LibNode.lib_Flags |= LIBF_DELEXP;

 return(N);
}

ULONG __saveds __asm ExtFuncLib(void)
{
 return(N);
}

struct SPObjectBase *SPObjectBase = N;

#ifdef __SASC

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;

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

#endif /* __SASC */
