delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/05/12/05:14:44

Date: Thu, 12 May 94 09:45 MET DST
From: rene_j AT tudebg DOT et DOT tudelft DOT nl (Rene Jager)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Q: Re: Q: timer interrupt

MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7BIT
X-Mailer: Mumail [version 2.3b i486-Linux]


Thanx for replies from DJ and Gordon. I'll give some more info on the
problem. We have a simulation tool which was originally coded using
Borland. The need for more memory, while still being able to use the
same graphics brought us to DJGPP. The combination DJGPP with GRX and 
BCC2GRX provided a simple upgrade to 32-bit, so no memory limits. 

At the momemt we're building in timer functions so we can not only
simulate but also do "real-time" control with the same package. To do
so, we set the 8253 timer to a resolution of 1ms, hook in our function
to perform calculations as interrupt and every 55ms the original timer
function is executed. Hence, the _go32_dpmi_..._chain_... can't do the
job since it causes the original timer to be called every time the
user timer returns. Below I included an example using Borland...

Rene'


* Rene' Jager * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Delft Univ. of Technology, Dept. of Electrical Engineering, Control Lab.  *
* snail-mail: Mekelweg 4, P.O. Box 5031, 2600 GA  Delft, The Netherlands    *
* e-mail: r DOT jager AT et DOT tudelft DOT nl | voice: +31.15.785114 | fax: +31.15.626738 *
* World Wide Web: http://dutera.et.tudelft.nl/people/rene_j/jager.html      *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
Example timer in Borland:
---------------->8---------------------->8---------------
#include <dos.h>

#define TMR_INT 0x08

static char timeron;
static unsigned int timercount;

void (*userfunction)(void);
void interrupt (*oldtimer)(void); /* old interrupt handler */

static unsigned int timercount;
static unsigned int period;
static char old55count;

void interrupt timer(void)
{
  --timercount;
  --old55count;

  if(!timercount) /* execute user timer every 'period' ms */
  {
    timercount = period;
    (*userfunction)();
  }

  if(!old55count) /* execute original timer */
  {
    old55count = 55;
    oldtimer();
  }

  outp(0x20, 0x20);
}

void installtimer(void (*userf)(void), unsigned int per)
{
  if(!timeron)
  {
    timeron = 1;
    period = timercount = per;
    old55count = 55;
    userfunction = userf;
    outp(0x21, inp(0x21) | 0x01);  /* interrupt disable */
    oldtimer = getvect(TMR_INT);   /* get current timer */
    setvect(TMR_INT, timer);       /* hook up new timer */
    outp(0x43, 0x34);              /* set timer to 1 ms */
    outp(0x40, 167);               /* ((65536L/55) & 0xFF) == 167 */
    outp(0x40, 4);                 /* ((65536L/55) >> 8) & 0xFF) == 4 */
    outp(0x21, inp(0x21) & ~0x01); /* interrupt enable */
  }
}

void removetimer(void)
{
  if(timeron)
  {
    outp(0x21, inp(0x21) | 0x01);  /* interrupt disable */
    setvect(TMR_INT, oldtimer);    /* put back old timer */
    outp(0x43, 0x34);              /* set timer to 55 ms */
    outp(0x40, 0);
    outp(0x40, 0);
    outp(0x21, inp(0x21) & ~0x01); /* interrupt enable */
    timeron = 0;
  }
}

/* for testing... */

int tics = 0;

void tic_it(void)
{
  tics++;
}

int main(void)
{
  int prvtics = 0;

  installtimer(tic_it, 30); /* execute tic_it every 30ms */ 
  
  while(!kbhit())
    if(prvtics != tics)
    {
      printf("tics = %d\n", tics);
      prvtics = tics;
    }
  
  removetimer();

  return 0;
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019