⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc_timer.c

📁 mesa-6.5-minigui源码
💻 C
字号:
/* * PC/HW routine collection v1.5 for DOS/DJGPP * *  Copyright (C) 2002 - Daniel Borca *  Email : dborca@yahoo.com *  Web   : http://www.geocities.com/dborca */#include <pc.h>#include <string.h>#include "pc_hw.h"#define TIMER_IRQ 0#define MAX_TIMERS 8#define PIT_FREQ 0x1234DD#define ADJUST(timer, basefreq) timer.counter = PIT_FREQ * timer.freq / SQR(basefreq)#define unvolatile(__v, __t) __extension__ ({union { volatile __t __cp; __t __p; } __q; __q.__cp = __v; __q.__p;})static int timer_installed;typedef struct {   volatile unsigned int counter, clock_ticks, freq;   volatile PFUNC func;   volatile void *parm;} TIMER;static TIMER timer_main, timer_func[MAX_TIMERS];/* Desc: main timer callback * * In  : - * Out : 0 to bypass BIOS, 1 to chain to BIOS * * Note: - */static inttimer (){   int i;   for (i = 0; i < MAX_TIMERS; i++) {      TIMER *t = &timer_func[i];      if (t->func) {         t->clock_ticks += t->counter;         if (t->clock_ticks >= timer_main.counter) {            t->clock_ticks -= timer_main.counter;            t->func(unvolatile(t->parm, void *));         }      }   }   timer_main.clock_ticks += timer_main.counter;   if (timer_main.clock_ticks >= 0x10000) {      timer_main.clock_ticks -= 0x10000;      return 1;   } else {      outportb(0x20, 0x20);      return 0;   }} ENDOFUNC(timer)/* Desc: uninstall timer engine * * In  : - * Out : - * * Note: - */voidpc_remove_timer (void){   if (timer_installed) {      timer_installed = FALSE;      pc_clexit(pc_remove_timer);      DISABLE();      outportb(0x43, 0x34);      outportb(0x40, 0);      outportb(0x40, 0);      ENABLE();      pc_remove_irq(TIMER_IRQ);   }}/* Desc: remove timerfunc * * In  : timerfunc id * Out : 0 if success * * Note: tries to relax the main timer whenever possible */intpc_remove_int (int fid){   int i;   unsigned int freq = 0;   /* are we installed? */   if (!timer_installed) {      return -1;   }   /* sanity check */   if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {      return -1;   }   timer_func[fid].func = NULL;   /* scan for maximum frequency */   for (i = 0; i < MAX_TIMERS; i++) {      TIMER *t = &timer_func[i];      if (t->func) {         if (freq < t->freq) {            freq = t->freq;         }      }   }   /* if there are no callbacks left, cleanup */   if (!freq) {      pc_remove_timer();      return 0;   }   /* if we just lowered the maximum frequency, try to relax the timer engine */   if (freq < timer_main.freq) {      unsigned int new_counter = PIT_FREQ / freq;      DISABLE();      for (i = 0; i < MAX_TIMERS; i++) {         if (timer_func[i].func) {            ADJUST(timer_func[i], freq);         }      }      outportb(0x43, 0x34);      outportb(0x40, (unsigned char)new_counter);      outportb(0x40, (unsigned char)(new_counter>>8));      timer_main.clock_ticks = 0;      timer_main.counter = new_counter;      timer_main.freq = freq;      ENABLE();   }    return 0;} ENDOFUNC(pc_remove_int)/* Desc: adjust timerfunc * * In  : timerfunc id, new frequency (Hz) * Out : 0 if success * * Note: might change the main timer frequency */intpc_adjust_int (int fid, unsigned int freq){   int i;   /* are we installed? */   if (!timer_installed) {      return -1;   }   /* sanity check */   if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {      return -1;   }   timer_func[fid].freq = freq;   /* scan for maximum frequency */   freq = 0;   for (i = 0; i < MAX_TIMERS; i++) {      TIMER *t = &timer_func[i];      if (t->func) {         if (freq < t->freq) {            freq = t->freq;         }      }   }   /* update main timer / sons to match highest frequency */   DISABLE();   /* using '>' is correct still (and avoids updating    * the HW timer too often), but doesn't relax the timer!    */   if (freq != timer_main.freq) {      unsigned int new_counter = PIT_FREQ / freq;      for (i = 0; i < MAX_TIMERS; i++) {         if (timer_func[i].func) {            ADJUST(timer_func[i], freq);         }      }      outportb(0x43, 0x34);      outportb(0x40, (unsigned char)new_counter);      outportb(0x40, (unsigned char)(new_counter>>8));      timer_main.clock_ticks = 0;      timer_main.counter = new_counter;      timer_main.freq = freq;   } else {      ADJUST(timer_func[fid], timer_main.freq);   }   ENABLE();   return 0;} ENDOFUNC(pc_adjust_int)/* Desc: install timer engine * * In  : - * Out : 0 for success * * Note: initial frequency is 18.2 Hz */static intinstall_timer (void){   if (timer_installed || pc_install_irq(TIMER_IRQ, timer)) {      return -1;   } else {      memset(timer_func, 0, sizeof(timer_func));      LOCKDATA(timer_func);      LOCKDATA(timer_main);      LOCKFUNC(timer);      LOCKFUNC(pc_adjust_int);      LOCKFUNC(pc_remove_int);      timer_main.counter = 0x10000;      DISABLE();      outportb(0x43, 0x34);      outportb(0x40, 0);      outportb(0x40, 0);      timer_main.clock_ticks = 0;      ENABLE();      pc_atexit(pc_remove_timer);      timer_installed = TRUE;      return 0;   }}/* Desc: install timerfunc * * In  : callback function, opaque pointer to be passed to callee, freq (Hz) * Out : timerfunc id (0 .. MAX_TIMERS-1) * * Note: returns -1 if error */intpc_install_int (PFUNC func, void *parm, unsigned int freq){   int i;   TIMER *t = NULL;   /* ensure the timer engine is set up */   if (!timer_installed) {      if (install_timer()) {         return -1;      }   }   /* find an empty slot */   for (i = 0; i < MAX_TIMERS; i++) {       if (!timer_func[i].func) {          t = &timer_func[i];          break;       }   }   if (t == NULL) {      return -1;   }   DISABLE();   t->func = func;   t->parm = parm;   t->freq = freq;   t->clock_ticks = 0;   /* update main timer / sons to match highest frequency */   if (freq > timer_main.freq) {      unsigned int new_counter = PIT_FREQ / freq;      for (i = 0; i < MAX_TIMERS; i++) {         if (timer_func[i].func) {            ADJUST(timer_func[i], freq);         }      }      outportb(0x43, 0x34);      outportb(0x40, (unsigned char)new_counter);      outportb(0x40, (unsigned char)(new_counter>>8));      timer_main.clock_ticks = 0;      timer_main.counter = new_counter;      timer_main.freq = freq;   } else {      /* t == &timer_func[i] */      ADJUST(timer_func[i], timer_main.freq);   }   i = t - timer_func;   ENABLE();   return i;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -