/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss of reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#ifndef _COOP_H
#define _COOP_H

#include <exec/BZ.h>

typedef struct {

	void			(*irqs)(void);	// Interrupt service entry. MUST BE FIRST!!!
	void			(*idle)(void);	// Idle processing
	BZ_PROC			*proc;			// Process table
	BZ_PORT			*port;			// Message port table
	BZ_MESG			*pool;			// Message pool table
	BZ_TIME			*tptr;			// Timer queue
	unsigned int	uptu;			// Uptime, microseconds
	unsigned int	upts;			// Uptime, seconds
	unsigned char	pnum;			// Number of ports
	unsigned char	flag;			// An internal event flag
	unsigned char	maxp;			// Max number of processes
	unsigned char	self;			// Current process index
	unsigned char	free;			// Free message list head
	unsigned char	mode;			// Priority or round-robin

} BZ_STAT;

extern BZ_STAT _bz_stat;

void	_bz_init( void (*)(void), int * ) __attribute__ ((noreturn));
int		_bz_context_switch( int, int **, int ** );
void	_bz_start( void );
int		_bz_EventPost( unsigned, int );
void	_bz_TimerAdd( BZ_STAT *base, BZ_TIME *this );

#define	NULL	((void*)0)

/*
*	Generic NULL object
*/

#define	NIL		255

/****************************************************************************/
/*			The rest is purely for documentation purposes					*/
/****************************************************************************/

#ifdef __DOXYGEN

/** @addtogroup coop_irq */
/** @{ */

/**
*	Disable or enable the IRQ interrupt.
*
*	The function disables or enables the IRQ interrupt and returns
*	its status prior to the effect of the function.
*
*	@param	irq	The desiredt state of the IRQ disable flag. If the parameter
*				is 0 (i.e. false), then the IRQ will be enabled. If it is
*				non-0, then IRQ interrupts will be disabled.
*
*	@return		The interrupt status before the operation. If the interrupt
*				was enabled before the call, then the returned value is 0,
*				if it was disabled, then a non-0 value.
*
*	@attention
*		The kernel's interrupt system can not handle nested interrupts.
*		Modifying the interrupt enable bit in an interrupt handler is likely
*		to cause a system crash.
*/

int		BZ_IrqDisable( int irq );

/**
*	Disable or enable the FIQ interrupt.
*
*	The function disables or enables the FIQ interrupt and returns
*	its status prior to the effect of the function.
*
*	@param	fiq	The desiredt state of the FIQ disable flag. If the parameter
*				is 0 (i.e. false), then the FIQ will be enabled. If it is
*				non-0, then FIQ interrupts will be disabled.
*
*	@return		The interrupt status before the operation. If the interrupt
*				was enabled before the call, then the returned value is 0,
*				if it was disabled, then a non-0 value.
*/

int		BZ_FiqDisable( int fiq );

/**
*	Atomic swap with a memory word
*
*	The function stores its first argument at the integer word in memory
*	pointed by its second argument and returns the content of the word
*	before the store. The reading of the memory word and the subsequent
*	writing of the argument into it is atomic, not even a DMA operation can
*	interveen between the two accesses.
*
*	@param	data	The data to be stored in the memory word
*
*	@param	addr	The address of the memory word
*
*	@return			The previous content of the memory word
*/

int		BZ_SwapWord( int data, int *addr );

/**
*	Atomic swap with a memory byte
*
*	The function stores its first argument at the byte in memory pinted
*	by its second argument and returns the content of the memory byte
*	before the store. The reading of the memory byte and the subsequent
*	writing of the argument into it is atomic, not even a DMA operation can
*	interveen between the two accesses.
*
*	@param	data	The data to be stored in the memory byte
*
*	@param	addr	The address of the memory byte
*
*	@return			The previous content of the memory byte
*/

char	BZ_SwapByte( char data, char *addr );

/** @} */

#endif

#endif


