home *** CD-ROM | disk | FTP | other *** search
- /* tick.c - installs a function which is called every clock tick */
- /* (c) - Amit Joshi, Princeton University
-
- This code may be used freely for any noncommercial use. It may NOT
- be used in any commercial package without written permission from
- the author. This clause is to protect me from legal hassles with
- the university about code developed here. This code is supplied
- "AS IS" i.e. with no warranty. Do not remove this notice. Any
- modifications should be clearly noted before redistribution.
- **/
-
- /** Amit Joshi
- MAE Dept., Engg. Quad.
- Princeton University
- December 1987
- **/
-
- /**
- The __tick__() and dosbusy() functions have been stolen from the
- "rdir.c" code by Dean D. McCrory. The __tick__() has been
- rewritten (and renamed from timer_handler()) to be more general.
- Amit Joshi
- January 1988
- **/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include "tick.h"
-
- /* Stuff for to handle the ctrl break functions */
- static int __nc_brks = 0;
- static char __abort = 1;
- static void (* __c_brks[NCBRKS])();
-
- /* Stuff to run timers */
- static void interrupt (* __otimer)() = NULLIVFP;
- static int __ntimers = 0;
- static void (* __timers[NTIMERS])();
- static char far * dosbusy_fl; /* dos maintains this */
-
- /* The functions used in this file */
- static int __cbrk(void);
- static void __clean_timer(void);
- static void interrupt __tick__(void);
- static char far * getdosbusy(void);
-
- static int
- __cbrk(void) {
- int nf;
-
- if (!abort) {
- for (nf = 0; nf < __nc_brks; ++nf)
- (* __c_brks[nf])();
- exit(1);
- } else return 1;
- }
-
- static void
- __clean_timer(void) {
- if (__otimer == NULLIVFP) return; /* nothing set yet */
- setvect(TIMER_INT,__otimer);
- }
-
- /* __tick__ ()
- *
- * This function intercepts the hardware timer interrupt. It checks the
- * dosbusy flag and runs through a list of timer driven functions if safe
- * to do so.
- */
-
- static void interrupt
- __tick__(void)
- {
- static int in_fl = 0;
- int timer;
-
- /* if the following statement is NOT coded, the 8259 blocks all hardware
- interrupts including the keyboard interrupt. Since we wait for a key
- in list_directory (), this causes the PC to lock up. This one took
- a while to figure out */
- outportb (0x20, 0x20); /* send eoi to 8259 */
- (*__otimer) (); /* chain to previous timer handler */
-
- if (! in_fl)
- {
- in_fl = 1; /* we are in our ISR */
- if (! *dosbusy_fl )
- /* run through the list of timers */
- for (timer = 0; timer < __ntimers; ++timer)
- if (__timers[timer] != NULLVFP)
- (* __timers[timer])();
- in_fl = 0;
- }
- return; /* return from ISR */
- }
-
- /* getdosbusy ()
- *
- * Gets the Dos busy flag through interrupt 34h. This Dos function returnes
- * the busy flag address in es:bx. This is an UNDOCUMENTED feature of Dos,
- * however it has worked in Dos versions 2.11 - 3.30 for me - Dean McCrory.
- */
- static char far *
- getdosbusy (void)
- {
- struct SREGS sregs; /* segment registers */
- union REGS regs; /* normal registers */
-
- regs.h.ah = 0x34; /* get dos busy flag address (UNDOCUMENTED) */
- intdosx (®s, ®s, &sregs);
- return (MK_FP (sregs.es, regs.x.bx));
- }
-
- int
- install_timer(void (*func)(void))
- {
- int i = 0;
- void __clean_timer();
- void interrupt __tick__();
-
- /* check if the function is already installed */
-
- if (!__ntimers) {
- __otimer = getvect(TIMER_INT);
- /* Get address of DOS busy flag. */
- dosbusy_fl = getdosbusy();
- if (atexit(__clean_timer)) return 2;
- install_cbrk(NULLVFP);
- setvect(TIMER_INT,__tick__);
- }
- /* are we already installed ? */
- for (i=0; i < __ntimers; i++)
- if (__timers[i] == func) return 0;
- /* enough space for another function ? */
- if (__ntimers >= NTIMERS) return 1;
- __timers[__ntimers++] = func;
- return 0;
- }
-
- int
- remove_timer(void (*func)(void))
- {
- int i = 0;
-
- if (func == NULLVFP) {
- __clean_timer();
- __ntimers = 0;
- return 0;
- }
-
- if (!__ntimers) return 1; /* No timers return func not there */
-
- do {
- /* have we found the function ? */
- if (__timers[i] == func) {
- /* is it the last one in the chain ? */
- if (i++ == __ntimers) {
- __timers[i-1] = NULLVFP;
- } else {
- /* move the chain backwards */
- do {
- __timers[i-1] = __timers[i]; i++;
- } while(i <= __ntimers);
- }
- __ntimers--;
- return 0;
- } else i++;
- } while (i < __ntimers);
- return 1;
- }
-
- int
- install_cbrk (void (* func)(void))
- {
- int i = 0;
-
-
-
- if (!__nc_brks) {
- setcbrk(1); /* ensure that ctrl break is enabled */
- ctrlbrk(__cbrk);
- __abort = 1;
- }
-
- if (func == NULLVFP) __abort = 1;
-
- for (i = 0; i < __nc_brks; i++)
- if (__c_brks[i] == func) return 0;
- /* enough space for another function ? */
- if (__nc_brks >= NCBRKS) return 1;
- __c_brks[__nc_brks++] = func;
- return 0;
- }
-
- int
- remove_cbrk (void (* func)(void))
- {
- int i = 0;
-
- if (func == NULLVFP) __abort = 0;
-
- if (!__nc_brks) return 1; /* No timers return func not there */
-
- do {
- /* have we found the function ? */
- if (__c_brks[i] == func) {
- /* is it the last one in the chain ? */
- if (i++ == __nc_brks) {
- __c_brks[i-1] = NULLVFP;
- } else {
- /* move the chain backwards */
- do {
- __c_brks[i-1] = __c_brks[i]; i++;
- } while(i <= __nc_brks);
- }
- __nc_brks--;
- return 0;
- } else i++;
- } while (i < __nc_brks);
- return 1;
-