#include <kernel.h>

#if ! TRACE_BUFF

void	BX_TraceFirst( char *buff, int size )
{
	*buff = 0;
	(void) size;
}

int		BX_TraceNext( char *buff, int size )
{
	*buff = 0;
	(void) size;
	return( 0 );
}

#else


char		*_bx_trace_ptr;
char		*_bx_trace_nxt;
char		_bx_trace_buf[ TRACE_BUFF ];

#include <stdio.h>

void	BX_TraceFirst( char *buff, int size )
{
	if ( ( _bx_trace_nxt = _bx_trace_ptr + 1 ) >= _bx_trace_buf + TRACE_BUFF )

		_bx_trace_nxt = _bx_trace_buf;

	BX_TraceNext( buff, size );
}

int		BX_TraceNext( char *buff, int size )
{
char	*p;
int		c;

	p = _bx_trace_nxt;

	for ( ;; ) {

		c = *p++;
		p = p >= _bx_trace_buf + TRACE_BUFF ? _bx_trace_buf : p;

		if ( size > 1 ) {

			*buff++ = c;
			size--;
		}

		if ( ! c ) break;
	}

	if ( size ) *buff++ = 0;
	return( ( _bx_trace_nxt = p ) != _bx_trace_ptr );
}

static	int		trace( void **p, const char *s, size_t l )
{
char	*d, *b, *e;

	b = _bx_trace_buf;
	e = _bx_trace_buf + TRACE_BUFF;
	d = *p;

	while ( l-- ) {

		*d++ = *s++;
		if ( d == e ) d = b;
	}

	*d = 0;
	*p = d;
	return( 1 );
}

void	_bx_Trace( const char *fmt, ... )
{
va_list	arg;
int		irq;

	irq = _bx_IrqDis();
	va_start( arg, fmt );
	print_int( fmt, arg, -1, trace, (void **) &_bx_trace_ptr, NULL );

	if ( ++_bx_trace_ptr >= _bx_trace_buf + TRACE_BUFF )

		_bx_trace_ptr = _bx_trace_buf;

	_bx_IrqRes( irq );
}

void	_bx_TraceInit( void )
{
char	*p;

	_bx_trace_ptr = _bx_trace_buf;
	for ( p = _bx_trace_buf ; p < _bx_trace_buf + TRACE_BUFF ; *p++ = 0 );
}

#endif

