Listing 2: Timer implementation
#include<bios.h> // the time function.
#include"timer.h"
int TIMER::executive_tic(void)
{
long current_time = biostime(_TIME_GETCLOCK, current_time);
if (last_bios_time != current_time) { //18.2 Hz, 54 ms
last_bios_time = current_time;
++time_count %= count_mod;
return 1;
}
return 0;
}
TIMER_HANDLE TIMER::open_timer(float seconds)
{
// Find a free handle.
for (int i=search_next_handle_start;
timer_used[i] && i<max_timers; i++);
search_next_handle_start = 0;
if(i==max_timers) return -1; //error, all timers are used.
timer_used[i] = true;
timer_expired[i] = false;
if (seconds < 0.05) timer_expired[i] = true;
expire_time[i] = (time_count + int(18.2 * seconds)) % count_mod;
return i;
}
boolean TIMER::expired(const TIMER_HANDLE &handle)
{
if (handle < 0 || handle >= max_timers) return true;
if (timer_expired[handle]) return true;
// There is a 2 second window (36 tics) for expired to be
// called and have it know it is expired. Otherwise it thinks
// that the time interval wraps-around our circular counter.
// Everybody should be executing faster than a 1 hz rate, so a
// 2 second window should be sufficient.
if ((time_count - expire_time[handle] + count_mod) %
count_mod > 36)
return false;
// If execution reaches here, then time has expired.
timer_expired[handle] = true;
return true;
}
// Return time left in seconds.
float TIMER::time_left(const TIMER_HANDLE &handle)
{
if (handle < 0 || handle >= max_timers) return 0.0;
if (timer_expired[handle]) return 0.0;
int diff_time = expire_time[handle] - time_count;
if (diff_time < -36) return float(diff_time + count_mod)/18.2;
if (diff_time > 0) return float(diff_time)/18.2;
return 0.0;
}
void TIMER::close_timer(TIMER_HANDLE &handle)
{
if (handle >= 0 && handle < max_timers) {
timer_used[handle] = false;
search_next_handle_start = handle;
}
handle = -1;
}
TIMER::TIMER(void): count_mod(4096)
// count_mod is an arbitrary number right now. turn over
// about 4 min.
{
for (int i=0; i<max_timers; i++) {
timer_used[i] = false;
timer_expired[i] = false;
expire_time[i] = 0;
}
last_bios_time = biostime(_TIME_GETCLOCK,
last_bios_time);
time_count = 0;
search_next_handle_start = 0;
}
//End of File