Hi!

24-Май-2004 18:39 [EMAIL PROTECTED] (Bart Oldeman) wrote to
[EMAIL PROTECTED]:

> +++ config.c  24 May 2004 18:39:49 -0000      1.87
>  UWORD GetBiosKey(int timeout)
> @@ -752,26 +749,19 @@
> +  if (timeout >= 0) do
>    {
>      r.a.x = 0x0100;             /* are there keys available ? */
>      init_call_intr(0x16, &r);
> +    if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
> +      return 0xffff;
>    }
> +  while (r.flags & FLG_ZERO);

     This is not good way to calculate delays - around midnight (when system
timer will be reset) above expression will be calculated wrongly (because
GetBiosTime() will be lesser than startTime).

     Let me quote, how this solved in clock() function (this is quote from
_my_ clock() function edition, which replaces BC RTL and fixes Windows
bugs):

______________O\_/_________________________________\_/O______________
/* beginning of program execution initialized in C0.ASM */
extern ulong _StartTime;

static byte startflag = 1;
static long daysFlip;
static ulong last;

#define BIOStime()      (*((volatile ulong far*) MK_FP (0, 0x46C)))
#define BIOSflip()      (*((volatile byte  far*) MK_FP (0, 0x470)))
#define setBIOSflip(v)  (BIOSflip () = v)

clock_t clock (void) {
        ulong now = BIOStime ();        /* order of reading `now' and   */
        byte flip = BIOSflip ();        /*      `flip' is required      */
        if (flip) {                     /* did day change just now?     */
                /* get DOS date to force DOS to recognize date change   */
                asm { mov ah,0x2A; int 0x21; }

                /* Protection against low probable, but possible date   */
                /* change between reading time `now' and date change    */
                /* flag `flip'                                          */
                now = BIOStime ();
                setBIOSflip (0);        /*!!! --- WINDOWS BUG FIX --- !!!*/
        }
        if (startflag-1 == 0) { daysFlip = -(last = _StartTime); startflag++; }

        if (flip || now < last)
                daysFlip += 1573040ul;  /* number of clock ticks in day */
        return (last = now) + daysFlip;
}
_____________________________________________________________________
              O/~\                                 /~\O

This is C-ish way. In CuteMouse I solve this by another way: I just count
how times timer variable is changed:

______________O\_/_________________________________\_/O______________
countloop_ 2+1,ch                      ; length of silence in ticks
                                       ; (include rest of curr tick)
       mov     ah,byte ptr [BIOS_timer]
 loop_
       movidx  dx,LSR_index,si
        in     al,dx                   ; {3FDh} LSR (line status reg)
       testflag al,mask LSR_RBF
        jnz    @@parse                 ; jump if data ready
       cmp     ah,byte ptr [BIOS_timer]
 until_ ne                             ; loop until next timer tick
end_ countloop                         ; loop until end of 2nd tick
break_                                 ; break if no more data
_____________________________________________________________________
              O/~\                                 /~\O

In given case (GetBiosKey()) I may propose next solution:

______________O\_/_________________________________\_/O______________
UWORD GetBiosKey(int timeout)
[...]
  if (timeout >= 0)
  {
    unsigned ticks = 18u * timeout;
    unsigned tick = (unsigned)GetBiosTime();
    for (;;)
    {
      r.AH = 1; /* are there keys available ? */
      init_call_intr(0x16, &r);
      if ((r.flags & FLG_ZERO) == 0)
        break;

      if (ticks == 0)
        return 0xffff;

      if (tick != GetBiosTime())
      {
        ticks--;
        tick = (unsigned)GetBiosTime();
      }
    } /* for */
  } /* if */

  /* key available or blocking wait (timeout < 0): fetch it */
  r.AH = 0;
_____________________________________________________________________
              O/~\                                 /~\O




-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g.
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id149&alloc_id│66&op=click
_______________________________________________
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel

Reply via email to