home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_04 / Diver / Timer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  4.0 KB  |  116 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : timer.cpp                                                             //
  10. //  Description: High performance time count ( Pentium only )                        //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define WIN32_EXTRA_LEAN
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <mmsystem.h>
  19. #include <assert.h>
  20.  
  21. #include "Timer.h"
  22.  
  23. #define enable_asm  warning (disable : 4704)
  24. #define disable_asm warning (default : 4704)
  25.  
  26.  
  27. #define GetCycleCountInto(Low, High)             \
  28. {                                                \
  29.     _asm                _emit 0x0F               \
  30.     _asm                _emit 0x31               \
  31.     _asm                mov Low, eax             \
  32.     _asm                mov High, edx            \
  33. }                                                                
  34.  
  35. unsigned long  InitCycleHigh;
  36. unsigned long  InitCycleLow;
  37.  
  38. unsigned NestedTimer::GetCPUSpeed(void)
  39. {
  40.     if ( CPUSpeed10 == CPUSpeed16 ) // not initialized
  41.     {
  42.         unsigned l0, h0;
  43.         unsigned l1, h1;
  44.             
  45.         GetCycleCountInto(l0, h0);
  46.     
  47.         // delay for 800 ms
  48.         Sleep(800);
  49.         // for (unsigned t1=timeGetTime()+800; timeGetTime()<t1; ) 
  50.     
  51.         GetCycleCountInto(l1, h1);    
  52.     
  53.         CPUSpeed16 = (l1 - l0 + 5000)/50000;   // clock speed (Mhz) *16
  54.         CPUSpeed10 = (l1 - l0 + 8000)/80000;   // clock speed (Mhz) *10
  55.     }
  56.  
  57.     return CPUSpeed10;
  58. }
  59.  
  60. #pragma enable_asm
  61.  
  62. void ResetTimer(void)
  63. {   
  64.     // ensure CPUSpeed10, CPUSpeed16 get calculated
  65.     nTimer.GetCPUSpeed();
  66.     
  67.     GetCycleCountInto(InitCycleLow, InitCycleHigh); // starting cycle count
  68. }
  69.  
  70. // get timer in micro seconds
  71.  
  72. // 2^32 microsecond = 4294,967,296 = 4294 sec = 71 minutes
  73.  
  74. #pragma enable_asm
  75.  
  76. unsigned __declspec(naked) GetMicroSecond(void)
  77. {
  78.     __asm       _emit 0x0F                      // RDTSC: read clock counter into EDX:EAX
  79.     __asm       _emit 0x31                      // 32 bit EAX: 21 sec on 200 Mhz machine
  80.                                                 // EDX CycleHigh
  81.                                                 // EAX CycleLow
  82.                                                      
  83.     __asm       sub eax, InitCycleLow                                                     
  84.     __asm       sbb edx, InitCycleHigh          // Cycle-=InitCycle                                        
  85.                                                 // relative to first GetCPUSpeed call           
  86.         
  87.     __asm       add eax, eax
  88.     __asm       adc edx, edx
  89.         
  90.     __asm       add eax, eax
  91.     __asm       adc edx, edx
  92.                             
  93.     __asm       add eax, eax
  94.     __asm       adc edx, edx
  95.                             
  96.     __asm       add eax, eax
  97.     __asm       adc edx, edx
  98.                             
  99.     __asm       div nTimer.CPUSpeed16            // EAX=[CycleHigh,CycleLow] / CPUSpeed
  100.                                                  // rslt=EAX
  101.     __asm       ret
  102. }
  103.  
  104. #pragma disable_asm
  105.  
  106. // Nested Timer with overhead
  107.  
  108. NestedTimer nTimer;
  109.  
  110.  
  111. void _stdcall timer_Uninitialize(void)   //     uninitialized the timer to avoid overflow
  112. {   
  113.     ResetTimer();
  114.     nTimer.started = FALSE;
  115. }
  116.