#include "mungal4.h" #pragma hdrstop #include "l4time.h" //#include //#include #include #include //############################################################################# //########################### System Clock ############################## //############################################################################# SystemClock SystemClock::timer; long SystemClock::ticksPerSecond; __int64 SystemClock::perfCounterFreq; __int64 SystemClock::perfCounterOrigin; //RB 1/20/07 //volatile long fast_time = 0L; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //void outportb(short portid, unsigned char value) //{ // __asm // { // MOV DX, portid // MOV AL, value // OUT DX, AL // } // __outbyte(portid, value); //} ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //// //unsigned char inportb(short portid) //{ // unsigned char retVal; // __asm // { // MOV DX, portid // IN AL, DX // MOV retVal, AL // } // return retVal; //} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // /*TIME RB 1/20/07 void Timer_Handler() { ++fast_time; }*/ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // // Milliseconds since this process started. // // It used to be milliseconds since the machine BOOTED, which is what // QueryPerformanceCounter counts from, and that had two consequences. // // The quiet one: Scalar is a 32-bit float, so an absolute time held in one // loses resolution as the number grows. Consecutive representable values // are 3.9ms apart after nine hours of uptime, 15.6ms after a day and a // half, and 31.25ms after three days - by which point the clock can no // longer resolve a single 20ms physics step. Anything computed by // subtracting two absolute times IN FLOAT inherits that, and the joystick // poll interval in L4CTRL is exactly such a subtraction: its 50ms test // quietly becomes 62.5ms after three days of uptime and 125ms after // twelve, so a player's controls grow less responsive the longer the // machine has been switched on. The smoke emitter in L4VIDRND has the same // defect, where adding a small interval to a large timestamp can round to // no change at all. // // The loud one: this returns a long, and milliseconds since boot overflows // one after 24.8 days. // // Counting from launch fixes both at the source and leaves every Time // arithmetic path untouched - those subtract ticks as integers and were // always exact. Peer machines already disagreed about this origin, having // booted at different moments, so the network is no worse off; reconciling // that is what RP412NETCLOCK does. // long SystemClock::GetRTC() { LARGE_INTEGER count; QueryPerformanceCounter(&count); return (long)( ((count.QuadPart - SystemClock::perfCounterOrigin) * (__int64)1000) / SystemClock::perfCounterFreq ); } double SystemClock::GetHiRes() { LARGE_INTEGER count; QueryPerformanceCounter(&count); return (count.QuadPart / (double)SystemClock::perfCounterFreq); } __int64 SystemClock::GetHiResTicks() { LARGE_INTEGER count; QueryPerformanceCounter(&count); return count.QuadPart; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SystemClock::SystemClock() { // //------------------------------- // Initialize the timer variables //------------------------------- // pauseStart = 0; pauseTime = 0; // //------------------------------ // Initialize the platform timer //------------------------------ // // query the performance counter for its frequency LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); //SystemClock::ticksPerSecond = freq.QuadPart; SystemClock::perfCounterFreq = freq.QuadPart; SystemClock::ticksPerSecond = 1000L; // // Time zero. Set here rather than on the first GetRTC call so that the // origin is fixed before anything can read the clock, and so no two // threads can race to establish it. // LARGE_INTEGER origin; QueryPerformanceCounter(&origin); SystemClock::perfCounterOrigin = origin.QuadPart; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SystemClock::Shutdown() { /*STUBBED: TIME RB 1/20/07 if (timer_handler_handle != 0xFFFF) { #if DEBUG_LEVEL>0 WORD err = sosTIMERRemoveEvent(timer_handler_handle); Verify(err == _ERR_NO_ERROR); err = sosTIMERUnInitSystem(0); Verify(err == _ERR_NO_ERROR); #else sosTIMERRemoveEvent(timer_handler_handle); sosTIMERUnInitSystem(0); #endif } */ } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // #define TIMER_CONTROL 0x43 #define GET_TIMER0 0xC2 #define TIMER0_PORT 0x40 #define OUTPUT_BIT 0x80 #undef inportb #undef outportb float Get_Frame_Percent_Used() { //STUBBED: SOS RB 1/14/07 ///* RB 1/11/07 //outportb(TIMER_CONTROL, GET_TIMER0); //int half = inportb(TIMER0_PORT) & OUTPUT_BIT; //int subtick = ((int)inportb(TIMER0_PORT)) >> 1; //subtick += (((int)inportb(TIMER0_PORT)) << 7); //*/ //__outbyte(TIMER_CONTROL, GET_TIMER0); //int half = __inbyte(TIMER0_PORT) & OUTPUT_BIT; //int subtick = ((int)__inbyte(TIMER0_PORT)) >> 1; //subtick += (((int)__inbyte(TIMER0_PORT)) << 7); //if (timer_handler_handle == 0xFFFF) //{ // subtick += half << 8; // return (65535 - subtick) / 65536.0f; //} //else //{ // if (half) // { // subtick += _wTIMERValue >> 1; // } // return (_wTIMERValue - 1 - subtick) / (float)_wTIMERValue; //} return 0.0f; }