home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 2.ddi / TOOLS.2 / EXAMPLES / IVCLOCK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  6.6 KB  |  264 lines

  1. /*
  2. *    IVCLOCK.C    Display a constantly updated digital clock on
  3. *            the screen.
  4. *
  5. *  This program displays a clock in the upper-right corner of the
  6. *  screen.  All of the interrupt support for running the clock is
  7. *  provided by Blaise IV (intervention code) routines.
  8. *
  9. *  IVCLOCK requests that the scheduler give it control every 18
  10. *  timer ticks (a little more than once per second).
  11. *
  12. *  IVCLOCK retrieves the time-of-day (in clock ticks) from the
  13. *  IV_EVENT structure passed to it by the intervention code scheduler.
  14. *
  15. *  The command line format is as follows:
  16. *
  17. *    ivclock [-r]
  18. *
  19. *  IVCLOCK is a self-removing interrupt service routine.  If IVCLOCK
  20. *  is invoked with no arguments, it installs itself (if not already
  21. *  installed); if it is invoked with the "-r" argument, it
  22. *  removes a running copy of IVCLOCK (if present).
  23. *
  24. *  The main thrust of IVCLOCK is to show off the new intervention
  25. *  capabilities of Turbo C TOOLS, and to provide a working example
  26. *  of the proper method of construction and use of intervention
  27. *  code and the intervention functions.
  28. *
  29. *  Version    6.00 (C)Copyright Blaise Computing, Inc. 1987, 1989
  30. *
  31. */
  32.  
  33.  
  34. #include <dos.h>
  35. #include <stdio.h>
  36.  
  37. #include <binterv.h>
  38. #include <bintrupt.h>
  39. #include <bscreens.h>
  40. #include <bvideo.h>
  41.  
  42.         /* The name of the function which will be called    */
  43.         /* approximately once per second.            */
  44. void intime (IV_EVENT *);
  45.  
  46. #define STKSIZE  2000
  47. #define OK     0
  48. #define FALL_OUT 101
  49.  
  50. #define NOT_FOUND      1
  51. #define ERROR_DISABLING   2
  52. #define ERROR_REMOVING      3
  53. #define ALREADY_INSTALLED 4
  54.  
  55.         /* Definitive signature for this version of IVCLOCK.*/
  56. #define IVCLOCK_SIGN "IVCLOK 03/31/89"
  57.  
  58.         /* Allocation of stack space for the intervention   */
  59.         /* scheduler and user function.             */
  60. char schedstk [STKSIZE];
  61.  
  62.         /* This is the data structure to pass to the        */
  63.         /* scheduler so that it will give control every 18  */
  64.         /* clock ticks.                     */
  65. IV_TIME timetab = {18, IV_TM_INTERVAL};
  66.  
  67.         /* Internal functions -- install & remove ISR.        */
  68. int install_iv (void);
  69. int remove_iv  (void);
  70.  
  71. void main(int, char **);
  72.  
  73.  
  74. void main (argc, argv)
  75. int   argc;
  76. char *argv [];
  77. {
  78.     if (argc == 1)
  79.     exit (install_iv ());
  80.  
  81.     if ((argc == 2)                       &&
  82.     (((argv [1][0] == '-') || (argv [1][0] == '/')) &&
  83.      ((argv [1][1] == 'r') || (argv [1][1] == 'R'))))
  84.     exit (remove_iv ());
  85.  
  86.     printf ("usage: ivclock [-r]\n");
  87.     exit (0);
  88. }
  89.  
  90.  
  91.  
  92. /**
  93. *
  94. * Name        INSTALL_IV -- Install interrupt vectors for IVCLOCK and
  95. *                  go TSR.
  96. *
  97. * Synopsis    ret = install_iv ();
  98. *
  99. *        int ret     Return code from IVINSTAL if there was
  100. *                a problem with installation of the
  101. *                intervention code routine.
  102. *
  103. * Description    This function installs IVCLOCK if another copy of
  104. *        IVCLOCK is not already installed.
  105. *
  106. * Returns    ret    ALREADY_INSTALLED (4)
  107. *                A copy of IVCLOCK is already installed.
  108. *            FALL_OUT (101)
  109. *                ISRESEXT() failed.
  110. *            IV_INSTALLED (5)
  111. *                A copy of IVCLOCK is already installed.
  112. *
  113. **/
  114.  
  115. int install_iv ()
  116. {
  117.     int      ercode;
  118.     IV_VECTORS     vecs;
  119.  
  120.         /* Check to see if IVCLOCK already installed.        */
  121.     ivvecs (IV_RETVEC, &vecs);
  122.     if (ivsense (&vecs, IVCLOCK_SIGN) != FARNIL)
  123.     {
  124.     puts ("IVCLOCK already installed.");
  125.     return (ALREADY_INSTALLED);
  126.     }
  127.  
  128.         /* Install the interrupt service routine--i.e. tell */
  129.         /* the scheduler about our clock routine.        */
  130.     if (0 !=
  131.     (ercode =
  132.      ivinstal (intime, IVCLOCK_SIGN, schedstk, STKSIZE,
  133.            (IV_KEY *) NIL, 0, &timetab,
  134.            sizeof(timetab) / sizeof(IV_TIME),
  135.         /* IVCLOCK uses TURBO C floating point support.     */
  136.            IV_FLOAT_NEED)))
  137.     {        /* Error!                        */
  138.     printf ("IVINSTAL error %d.\n", ercode);
  139.     return (ercode);
  140.     }
  141.  
  142.         /* Terminate and stay resident.             */
  143.     isresext (OK);
  144.  
  145.         /* Should never get here.                */
  146.     return (FALL_OUT);
  147. }
  148.  
  149.  
  150.  
  151. /**
  152. *
  153. * Name        REMOVE_IV -- Remove a previously-installed copy of IVCLOCK.
  154. *
  155. * Synopsis    ret = remove_iv ();
  156. *
  157. *        int ret     Return code.
  158. *                  NO_ERROR  (0)-
  159. *                      No error encountered.
  160. *                  NOT_FOUND (1)-
  161. *                      IVCLOCK not found.
  162. *                  ERROR_DISABLING (2)-
  163. *                      IVCLOCK could not be disabled.
  164. *                      This error should *never* be
  165. *                      seen.
  166. *                  ERROR_REMOVING (3)--
  167. *                      IVCLOCK could not be removed
  168. *                      (most likely overwritten MALLOC
  169. *                      pointers).
  170. *
  171. * Description    This function removes a currently-active copy of IVCLOCK
  172. *        from memory, cleaning up interrupt vectors and freeing
  173. *        memory in the process.
  174. *
  175. * Returns    ret (nonzero if error--see above).
  176. *
  177. **/
  178.  
  179. int remove_iv ()
  180. {
  181.     IV_VECTORS     vecs;
  182.     IV_CTRL far *pivctrl;
  183.  
  184.     ivvecs (IV_RETVEC, &vecs);
  185.  
  186.     if ((pivctrl = ivsense (&vecs, IVCLOCK_SIGN)) == FARNIL)
  187.     {
  188.     puts ("IVCLOCK not found.");
  189.     return (NOT_FOUND);
  190.     }
  191.  
  192.     if (ivdisabl (pivctrl))
  193.     {
  194.     puts ("Error disabling IVCLOCK.");
  195.     return (ERROR_DISABLING);
  196.     }
  197.  
  198.     if (isremove (pivctrl->psp))
  199.     {
  200.     puts ("Error removing IVCLOCK.");
  201.     return (ERROR_REMOVING);
  202.     }
  203.  
  204.     return (0);
  205. }
  206.  
  207.  
  208.  
  209. /**
  210. *
  211. * Name        INTIME -- Display a digital clock with the current
  212. *              time on the screen.
  213. *
  214. * Synopsis    (To be called only by intervention code scheduler)
  215. *
  216. *        intime (pevent);
  217. *
  218. *        IV_EVENT *pevent    Pointer to intervention event
  219. *                    structure.  The structure
  220. *                    contains the current time of
  221. *                    day (in timer ticks since
  222. *                    midnight) as well as other
  223. *                    data.
  224. *
  225. * Description    This function accepts control from the scheduler
  226. *        approximately once per second, displays a digital
  227. *        clock with the current time, and exits.
  228. *
  229. * Returns    None.
  230. *
  231. **/
  232.  
  233. void intime (pevent)
  234. IV_EVENT *pevent;
  235. {
  236.     char time_str[10];
  237.     int  mode, act_page, columns;
  238.     int  hours, mins, secs;
  239.     long elpsec;
  240.  
  241.         /* Get the current mode and active display page     */
  242.         /* from BIOS.                        */
  243.     scmode (&mode,&columns,&act_page);
  244.  
  245.         /* Direct our display output to the current display */
  246.         /* page.                        */
  247.     scpage (act_page);
  248.  
  249.         /* Figure out number of seconds past midnight from  */
  250.         /* (given) number of timer ticks since midnight.    */
  251.     elpsec = (long) (0.0549254 * (double) pevent->time);
  252.  
  253.         /* Figure out hours, minutes, seconds from seconds  */
  254.         /* past midnight.                    */
  255.     hours  = (int)  (elpsec / 3600L);
  256.     mins   = (int) ((elpsec / 60L) % 60L);
  257.     secs   = (int)  (elpsec % 60L);
  258.  
  259.         /* Display the time.                    */
  260.     sprintf (time_str, "%02d:%02d:%02d", hours, mins, secs);
  261.     vidspmsg (0, columns - strlen (time_str),
  262.           NORMAL | INTENSITY, SC_BLACK, time_str);
  263. }
  264.