    /*  EX 2.5 Torch with timeout  */
    /*  Rob Miles January 2000     */

    unsigned char key ( void )
    {
       unsigned char count = 0 ;
       unsigned char oldv, newv ;
       oldv = input_pin_port_b ( 0 ) ;
       while ( count < 20 )
       {
          newv = input_pin_port_b (0) ;
          if ( oldv == newv )
          {
             count++ ;
          }
          else
          {
             count = 0 ;
             oldv = newv ;
          }
       }
       return oldv ;
    }

    #define C1LIMIT 500
    #define C2LIMIT 100

    int c1, c2 ;

    void start_clock (void)
    {
       c1 = 0 ;
       c2 = 0 ;
    }

    void do_time (void)
    {
       /*  if light off do nothing */
       if (input_pin_port_a(0) == 0)
    	{
          return ;
       }

       /* increase first counter  */
       c1++ ;

       if ( c1 > C1LIMIT )
       {
          /*  clear first counter    */
          c1 = 0 ;

          /*  need to update the     */
          /* second counter          */
          c2++ ;

          /*  .. and check its value */
          if ( c2 > C2LIMIT )
          {
             /* turn light off here  */
                   output_low_port_a(0) ;
          }
       }
    }

    void main ( void )
    {
       /* Select the Register bank 1 */
       set_bit(STATUS,RP0);

       /* set all of PORTB for input */
         TRISB=0xff;

       /* set PORTA bit 0 as output */
         TRISA=0x1e;

       /* now use Register bank 0    */
         clear_bit(STATUS,RP0);

       /* repeat forever */
         while (1)
       {
          /* wait for the button to  */
          /* go down                 */
          while (key () == 0)
          {
             do_time () ;
          }

          /* if the light is on turn */
          /* it off                  */
          if (input_pin_port_a(0))
          {
             output_low_port_a(0);
          }
          else
          {
          /* if the light is off    */
          /* turn it on             */
             output_high_port_a(0);
             /* start the timer     */
             start_clock () ;
          }

          /* wait for the button    */
          /* to go up again         */
               while (key() == 1)
          {
             do_time () ;
          }
       }
    }