Reading PC's 8253/4 counter 0? - was 160 baud ALDL data....

Peter Gargano peter at ntserver.techedge.com.au
Fri Jun 18 01:03:26 GMT 1999


Thanks Ludis, counter 0 does clock at twice 0.838 uSec, and it is set to=20
"square wave" mode. See below for more info..

Ludis Langens wrote:

> > Does anyone know what frequency the AT clocks counter 0 at?

> It sounds like counter 0 is being run in "square wave" mode.  In this
> mode, the 8253 counts by twos and toggles the output each time the
> counter expires.  If your system uses the 8254, you could use the statu=
s
> readback to verify this.  (Note - I know next to nothing about Wintel s=
ystems...)

In fact the mode byte I read back is 0x36 which indicates Mode 3, which
is, you guessed it, "square wave mode". You can try it yourself (8254 is =
at 0x40
to 0x43 on IBM PC clones)...

=A6  outportb (0x43, 0xE2);  // command the 8254 to read counter 0's stat=
us byte
=A6  count =3D inportb(0x40);  // read the status byte!
=A6
=A6  printf("Mode byte for Counter 0 is %02xH\n", count);

So, the documentation I have, ie. Annabooks "The XT-AT HANDBOOK", says "i=
f
reading registers ... each count from counter 0 is =3D 1/1.19318 Mhz, or=20
.8380966 uSecs." is WRONG!

It's wrong because .. in mode 3 (and I just looked at my BIOS listing fro=
m IBM's
original AT documentation, and that's what IBM set the mode to for counte=
r 0),
the counter actually counts in twos on each clock cycle (at 1.19 Mhz) and=
 at
each counter rollover the counter's hardware output toggles. The counter =
output
must be connected to the 8259 (interrupt controller) and interrupts on an
edge that would be generated at every two counter rollovers or 18.2 times=
 per
second!

So, the average person could be led to believe, unless they checked, that=
 counter 0
counts at 0.83 uSec when in fact it counts at twice this rate but interru=
pts just
once every 65536 x 2 counts.=20

Want to check that counter 0 really counts at half 0.83 uSec? Try this...
It's a batch file xx.bat that calls program x.exe that counts 2000 counte=
r 0
underruns (or rollovers, or is that rollunders?). It will run in a DOS bo=
x
or in native DOS mode. You'll need a C compiler to make it though!

----
xx.bat follows: xx.bat is used to "trigger" x.c and produce two timestamp=
s
file "cr" simply contains a carriage return character. Generate it by "co=
py con cr"
and hitting "Enter" then "CTRL+Z".

time <cr
x.exe
time <cr

----
x.c follows:

=A6#include <dos.h>
=A6#include <stdio.h>
=A6
=A6void main(void)
=A6{
=A6
=A6  unsigned int last, next, count;
=A6
=A6  int i;
=A6
=A6  last =3D 0;
=A6  i =3D 0;
=A6
=A6  outportb (0x43, 0xE2); // read counter 0 status
=A6  count =3D inportb(0x40);
=A6  printf("Mode byte for Counter 0 is %02xH\n", count);
=A6
=A6  while (i < 2000) {
=A6    outportb (0x43, 0);
=A6    count =3D inportb(0x40);
=A6    next =3D (inportb(0x40) << 8) + count;
=A6    if (last < next) {
=A6      i++;
=A6      //printf(".");
=A6    }
=A6    last =3D next;
=A6  }
=A6  printf("End\n");
=A6
=A6}

Output from this is...

D:\>xx

D:\>time <cr
Current time is 10:40:53.77a
Enter new time:

D:\>x.exe
Mode byte for Counter 0 is 36H
End

D:\>time <cr
Current time is 10:41:48.81a
Enter new time:

D:\>

Time difference is (so, are these METRIC fractions of a second?) =3D 55.0=
4
for 2000 rollovers giving an apparent frequency of ~=3D 131/55 =3D 2.38 M=
hz
which is twice the actual frequency of 1.18 Mhz.

This is, within the accuracy of measurement, exactly twice what the doco=20
says, but is explained because counter 0 is in mode 3. And, just for a ch=
eck,
you could try and read back the counter 0 count. You'll find it's always
an even quantity!

Thanks again Ludis, for the mode 3 explanation.
--=20
Peter Gargano



More information about the Gmecm mailing list