[comp.sys.amiga.tech] Timer problems

deven@rpi.edu (Deven T. Corzine) (04/11/90)

On 6 Apr 90 09:02:46 GMT, mcmahan@netcom.UUCP (Dave Mc Mahan) said:

[confused by system time as returned by timer.device]

Dave> 1) What is taking exactly 1/60 second out of my timer request?
Dave>    Is this something to do with the vertical retrace of the CRT?
Dave>    How do I stop this from occuring if Disable() can't do it?

The system timer is tied to one of the UNIT_VBLANK timers in one of
the two 8250 CIA timer chips in the Amiga.  Since this is not intended
as a fine-grain resolution timer, it is only updated every 1/60 of a
second, which I believe is triggered by power line frequency, not
vblank, I believe.  [power line frequency is stable over long periods
of time.]  Disable() does not affect it, since the timer chip is doing
the update, not the CPU.

Dave> 2) Why do I get a minimum of 1 uSecond at times?

System time has a resolution of 1/60 of a second as mentioned above.
It is a feature of the timer.device that a TR_GETSYSTIME request
increments the system time by 1 microsecond, so that no two requests
for the system time can return the same value.  This is so that the
value returned by TR_GETSYSTIME can be used as a unique identifier
within the system.  I expect that at the 1/60 second updates, the
microsecond increments are normalized, but I'm not sure about that.

Dave> 3) Is there any way to read the timer registers directly, so I
Dave>    don't have to pay the overhead of a DoIO() call?  I realize
Dave>    that this is not kosher from a general standpoint, but my
Dave>    program MUST HAVE the ability to obtain the time relative to
Dave>    another event down to about 300 uSeconds and I must be able
Dave>    to sustain this accuracy for about 4 or 5 minutes.  I don't
Dave>    really care if I screw up the accurate keeping of system time
Dave>    if this is the only way to get what I need.  I realize that
Dave>    sometimes reading a hardware register causes the register to
Dave>    reset, meaning that only one routine should have access to
Dave>    it.  If this is true, I can live with it.  I just need to be
Dave>    able to get accurate relative times over the measurement
Dave>    period.

DON'T attempt this.  Leave the system timer unit alone.  Since it is a
UNIT_VBLANK timer, it is useless in this application anyhow.  What you
CAN do is to use AllocResource to allocate one of the CIA timers, and
ONLY after allocating it, then you can access the hardware registers
directly in a system-compatible way.  For 300 uSecond resolution, you
will need to use a UNIT_MICROHZ timer unit.  There is at least one
such unit not reserved for system use.  Check the (preferrably V1.3)
Libraries & Devices RKM for information on allocating the cia timer
unit and the Hardware RKM for usage of the CIA registers.

If there's a way to legally retrieve reference time marks with microhz
resolution, I'm missing it.  Possibly tapping into the UNIT_MICROHZ
timer already reserved for system use is possible.  Is there a legal
way to do this?  [I can't look through the RKM's right now; I'm
writing this all from memory...]

Dave> 4) Does DoIO() somehow cause multi-tasking to occur, even though
Dave>    I have Disable() in effect?  I know that I have to wait for
Dave>    the answer (as compared to SendIO()) but I figure that
Dave>    getting the time takes very little effort and should return
Dave>    quickly.

DoIO() will attempt "quick I/O" on the IORequest.  That is, it sets
the IOF_QUICK bit in the io_Flags field in the IORequest structure,
and calls the BEGINIO vector of the device with the IORequest.  When
BEGINIO returns, if the quick bit is still set, the request was
completed "quickly" and no message passing was done.  If the bit is
cleared, then the request could not be processed immediately and was
instead queued normally.

If the request was not completed "quickly", DoIO() will Wait() until
the IORequest is returned via ReplyMsg from the device.  The Wait()
will break a Forbid() or Disable() for the duration.  A TR_GETSYSTIME
timerequest should execute "quickly" and therefore should not cause a
Wait(), so the Disable() should remain unbroken.  But your resolution
remains 1/60 of a second, and subsequent calls will each be at least 1
microsecond higher than the last.

In summary:

System time has 1/60 of a second resolution, unavoidable.  For more
precision, allocate a cia UNIT_MICROHZ timer via AllocResource()
(refer to the (1.3) L&D RKM) and use it to make your measurements.
Refer to the (1.3) Hardware RKM for hardware information.  Follow
system rules; there is no need to break them, even when there IS a
need to go to the hardware.

Deven
-- 
Deven T. Corzine        Internet:  deven@rpi.edu, shadow@pawl.rpi.edu
Snail:  2151 12th St. Apt. 4, Troy, NY 12180   Phone:  (518) 274-0327
Bitnet:  deven@rpitsmts, userfxb6@rpitsmts     UUCP:  uunet!rpi!deven
Simple things should be simple and complex things should be possible.