#include #include #include #include #include #include _go32_dpmi_seginfo info; _go32_dpmi_seginfo original; volatile long long OldTimerHandler; volatile int TicksPerCall, OriginalTicks, Counter; static volatile void TimerStart() {} void TimerHandler() { Counter++; OriginalTicks+=TicksPerCall; if(OriginalTicks>=65536) { OriginalTicks-=65536; __asm__ __volatile__ (" pushfl lcall %0 " : : "g" (OldTimerHandler)); } else { outportb(0x20, 0x20); } } static volatile void TimerEnd() {} void SetTimerRate(unsigned short ticks) { outportb(0x43, 0x34); outportb(0x40, ( ticks & 0x00FF ) ); outportb(0x40, ( ( ticks >> 8 ) & 0x00FF ) ); } void InitTimer(int tickspersecond) { __dpmi_meminfo lock; lock.address = __djgpp_base_address + (unsigned) &TimerStart; lock.size = ((unsigned)&TimerEnd - (unsigned)&TimerStart); __dpmi_lock_linear_region(&lock); Counter=0; OriginalTicks=0; TicksPerCall=1193181/((unsigned short)tickspersecond); disable(); _go32_dpmi_get_protected_mode_interrupt_vector(0x0008, &original); OldTimerHandler=((unsigned long long)original.pm_offset) + (((unsigned long long)original.pm_selector)<<32); info.pm_offset=(unsigned long int)TimerHandler; info.pm_selector=_my_cs(); _go32_dpmi_allocate_iret_wrapper(&info); SetTimerRate(TicksPerCall); _go32_dpmi_set_protected_mode_interrupt_vector(0x0008, &info); enable(); } void DeinitTimer() { disable(); SetTimerRate(0); _go32_dpmi_set_protected_mode_interrupt_vector(0x0008, &original); enable(); }