home *** CD-ROM | disk | FTP | other *** search
- /*
- * ISCLOCK.C Display a constantly updated digital clock on
- * the screen.
- *
- * This program displays a clock in the upper-right corner of the
- * screen. All of the interrupt support for running the clock is
- * provided by Turbo C TOOLS interrupt support (IS) routines.
- *
- * ISCLOCK is set up to receive control every clock tick, but only
- * to do any work on every tenth clock tick. (a little less than
- * once every half second).
- *
- * ISCLOCK retrieves the time-of-day (in clock ticks) from the BIOS.
- *
- * The command line format is as follows:
- *
- * isclock [-r]
- *
- * ISCLOCK is a self-removing interrupt service routine. If ISCLOCK
- * is invoked with no arguments, it installs itself (if not already
- * installed); if it is invoked with the "-r" argument, it
- * removes a running copy of ISCLOCK (if present).
- *
- * The purpose of ISCLOCK is to exhibit the interrupt service
- * capabilities of Turbo C TOOLS, and to provide a working example
- * of the proper method of construction and use of interrupt service
- * code.
- *
- * Version 6.00 (C)Copyright Blaise Computing, Inc. 1987, 1989
- *
- */
-
-
- #include <dos.h>
- #include <stdio.h>
- #include <string.h>
-
- #include <bintrupt.h>
- #include <bscreens.h>
- #include <bvideo.h>
-
- /* The function which will be called every timer */
- /* tick. */
- void intime (ALLREG *,ISRCTRL *,ISRMSG *);
-
- #if (IS_NUM_FLOAT_VECS > 0)
- /* Storage for floating point vectors. */
- static void far *float_vec [IS_NUM_FLOAT_VECS];
- #endif
-
- #define STKSIZE 2000
-
- /* Exit values. */
- #define FALL_OUT 101
- #define OK 0
-
- #define NOT_FOUND 1
- #define ERROR_REMOVING 3
- #define ALREADY_INSTALLED 4
-
- #define TIMER_VEC 0x08
-
- /* Definitive signature for this version of ISCLOCK.*/
- char *isclock_ident = "ISCLOK 03/31/89";
-
- /* Allocation of stack space for the intervention */
- /* scheduler and user function. */
- char isstack [STKSIZE];
-
- /* Control block for ISR dispatcher. */
- ISRCTRL isrctrl;
-
- /* Internal functions -- install & remove ISR. */
- int install_is (void);
- int remove_is (void);
-
- void main(int, char **);
-
-
- void main (argc, argv)
- int argc;
- char *argv [];
- {
- if (argc == 1)
- exit (install_is ());
-
- if ((argc == 2) &&
- (((argv [1][0] == '-') || (argv [1][0] == '/')) &&
- ((argv [1][1] == 'r') || (argv [1][1] == 'R'))))
- exit (remove_is ());
-
- printf ("usage: isclock [-r]\n");
- exit (0);
- }
-
-
-
- /**
- *
- * Name INSTALL_IS -- Install interrupt vectors for ISCLOCK and
- * go TSR.
- *
- * Synopsis ret = install_is ();
- *
- * int ret Return code from ISINSTAL if there was
- * a problem with installation of the
- * interrupt service routine.
- *
- * Description This function installs ISCLOCK if another copy of
- * ISCLOCK is not already installed.
- *
- * Returns ret
- *
- **/
-
- int install_is ()
- {
- int i, ret;
- void far *timer_vec = isgetvec (TIMER_VEC);
-
- if (issense (timer_vec, isclock_ident) != FARNIL)
- {
- puts ("ISCLOCK already installed");
- return (ALREADY_INSTALLED);
- }
-
- #if (IS_NUM_FLOAT_VECS > 0)
- /* Save floating point vectors. */
- for (i = 0; i < IS_NUM_FLOAT_VECS; i++)
- float_vec[i] = isgetvec (IS_1ST_FLOAT_VEC + i);
- #endif
-
- /* Install the interrupt service routine. */
- if ((ret = isinstal (TIMER_VEC, intime, isclock_ident,
- &isrctrl, isstack, STKSIZE, 1)) != 0)
- { /* Error! */
- printf ("ISINSTAL error %d.\n", ret);
- return (ret);
- }
-
- /* Terminate and stay resident. */
- isresext (OK);
-
- /* Should never get here. */
- return (FALL_OUT);
- }
-
-
-
- /**
- *
- * Name REMOVE_IS -- Remove a previously-installed copy of ISCLOCK.
- *
- * Synopsis ret = remove_is ();
- *
- * int ret Return code.
- * NO_ERROR (0)-
- * No error encountered.
- * NOT_FOUND (1)-
- * ISCLOCK not found.
- * ERROR_REMOVING (3)--
- * ISCLOCK could not be removed
- * (most likely overwritten MALLOC
- * pointers).
- *
- * Description This function removes a currently-active copy of ISCLOCK
- * from memory, cleaning up interrupt vectors and freeing
- * memory in the process.
- *
- * Returns ret (nonzero if error--see above).
- *
- **/
-
- int remove_is ()
- {
- ISRCTRL far *pisrctrl;
- void far *timer_vec = isgetvec (TIMER_VEC);
-
- /* Check to see if ISCLOCK installed. */
- if ((pisrctrl = issense (timer_vec, isclock_ident)) == FARNIL)
- {
- puts ("ISCLOCK not found.");
- return (NOT_FOUND);
- }
-
- /* Restore the old interrupt vector. */
- isputvec (TIMER_VEC, pisrctrl->prev_vec);
-
- if (isremove (pisrctrl->isrpsp))
- {
- puts ("Error removing ISCLOCK.");
- return (ERROR_REMOVING);
- }
-
- return (0);
- }
-
-
-
- /**
- *
- * Name INTIME -- Display a digital clock with the current
- * time on the screen.
- *
- * Synopsis (To be called only by interrupt service dispatcher)
- *
- * intime (pallreg, pisrctrl, pisrmsg);
- *
- * ALLREG *pallreg Pointer to a structure which
- * contains the contents of all
- * CPU registers.
- * ISRCTRL *pisrctrl Pointer to information used by
- * ISR dispatcher. This is where
- * information on nested-ness is
- * kept.
- * ISRMSG *pisrmsg Not used.
- *
- * Description This function accepts control from the dispatcher
- * approximately 18.2 times per second, displays a
- * digital clock with the current time (every 18th
- * invocation), and exits.
- *
- * Returns None.
- *
- **/
-
- void intime (pallreg, pisrctrl, pisrmsg)
- ALLREG *pallreg;
- ISRCTRL *pisrctrl;
- ISRMSG *pisrmsg;
- {
- static int ticks = 0;
- long elpsec, time;
- int mode, act_page, columns;
- int hours, mins, secs;
- char time_str[10];
- #if (IS_NUM_FLOAT_VECS > 0)
- void far *save_float [IS_NUM_FLOAT_VECS];
- #endif
-
- /* Get rid of compiler warning message. */
- hours = *((int *) pisrmsg);
-
-
- /* Call previous owner of the timer vector first. */
- iscall (pisrctrl->prev_vec, pallreg);
-
- /* If we have enough ticks, get time from BIOS tick */
- /* counter (via UTGETCLK), and display it. */
- if (++ticks >= 18)
- {
- ticks = 0;
-
- #if (IS_NUM_FLOAT_VECS > 0)
- /* Save current floating point vectors. */
- utintflg (UT_INTOFF);
- utpeekn (uttofar (0, 4*IS_1ST_FLOAT_VEC, char), save_float,
- sizeof (save_float));
-
- /* Reinstall our own floating point vectors. */
- utpoken (float_vec, uttofar (0, 4*IS_1ST_FLOAT_VEC, char),
- sizeof (float_vec));
- utintflg (UT_INTON);
- #endif
- /* Get the current mode and active display page */
- /* from BIOS. */
- scmode (&mode, &columns, &act_page);
-
- /* Direct our display output to the current display */
- /* page. */
- scpage (act_page);
-
- /* Get current time of day from BIOS. */
-
- /* Figure out number of seconds past midnight from */
- /* (given) number of timer ticks since midnight. */
- utgetclk (&time);
-
- /* Figure out number of seconds past midnight from */
- /* (given) number of timer ticks since midnight. */
- elpsec = (long) (0.0549254 * (double) time);
-
- /* Figure out hours, minutes, seconds from seconds */
- /* past midnight. */
- hours = (int) (elpsec / 3600L);
- mins = (int) ((elpsec / 60L) % 60L);
- secs = (int) (elpsec % 60L);
-
- /* Display the time. */
- sprintf (time_str, "%02d:%02d:%02d", hours, mins, secs);
- vidspmsg (0, columns - strlen (time_str),
- NORMAL | INTENSITY, SC_BLACK, time_str);
-
- #if (IS_NUM_FLOAT_VECS > 0)
- /* Restore floating point vectors. */
- utintflg (UT_INTOFF);
- utpoken (save_float, uttofar (0, 4*IS_1ST_FLOAT_VEC, char),
- sizeof (save_float));
- utintflg (UT_INTON);
- #endif
- }
- }