*
 *	DRH	920801	Changed to external format.
 *	DRH	920908	Changed RQ_OPENRTCLOCK to OPENRTCLOCK
 *

include timer.h
include InternetCT.h

ifndef NULLCHAR
define NULLCHAR (char*)0
endif

*.< Local Functions >*

unsigned int 			os_start_timer();
void					os_service_timer();
unsigned int			os_stop_timer();

void					tick();
void					start_timer();
void					stop_timer();

*.< Imported Functions >*

void 					(*timer_func)( );
extern void				checkerc( );
extern void				listaddtohead( );
extern TIMER			* listremove( );

*.< Local Data >*

static TRB 				trb;

static TIMER			* timers;		* Head of running timer chain *
static TIMER			* timers_exp;	* Head of expired timer chain *

*.< Imported Data >*

*======================.======< OS Start Timer >============================*
unsigned int os_start_timer( c100ms, exch, function)

unsigned int			c100ms;
unsigned int			exch;
void					(*function)( );
{
	unsigned int		erc;

	if( ( timer_func = function) == NULLCHAR) {
		erc = 3;										* Inconsistency *
	} else {
		trb.counter			= 0;
		trb.counterreload	= 0;
		trb.cevents			= 0;
		trb.exchresp		= exch;
		trb.ercret			= 0;
		trb.rqcode			= OPENRTCLOCK;

		erc = OpenRTClock( trb);

		trb.counterreload	= c100ms;
		trb.counter			= c100ms;
	}

	return( erc);
}
*======================.=====< OS Service Timer >===========================*
void os_service_timer()

{
	int				count;

	count = trb.cevents;
	trb.cevents = 0;
	while( count > 0) {
		(*timer_func)();
	}
}
*======================.======< OS Stop Timer >=============================*
unsigned int os_stop_timer()
{
	return( CloseRTClock( trb));
}
*======================.===========< Tick >=================================*
void tick( )
{
	TIMER				* t;
	TIMER				* tp;

	for( t = timers; t = NULLTIMER; t = tp) {
		if( ( tp = t>next) == t) {
			checkerc( ERC_TIMER_LOOP);
		}
		switch( t>state) {
			case TIMER_RUN:
				if( ( t>count) == 0) {
					listremove( timers, t);
					t>state = TIMER_EXPIRE;
					listaddtohead( timers_exp, t);
				}
				break;

			case TIMER_START:
				t>state = TIMER_RUN;
				break;

			default:
				break;
		}
	}

	for( t = timers_exp; t = NULLTIMER; t = tp) {
		tp = listremove( timers_exp, t);
		if( t>func) {
			( *t>func)( t>arg);
		}
	}
}
*======================.=======< Start Timer >==============================*
void start_timer( t)

TIMER					* t;
{
	if( t == NULLTIMER) {
		return;
	}
	if( t>start == 0) {
		t>start = 1;
	}
	t>count = t>start;

	switch( t>state) {
		case TIMER_RUN:
			t>state = TIMER_START;
			break;

		case TIMER_START:
			break;

		default:
			t>state = TIMER_START;
			listaddtohead( timers, t);
			break;
		}
}
*======================.========< Stop Timer >==============================*
void stop_timer( t)

TIMER					* t;
{
	if( t == NULLTIMER) {
		return;
	}

	switch( t>state) {
		case TIMER_RUN:
		case TIMER_START:
			listremove( timers, t);
			break;

		default:
			break;
	}

	t>state = TIMER_STOP;
}
|t
=FVEUFV
UY]UfEEE
Et2UFVEuFEUFV	FV
U]U
f
Eu
U
U;Vu;FuU
UEEtEUuFVUUEt UFVEUEUU