     This file documents the library of timer functions that was used to
     create the ATAHD.EXE program. For anyone who wishes to purchase
     the library, there is an order form at the end of this document.



-----OVERVIEW of TILIB v2.0:

     A library of general purpose, high precision timer functions for
     use with C/C++, Pascal, Basic and Assembler.

     Written entirely in Assembler.

     Should run on any version of DOS that your compiler supports.



----PART ONE:   Function Descriptions


    The ReadTimer function:

        The lowest level routine, this is the workhorse. Except for the
        CONVERSION functions, all other functions call this routine.
        ReadTimer takes the standard BIOS timer tick count (18.2 ticks
        per second) and increases it's effective resolution by a factor
        of 1024 (18643.4 ticks per second) which are referred to here as
        high precision timer ticks. This allows for a timing accuracy of
        0.00005 seconds per event.

        A call to this routine returns a long integer a maximum of 31
        bits wide (no negative values) reflecting the number of high
        precision timer ticks since midnight.



    STOPWATCH functions:

        StartTime GetElapsedTime

        These functions implement the action of a stopwatch. A call to
        StartTime starts the count, then each call to GetElapsedTime
        returns the elapsed time in milliseconds, much like the LAP
        button on a typical stopwatch.

        If StartTime is NOT called, GetElapsedTime returns the number of
        milliseconds since midnight.



    DELAY function:

        Delay

        Implements a delay of xx milliseconds. Delay will lock up the
        machine but since it only excepts 16 bit values (a max of 65536
        milliseconds), there can be only 65 seconds of grief.

        This is similar to the function of the same name in some
        languages but this one is actually accurate to 1 millisecond.



    INTERVAL functions:

        SetInterval WaitInterval

        These functions can be used to create a delay, as above, but are
        much more flexible.
        
        Call SetInterval with an argument of xx milliseconds, then
        execute some code. A subsequent call to WaitInterval will then
        delay until the remainder of xx milliseconds has expired. This
        makes it very easy to create medium precision timing loops
        without regard for the actual execution time of the code itself.

        What happens if the executed code takes longer than xx
        milliseconds to execute? In this case, the call to WaitInterval
        returns the difference between xx milliseconds and the actual
        execution time, otherwise it returns 0. In other words,
        WaitInterval becomes transparent once this threshold is crossed
        (it does nothing).

        SetInterval need only be called again if a new interval is
        desired, otherwise, each call to WaitInterval resets the
        interval.



    CONVERSION functions:

        ConvMsToTicks ConvTicksToMs

        Converts milliseconds to high precision timer ticks and vice
        versa. Many of the above functions use these routines.

        A simple algorithm is used to produce fast, accurate results
        using only 16-bit integer math.

        These routines will not except values larger than a 24 hour
        period. On overflow they return -1 and the carry flag set.
        CONVERSION routines do not call any other functions.




    MIDNIGHT ROLLOVER

        INTERVAL, STOPWATCH and DELAY functions take into account that
        midnight might occur while a timing function is taking place.

        ReadTimer, the lowest level function, makes no such effort. Any
        code that directly calls ReadTimer is responsible for it's own
        checks (the rollover flag is returned in the BX register, which
        is accessible with assembler or through the use of pseudo-
        registers).

        None of the above routines resets the rollover flag, they only
        check to see if it has CHANGED from one call to the next. If a
        change indicates midnight then compensation is made.

        If some intervening code resets the BIOS midnight rollover flag
        (for instance, between calls to StartTime and GetElapsedTime),
        then results may be unpredictable.




----PART TWO:   Function Implementations



        C/C++ ---------------------------------------------------

            long ReadTimer (void);
            long ConvTicksToMs (long);
            long ConvMsToTicks (long);
            void Delay (unsigned short milliseconds);
            void SetInterval (unsigned short milliseconds);
            short WaitInterval (void);
            void StartTime (void);
            long GetElapsedTime (void);


            #define TICKS_PER_SEC 18643.437037
            #define TICKS_PER_DAY 1610792960


            Files included for C/C++:

                TILIB.H         ; Contains the above declarations
                TICS.LIB        ; Small model for DOS
                TICL.LIB        ; Large model for DOS



        PASCAL --------------------------------------------------

            function ReadTimer :longint;
            function ConvMsToTicks ( ms:longint ) :longint;
            function ConvTicksToMs ( ticks:longint ) :longint;
            procedure Delay ( ms:integer );
            procedure SetInterval ( ms:integer );
            function WaitInterval :integer;
            procedure StartTime;
            function GetElapsedTime :longint;

            const
              TicksPerSecond = 18643.437037;
              TicksPerDay = 1610792960;


            Files included for TURBO PASCAL:

                TIMER.PAS       ; Contains the above declarations
                TIMER.TPU       ; Turbo PASCAL Unit compiled from TIMER.PAS

            General purpose libraries using the Pascal calling convention:

                TIPASS.LIB      ; Small code model for DOS
                TIPASL.LIB      ; Large code model for DOS



        BASIC ---------------------------------------------------

            DECLARE FUNCTION ReadTimer& ()
            DECLARE FUNCTION ConvTicksToMs& (ticks&)
            DECLARE FUNCTION ConvMsToTicks& (milliseconds&)
            DECLARE FUNCTION Delay (milliseconds%)
            DECLARE SUB SetInterval (milliseconds%)
            DECLARE FUNCTION WaitInterval% ()
            DECLARE SUB StartTime ()
            DECLARE FUNCTION GetElapsedTime& ()

            CONST TicksPerSecond = 18643.437037#
            CONST TicksPerDay = 1610792960


            Files included for QuickBASIC:

                TIMER.BI        ; Contains the above declarations
                TIMER.QLB       ; QuickBASIC QuickLibrary for DOS
                TIPASL.LIB      ; Standard library for DOS



        ASSEMBLER -----------------------------------------------

            All values are passed in registers.
                DX:AX   for long integers
                AX      for short integers

            Files included for Assembler:

                TIASMS.LIB      ; Small model for DOS
                TIASML.LIB      ; Large model for DOS



----PART THREE:   Order Form:


    Send a check or money order, drawn an a U.S. bank, for $29.50 to:

        M.B.Mallory
        P.O.Box 12412
        Lake Park, FL 33403
        U.S.A.


    Please send the timer library to:

    Name:_____________________________________________

    Address1:_________________________________________

    Address2:_________________________________________

    City:___________________________ State:__________ Zip:___________

    Country:________________________



    E-mail address:______________________________________



    My e-mail address is:

        mbmallory@netscape.net


    Please wait the appropriate amount of time for checks to clear.

    Thank you very much.
