Adds epiktimer

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@453 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2008-05-22 12:20:58 +00:00
parent c7b306fc4e
commit bfef8f4584
18 changed files with 2882 additions and 0 deletions

View File

@ -0,0 +1,31 @@
Change log
Initially written on 24-06-2003 TL
Pre-release 30-06-2003 TL - Needs testing on the BSD's and Win32
1-7-2003 TL
Version 0.1 initial beta release
3-7-2003 TL
Version 0.2
Revised logic around hardware detection to prevent executing extended
instructions if the HasCapabilityData call returns false. Removed
exposed low level diagnositic functions from unit interface.
Revised demo.
15-11-2005
Version 0.3
Updated 0.2 version to make it compile on the latest Lazarus (0.9.10).
Added LCL to te required packages.
Changed mode to Delphi in order to compile.
Changed windows timebase to use QueryPerformanceCounter, because has a
much greater precision then GetSystemTime.
Added changes to ensure the component compiles on Delphi 7.0
Made tests on Windows and Linux
06-10-2006
Version 1.0
Changes for 64 bits operation
Added units BaseUnix, Unix and UnixUtil, removed oldlinux (obsolete)
Gettimeofday -> fpGettimeofday
Changed systemsleep for 64 bits systems
Some changes in timeval
Tested on AMD64 (linux)

View File

@ -0,0 +1,128 @@
Description: Precision timer/stopwatch component for Lazarus/FPC
Author: Tom Lisjac <netdxr@gmail.com>
Contributors:
* Felipe Monteiro de Carvalho <felipemonteiro.carvalho@gmail.com>
* Marcel Minderhoud
License: Modifyed LGPL (The same as Free Pascal RTL and LCL)
Copyright (C) 2003-2006 by Tom Lisjac, Felipe Monteiro de Carvalho and Marcel Minderhoud
Latest version can be obtained at: http://wiki.lazarus.freepascal.org/EpikTimer
Contents:
1. The EpikTimer.pas component and palette icon
2. ETPackage.lpk package for installation
3. ETDemo demonstration app and host system clock evaluator
-----------------------------------------------------------------
The EpikTimer Component
Documentation:
See epiktimer.pas for detailed discussion of timebase sources, timing
accuracy and clock correlation techniques that can provide traceable
precision during long term measurements.
Installation:
- In Components/Open Package File, open etpackage.lpk.
- Compile the component to verify that everything is there.
- Install and let Lazarus rebuild
- Component will be in the System Palette (stopwatch-ruler icon)
Usage:
Drop the component on a form. The component contains a single timer
instance and parameterless calls to start, stop, elapsed and clear
will implicitly reference it. If the timer is named ET:
Procedure InstrumentedCall;
Begin
ET.Clear; // optional... timer is cleared at creation
ET.Start;
ExecuteFirstTimedSection;
ET.Stop; // the timer is actually paused and can be restarted later
TimedSection1:=ET.Elapsed; // store the elapsed in a global
MakeAnUntimedOverheadCall; // not counted in the timer
ET.Start; //resume the timer... continue accumulating ticks
CallTimedSection2;
TimedSection2:=ET.Elapsed; //timer keeps running... we've just sample it.
CallTimedSection3;
CallSomethingElse;
TimedSection3:=ET.Elapsed; //keep counting... tap the elapsed
CallTimedSection4;
TimedSection4:=ET.Elapsed; //keep counting... tap the elapsed
ET.clear // done... timer is stopped and zeroed
end;
You can also create any number of timers from a single component on
the form by declaring a TimerData record and passing it as a parameter
to start, stop, elapsed and clear using the overloaded methods in the
component. An example would be:
Function TimedExecution:Extended;
Var DiskAccessTime:TimerData;
Begin
ET.Clear(DiskAccessTimer); // Declared timers *must* be cleared before use.
ET.Start(DiskAccessTimer);
ExecuteTheTimedSection;
Result:=ET.Elapsed(DiskAccessTimer); // the timer keeps running...
etc...
See etdemo.pas for additional examples of component usage
The ETDemo Application
The ETDemo application does not require EpikTimer to be installed in order
to compile and operate. I never liked having to install a palette full of
components only to find out that I didn't like any of them! :)
Installation
Open etdemo.lpi and compile it.
Operation
As the program comes up, it will create and initialize 10 invisible timer
forms that can be spawned from the main program's Stopwatch group box. A
progress bar is supposed to reduce the boredom.
Host Hardware Information
This group evaluates the host system and reports if it finds hardware
support for the Pentium Time Stamp Counter. If so, you'll be able to get
a snapshot of it's value along with the microsecond ticks from your
OS clock. The sizes of the hardware and system ticks isn't as important
as the rates that they change. On a Linux system, the system ticks value
represent microseconds of Epoch time.
Timebase Calibration
If your system lacks the TSC or a microsecond resolution system clock,
EpikTimer falls back to using gated measurements for setting the
internal tick frequencies. Timing is non-deterministic when calling
the Linux kernel so some averaging and smoothing of the resulting jitter
is helpful. If EpikTimer is in this mode, long term accuracy isn't
guaranteed... but short term comparitive measurements can still be made.
Pressing "Calibrate" performs overhead extraction and gates the selected
timebase against the best timebase gate available on a given host. The
results are displayed in the memo boxes.
Timebase Correlation
This is the default mode for measuring the TSC frequency and provides a
reliable mechanism for synchronizing the TSC ticks to the system clock.
If the system clock is maintained via NTP and the CorrelateTimebases
method is called at regular intervals, the TSC stream can display the
same long term accuracy (at very high resolutions) as the quality of
the system's synchronizing time source.
Timer/Stopwatch Functions
This section implements a single stopwatch using the component's internal
timer data record. The Spawn Timers group box will bring up the 10 timers
that were created and initialized during program startup.
----------------- End of EpikTimer Release Documentation ------------------

View File

@ -0,0 +1,15 @@
LazarusResources.Add('tepiktimer','XPM',[
'/* XPM */'#10'static char * tepiktimer_xpm[] = {'#10'"22 23 8 1",'#10'" '#9
+'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #7F7F7F",'#10'"@'#9'c #FFFFFF",'
+#10'"#'#9'c #BFBFBF",'#10'"$'#9'c #FF0000",'#10'"%'#9'c #101010",'#10'"&'#9
+'c #FEF900",'#10'" ...... ",'#10'" +@..@+ ",'#10
+'" .. ...... .. ",'#10'" .#@...######...@#. ",'#10'" .+..++@@$$@@'
+'++..+. ",'#10'" ..+@@@@$$@@@@+.. ",'#10'" .+@.@@@@@@@@@@+. ",'#10
+'" .+@@.@@@@@@.@@+. ",'#10'" .+@@@@.@@@@.@@@@+. ",'#10'" .+@@@@@.@@.@'
+'@@@@+. ",'#10'" .#$$@@@@..@@@@$$#. ",'#10'" .#$$@@@@..@@@@$$#. ",'#10
+'" .+@@@@@@@@@@@@@@+. ",'#10'" .+@@@@@@@@@@@@@@+. ",'#10'"%%%%%%%%%%%%%%'
+'%%%%%%%%",'#10'"%&.&&.&&.&&.&&.&&.&&&%",'#10'"%&.&&.&&.&&.&&.&&.&&&%",'#10
+'"%&.&&.&&.&&.&&.&&.&&&%",'#10'"%&&&&.&&&&&.&&&&&.&&&%",'#10'"%&&&&.&&&&&.&&'
+'&&&.&&&%",'#10'"%&&&&&&&&&&&&&&&&&&&&%",'#10'"%%%%%%%%%%%%%%%%%%%%%%",'#10
+'" "};'#10
]);

View File

@ -0,0 +1,802 @@
unit EpikTimer;
{ Name: EpikTimer
Description: Precision timer/stopwatch component for Lazarus/FPC
Author: Tom Lisjac <netdxr@gmail.com>
Started on: June 24, 2003
Features:
Dual selectable timebases: Default:System (uSec timeofday or "now" in Win32)
Optional: Pentium Time Stamp Counter.
Default timebase should work on most Unix systems of any architecture.
Timebase correlation locks time stamp counter accuracy to system clock.
Timers can be started, stopped, paused and resumed.
Unlimited number of timers can be implemented with one component.
Low resources required: 25 bytes per timer; No CPU overhead.
Internal call overhead compensation.
System sleep function
Designed to support multiple operating systems and Architectures
Designed to support other hardware tick sources
Credits: Thanks to Martin Waldenburg for a lot of great ideas for using
the Pentium's RDTSC instruction in wmFastTime and QwmFastTime.
}
{ Copyright (C) 2003-2006 by Tom Lisjac <netdxr@gmail.com>,
Felipe Monteiro de Carvalho and Marcel Minderhoud
This library is licensed on the same Modifyed LGPL as Free Pascal RTL and LCL are
Please contact the author if you'd like to use this component but the Modifyed LGPL
doesn't work with your project licensing.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
Contributor(s):
* Felipe Monteiro de Carvalho (felipemonteiro.carvalho@gmail.com)
* Marcel Minderhoud
}
{
Known Issues
- Tested on Linux but no other Lazarus/FPC supported Unix platforms
- If system doesn't have microsecond system clock resolution, the component
falls back to a single gated measurement of the hardware tick frequency via
nanosleep. This usually results in poor absolute accuracy due large amounts
of jitter in nanosleep... but for typical short term measurements, this
shouldn't be a problem.
}
{$IFDEF FPC}
{$MODE DELPHI}{$H+}
{$ENDIF}
{$IFNDEF FPC}
{$DEFINE Windows}
{$ENDIF}
{$IFDEF Win32}
{$DEFINE Windows}
{$ENDIF}
interface
uses
{$IFDEF Windows}
Windows, MMSystem,
{$ELSE}
baseunix, unix, unixutil,
{$ENDIF}
{$IFDEF FPC}
LResources,
{$ENDIF}
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, dateutils;
Const
DefaultSystemTicksPerSecond = 1000000; //Divisor for microsecond resolution
{ HW Tick frequency falls back to gated measurement if the initial system
clock measurement is outside this range plus or minus.}
SystemTicksNormalRangeLimit = 100000;
type
TickType = Int64; // Global declaration for all tick processing routines
FormatPrecision = 1..12; // Number of decimal places in elapsed text format
// Component powers up in System mode to provide some cross-platform safety.
TickSources = (SystemTimebase, HardwareTimebase); // add others if desired
(* * * * * * * * * * * Timebase declarations * * * * * * * * * * *)
{ There are two timebases currently implemented in this component but others
can be added by declaring them as "TickSources", adding a TimebaseData
variable to the Private area of TEpikTimer and providing a "Ticks" routine
that returns the current counter value.
Timebases are "calibrated" during initialization by taking samples of the
execution times of the SystemSleep and Ticks functions measured with in the
tick period of the selected timebase. At runtime, these values are retrieved
and used to remove the call overhead to the best degree possible.
System latency is always present and contributes "jitter" to the edges of
the sample measurements. This is especially true if a microsecond system
clock isn't detected on the host system and a fallback gated measurement
(based on nanosleep in Linux and sleep in Win32) is used to determine the
timebase frequency. This is sufficient for short term measurements where
high resolution comparisons are desired... but over a long measurement
period, the hardware and system wall clock will diverge significantly.
If a microsecond system clock is found, timebase correlation is used to
synchronize the hardware counter and system clock. This is described below.
}
TickCallFunc = function: Ticktype; // Ticks interface function
// Contains timebase overhead compensation factors in ticks for each timebase
TimebaseCalibrationParameters = record
FreqCalibrated: Boolean; // Indicates that the tickfrequency has been calibrated
OverheadCalibrated: Boolean; // Indicates that all call overheads have been calibrated
TicksIterations: Integer; // number of iterations to use when measuring ticks overhead
SleepIterations: Integer; // number of iterations to use when measuring SystemSleep overhead
FreqIterations: Integer; // number of iterations to use when measuring ticks frequency
FrequencyGateTimeMS: Integer; // gate time to use when measuring ticks frequency
end;
// This record defines the Timebase context
TimebaseData = record
CalibrationParms: TimebaseCalibrationParameters; // Calibration data for this timebase
TicksFrequency: TickType; // Tick frequency of this timebase
TicksOverhead: Ticktype; // Ticks call overhead in TicksFrequency for this timebase
SleepOverhead: Ticktype; // SystemSleep all overhead in TicksFrequency for this timebase
Ticks: TickCallFunc; // all methods get their ticks from this function when selected
end;
TimeBaseSelector = ^TimebaseData;
(* * * * * * * * * * * Timebase Correlation * * * * * * * * * * *)
{ The TimeBaseCorrelation record stores snapshot samples of both the system
ticks (the source of known accuracy) and the hardware tick source (the
source of high measurement resolution). An initial sample is taken at power
up. The CorrelationMode property sets where and when updates are acquired.
When an update snapshot is acquired, the differences between it and the
startup value can be used to calculate the hardware clock frequency with
high precision from the accuracy of the accumulated system clocks. The
longer time that elapses between startup and a call to "CorrelateTimebases",
the better the accuracy will be. On a 1.6 Ghz P4, it only takes a few
seconds to achieve measurement certainty down to a few Hertz.
Of course this system is only as good as your system clock accuracy, so
it's a good idea to periodically sync it with NTP or against another source
of known accuracy if you want to maximize the long term of the timers. }
TimebaseCorrelationData = record
SystemTicks: TickType;
HWTicks: TickType;
end;
// If the Correlation property is set to automatic, an update sample is taken
// anytime the user calls Start or Elapsed. If in manual, the correlation
// update is only done when "CorrelateTimebases" is called. Doing updates
// with every call adds a small amount of overhead... and after the first few
// minutes of operation, there won't be very much correcting to do!
CorrelationModes=(Manual, OnTimebaseSelect, OnGetElapsed);
(* * * * * * * * * * * Timer Data record structure * * * * * * * * * * *)
// This is the timer data context. There is an internal declaration of this
// record and overloaded methods if you only want to use the component for a
// single timer... or you can declare multiple TimerData records in your
// program and create as many instances as you want with only a single
// component on the form. See the "Stopwatch" methods in the TEpikTimer class.
// Each timers points to the timebase that started it... so you can mix system
// and hardware timers in the same application.
TimerData = record
Running:Boolean; // Timer is currently running
TimebaseUsed:TimeBaseSelector; // keeps timer aligned with the source that started it.
StartTime:TickType; // Ticks sample when timer was started
TotalTicks:TickType; // Total ticks... for snapshotting and pausing
end;
TEpikTimer= class(TComponent)
private
BuiltInTimer:TimerData; // Used to provide a single built-in timer;
FHWTickSupportAvailable:Boolean; // True if hardware tick support is available
FHWCapabilityDataAvailable:Boolean; // True if hardware tick support is available
FHWTicks:TimeBaseData; // The hardware timebase
FSystemTicks:TimeBaseData; // The system timebase
FSelectedTimebase:TimeBaseSelector; // Pointer to selected database
FTimeBaseSource: TickSources; // use hardware or system timebase
FWantDays: Boolean; // true if days are to be displayed in string returns
FWantMS: Boolean; // True to display milliseconds in string formatted calls
FSPrecision: FormatPrecision; // number of digits to display in string calls
FMicrosecondSystemClockAvailable:Boolean; // true if system has microsecond clock
StartupCorrelationSample:TimebaseCorrelationData; // Starting ticks correlation snapshot
UpdatedCorrelationSample:TimebaseCorrelationData; // Snapshot of last correlation sample
FCorrelationMode: CorrelationModes; // mode to control when correlation updates are performed
protected
function GetSelectedTimebase: TimebaseData;
procedure SetSelectedTimebase(const AValue: TimebaseData);
procedure SetTimebaseSource(const AValue: TickSources); //setter for TB
Procedure GetCorrelationSample(Var CorrelationData:TimeBaseCorrelationData);
public
{ Stopwatch emulation routines
These routines behave exactly like a conventional stopwatch with start,
stop, elapsed (lap) and clear methods. The timers can be started,
stopped and resumed. The Elapsed routines provide a "lap" time analog.
The methods are overloaded to make it easy to simply use the component's
BuiltInTimer as a single timer... or to declare your own TimerData records
in order to implement unlimited numbers of timers using a single component
on the form. The timers are very resource efficient because they consume
no CPU overhead and only require about 25 bytes of memory.
}
// Stops and resets the timer
procedure Clear; overload;// Call this routine to use the built-in timer record
procedure Clear(Var T:TimerData); overload; // pass your TimerData record to this one
//Start or resume a stopped timer
procedure Start; overload;
procedure Start(Var T:TimerData); overload;
//Stop or pause a timer
procedure Stop; overload;
procedure Stop(Var T:TimerData); overload;
//Return elapsed time in seconds as an extended type
function Elapsed:Extended; overload;
function Elapsed(var T: TimerData):Extended; overload;
//Return a string in Day:Hour:Minute:Second format. Milliseconds can be
//optionally appended via the WantMilliseconds property
function ElapsedDHMS:String; overload;
function ElapsedDHMS(var T: TimerData):String; overload;
//Return a string in the format of seconds.milliseconds
function ElapsedStr:String; overload;
function ElapsedStr(var T:TimerData):String; overload;
function WallClockTime:String; // Return time of day string from system time
//Overhead compensated system sleep to provide a best possible precision delay
function SystemSleep(Milliseconds: Integer):integer; Virtual;
//Diagnostic taps for development and fine grained timebase adjustment
property HWTimebase: TimeBaseData read FHWTicks write FHWTicks; // The hardware timebase
property SysTimebase: TimebaseData read FSystemTicks write FSystemTicks;
function GetHardwareTicks:TickType; // return raw tick value from hardware source
function GetSystemTicks:Ticktype; // Return system tick value(in microseconds of Epoch time)
function GetTimebaseCorrelation:TickType;
function CalibrateCallOverheads(Var TimeBase:TimebaseData) : Integer; Virtual;
function CalibrateTickFrequency(Var TimeBase:TimebaseData): Integer; Virtual;
property MicrosecondSystemClockAvailable:Boolean read FMicrosecondSystemClockAvailable;
property SelectedTimebase:TimebaseSelector read FSelectedTimebase write FSelectedTimebase;
property HWTickSupportAvailable:Boolean read FHWTickSupportAvailable;
property HWCapabilityDataAvailable:Boolean read FHWCapabilityDataAvailable;
procedure CorrelateTimebases; // Manually call to do timebase correlation snapshot and update
constructor Create(AOwner:TComponent); Override;
destructor Destroy; Override;
Published
property StringPrecision: FormatPrecision read FSPrecision write FSPrecision;
property WantMilliseconds: Boolean read FWantMS write FWantMS;
property WantDays: Boolean read FWantDays write FWantDays;
property TimebaseSource: TickSources read FTimeBaseSource write SetTimebaseSource;
property CorrelationMode:CorrelationModes read FCorrelationMode write FCorrelationMode;
end;
procedure Register;
implementation
(* * * * * * * * * * * * * * Timebase Section * * * * * * * * * * * * *)
{
There are two tick sources defined in this section. The first uses a hardware
source which, in this case, is the Pentium's internal 64 Time Stamp Counter.
The second source (the default) uses the given environment's most precision
"timeofday" system call so it can work across OS platforms and architectures.
The hardware timer's accuracy depends on the frequency of the timebase tick
source that drives it... in other words, how many of the timebase's ticks
there are in a second. This frequency is measured by capturing a sample of the
timebase ticks for a known period against a source of known accuracy. There
are two ways to do this.
The first is to capture a large sample of ticks from both the unknown and
known timing sources. Then the frequency of the unknown tick stream can be
calculated by: UnknownSampleTicks / (KnownSampleTicks / KnownTickFrequency).
Over a short period of time, this can provide a precise synchronization
mechanism that effectively locks the measurements taken with the high
resolution source to the known accuracy of the system clock.
The first method depends on the existance of an accurate system time source of
microsecond resolution. If the host system doesn't provide this, the second
fallback method is to gate the unknown tick stream by a known time. This isn't
as good because it usually involves calling a system "delay" routine that
usually has a lot of overhead "jitter" and non-deterministic behavior. This
approach is usable, however, for short term, high resolution comparisons where
absolute accuracy isn't important.
}
(* * * * * * * * Start of i386 Hardware specific code * * * * * * *)
{$IFDEF CPUI386}
{ Some references for this section can be found at:
http://www.sandpile.org/ia32/cpuid.htm
http://www.sandpile.org/ia32/opc_2.htm
http://www.sandpile.org/ia32/msr.htm
}
// Pentium specific... push and pop the flags and check for CPUID availability
function HasHardwareCapabilityData: Boolean;
begin
asm
PUSHFD
POP EAX
MOV EDX,EAX
XOR EAX,$200000
PUSH EAX
POPFD
PUSHFD
POP EAX
XOR EAX,EDX
JZ @EXIT
MOV AL,TRUE
@EXIT:
end;
end;
function HasHardwareTickCounter: Boolean;
var FeatureFlags: Longword;
begin
FeatureFlags:=0;
asm
PUSH EBX
XOR EAX,EAX
DW $A20F
POP EBX
CMP EAX,1
JL @EXIT
XOR EAX,EAX
MOV EAX,1
PUSH EBX
DW $A20F
MOV FEATUREFLAGS,EDX
POP EBX
@EXIT:
end;
Result := (FeatureFlags and $10) <> 0;
end;
// Execute the Pentium's RDTSC instruction to access the counter value.
function HardwareTicks: TickType; assembler; asm DW 0310FH end;
(* * * * * * * * End of i386 Hardware specific code * * * * * * *)
// These are here for architectures that don't have a precision hardware
// timing source. They'll return zeros for overhead values. The timers
// will work but there won't be any error compensation for long
// term accuracy.
{$ELSE} // add other architectures and hardware specific tick sources here
function HasHardwareCapabilityData: Boolean; begin Result:=False end;
function HasHardwareTickCounter: Boolean; begin Result:=false end;
function HardwareTicks:TickType; begin result:=0 end;
{$ENDIF}
function NullHardwareTicks:TickType; begin Result:=0 end;
// Return microsecond normalized time source for a given platform.
// This should be sync'able to an external time standard (via NTP, for example).
function SystemTicks: TickType;
{$IFDEF Windows}
begin
QueryPerformanceCounter(Result);
//Result := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)) * 1000) // an alternative Win32 timebase
{$ELSE}
var t : timeval;
begin
fpgettimeofday(@t,nil);
// Build a 64 bit microsecond tick from the seconds and microsecond longints
Result := (TickType(t.tv_sec) * 1000000) + t.tv_usec;
{$ENDIF}
end;
function TEpikTimer.SystemSleep(Milliseconds: Integer):Integer;
{$IFDEF Windows}
begin
Sleep(Milliseconds);
Result := 0;
end;
{$ELSE}
{$IFDEF CPUX86_64}
begin
Sleep(Milliseconds);
Result := 0;
end;
{$ELSE}
var
timerequested, timeremaining: timespec;
begin
// This is not a very accurate or stable gating source... but it's the
// only one that's available for making short term measurements.
timerequested.tv_sec:=Milliseconds div 1000;
timerequested.tv_nsec:=(Milliseconds mod 1000) * 1000000;
Result := fpnanosleep(@timerequested, @timeremaining) // returns 0 if ok
end;
{$ENDIF}
{$ENDIF}
function TEpikTimer.GetHardwareTicks: TickType;
begin
Result:=FHWTicks.Ticks();
end;
function TEpikTimer.GetSystemTicks: Ticktype;
begin
Result:=FSystemTicks.Ticks();
end;
procedure TEpikTimer.SetTimebaseSource(const AValue: TickSources);
procedure UseSystemTimer;
begin
FTimeBaseSource := SystemTimebase;
SelectedTimebase := @FSystemTicks;
end;
begin
case AValue of
HardwareTimebase:
try
if HWTickSupportAvailable then
begin
SelectedTimebase:=@FHWTicks;
FTimeBaseSource:=HardwareTimebase;
If CorrelationMode<>Manual then CorrelateTimebases
end
except // If HW init fails, fall back to system tick source
UseSystemTimer
end;
SystemTimeBase: UseSystemTimer
end
end;
function TEpikTimer.GetSelectedTimebase: TimebaseData;
begin
Result := FSelectedTimebase^;
end;
procedure TEpikTimer.SetSelectedTimebase(const AValue: TimebaseData);
begin
FSelectedTimebase^ := AValue;
end;
(* * * * * * * * * * Time measurement core routines * * * * * * * * * *)
procedure TEpikTimer.Clear(var T: TimerData);
begin
with T do
begin
Running:=False; StartTime:=0; TotalTicks:=0; TimeBaseUsed:=FSelectedTimebase
end;
end;
procedure TEpikTimer.Start(var T: TimerData);
begin
if not T.running then
With FSelectedTimebase^ do
begin
T.StartTime:=Ticks()-TicksOverhead;
T.TimebaseUsed:=FSelectedTimebase;
T.Running:=True
end
end;
procedure TEpikTimer.Stop(var T: TimerData);
Var CurTicks:TickType;
Begin
if T.Running then
With T.TimebaseUsed^ do
Begin
CurTicks:=Ticks()-TicksOverhead; // Back out the call overhead
T.TotalTicks:=(CurTicks - T.Starttime)+T.TotalTicks; T.Running:=false
end
end;
function TEpikTimer.Elapsed(var T: TimerData): Extended;
var
CurTicks: TickType;
begin
With T.TimebaseUsed^ do
if T.Running then
Begin
CurTicks:=Ticks()-TicksOverhead; // Back out the call overhead
If CorrelationMode>OnTimebaseSelect then CorrelateTimebases;
Result := ((CurTicks - T.Starttime)+T.TotalTicks) / TicksFrequency
End
Else Result := T.TotalTicks / TicksFrequency;
end;
(* * * * * * * * * * Output formatting routines * * * * * * * * * *)
function TEpikTimer.ElapsedDHMS(var T: TimerData): String;
var
Tmp, MS: extended;
D, H, M, S: Integer;
P, SM: string;
begin
Tmp := Elapsed(T);
P := inttostr(FSPrecision);
MS := frac(Tmp); SM:=format('%0.'+P+'f',[MS]); delete(SM,1,1);
D := trunc(Tmp / 84600); Tmp:=Trunc(tmp) mod 84600;
H := trunc(Tmp / 3600); Tmp:=Trunc(Tmp) mod 3600;
M := Trunc(Tmp / 60); S:=(trunc(Tmp) mod 60);
If FWantDays then
Result := format('%2.3d:%2.2d:%2.2d:%2.2d',[D,H,M,S])
else
Result := format('%2.2d:%2.2d:%2.2d',[H,M,S]);
If FWantMS then Result:=Result+SM;
end;
function TEpikTimer.ElapsedStr(var T: TimerData): string;
begin
Result := format('%.'+inttostr(FSPrecision)+'f',[Elapsed(T)]);
end;
function TEpikTimer.WallClockTime: string;
var
Y, D, M, hour, min, sec, ms, us: Word;
{$IFNDEF Windows}
t: timeval;
{$ENDIF}
begin
{$IFDEF Windows}
DecodeDatetime(Now, Y, D, M, Hour, min, Sec, ms);
us:=0;
{$ELSE}
// "Now" doesn't report milliseconds on Linux... appears to be broken.
// I opted for this approach which also provides microsecond precision.
fpgettimeofday(@t,nil);
EpochToLocal(t.tv_sec, Y, M, D, hour, min, sec);
ms:=t.tv_usec div 1000; us:=t.tv_usec mod 1000;
{$ENDIF}
Result:='';
If FWantDays then
Result := Format('%4.4d/%2.2d/%2.2d-',[Y,M,D]);
Result := Result + Format('%2.2d:%2.2d:%2.2d',[hour,min,sec]);
If FWantMS then
Result := Result + Format('.%3.3d%3.3d',[ms,us])
end;
(* * * Overloaded methods to use the component's internal timer data * * *)
procedure TEpikTimer.Clear; begin Clear(BuiltInTimer) end;
procedure TEpikTimer.Start; begin Start(BuiltInTimer) end;
procedure TEpikTimer.Stop; Begin Stop(BuiltInTimer) End;
function TEpikTimer.Elapsed: Extended; begin Result:=Elapsed(BuiltInTimer) end;
function TEpikTimer.ElapsedStr: String; Begin Result:=ElapsedStr(BuiltInTimer) end;
function TEpikTimer.ElapsedDHMS: String; begin Result:=ElapsedDHMS(BuiltInTimer) end;
(* * * * * * * * * * Timebase calibration section * * * * * * * * * *)
// Set up compensation for call overhead to the Ticks and SystemSleep functions.
// The Timebase record contains Calibration parameters to be used for each
// timebase source. These have to be unique as the output of this measurement
// is measured in "ticks"... which are different periods for each timebase.
function TEpikTimer.CalibrateCallOverheads(Var Timebase:TimebaseData):Integer;
var i:Integer; St,Fin,Total:TickType;
begin
with Timebase, Timebase.CalibrationParms do
begin
Total:=0; Result:=1;
for I:=1 to TicksIterations do // First get the base tick getting overhead
begin
St:=Ticks(); Fin:=Ticks();
Total:=Total+(Fin-St); // dump the first sample
end;
TicksOverhead:=Total div TicksIterations;
Total:=0;
For I:=1 to SleepIterations do
Begin
St:=Ticks();
if SystemSleep(0)<>0 then exit;
Fin:=Ticks();
Total:=Total+((Fin-St)-TicksOverhead);
End;
SleepOverhead:=Total div SleepIterations;
OverheadCalibrated:=True; Result:=0
End
end;
// CalibrateTickFrequency is a fallback in case a microsecond resolution system
// clock isn't found. It's still important because the long term accuracy of the
// timers will depend on the determination of the tick frequency... in other words,
// the number of ticks it takes to make a second. If this measurement isn't
// accurate, the counters will proportionately drift over time.
//
// The technique used here is to gate a sample of the tick stream with a known
// time reference which, in this case, is nanosleep. There is a *lot* of jitter
// in a nanosleep call so an attempt is made to compensate for some of it here.
function TEpikTimer.CalibrateTickFrequency(Var Timebase:TimebaseData):Integer;
var
i: Integer;
Total, SS, SE: TickType;
ElapsedTicks, SampleTime: Extended;
begin
With Timebase, Timebase.CalibrationParms do
Begin
Result:=1; //maintain unitialized default in case something goes wrong.
Total:=0;
For i:=1 to FreqIterations do
begin
SS:=Ticks();
SystemSleep(FrequencyGateTimeMS);
SE:=Ticks();
Total:=Total+((SE-SS)-(SleepOverhead+TicksOverhead))
End;
//doing the floating point conversion allows SampleTime parms of < 1 second
ElapsedTicks:=Total div FreqIterations;
SampleTime:=FrequencyGateTimeMS;
TicksFrequency:=Trunc( ElapsedTicks / (SampleTime / 1000));
FreqCalibrated:=True;
end;
end;
// Grab a snapshot of the system and hardware tick sources... as quickly as
// possible and with overhead compensation. These samples will be used to
// correct the accuracy of the hardware tick frequency source when precision
// long term measurements are desired.
procedure TEpikTimer.GetCorrelationSample(var CorrelationData: TimeBaseCorrelationData);
Var
TicksHW, TicksSys: TickType;
THW, TSYS: TickCallFunc;
begin
THW:=FHWTicks.Ticks; TSYS:=FSystemTicks.Ticks;
TicksHW:=THW(); TicksSys:=TSYS();
With CorrelationData do
Begin
SystemTicks:= TicksSys-FSystemTicks.TicksOverhead;
HWTicks:=TicksHW-FHWTicks.TicksOverhead;
End
end;
(* * * * * * * * * * Timebase correlation section * * * * * * * * * *)
{ Get another snapshot of the system and hardware tick sources and compute a
corrected value for the hardware frequency. In a short amount of time, the
microsecond system clock accumulates enough ticks to perform a *very*
accurate frequency measurement of the typically picosecond time stamp counter. }
Function TEpikTimer.GetTimebaseCorrelation:TickType;
Var
HWDiff, SysDiff, Corrected: Extended;
begin
If HWtickSupportAvailable then
Begin
GetCorrelationSample(UpdatedCorrelationSample);
HWDiff:=UpdatedCorrelationSample.HWTicks-StartupCorrelationSample.HWTicks;
SysDiff:=UpdatedCorrelationSample.SystemTicks-StartupCorrelationSample.SystemTicks;
Corrected:=HWDiff / (SysDiff / DefaultSystemTicksPerSecond);
Result:=trunc(Corrected)
End
else result:=0
end;
{ If an accurate reference is available, update the TicksFrequency of the
hardware timebase. }
procedure TEpikTimer.CorrelateTimebases;
begin
If MicrosecondSystemClockAvailable and HWTickSupportAvailable then
FHWTicks.TicksFrequency:=GetTimebaseCorrelation
end;
(* * * * * * * * Initialization: Constructor and Destructor * * * * * * *)
constructor TEpikTimer.Create(AOwner: TComponent);
Procedure InitTimebases;
Begin
{ Tick frequency rates are different for the system and HW timebases so we
need to store calibration data in the period format of each one. }
FSystemTicks.Ticks:=@SystemTicks; // Point to Ticks routine
With FSystemTicks.CalibrationParms do
Begin
FreqCalibrated:=False;
OverheadCalibrated:=False;
TicksIterations:=5;
SleepIterations:=10;
FrequencyGateTimeMS:=100;
FreqIterations:=1;
End;
// Initialize the HW tick source data
FHWCapabilityDataAvailable:=False;
FHWTickSupportAvailable:=False;
FHWTicks.Ticks:=@NullHardwareTicks; // returns a zero if no HW support
FHWTicks.TicksFrequency:=1;
With FHWTicks.CalibrationParms do
Begin
FreqCalibrated:=False;
OverheadCalibrated:=False;
TicksIterations:=10;
SleepIterations:=20;
FrequencyGateTimeMS:=150;
FreqIterations:=1;
End;
if HasHardwareCapabilityData then
Begin
FHWCapabilityDataAvailable:=True;
If HasHardwareTickCounter then
Begin
FHWTicks.Ticks:=@HardwareTicks;
FHWTickSupportAvailable:=CalibrateCallOverheads(FHWTicks)=0
End
end;
CalibrateCallOverheads(FSystemTicks);
CalibrateTickFrequency(FSystemTicks);
// Overheads are set... get starting timestamps for long term calibration runs
GetCorrelationSample(StartupCorrelationSample);
With FSystemTicks do
If (TicksFrequency>(DefaultSystemTicksPerSecond-SystemTicksNormalRangeLimit)) and
(TicksFrequency<(DefaultSystemTicksPerSecond+SystemTicksNormalRangeLimit)) then
Begin // We've got a good microsecond system clock
FSystemTicks.TicksFrequency:=DefaultSystemTicksPerSecond; // assume it's pure
FMicrosecondSystemClockAvailable:=True;
If FHWTickSupportAvailable then
Begin
SystemSleep(FHWTicks.CalibrationParms.FrequencyGateTimeMS); // rough gate
CorrelateTimebases
End
end
else
Begin
FMicrosecondSystemClockAvailable:=False;
If FHWTickSupportAvailable then
CalibrateTickFrequency(FHWTicks) // sloppy but usable fallback calibration
End;
End;
begin
inherited Create(AOwner);
StringPrecision:=6; FWantMS:=True; FWantDays:=True;
InitTimebases;
CorrelationMode:=OnTimebaseSelect;
// Default is the safe, cross-platform but less precise system timebase
TimebaseSource:=SystemTimebase;
Clear(BuiltInTimer)
end;
destructor TEpikTimer.Destroy;
begin
inherited Destroy;
// here in case we need to clean something up in a later version
end;
(* * * * * * * * * * * Register Component * * * * * * * * * * * *)
procedure Register;
begin
RegisterComponents('System', [TEpikTimer]);
end;
Initialization
{$IFDEF FPC}
{$I epiktimer.lrs}
{$ENDIF}
end.

View File

@ -0,0 +1,134 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="/"/>
<Version Value="5"/>
<General>
<MainUnit Value="0"/>
<IconPath Value="./"/>
<TargetFileExt Value=""/>
<Title Value="etdemo"/>
<ActiveEditorIndexAtStart Value="0"/>
</General>
<LazDoc Paths=""/>
<Units Count="9">
<Unit0>
<CursorPos X="10" Y="3"/>
<EditorIndex Value="0"/>
<Filename Value="etdemo.lpr"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<TopLine Value="1"/>
<UnitName Value="project1"/>
<UsageCount Value="25"/>
</Unit0>
<Unit1>
<CursorPos X="25" Y="182"/>
<EditorIndex Value="4"/>
<Filename Value="main.pas"/>
<ComponentName Value="Form1"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<ResourceFilename Value="main.lrs"/>
<TopLine Value="174"/>
<UnitName Value="main"/>
<UsageCount Value="20"/>
</Unit1>
<Unit2>
<CursorPos X="1" Y="563"/>
<EditorIndex Value="2"/>
<Filename Value="EpikTimer.pas"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<TopLine Value="550"/>
<UnitName Value="EpikTimer"/>
<UsageCount Value="20"/>
</Unit2>
<Unit3>
<CursorPos X="7" Y="6"/>
<EditorIndex Value="1"/>
<Filename Value="newsw.pas"/>
<ComponentName Value="Form2"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<ResourceFilename Value="newsw.lrs"/>
<TopLine Value="18"/>
<UnitName Value="newsw"/>
<UsageCount Value="20"/>
</Unit3>
<Unit4>
<CursorPos X="8" Y="7"/>
<EditorIndex Value="3"/>
<Filename Value="splash.pas"/>
<ComponentName Value="Form3"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<ResourceFilename Value="splash.lrs"/>
<TopLine Value="1"/>
<UnitName Value="splash"/>
<UsageCount Value="20"/>
</Unit4>
<Unit5>
<CursorPos X="14" Y="8"/>
<Filename Value="C:/Programas/lazarus_stable/fpcsrc/rtl/win32/windows.pp"/>
<TopLine Value="1"/>
<UnitName Value="windows"/>
<UsageCount Value="10"/>
</Unit5>
<Unit6>
<CursorPos X="8" Y="1"/>
<Filename Value="etpackage.pas"/>
<TopLine Value="1"/>
<UnitName Value="etpackage"/>
<UsageCount Value="10"/>
</Unit6>
<Unit7>
<CursorPos X="3" Y="21"/>
<Filename Value="home/felipe/Programa��o/OsciloscopioISA/principal.pas"/>
<ComponentName Value="frmPrincipal"/>
<HasResources Value="True"/>
<ResourceFilename Value="home/felipe/Programa��o/OsciloscopioISA/principal.lrs"/>
<TopLine Value="5"/>
<UnitName Value="principal"/>
<UsageCount Value="10"/>
</Unit7>
<Unit8>
<CursorPos X="12" Y="1495"/>
<Filename Value="usr/share/fpcsrc/rtl/unix/linuxold.inc"/>
<TopLine Value="1478"/>
<UsageCount Value="10"/>
</Unit8>
</Units>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
<MinVersion Major="1" Valid="True"/>
</Item1>
</RequiredPackages>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectOptions>
<CompilerOptions>
<Version Value="5"/>
<SearchPaths>
<SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,27 @@
program ETDemo;
{$mode objfpc}{$H+}
uses
Interfaces,
Forms, main, EpikTimer, newsw, splash;
var i:Integer;
begin
Application.Initialize;
Form3 := TForm3.Create(nil);
Try
Application.ProcessMessages;
Application.CreateForm(TForm1, Form1);
for i:=1 to MaxStopwatches do
Begin
Application.CreateForm(TForm2, NewStopwatches[i]);
Form3.Progressbar1.position:=i;
Application.ProcessMessages;
End;
Finally
Form3.free;
End;
Application.Run;
end.

View File

@ -0,0 +1,54 @@
<?xml version="1.0"?>
<CONFIG>
<Package Version="2">
<Name Value="etpackage"/>
<Author Value="Tom Lisjac <netdxr@gmail.com>"/>
<CompilerOptions>
<Version Value="5"/>
<SearchPaths>
<OtherUnitFiles Value="$(LazarusDir)/lcl/units/"/>
<UnitOutputDirectory Value="lib"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Description Value="EpikTimer elapsed time component
http://wiki.lazarus.freepascal.org/EpikTimer
"/>
<License Value="Modifyed LGPL
"/>
<Version Major="1"/>
<Files Count="2">
<Item1>
<Filename Value="epiktimer.lrs"/>
<Type Value="LRS"/>
</Item1>
<Item2>
<Filename Value="epiktimer.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="EpikTimer"/>
</Item2>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">
<Item1>
<PackageName Value="LCL"/>
</Item1>
<Item2>
<PackageName Value="FCL"/>
<MinVersion Major="1" Valid="True"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)/"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
</PublishOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,21 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit etpackage;
interface
uses
EpikTimer, LazarusPackageIntf;
implementation
procedure Register;
begin
RegisterUnit('EpikTimer', @EpikTimer.Register);
end;
initialization
RegisterPackage('etpackage', @Register);
end.

View File

@ -0,0 +1,34 @@
/* XPM */
static char * tepiktimer_xpm[] = {
"22 23 8 1",
" c None",
". c #000000",
"+ c #7F7F7F",
"@ c #FFFFFF",
"# c #BFBFBF",
"$ c #FF0000",
"% c #101010",
"& c #FEF900",
" ...... ",
" +@..@+ ",
" .. ...... .. ",
" .#@...######...@#. ",
" .+..++@@$$@@++..+. ",
" ..+@@@@$$@@@@+.. ",
" .+@.@@@@@@@@@@+. ",
" .+@@.@@@@@@.@@+. ",
" .+@@@@.@@@@.@@@@+. ",
" .+@@@@@.@@.@@@@@+. ",
" .#$$@@@@..@@@@$$#. ",
" .#$$@@@@..@@@@$$#. ",
" .+@@@@@@@@@@@@@@+. ",
" .+@@@@@@@@@@@@@@+. ",
"%%%%%%%%%%%%%%%%%%%%%%",
"%&.&&.&&.&&.&&.&&.&&&%",
"%&.&&.&&.&&.&&.&&.&&&%",
"%&.&&.&&.&&.&&.&&.&&&%",
"%&&&&.&&&&&.&&&&&.&&&%",
"%&&&&.&&&&&.&&&&&.&&&%",
"%&&&&&&&&&&&&&&&&&&&&%",
"%%%%%%%%%%%%%%%%%%%%%%",
" "};

View File

@ -0,0 +1,561 @@
object Form1: TForm1
BorderStyle = bsToolWindow
Caption = 'EpikTimer Component Test Application'
OnCreate = Form1CREATE
OnDestroy = Form1DESTROY
PixelsPerInch = 96
Position = poScreenCenter
ShowHint = True
HorzScrollBar.Page = 714
VertScrollBar.Page = 597
Left = 160
Height = 598
Top = 707
Width = 715
object Groupbox2: TGroupBox
Caption = 'Host Hardware Information'
ClientHeight = 77
ClientWidth = 691
ParentColor = True
ParentCtl3D = False
TabOrder = 0
Left = 10
Height = 95
Top = 50
Width = 695
object Label6: TLabel
Caption = 'Has CPUID: '
Color = clNone
Left = 13
Height = 17
Top = 4
Width = 140
end
object Label7: TLabel
Caption = 'Has Time Stamp Counter: '
Color = clNone
Left = 168
Height = 17
Top = 4
Width = 190
end
object Label9: TLabel
Caption = 'Time Stamp Value'
Color = clNone
Left = 133
Height = 17
Top = 55
Width = 120
end
object Label8: TLabel
Caption = 'System Ticks (in microseconds)'
Color = clNone
Left = 363
Height = 17
Top = 55
Width = 185
end
object Edit4: TEdit
TabOrder = 2
Left = 133
Height = 23
Top = 30
Width = 211
end
object Button6: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Get Time Stamp'
OnClick = Button6CLICK
ParentShowHint = False
ShowHint = True
TabOrder = 0
Left = 13
Height = 25
Hint = 'Gets the current value of the Pentium Time Stamp counter and the System ticks counter'
Top = 29
Width = 100
end
object Edit6: TEdit
TabOrder = 1
Left = 363
Height = 23
Top = 29
Width = 210
end
end
object Groupbox3: TGroupBox
Caption = 'Timer/Stopwatch Functions'
ClientHeight = 152
ClientWidth = 691
ParentColor = True
ParentCtl3D = False
TabOrder = 1
Left = 10
Height = 170
Top = 420
Width = 695
object Label3: TLabel
Caption = 'Elapsed seconds'
Color = clNone
Left = 323
Height = 17
Top = 35
Width = 115
end
object Label4: TLabel
Caption = 'Elapsed Day:H:M:S.ms'
Color = clNone
Left = 323
Height = 17
Top = 85
Width = 130
end
object Label5: TLabel
Caption = 'Precision'
Color = clNone
Left = 378
Height = 17
Top = 120
Width = 115
end
object Button2: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Start'
OnClick = Button2CLICK
TabOrder = 0
Left = 18
Height = 25
Top = 10
Width = 75
end
object Button3: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Stop'
OnClick = Button3CLICK
TabOrder = 1
Left = 18
Height = 25
Top = 80
Width = 75
end
object Button4: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Elapsed'
OnClick = Button4CLICK
TabOrder = 2
Left = 18
Height = 25
Top = 45
Width = 75
end
object Edit2: TEdit
TabOrder = 3
Left = 323
Height = 23
Top = 10
Width = 155
end
object Edit3: TEdit
TabOrder = 4
Left = 323
Height = 23
Top = 60
Width = 155
end
object Button5: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Clear'
OnClick = Button5CLICK
TabOrder = 5
Left = 18
Height = 25
Top = 115
Width = 75
end
object Checkbox2: TCheckBox
AllowGrayed = True
Caption = 'Want MS'
DragCursor = crDefault
OnClick = Checkbox2CLICK
TabOrder = 6
Left = 533
Height = 20
Top = 117
Width = 88
end
object Checkbox3: TCheckBox
AllowGrayed = True
Caption = 'Want Days'
DragCursor = crDefault
OnClick = Checkbox3CLICK
TabOrder = 7
Left = 443
Height = 20
Top = 118
Width = 88
end
object Combobox1: TComboBox
Items.Strings = (
'0'
'1'
'2'
'3'
'4'
'5'
'6'
)
ItemIndex = 0
MaxLength = 0
OnChange = Combobox1CHANGE
ParentCtl3D = False
Style = csDropDownList
TabOrder = 8
Text = '0'
Left = 323
Height = 21
Top = 114
Width = 50
end
object Edit5: TEdit
TabOrder = 11
Left = 103
Height = 23
Top = 10
Width = 205
end
object Edit8: TEdit
TabOrder = 13
Left = 103
Height = 23
Top = 45
Width = 205
end
object Edit11: TEdit
TabOrder = 9
Left = 103
Height = 23
Top = 80
Width = 205
end
object Edit1: TEdit
TabOrder = 10
Left = 103
Height = 23
Top = 115
Width = 205
end
object Groupbox1: TGroupBox
Caption = 'Spawn Timers'
ClientHeight = 77
ClientWidth = 187
ParentColor = True
ParentCtl3D = False
TabOrder = 12
Left = 492
Height = 95
Top = 10
Width = 191
object Button1: TButton
BorderSpacing.InnerBorder = 2
Caption = '1'
OnClick = Button1CLICK
TabOrder = 0
Left = 13
Height = 25
Top = 5
Width = 25
end
object Button9: TButton
BorderSpacing.InnerBorder = 2
Caption = '2'
OnClick = Button1CLICK
TabOrder = 1
Left = 46
Height = 25
Top = 5
Width = 25
end
object Button10: TButton
BorderSpacing.InnerBorder = 2
Caption = '3'
OnClick = Button1CLICK
TabOrder = 2
Left = 79
Height = 25
Top = 5
Width = 25
end
object Button11: TButton
BorderSpacing.InnerBorder = 2
Caption = '4'
OnClick = Button1CLICK
TabOrder = 3
Left = 112
Height = 25
Top = 5
Width = 25
end
object Button12: TButton
BorderSpacing.InnerBorder = 2
Caption = '5'
OnClick = Button1CLICK
TabOrder = 4
Left = 145
Height = 25
Top = 5
Width = 25
end
object Button13: TButton
BorderSpacing.InnerBorder = 2
Caption = '6'
OnClick = Button1CLICK
TabOrder = 5
Left = 13
Height = 25
Top = 45
Width = 25
end
object Button14: TButton
BorderSpacing.InnerBorder = 2
Caption = '7'
OnClick = Button1CLICK
TabOrder = 6
Left = 46
Height = 25
Top = 45
Width = 25
end
object Button15: TButton
BorderSpacing.InnerBorder = 2
Caption = '8'
OnClick = Button1CLICK
TabOrder = 7
Left = 79
Height = 25
Top = 45
Width = 25
end
object Button16: TButton
BorderSpacing.InnerBorder = 2
Caption = '9'
OnClick = Button1CLICK
TabOrder = 8
Left = 112
Height = 25
Top = 45
Width = 25
end
object Button17: TButton
BorderSpacing.InnerBorder = 2
Caption = '10'
OnClick = Button1CLICK
TabOrder = 9
Left = 145
Height = 25
Top = 45
Width = 25
end
end
end
object Groupbox4: TGroupBox
Caption = 'Timebase calibration'
ClientHeight = 252
ClientWidth = 691
ParentColor = True
ParentCtl3D = False
TabOrder = 2
Left = 10
Height = 270
Top = 150
Width = 695
object Label10: TLabel
Caption = 'SystemSleep(0)'
Color = clNone
Left = 114
Height = 17
Top = 130
Width = 120
end
object Label16: TLabel
Caption = 'Ticks'
Color = clNone
Left = 253
Height = 17
Top = 130
Width = 85
end
object Label17: TLabel
Caption = 'Ticks per second'
Color = clNone
Left = 334
Height = 17
Top = 130
Width = 95
end
object Label2: TLabel
Caption = 'Jitter (current-previous)'
Color = clNone
Left = 509
Height = 17
Top = 130
Width = 130
end
object Memo2: TMemo
ScrollBars = ssAutoVertical
TabOrder = 0
Left = 114
Height = 125
Top = 5
Width = 135
end
object Memo3: TMemo
ScrollBars = ssAutoVertical
TabOrder = 1
Left = 253
Height = 125
Top = 5
Width = 79
end
object Memo4: TMemo
ScrollBars = ssAutoVertical
TabOrder = 2
Left = 334
Height = 125
Top = 5
Width = 170
end
object Button7: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Calibrate'
OnClick = Button7CLICK
ParentShowHint = False
ShowHint = True
TabOrder = 6
Left = 9
Height = 25
Hint = 'Calls the calibration routines for call overhead calculation and gated timebase frequency measurement'
Top = 5
Width = 95
end
object Radiogroup1: TRadioGroup
Caption = 'Timebase'
Items.Strings = (
'System'
'Hardware'
)
OnClick = Radiogroup1CLICK
ParentColor = True
Left = 8
Height = 90
Top = 40
Width = 96
end
object Memo1: TMemo
ScrollBars = ssAutoVertical
TabOrder = 3
Left = 509
Height = 125
Top = 5
Width = 174
end
object Groupbox5: TGroupBox
Caption = 'Timebase Correlation'
ClientHeight = 72
ClientWidth = 667
ParentColor = True
ParentCtl3D = False
TabOrder = 4
Left = 8
Height = 90
Top = 155
Width = 671
object Label11: TLabel
Caption = 'System Has Microsecond Clock:'
Color = clNone
Left = 13
Height = 17
Top = 5
Width = 235
end
object Label1: TLabel
Caption = 'Correlated HW clock frequency'
Color = clNone
Left = 118
Height = 17
Top = 55
Width = 185
end
object Label12: TLabel
Caption = 'Jitter (Hz)'
Color = clNone
Left = 328
Height = 17
Top = 55
Width = 80
end
object Button8: TButton
BorderSpacing.InnerBorder = 2
Caption = 'Correlate'
OnClick = Button8CLICK
TabOrder = 0
Left = 13
Height = 25
Top = 30
Width = 95
end
object Edit7: TEdit
TabOrder = 1
Left = 118
Height = 23
Top = 30
Width = 190
end
object Checkbox4: TCheckBox
AllowGrayed = True
Caption = 'Apply Correction'
DragCursor = crDefault
TabOrder = 2
Left = 473
Height = 20
Top = 33
Width = 130
end
object Edit9: TEdit
TabOrder = 3
Left = 328
Height = 23
Top = 30
Width = 125
end
end
end
object Panel1: TPanel
Align = alTop
ClientHeight = 40
ClientWidth = 715
FullRepaint = False
TabOrder = 3
TabStop = True
Height = 40
Width = 715
object Label13: TLabel
Alignment = taCenter
Caption = 'Test and demo program for the EpikTimer component.'#10'Beta release: 7-3-2003'
Color = clNone
Left = 5
Height = 35
Top = 5
Width = 708
end
object Button18: TButton
BorderSpacing.InnerBorder = 2
Caption = 'About'
OnClick = Button18CLICK
TabOrder = 0
Left = 660
Height = 25
Top = 8
Width = 45
end
end
end

View File

@ -0,0 +1,273 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TForm1','FORMDATA',[
'TPF0'#6'TForm1'#5'Form1'#11'BorderStyle'#7#12'bsToolWindow'#7'Caption'#6'$Ep'
+'ikTimer Component Test Application'#8'OnCreate'#7#11'Form1CREATE'#9'OnDestr'
+'oy'#7#12'Form1DESTROY'#13'PixelsPerInch'#2'`'#8'Position'#7#14'poScreenCent'
+'er'#8'ShowHint'#9#18'HorzScrollBar.Page'#3#202#2#18'VertScrollBar.Page'#3'U'
+#2#4'Left'#3#160#0#6'Height'#3'V'#2#3'Top'#3#195#2#5'Width'#3#203#2#0#9'TGro'
+'upBox'#9'Groupbox2'#7'Caption'#6#25'Host Hardware Information'#12'ClientHei'
+'ght'#2'M'#11'ClientWidth'#3#179#2#11'ParentColor'#9#11'ParentCtl3D'#8#8'Tab'
+'Order'#2#0#4'Left'#2#10#6'Height'#2'_'#3'Top'#2'2'#5'Width'#3#183#2#0#6'TLa'
+'bel'#6'Label6'#7'Caption'#6#11'Has CPUID: '#5'Color'#7#6'clNone'#4'Left'#2
+#13#6'Height'#2#17#3'Top'#2#4#5'Width'#3#140#0#0#0#6'TLabel'#6'Label7'#7'Cap'
+'tion'#6#24'Has Time Stamp Counter: '#5'Color'#7#6'clNone'#4'Left'#3#168#0#6
+'Height'#2#17#3'Top'#2#4#5'Width'#3#190#0#0#0#6'TLabel'#6'Label9'#7'Caption'
+#6#16'Time Stamp Value'#5'Color'#7#6'clNone'#4'Left'#3#133#0#6'Height'#2#17#3
+'Top'#2'7'#5'Width'#2'x'#0#0#6'TLabel'#6'Label8'#7'Caption'#6#30'System Tick'
+'s (in microseconds)'#5'Color'#7#6'clNone'#4'Left'#3'k'#1#6'Height'#2#17#3'T'
+'op'#2'7'#5'Width'#3#185#0#0#0#5'TEdit'#5'Edit4'#8'TabOrder'#2#2#4'Left'#3
+#133#0#6'Height'#2#23#3'Top'#2#30#5'Width'#3#211#0#0#0#7'TButton'#7'Button6'
+#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#14'Get Time Stamp'#7'OnClick'
+#7#12'Button6CLICK'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#0#4'Lef'
+'t'#2#13#6'Height'#2#25#4'Hint'#6'UGets the current value of the Pentium Tim'
+'e Stamp counter and the System ticks counter'#3'Top'#2#29#5'Width'#2'd'#0#0
+#5'TEdit'#5'Edit6'#8'TabOrder'#2#1#4'Left'#3'k'#1#6'Height'#2#23#3'Top'#2#29
+#5'Width'#3#210#0#0#0#0#9'TGroupBox'#9'Groupbox3'#7'Caption'#6#25'Timer/Stop'
+'watch Functions'#12'ClientHeight'#3#152#0#11'ClientWidth'#3#179#2#11'Parent'
+'Color'#9#11'ParentCtl3D'#8#8'TabOrder'#2#1#4'Left'#2#10#6'Height'#3#170#0#3
+'Top'#3#164#1#5'Width'#3#183#2#0#6'TLabel'#6'Label3'#7'Caption'#6#15'Elapsed'
+' seconds'#5'Color'#7#6'clNone'#4'Left'#3'C'#1#6'Height'#2#17#3'Top'#2'#'#5
+'Width'#2's'#0#0#6'TLabel'#6'Label4'#7'Caption'#6#20'Elapsed Day:H:M:S.ms'#5
+'Color'#7#6'clNone'#4'Left'#3'C'#1#6'Height'#2#17#3'Top'#2'U'#5'Width'#3#130
+#0#0#0#6'TLabel'#6'Label5'#7'Caption'#6#9'Precision'#5'Color'#7#6'clNone'#4
+'Left'#3'z'#1#6'Height'#2#17#3'Top'#2'x'#5'Width'#2's'#0#0#7'TButton'#7'Butt'
+'on2'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#5'Start'#7'OnClick'#7#12
+'Button2CLICK'#8'TabOrder'#2#0#4'Left'#2#18#6'Height'#2#25#3'Top'#2#10#5'Wid'
+'th'#2'K'#0#0#7'TButton'#7'Button3'#25'BorderSpacing.InnerBorder'#2#2#7'Capt'
+'ion'#6#4'Stop'#7'OnClick'#7#12'Button3CLICK'#8'TabOrder'#2#1#4'Left'#2#18#6
+'Height'#2#25#3'Top'#2'P'#5'Width'#2'K'#0#0#7'TButton'#7'Button4'#25'BorderS'
+'pacing.InnerBorder'#2#2#7'Caption'#6#7'Elapsed'#7'OnClick'#7#12'Button4CLIC'
+'K'#8'TabOrder'#2#2#4'Left'#2#18#6'Height'#2#25#3'Top'#2'-'#5'Width'#2'K'#0#0
+#5'TEdit'#5'Edit2'#8'TabOrder'#2#3#4'Left'#3'C'#1#6'Height'#2#23#3'Top'#2#10
+#5'Width'#3#155#0#0#0#5'TEdit'#5'Edit3'#8'TabOrder'#2#4#4'Left'#3'C'#1#6'Hei'
+'ght'#2#23#3'Top'#2'<'#5'Width'#3#155#0#0#0#7'TButton'#7'Button5'#25'BorderS'
+'pacing.InnerBorder'#2#2#7'Caption'#6#5'Clear'#7'OnClick'#7#12'Button5CLICK'
+#8'TabOrder'#2#5#4'Left'#2#18#6'Height'#2#25#3'Top'#2's'#5'Width'#2'K'#0#0#9
+'TCheckBox'#9'Checkbox2'#11'AllowGrayed'#9#7'Caption'#6#7'Want MS'#10'DragCu'
+'rsor'#7#9'crDefault'#7'OnClick'#7#14'Checkbox2CLICK'#8'TabOrder'#2#6#4'Left'
+#3#21#2#6'Height'#2#20#3'Top'#2'u'#5'Width'#2'X'#0#0#9'TCheckBox'#9'Checkbox'
+'3'#11'AllowGrayed'#9#7'Caption'#6#9'Want Days'#10'DragCursor'#7#9'crDefault'
+#7'OnClick'#7#14'Checkbox3CLICK'#8'TabOrder'#2#7#4'Left'#3#187#1#6'Height'#2
+#20#3'Top'#2'v'#5'Width'#2'X'#0#0#9'TComboBox'#9'Combobox1'#13'Items.Strings'
+#1#6#1'0'#6#1'1'#6#1'2'#6#1'3'#6#1'4'#6#1'5'#6#1'6'#0#9'ItemIndex'#2#0#9'Max'
+'Length'#2#0#8'OnChange'#7#15'Combobox1CHANGE'#11'ParentCtl3D'#8#5'Style'#7
+#14'csDropDownList'#8'TabOrder'#2#8#4'Text'#6#1'0'#4'Left'#3'C'#1#6'Height'#2
+#21#3'Top'#2'r'#5'Width'#2'2'#0#0#5'TEdit'#5'Edit5'#8'TabOrder'#2#11#4'Left'
+#2'g'#6'Height'#2#23#3'Top'#2#10#5'Width'#3#205#0#0#0#5'TEdit'#5'Edit8'#8'Ta'
+'bOrder'#2#13#4'Left'#2'g'#6'Height'#2#23#3'Top'#2'-'#5'Width'#3#205#0#0#0#5
+'TEdit'#6'Edit11'#8'TabOrder'#2#9#4'Left'#2'g'#6'Height'#2#23#3'Top'#2'P'#5
+'Width'#3#205#0#0#0#5'TEdit'#5'Edit1'#8'TabOrder'#2#10#4'Left'#2'g'#6'Height'
+#2#23#3'Top'#2's'#5'Width'#3#205#0#0#0#9'TGroupBox'#9'Groupbox1'#7'Caption'#6
+#12'Spawn Timers'#12'ClientHeight'#2'M'#11'ClientWidth'#3#187#0#11'ParentCol'
+'or'#9#11'ParentCtl3D'#8#8'TabOrder'#2#12#4'Left'#3#236#1#6'Height'#2'_'#3'T'
+'op'#2#10#5'Width'#3#191#0#0#7'TButton'#7'Button1'#25'BorderSpacing.InnerBor'
+'der'#2#2#7'Caption'#6#1'1'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'#2#0#4
+'Left'#2#13#6'Height'#2#25#3'Top'#2#5#5'Width'#2#25#0#0#7'TButton'#7'Button9'
+#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#1'2'#7'OnClick'#7#12'Button1'
,'CLICK'#8'TabOrder'#2#1#4'Left'#2'.'#6'Height'#2#25#3'Top'#2#5#5'Width'#2#25
+#0#0#7'TButton'#8'Button10'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#1
+'3'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'#2#2#4'Left'#2'O'#6'Height'#2#25
+#3'Top'#2#5#5'Width'#2#25#0#0#7'TButton'#8'Button11'#25'BorderSpacing.InnerB'
+'order'#2#2#7'Caption'#6#1'4'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'#2#3#4
+'Left'#2'p'#6'Height'#2#25#3'Top'#2#5#5'Width'#2#25#0#0#7'TButton'#8'Button1'
+'2'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#1'5'#7'OnClick'#7#12'Butt'
+'on1CLICK'#8'TabOrder'#2#4#4'Left'#3#145#0#6'Height'#2#25#3'Top'#2#5#5'Width'
+#2#25#0#0#7'TButton'#8'Button13'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'
+#6#1'6'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'#2#5#4'Left'#2#13#6'Height'
+#2#25#3'Top'#2'-'#5'Width'#2#25#0#0#7'TButton'#8'Button14'#25'BorderSpacing.'
+'InnerBorder'#2#2#7'Caption'#6#1'7'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'
+#2#6#4'Left'#2'.'#6'Height'#2#25#3'Top'#2'-'#5'Width'#2#25#0#0#7'TButton'#8
+'Button15'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#1'8'#7'OnClick'#7
+#12'Button1CLICK'#8'TabOrder'#2#7#4'Left'#2'O'#6'Height'#2#25#3'Top'#2'-'#5
+'Width'#2#25#0#0#7'TButton'#8'Button16'#25'BorderSpacing.InnerBorder'#2#2#7
+'Caption'#6#1'9'#7'OnClick'#7#12'Button1CLICK'#8'TabOrder'#2#8#4'Left'#2'p'#6
+'Height'#2#25#3'Top'#2'-'#5'Width'#2#25#0#0#7'TButton'#8'Button17'#25'Border'
+'Spacing.InnerBorder'#2#2#7'Caption'#6#2'10'#7'OnClick'#7#12'Button1CLICK'#8
+'TabOrder'#2#9#4'Left'#3#145#0#6'Height'#2#25#3'Top'#2'-'#5'Width'#2#25#0#0#0
+#0#9'TGroupBox'#9'Groupbox4'#7'Caption'#6#20'Timebase calibration'#12'Client'
+'Height'#3#252#0#11'ClientWidth'#3#179#2#11'ParentColor'#9#11'ParentCtl3D'#8
+#8'TabOrder'#2#2#4'Left'#2#10#6'Height'#3#14#1#3'Top'#3#150#0#5'Width'#3#183
+#2#0#6'TLabel'#7'Label10'#7'Caption'#6#14'SystemSleep(0)'#5'Color'#7#6'clNon'
+'e'#4'Left'#2'r'#6'Height'#2#17#3'Top'#3#130#0#5'Width'#2'x'#0#0#6'TLabel'#7
+'Label16'#7'Caption'#6#5'Ticks'#5'Color'#7#6'clNone'#4'Left'#3#253#0#6'Heigh'
+'t'#2#17#3'Top'#3#130#0#5'Width'#2'U'#0#0#6'TLabel'#7'Label17'#7'Caption'#6
+#16'Ticks per second'#5'Color'#7#6'clNone'#4'Left'#3'N'#1#6'Height'#2#17#3'T'
+'op'#3#130#0#5'Width'#2'_'#0#0#6'TLabel'#6'Label2'#7'Caption'#6#25'Jitter (c'
+'urrent-previous)'#5'Color'#7#6'clNone'#4'Left'#3#253#1#6'Height'#2#17#3'Top'
+#3#130#0#5'Width'#3#130#0#0#0#5'TMemo'#5'Memo2'#10'ScrollBars'#7#14'ssAutoVe'
+'rtical'#8'TabOrder'#2#0#4'Left'#2'r'#6'Height'#2'}'#3'Top'#2#5#5'Width'#3
+#135#0#0#0#5'TMemo'#5'Memo3'#10'ScrollBars'#7#14'ssAutoVertical'#8'TabOrder'
+#2#1#4'Left'#3#253#0#6'Height'#2'}'#3'Top'#2#5#5'Width'#2'O'#0#0#5'TMemo'#5
+'Memo4'#10'ScrollBars'#7#14'ssAutoVertical'#8'TabOrder'#2#2#4'Left'#3'N'#1#6
+'Height'#2'}'#3'Top'#2#5#5'Width'#3#170#0#0#0#7'TButton'#7'Button7'#25'Borde'
+'rSpacing.InnerBorder'#2#2#7'Caption'#6#9'Calibrate'#7'OnClick'#7#12'Button7'
+'CLICK'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#6#4'Left'#2#9#6'Hei'
+'ght'#2#25#4'Hint'#6'eCalls the calibration routines for call overhead calcu'
+'lation and gated timebase frequency measurement'#3'Top'#2#5#5'Width'#2'_'#0
+#0#11'TRadioGroup'#11'Radiogroup1'#7'Caption'#6#8'Timebase'#13'Items.Strings'
+#1#6#6'System'#6#8'Hardware'#0#7'OnClick'#7#16'Radiogroup1CLICK'#11'ParentCo'
+'lor'#9#4'Left'#2#8#6'Height'#2'Z'#3'Top'#2'('#5'Width'#2'`'#0#0#5'TMemo'#5
+'Memo1'#10'ScrollBars'#7#14'ssAutoVertical'#8'TabOrder'#2#3#4'Left'#3#253#1#6
+'Height'#2'}'#3'Top'#2#5#5'Width'#3#174#0#0#0#9'TGroupBox'#9'Groupbox5'#7'Ca'
+'ption'#6#20'Timebase Correlation'#12'ClientHeight'#2'H'#11'ClientWidth'#3
+#155#2#11'ParentColor'#9#11'ParentCtl3D'#8#8'TabOrder'#2#4#4'Left'#2#8#6'Hei'
+'ght'#2'Z'#3'Top'#3#155#0#5'Width'#3#159#2#0#6'TLabel'#7'Label11'#7'Caption'
+#6#29'System Has Microsecond Clock:'#5'Color'#7#6'clNone'#4'Left'#2#13#6'Hei'
+'ght'#2#17#3'Top'#2#5#5'Width'#3#235#0#0#0#6'TLabel'#6'Label1'#7'Caption'#6
+#29'Correlated HW clock frequency'#5'Color'#7#6'clNone'#4'Left'#2'v'#6'Heigh'
+'t'#2#17#3'Top'#2'7'#5'Width'#3#185#0#0#0#6'TLabel'#7'Label12'#7'Caption'#6
+#11'Jitter (Hz)'#5'Color'#7#6'clNone'#4'Left'#3'H'#1#6'Height'#2#17#3'Top'#2
+'7'#5'Width'#2'P'#0#0#7'TButton'#7'Button8'#25'BorderSpacing.InnerBorder'#2#2
+#7'Caption'#6#9'Correlate'#7'OnClick'#7#12'Button8CLICK'#8'TabOrder'#2#0#4'L'
+'eft'#2#13#6'Height'#2#25#3'Top'#2#30#5'Width'#2'_'#0#0#5'TEdit'#5'Edit7'#8
+'TabOrder'#2#1#4'Left'#2'v'#6'Height'#2#23#3'Top'#2#30#5'Width'#3#190#0#0#0#9
+'TCheckBox'#9'Checkbox4'#11'AllowGrayed'#9#7'Caption'#6#16'Apply Correction'
+#10'DragCursor'#7#9'crDefault'#8'TabOrder'#2#2#4'Left'#3#217#1#6'Height'#2#20
+#3'Top'#2'!'#5'Width'#3#130#0#0#0#5'TEdit'#5'Edit9'#8'TabOrder'#2#3#4'Left'#3
+'H'#1#6'Height'#2#23#3'Top'#2#30#5'Width'#2'}'#0#0#0#0#6'TPanel'#6'Panel1'#5
+'Align'#7#5'alTop'#12'ClientHeight'#2'('#11'ClientWidth'#3#203#2#11'FullRepa'
+'int'#8#8'TabOrder'#2#3#7'TabStop'#9#6'Height'#2'('#5'Width'#3#203#2#0#6'TLa'
+'bel'#7'Label13'#9'Alignment'#7#8'taCenter'#7'Caption'#6'ITest and demo prog'
,'ram for the EpikTimer component.'#10'Beta release: 7-3-2003'#5'Color'#7#6'c'
+'lNone'#4'Left'#2#5#6'Height'#2'#'#3'Top'#2#5#5'Width'#3#196#2#0#0#7'TButton'
+#8'Button18'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#5'About'#7'OnCli'
+'ck'#7#13'Button18CLICK'#8'TabOrder'#2#0#4'Left'#3#148#2#6'Height'#2#25#3'To'
+'p'#2#8#5'Width'#2'-'#0#0#0#0
]);

View File

@ -0,0 +1,284 @@
unit main;
{ Name: EpikTimer Demo Program
Description: Test application
Author: Tom Lisjac <vlx@users.sourceforge.net>
Demonstrates the capabilities of TEpikTimer in epiktimer.pas
}
{ Copyright (C) 2003 by Tom Lisjac <vlx@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
}
{
Contributors
Felipe Monteiro de Carvalho (felipemonteiro.carvalho@gmail.com)
Known Issues
- Quickly written and completely undocumented... but there's nothing
complicated going on in this unit.
Change log
Initially written on 28-06-2003 TL
Pre-release 30-06-2003 TL - Needs testing on systems without CPUID and TSC hardware
15-11-2005
Removed Linux unit to compile on Windows. It happens that main.pas didn�t
use this unit.
}
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
Buttons, StdCtrls, ExtCtrls, EpikTimer, ComCtrls, Grids, newsw;
Const
MaxStopwatches=10;
type
TForm1 = class(TForm)
Button1: TBUTTON;
Button10: TBUTTON;
Button11: TBUTTON;
Button12: TBUTTON;
Button13: TBUTTON;
Button14: TBUTTON;
Button15: TBUTTON;
Button16: TBUTTON;
Button17: TBUTTON;
Button18: TBUTTON;
Button2: TBUTTON;
Button3: TBUTTON;
Button4: TBUTTON;
Button5: TBUTTON;
Button6: TBUTTON;
Button7: TBUTTON;
Button8: TBUTTON;
Button9: TBUTTON;
Checkbox2: TCHECKBOX;
Checkbox3: TCHECKBOX;
Checkbox4: TCHECKBOX;
Combobox1: TCOMBOBOX;
Edit1: TEDIT;
Edit11: TEDIT;
Edit2: TEDIT;
Edit3: TEDIT;
Edit4: TEDIT;
Edit5: TEDIT;
Edit6: TEDIT;
Edit7: TEDIT;
Edit8: TEDIT;
Edit9: TEDIT;
Groupbox1: TGROUPBOX;
Groupbox2: TGROUPBOX;
Groupbox3: TGROUPBOX;
Groupbox4: TGROUPBOX;
Groupbox5: TGROUPBOX;
Idletimer1: TIDLETIMER;
Label1: TLABEL;
Label10: TLABEL;
Label11: TLABEL;
Label12: TLABEL;
Label13: TLABEL;
Label16: TLABEL;
Label17: TLABEL;
Label2: TLABEL;
Label3: TLABEL;
Label4: TLABEL;
Label5: TLABEL;
Label6: TLABEL;
Label7: TLABEL;
Label8: TLABEL;
Label9: TLABEL;
Memo1: TMEMO;
Memo2: TMEMO;
Memo3: TMEMO;
Memo4: TMEMO;
Panel1: TPANEL;
Radiogroup1: TRADIOGROUP;
procedure Button18CLICK(Sender: TObject);
procedure Button1CLICK(Sender: TObject);
procedure Button2CLICK(Sender: TObject);
procedure Button3CLICK(Sender: TObject);
procedure Button4CLICK(Sender: TObject);
procedure Button5CLICK(Sender: TObject);
procedure Button6CLICK(Sender: TObject);
procedure Button7CLICK(Sender: TObject);
procedure Button8CLICK(Sender: TObject);
procedure Checkbox2CLICK(Sender: TObject);
procedure Checkbox3CLICK(Sender: TObject);
procedure Combobox1CHANGE(Sender: TObject);
procedure Form1CREATE(Sender: TObject);
procedure Form1DESTROY(Sender: TObject);
procedure Radiogroup1CLICK(Sender: TObject);
private
CurFreq,PrevFreq:Extended;
CorrelationJitter:Extended;
Iter:Integer;
public
ET:TEpikTimer;
end;
var
Form1: TForm1;
NewStopwatches:array[1..MaxStopwatches] of Tform2;
implementation
{ TForm1 }
procedure TForm1.Button1CLICK(Sender: TObject);
Var TimerNumber:Integer;
begin
TimerNumber:=StrtoInt(Tbutton(Sender).Caption);
With Newstopwatches[TimerNumber] do
Begin
Left:=TimerNumber*8;
Top:=TimerNumber*8;
Caption:='Stopwatch '+Tbutton(Sender).Caption;
visible:=true;
show
End
end;
procedure TForm1.Button18CLICK(Sender: TObject);
begin
Showmessage('EpikTimer component demo program'+#10#10+
'By Tom Lisjac <vlx@users.sourceforge.net>'+#10+
'Additional information about this program can be found at http://theseus.sourceforge.net/fpclaz'+#10+
'or by contacting the author.');
end;
procedure TForm1.Button2CLICK(Sender: TObject);
begin
ET.Start;
Edit5.text:=ET.WallClockTime;
end;
procedure TForm1.Button3CLICK(Sender: TObject);
begin
ET.Stop;
edit11.text:=ET.WallClockTime;
end;
procedure TForm1.Button4CLICK(Sender: TObject);
begin
edit2.text:=ET.ElapsedStr;
Edit3.text:=ET.elapsedDHMS;
edit8.text:=ET.WallClockTime;
end;
procedure TForm1.Button5CLICK(Sender: TObject);
begin
ET.Clear;
edit1.text:=ET.WallClockTime;
edit2.text:=ET.ElapsedStr;
Edit3.text:=ET.elapsedDHMS;
end;
procedure TForm1.Button6CLICK(Sender: TObject);
begin
edit4.text:=format('%.0n',[extended(ET.GetHardwareTicks)]);
edit6.text:=format('%.0n',[extended(ET.GetSystemTicks)]);
end;
procedure TForm1.Button7CLICK(Sender: TObject);
begin
Inc(Iter);
ET.CalibrateCallOverheads(ET.SelectedTimebase^);
ET.CalibrateTickFrequency(ET.SelectedTimebase^);
With ET.SelectedTimebase^ do
Begin
memo2.lines.insert(0,format('%2.0d:%.0n',[Iter,extended(SleepOverhead)]));
memo3.lines.insert(0,format('%2.0d:%.0n',[Iter,extended(TicksOverhead)]));
memo4.lines.insert(0,format('%2.0d:%.0n',[Iter,extended(TicksFrequency)]));
CurFreq:=TicksFrequency;
memo1.lines.insert(0,format('%2.0d:%.0n',[Iter,CurFreq-PrevFreq]));
End;
PrevFreq:=CurFreq;
end;
procedure TForm1.Button8CLICK(Sender: TObject);
Var CorrelatedTickFrequency:TickType;
begin
CorrelatedTickFrequency:=ET.GetTimebaseCorrelation;
Edit9.text:=format('%.0n',[extended(CorrelationJitter-CorrelatedTickFrequency)]);
Edit7.text:=format('%.0n',[extended(CorrelatedTickFrequency)]);
CorrelationJitter:= CorrelatedTickFrequency;
If checkbox4.checked then
ET.HWTimebase.TicksFrequency:=trunc(CorrelatedTickFrequency);
end;
procedure TForm1.Checkbox2CLICK(Sender: TObject);
begin
ET.WantMilliseconds:=Checkbox2.checked
end;
procedure TForm1.Checkbox3CLICK(Sender: TObject);
begin
ET.WantDays:=Checkbox3.checked
end;
procedure TForm1.Combobox1CHANGE(Sender: TObject);
begin
ET.StringPrecision:=ComboBox1.Itemindex;
end;
procedure TForm1.Form1CREATE(Sender: TObject);
Var S:String;
begin
Iter:=0;
PrevFreq:=0.0;
CorrelationJitter:=0.0;
ET:=TEpikTimer.create(nil);
RadioGroup1.itemindex:=ord(ET.TimebaseSource);
ComboBox1.itemindex:=ET.StringPrecision;
If ET.HWCapabilityDataAvailable then S:='Yes' else S:='No';
Label6.caption:=label6.caption+S;
If ET.HWTickSupportAvailable then S:='Yes' else S:='No';
Label7.caption:=label7.caption+S;
If ET.MicrosecondSystemClockAvailable then S:='Yes' else S:='No';
Label11.caption:=Label11.caption+S;
Checkbox2.checked:=ET.WantMilliseconds;
Checkbox3.checked:=ET.WantDays;
Application.showhint:=true;
end;
procedure TForm1.Form1DESTROY(Sender: TObject);
begin
ET.free;
end;
procedure TForm1.Radiogroup1CLICK(Sender: TObject);
begin
ET.TimebaseSource:= TickSources(Radiogroup1.itemindex);
Radiogroup1.itemindex:=ord(ET.TimebaseSource); // verifies the change
Iter:=0;
end;
initialization
{$i main.lrs}
end.

View File

@ -0,0 +1,176 @@
object Form2: TForm2
Caption = 'Form2'
ClientHeight = 340
ClientWidth = 359
OnCreate = Form2CREATE
OnDestroy = Form2DESTROY
PixelsPerInch = 96
HorzScrollBar.Page = 358
VertScrollBar.Page = 339
Left = 420
Height = 340
Top = 364
Width = 359
object Groupbox1: TGroupBox
BorderSpacing.OnChange = nil
Caption = 'Using Built-in timer'
ClientHeight = 137
ClientWidth = 336
ParentColor = True
ParentCtl3D = False
TabOrder = 0
Left = 10
Height = 155
Top = 10
Width = 340
object Button1: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Elapsed'
OnClick = Button1CLICK
TabOrder = 0
Left = 173
Height = 25
Top = 10
Width = 75
end
object Button2: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Start'
OnClick = Button2CLICK
TabOrder = 1
Left = 18
Height = 25
Top = 10
Width = 75
end
object Button3: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Stop'
OnClick = Button3CLICK
TabOrder = 2
Left = 18
Height = 25
Top = 40
Width = 75
end
object Button4: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Clear'
OnClick = Button4CLICK
TabOrder = 3
Left = 18
Height = 25
Top = 73
Width = 75
end
object Edit1: TEdit
BorderSpacing.OnChange = nil
TabOrder = 4
Left = 113
Height = 23
Top = 45
Width = 205
end
object Edit2: TEdit
BorderSpacing.OnChange = nil
TabOrder = 5
Left = 113
Height = 23
Top = 75
Width = 205
end
object Edit4: TEdit
BorderSpacing.OnChange = nil
TabOrder = 6
Left = 18
Height = 23
Top = 105
Width = 300
end
end
object Groupbox2: TGroupBox
BorderSpacing.OnChange = nil
Caption = 'Using program created timer'
ClientHeight = 137
ClientWidth = 336
ParentColor = True
ParentCtl3D = False
TabOrder = 1
Left = 10
Height = 155
Top = 175
Width = 340
object Button5: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Elapsed'
OnClick = Button5CLICK
TabOrder = 0
Left = 173
Height = 25
Top = 10
Width = 75
end
object Button6: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Start'
OnClick = Button6CLICK
TabOrder = 1
Left = 18
Height = 25
Top = 10
Width = 75
end
object Button7: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Stop'
OnClick = Button7CLICK
TabOrder = 2
Left = 18
Height = 25
Top = 40
Width = 75
end
object Button8: TButton
BorderSpacing.OnChange = nil
BorderSpacing.InnerBorder = 2
Caption = 'Clear'
OnClick = Button8CLICK
TabOrder = 3
Left = 18
Height = 25
Top = 75
Width = 75
end
object Edit3: TEdit
BorderSpacing.OnChange = nil
TabOrder = 4
Left = 113
Height = 23
Top = 45
Width = 205
end
object Edit5: TEdit
BorderSpacing.OnChange = nil
TabOrder = 5
Left = 113
Height = 23
Top = 75
Width = 205
end
object Edit6: TEdit
BorderSpacing.OnChange = nil
TabOrder = 6
Left = 18
Height = 23
Top = 105
Width = 300
end
end
end

View File

@ -0,0 +1,95 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TForm2','FORMDATA',[
'TPF0'#6'TForm2'#5'Form2'#7'Caption'#6#5'Form2'#12'ClientHeight'#3'T'#1#11'Cl'
+'ientWidth'#3'g'#1#8'OnCreate'#7#11'Form2CREATE'#9'OnDestroy'#7#12'Form2DEST'
+'ROY'#13'PixelsPerInch'#2'`'#18'HorzScrollBar.Page'#3'f'#1#18'VertScrollBar.'
+'Page'#3'S'#1#4'Left'#3#164#1#6'Height'#3'T'#1#3'Top'#3'l'#1#5'Width'#3'g'#1
+#0#9'TGroupBox'#9'Groupbox1'#22'BorderSpacing.OnChange'#13#7'Caption'#6#20'U'
+'sing Built-in timer'#12'ClientHeight'#3#137#0#11'ClientWidth'#3'P'#1#11'Par'
+'entColor'#9#11'ParentCtl3D'#8#8'TabOrder'#2#0#4'Left'#2#10#6'Height'#3#155#0
+#3'Top'#2#10#5'Width'#3'T'#1#0#7'TButton'#7'Button1'#22'BorderSpacing.OnChan'
+'ge'#13#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#7'Elapsed'#7'OnClick'
+#7#12'Button1CLICK'#8'TabOrder'#2#0#4'Left'#3#173#0#6'Height'#2#25#3'Top'#2
+#10#5'Width'#2'K'#0#0#7'TButton'#7'Button2'#22'BorderSpacing.OnChange'#13#25
+'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#5'Start'#7'OnClick'#7#12'Button'
+'2CLICK'#8'TabOrder'#2#1#4'Left'#2#18#6'Height'#2#25#3'Top'#2#10#5'Width'#2
+'K'#0#0#7'TButton'#7'Button3'#22'BorderSpacing.OnChange'#13#25'BorderSpacing'
+'.InnerBorder'#2#2#7'Caption'#6#4'Stop'#7'OnClick'#7#12'Button3CLICK'#8'TabO'
+'rder'#2#2#4'Left'#2#18#6'Height'#2#25#3'Top'#2'('#5'Width'#2'K'#0#0#7'TButt'
+'on'#7'Button4'#22'BorderSpacing.OnChange'#13#25'BorderSpacing.InnerBorder'#2
+#2#7'Caption'#6#5'Clear'#7'OnClick'#7#12'Button4CLICK'#8'TabOrder'#2#3#4'Lef'
+'t'#2#18#6'Height'#2#25#3'Top'#2'I'#5'Width'#2'K'#0#0#5'TEdit'#5'Edit1'#22'B'
+'orderSpacing.OnChange'#13#8'TabOrder'#2#4#4'Left'#2'q'#6'Height'#2#23#3'Top'
+#2'-'#5'Width'#3#205#0#0#0#5'TEdit'#5'Edit2'#22'BorderSpacing.OnChange'#13#8
+'TabOrder'#2#5#4'Left'#2'q'#6'Height'#2#23#3'Top'#2'K'#5'Width'#3#205#0#0#0#5
+'TEdit'#5'Edit4'#22'BorderSpacing.OnChange'#13#8'TabOrder'#2#6#4'Left'#2#18#6
+'Height'#2#23#3'Top'#2'i'#5'Width'#3','#1#0#0#0#9'TGroupBox'#9'Groupbox2'#22
+'BorderSpacing.OnChange'#13#7'Caption'#6#27'Using program created timer'#12
+'ClientHeight'#3#137#0#11'ClientWidth'#3'P'#1#11'ParentColor'#9#11'ParentCtl'
+'3D'#8#8'TabOrder'#2#1#4'Left'#2#10#6'Height'#3#155#0#3'Top'#3#175#0#5'Width'
+#3'T'#1#0#7'TButton'#7'Button5'#22'BorderSpacing.OnChange'#13#25'BorderSpaci'
+'ng.InnerBorder'#2#2#7'Caption'#6#7'Elapsed'#7'OnClick'#7#12'Button5CLICK'#8
+'TabOrder'#2#0#4'Left'#3#173#0#6'Height'#2#25#3'Top'#2#10#5'Width'#2'K'#0#0#7
+'TButton'#7'Button6'#22'BorderSpacing.OnChange'#13#25'BorderSpacing.InnerBor'
+'der'#2#2#7'Caption'#6#5'Start'#7'OnClick'#7#12'Button6CLICK'#8'TabOrder'#2#1
+#4'Left'#2#18#6'Height'#2#25#3'Top'#2#10#5'Width'#2'K'#0#0#7'TButton'#7'Butt'
+'on7'#22'BorderSpacing.OnChange'#13#25'BorderSpacing.InnerBorder'#2#2#7'Capt'
+'ion'#6#4'Stop'#7'OnClick'#7#12'Button7CLICK'#8'TabOrder'#2#2#4'Left'#2#18#6
+'Height'#2#25#3'Top'#2'('#5'Width'#2'K'#0#0#7'TButton'#7'Button8'#22'BorderS'
+'pacing.OnChange'#13#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#5'Clear'
+#7'OnClick'#7#12'Button8CLICK'#8'TabOrder'#2#3#4'Left'#2#18#6'Height'#2#25#3
+'Top'#2'K'#5'Width'#2'K'#0#0#5'TEdit'#5'Edit3'#22'BorderSpacing.OnChange'#13
+#8'TabOrder'#2#4#4'Left'#2'q'#6'Height'#2#23#3'Top'#2'-'#5'Width'#3#205#0#0#0
+#5'TEdit'#5'Edit5'#22'BorderSpacing.OnChange'#13#8'TabOrder'#2#5#4'Left'#2'q'
+#6'Height'#2#23#3'Top'#2'K'#5'Width'#3#205#0#0#0#5'TEdit'#5'Edit6'#22'Border'
+'Spacing.OnChange'#13#8'TabOrder'#2#6#4'Left'#2#18#6'Height'#2#23#3'Top'#2'i'
+#5'Width'#3','#1#0#0#0#0
]);

View File

@ -0,0 +1,135 @@
unit newsw;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
Grids, Buttons,EpikTimer;
type
TForm2 = class(TForm)
Button1: TBUTTON;
Button2: TBUTTON;
Button3: TBUTTON;
Button4: TBUTTON;
Button5: TBUTTON;
Button6: TBUTTON;
Button7: TBUTTON;
Button8: TBUTTON;
Edit1: TEDIT;
Edit2: TEDIT;
Edit3: TEDIT;
Edit4: TEDIT;
Edit5: TEDIT;
Edit6: TEDIT;
Groupbox1: TGROUPBOX;
Groupbox2: TGROUPBOX;
procedure Button1CLICK(Sender: TObject);
procedure Button2CLICK(Sender: TObject);
procedure Button3CLICK(Sender: TObject);
procedure Button4CLICK(Sender: TObject);
procedure Button5CLICK(Sender: TObject);
procedure Button6CLICK(Sender: TObject);
procedure Button7CLICK(Sender: TObject);
procedure Button8CLICK(Sender: TObject);
procedure Form2CREATE(Sender: TObject);
procedure Form2DESTROY(Sender: TObject);
private
ET:TEpikTimer;
LocalTimer:TimerData;
Procedure UpdateDisplay(Msg:String);
Procedure UpdateDisplayLocal(Msg:String);
public
{ public declarations }
end;
Var
Form2:Tform2;
implementation
{ TForm2 }
procedure TForm2.UpdateDisplay(Msg:String);
begin
edit1.text:=ET.ElapsedStr;
Edit2.text:=ET.elapsedDHMS;
edit4.text:=Msg+': '+ET.WallClockTime;
end;
procedure TForm2.Button2CLICK(Sender: TObject);
begin
ET.Start;
UpdateDisplay('Start')
end;
procedure TForm2.Button3CLICK(Sender: TObject);
begin
ET.Stop;
UpdateDisplay('Stop')
end;
procedure TForm2.Button4CLICK(Sender: TObject);
begin
ET.Clear;
UpdateDisplay('Clear')
end;
procedure TForm2.Button1CLICK(Sender: TObject);
begin
UpdateDisplay('Elapsed')
end;
(* This group uses a locally created timer *)
procedure TForm2.UpdateDisplayLocal(Msg:String);
begin
edit3.text:=ET.ElapsedStr(LocalTimer);
Edit5.text:=ET.elapsedDHMS(LocalTimer);
edit6.text:=Msg+': '+ET.WallClockTime;
end;
procedure TForm2.Button6CLICK(Sender: TObject);
begin
ET.Start(LocalTimer);
UpdateDisplayLocal('Start')
end;
procedure TForm2.Button7CLICK(Sender: TObject);
begin
ET.Stop(LocalTimer);
UpdateDisplayLocal('Stop')
end;
procedure TForm2.Button8CLICK(Sender: TObject);
begin
ET.Clear(LocalTimer);
UpdateDisplayLocal('Clear')
end;
procedure TForm2.Button5CLICK(Sender: TObject);
begin
UpdateDisplayLocal('Elapsed:')
end;
procedure TForm2.Form2CREATE(Sender: TObject);
begin
ET:=TEpikTimer.create(nil);
ET.Clear(LocalTimer) // you have to do this if you create a local timer
end;
procedure TForm2.Form2DESTROY(Sender: TObject);
begin
ET.Free
end;
initialization
{$I newsw.lrs}
end.

View File

@ -0,0 +1,59 @@
object Form3: TForm3
CAPTION = 'EpikTimer Demo Initialization - Please wait'
CLIENTHEIGHT = 167
CLIENTWIDTH = 400
POSITION = poscreencenter
VISIBLE = True
HORZSCROLLBAR.PAGE = 401
VERTSCROLLBAR.PAGE = 168
LEFT = 440
HEIGHT = 167
TOP = 428
WIDTH = 400
object Progressbar1: TPROGRESSBAR
MIN = 1
MAX = 9
STEP = 1
SMOOTH = True
DRAGCURSOR = 0
TABORDER = 0
TABSTOP = True
LEFT = 60
HEIGHT = 20
TOP = 105
WIDTH = 294
end
object Label1: TLABEL
ALIGNMENT = tacenter
CAPTION = 'EpikTimer Test application'
LAYOUT = tltop
LEFT = 5
HEIGHT = 17
TOP = 25
WIDTH = 395
end
object Label2: TLABEL
ALIGNMENT = tacenter
CAPTION = 'Beta release: 7-3-2003'
LAYOUT = tltop
HEIGHT = 17
TOP = 65
WIDTH = 400
end
object Label3: TLABEL
ALIGNMENT = tacenter
CAPTION = 'By Tom Lisjac <vlx@users.sourceforge.net>'
LAYOUT = tltop
HEIGHT = 17
TOP = 45
WIDTH = 400
end
object Label4: TLABEL
ALIGNMENT = tacenter
CAPTION = 'System initializing... please wait'
LAYOUT = tltop
HEIGHT = 17
TOP = 135
WIDTH = 400
end
end

View File

@ -0,0 +1,20 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TForm3','FORMDATA',[
'TPF0'#6'TForm3'#5'Form3'#7'CAPTION'#6'+EpikTimer Demo Initialization - Pleas'
+'e wait'#12'CLIENTHEIGHT'#3#167#0#11'CLIENTWIDTH'#3#144#1#8'POSITION'#7#14'p'
+'oscreencenter'#7'VISIBLE'#9#18'HORZSCROLLBAR.PAGE'#3#145#1#18'VERTSCROLLBAR'
+'.PAGE'#3#168#0#4'LEFT'#3#184#1#6'HEIGHT'#3#167#0#3'TOP'#3#172#1#5'WIDTH'#3
+#144#1#0#12'TPROGRESSBAR'#12'Progressbar1'#3'MIN'#2#1#3'MAX'#2#9#4'STEP'#2#1
+#6'SMOOTH'#9#10'DRAGCURSOR'#2#0#8'TABORDER'#2#0#7'TABSTOP'#9#4'LEFT'#2'<'#6
+'HEIGHT'#2#20#3'TOP'#2'i'#5'WIDTH'#3'&'#1#0#0#6'TLABEL'#6'Label1'#9'ALIGNMEN'
+'T'#7#8'tacenter'#7'CAPTION'#6#26'EpikTimer Test application'#6'LAYOUT'#7#5
+'tltop'#4'LEFT'#2#5#6'HEIGHT'#2#17#3'TOP'#2#25#5'WIDTH'#3#139#1#0#0#6'TLABEL'
+#6'Label2'#9'ALIGNMENT'#7#8'tacenter'#7'CAPTION'#6#22'Beta release: 7-3-2003'
+#6'LAYOUT'#7#5'tltop'#6'HEIGHT'#2#17#3'TOP'#2'A'#5'WIDTH'#3#144#1#0#0#6'TLAB'
+'EL'#6'Label3'#9'ALIGNMENT'#7#8'tacenter'#7'CAPTION'#6')By Tom Lisjac <vlx@u'
+'sers.sourceforge.net>'#6'LAYOUT'#7#5'tltop'#6'HEIGHT'#2#17#3'TOP'#2'-'#5'WI'
+'DTH'#3#144#1#0#0#6'TLABEL'#6'Label4'#9'ALIGNMENT'#7#8'tacenter'#7'CAPTION'#6
+'"System initializing... please wait'#6'LAYOUT'#7#5'tltop'#6'HEIGHT'#2#17#3
+'TOP'#3#135#0#5'WIDTH'#3#144#1#0#0#0
]);

View File

@ -0,0 +1,33 @@
unit splash;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls,
StdCtrls;
type
TForm3 = class(TForm)
Label1: TLABEL;
Label2: TLABEL;
Label3: TLABEL;
Label4: TLABEL;
Progressbar1: TPROGRESSBAR;
private
{ private declarations }
public
{ public declarations }
end;
var
Form3: TForm3;
implementation
initialization
{$I splash.lrs}
end.