<?xml version="1.0"?>
<!DOCTYPE riscos-prm PUBLIC "-//Gerph//DTD PRM documentation 1.02//EN"
                            "http://gerph.org/dtd/102/prm.dtd">

<riscos-prm>
<chapter title="High resolution timer (TimerMod)">
<section title="Introduction and Overview">
<p>
The standard <reference type='swi' name='OS_ReadMonotonicTime' href='?'/> SWI provides a centisecond time
since the system has booted. This is not sufficient for some tasks, and a greater resolution is required
for some interfaces. The TimerMod module provides a means of accessing a timer at a higher resolution
than the standard.
</p>
</section>


<section title="Technical details">
<p>
    The TimerMod abstracts away the interfaces required for accessing an incrementing timer, at an
    undefined resolution. All timings are returned in units of microseconds, although the accuracy
    of the timings may be far less than this. The module provides access to a single-user stopwatch
    timer, and an incrementing timer.
</p>

<subsection title="Stop watch">
    <p>
        The stop watch is essentially an interval timer which can be started and stopped arbitrarily.
        The <reference type='swi' name="Timer_Start"/> and <reference type='swi' name='Timer_Stop'/>
        SWIs provide a means by which the stop watch can be started, and stopped. The timer has a
        simple life cycle:
    </p>

    <p>
    <list>
        <item>The user issues <reference type='swi' name="Timer_Start"/>, and the module resets the
              start time to 0.</item>
        <item>The user issues <reference type='swi' name="Timer_Stop"/>, and the module returns the
              elapsed time since the initial Timer_Start call.</item>
        <item>Subsequent calls to <reference type='swi' name="Timer_Stop"/>, return the same value
              as the last call to Timer_Stop.</item>
    </list>
    </p>

    <p>There is only a single stop watch, so this interface is only suitable for a debug and diagnostic
       purposes. Using this interface within distributed components may interfere with other users
       of the interface.</p>
</subsection>

<subsection title="Timer">
    <p>The timer counts upwards from 0 at system boot, and can be retrieved with
       <reference type='swi' name="Timer_Value"/>. This value is unaffected by the stop watch, and will
       continue incrementing whilst the system is running. When the system is reset, the timer will reset
       and begin counting from 0 again.
    </p>
</subsection>


<subsection title="Hardware implementation">
<p>
    On all machines the module uses the CMOS clock for time calculations to
    1 centisecond resolution. Microsecond resolution is provided by hardware
    specific timers.
</p>
<p>
<list>
    <item>On RiscPC, A7000 and Archimedes machines, the 2MHz IOMD/IOC timer 0 is used.</item>
    <item>On RISC OS 5 machines, the HAL counter 0 is read.
          On the Iyonix this provided by the XScale 80321 and runs at 200MHz.
          It also works on the Raspberry Pi which has a 1MHz timer.
    </item>
    <item>On RISC OS Pyromaniac, the host system timer is used.</item>
</list>
</p>
</subsection>

</section>


<section title="SWI calls">

<swi-definition name="Timer_Start"
                number="490C0"
                description="Starts the timer stop watch"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
</entry>
<exit>
</exit>

<use>
<p>The Timer_Start SWI is used to reset the timer stop watch and begin it running. Repeated calls whilst
the stop watch is running will reset the stop watch to 0.</p>
</use>

<related>
    <reference type="swi" name="Timer_Stop" />
    <reference type="command" name="TimerStart" />
    <reference type="command" name="TimerStop" />
</related>

</swi-definition>


<swi-definition name="Timer_Stop"
                number="490C1"
                description="Stops the timer stop watch"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
</entry>
<exit>
 <register-use number="0">Seconds between the last stop watch start, and its stop.</register-use>
 <register-use number="1">Fractional microseconds between the last stop watch start, and its stop.</register-use>
</exit>

<use>
<p>The Timer_Stop SWI is used to stop the stop watch timer, and return the interval between the start of the
stop watch, and its stop. Subsequent calls to the SWI will return that value again, until the stop watch is
started again.</p>

<p>
    The returned value is broken into two registers, containing the second and microsecond measures of the
    interval between the start and stop.
</p>
</use>

<related>
    <reference type="swi" name="Timer_Start" />
    <reference type="swi" name="Timer_Value" />
    <reference type="command" name="TimerStart" />
    <reference type="command" name="TimerStop" />
</related>

</swi-definition>



<swi-definition name="Timer_Value"
                number="490C2"
                description="Returns the current value of the monotonic time"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
</entry>
<exit>
 <register-use number="0">Seconds since system boot.</register-use>
 <register-use number="1">Fractional microseconds since system boot.</register-use>
</exit>

<use>
<p>The Timer_Value SWI is used to read the value of the Monotonic Timer to a greater accuracy. The Monotonic timer starts when the system boots and increases during the system's runtime.</p>

<p>
    The returned value is broken into two registers, containing the second and microsecond measures of the
    time since the system booted.
</p>
</use>

<related>
    <reference type="swi" name="OS_ReadMonotonicTime" href='?'/>
    <reference type="swi" name="Timer_Stop" />
    <reference type="command" name="TimerValue" />
</related>

</swi-definition>

</section>


<section title="*Commands">

<command-definition name="TimerStart"
                    description="Starts the timer stop watch">

<syntax>
</syntax>

<use>
<p>*TimerStart uses SWI Timer_Start to start the stop watch.</p>
</use>

<example>
<command>*TimerStart</command>
</example>


<related>
    <reference type="swi" name="Timer_Start" />
    <reference type="swi" name="Timer_Stop" />
    <reference type="command" name="TimerStop" />
</related>

</command-definition>


<command-definition name="TimerStop"
                    description="Stops the timer stop watch and reports the interval">

<syntax>
</syntax>

<use>
<p>*TimerStop uses SWI Timer_Stop to stop the stop watch and then reports the time.</p>
</use>

<example>
<command>*TimerStop</command>
<systemoutput>
Elapsed time: 13.279904
</systemoutput>
</example>


<related>
    <reference type="swi" name="Timer_Start" />
    <reference type="swi" name="Timer_Stop" />
    <reference type="command" name="TimerStart" />
</related>

</command-definition>


<command-definition name="TimerValue"
                    description="Report the time since boot">

<syntax>
</syntax>

<use>
<p>*TimerValue uses SWI Timer_Value to reports the time since boot with greater accuracy
    than the OS_ReadMonotonicTime SWI.</p>
</use>

<example>
<command>*TimerValue</command>
<systemoutput>
Elapsed time: 83.432451
</systemoutput>
</example>


<related>
    <reference type="swi" name="OS_ReadMonotonicTime" href='?'/>
    <reference type="swi" name="Timer_Start" />
    <reference type="swi" name="Timer_Stop" />
    <reference type="command" name="TimerStart" />
</related>

</command-definition>

</section>

</chapter>

<!-- MetaData -->
<meta>
 <maintainer>
  <email name="Druck" address="druck@druck.org.uk" />
  <email name="Gerph" address="gerph@gerph.org" />
 </maintainer>
 <disclaimer>
    <p>
        &copy; 1991-2020, DEEJ Technology PLC.
    </p>
 </disclaimer>

 <history>
  <!-- Incorporates the module history -->

    <revision number="1.00" author="Druck">
        <change>Initial release.</change>
    </revision>

    <revision number="2.00" author="Druck">
        <change>*commands added.</change>
    </revision>

    <revision number="3.00" author="Druck">
        <change>SWI chunk base now registered with Acorn.</change>
    </revision>

    <revision number="4.00" author="Druck">
        <change>Iyonic HAL and 32bit neutral version.</change>
    </revision>

    <revision number="4.10" author="Druck">
        <change>Uses own time to string routine to prevent time zone offsets.</change>
    </revision>

    <revision number="4.11" author="Druck">
        <change>Fixed counter wrapping comparison bug.</change>
    </revision>

    <revision number="4.12" author="Druck">
        <change>Fixed IOC counter off by 1.</change>
    </revision>

    <revision number="4.13" author="Druck">
        <change>Fixed us value out of range due to RTCAdjust modules.</change>
    </revision>

    <revision number="4.14" author="Druck">
        <change>Uses HAL direct calls.</change>
    </revision>

    <revision number="4.15" author="Druck">
        <change>Fixed prompt output in TimedOS mode.</change>
    </revision>

    <revision number="4.16" author="Druck">
        <change>Fixed bug where HAL counter period is slightly less 10000 on Raspberry Pi.</change>
        <change>Fixed time display in TimedOS broken by 4.15.</change>
    </revision>

    <revision number="4.17" author="Druck">
        <change>Counter period corrected for NetTime adjustment.</change>
    </revision>

    <revision number="4.18" author="David Thomas">
        <change>ARM2 compatibility courtesy of David Thomas.</change>
    </revision>

    <revision number="4.19" author="David Thomas">
        <change>Fixed issuing `*TimedOS` within `*TimedOS` causing a crash.</change>
        <change>Fixed `*Quite` etc. working as `*Quit` within *TimedOS.</change>
        <change>Added copyright to the module help string.</change>
    </revision>

    <revision number="4.19doc" author="Gerph" date="27 Feb 2021" title="Created PRMinXML documentation">
        <change>Document created from original text documentation.</change>
        <change>Notes from the Pyromaniac implementation.</change>
    </revision>

 </history>

 <related>
    <reference type='link' href="https://armclub.org.uk/free/" />
 </related>
</meta>
</riscos-prm>
