summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/ztimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/ztimer.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/ztimer.c517
1 files changed, 517 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/ztimer.c b/board/MAI/bios_emulator/scitech/src/pm/ztimer.c
new file mode 100644
index 0000000000..35081e9a36
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/pm/ztimer.c
@@ -0,0 +1,517 @@
+/****************************************************************************
+*
+* SciTech OS Portability Manager Library
+*
+* ========================================================================
+*
+* The contents of this file are subject to the SciTech MGL Public
+* License Version 1.0 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.scitechsoft.com/mgl-license.txt
+*
+* Software distributed under the License is distributed on an
+* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
+*
+* The Initial Developer of the Original Code is SciTech Software, Inc.
+* All Rights Reserved.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+*
+* Description: Module to implement high precision timing on each OS.
+*
+****************************************************************************/
+
+#include "ztimer.h"
+#include "pmapi.h"
+#include "oshdr.h"
+
+/*---------------------------- Global variables ---------------------------*/
+
+static LZTimerObject LZTimer;
+static ulong start,finish;
+#ifdef __INTEL__
+static long cpuSpeed = -1;
+static ibool haveRDTSC = false;
+#endif
+
+/*----------------------------- Implementation ----------------------------*/
+
+/* External Intel assembler functions */
+#ifdef __INTEL__
+/* {secret} */
+void _ASMAPI _CPU_readTimeStamp(CPU_largeInteger *time);
+/* {secret} */
+ulong _ASMAPI _CPU_diffTime64(CPU_largeInteger *t1,CPU_largeInteger *t2,CPU_largeInteger *t);
+/* {secret} */
+ulong _ASMAPI _CPU_calcMicroSec(CPU_largeInteger *count,ulong freq);
+#endif
+
+#if defined(__SMX32__)
+#include "smx/ztimer.c"
+#elif defined(__RTTARGET__)
+#include "rttarget/ztimer.c"
+#elif defined(__REALDOS__)
+#include "dos/ztimer.c"
+#elif defined(__NT_DRIVER__)
+#include "ntdrv/ztimer.c"
+#elif defined(__WIN32_VXD__)
+#include "vxd/ztimer.c"
+#elif defined(__WINDOWS32__)
+#include "win32/ztimer.c"
+#elif defined(__OS2_VDD__)
+#include "vdd/ztimer.c"
+#elif defined(__OS2__)
+#include "os2/ztimer.c"
+#elif defined(__LINUX__)
+#include "linux/ztimer.c"
+#elif defined(__QNX__)
+#include "qnx/ztimer.c"
+#elif defined(__BEOS__)
+#include "beos/ztimer.c"
+#else
+#error Timer library not ported to this platform yet!
+#endif
+
+/*------------------------ Public interface routines ----------------------*/
+
+/****************************************************************************
+DESCRIPTION:
+Initializes the Zen Timer library (extended)
+
+PARAMETERS:
+accurate - True of the speed should be measured accurately
+
+HEADER:
+ztimer.h
+
+REMARKS:
+This function initializes the Zen Timer library, and /must/ be called before
+any of the remaining Zen Timer library functions are called. The accurate
+parameter is used to determine whether highly accurate timing should be
+used or not. If high accuracy is needed, more time is spent profiling the
+actual speed of the CPU so that we can obtain highly accurate timing
+results, but the time spent in the initialisation routine will be
+significantly longer (on the order of 5 seconds).
+****************************************************************************/
+void ZAPI ZTimerInitExt(
+ ibool accurate)
+{
+ if (cpuSpeed == -1) {
+ __ZTimerInit();
+#ifdef __INTEL__
+ cpuSpeed = CPU_getProcessorSpeedInHZ(accurate);
+ haveRDTSC = CPU_haveRDTSC() && (cpuSpeed > 0);
+#endif
+ }
+}
+
+/****************************************************************************
+DESCRIPTION:
+Initializes the Zen Timer library.
+
+HEADER:
+ztimer.h
+
+REMARKS:
+This function initializes the Zen Timer library, and /must/ be called before
+any of the remaining Zen Timer library functions are called.
+****************************************************************************/
+void ZAPI ZTimerInit(void)
+{
+ ZTimerInitExt(false);
+}
+
+/****************************************************************************
+DESCRIPTION:
+Starts the Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+tm - Timer object to start timing with
+
+REMARKS:
+Starts the Long Period Zen Timer counting. Once you have started the timer,
+you can stop it with LZTimerOff or you can latch the current count with
+LZTimerLap.
+
+The Long Period Zen Timer uses a number of different high precision timing
+mechanisms to obtain microsecond accurate timings results whenever possible.
+The following different techniques are used depending on the operating
+system, runtime environment and CPU on the target machine. If the target
+system has a Pentium CPU installed which supports the Read Time Stamp
+Counter instruction (RDTSC), the Zen Timer library will use this to
+obtain the maximum timing precision available.
+
+Under 32-bit Windows, if the Pentium RDTSC instruction is not available, we
+first try to use the Win32 QueryPerformanceCounter API, and if that is not
+available we fall back on the timeGetTime API which is always supported.
+
+Under 32-bit DOS, if the Pentium RDTSC instruction is not available, we
+then do all timing using the old style 8253 timer chip. The 8253 timer
+routines provide highly accurate timings results in pure DOS mode, however
+in a DOS box under Windows or other Operating Systems the virtualization
+of the timer can produce inaccurate results.
+
+Note: Because the Long Period Zen Timer stores the results in a 32-bit
+ unsigned integer, you can only time periods of up to 2^32 microseconds,
+ or about 1hr 20mins. For timing longer periods use the Ultra Long
+ Period Zen Timer.
+
+SEE ALSO:
+LZTimerOff, LZTimerLap, LZTimerCount
+****************************************************************************/
+void ZAPI LZTimerOnExt(
+ LZTimerObject *tm)
+{
+#ifdef __INTEL__
+ if (haveRDTSC) {
+ _CPU_readTimeStamp(&tm->start);
+ }
+ else
+#endif
+ __LZTimerOn(tm);
+}
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Long Period Zen Timer and keeps it
+running.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+tm - Timer object to do lap timing with
+
+RETURNS:
+Count that has elapsed in microseconds.
+
+REMARKS:
+Returns the current count that has elapsed since the last call to
+LZTimerOn in microseconds. The time continues to run after this function is
+called so you can call this function repeatedly.
+
+SEE ALSO:
+LZTimerOn, LZTimerOff, LZTimerCount
+****************************************************************************/
+ulong ZAPI LZTimerLapExt(
+ LZTimerObject *tm)
+{
+#ifdef __INTEL__
+ CPU_largeInteger tmLap,tmCount;
+
+ if (haveRDTSC) {
+ _CPU_readTimeStamp(&tmLap);
+ _CPU_diffTime64(&tm->start,&tmLap,&tmCount);
+ return _CPU_calcMicroSec(&tmCount,cpuSpeed);
+ }
+ else
+#endif
+ return __LZTimerLap(tm);
+}
+
+/****************************************************************************
+DESCRIPTION:
+Stops the Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+tm - Timer object to stop timing with
+
+REMARKS:
+Stops the Long Period Zen Timer counting and latches the count. Once you
+have stopped the timer you can read the count with LZTimerCount. If you need
+highly accurate timing, you should use the on and off functions rather than
+the lap function since the lap function does not subtract the overhead of
+the function calls from the timed count.
+
+SEE ALSO:
+LZTimerOn, LZTimerLap, LZTimerCount
+****************************************************************************/
+void ZAPI LZTimerOffExt(
+ LZTimerObject *tm)
+{
+#ifdef __INTEL__
+ if (haveRDTSC) {
+ _CPU_readTimeStamp(&tm->end);
+ }
+ else
+#endif
+ __LZTimerOff(tm);
+}
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Long Period Zen Timer.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+tm - Timer object to compute the elapsed time with.
+
+RETURNS:
+Count that has elapsed in microseconds.
+
+REMARKS:
+Returns the current count that has elapsed between calls to
+LZTimerOn and LZTimerOff in microseconds.
+
+SEE ALSO:
+LZTimerOn, LZTimerOff, LZTimerLap
+****************************************************************************/
+ulong ZAPI LZTimerCountExt(
+ LZTimerObject *tm)
+{
+#ifdef __INTEL__
+ CPU_largeInteger tmCount;
+
+ if (haveRDTSC) {
+ _CPU_diffTime64(&tm->start,&tm->end,&tmCount);
+ return _CPU_calcMicroSec(&tmCount,cpuSpeed);
+ }
+ else
+#endif
+ return __LZTimerCount(tm);
+}
+
+/****************************************************************************
+DESCRIPTION:
+Starts the Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+REMARKS:
+Obsolete function. You should use the LZTimerOnExt function instead
+which allows for multiple timers running at the same time.
+****************************************************************************/
+void ZAPI LZTimerOn(void)
+{ LZTimerOnExt(&LZTimer); }
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Long Period Zen Timer and keeps it
+running.
+
+HEADER:
+ztimer.h
+
+RETURNS:
+Count that has elapsed in microseconds.
+
+REMARKS:
+Obsolete function. You should use the LZTimerLapExt function instead
+which allows for multiple timers running at the same time.
+****************************************************************************/
+ulong ZAPI LZTimerLap(void)
+{ return LZTimerLapExt(&LZTimer); }
+
+/****************************************************************************
+DESCRIPTION:
+Stops the Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+REMARKS:
+Obsolete function. You should use the LZTimerOffExt function instead
+which allows for multiple timers running at the same time.
+****************************************************************************/
+void ZAPI LZTimerOff(void)
+{ LZTimerOffExt(&LZTimer); }
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Long Period Zen Timer.
+
+HEADER:
+ztimer.h
+
+RETURNS:
+Count that has elapsed in microseconds.
+
+REMARKS:
+Obsolete function. You should use the LZTimerCountExt function instead
+which allows for multiple timers running at the same time.
+****************************************************************************/
+ulong ZAPI LZTimerCount(void)
+{ return LZTimerCountExt(&LZTimer); }
+
+/****************************************************************************
+DESCRIPTION:
+Starts the Ultra Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+REMARKS:
+Starts the Ultra Long Period Zen Timer counting. Once you have started the
+timer, you can stop it with ULZTimerOff or you can latch the current count
+with ULZTimerLap.
+
+The Ultra Long Period Zen Timer uses the available operating system services
+to obtain accurate timings results with as much precision as the operating
+system provides, but with enough granularity to time longer periods of
+time than the Long Period Zen Timer. Note that the resolution of the timer
+ticks is not constant between different platforms, and you should use the
+ULZTimerResolution function to determine the number of seconds in a single
+tick of the timer, and use this to convert the timer counts to seconds.
+
+Under 32-bit Windows, we use the timeGetTime function which provides a
+resolution of 1 millisecond (0.001 of a second). Given that the timer
+count is returned as an unsigned 32-bit integer, this we can time intervals
+that are a maximum of 2^32 milliseconds in length (or about 1,200 hours or
+50 days!).
+
+Under 32-bit DOS, we use the system timer tick which runs at 18.2 times per
+second. Given that the timer count is returned as an unsigned 32-bit integer,
+this we can time intervals that are a maximum of 2^32 * (1/18.2) in length
+(or about 65,550 hours or 2731 days!).
+
+SEE ALSO:
+ULZTimerOff, ULZTimerLap, ULZTimerCount, ULZElapsedTime, ULZReadTime
+****************************************************************************/
+void ZAPI ULZTimerOn(void)
+{ start = __ULZReadTime(); }
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Ultra Long Period Zen Timer and keeps it
+running.
+
+HEADER:
+ztimer.h
+
+RETURNS:
+Count that has elapsed in resolution counts.
+
+REMARKS:
+Returns the current count that has elapsed since the last call to
+ULZTimerOn in microseconds. The time continues to run after this function is
+called so you can call this function repeatedly.
+
+SEE ALSO:
+ULZTimerOn, ULZTimerOff, ULZTimerCount
+****************************************************************************/
+ulong ZAPI ULZTimerLap(void)
+{ return (__ULZReadTime() - start); }
+
+/****************************************************************************
+DESCRIPTION:
+Stops the Long Period Zen Timer counting.
+
+HEADER:
+ztimer.h
+
+REMARKS:
+Stops the Ultra Long Period Zen Timer counting and latches the count. Once
+you have stopped the timer you can read the count with ULZTimerCount.
+
+SEE ALSO:
+ULZTimerOn, ULZTimerLap, ULZTimerCount
+****************************************************************************/
+void ZAPI ULZTimerOff(void)
+{ finish = __ULZReadTime(); }
+
+/****************************************************************************
+DESCRIPTION:
+Returns the current count for the Ultra Long Period Zen Timer.
+
+HEADER:
+ztimer.h
+
+RETURNS:
+Count that has elapsed in resolution counts.
+
+REMARKS:
+Returns the current count that has elapsed between calls to
+ULZTimerOn and ULZTimerOff in resolution counts.
+
+SEE ALSO:
+ULZTimerOn, ULZTimerOff, ULZTimerLap, ULZTimerResolution
+****************************************************************************/
+ulong ZAPI ULZTimerCount(void)
+{ return (finish - start); }
+
+/****************************************************************************
+DESCRIPTION:
+Reads the current time from the Ultra Long Period Zen Timer.
+
+HEADER:
+ztimer.h
+
+RETURNS:
+Current timer value in resolution counts.
+
+REMARKS:
+Reads the current Ultra Long Period Zen Timer and returns it’s current
+count. You can use the ULZElapsedTime function to find the elapsed time
+between two timer count readings.
+
+SEE ALSO:
+ULZElapsedTime, ULZTimerResolution
+****************************************************************************/
+ulong ZAPI ULZReadTime(void)
+{ return __ULZReadTime(); }
+
+/****************************************************************************
+DESCRIPTION:
+Compute the elapsed time between two timer counts.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+start - Starting time for elapsed count
+finish - Ending time for elapsed count
+
+RETURNS:
+Elapsed timer in resolution counts.
+
+REMARKS:
+Returns the elapsed time for the Ultra Long Period Zen Timer in units of the
+timers resolution (1/18th of a second under DOS). This function correctly
+computes the difference even if a midnight boundary has been crossed
+during the timing period.
+
+SEE ALSO:
+ULZReadTime, ULZTimerResolution
+****************************************************************************/
+ulong ZAPI ULZElapsedTime(
+ ulong start,
+ ulong finish)
+{ return __ULZElapsedTime(start,finish); }
+
+/****************************************************************************
+DESCRIPTION:
+Returns the resolution of the Ultra Long Period Zen Timer.
+
+HEADER:
+ztimer.h
+
+PARAMETERS:
+resolution - Place to store the timer in microseconds per timer count.
+
+REMARKS:
+Returns the resolution of the Ultra Long Period Zen Timer as a 32-bit
+integer value measured in microseconds per timer count.
+
+SEE ALSO:
+ULZReadTime, ULZElapsedTime, ULZTimerCount
+****************************************************************************/
+void ZAPI ULZTimerResolution(
+ ulong *resolution)
+{ *resolution = ULZTIMER_RESOLUTION; }
+
OpenPOWER on IntegriCloud