added glutGetProcAddress() and GLUT_FPS env var option
[mesa.git] / src / glut / dos / PC_HW / pc_timer.c
1 /*
2 * PC/HW routine collection v1.0 for DOS/DJGPP
3 *
4 * Copyright (C) 2002 - Borca Daniel
5 * Email : dborca@yahoo.com
6 * Web : http://www.geocities.com/dborca
7 */
8
9
10 #include <pc.h>
11
12 #include "pc_hw.h"
13
14 #define TIMER_IRQ 0
15
16 #define MAX_TIMERS 8
17
18 #define PIT_FREQ 0x1234DD
19
20 #define unvolatile(__v, __t) __extension__ ({union { volatile __t __cp; __t __p; } __q; __q.__cp = __v; __q.__p;})
21
22 static int timer_installed;
23
24 typedef struct {
25 volatile unsigned int counter, clock_ticks, freq;
26 volatile PFUNC func;
27 volatile void *parm;
28 } TIMER;
29
30 TIMER timer_main, timer_func[MAX_TIMERS];
31
32 static int timer ()
33 {
34 int i;
35
36 for (i=0;i<MAX_TIMERS;i++) {
37 TIMER *t = &timer_func[i];
38 if (t->func) {
39 t->clock_ticks += t->counter;
40 if (t->clock_ticks>=timer_main.counter) {
41 t->clock_ticks -= timer_main.counter;
42 t->func(unvolatile(t->parm, void *));
43 }
44 }
45 }
46
47 timer_main.clock_ticks += timer_main.counter;
48 if (timer_main.clock_ticks>=0x10000) {
49 timer_main.clock_ticks -= 0x10000;
50 return 1;
51 } else {
52 outportb(0x20, 0x20);
53 return 0;
54 }
55 } ENDOFUNC(timer)
56
57 void pc_remove_timer (void)
58 {
59 if (timer_installed) {
60 timer_installed = FALSE;
61 pc_clexit(pc_remove_timer);
62
63 DISABLE();
64 outportb(0x43, 0x34);
65 outportb(0x40, 0);
66 outportb(0x40, 0);
67 ENABLE();
68
69 pc_remove_irq(TIMER_IRQ);
70 }
71 }
72
73 static int install_timer (void)
74 {
75 if (timer_installed||pc_install_irq(TIMER_IRQ, timer)) {
76 return -1;
77 } else {
78 LOCKDATA(timer_func);
79 LOCKDATA(timer_main);
80 LOCKFUNC(timer);
81
82 timer_main.counter = 0x10000;
83
84 DISABLE();
85 outportb(0x43, 0x34);
86 outportb(0x40, 0);
87 outportb(0x40, 0);
88 timer_main.clock_ticks = 0;
89 ENABLE();
90
91 pc_atexit(pc_remove_timer);
92 timer_installed = TRUE;
93 return 0;
94 }
95 }
96
97 static TIMER *find_slot (PFUNC func)
98 {
99 int i;
100
101 for (i=0;i<MAX_TIMERS;i++) {
102 if (timer_func[i].func==func) {
103 return &timer_func[i];
104 }
105 }
106 for (i=0;i<MAX_TIMERS;i++) {
107 if (!timer_func[i].func) {
108 return &timer_func[i];
109 }
110 }
111
112 return NULL;
113 }
114
115 int pc_install_int (PFUNC func, void *parm, unsigned int freq)
116 {
117 int i;
118 TIMER *t;
119
120 if (!timer_installed) {
121 if (install_timer()) {
122 return -1;
123 }
124 }
125
126 if ((t=find_slot(func))!=NULL) {
127 unsigned int new_counter = PIT_FREQ / freq;
128
129 DISABLE();
130
131 t->func = func;
132 t->parm = parm;
133 t->freq = freq;
134 t->clock_ticks = 0;
135
136 if (new_counter < timer_main.counter) {
137 for (i=0;i<MAX_TIMERS;i++) {
138 if (timer_func[i].func) {
139 timer_func[i].counter = new_counter * timer_func[i].freq / freq;
140 }
141 }
142 outportb(0x43, 0x34);
143 outportb(0x40, (unsigned char)new_counter);
144 outportb(0x40, (unsigned char)(new_counter>>8));
145 timer_main.clock_ticks = 0;
146 timer_main.counter = new_counter;
147 timer_main.freq = freq;
148 } else {
149 t->counter = PIT_FREQ * freq / (timer_main.freq * timer_main.freq);
150 }
151
152 ENABLE();
153
154 return 0;
155 }
156
157 return -1;
158 }