## MMPM/2 Device Driver Reference

[prev][next][parent][TOC]

### Ring-3 Usage

The IOCtl interface provides the ability to:

obtain a pointer to the clock counter The pointer returned is a 16:16 pointer, which should be converted to a 0:32 pointer for use with 32-bit applications.

query and set the resolution Currently, the resolution is always 1 millisecond. Attempts to set it to another value will be ignored, and querying the driver will always return 1 millisecond. You should set the resolution anyway-in the future, the driver may actually use a lower resolution to conserve resources.

block until a certain time has elapsed

Use the following code as an example of reading the current time. The compiler used is C-Set++ 2.1. If you use a different compiler, you may need another technique for handling 16:16 pointers.

    #include "tmr0_ioc.h"

    APIRET rc;

    HFILE  hfile;

    ULONG  ulAction;

    ULONG  ulOpenFlag = OPEN_ACTION_OPEN_IF_EXISTS;

    ULONG  ulOpenMode = OPEN_FLAGS_FAIL_ON_ERROR |

                        OPEN_SHARE_DENYNONE |

                        OPEN_ACCESS_READWRITE;

    ULONG  ulResolution = 1;

    ULONG  ulSize1=sizeof( ulResolution );

    ULONG  * _Seg16 pulTimer16;

    ULONG  ulSize2=sizeof( pulTimer16 );

    ULONG  *pulTimer;

    rc=DosOpen( "TIMER0$ ", &hfile, &ulAction, 0, 0, ulOpenFlag, ulOpenMode, NULL );

    if( rc )

    {

       printf( "Couldn't open TIMER0$.\n" );

       return;

    }

    printf( "TIMER0$ opened.  File Handle is %lu\n",hfile );

    rc=DosDevIOCtl( hfile, HRT_IOCTL_CATEGORY, HRT_SET_RESOLUTION,

                    &ulResolution, ulSize1, &ulSize1, NULL, 0, NULL );

    if( rc )

    {

       printf( "Couldn't set resolution.\n" );

       DosClose( hfile );

       return;

    }

    rc=DosDevIOCtl( hfile, HRT_IOCTL_CATEGORY, HRT_GET_POINTER,

                    NULL, 0, NULL, &pulTimer16, ulSize2, &ulSize2 );

    if( rc )

    {

       printf( "Couldn't get pointer.\n" );

       DosClose( hfile );

       return;

    }

    pulTimer=pulTimer16;                // Converts a 16:16 pointer to a 0:32 pointer

    if( !pulTimer )

    {

       printf( "NULL pointer.\n" );

       DosClose( hfile );

       return;

    }

    // At this point, pulTimer is now a pointer to the timer 0 counter variable

    rc=DosClose( hfile );

DosOpen( "TIMER0$" ) registers the application as a client. At this point, the high-resolution timer driver is taking interrupts; so make sure the driver is open only when you need timer services. The pointer is valid for the life of the process; and each call to HRT_GET_POINTER allocates another selector-therefore, this call should be made only once.

To block until a certain time has elapsed, use the following code as an example. For brevity, the details (such as checking return codes) have been omitted.

    ULONG  ulDelay=1;                     // Number of milliseconds to wait

    ULONG  ulSize2=sizeof( ulDelay );

    DosOpen( "TIMER0$  ", &hfile, &ulAction, 0, 0, ulOpenFlag, ulOpenMode, NULL );

    DosSetPriority( 0, PRTYC_TIMECRITICAL, 0, 0 );

    DosDevIOCtl( hfile, HRT_IOCTL_CATEGORY, HRT_BLOCKUNTIL,

                 &ulDelay, ulSize2, &ulSize2, NULL, 0, NULL );

Using a time-critical thread is important.