home *** CD-ROM | disk | FTP | other *** search
/ PC User 1997 April / PCU_APR_97.ISO / utils / cpu / cpuinfo / source / tstdll32 / tstdll32.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-06  |  16.9 KB  |  696 lines

  1. /***************************************************************
  2. * C file:  Tstdll32.c... for Tstdll32.exe
  3. *
  4. *       This program has been developed by Intel Corporation.  
  5. *        You have Intel's permission to incorporate this code 
  6. *       into your product, royalty free.  Intel has various 
  7. *        intellectual property rights which it may assert under
  8. *       certain circumstances, such as if another manufacturer's
  9. *       processor mis-identifies itself as being "GenuineIntel"
  10. *        when the CPUID instruction is executed.
  11. *
  12. *       Intel specifically disclaims all warranties, express or
  13. *       implied, and all liability, including consequential and
  14. *        other indirect damages, for the use of this code, 
  15. *        including liability for infringement of any proprietary
  16. *        rights, and including the warranties of merchantability
  17. *        and fitness for a particular purpose.  Intel does not 
  18. *        assume any responsibility for any errors which may 
  19. *        appear in this code nor any responsibility to update it.
  20. *
  21. *  * Other brands and names are the property of their respective
  22. *    owners.
  23. *
  24. *  Copyright (c) 1995, Intel Corporation.  All rights reserved.
  25. * History:
  26. *  June 12 96: fixed misdeclaration for wincpufeatures() -- now a DWORD
  27. *            : added message for MMX(TM) Technology processors
  28. *  Aug 96    : added check for missing dll.  
  29. *
  30. ***************************************************************/
  31.  
  32. #include <windows.h>
  33. #include <stdio.h>
  34. #include <math.h>
  35.  
  36. #include "tstdll32.h"
  37. #include "resource.h"
  38.  
  39.  
  40.  
  41. HINSTANCE hLibrary;                //handle for cpuinf32 dll
  42.  
  43. WORD (FAR *lpfnwincpuid)();
  44. WORD (FAR *lpfnwincpuidsupport)();
  45. WORD (FAR *lpfnwincpuidext)();
  46. DWORD (FAR *lpfnwincpufeatures)();
  47. ushort(FAR PASCAL *lpfngetdllversion)();
  48. struct TIME_STAMP (FAR *lpfnwinrdtsc)();
  49. struct FREQ_INFO  (FAR *lpfnwincpuspeed)(int BSFclocks);
  50.  
  51. HWND    hWnd;
  52. HDC         hDC;
  53.  
  54. #if !defined (APIENTRY)
  55.         #define    APIENTRY pascal
  56. #endif
  57.  
  58.  
  59.         // The name of this application
  60. #define APPCLASSNAME "tstdll32"
  61.  
  62.  
  63.  
  64. HINSTANCE hInst;
  65. char szAppName[] = "tstdll32";
  66. char szAppIconName[] = "test32icon";
  67. char szTitle[]   = "32-bit dll test";
  68. char szAppClass[32];
  69.  
  70.  
  71. /***************************************************************
  72. * WinMain()
  73. *
  74. * Inputs:
  75. *    hInstance        Main window handle instance
  76. *    hPrevInstance    Previous window handle instance
  77. *    lpCmdLine        Pointer to command line string
  78. *    nCmdShow        Window display flag
  79. *
  80. * Results:
  81. *    return value of the PostQuitMessage function if the function
  82. *       is successful.
  83. *    return NULL if it terminates before entering the message 
  84. *      loop.            
  85. ***************************************************************/
  86.  
  87. int APIENTRY WinMain ( HINSTANCE hInstance, 
  88.                        HINSTANCE hPrevInstance,
  89.                           LPSTR lpCmdLine, int nCmdShow )
  90. {
  91.         char buf[512]="";        // String Variable for 
  92.                                     //   Message Boxes
  93.  
  94.     //Load CPUINF32.DLL and do CPUID
  95.     if (LoadLibrary(CPUINFODLL)==NULL) {
  96.  
  97.         if (LOBYTE(LOWORD(GetVersion()))<4) {
  98.                 
  99.             return (FALSE);                    // if DLL not found exit app
  100.             }
  101.         else {
  102.             sprintf(buf, "CPUINF32.DLL not found");
  103.                MessageBox(NULL,buf,"Error", MB_ICONINFORMATION); 
  104.             return (FALSE);                    // if DLL not found exit app
  105.             }
  106.     }//if
  107.     else {
  108.     
  109.     
  110.     sprintf( szAppClass, "%s%d", APPCLASSNAME, hInstance);
  111.     if (!InitApplication( hInstance)) {
  112.         return (FALSE);
  113.     }
  114.     // Initialization for specific instance
  115.     if (!InitInstance(hInstance, nCmdShow)) {
  116.         return (FALSE);
  117.     }
  118.     EventLoop(hInstance);
  119.     return 0;
  120.  
  121.     lpCmdLine;
  122.    }
  123. } // WinMain()
  124.  
  125.  
  126.  
  127. /***************************************************************
  128. * InitApplication()
  129. *
  130. * Inputs:
  131. *    hInstance    Handle for first instance of app
  132. *
  133. * Returns:
  134. *    atom that uniquely identifies the class being registered.
  135. *    zero if an error occurs.
  136. ***************************************************************/
  137.  
  138. BOOL InitApplication( HINSTANCE hInstance)
  139. {    // called for first instance of app
  140.     WNDCLASS  wc;
  141.  
  142.     wc.style = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC);
  143.     
  144.     wc.lpfnWndProc   = (WNDPROC)WndProc;    // Window Procedure
  145.     
  146.     wc.cbClsExtra    = 0;                    // No per-class 
  147.                                             //   extra data.
  148.     
  149.     wc.cbWndExtra    = (int)NULL;            // 4-bytes extra 
  150.                                             //   data.
  151.     
  152.     wc.hInstance     = hInstance;            // Owner of this
  153.                                             //   class
  154.     
  155.     wc.hIcon         = LoadIcon (hInstance, szAppIconName);    
  156.                                             // Icon name from 
  157.                                             //   .RC
  158.     
  159.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     
  160.                                             // Cursor
  161.     
  162.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        
  163.                                             // Default color
  164.     
  165.     wc.lpszMenuName  = szAppName;            // Menu name from
  166.                                             //   .RC file
  167.     
  168.     wc.lpszClassName = szAppClass;            // Name to register
  169.                                             //   as
  170.  
  171.     return (RegisterClass(&wc));
  172. } // InitApplication()
  173.  
  174.  
  175.  
  176. /***************************************************************
  177. * InitInstance()
  178. * Purpose:
  179. *   Initialization for first instance of app.
  180. *
  181. * Inputs:
  182. *    hInstance    Main window handle instance 
  183. *    nCmdShow    Main window display flag
  184. *
  185. * Returns:
  186. *    Always returns true.
  187. ***************************************************************/
  188.  
  189. BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
  190. {
  191.     HWND    wHdl;
  192.  
  193.  
  194.     hInst = hInstance;             // Save instance handle
  195.                                 
  196.                                 // Main window for this app 
  197.                                 //   instance.
  198.     wHdl = CreateWindow(
  199.         szAppClass,                // See RegisterClass()
  200.         szTitle,                // Window title bar
  201.         WS_OVERLAPPEDWINDOW,    // Window style.
  202.         CW_USEDEFAULT,            // Init x pos
  203.         CW_USEDEFAULT,            // Init y pos
  204.         CW_USEDEFAULT,            // Init x size
  205.         CW_USEDEFAULT,            // Init y size
  206.         
  207.         NULL,                    // Overlapped windows have no 
  208.                                 //   parent.
  209.         
  210.         NULL,                    // Use the window class menu.
  211.         
  212.         hInstance,                // This instance owns this 
  213.                                 //   window.
  214.         
  215.         NULL                    // We don't use any data in our
  216.                                 //   WM_CREATE
  217.     );
  218.  
  219.  
  220.     // Make the window visible; update its client area; 
  221.     //   and return "success"
  222.     
  223.     ShowWindow(wHdl, nCmdShow); // Show the window
  224.     UpdateWindow(wHdl);            // Sends WM_PAINT message
  225.  
  226.     hWnd = wHdl;                // Used in actions.c
  227.     return (TRUE);                // We succeeded...
  228.  
  229. } // InitInstance()
  230.  
  231.  
  232.  
  233. /***************************************************************
  234. * EventLoop()
  235. *
  236. * Inputs:
  237. *    hInstance    Window instance handle
  238. *
  239. * Returns: none
  240. ***************************************************************/
  241.  
  242. void EventLoop(HINSTANCE hInstance)
  243. {
  244.     MSG     msg;
  245.      HANDLE hAccel;
  246.  
  247.     hAccel=LoadAccelerators(hInstance, szAppName);
  248.     while (GetMessage(&msg,     // Message structure
  249.               NULL,               // Handle of window receiving 
  250.                                   //   the message
  251.               0,                  // Lowest message to examine
  252.               0))                 // Highest message to examine
  253.     {
  254.     
  255.     if (!TranslateAccelerator (hWnd,hAccel, &msg)) {
  256.     TranslateMessage(&msg);        // Translates virtual key codes
  257.     DispatchMessage(&msg);         // Dispatches message to window
  258.     }
  259.  
  260.     }
  261. } // EventLoop()       
  262.  
  263.  
  264. void GetSpeed( int iType )
  265. {
  266.     WORD    cpu_type   = 0;    // CPU Family variable
  267.     WORD    extensions = 0; // CPU Extensions variable
  268.     DWORD    features   = 0;    // CPU Features variable
  269.     
  270.     ushort    version       = 0; // CPUINFO DLL Version
  271.  
  272.     struct FREQ_INFO cpu_speed;        // Return variable 
  273.                                             //   structure for 
  274.                                             //   cpuspeed 
  275.                                             //   routine
  276.             
  277.     char buf[512]="";        // String Variable for 
  278.                                     //   Message Boxes
  279.     
  280.       
  281.     
  282.     int u1,u2,exact;        // Statistical variables for
  283.     int d1,d2;                //   raw frequency analysis
  284.          
  285.     float per1,per2,per3;    // Statistical Percentages
  286.  
  287.     ulong norm_freq, raw_freq;        // Previous Normalized 
  288.                                     //   Frequency
  289.         
  290.     int missed=0;            // Keeps track of whether 
  291.                                     //   any speeds more than
  292.                                     //   3 MHz from the 
  293.                                     //   normalized occurred
  294.         
  295.        LARGE_INTEGER start, end;    // Variables to delay
  296.     ulong time;                    //   determine average
  297.                                         //    per test 
  298.  
  299.     int i, response;            // Variable for processing
  300.                                     //   MessageBox responses
  301.                 
  302.  
  303.     hLibrary=LoadLibrary(CPUINFODLL);
  304.  
  305.     (FARPROC) lpfnwincpuspeed = 
  306.             GetProcAddress(hLibrary,"cpuspeed");
  307.                 
  308.     cpu_speed = (*lpfnwincpuspeed)(iType);
  309.                 
  310.     if ( cpu_speed.in_cycles == 0 && cpu_speed.ex_ticks  == 0 ) {
  311.                      
  312.          sprintf(buf,
  313.                  "This processor cannot be accurately "
  314.                  "timed with this program.\n The "
  315.                  "processor is either an Intel Clone "
  316.                  "or is below 80386 level.");
  317.          MessageBox(NULL,buf,"error", MB_ICONINFORMATION );
  318.     }
  319.  
  320.     sprintf(buf,
  321.             "Clock Cycles: %lu cycles\n"
  322.             "Elapsed Time: %luus\n"
  323.             "Raw Clock Frequency: %luMHz\n"
  324.             "Normalized Frequency: %luMHz",
  325.             cpu_speed.in_cycles,
  326.             cpu_speed.ex_ticks,
  327.             cpu_speed.raw_freq,
  328.             cpu_speed.norm_freq);          
  329.  
  330.     MessageBox(NULL,buf,"32-bit cpuspeed", 
  331.                 MB_ICONINFORMATION );
  332.  
  333.     if ( iType == -1 )    // If Cmos time, then return because too slow
  334.         return;
  335.  
  336.     sprintf(buf,
  337.             "Would you like to perform\n"
  338.             "  a 1000 iteration test?");
  339.  
  340.     response = MessageBox(NULL,buf,"test", 
  341.             MB_YESNO|MB_ICONQUESTION );
  342.                 
  343.     if ( response == IDNO ) {
  344.             
  345.         FreeLibrary(hLibrary);
  346.         return;
  347.     }
  348.         
  349.     // Testing Code.... Runs 100 times and does 
  350.     //   statistical analysis on the data returned.
  351.     //       --BEGIN--
  352.             
  353.     norm_freq = cpu_speed.norm_freq;
  354.     raw_freq = cpu_speed.raw_freq;
  355.     u2=0;
  356.     u1=0;
  357.     exact=0;
  358.     d1=0;
  359.     d2=0;
  360.  
  361.     QueryPerformanceCounter(&start);
  362.  
  363.     for ( i = 0; i<1000; i++ ) {
  364.  
  365.            cpu_speed = (*lpfnwincpuspeed)(iType);
  366.                             
  367.         switch ( (int)cpu_speed.norm_freq - 
  368.                  (int)norm_freq ) {
  369.                         
  370.             case 0:
  371.                 exact++;
  372.                 break;
  373.                         
  374.             case 1:
  375.                 u1++;
  376.                 break;
  377.                         
  378.             case 2:
  379.                 u2++;
  380.                 break;
  381.                         
  382.             case -1:
  383.                 d1++;
  384.                 break;
  385.                     
  386.             case -2:
  387.                 d2++;
  388.                 break;
  389.                     
  390.             default:
  391.                 missed++; // Set missed flag; deviate more than 3Mhz
  392.         }
  393.     }
  394.                 
  395.     QueryPerformanceCounter(&end);
  396.                 
  397.     time = (ulong) (end.LowPart - start.LowPart);
  398.     time = time / 1193180;
  399.  
  400.     per1 = (float)((float)exact/10.0);
  401.                 
  402.     per2 = (float)((float)(u1+d1)/10.0);
  403.                 
  404.     per3 = (float)((float)(u2+d2)/10.0);
  405.  
  406.     sprintf(buf,
  407.             "%luMHz\t%luMHz\t%luMHz\t%luMHz\t%luMHz\n"
  408.             "  %03d\t  %03d\t  %03d\t  %03d\t  %03d\t"
  409.             "\n\n"
  410.             "Exact value  \t: %.2f\n"
  411.             "Within 1 MHz \t: %.2f\n"
  412.             "Within 2 MHz \t: %.2f\n\n"
  413.             "Beyond 2 MHz \t: %.2f\n\n"
  414.             "----->  Normalized Speed  \t=  %lu\n"
  415.             "----->    Raw Speed       \t=  %lu\n\n"
  416.             "   Delay per test = %dms",
  417.             norm_freq-2,norm_freq-1,norm_freq,norm_freq+1,norm_freq+2,d2,d1,
  418.             exact,u1,u2,per1,per2,per3,0.0,
  419.             norm_freq,raw_freq,time);
  420.                 
  421.     MessageBox(NULL,buf,"32-bit cpuspeed",
  422.                 MB_ICONINFORMATION );
  423.  
  424.     //        --END--
  425.     // Testing Code.... Ran 100 times and did 
  426.     //   statistical analysis on the data returned.
  427.                                                    
  428.     FreeLibrary(hLibrary);
  429. }
  430.  
  431.  
  432. /***************************************************************
  433. * WndProc(HWND, UINT, WPARAM, LPARAM)
  434. *
  435. * Purpose:
  436. *   Processes messages
  437. *
  438. * Messages:
  439. *    WM_COMMAND    - application menu (About dialog box)
  440. *    WM_DESTROY    - destroy window
  441. *
  442. * Inputs:
  443. *   hWnd        Window Handle
  444. *   message        Type of Message
  445. *   uParam        Additional Information
  446. *    LParam        Additional Information
  447. *
  448. * Returns:
  449. *   LRESULT returned by DefWindowProc or 0
  450. ***************************************************************/
  451.  
  452. LRESULT CALLBACK WndProc(
  453.       HWND hWnd,                 // Window handle
  454.       UINT message,              // Type of message
  455.       WPARAM uParam,             // Additional information
  456.       LPARAM lParam              // Additional information
  457.       )
  458. {                                // Message Handler
  459.     PAINTSTRUCT    ps;                                         
  460.     
  461.     switch (message) {
  462.         
  463.         case WM_CREATE:
  464.             hDC = GetDC( hWnd);
  465.             break;
  466.     
  467.         case WM_SIZE:
  468.             break ;
  469.  
  470.         case WM_PAINT:
  471.             hDC=BeginPaint(hWnd,&ps);
  472.             EndPaint(hWnd,&ps);
  473.             break;
  474.  
  475.         case WM_CLOSE:
  476.             return (DefWindowProc(hWnd,message,uParam,lParam));
  477.             break;
  478.  
  479.         case WM_DESTROY:    // Message: window being destroyed
  480.             PostQuitMessage(0);
  481.             break;
  482.  
  483.          case WM_COMMAND:    // Message: command from application 
  484.                              //   menu
  485.         {
  486.            
  487.             WORD    cpu_type   = 0;    // CPU Family variable
  488.             WORD    extensions = 0; // CPU Extensions variable
  489.             DWORD    features   = 0;    // CPU Features variable
  490.     
  491.             ushort    version       = 0; // CPUINFO DLL Version
  492.  
  493.             int major, minor;        // Variables for storing DLL
  494.                                     //   version
  495.  
  496.             char buf[512]="";        // String Variable for 
  497.                                     //   Message Boxes
  498.     
  499.         
  500.             int missed=0;            // Keeps track of whether 
  501.                                     //   any speeds more than
  502.                                     //   3 MHz from the 
  503.                                     //   normalized occurred
  504.         
  505.             char misses[256]= "";    // Keeps track of all raw 
  506.                                     //   speeds more than 3 MHz
  507.                                     //   from the normalized 
  508.                                     //   value
  509.  
  510.             struct TIME_STAMP stamp;    
  511.                                     // Variable for 64-bit Time
  512.                                     //   Stamp read
  513.  
  514.                int cpuid_support;        // Flag to determine whether
  515.                                     //   CPUID opcode is 
  516.                                     //   supported
  517.  
  518.         
  519.             WORD wmId, wmEvent;
  520.         
  521.             wmId    = LOWORD(uParam);
  522.             wmEvent = HIWORD(uParam);
  523.          
  524.             switch(LOWORD(uParam)) {
  525.  
  526.  
  527.             case IDM_EXIT:
  528.             
  529.                 SendMessage(hWnd, WM_CLOSE, 0, 0l);
  530.                 break;
  531.  
  532.  
  533.             case IDM_CPUID:
  534.  
  535.                 hLibrary=LoadLibrary(CPUINFODLL);
  536.             
  537.                 (FARPROC) lpfnwincpuid = 
  538.                         GetProcAddress(hLibrary,"wincpuid");
  539.                 (FARPROC) lpfnwincpuidsupport =
  540.                         GetProcAddress(hLibrary,
  541.                             "wincpuidsupport");
  542.                 
  543.                 cpu_type = (*lpfnwincpuid)();
  544.                 cpuid_support = (*lpfnwincpuidsupport)();
  545.  
  546.                 FreeLibrary(hLibrary);
  547.  
  548.                 if ( cpu_type & CLONE_MASK )
  549.                     sprintf(buf,"Intel Clone CPU Family : %x",
  550.                         cpu_type);
  551.  
  552.                 else if ( cpuid_support )    
  553.                                     // Intel processor presence 
  554.                                     //   can only be verified if
  555.                                     //   CPUID opcode is 
  556.                                     //   supported and the 
  557.                                     //   GenuineIntel vendor ID 
  558.                                     //   is read.
  559.                                                 
  560.                     sprintf(buf,"Intel CPU Family : %x",
  561.                         cpu_type);
  562.                 
  563.                 else
  564.                     sprintf(buf,"CPU Family : %x", cpu_type);
  565.             
  566.                 MessageBox(NULL,buf,"wincpuid",
  567.                     MB_ICONINFORMATION);
  568.                 
  569.                 break;
  570.  
  571.         case IDM_CPUID2:
  572.  
  573.                 hLibrary=LoadLibrary(CPUINFODLL);           
  574.                 
  575.                 (FARPROC) lpfnwincpuidext = 
  576.                         GetProcAddress(hLibrary,"wincpuidext");
  577.                 
  578.                 extensions = (*lpfnwincpuidext)();
  579.    
  580.                    FreeLibrary(hLibrary);
  581.  
  582.                 sprintf(buf,"Type/Family/Model/Stepping: %.4x",
  583.                         extensions);
  584.                 
  585.                 MessageBox(NULL,buf,"wincpuidext",
  586.                     MB_ICONINFORMATION);
  587.  
  588.                 break;
  589.  
  590.         case IDM_CMOSSPEED:
  591.             {
  592.                 int response;
  593.  
  594.                 response = MessageBox(NULL,"This feature is not supported for NT; do you want to continue?","test", 
  595.                                     MB_YESNO|MB_ICONQUESTION );
  596.                 
  597.                 if ( response == IDYES ) {
  598.                     GetSpeed( -1 );
  599.                 }
  600.             }
  601.             break;
  602.  
  603.         case IDM_CPUSPEED:
  604.                 GetSpeed( 0 );
  605.                 break;
  606.  
  607.  
  608.         case IDM_FEATUREFLAGS:
  609.  
  610.                 hLibrary=LoadLibrary(CPUINFODLL);
  611.                 
  612.                 (FARPROC) lpfnwincpufeatures = 
  613.                         GetProcAddress(hLibrary,
  614.                         "wincpufeatures");
  615.                 
  616.                 features = (*lpfnwincpufeatures)();
  617.         
  618.             /*Print extra line in message for MMX(TM) technology processor, ie, features(23)=1*/
  619.                 if (features & 0x00800000) //then MMX(TM) technology
  620.                  sprintf(buf,
  621.                    "Feature Flags: %.8x \n on a processor with MMX(TM) technology", features);
  622.                 else 
  623.                  sprintf(buf,"Feature Flags: %.8x",features);        
  624.                 /***************************/
  625.  
  626.                 
  627.                 MessageBox(NULL,buf,"wincpufeatures",
  628.                     MB_ICONINFORMATION);
  629.                 FreeLibrary(hLibrary);
  630.                 break;
  631.  
  632.         case IDM_READ:
  633.                 
  634.                 hLibrary=LoadLibrary(CPUINFODLL);
  635.                 (FARPROC) lpfnwinrdtsc = 
  636.                     GetProcAddress(hLibrary,"winrdtsc");
  637.                     
  638.                 stamp=(*lpfnwinrdtsc)();
  639.                 
  640.                 if ( stamp.High != 0 || stamp.Low != 0 ) {
  641.                 
  642.                     sprintf(buf,"Time Stamp: %08lx  %08lx",
  643.                         stamp.High,stamp.Low);
  644.                     
  645.                     MessageBox(NULL,buf,"winrdtsc",
  646.                         MB_ICONINFORMATION);
  647.                 
  648.                 }
  649.                 else {
  650.                     
  651.                     MessageBox(NULL,"Time Stamping not "
  652.                         "available on this system","error",
  653.                         MB_ICONINFORMATION);
  654.                 
  655.                 }
  656.                 
  657.                 FreeLibrary(hLibrary);
  658.                 break;
  659.             
  660.  
  661.         case IDM_GETDLLVERSION:
  662.             
  663.                 hLibrary=LoadLibrary(CPUINFODLL);
  664.                 (FARPROC) lpfngetdllversion =
  665.                     GetProcAddress(hLibrary,"getdllversion");
  666.                     
  667.                 version = (*lpfngetdllversion)();
  668.                 
  669.                 major = version >> 8;        // Shift out minor
  670.                                             //   version.
  671.                                             
  672.                 minor = version - major*256;    // Subtract off
  673.                                                 //   major 
  674.                                                 //   version.
  675.                 
  676.                 sprintf(buf,"CPUINFO32 DLL Version: %x.%x",
  677.                     major,minor);
  678.                 
  679.                 MessageBox(NULL,buf,"getdllversion",
  680.                     MB_ICONINFORMATION);
  681.                 
  682.                 FreeLibrary(hLibrary);    
  683.                 break;
  684.  
  685.         }
  686.     }
  687.  
  688.     default:          // Passes it on if unproccessed
  689.          return (DefWindowProc(hWnd, message, uParam, lParam));
  690.     }
  691.  
  692.     return (0);
  693. }
  694.  
  695.