/*  001  15-Apr-87  tone.c

        Copyright (c) 1987 by Blue Sky Software.  All rights reserved.

        NOTE:  This routine is very hardware and software dependent.
*/

#include <dos.h>

#define CLOCK_RATE (1193180L)          /* timer clock rate */
#define TIMER_CTL  (67)                /* timer control port */
#define TIMER_CNT  (66)                /* timer count port */
#define READY_CMD  (182)               /* command to ready timer */
#define PPI        (97)                /* Programmable Peripheral Interface */
#define SPEAK_BITS (3)                 /* speaker control bits */
#define FULL_DAY   (1573040L)          /* a full day in clock ticks */
#define BIOS_TICKS (0x46CL)            /* ptr to bios clock ticks in low mem */


/*****************************************************************************
                                T O N E
 ****************************************************************************/

tone(fq,ticks) /* generate a tone for selected # clock ticks */
unsigned fq, ticks;
{
   unsigned count;
   unsigned long endtime, now, new;

   count = CLOCK_RATE / fq;            /* calculate timer count for freq */

   outp(TIMER_CTL,READY_CMD);          /* send timer count */
   outp(TIMER_CNT,count % 256);
   outp(TIMER_CNT,count / 256);

   outp(PPI,inp(PPI) | SPEAK_BITS);    /* turn on the speaker */

   /* determine what time it is in clock ticks and when to end */

   endtime = (now = *((long far *) BIOS_TICKS)) + ticks;

   /* kill time until the duration is up */

   while (now < endtime) {
      new = *((long far *) BIOS_TICKS);
      if (new < now)                           /* just in case its midnight */
         now = new + FULL_DAY;
      else
         now = new;
   }

   outp(PPI,inp(PPI) & ~SPEAK_BITS);   /* turn off the speaker */
}