www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/05/12/07:24:34

From: mauch AT unidui DOT uni-duisburg DOT de (Michael Mauch)
To: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
Cc: djgpp AT delorie DOT com
Subject: Re: testing uclock()
Date: Mon, 12 May 1997 13:22:03 +0200
Organization: Home, sweet home (via Gesamthochschule Duisburg)
Message-Id: <337cfc42.2988017@unidui.uni-duisburg.de>
References: <Pine DOT SUN DOT 3 DOT 91 DOT 970511122103 DOT 27751O-100000 AT is>
In-Reply-To: <Pine.SUN.3.91.970511122103.27751O-100000@is>
Mime-Version: 1.0

----=_3376fd5b326908407598619.MFSBCHJLHS
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

On Sun, 11 May 1997 12:21:41 +0300 (IDT), Eli Zaretskii wrote:

> On Fri, 9 May 1997, Michael Mauch wrote:
> 
> > Thanks for your explanation of __bss_count. I guess this should be
> > changed in puclock, too. Shall I repost the whole thing?
> 
> I think so, yes.

Ok. I declared wuclock() as a public symbol now, so a program can test
if the VTD API is available.

Regards...
		Michael


----=_3376fd5b326908407598619.MFSBCHJLHS
Content-Type: text/plain; charset=us-ascii; name=Puclock.h
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=Puclock.h

#ifndef PUCLOCK_H
#define PUCLOCK_H

#include <time.h>

extern uclock_t (*puclock)(void);

uclock_t wuclock(void);

#endif

----=_3376fd5b326908407598619.MFSBCHJLHS
Content-Type: text/plain; charset=us-ascii; name=Puclock.c
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=Puclock.c


#include <string.h>
#include <dpmi.h>
#include <libc/bss.h>


#include "puclock.h"



static uclock_t wuclock_wrapper(void);

uclock_t (*puclock)(void) = wuclock_wrapper;

static int puclock_bss = -1;


/* 
** wuclock() works just like uclock(), that is:
**
** "This function returns the number of uclock ticks since an arbitrary
**  time, actually, since the first call to `uclock', which itself returns
**  zero.  The number of tics per second is UCLOCKS_PER_SEC."
** (quoted from libc.inf).
**
** wuclock() queries the Virtual Timer Device (VTD) of Windows 3.1 / Win95.
** Ralf Brown's Interrupt List says that the VTD returns the
** "clock tick time in 840ns units since Windows was started"
** - see Table 1969 in Intwin53.hlp, referenced by the topic
** "INT 2F 1684 - MS Windows - VTD - GET API ENTRY POINT".
**
** I hope that these "840ns units" are the same as 1 sec / UCLOCKS_PER_SEC,
** i.e. 838.1ns.
**
** Although we don't get this high resolution inside Windows, the granularity
** should still be better than the 55ms provided by other functions (e.g.
** rawclock()).
**
** Eli Zaretskii pointed out that we can't use uclock() on Windows 95,
** because Windows 95 reprograms the timer chip every now and then,
** spoiling the timer chip mode that uclock() relies on.
**
** wuclock() returns negative values if the VTD API is not available.
** The VTD API is supported in (the DOS window of) Win3.1, WfW3.11, Win95(a)
** and Win95b (OSR2), but not on plain DOS and WinNT4.0.
** I don't know about other varieties of Windows (NT3.51, OS/2, ...).
**
** The pointer puclock initially points to wuclock_wrapper(). This function
** calls wuclock() to test if the VTD API is available, if so, it sets
** puclock to wuclock(), else it sets it to the original uclock().
**
*/
uclock_t wuclock(void)
{
  static struct
  {
    unsigned short lo,hi;
  } VTD;   /* address of the Virtual Timer Device API entry point */

  static uclock_t base;
  uclock_t rv;
  __dpmi_regs regs;  /* __dpmi_regs = _go32_dpmi_registers */

  if (puclock_bss != __bss_count)
  {
    memset(&regs,0,sizeof(regs));
    regs.x.ax = 0x1684;
    regs.x.bx = 0x0005;
    regs.x.di = 0;
    regs.x.es = 0;
    if(__dpmi_simulate_real_mode_interrupt(0x2F,&regs))  /* = _go32_dpmi_simulate_int */
      return -1; /* error: VTD API not available */

    VTD.lo = regs.x.di;
    VTD.hi = regs.x.es;
    if(!(VTD.lo | VTD.hi))
      return -2; /* error: VTD API not available */

    base = 0;
    puclock_bss = __bss_count;
  }
  memset(&regs,0,sizeof(regs));
  regs.x.ax = 0x100;
  regs.x.cs = VTD.hi;
  regs.x.ip = VTD.lo;
  if(__dpmi_simulate_real_mode_procedure_retf(&regs))
    return -3; /* error: VTD API call failed */

  *((long*)&rv+0) = regs.d.eax;
  *((long*)&rv+1) = regs.d.edx;

  if(!base)
    base = rv;

  return rv - base;
}

static uclock_t wuclock_wrapper(void)
{
  uclock_t r = wuclock();  /* test if VTD API is available */
  if(r<0)
    return puclock = uclock, uclock();
  return puclock = wuclock, r;
}


----=_3376fd5b326908407598619.MFSBCHJLHS--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019