You've already forked lazarus-ccr
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:
31
components/epiktimer/CHANGES.txt
Normal file
31
components/epiktimer/CHANGES.txt
Normal 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)
|
||||
|
128
components/epiktimer/README.txt
Normal file
128
components/epiktimer/README.txt
Normal 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 ------------------
|
||||
|
15
components/epiktimer/epiktimer.lrs
Normal file
15
components/epiktimer/epiktimer.lrs
Normal 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
|
||||
]);
|
802
components/epiktimer/epiktimer.pas
Normal file
802
components/epiktimer/epiktimer.pas
Normal 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.
|
||||
|
134
components/epiktimer/etdemo.lpi
Normal file
134
components/epiktimer/etdemo.lpi
Normal 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>
|
27
components/epiktimer/etdemo.lpr
Normal file
27
components/epiktimer/etdemo.lpr
Normal 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.
|
||||
|
54
components/epiktimer/etpackage.lpk
Normal file
54
components/epiktimer/etpackage.lpk
Normal 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>
|
21
components/epiktimer/etpackage.pas
Normal file
21
components/epiktimer/etpackage.pas
Normal 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.
|
34
components/epiktimer/graphics/tepiktimer.xpm
Normal file
34
components/epiktimer/graphics/tepiktimer.xpm
Normal 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",
|
||||
" ...... ",
|
||||
" +@..@+ ",
|
||||
" .. ...... .. ",
|
||||
" .#@...######...@#. ",
|
||||
" .+..++@@$$@@++..+. ",
|
||||
" ..+@@@@$$@@@@+.. ",
|
||||
" .+@.@@@@@@@@@@+. ",
|
||||
" .+@@.@@@@@@.@@+. ",
|
||||
" .+@@@@.@@@@.@@@@+. ",
|
||||
" .+@@@@@.@@.@@@@@+. ",
|
||||
" .#$$@@@@..@@@@$$#. ",
|
||||
" .#$$@@@@..@@@@$$#. ",
|
||||
" .+@@@@@@@@@@@@@@+. ",
|
||||
" .+@@@@@@@@@@@@@@+. ",
|
||||
"%%%%%%%%%%%%%%%%%%%%%%",
|
||||
"%&.&&.&&.&&.&&.&&.&&&%",
|
||||
"%&.&&.&&.&&.&&.&&.&&&%",
|
||||
"%&.&&.&&.&&.&&.&&.&&&%",
|
||||
"%&&&&.&&&&&.&&&&&.&&&%",
|
||||
"%&&&&.&&&&&.&&&&&.&&&%",
|
||||
"%&&&&&&&&&&&&&&&&&&&&%",
|
||||
"%%%%%%%%%%%%%%%%%%%%%%",
|
||||
" "};
|
561
components/epiktimer/main.lfm
Normal file
561
components/epiktimer/main.lfm
Normal 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
|
273
components/epiktimer/main.lrs
Normal file
273
components/epiktimer/main.lrs
Normal 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
|
||||
|
||||
]);
|
||||
|
284
components/epiktimer/main.pas
Normal file
284
components/epiktimer/main.pas
Normal 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.
|
||||
|
176
components/epiktimer/newsw.lfm
Normal file
176
components/epiktimer/newsw.lfm
Normal 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
|
95
components/epiktimer/newsw.lrs
Normal file
95
components/epiktimer/newsw.lrs
Normal 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
|
||||
|
||||
]);
|
||||
|
135
components/epiktimer/newsw.pas
Normal file
135
components/epiktimer/newsw.pas
Normal 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.
|
||||
|
59
components/epiktimer/splash.lfm
Normal file
59
components/epiktimer/splash.lfm
Normal 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
|
20
components/epiktimer/splash.lrs
Normal file
20
components/epiktimer/splash.lrs
Normal 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
|
||||
]);
|
33
components/epiktimer/splash.pas
Normal file
33
components/epiktimer/splash.pas
Normal 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.
|
||||
|
Reference in New Issue
Block a user