/**************************************************************************** * * Ultra Long Period Timer * * Copyright (C) 1993-4 SciTech Software * All rights reserved. * * Filename: $Workfile: ulztimer.c $ * Version: $Revision: 1.0 $ * * Language: ANSI C * Environment: IBM PC (MSDOS and Windows) * * Description: Module to interface to the BIOS Timer Tick for timing * code that takes up to 24 hours (ray tracing etc). There * is a small overhead in calculating the time, this * will be negligible for such long periods of time. * * $Date: 05 Feb 1996 14:50:22 $ $Author: KendallB $ * ****************************************************************************/ #include "ztimer.h" #include "pmode.h" #ifdef __WINDOWS32__ #undef TRUE #undef FALSE #define WIN32_LEAN_AND_MEAN #include #include /* Win32 compatability routines. Win32 apps cannot program the timer and * ToolHelp is not available. However we can use the timeGetTime() function * to get the current time in ms since Windows started */ PRIVATE ulong tmStart,tmEnd; PRIVATE ulong start,finish; void ZTimerInit(void) {} void _ASMAPI LZTimerOn(void) { tmStart = timeGetTime(); } ulong _ASMAPI LZTimerLap(void) { ulong tmLap = timeGetTime(); return (tmLap - tmStart) * 1000L; } void _ASMAPI LZTimerOff(void) { tmEnd = timeGetTime(); } ulong _ASMAPI LZTimerCount(void) { return (tmEnd - tmStart) * 1000L; } void ULZTimerOn(void) { start = timeGetTime(); } void ULZTimerOff(void) { finish = timeGetTime(); } ulong ULZTimerLap(void) { return (timeGetTime() - start); } ulong ULZTimerCount(void) { return (start - finish); } float ULZTimerResolution(void) { return 0.001; } #elif defined(__WINDOWS16__) #undef TRUE #undef FALSE #include #include /* 16 bit Windows compatability routines. Rather than reading the timer * directly under Windows, we use the Windows API routines (which only * provide an accuracy of 1ms however). The timer interrupts are virtualised * under windows, which causes us to get incorrect results if we program * the timer directly. */ PRIVATE TIMERINFO tmStart,tmEnd,tmLap; PRIVATE TIMERINFO start,finish; void ZTimerInit(void) { tmStart.dwSize = tmEnd.dwSize = tmLap.dwSize = sizeof(TIMERINFO); start.dwSize = finish.dwSize = sizeof(TIMERINFO); } void _ASMAPI LZTimerOn(void) { TimerCount(&tmStart); } ulong _ASMAPI LZTimerLap(void) { TimerCount(&tmLap); return (tmLap.dwmsSinceStart - tmStart.dwmsSinceStart) * 1000L; } void _ASMAPI LZTimerOff(void) { TimerCount(&tmEnd); } ulong _ASMAPI LZTimerCount(void) { return (tmEnd.dwmsSinceStart - tmStart.dwmsSinceStart) * 1000L; } void ULZTimerOn(void) { TimerCount(&start); } void ULZTimerOff(void) { TimerCount(&finish); } ulong ULZTimerLap(void) { TimerCount(&tmLap); return (tmLap.dwmsSinceStart - start.dwmsSinceStart); } ulong ULZTimerCount(void) { return (finish.dwmsSinceStart - start.dwmsSinceStart); } float ULZTimerResolution(void) { return 0.001; } #else PRIVATE ulong start,finish; ushort _ASMAPI _ZTimerBIOS; void _ASMAPI LZ_disable(void); void _ASMAPI LZ_enable(void); void ZTimerInit(void) { _ZTimerBIOS = PM_getBIOSSelector(); } void ULZTimerOn(void) { start = ULZReadTime(); } void ULZTimerOff(void) { finish = ULZReadTime(); } ulong ULZTimerLap(void) { return ULZElapsedTime(start,ULZReadTime()); } ulong ULZTimerCount(void) { return ULZElapsedTime(start,finish); } ulong ULZReadTime(void) /**************************************************************************** * * Function: ULZReadTime * Returns: Current timer tick count. * * Description: We turn of interrupts while we * get the value from the BIOS data area since it is stored * as two bytes and an interrupt COULD stuff up our reading. * ****************************************************************************/ { ulong ticks; LZ_disable(); /* Turn of interrupts */ ticks = PM_getLong(_ZTimerBIOS,0x6C); LZ_enable(); /* Turn on interrupts again */ return ticks; } ulong ULZElapsedTime(ulong start,ulong finish) /**************************************************************************** * * Function: ULZElapsedTime * Parameters: start - Starting timer tick value * finish - Ending timer tick value * * Returns: Elapsed timer between starting time and ending time in * 1/18 ths of a second. * ****************************************************************************/ { /* Check to see whether a midnight boundary has passed, and if so * adjust the finish time to account for this. We cannot detect if * more that one midnight boundary has passed, so if this happens * we will be generating erronous results. */ if (finish < start) finish += 1573040L; /* Number of ticks in 24 hours */ return finish - start; } float ULZTimerResolution(void) /**************************************************************************** * * Function: ULZTimerResolution * Returns: Resolution of the ULZTimer routines (seconds in a tick) * ****************************************************************************/ { return 0.054925; } #endif /* DOS */