Pascal

Moderators: None (Apply to moderate this forum)
Number of threads: 4106
Number of posts: 14016

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Timer2 Posted by NinthAngle on 30 Aug 2005 at 10:06 AM
when I run this bit of code, there are two things that baffle me.
Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?


PROGRAM Time;
USES Crt, Dos;
VAR  hb, mb, sb, hsb: Word;
     h, m, s, hs: Word;


BEGIN
ClrScr;
GetTime(hb, mb, sb, hsb);
Repeat
GotoXY(1, 1);
          GetTime(h, m, s, hs);
          write(m,':', s,':', hs);
UNTIL Keypressed;
GotoXY(10,10);
Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
Readln;
END.

Report
Re: Timer2 Posted by zibadian on 30 Aug 2005 at 10:53 AM
: when I run this bit of code, there are two things that baffle me.
: Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
: Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
:
:
:
: PROGRAM Time;
: USES Crt, Dos;
: VAR  hb, mb, sb, hsb: Word;
:      h, m, s, hs: Word;
: 
: 
: BEGIN
: ClrScr;
: GetTime(hb, mb, sb, hsb);
: Repeat
: GotoXY(1, 1);
:           GetTime(h, m, s, hs);
:           write(m,':', s,':', hs);
: UNTIL Keypressed;
: GotoXY(10,10);
: Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: Readln;
: END.
: 

:
1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.

2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
Report
Re: Timer2 Posted by NinthAngle on 30 Aug 2005 at 1:28 PM
: : when I run this bit of code, there are two things that baffle me.
: : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
: : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
: :
: :
: :
: : PROGRAM Time;
: : USES Crt, Dos;
: : VAR  hb, mb, sb, hsb: Word;
: :      h, m, s, hs: Word;
: : 
: : 
: : BEGIN
: : ClrScr;
: : GetTime(hb, mb, sb, hsb);
: : Repeat
: : GotoXY(1, 1);
: :           GetTime(h, m, s, hs);
: :           write(m,':', s,':', hs);
: : UNTIL Keypressed;
: : GotoXY(10,10);
: : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: : Readln;
: : END.
: : 

: :
: 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
:
: 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
:

So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
Report
Re: Timer2 Posted by zibadian on 30 Aug 2005 at 1:49 PM
: : : when I run this bit of code, there are two things that baffle me.
: : : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
: : : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
: : :
: : :
: : :
: : : PROGRAM Time;
: : : USES Crt, Dos;
: : : VAR  hb, mb, sb, hsb: Word;
: : :      h, m, s, hs: Word;
: : : 
: : : 
: : : BEGIN
: : : ClrScr;
: : : GetTime(hb, mb, sb, hsb);
: : : Repeat
: : : GotoXY(1, 1);
: : :           GetTime(h, m, s, hs);
: : :           write(m,':', s,':', hs);
: : : UNTIL Keypressed;
: : : GotoXY(10,10);
: : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: : : Readln;
: : : END.
: : : 

: : :
: : 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
: :
: : 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
: :
:
: So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
:
You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
  GetTime(hb, mb, sb, hsb);
  Repeat
  UNTIL Keypressed;
  GetTime(h, m, s, hs);
  GotoXY(10,10);
  Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);

The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
Report
Re: Timer2 Posted by NinthAngle on 30 Aug 2005 at 5:23 PM
: : : : when I run this bit of code, there are two things that baffle me.
: : : : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
: : : : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
: : : :
: : : :
: : : :
: : : : PROGRAM Time;
: : : : USES Crt, Dos;
: : : : VAR  hb, mb, sb, hsb: Word;
: : : :      h, m, s, hs: Word;
: : : : 
: : : : 
: : : : BEGIN
: : : : ClrScr;
: : : : GetTime(hb, mb, sb, hsb);
: : : : Repeat
: : : : GotoXY(1, 1);
: : : :           GetTime(h, m, s, hs);
: : : :           write(m,':', s,':', hs);
: : : : UNTIL Keypressed;
: : : : GotoXY(10,10);
: : : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: : : : Readln;
: : : : END.
: : : : 

: : : :
: : : 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
: : :
: : : 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
: : :
: :
: : So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
: :
: You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
:
:   GetTime(hb, mb, sb, hsb);
:   Repeat
:   UNTIL Keypressed;
:   GetTime(h, m, s, hs);
:   GotoXY(10,10);
:   Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: 

: The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
:

1) If the clock increments ever 20milliseconds, then why does my timer display 2 seconds and 57milliseconds? (0:2:57)

2)How does one clear the keyboard buffer?

3) Is there any way around the monitor refreshments which create those annoying 655's or 654's?

Report
Re: Timer2 Posted by Phat Nat on 30 Aug 2005 at 7:00 PM
: 2)How does one clear the keyboard buffer?
:
: 3) Is there any way around the monitor refreshments which create those annoying 655's or 654's?


To clear the keyboard buffer, use READKEY. readkey is a function, so you can call it with or without a variable assignment. To just clear the buffer, call READKEY. To find out what key was pressed, use:
VAR
   key : Char;
Begin
     Repeat
           If Keypressed Then
              Key := Readkey;
           GotoXY(1,1); Write(ORD(Key));
     Until Key = #13;
End.

This will repeat until you press ENTER.

As for the flickering 655s, try using a DELAY(1); after the Write procedure.

Report
Re: Timer2 Posted by Phat Nat on 30 Aug 2005 at 7:06 PM
: You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
:
:   GetTime(hb, mb, sb, hsb);
:   Repeat
:   UNTIL Keypressed;
:   GetTime(h, m, s, hs);
:   GotoXY(10,10);
:   Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: 

: The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
:

That's why I prefer to use the clock in memory. It is just a continuous counter, so you don't need to take into account minutes, hours, etc passing by. Just subtract the 2 numbers and you have a value. If you want actual time, divide the value by 18.2

VAR
   TimeStart,
   TimeEnd    : LongInt;
Begin
     Move(Mem[$0040:$006C],TimeStart,4);

     { BLAH BLAH BLAH, do some stuff here }

     Move(Mem[$0040:$006C],TimeEnd,4);
     WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
     WriteLn('Total Time Taken  : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
End.


Phat Nat

Report
Re: Timer2 Posted by NinthAngle on 31 Aug 2005 at 11:34 AM
: : You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
: :
: :   GetTime(hb, mb, sb, hsb);
: :   Repeat
: :   UNTIL Keypressed;
: :   GetTime(h, m, s, hs);
: :   GotoXY(10,10);
: :   Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
: : 

: : The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
: :
:
: That's why I prefer to use the clock in memory. It is just a continuous counter, so you don't need to take into account minutes, hours, etc passing by. Just subtract the 2 numbers and you have a value. If you want actual time, divide the value by 18.2
:
:
: VAR
:    TimeStart,
:    TimeEnd    : LongInt;
: Begin
:      Move(Mem[$0040:$006C],TimeStart,4);
: 
:      { BLAH BLAH BLAH, do some stuff here }
: 
:      Move(Mem[$0040:$006C],TimeEnd,4);
:      WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
:      WriteLn('Total Time Taken  : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
: End.
: 

:
: Phat Nat
:
:


I tried your code and it works, but inconsistently... I dont understand why, sometimes, the time it takes is .99seconds, sometimes 1.10 seconds and sometimes .70 seconds etc, even though the delay is always consistent???

PROGRAM Time;
USES Crt;
VAR
   TimeStart,
   TimeEnd    : LongInt;

Begin
     Move(Mem[$0040:$006C],TimeStart,4);

     { BLAH BLAH BLAH, do some stuff here }
       ClrScr;
       Delay(1000);

     Move(Mem[$0040:$006C],TimeEnd,4);
     WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
     WriteLn('Total Time Taken  : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
     Readln;
End.




 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.