From: aki@cruzio.santa-cruz.ca.us
Newsgroups: comp.os.msdos.programmer
Subject: Re: Real time AT Clock on int 70h
Date: Thu, 08 Oct 92 17:02:20 PDT
Reply-To: aki@cruzio.santa-cruz.ca.us

In article <E36CBC0C807F40DB59@qut.edu.au>, ISB202REID@redgum.qut.edu.au (Did somebody say Coffee ??????) writes:
> I was perusing Ralf Brown's interrupt list,
> when I found the entry for the real time AT clock on Int 70h.
> 
> So I wrote a TSR that hooked it and hoped it would be invoked,
> every 1024th of a second.
> 
> Absolutely nothing happened.
> 
> The TSR hooked it OK, it just wasn't getting invoked...
> 


INT 70H is the IRQ 8 line on PC/AT's and later.  IRQ 8 is by
definition hooked to the Real Time Clock to signal events.
One of the events that can be signalled is the 1024 Hz periodic
interrupt. Others are Alarm and End-Of-Update (i.e. when the
clock time changes). 

The use of these events for timing is theoretically very easy.
You enable the IRQ and tell the RTC to start signaling.
Unfortunately the design of the Industry Standard BIOS makes
this virtually impossible.  BIOS takes full control of the
RTC.  If you want to time a certain time frame, you must ask
BIOS to do it for you.  If you want an alarm,  you must ask
BIOS to set it up for you, and trust that it will call you
when the time comes.  End of Update is the only signal that's
somewhat OK to use, but then this signal only occurs once per
second.  

"How can BIOS shield the RTC clock?" you ask...  It starts
with the way BIOS times a lot of things, including disk access,
some serial communications, and occasionally even the keyboard.
Every time you call the BIOS,  you are liable to invoke some
timing loop.  To remain clock-frequency flexible,  most BIOSes
use the RTC for timing loops.  This means that the BIOS sets
up its own IRQ handler (actually it assumes that this was
set-up correctly during boot-up), tells the RTC to enable
Periodic Interrupts,  and counts as long as it wishes to
wait (industry standard is 1024Hz accuracy, but you could
go higher or lower).  The pitfalls are easy to see:
  1. When BIOS turns the Periodic Interrupts on, it may
     not bother to preserve the status of the Alarm and
     End Of Update interrups as they are set in the RTC,
     but will use what ever suits its purposes.  IBM AT
     BIOS preserves the bits.
  2. BIOS may rewrite the IRQ vector, although this would
     be incompatible with the Industry "Standard".
  3. At the end of a timing period the BIOS may turn off
     Interrupts.  In fact this is where most programs
     will fail. IBM AT BIOS will turn off Periodic Interrupts
     if its IRQ 8 handler is invoked and no timing has been
     requested.  IBM AT BIOS will do the same to the Alarm
     Interrupt.  For some reason the End Of Update has been
     spared;  thus its the only non-BIOS controllable item.
  4. Microsoft Windows may not be totally compatible with
     what you would like to do with the RTC... producing
     "interesting" results.

In your case the problem is that you did not turn on the interrupt
at the RTC.  To turn the interrupt ON do the following (pseudo) code:

   CLI      [so that IRQ functions can't mess with the Index reg.]
   OUT 70H, 0BH   ; index 0BH
   IN AL, 71H
   [Set bit 6 for Periodic Int, 5 for Alarm Int, 4 for End Of Update Int]
   OUT 71H, AL
   STI

In an IRQ function do the following code to identify what caused the
Int:
    CLI
    OUT 70H, 0CH
    IN AL, 71H
    STI
        [ bit 7 set if Interrupt Output Signal is active,
      bit 6 set if Periodic Interrupt
      bit 5 set if Alarm Interrupt,  bit 4 set if End-Of-Update]
  
I tell everyone not use the RTC,  but it's up to you guys.

Aki.

-- 
/  Phone: 408-662 9664   Fax: 662 9676  |  "Aki" pronounced: Ah-Key. I know  \ 
\  125 Searidge Ct #D, Aptos, CA 95003  |  what I'm doing most of the time.  /
Newsgroups: comp.os.msdos.programmer