BOBOLI THE MIGHTY KNIGHT Networked Medieval Conflict
Submitted By:
Unknown
Rating:





(
Rate It)
/* TIMER functions.
Really a skeleton. The timer procedure does nothing but set a flag that
one tick of the selected rate has passed, and keep track of how many such
ticks have occurred. If you need to do more than that in your timer
function, then copy this file, and modify what the timer function does.
*/
#include <dpmi.h>
#include "timer.h"
#include "mgraph.h"
volatile byte timepassed,timetick;
volatile unsigned short clock_ticks;
volatile unsigned long counter;
static _go32_dpmi_seginfo old_rm_timer_vector,
new_rm_timer_vector,
old_pm_timer_vector,
new_pm_timer_vector;
static _go32_dpmi_registers _timer_r;
void pm_timer_handler(void);
void rm_timer_handler(void);
void timer_init(byte Hz)
{
counter=_PIT_freq/Hz;
clock_ticks=0;
timetick=0;
timepassed=0;
new_pm_timer_vector.pm_selector=_go32_my_cs();
new_pm_timer_vector.pm_offset=(int) pm_timer_handler;
new_rm_timer_vector.pm_selector=_go32_my_cs();
new_rm_timer_vector.pm_offset=(int) rm_timer_handler;
disable();
_go32_dpmi_get_protected_mode_interrupt_vector(_Timer_intr,
&old_pm_timer_vector);
_go32_dpmi_chain_protected_mode_interrupt_vector(_Timer_intr,
&new_pm_timer_vector);
_go32_dpmi_allocate_real_mode_callback_iret(&new_rm_timer_vector, &_timer_r);
_go32_dpmi_get_real_mode_interrupt_vector(_Timer_intr,
&old_rm_timer_vector);
outportb(0x43,0x34);
outportb(0x40,counter%256);
outportb(0x40,counter/256);
enable();
}
void timer_exit(void)
{
unsigned long tick;
char *cmostime;
disable();
outportb(0x43,0x36);
outportb(0x40,0);
outportb(0x40,0);
_go32_dpmi_set_real_mode_interrupt_vector(_Timer_intr,
&old_rm_timer_vector);
_go32_dpmi_set_protected_mode_interrupt_vector(_Timer_intr,
&old_pm_timer_vector);
_go32_dpmi_free_real_mode_callback(&new_rm_timer_vector);
enable();
/* irqs are restored, now fix the clock, if it's off */
cmostime = get_cmostime();
tick=18.2067597*((((float) *cmostime)*3600)+(((float)*(cmostime + 1))*60)+
(((float) *(cmostime + 2))));
biostime(1, tick);
}
void qdelay(unsigned short time)
{
unsigned short t;
for(t=1;t<=time;t++) inportb(0x388);
}
void rm_timer_handler(void)
{
disable();
timetick++;
timepassed=1;
clock_ticks+=counter;
if(clock_ticks>=0x10000) {
clock_ticks-=0x10000;
memset(&_timer_r, 0, sizeof(_timer_r));
_timer_r.x.cs = old_rm_timer_vector.rm_segment;
_timer_r.x.ip = old_rm_timer_vector.rm_offset;
_timer_r.x.ss = _timer_r.x.sp = 0;
enable();
_go32_dpmi_simulate_fcall_iret(&_timer_r);
}
else outportb(0x20,0x20);
}
void pm_timer_handler(void)
{
disable();
timetick++;
timepassed=1;
clock_ticks+=counter;
if(clock_ticks>=0x10000) {
clock_ticks-=0x10000;
memset(&_timer_r, 0, sizeof(_timer_r));
_timer_r.x.cs = old_pm_timer_vector.rm_segment;
_timer_r.x.ip = old_pm_timer_vector.rm_offset;
_timer_r.x.ss = _timer_r.x.sp = 0;
enable();
_go32_dpmi_simulate_fcall_iret(&_timer_r);
}
else outportb(0x20,0x20);
}
char *get_cmostime(void)
{
char *buff;
static char buffer[6];
char ch;
buff = buffer;
memset(&_timer_r, 0, sizeof(_timer_r));
_timer_r.h.ah = 0x02;
_go32_dpmi_simulate_int(0x1a, &_timer_r);
ch = _timer_r.h.ch;
buffer[0] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
ch = _timer_r.h.cl;
buffer[1] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
ch = _timer_r.h.dh;
buffer[2] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
buffer[3] = _timer_r.h.dl;
buffer[4] = (char) (_timer_r.x.flags & 0x0001);
buffer[5] = 0x00;
return (buff);
}