/***********************************************************************    

      PRTDEMO.C


      BL11xx/Little Giant, Tiny Giant, SmartBlock(with Interface Board),
      BL13xx/Protocol Switch(with Interface Board)
   
   PRT1 demo program 

   This program sets up the Z180 PRT1 for periodic interrupts 200 times 
   per second. It counts to 5000 and then exits. This takes 25 seconds.
   While the program is running, add "counter" to the watch window (Ctrl+W)
   , then press update the watch window repeatedly (Ctrl+U). The current
   value of "counter" is displayed in the watch window. You can also
   experiment with the command inport() in the watch window.

   This program shows the use of the PRT interrupt and the use of the
   runwatch() function. The runwatch() function executes watch
   statements while the target program is executing so that it
   is possible to "snoop" while a program runs.

   This program shows the use of the "shared" keyword. Whenever
   a shared variable is accessed the access is performed in an atomic
   fashion by turning off the interrupts(if on) during the multi-
   byte read or store of the variable. This avoids the possiblity
   of an interrupt routine changing a variable between reading
   the first bytes and the last bytes, which results in reading a 
   corrupted value.

   This program shows the method for writing interrupt routines
   using the C language.  It also shows how to set an interrupt vector
   with #INT_VEC. 

   The use of conditional defines is shown by flashing the lights
   of the different Dynamic C compatible boards.  Remove the comment
   operators from the define line for your board.

**********************************************************************/

#define USETG 1          /* flash light on Tiny Giant */

//#define USESB 1        /* flash light on Smart Block Interface */

int prt1_init(int tc);        /* initialize prt1 */

#define TDE1      1            /* PRT ch 1 down count enable bit */
#define TIE1      5            /* PRT ch 1 interrupt enable bit */ 

shared long int counter;   /* shared between different interrupt levels */

main()
{
   counter = 0x0L;            /* initialize counter to zero */

   prt1_init(2304);          /*(9216000 / 20) / 200 = 5 ms interrupts */

#ifdef USETG                  /* set up PIO on Tiny Giant to flash light */
   outport(PIOCA,0xcf);
   outport(PIOCA,0xfd);
#endif
   
   while(1)  
   {
   	hitwd();
      runwatch();            /* enables watches to run while target runs */
      if( counter >= 5000) 
         break;

/* use defines to flash lights on different boards */

#ifdef USETG
     (counter & 64) ? outport(PIODA,2) : outport(PIODA,0);  /* Tiny Giant */
#else
#ifdef USESB
     (counter & 64) ? outport(PIODB,0) : outport(PIODB,0xff); /* SmartBlck */
#else
      outport(ENB485, !(counter & 64) );   /* BL11xx/Little Giant */
#endif
#endif
   }
   
   IRES(TCR, TDE1);          /* disable count down */
   IRES(TCR, TIE1);          /* disable interrupts */

#ifndef USESB
   outport(ENB485, 0);       /* if not Smart Block make sure light is on */
#endif

   puts( "Counter has reached 5000.\n" );

}

#INT_VEC PRT1_VEC ccc     /* set interrupt vector for interrupt routine */

/* this interrupt routine increments the variable "counter" */

interrupt reti int ccc()
{
   inport(TCR); 
   inport(TMDR1L);            /* clear TIF */
   EI();
   counter = counter + 1;  
}

int prt1_init(int tc)
{
   IRES(TCR, TDE1);              /* disable count down */
   IRES(TCR, TIE1);              /* disable interrupts */
   outport(TMDR1L, tc); 
   outport(TMDR1H, tc >> 8);     /* set data reg */
   outport(RLDR1H, tc >> 8);     /* set reload counter to value */
   outport(RLDR1L, tc);          /* set reload counter to value*/
   ISET(TCR, TDE1);              /* enable count down */
   ISET(TCR, TIE1);              /* enable interrupts */
   EI();
}

/*************************************************End of PRTDEMO.C ****/
