home *** CD-ROM | disk | FTP | other *** search
- /*
- * IVCLOCK.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 Blaise IV (intervention code) routines.
- *
- * IVCLOCK requests that the scheduler give it control every 18
- * timer ticks (a little more than once per second).
- *
- * IVCLOCK retrieves the time-of-day (in clock ticks) from the
- * IV_EVENT structure passed to it by the intervention code scheduler.
- *
- * The command line format is as follows:
- *
- * ivclock [-r]
- *
- * IVCLOCK is a self-removing interrupt service routine. If IVCLOCK
- * 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 IVCLOCK (if present).
- *
- * The main thrust of IVCLOCK is to show off the new intervention
- * capabilities of Turbo C TOOLS, and to provide a working example
- * of the proper method of construction and use of intervention
- * code and the intervention functions.
- *
- * Version 6.00 (C)Copyright Blaise Computing, Inc. 1987, 1989
- *
- */
-
-
- #include <dos.h>
- #include <stdio.h>
-
- #include <binterv.h>
- #include <bintrupt.h>
- #include <bscreens.h>
- #include <bvideo.h>
-
- /* The name of the function which will be called */
- /* approximately once per second. */
- void intime (IV_EVENT *);
-
- #define STKSIZE 2000
- #define OK 0
- #define FALL_OUT 101
-
- #define NOT_FOUND 1
- #define ERROR_DISABLING 2
- #define ERROR_REMOVING 3
- #define ALREADY_INSTALLED 4
-
- /* Definitive signature for this version of IVCLOCK.*/
- #define IVCLOCK_SIGN "IVCLOK 03/31/89"
-
- /* Allocation of stack space for the intervention */
- /* scheduler and user function. */
- char schedstk [STKSIZE];
-
- /* This is the data structure to pass to the */
- /* scheduler so that it will give control every 18 */
- /* clock ticks. */
- IV_TIME timetab = {18, IV_TM_INTERVAL};
-
- /* Internal functions -- install & remove ISR. */
- int install_iv (void);
- int remove_iv (void);
-
- void main(int, char **);
-
-
- void main (argc, argv)
- int argc;
- char *argv [];
- {
- if (argc == 1)
- exit (install_iv ());
-
- if ((argc == 2) &&
- (((argv [1][0] == '-') || (argv [1][0] == '/')) &&
- ((argv [1][1] == 'r') || (argv [1][1] == 'R'))))
- exit (remove_iv ());
-
- printf ("usage: ivclock [-r]\n");
- exit (0);
- }
-
-
-
- /**
- *
- * Name INSTALL_IV -- Install interrupt vectors for IVCLOCK and
- * go TSR.
- *
- * Synopsis ret = install_iv ();
- *
- * int ret Return code from IVINSTAL if there was
- * a problem with installation of the
- * intervention code routine.
- *
- * Description This function installs IVCLOCK if another copy of
- * IVCLOCK is not already installed.
- *
- * Returns ret ALREADY_INSTALLED (4)
- * A copy of IVCLOCK is already installed.
- * FALL_OUT (101)
- * ISRESEXT() failed.
- * IV_INSTALLED (5)
- * A copy of IVCLOCK is already installed.
- *
- **/
-
- int install_iv ()
- {
- int ercode;
- IV_VECTORS vecs;
-
- /* Check to see if IVCLOCK already installed. */
- ivvecs (IV_RETVEC, &vecs);
- if (ivsense (&vecs, IVCLOCK_SIGN) != FARNIL)
- {
- puts ("IVCLOCK already installed.");
- return (ALREADY_INSTALLED);
- }
-
- /* Install the interrupt service routine--i.e. tell */
- /* the scheduler about our clock routine. */
- if (0 !=
- (ercode =
- ivinstal (intime, IVCLOCK_SIGN, schedstk, STKSIZE,
- (IV_KEY *) NIL, 0, &timetab,
- sizeof(timetab) / sizeof(IV_TIME),
- /* IVCLOCK uses TURBO C floating point support. */
- IV_FLOAT_NEED)))
- { /* Error! */
- printf ("IVINSTAL error %d.\n", ercode);
- return (ercode);
- }
-
- /* Terminate and stay resident. */
- isresext (OK);
-
- /* Should never get here. */
- return (FALL_OUT);
- }
-
-
-
- /**
- *
- * Name REMOVE_IV -- Remove a previously-installed copy of IVCLOCK.
- *
- * Synopsis ret = remove_iv ();
- *
- * int ret Return code.
- * NO_ERROR (0)-
- * No error encountered.
- * NOT_FOUND (1)-
- * IVCLOCK not found.
- * ERROR_DISABLING (2)-
- * IVCLOCK could not be disabled.
- * This error should *never* be
- * seen.
- * ERROR_REMOVING (3)--
- * IVCLOCK could not be removed
- * (most likely overwritten MALLOC
- * pointers).
- *
- * Description This function removes a currently-active copy of IVCLOCK
- * from memory, cleaning up interrupt vectors and freeing
- * memory in the process.
- *
- * Returns ret (nonzero if error--see above).
- *
- **/
-
- int remove_iv ()
- {
- IV_VECTORS vecs;
- IV_CTRL far *pivctrl;
-
- ivvecs (IV_RETVEC, &vecs);
-
- if ((pivctrl = ivsense (&vecs, IVCLOCK_SIGN)) == FARNIL)
- {
- puts ("IVCLOCK not found.");
- return (NOT_FOUND);
- }
-
- if (ivdisabl (pivctrl))
- {
- puts ("Error disabling IVCLOCK.");
- return (ERROR_DISABLING);
- }
-
- if (isremove (pivctrl->psp))
- {
- puts ("Error removing IVCLOCK.");
- return (ERROR_REMOVING);
- }
-
- return (0);
- }
-
-
-
- /**
- *
- * Name INTIME -- Display a digital clock with the current
- * time on the screen.
- *
- * Synopsis (To be called only by intervention code scheduler)
- *
- * intime (pevent);
- *
- * IV_EVENT *pevent Pointer to intervention event
- * structure. The structure
- * contains the current time of
- * day (in timer ticks since
- * midnight) as well as other
- * data.
- *
- * Description This function accepts control from the scheduler
- * approximately once per second, displays a digital
- * clock with the current time, and exits.
- *
- * Returns None.
- *
- **/
-
- void intime (pevent)
- IV_EVENT *pevent;
- {
- char time_str[10];
- int mode, act_page, columns;
- int hours, mins, secs;
- long elpsec;
-
- /* 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);
-
- /* Figure out number of seconds past midnight from */
- /* (given) number of timer ticks since midnight. */
- elpsec = (long) (0.0549254 * (double) pevent->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);
- }