diff options
author | Daniel Borca <dborca@users.sourceforge.net> | 2003-11-18 12:18:13 +0000 |
---|---|---|
committer | Daniel Borca <dborca@users.sourceforge.net> | 2003-11-18 12:18:13 +0000 |
commit | ef563d011b5a11dc5f7a0da6445e68f14cc33062 (patch) | |
tree | b61e2f338d71c77f3a9a565f146efc9070c5317e /src/glut | |
parent | aa0d6dcd652ca3f6ece2e9314020283589d79a2a (diff) |
doc updates; GLUT timer additions; fixed compilation warnings
Diffstat (limited to 'src/glut')
-rw-r--r-- | src/glut/dos/PC_HW/pc_hw.h | 6 | ||||
-rw-r--r-- | src/glut/dos/PC_HW/pc_timer.c | 247 |
2 files changed, 211 insertions, 42 deletions
diff --git a/src/glut/dos/PC_HW/pc_hw.h b/src/glut/dos/PC_HW/pc_hw.h index 26bb8ba17df..bd2293eb29d 100644 --- a/src/glut/dos/PC_HW/pc_hw.h +++ b/src/glut/dos/PC_HW/pc_hw.h @@ -1,5 +1,5 @@ /* - * PC/HW routine collection v1.3 for DOS/DJGPP + * PC/HW routine collection v1.4 for DOS/DJGPP * * Copyright (C) 2002 - Borca Daniel * Email : dborca@yahoo.com @@ -19,6 +19,8 @@ #define FALSE 0 #define TRUE !FALSE +#define SQR(x) ((x) * (x)) + #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #define MID(x,y,z) MAX((x), MIN((y), (z))) @@ -201,6 +203,8 @@ int pc_keyshifts (void); * timer */ int pc_install_int (PFUNC func, void *parm, unsigned int freq); +int pc_remove_int (int fid); +int pc_adjust_int (int fid, unsigned int freq); void pc_remove_timer (void); /* diff --git a/src/glut/dos/PC_HW/pc_timer.c b/src/glut/dos/PC_HW/pc_timer.c index bf39bd0a4c0..f11917db1aa 100644 --- a/src/glut/dos/PC_HW/pc_timer.c +++ b/src/glut/dos/PC_HW/pc_timer.c @@ -1,5 +1,5 @@ /* - * PC/HW routine collection v1.3 for DOS/DJGPP + * PC/HW routine collection v1.4 for DOS/DJGPP * * Copyright (C) 2002 - Borca Daniel * Email : dborca@yahoo.com @@ -8,6 +8,7 @@ #include <pc.h> +#include <string.h> #include "pc_hw.h" @@ -17,6 +18,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; @@ -29,15 +32,24 @@ typedef struct { 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 int timer () { int i; - for (i=0;i<MAX_TIMERS;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) { + if (t->clock_ticks >= timer_main.counter) { t->clock_ticks -= timer_main.counter; t->func(unvolatile(t->parm, void *)); } @@ -45,7 +57,7 @@ static int timer () } timer_main.clock_ticks += timer_main.counter; - if (timer_main.clock_ticks>=0x10000) { + if (timer_main.clock_ticks >= 0x10000) { timer_main.clock_ticks -= 0x10000; return 1; } else { @@ -54,6 +66,15 @@ static int timer () } } ENDOFUNC(timer) + + +/* Desc: uninstall timer engine + * + * In : - + * Out : - + * + * Note: - + */ void pc_remove_timer (void) { if (timer_installed) { @@ -70,11 +91,22 @@ void pc_remove_timer (void) } } + + +/* Desc: install timer engine + * + * In : - + * Out : 0 for success + * + * Note: initial frequency is 18.2 Hz + */ static int install_timer (void) { - if (timer_installed||pc_install_irq(TIMER_IRQ, timer)) { + 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); @@ -94,65 +126,198 @@ static int install_timer (void) } } -static TIMER *find_slot (PFUNC func) + + +/* 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 + */ +int pc_install_int (PFUNC func, void *parm, unsigned int freq) { int i; + TIMER *t = NULL; - for (i=0;i<MAX_TIMERS;i++) { - if (timer_func[i].func==func) { - return &timer_func[i]; - } + /* ensure the timer engine is set up */ + if (!timer_installed) { + if (install_timer()) { + return -1; + } } - for (i=0;i<MAX_TIMERS;i++) { + + /* find an empty slot */ + for (i = 0; i < MAX_TIMERS; i++) { if (!timer_func[i].func) { - return &timer_func[i]; + 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); + } + } - return NULL; + 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); + } + + ENABLE(); + + return t - timer_func; } -int pc_install_int (PFUNC func, void *parm, unsigned int freq) + + +/* Desc: remove timerfunc + * + * In : timerfunc id + * Out : 0 if success + * + * Note: tries to relax the main timer whenever possible + */ +int pc_remove_int (int fid) { int i; - TIMER *t; + unsigned int freq = 0; + /* are we installed? */ if (!timer_installed) { - if (install_timer()) { - return -1; - } + return -1; } - if ((t=find_slot(func))!=NULL) { + /* 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(); - t->func = func; - t->parm = parm; - t->freq = freq; - t->clock_ticks = 0; - - if (new_counter < timer_main.counter) { - for (i=0;i<MAX_TIMERS;i++) { - if (timer_func[i].func) { - timer_func[i].counter = new_counter * timer_func[i].freq / 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->counter = PIT_FREQ * freq / (timer_main.freq * timer_main.freq); + for (i = 0; i < MAX_TIMERS; i++) { + if (timer_func[i].func) { + ADJUST(timer_func[i], freq); + } } - ENABLE(); + 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; - return 0; + ENABLE(); } - return -1; + return 0; +} + + + +/* Desc: adjust timerfunc + * + * In : timerfunc id, new frequency (Hz) + * Out : 0 if success + * + * Note: might change the main timer frequency + */ +int pc_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; } |