/*	
	Timer interrupt example 0.11 for GCC
	made by Ismo Horppu on 1996 - 1997
*/

#include <pc.h>
#include <dpmi.h>
#include <go32.h>
#include <stdio.h>

#include "types.h"
#include "tspeed.h"
#include "rtimer.h"

/*	
	here is the timer interrupt
	(chained to old handler)
	1000Hz tick rate :)
	
*/
void timer_handler (...)
{
	if (delay_start == 1){
		delay_ticks++;

		if (delay_ticks >= delay_limit){
			delay_ticks = 0;
		}
	}
	
	if (timer_start == 1){
		timer_ticks++;
	}
}

// installs our own timer interrupt
void Set_Timer (WORD tps)
{
	if (tps < 18) tps = 18;	// minimum speed :)
	
	// set timer new handler & speed
	_go32_dpmi_get_protected_mode_interrupt_vector (TIMER_INTR, &timer_old_handler);
	timer_new_handler.pm_offset = (DWORD) timer_handler;
	timer_new_handler.pm_selector = _go32_my_cs ();

	// chain our handler 
	asm ("cli");
	_go32_dpmi_chain_protected_mode_interrupt_vector (TIMER_INTR, &timer_new_handler);
	set_timer_TPS (tps);
	_go32_dpmi_lock_code (timer_handler, (DWORD) (Set_Timer - timer_handler));
	_go32_dpmi_lock_data (&timer_ticks, 4);
	_go32_dpmi_lock_data (&timer_start, 4);
	asm ("sti");
}

// restores old timer interrupt 
int Restore_Timer (void)
{
	asm ("cli");
	_go32_dpmi_set_protected_mode_interrupt_vector (TIMER_INTR, &timer_old_handler);

	// restore timer old handler & speed	
	set_timer_speed (0xFFFF);
	asm ("sti");
	return 0;
}

/*	
	wait specified count of timer ticks (not ms, unless TPS = 1000)
*/
void xdelay (WORD ms)
{
	BYTE old_start;
	DWORD old_ticks;
	
	// save old state
	old_start = timer_start;
	old_ticks = timer_ticks;
		
	if (ms < 0) return;
	timer_ticks = 0;
	timer_start = 1;
	while (timer_ticks < ms);
	
	// restore old state
	timer_start = old_start;
	timer_ticks = old_ticks;
}