Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!utgpu!water!watmath!clyde!cbosgd!ucbvax!jade!violet.berkeley.edu!izumi
From: izumi@violet.berkeley.edu.UUCP
Newsgroups: comp.sys.ibm.pc
Subject: Re: millisecond timing
Message-ID: <4343@jade.BERKELEY.EDU>
Date: Mon, 13-Jul-87 22:29:32 EDT
Article-I.D.: jade.4343
Posted: Mon Jul 13 22:29:32 1987
Date-Received: Thu, 16-Jul-87 03:03:38 EDT
Sender: usenet@jade.BERKELEY.EDU
Reply-To: izumi@violet.berkeley.edu ()
Organization: University of California, Berkeley
Lines: 75

[eat]
Someone recently asked about ways to do timings with 1 millisecond
accuracy on an XT or compatibles.  Here's what I think is possible.

If you haven't bought a computer yet, and AT or compatibles is an option,
you can probably do the timing at near 1 msec accuracy without adding
any hardware.  Otherwise, on XT, you will have to do something quite a bit
more involved.

First, on AT, there is already a piece of hardware that can do the timing
with the accuracy and resolution of about 1 msec (1/1024 sec).  Because
this hardware can generate interrupts at the preprogrammed rate of 1024Hz,
and this rate is not dependent on the CPU clock frequency, the same program
will give you the same results on all versions of the AT and compatibles.
Interrupt at 1024Hz can be generated on ATs by non-volatile (w/ battery b.u.)
Real-time clock/ CMOS RAM chip.
The information on this is covered on the AT reference around page 1-46,
system board section.  (I/O address of that chip is 70 and 71 hex).

To activate interrupt from this chip (RTC), you have to first enable
"Periodic Interrupt Enable" bit of Status Register B of the clock chip.
Done by,

	out 70h,0bh		;address Status Reg B
	in  al,71h		;read register
	or  al,40h		;bit-6 is the PIE
	out 70h,0bh
	out 71h,al		;write back

etc.

This will activate Hardware interrupt INT 70h (IRQ8) to the
second PIC (interrupt controller chip) in the AT.
As with regular interrupt you have to un-mask the bit-0 (IRQ8) of the
IMR in the second PIC 8259 whose I/O address begins at 0a0h.

There is an interrupt service routine to handle this interrupt (RTC_INT)
in the  BIOS listing. see pages BIOS2 5-161 on.  You will see there
what has to be done during interrut servicing.  Note that you have to
issue EOI (end of interrupt) to both PICs (8259s).
Since this ISR routine is short, doesn't do anything particularly important
, you can entirely take over the interrupt vector INT 70h (By the way, BIOS's
INT 50 is a typo,  I suppose).
    ^^
You can replace this interrupt service routine with your own to do the
timing at near 1 msec accuracy.

Unfortunately, I have not programmed this chip to do the interrupt at 1.024
kHz, so there may be some more details that have to be worked out.  But, I am
pretty sure it can be done.   Indeed, I remember seeing an article on the
use of this interrupt in PC Tech Journal about a year (?) ago. (I forgot
which issue).

Now, if you MUST use XT or compatibles, and want to do it without timing
loops which is affected by the CPU clock frequency, you will have to 
add an plug in adapter card which has a timer or hardware interrupt 
circuitry on it.  One example is Scientific Solutions (spawned from
Tecmar) LabMaster (This has the whole analog I/O stuff on it and probably
an overkill for your purpose.).

If you want to do it without buying these things, you can probably
use your spare printer adapter to do the job.
IBM PC printer adapters can generate interrupts IRQ7 (or IRQ5 ?).
So, if you have a printer port that you don't need, you can
connect an 1 kHz oscillator (TTL level) to ACK line of the printer port.
Then, put proper interrupt service routine to int vector for IRQ7,
enable interrupt on the printer adapter, and on the 8259 PIC (interrupt
controller).  Since there are a few more input lines on the printer
adapter, you can probably use them for buttons pressed by subject. 
 
Hope this helps.

Izumi Ohzawa
izumi@violet.berkeley.edu
(415) 642-6440