What do you guys think? Below is the source code for the real_ms routine
along with a little program to test it. If it would help anyone, I
could upload the executable to a FTP site.
-----------------------CUT HERE----------------CUT HERE-------------------
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <dos.h>
#include <stdlib.h> /* needed only for rand function */
main()
/*This program is intended to test the real_ms() function,
and nothing more. It is not intended to be usefull. */
{
int a,b,c=0,d=0,e=0,f=0;
while (d<25000)
{
realtime_ms();
/*printf("\nHello!!"); */
b=rand() % 30;
delay(b);
a=realtime_ms();
printf("\nThat took %i millisconds\n",a);
if (a<=b-3)
{
c=c+1;
e=a; /*realtime returned value */
f=b; /*rand value */
}
printf("total errors = %i, total tries %i, rand value = %i\n",c,d,b);
printf("error was %i for realtime value, and %i for rand value\n",e,f);
printf("\n%f\n",CLK_TCK);
d=d+1;
}
}
realtime_ms(void)
/* function deffinition to return the number of milliseconds
since the last time it was called
It has some bugs, and returns a wrong value about 2% of the time.
Written by Steve Kenshalo, sken...@csufresno.edu
*/
{
int unsigned b,lsb,msb,word,c,a;
static int ticker,clocker; /* static preserves value between function calls */
_disable(); /* prevent interrupts between timer calls */
outp(0x43,06); /* 00000110 latch currrent timer value */
lsb=inp(0x40); /* read lsb */
msb=inp(0x40); /* read MSB */
c=clock(); /* NOTE: this function may enable interrupts */
_enable();
a=c-clocker;
if (word>ticker) /* detect wraparound */
--a; /* one of the ticks in a is unneeded */
clocker=c; /*save for next call */
word=(msb*256)+lsb; /* combine msb and lsb into word */
/*word=word*.000838395; /* convert word (ticks) into milliseconds */
b=(0.000838395*(ticker - word))+(a*0.05494505495);
ticker = word; /* save word for next call */
return b;
}
> --a; /* one of the ticks in a is unneeded */
> clocker=c; /*save for next call */
>
> word=(msb*256)+lsb; /* combine msb and lsb into word */
> /*word=word*.000838395; /* convert word (ticks) into milliseconds */
> b=(0.000838395*(ticker - word))+(a*0.05494505495);
>
> ticker = word; /* save word for next call */
> return b;
> }
--
You reference variable "word" before any assignment - a sure route
to tears!
Secondly, I haven't looked at the algorithm in detail, but I'm very
suspicious of that floating point stuff - I would expect it to
produce rounding errors at best. Better do it all in (long?) integer
arithmetic (and faster!).
Finally, it wouldn't surprise me if the clock() function (or
the time-of-day service called by clock()) had differential
errors due to rounding - I don't think it's really intended for this
level of precision. Also, clock() is typed as clock_t in MSC - isn't
that actually a long? (You assign it to an unsigned int, i.e., short
in MSC - I can't speak for Turbo. I might expect this to result in
wrap-around every 65536/18.2 seconds, i.e., about once per hour).
Hope that gives some food for thought.
Dick.
-----------------------------------------------------
As an economy measure, the light at the end of the
tunnel will be switched off while the recession lasts.
-----------------------------------------------------
If I remember correctly, the timer resets to zero every time it gets
to the count required to trigger the interrupt. On that basis you
would need to forget the previous value and just offset the
regular time value.
/*------------------------+---------------------------------------
| Carle C. Henson | Opinions expressed are my own and may
| Hughes Network Systems | not be shared by anyone else on the
| hen...@lando.hns.com | planet, even if I am right. The
| Voice (301) 428-5917 | possible exception being Rush Limbaugh
| Fax (301) 428-1868 | who is always right.
+-------------------------+-------------------------------------*/