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

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


Damned Nutscrape screwed my posting (it doesn't like characters with
the high bit set, but it's still better than M$ Exploder). 

Here it is again (sorry for the repetition)...

Thanks Ludis, counter 0 does clock at twice 0.838 uSec, and it is set to 
"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 status
> readback to verify this.  (Note - I know next to nothing about Wintel systems...)

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)...

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

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

It's wrong because .. in mode 3 (and I just looked at my BIOS listing from IBM's
original AT documentation, and that's what IBM set the mode to for counter 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 interrupts just
once every 65536 x 2 counts. 

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 counter 0
underruns (or rollovers, or is that rollunders?). It will run in a DOS box
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 timestamps
file "cr" simply contains a carriage return character. Generate it by "copy con cr"
and hitting "Enter" then "CTRL+Z".

time <cr
x.exe
time <cr

----
x.c follows:

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

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?) = 55.04
for 2000 rollovers giving an apparent frequency of ~= 131/55 = 2.38 Mhz
which is twice the actual frequency of 1.18 Mhz.

This is, within the accuracy of measurement, exactly twice what the doco 
says, but is explained because counter 0 is in mode 3. And, just for a check,
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.
-- 
Peter Gargano



More information about the Gmecm mailing list