home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / masm / masm6 / tsr / bell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-29  |  6.8 KB  |  196 lines

  1. /* BELL.C - Beeps speaker at preset time. Illustrates how to create
  2.  * a TSR in a high-level language using the TSR library of assembly
  3.  * routines. Also shows how to write a time-activated TSR by passing
  4.  * hour and minute arguments to the Install procedure.
  5.  *
  6.  * To install BELL, include argument hhmm = hour:minute for activation.
  7.  * Argument must be in military format (1855 for 6:55 p.m., for example)
  8.  * and must consist of 4 digits. To activate BELL at 8:30 a.m., enter
  9.  *     BELL 0830
  10.  *
  11.  * Some differences exist between BELL.C and the ALARM.ASM program
  12.  * presented in Section 17.3 of the Programmer's Guide. The C version
  13.  * requires more memory and does not allow multiple installations since
  14.  * it calls the multiplex handler to check for prior residency. BELL
  15.  * is deinstallable at any time, however, by entering
  16.  *     BELL /D
  17.  * at the command line. To reset the number of times BELL beeps the
  18.  * speaker, enter
  19.  *     BELL /Cx
  20.  * where x = desired number of beeps.
  21.  */
  22.  
  23.  
  24. void far  Beeper( void );       /* Main TSR code */
  25. void near ErrorExit( int );     /* Exit routine  */
  26.  
  27. #include <dos.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include "tsr.h"
  31. #include "demo.h"
  32.  
  33. int BeepCount = 1;              /* Global variable  = number of beeps      */
  34.  
  35. void main( int argc, char *argv[] )
  36. {
  37.     char c;                             /* Character                       */
  38.     int Err, Hour, Minute, Time;        /* Error code, activation hour:min */
  39.     int far *BeepCountPtr;              /* Pointer to shared memory        */
  40.  
  41.     /* Initialize data before calling other TSR library routines.
  42.      * Pass far address of identifier string unique to this TSR.
  43.      * Pass far address of global variable BeepCount as address
  44.      * of shared memory. This allows a subsequent execution of
  45.      * the program to locate the resident BeepCount and reset it
  46.      * to a new value. See comments below describing /C switch.
  47.      */
  48.     Err = InitTsr( _psp, (char far *)"BELL DEMO TSR", &BeepCount );
  49.  
  50.     /* Argument required */
  51.     if( argc == 1 )
  52.     {
  53.         puts( "Requires argument for time = hhmm,\n"
  54.               "deinstallation = /D, or\n"
  55.               "new beep count = /Cx" );
  56.         exit( 1 );
  57.     }
  58.  
  59.     /* Check for /D or /C arguments. Do this block if argument
  60.      * begins with '/' or '-' prefix. Otherwise, assume argument
  61.      * specifies alarm setting hhmm and skip to next section.
  62.      */
  63.     c = *argv[1];
  64.     if( c == '/' || c == '-' )
  65.     {
  66.         c = (char)toupper( *(++argv[1]) );
  67.  
  68.         /* If /D argument, deinstall resident TSR and exit */
  69.         if( c == 'D' )
  70.         {
  71.             Err = Deinstall();
  72.             if( Err <= BAD_ARGUMENT )
  73.                 ErrorExit( Err );
  74.             ErrorExit( FreeTsr( Err ) );
  75.         }
  76.  
  77.         /* If /Cx ("change") argument, call multiplex handler to
  78.          * locate resident BeepCount, rewrite BeepCount with new
  79.          * value specified by integer x, and exit.
  80.          */
  81.         if( c != 'C' )
  82.             ErrorExit( BAD_ARGUMENT );
  83.         if( CallMultiplexC( 2, &BeepCountPtr ) != IS_INSTALLED )
  84.             ErrorExit( CANT_ACCESS );
  85.         *BeepCountPtr = atoi( ++argv[1] );
  86.         ErrorExit( OK_ACCESS );
  87.     }
  88.  
  89.     /* Do this section if argument is not preceded by '/' or '-'
  90.      * prefix. Assume argument specifies TSR activation time in
  91.      * military format hhmm, where hh = hour and mm = minute.
  92.      * Install TSR to activate at this time.
  93.      */
  94.     Time   = atoi( argv[1] );
  95.     Hour   = Time / 100;
  96.     Minute = Time - (Hour * 100);
  97.  
  98.     /* Call Install procedure with first argument = 0. This
  99.      * signals procedure that TSR is to be time-activated at
  100.      * hour:minute given by 2nd and third arguments. The 4th
  101.      * argument gives the far address of the main body of the
  102.      * TSR that executes at the specified time -- in this case
  103.      * the function Beeper.
  104.      */
  105.     Err = Install( 0, Hour, Minute, Beeper );
  106.     if( Err )
  107.         ErrorExit( Err );
  108.     _dos_keep( 0, (unsigned)GetResidentSize( _psp ) );
  109. }
  110.  
  111.  
  112. /* ErrorExit - Displays appropriate exit message and exits program. */
  113. void ErrorExit( int Err )
  114. {
  115.     extern char *MSGTBL[];
  116.  
  117.     puts( MSGTBL[ Err ] );
  118.     exit( Err );
  119. }
  120.     
  121.  
  122. /* ILLEGAL C FUNCTIONS
  123.  * -------------------
  124.  * Use of certain C library functions in a resident program is either
  125.  * illegal or ill-advised. These functions include:
  126.  *
  127.  *     exec/spawn functions such as execv(), spawnv(), and system()
  128.  *     environment functions such as getenv(), _searchenv(), and putenv()
  129.  *
  130.  *
  131.  * USING THE HEAP IN A RESIDENT PROGRAM
  132.  * ------------------------------------
  133.  * Functions that use heap space require additional caution. The assembly
  134.  * procedure GetResidentSize returns the amount of memory in paragraphs
  135.  * required by the _TEXT and _DATA segments. It allows a C program to
  136.  * discard segments unused during residency -- segments such as INSTALLCODE,
  137.  * INSTALLDATA, and _STACK. It also truncates the memory occupied by the
  138.  * program's heap.
  139.  *
  140.  * Therefore, if your program uses GetResidentSize to determine its memory
  141.  * requirements, the resident portion of the program must not call functions
  142.  * that make use of the heap. These include:
  143.  *
  144.  *     allocate functions such as malloc()
  145.  *     strdup functions
  146.  *     directory functions such as getcwd() and _getdcwd()
  147.  *     miscellaneous functions such as _fullpath() and tempnam()
  148.  *
  149.  * Note that stream I/O functions such as fputs() also allocate heap space
  150.  * unless a static buffer is provided through the function setvbuf().
  151.  *
  152.  * If you wish to make the heap resident, request a stack size large enough
  153.  * to accommodate the installation code and no more. The _STACK segment
  154.  * below the heap is wasted memory during the program's resident phase.
  155.  *
  156.  *
  157.  * FLOATING-POINT CALCULATIONS
  158.  * ---------------------------
  159.  * For floating-point math operations, specify the alternate math package.
  160.  * This prevents your program from setting up interrupt handlers at startup.
  161.  *
  162.  *
  163.  * STACK-CHECKING
  164.  * --------------
  165.  * Turn off stack-checking for resident function(s) as follows:
  166.  */
  167.  
  168. #pragma check_stack ( off )
  169.  
  170. /* This is necessary because the Activate procedure in HANDLERS.ASM
  171.  * switches stacks. To adjust the size of the TSR's stack, reset the
  172.  * constant STACK_SIZ in the file TSR.INC and rebuild the program by
  173.  * assembling the HANDLERS.ASM module and relinking.
  174.  */
  175.  
  176.  
  177. /* Beeper - Writes ASCII character 07 (bell character) to the
  178.  * screen to beep the speaker. Iterates BeepCount times.
  179.  *
  180.  * Params:  None
  181.  *
  182.  * Return:  None
  183.  */
  184. void far Beeper( void )
  185. {
  186.     int i;
  187.     for( i = 0; i < BeepCount; ++i )
  188.     {
  189.         _asm
  190.         {
  191.             mov ax, 0E07h               ; Request function 0Eh
  192.             int 10h                     ; Write char 7 (bell) to screen
  193.         }
  194.     }
  195. }
  196.