
/*****************************************************************************
 *
 * CyberSound: 14 Bit sound driver
 *
 * (c) 1995 by Christian Buchner
 *
 *****************************************************************************
 *
 * Library.c
 */

#include "driverbase.h"

#undef IntuitionBase
#undef GfxBase


/*****************************************************************************/

struct Library *__asm LibInit (register __d0 struct DriverBase *db, register __a0 BPTR seglist, register __a6 struct Library * sysbase);

UBYTE LibName[]="14bit.driver";
UBYTE Version[]={'$','V','E','R',':',' '};
UBYTE LibId[]="14bit.driver 1.1 "__AMIGADATE__" by Christian Buchner\n";

extern UWORD LibFuncTable[];
extern UWORD LibDataTable[];

ULONG LibInitTable[]=
{
	(ULONG)sizeof(struct DriverBase),
	(ULONG)LibFuncTable,
	(ULONG)LibDataTable,
	(ULONG)&LibInit
};


/*****************************************************************************/

struct Library *__asm LibInit (register __d0 struct DriverBase *db, register __a0 BPTR seglist, register __a6 struct Library * sysbase)
{
	SegList = seglist;
	
	return (struct Library*) db;
}

/*****************************************************************************/

LONG __asm LibOpen (register __a6 struct DriverBase *db)
{
	LONG retval = NULL;
	
	Forbid();
	
	/* This library can only be opened once */
	
	if (db->db_Lib.lib_OpenCnt == 0)
	{
		/* Open Intuition and Gfx */
		
		if (db->db_DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37))
		{
			if (db->db_IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",37))
			{
				if (db->db_GfxBase=(struct GfxBase*)OpenLibrary("graphics.library",37))
				{
					/* Verify size of library base */
					
					if (db->db_Lib.lib_PosSize==sizeof(struct DriverBase))
					{
						/* Init driver */
						
						if (InitDriver(db))
						{
							/* success */
							db->db_Lib.lib_OpenCnt++;
							db->db_Lib.lib_Flags &= ~LIBF_DELEXP;
							retval = (LONG) db;
						}
					}
				}
			}
		}
		/* On failure, close Gfx and Intuition */
		
		if (!retval)
		{
			if (db->db_GfxBase)
			{
				CloseLibrary((struct Library*)db->db_GfxBase);
				db->db_GfxBase=NULL;
			}
			if (db->db_IntuitionBase)
			{
				CloseLibrary((struct Library*)db->db_IntuitionBase);
				db->db_IntuitionBase=NULL;
			}
			if (db->db_DOSBase)
			{
				CloseLibrary((struct Library*)db->db_DOSBase);
				db->db_DOSBase=NULL;
			}
		}
	}
	
	Permit();
	
	return (retval);
}

/*****************************************************************************/

LONG __asm LibClose (register __a6 struct DriverBase *db)
{
	LONG retval = NULL;
	
	Forbid();
	
	if (db->db_Lib.lib_OpenCnt) db->db_Lib.lib_OpenCnt--;
	
	if (db->db_Lib.lib_OpenCnt == 0)
	{
		/* Deinit driver */
		
		DeInitDriver(db);
		
		/* Close Gfx and Intuition */
		
		if (db->db_GfxBase)
		{
			CloseLibrary((struct Library*)db->db_GfxBase);
			db->db_GfxBase=NULL;
		}
		if (db->db_IntuitionBase)
		{
			CloseLibrary((struct Library*)db->db_IntuitionBase);
			db->db_IntuitionBase=NULL;
		}
		if (db->db_DOSBase)
		{
			CloseLibrary((struct Library*)db->db_DOSBase);
			db->db_DOSBase=NULL;
		}
	}
	
	if (db->db_Lib.lib_Flags & LIBF_DELEXP) retval = LibExpunge (db);
	
	Permit();
	
	return (retval);
}

/*****************************************************************************/

LONG __asm LibExpunge (register __a6 struct DriverBase *db)
{
	BPTR seg = SegList;
	
	if (db->db_Lib.lib_OpenCnt)
	{
		db->db_Lib.lib_Flags |= LIBF_DELEXP;
		return (NULL);
	}
	
	Remove ((struct Node *) db);
	
	FreeMem ((APTR)((ULONG)(db) - (ULONG)(db->db_Lib.lib_NegSize)), (ULONG)(db->db_Lib.lib_NegSize + db->db_Lib.lib_PosSize));
	
	return ((LONG) seg);
}

/*****************************************************************************/

void __asm LibReserved(register __a6 struct DriverBase *db)
{
}
