From bfef8f458472eb81bfcc2bf077a60ee34ac6840a Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Thu, 22 May 2008 12:20:58 +0000 Subject: [PATCH] Adds epiktimer git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@453 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/epiktimer/CHANGES.txt | 31 + components/epiktimer/README.txt | 128 +++ components/epiktimer/epiktimer.lrs | 15 + components/epiktimer/epiktimer.pas | 802 +++++++++++++++++++ components/epiktimer/etdemo.lpi | 134 ++++ components/epiktimer/etdemo.lpr | 27 + components/epiktimer/etpackage.lpk | 54 ++ components/epiktimer/etpackage.pas | 21 + components/epiktimer/graphics/tepiktimer.xpm | 34 + components/epiktimer/main.lfm | 561 +++++++++++++ components/epiktimer/main.lrs | 273 +++++++ components/epiktimer/main.pas | 284 +++++++ components/epiktimer/newsw.lfm | 176 ++++ components/epiktimer/newsw.lrs | 95 +++ components/epiktimer/newsw.pas | 135 ++++ components/epiktimer/splash.lfm | 59 ++ components/epiktimer/splash.lrs | 20 + components/epiktimer/splash.pas | 33 + 18 files changed, 2882 insertions(+) create mode 100644 components/epiktimer/CHANGES.txt create mode 100644 components/epiktimer/README.txt create mode 100644 components/epiktimer/epiktimer.lrs create mode 100644 components/epiktimer/epiktimer.pas create mode 100644 components/epiktimer/etdemo.lpi create mode 100644 components/epiktimer/etdemo.lpr create mode 100644 components/epiktimer/etpackage.lpk create mode 100644 components/epiktimer/etpackage.pas create mode 100644 components/epiktimer/graphics/tepiktimer.xpm create mode 100644 components/epiktimer/main.lfm create mode 100644 components/epiktimer/main.lrs create mode 100644 components/epiktimer/main.pas create mode 100644 components/epiktimer/newsw.lfm create mode 100644 components/epiktimer/newsw.lrs create mode 100644 components/epiktimer/newsw.pas create mode 100644 components/epiktimer/splash.lfm create mode 100644 components/epiktimer/splash.lrs create mode 100644 components/epiktimer/splash.pas diff --git a/components/epiktimer/CHANGES.txt b/components/epiktimer/CHANGES.txt new file mode 100644 index 000000000..807f4ef45 --- /dev/null +++ b/components/epiktimer/CHANGES.txt @@ -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) + diff --git a/components/epiktimer/README.txt b/components/epiktimer/README.txt new file mode 100644 index 000000000..eba2f29b5 --- /dev/null +++ b/components/epiktimer/README.txt @@ -0,0 +1,128 @@ + + + Description: Precision timer/stopwatch component for Lazarus/FPC + Author: Tom Lisjac + Contributors: + * Felipe Monteiro de Carvalho + * 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 ------------------ + diff --git a/components/epiktimer/epiktimer.lrs b/components/epiktimer/epiktimer.lrs new file mode 100644 index 000000000..b132020f4 --- /dev/null +++ b/components/epiktimer/epiktimer.lrs @@ -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 +]); diff --git a/components/epiktimer/epiktimer.pas b/components/epiktimer/epiktimer.pas new file mode 100644 index 000000000..7c4ca77e5 --- /dev/null +++ b/components/epiktimer/epiktimer.pas @@ -0,0 +1,802 @@ +unit EpikTimer; + +{ Name: EpikTimer + Description: Precision timer/stopwatch component for Lazarus/FPC + Author: Tom Lisjac + 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 , + 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. + diff --git a/components/epiktimer/etdemo.lpi b/components/epiktimer/etdemo.lpi new file mode 100644 index 000000000..5210f9214 --- /dev/null +++ b/components/epiktimer/etdemo.lpi @@ -0,0 +1,134 @@ + + + + + + + + + + + <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> diff --git a/components/epiktimer/etdemo.lpr b/components/epiktimer/etdemo.lpr new file mode 100644 index 000000000..96ba3c5bc --- /dev/null +++ b/components/epiktimer/etdemo.lpr @@ -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. + diff --git a/components/epiktimer/etpackage.lpk b/components/epiktimer/etpackage.lpk new file mode 100644 index 000000000..eec5ea436 --- /dev/null +++ b/components/epiktimer/etpackage.lpk @@ -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> diff --git a/components/epiktimer/etpackage.pas b/components/epiktimer/etpackage.pas new file mode 100644 index 000000000..0ebe5c964 --- /dev/null +++ b/components/epiktimer/etpackage.pas @@ -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. diff --git a/components/epiktimer/graphics/tepiktimer.xpm b/components/epiktimer/graphics/tepiktimer.xpm new file mode 100644 index 000000000..6d706350b --- /dev/null +++ b/components/epiktimer/graphics/tepiktimer.xpm @@ -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", +" ...... ", +" +@..@+ ", +" .. ...... .. ", +" .#@...######...@#. ", +" .+..++@@$$@@++..+. ", +" ..+@@@@$$@@@@+.. ", +" .+@.@@@@@@@@@@+. ", +" .+@@.@@@@@@.@@+. ", +" .+@@@@.@@@@.@@@@+. ", +" .+@@@@@.@@.@@@@@+. ", +" .#$$@@@@..@@@@$$#. ", +" .#$$@@@@..@@@@$$#. ", +" .+@@@@@@@@@@@@@@+. ", +" .+@@@@@@@@@@@@@@+. ", +"%%%%%%%%%%%%%%%%%%%%%%", +"%&.&&.&&.&&.&&.&&.&&&%", +"%&.&&.&&.&&.&&.&&.&&&%", +"%&.&&.&&.&&.&&.&&.&&&%", +"%&&&&.&&&&&.&&&&&.&&&%", +"%&&&&.&&&&&.&&&&&.&&&%", +"%&&&&&&&&&&&&&&&&&&&&%", +"%%%%%%%%%%%%%%%%%%%%%%", +" "}; diff --git a/components/epiktimer/main.lfm b/components/epiktimer/main.lfm new file mode 100644 index 000000000..7944567a4 --- /dev/null +++ b/components/epiktimer/main.lfm @@ -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 diff --git a/components/epiktimer/main.lrs b/components/epiktimer/main.lrs new file mode 100644 index 000000000..d305720b2 --- /dev/null +++ b/components/epiktimer/main.lrs @@ -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 + +]); + diff --git a/components/epiktimer/main.pas b/components/epiktimer/main.pas new file mode 100644 index 000000000..6438d87a4 --- /dev/null +++ b/components/epiktimer/main.pas @@ -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. + diff --git a/components/epiktimer/newsw.lfm b/components/epiktimer/newsw.lfm new file mode 100644 index 000000000..28ec9095e --- /dev/null +++ b/components/epiktimer/newsw.lfm @@ -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 diff --git a/components/epiktimer/newsw.lrs b/components/epiktimer/newsw.lrs new file mode 100644 index 000000000..a9b7708cf --- /dev/null +++ b/components/epiktimer/newsw.lrs @@ -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 + +]); + diff --git a/components/epiktimer/newsw.pas b/components/epiktimer/newsw.pas new file mode 100644 index 000000000..6d4e6d991 --- /dev/null +++ b/components/epiktimer/newsw.pas @@ -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. + diff --git a/components/epiktimer/splash.lfm b/components/epiktimer/splash.lfm new file mode 100644 index 000000000..55accaa8a --- /dev/null +++ b/components/epiktimer/splash.lfm @@ -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 diff --git a/components/epiktimer/splash.lrs b/components/epiktimer/splash.lrs new file mode 100644 index 000000000..58f2564e0 --- /dev/null +++ b/components/epiktimer/splash.lrs @@ -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 +]); diff --git a/components/epiktimer/splash.pas b/components/epiktimer/splash.pas new file mode 100644 index 000000000..43196fc3a --- /dev/null +++ b/components/epiktimer/splash.pas @@ -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. +