Re: [Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread Bart Oldeman
Hi Tom,

> > Menu timeout set at 10 seconds. Boot kernel with menu at 23:59:55.
> > Timer expires at 00:00:00 (0-1.5M = very large number)
> and that's exactly the wanted behaviour.

is it? At least the comment doesn't say so, maybe it was in your head
though.

>
> > instead of  00:00:05.
>
> and to wait precisely 10 seconds in the case that someone boots
> FreeDOS at midnight AND is sitting at the keyboard AND thinks it's a
> bug that the timer gotes off early is simply not worth the code to
> handle this case.

well I do agree it's a highly unlikely situation.
>
> > >> +if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
> and the original code uses long arithmetic on purpose.

The original code only pretends to use long arithmetic:

if (GetBiosTime() - startTime >= (unsigned)timeout * 18)
  break;

The reason is that (unsigned)timeout * 18 is a 16 bit value.
GetBiosTime() - startTime will under normal circumstances (outside
midnight) *never* be >= 0x1, since it increases step by step from 0
and bails out before it gets even close. Hence it is perfectly OK to cast
to (unsigned).

If you have a purpose to use long arithmetic then the original code needs
to be:

if (GetBiosTime() - startTime >= (unsigned long)timeout * 18)
  break;

Now what am I missing here?

Bart



---
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_id=3149&alloc_id=8166&op=click
___
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel


Re: [Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread tom ehlert
Hello Bart,

>> if (GetBiosTime() - startTime > (unsigned)timeout * 18)
>>break;

> Menu timeout set at 10 seconds. Boot kernel with menu at 23:59:55.
> Timer expires at 00:00:00 (0-1.5M = very large number)
and that's exactly the wanted behaviour.

> instead of  00:00:05.

but it times out, and doesn't wait indefinitively.

and to wait precisely 10 seconds in the case that someone boots
FreeDOS at midnight AND is sitting at the keyboard AND thinks it's a
bug that the timer gotes off early is simply not worth the code to
handle this case.

> >> +if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
and the original code uses long arithmetic on purpose.

tom






---
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_id=3149&alloc_id=8166&op=click
___
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel


Re: [Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread Bart Oldeman
Hello Tom,

> >> +if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
> >> +  return 0x;
> >>}
> >> +  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).
>
> bla. blubber. blabla.
>
> the original code reads:
> if (GetBiosTime() - startTime > (unsigned)timeout * 18)
>break;
>
> and now I want to get an example when this breaks.

Menu timeout set at 10 seconds. Boot kernel with menu at 23:59:55.
Timer expires at 00:00:00 (0-1.5M = very large number) instead of
00:00:05.

The (unsigned) cast for (GetBiosTime() - startTime) makes
absolutely no difference in this respect. Signed numbers won't help
either.

Bart



---
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_id=3149&alloc_id=8166&op=click
___
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel


Re: [Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread Arkady V.Belousov
Hi!

24-Май-2004 22:14 [EMAIL PROTECTED] (tom ehlert) wrote to "Arkady V.Belousov"
<[EMAIL PROTECTED]>:

te> the original code reads:
te> if (GetBiosTime() - startTime > (unsigned)timeout * 18)
te>break;
te> and now I want to get an example when this breaks.

 For example, set timeout 30 seconds and run 10 seconds before midnight.
Then above code willn't wait all 30 seconds, but not more than 10 seconds.




---
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


Re: [Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread tom ehlert
Hello Arkady,

> Hi!

>> +if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
>> +  return 0x;
>>}
>> +  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).

bla. blubber. blabla.

the original code reads:
if (GetBiosTime() - startTime > (unsigned)timeout * 18)
   break;

and now I want to get an example when this breaks.





---
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_id=3149&alloc_id=8166&op=click
___
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel


[Freedos-kernel] Re: [Freedos-cvs] kernel/kernel config.c,1.86,1.87

2004-05-24 Thread Arkady V.Belousov
Hi!

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

> +++ config.c  24 May 2004 18:39:49 -  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 0x;
>}
> +  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 0x;

  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