/********************************************************************/
/*   Modul : COOKIE.C                                               */
/*                                                                  */
/*   Autor : Markus Hvener, Markenkamp 13                          */
/*           4358 Haltern, Tel.: 02364/169855                       */
/*                                                                  */
/*           Diese Modul beinhaltet alle grundlegenden Funktionen,  */
/*           die zum Umgang mit COOKIEs erforderlich sind.          */
/*                                                                  */
/********************************************************************/

# include <portab.h>
# include <stddef.h>
# include <stdio.h>
# include <string.h>
# include <tos.h>

# include "cookie.h"




/********************************************************************/
/* Zeiger auf den COOKIE-Jar holen                                  */
/*                                                                  */
/* bergabe : ---                                                   */
/* Rckgabe : Zeiger auf den Jar                                    */
/*                                                                  */
/********************************************************************/
COOKIE_STRUCT *GetJarPointer( VOID )
{
	LONG  old_stack,
	      *jar;
	

	/* Zeiger holen */
	old_stack = Super( 0L );
	jar       = *((LONG **)_p_cookies);


	Super( (VOID *)old_stack );

	return( (COOKIE_STRUCT *)jar );
}








/********************************************************************/
/* Eine COOKIE-Struktur im Speicher erstellen                       */
/*                                                                  */
/* bergabe : Zeiger auf die Struktur, ID, Wert                     */
/* Rckgabe : ---                                                   */
/*                                                                  */
/********************************************************************/
VOID CreateCookieStruct( COOKIE_STRUCT *ptr,
                         UBYTE *id, LONG value )
{
	/* ID kopieren */
	strncpy( ptr->id, id, 4L );


	/* Wert einsetzen */
	ptr->value = value;
}








/********************************************************************/
/* Ermittelt die Gre des Jars                                     */
/*                                                                  */
/* bergabe : ---                                                   */
/* Rckgabe : Gre des Jars                                        */
/*                                                                  */
/********************************************************************/
LONG GetJarSize( VOID )
{
	COOKIE_STRUCT  *jar;
	LONG           i = 0;


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i]) )
		++i;

		
	/* Wert des NULL-COOKIES als Rckgabewert */
	return( jar[i].value );
}








/********************************************************************/
/* Ermittelt die Anzahl der belegten COOKIES im Jar                 */
/*                                                                  */
/* bergabe : ---                                                   */
/* Rckgabe : Anzahl der COOKIES                                    */
/*                                                                  */
/********************************************************************/
LONG GetJarUsed( VOID )
{
	COOKIE_STRUCT  *jar;
	LONG           i = 0;


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i++]) );
	
		
	/* Wert der Zhlervariable als Rckgabewert */
	return( --i );
}








/********************************************************************/
/* Sucht einen COOKIE anhand der ID                                 */
/*                                                                  */
/* bergabe : ID, Zeiger auf LONG (fr das Ergebnis des gefundenen  */
/*            COOKIES (bei bergabe von NULL wird der Wert nicht    */
/*            in die Variable geschrieben                           */
/* Rckgabe : 0 falls gefunden; ansonsten !0                        */
/*                                                                  */
/********************************************************************/
WORD FindCookie( UBYTE *id, LONG *value )
{
	COOKIE_STRUCT  *jar;
	LONG           i = 0;


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i]) )
		if( !strncmp( jar[i].id, id, 4L ) )
		{
			/* Wert interessant ?? */
			if( value != NULL )
				*value = jar[i].value;
				
			return( CK_NO_ERROR );
		}
		else
			++i;

		
	/* Nicht gefunden... */
	return( CK_NO_FOUND );
}








/********************************************************************/
/* Fgt einen COOKIE in den Jar ein                                 */
/*                                                                  */
/* bergabe : Zeiger auf den COOKIE                                 */
/* Rckgabe : 0 falls geklappt, sonst !0                            */
/*                                                                  */
/********************************************************************/
WORD InsertCookie( COOKIE_STRUCT *cp )
{
	COOKIE_STRUCT  *jar,
	               buffer;
	LONG           i = 0;


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* COOKIE schon da ?? */
	if( !FindCookie( cp->id, NULL ) )
		return( CK_EXISTED );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i++]) );



	/* Ist noch Platz im Jar ?? 
	   Also einfgen...          */
	if( i < GetJarSize() )
	{
		/* NULL-COOKIE puffern */
		memcpy( &buffer, &jar[i - 1], sizeof( COOKIE_STRUCT ) );

		/* Neuen COOKIE schreiben */
		memcpy( &jar[i - 1], cp, sizeof( COOKIE_STRUCT ) );
		
		/* NULL-COOKIE schreiben */
		memcpy( &jar[i], &buffer, sizeof( COOKIE_STRUCT ) );

		return( CK_NO_ERROR );
	}


		
	/* Nicht geklappt... */
	return( CK_NO_FREE );
}








/********************************************************************/
/* Lscht einen COOKIE aus dem Jar                                  */
/*                                                                  */
/* bergabe : ID des COOKIES                                        */
/* Rckgabe : 0 falls geklappt, sonst !0                            */
/*                                                                  */
/********************************************************************/
WORD DeleteCookie( UBYTE *id )
{
	COOKIE_STRUCT  *jar;
	LONG           i = 0,
	               j,
	               max_index = GetJarSize();


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i]) )
		if( !strncmp( jar[i].id, id, 4L ) )
		{
			for( j=i; j<max_index - 1; j++ )
				memcpy( &jar[j], &jar[j + 1], sizeof( COOKIE_STRUCT ) );

			return( CK_NO_ERROR );
		}
		else
			++i;
		

	/* Nichts gefunden... */
	return( CK_NO_FOUND );
}








/********************************************************************/
/*                                                                  */
/* bergabe : ID, Neuer gewnschter Wert                            */
/* Rckgabe : 0 falls geklappt, sonst !0                            */
/*                                                                  */
/********************************************************************/
LONG ChangeCookieValue( UBYTE *id, LONG new_value )
{
	COOKIE_STRUCT  *jar;
	LONG           i = 0;


	/* Zeiger holen */
	if( (jar = GetJarPointer()) == NULL )
		return( CK_NO_JAR );


	/* Solange der NULL-Cookie nicht erreicht ist */
	while( *((LONG *)&jar[i]) )
		if( !strncmp( jar[i].id, id, 4L ) )
		{
			jar[i].value = new_value;
				
			return( CK_NO_ERROR );
		}
		else
			++i;

		
	/* Nicht gefunden... */
	return( CK_NO_FOUND );
}






/********************************************************************/
/* Liefert die Bedeutung eines Cookies als String                   */
/*                                                                  */
/* bergabe : ID, Wert des Cookies, String fr die Erklrung        */
/* Rckgabe : 0 : Bedeutung bekannt, !0 : nicht bekannt             */
/*                                                                  */
/********************************************************************/
WORD GetCookieExplanation( UBYTE *id, LONG value, UBYTE *res )
{
	strcpy( res, "" );


	/*************/
	/* CPU-Werte */
	/*************/
	if( !strncmp( id, "_CPU", 4L ) )
	{
		strcpy( res, "Typ unbekannt" );

		switch( (WORD)value )
		{
			case 0  : strcpy( res, "68000er CPU" ); break;
			case 10 : strcpy( res, "68010er CPU" ); break;
			case 20 : strcpy( res, "68020er CPU" ); break;
			case 30 : strcpy( res, "68030er CPU" ); break;
		}
		return( 0 );
	}


	/**********/
	/* FPU    */
	/**********/
	if( !strncmp( id, "_FPU", 4L ) )
	{
		if( !value )
			strcpy( res, "Keine FPU vorhanden" );


		value >>= 16;


		/* Bit 0 */
		if( value & 1L )
			strcpy( res, "SFP 004 oder kompatible FPU-Karte" );

		/* Bit 1..2 */
		if( (value & 6L) )
			switch( ((WORD)value & 6) >> 1 )
			{
				case 0 : strcpy( res, "Weder 68881 oder 68882" ); break;
				case 1 : strcpy( res, "68881 oder 68882" ); break;
				case 2 : strcpy( res, "68881" ); break;
				case 3 : strcpy( res, "68882" ); break;
			}
		
		if( value & 8L )
			strcpy( res, "68040er FPU" );

		return( 0 );
	}




	/*******************/
	/* Fast-RAM-Buffer */
	/*******************/
	if( !strncmp( id, "_FRB", 4L ) )
	{
		sprintf( res, "Fast-RAM-Buffer Adresse : 0x%lX", value );
		return( 0 );
	}



	/******************/
	/* Maschinentyp   */
	/******************/
	if( !strncmp( id, "_MCH", 4L ) )
	{
		switch( (WORD)(value >> 16) )
		{
			case 0 : strcpy( res, "ST-Rechner" ); break;
			case 1 : strcpy( res, "STE-Rechner" ); break;
			case 2 : strcpy( res, "TT-Rechner" ); break;
		}
		return( 0 );
	}


	/*****************/
	/* Soundhardware */
	/*****************/
	if( !strncmp( id, "_SND", 4L ) )
	{
		if( value & 1L )
			strcpy( res, "GI/YAMAHA Sound Chip" );
		else
			strcpy( res, "Stereo-DMA-Sound" );

		return( 0 );
	}


	/********************/
	/* Floppycontroller */
	/********************/
	if( !strncmp( id, "_FDC", 4L ) )
	{
		switch( (WORD)(value >> 16) )
		{
			case 0 : strcpy( res, "Normales Floppyinterface" ); break;
			case 1 : strcpy( res, "High-Density" ); break;
			case 2 : strcpy( res, "Extra High Density" ); break;
		}
		return( 0 );
	}



	/********************/
	/* File-Locking     */
	/********************/
	if( !strncmp( id, "_FLK", 4L ) )
	{
		sprintf( res, "File-Locking mglich (Versionsnummer %ld)", value );
		return( 0 );
	}


	/********************/
	/* Netzwerk         */
	/********************/
	if( !strncmp( id, "_NET", 4L ) )
	{
		strcpy( res, "Netzwerkerweiterung vorhanden" );
		return( 0 );
	}
	
	/********************/
	/* Videohardware    */
	/********************/
	if( !strncmp( id, "_VDO", 4L ) )
	{
		switch( (WORD)(value >> 16) )
		{
			case 0 : strcpy( res, "ST-Videohardware" ); break;
			case 1 : strcpy( res, "STE-Videohardware" ); break;
			case 2 : strcpy( res, "TT-Videohardware" ); break;
		}
		return( 0 );
	}


	return( -1 );
}