The following IOCtls are defined and supported by the TIMER0$ device driver by way of the DosDevIOCtl call. The IOCtl category code is 80h (defined as HRT_IOCTL_CATEGORY).

The function codes within the HRT_IOCTL_CATEGORY are:

ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³Function  ³Description                                       ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³00h       ³Get Version                                       ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³01h       ³Get Resolution                                    ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³02h       ³Set Resolution                                    ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³03h       ³Get Pointer to Clock Timer                        ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³04h       ³Free Pointer to Clock Timer                       ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³05h       ³Block Until Time Elapses                          ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³06h-7Fh   ³Reserved                                          ³
ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

An example of the DosDevIOCtl calling convention for reading the current time follows:

   #include "tmr0_ioc.h"

   APIRET rc           = NO_ERROR;
   HFILE  hfile        = NULLHANDLE;
   ULONG  ulAction     = 0L;

   ULONG  ulResolution = 1;
   ULONG  ulSize1      = sizeof(ulResolution);

   ULONG  * _Seg16 pulTimer16;             // defines a 16:16 pointer
   ULONG  ulSize2      = sizeof(pulTimer16);
   ULONG  *pulTimer;

   rc=DosOpen( "TIMER0$ ",
               &hfile,
               &ulAction,
               0,0,
               OPEN_ACTION_OPEN_IF_EXISTS,
               OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE |
               OPEN_ACCESS_READWRITE,
               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);

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

While the HRT is taking interrupts, DOS sessions (VDMs) will not receive INT 8 or INT 1Ch calls. The reason for this is that OS/2 only allows one device driver to receive interrupts on a given IRQ, and VTIMER.SYS (the VDD that provides INT 8 and INT 1Ch services to VDM's) expects CLOCK0x.SYS to deliver IRQ 0 interrupts. When the HRT is active, it receives the IRQ 0 interrupts instead of CLOCK0x.SYS, and thus VTIMER.SYS never gets them either.

Note: Performance tools, such as C Set's DDE4XTRA.SYS and VisualAge's CPPOPA3.SYS, are incompatible with this driver. Performance analysis tools cannot be run while the high-resolution timer is active, and vice versa.