home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2005 March / PCpro_2005_03.ISO / files / systools / speedswitchxp / sswitchxp14.exe / Typical / Cpudata.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-14  |  21.1 KB  |  801 lines

  1. /*
  2.    SpeedswitchXP V1.4
  3.    - Windows XP CPU Frequency Control for Notebooks -
  4.  
  5.    Copyright(c) 2002-2004 Christian Diefer
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License version 2 as 
  9.    published by the Free Software Foundation.
  10.    
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.    
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #include "stdafx.h"
  22. #include "SpeedswitchXP.h"
  23. #include "CPUData.h"
  24. #include "cpuid.h"
  25. #include "speed.h"
  26.  
  27. // CCPUData dialog
  28.  
  29. IMPLEMENT_DYNAMIC(CCPUData, CDialog)
  30. CCPUData::CCPUData(CWnd* pParent /*=NULL*/)
  31.     : CDialog(CCPUData::IDD, pParent)
  32.   , m_szSupportsCPUID(_T(""))
  33.   , m_szVendor(_T(""))
  34.   , m_szFeatures(_T(""))
  35.   , m_iMaxIDVal(0)
  36.   , m_szManufacturer(_T(""))
  37.   , m_iFamily(0)
  38.   , m_iModel(0)
  39.   , m_iStepping(0)
  40.   , m_iFType(0)
  41.   , m_szMaxExLevel(_T(""))
  42.   , m_szExCPUName(_T(""))
  43.   , m_szExFeatures(_T(""))
  44.   , m_iBrandID(0)
  45.   , m_szBrandStr(_T(""))
  46.   , m_szExFeatures2(_T(""))
  47.   , m_szFlags(_T(""))
  48. { }
  49.  
  50. CCPUData::~CCPUData()
  51. { }
  52.  
  53. void CCPUData::DoDataExchange(CDataExchange* pDX)
  54. {
  55.   CDialog::DoDataExchange(pDX);
  56.   DDX_Text(pDX, IDC_EDIT1, m_szSupportsCPUID);
  57.   DDX_Text(pDX, IDC_EDIT4, m_szVendor);
  58.   DDX_Text(pDX, IDC_EDIT5, m_szFeatures);
  59.   DDX_Text(pDX, IDC_EDIT6, m_iMaxIDVal);
  60.   DDX_Text(pDX, IDC_EDIT7, m_szManufacturer);
  61.   DDX_Text(pDX, IDC_EDIT9, m_iFamily);
  62.   DDX_Text(pDX, IDC_EDIT10, m_iModel);
  63.   DDX_Text(pDX, IDC_EDIT11, m_iStepping);
  64.   DDX_Text(pDX, IDC_EDIT13, m_iFType);
  65.   DDX_Text(pDX, IDC_EDIT14, m_szMaxExLevel);
  66.   DDX_Text(pDX, IDC_EDIT15, m_szExCPUName);
  67.   DDX_Text(pDX, IDC_EDIT2, m_szExFeatures);
  68.   DDX_Text(pDX, IDC_EDIT8, m_iBrandID);
  69.   DDX_Text(pDX, IDC_EDIT12, m_szBrandStr);
  70.   DDX_Text(pDX, IDC_EDIT19, m_szExFeatures2);
  71.   DDX_Text(pDX, IDC_EDIT3, m_szFlags);
  72.   DDX_Control(pDX, IDC_EDIT3, m_eFeatures);
  73. }
  74.  
  75. BEGIN_MESSAGE_MAP(CCPUData, CDialog)
  76. END_MESSAGE_MAP()
  77.  
  78. // CCPUData message handlers
  79.  
  80. BOOL CCPUData::OnInitDialog()
  81. {
  82.   CDialog::OnInitDialog();
  83.   return TRUE;
  84. }
  85.  
  86. void CCPUData::setVars()
  87. {
  88.   init();
  89.   getCPUType();
  90.  
  91.   m_szExCPUName = cpuStr;
  92.   m_szVendor = vendorID;
  93.   m_iFType = typid;
  94.   m_iFamily = familyid;
  95.   m_iModel = modelid;
  96.   m_iStepping = steppingid;
  97.   m_szSupportsCPUID = (supportsCPUID ? "Yes" : "No");
  98.   m_iMaxIDVal = maxIDVal;
  99.   m_iBrandID = brandID & 255;
  100.   m_szBrandStr = brandStr;
  101.  
  102.   char text[64];
  103.   wsprintf( text, "0x%08x", features );
  104.   m_szFeatures = text;
  105.  
  106.   wsprintf( text, "0x%08x", exfeatures );
  107.   m_szExFeatures = text;
  108.  
  109.   wsprintf( text, "0x%08x", exfeatures2 );
  110.   m_szExFeatures2 = text;
  111.  
  112.   if( exlevel >= 0x80000000 )
  113.     wsprintf( text, "0x%08x", exlevel );
  114.   else
  115.     strcpy( text, "---" );
  116.   m_szMaxExLevel = text;
  117.  
  118.   memset( &lf, 0, sizeof(LOGFONT) ); 
  119.  
  120. //  CFont* pFont = m_eFeatures.GetFont();
  121. //  if( pFont != NULL )
  122. //    pFont->GetObject( sizeof(LOGFONT), &lf );
  123. //  else
  124. //    ::GetObject( GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf );
  125.  
  126.   lf.lfHeight = -13;
  127.   lf.lfWidth = 0;
  128.   lf.lfEscapement = 0;
  129.   lf.lfOrientation = 0;
  130.   lf.lfWeight = 400;
  131.   lf.lfItalic = 0;
  132.   lf.lfUnderline = 0;
  133.   lf.lfStrikeOut = 0;
  134.   lf.lfCharSet = 0;
  135.   lf.lfOutPrecision = 1;
  136.   lf.lfClipPrecision = 2;
  137.   lf.lfQuality = 1;
  138.   lf.lfPitchAndFamily = 49;
  139.   strcpy( lf.lfFaceName, "Courier" );
  140.  
  141.   mf.DeleteObject();
  142.   mf.CreateFontIndirect( &lf );
  143.   m_eFeatures.SetFont( &mf, true );
  144.   m_eFeatures.SetLimitText( 64000 );
  145.  
  146.   *flagText = '\0';
  147.  
  148.   if( f_fpu )   Message( "FPU   - Floating Point Unit" );
  149.   if( f_vme )   Message( "VME   - V86 Mode Extensions" );
  150.   if( f_de )    Message( "DE    - Debug Extensions" );
  151.   if( f_pse )   Message( "PSE   - Page Size Extensions" );
  152.   if( f_tsc )   Message( "TSC   - Timestamp Counter" );
  153.   if( f_msr )   Message( "MSR   - Model Specific Registers" );
  154.   if( f_pae )   Message( "PAE   - Physical Address Extensions" );
  155.   if( f_mce )   Message( "MCE   - Machine Check Exception" );
  156.   if( f_c8x )   Message( "C8X   - CMPXCHG8B Instruction" );
  157.   if( f_apic )  Message( "APIC  - Local APIC" );
  158.   if( f_sep )   Message( "SEP   - Fast System Call" );
  159.   if( f_mtrr )  Message( "MTRR  - Memory Type Range Registers" );
  160.   if( f_pge )   Message( "PGE   - Page Global Enable" );
  161.   if( f_mca )   Message( "MCA   - Machine Check Architecture" );
  162.   if( f_cmov )  Message( "CMOV  - CMOV Instructions" );
  163.   if( f_pse36 ) Message( "PSE36 - 36bit Page Size Extensions" );
  164.   if( f_psn )   Message( "PSN   - Processor Serial Number" );
  165.   if( f_mmx )   Message( "MMX   - MMX Instructions" );
  166.  
  167.   switch( vendor )
  168.   {
  169.     case 0: m_szManufacturer = "Intel";
  170.             if( f_acpi ) Message( "ACPI  - ACPI Support" );
  171.             if( f_pat )  Message( "PAT   - Page Attribute Table" );
  172.             if( f_fxsr ) Message( "FXSR  - FXSAVE/FXRSTOR Instructions" );
  173.             if( f_sse )  Message( "SSE   - SSE Instructions" );
  174.             if( f_sse2 ) Message( "SSE2  - SSE2 Instructions" );
  175.             if( f_ss )   Message( "SS    - Self Snoop" );
  176.             if( f_htt )  Message( "HTT   - Hyperthreading Technology" );
  177.             if( f_tm )   Message( "TM    - Thermal Monitoring" );
  178.             if( f_ia64 ) Message( "IA64  - IA64 Instructions" );
  179.             break;
  180.  
  181.     case 1: m_szManufacturer = "AMD";
  182.             if( f_fsc )      Message( "FSC   - Fast System Call" );
  183.             if( f_fcmov )    Message( "FCMOV - FCMOV Instruction" );
  184.             if( f_mmxext )   Message( "MMXE  - Extended MMX Instructions" );
  185.             if( f_sse )      Message( "SSE   - SSE Instructions" );
  186.             if( f_sse2 )     Message( "SSE2  - SSE2 Instructions" );
  187.             if( f_3dnowext ) Message( "3DNE  - Extended 3DNow! Instructions" );
  188.             if( f_3dnow )    Message( "3DNOW - 3DNow! Instructions" );
  189.             break;
  190.  
  191.     case 2: m_szManufacturer = "Cyrix";
  192.             if( f_cxmmx ) Message( "CXMMX - Cyrix MMX Instructions" );
  193.             break;
  194.  
  195.     case 3: m_szManufacturer = "Transmeta";
  196.             break;
  197.  
  198.     case 4: m_szManufacturer = "Centaur";
  199.             if( f_3dnow ) Message( "3DNOW - 3DNow! Instructions" );
  200.             break;
  201.  
  202.     case 5: m_szManufacturer = "Rise";
  203.             break;
  204.  
  205.     case 6: m_szManufacturer = "UMC";
  206.             break;
  207.  
  208.     case 7: m_szManufacturer = "NexGen";
  209.             break;
  210.  
  211.     default:m_szManufacturer = "Unknown";
  212.             break;
  213.   }
  214.  
  215.   m_szFlags = flagText;
  216. }
  217.  
  218. void CCPUData::getCPUType()
  219. {
  220.   cpuType = wincpuid();
  221.   supportsCPUID = wincpuidsupport();
  222.  
  223.   switch( cpuType & (CLONE_MASK-1) )
  224.   {
  225.     case 0: strcpy( cpuStr, "8086" );
  226.             break;
  227.  
  228.     case 1: strcpy( cpuStr, "80186" );
  229.             break;
  230.  
  231.     case 2: strcpy( cpuStr, "80286" );
  232.             break;
  233.  
  234.     case 3: strcpy( cpuStr, "80386" );
  235.             break;
  236.  
  237.     case 4: strcpy( cpuStr, "80486" );
  238.             break;
  239.  
  240.     case 5: strcpy( cpuStr, "Pentium" );
  241.             break;
  242.  
  243.     case 6: strcpy( cpuStr, "Pentium Pro" );
  244.             break;
  245.  
  246.     case 15:strcpy( cpuStr, "Pentium 4" );
  247.             break;
  248.  
  249.     default:strcpy( cpuStr, "Unknown" );
  250.             break;
  251.   }
  252.  
  253.   familyid = cpuType & (CLONE_MASK-1);
  254.  
  255.   if( !supportsCPUID )
  256.     return;
  257.  
  258.   getCPUFeatures();
  259.  
  260.   typid = (family & (3<<12))>>12;
  261.   familyid = (family&(15<<8))>>8;
  262.   modelid = (family&(15<<4))>>4;
  263.   steppingid = family&15;
  264.  
  265.   f_fpu = features & 1;
  266.   f_vme = features & 2;
  267.   f_de = features & 4;
  268.   f_pse = features & 8;
  269.   f_tsc = features & 16;
  270.   f_msr = features & 32;
  271.   f_pae = features & 64;
  272.   f_mce = features & 128;
  273.   f_c8x = features & (1<<8);
  274.   f_apic = features & (1<<9);
  275.   f_sep = features & (1<<11);
  276.   f_mtrr = features & (1<<12);
  277.   f_pge = features & 8192;
  278.   f_mca = features & 16384;
  279.   f_cmov = features & 32768;
  280.   f_pse36 = features & (1<<17);
  281.   f_psn = features & (1<<18);
  282.   f_mmx = features & (1<<23);
  283.  
  284.   if( !stricmp((char*)vendorID,"GenuineIntel") )
  285.   {
  286.     vendor = 0;   // Intel
  287.     f_pat = features & (1<<16);
  288.     f_acpi = features & (1<<22);
  289.     f_fxsr = features & (1<<24);
  290.     f_sse = features & (1<<25);
  291.     f_sse2 = features & (1<<26);
  292.     f_ss = features & (1<<27);
  293.     f_htt = features & (1<<28);
  294.     f_tm = features & (1<<29);
  295.     f_ia64 = features & (1<<30);
  296.     identifyIntel();
  297.   }
  298.   else if( !stricmp((char*)vendorID,"AuthenticAMD") )
  299.   {
  300.     vendor = 1;   // AMD
  301.     f_fsc = features & (1<<10);
  302.     f_fcmov = features & (1<<16);
  303.     f_mmxext = features & (1<<22);
  304.     f_sse = features & (1<<25);
  305.     f_sse2 = features & (1<<26);
  306. //    f_3dnowext = features & (1<<30);
  307. //    f_3dnow = features & (1<<31);
  308.     identifyAMD();
  309.   }
  310.   else if( !stricmp((char*)vendorID,"CyrixInstead") )
  311.   {
  312.     vendor = 2;   // Cyrix
  313.     f_cxmmx = features & (1<<24);
  314.   }
  315.   else if( !stricmp((char*)vendorID,"GenuineTMx86") )
  316.   {
  317.     vendor = 3;   // Transmeta
  318.   }
  319.   else if( !stricmp((char*)vendorID,"CentaurHauls") )
  320.   {
  321.     vendor = 4;   // Centaur
  322.     f_3dnow = features & (1<<31);
  323.   }
  324.   else if( !stricmp((char*)vendorID,"RISERISERISE") )
  325.   {
  326.     vendor = 5;   // Rise
  327.   }
  328.   else if( !stricmp((char*)vendorID,"UMC UMC UMC ") )
  329.   {
  330.     vendor = 6;   // UMC
  331.   }
  332.   else if( !stricmp((char*)vendorID,"NexGenDriven") )
  333.   {
  334.     vendor = 7;   // NexGen
  335.   }
  336.  
  337.   DWORD exl;
  338.  
  339.   __asm {
  340.     pushad
  341.     mov eax,0x80000000
  342.     CPU_ID
  343.     mov dword ptr exl,eax
  344.     popad
  345.   }
  346.  
  347.   exlevel = exl;
  348.  
  349.   if( exlevel>=0x80000001 && vendor==1 )  // nur bei AMD
  350.   {
  351.     DWORD amdflags;
  352.  
  353.     __asm {
  354.       pushad
  355.       mov eax, 0x80000001
  356.       CPU_ID
  357.       mov dword ptr amdflags, edx
  358.       popad
  359.     }
  360.  
  361.     exfeatures2 = amdflags;
  362.  
  363.     f_3dnow = amdflags & (1<<31);
  364.     f_3dnowext = amdflags & (1<<30);
  365.   }
  366.  
  367.   if( exlevel >= 0x80000004 )
  368.   {
  369.     DWORD pstr[12];
  370.  
  371.     __asm {
  372.       pushad
  373.       mov eax, 0x80000002
  374.       CPU_ID
  375.       mov dword ptr pstr, eax
  376.       mov dword ptr pstr+4, ebx
  377.       mov dword ptr pstr+8, ecx
  378.       mov dword ptr pstr+12, edx
  379.       mov eax, 0x80000003
  380.       CPU_ID
  381.       mov dword ptr pstr+16, eax
  382.       mov dword ptr pstr+20, ebx
  383.       mov dword ptr pstr+24, ecx
  384.       mov dword ptr pstr+28, edx
  385.       mov eax, 0x80000004
  386.       CPU_ID
  387.       mov dword ptr pstr+32, eax
  388.       mov dword ptr pstr+36, ebx
  389.       mov dword ptr pstr+40, ecx
  390.       mov dword ptr pstr+44, edx
  391.       popad
  392.     }
  393.  
  394.     strcpy( cpuStr, (char*)pstr );
  395.   }
  396. }
  397.  
  398. void CCPUData::identifyIntel()
  399. {
  400.   switch( familyid )
  401.   {
  402.     case 4: switch( modelid )
  403.             {
  404.               case 0:
  405.               case 1: strcpy( cpuStr, "80486DX" );
  406.                       break;
  407.  
  408.               case 2: strcpy( cpuStr, "80486SX" );
  409.                       break;
  410.  
  411.               case 3: strcpy( cpuStr, "80487/DX2/DX2 Overdrive" );
  412.                       break;
  413.  
  414.               case 4: strcpy( cpuStr, "80486SL" );
  415.                       break;
  416.  
  417.               case 5: strcpy( cpuStr, "80486SX2" );
  418.                       break;
  419.  
  420.               case 6: strcpy( cpuStr, "80486DX (write-back)" );
  421.                       break;
  422.  
  423.               case 7: strcpy( cpuStr, "80486DX4/DX4 Overdrive" );
  424.                       break;
  425.  
  426.               default:strcpy( cpuStr, "Unknown 80486" );
  427.                       break;
  428.             }
  429.             break;
  430.  
  431.     case 5: switch( modelid )
  432.             {
  433.               case 1: if( typid == 1 )
  434.                         strcpy( cpuStr, "Pentium OverDrive (60,66)" );
  435.                       else
  436.                         strcpy( cpuStr, "Pentium (60,66)" );
  437.                       break;
  438.  
  439.               case 2: if( typid == 1 )
  440.                         strcpy( cpuStr, "Pentium (75,90,100,120,133,150,166,200)" );
  441.                       else
  442.                         strcpy( cpuStr, "Pentium OverDrive (75,90,100,120,133,150,166,200)" );
  443.                       break;
  444.  
  445.               case 3: strcpy( cpuStr, "Pentium Overdrive (for 80486)" );
  446.                       break;
  447.  
  448.               case 4: if( typid == 1 )
  449.                         strcpy( cpuStr, "Pentium OverDrive MMC (75,90,100,120,133)" );
  450.                       else
  451.                         strcpy( cpuStr, "Pentium MMX (166,200)" );
  452.                       break;
  453.  
  454.               default:strcpy( cpuStr, "Unknown Pentium" );
  455.                       break;
  456.             }
  457.             break;
  458.  
  459.     case 6: switch( modelid )
  460.             {
  461.               case 0: strcpy( cpuStr, "Pentium Pro (A-Step)" );
  462.                       break;
  463.  
  464.               case 1: strcpy( cpuStr, "Pentium Pro" );
  465.                       break;
  466.  
  467.               case 3: if( typid == 1 )
  468.                         strcpy( cpuStr, "Pentium II OverDrive" );
  469.                       else
  470.                         strcpy( cpuStr, "Pentium II (Klamath)" );
  471.                       break;
  472.  
  473.               case 5: strcpy( cpuStr, "Pentium II/Pentium II Xeon/Celeron (0.25╡m)" );
  474.                       break;
  475.  
  476.               case 6: strcpy( cpuStr, "Celeron (model 6)" );
  477.                       break;
  478.  
  479.               case 7: strcpy( cpuStr, "Pentium III/Pentium III Xeon (0.25╡m)" );
  480.                       break;
  481.  
  482.               case 8: strcpy( cpuStr, "Pentium III/Pentium III Xeon/Celeron (Coppermine)" );
  483.                       break;
  484.  
  485.               case 9: strcpy( cpuStr, "Pentium-M (Banias)" );
  486.                       break;
  487.  
  488.               case 10:strcpy( cpuStr, "Pentium III/PIII Xeon (Coppermine)" );
  489.                       break;
  490.  
  491.               case 11:strcpy( cpuStr, "Pentium III (Tualatin)" );
  492.                       break;
  493.  
  494.               default:strcpy( cpuStr, "Unknown Pentium Pro/II/III" );
  495.                       break;
  496.             }
  497.             break;
  498.  
  499.     case 15:switch( modelid )
  500.             {
  501.               case 0: strcpy( cpuStr, "Pentium 4 Willamette" );
  502.                       break;
  503.  
  504.               case 1: strcpy( cpuStr, "Pentium 4 Willamette" );
  505.                       break;
  506.  
  507.               case 2: strcpy( cpuStr, "Pentium 4 Northwood" );
  508.                       break;
  509.  
  510.               case 3: strcpy( cpuStr, "Pentium 4 Prescott" );
  511.                       break;
  512.  
  513.               default:strcpy( cpuStr, "Unknown Pentium 4" );
  514.                       break;
  515.             }
  516.             break;
  517.  
  518.     default:strcpy( cpuStr, "Unknown Intel CPU" );
  519.             break;
  520.   }
  521.  
  522.   char* bstr = "";
  523.  
  524.   switch( brandID & 255 )
  525.   {
  526.     case 0: brandStr = "---";
  527.             break;
  528.  
  529.     case 1: bstr = "Celeron (Coppermine)";
  530.             break;
  531.  
  532.     case 2: bstr = "Pentium III (Coppermine)";
  533.             break;
  534.  
  535.     case 3: bstr = "Celeron/Pentium III Xeon (Coppermine)";
  536.             break;
  537.  
  538.     case 4: bstr = "Pentium III (Tualatin)";
  539.             break;
  540.  
  541.     case 6: bstr = "Mobile Pentium III-M (Tualatin)";
  542.             break;
  543.  
  544.     case 7: bstr = "Mobile Celeron (Tualatin)";
  545.             break;
  546.  
  547.     case 8: if( family == 0xf24 )
  548.               bstr = "Mobile Celeron 4 (Northwood)";
  549.             else
  550.               bstr = "Pentium 4 (Willamette)";
  551.             break;
  552.  
  553.     case 9: bstr = "Pentium 4 (Northwood)";
  554.             break;
  555.  
  556.     case 10:bstr = "Celeron 4 (Willamette)";
  557.             break;
  558.  
  559.     case 11:bstr = "Pentium 4 Xeon (Northwood/Willamette)";
  560.             break;
  561.  
  562.     case 12:bstr = "Pentium 4 Xeon MP (Northwood)";
  563.             break;
  564.  
  565.     case 14:bstr = "Mobile Pentium 4-M (Northwood)";
  566.             break;
  567.  
  568.     case 15:if( family == 0xf27 )
  569.               bstr = "Mobile Celeron 4 (Northwood)";
  570.             else
  571.               bstr = "Mobile Pentium 4-M (Northwood)";
  572.             break;
  573.  
  574.     case 22:bstr = "Pentium-M (Banias)";
  575.             break;
  576.  
  577.     default:brandStr = "---";
  578.             break;
  579.   }
  580.  
  581.   if( *bstr )
  582.   {
  583.     strcpy( cpuStr, bstr );
  584.     brandStr = bstr;
  585.   }
  586. }
  587.  
  588. void CCPUData::identifyAMD()
  589. {
  590.   switch( familyid )
  591.   {
  592.     case 4: switch( modelid )
  593.             {
  594.               case 3: strcpy( cpuStr, "486DX/2" );
  595.                       break;
  596.  
  597.               case 7: strcpy( cpuStr, "486DX/2-WB" );
  598.                       break;
  599.  
  600.               case 8: strcpy( cpuStr, "486DX/4" );
  601.                       break;
  602.  
  603.               case 9: strcpy( cpuStr, "486DX/4-WB" );
  604.                       break;
  605.  
  606.               case 14:strcpy( cpuStr, "Am5x86-WT" );
  607.                       break;
  608.  
  609.               case 15:strcpy( cpuStr, "Am5x86-WB" );
  610.                       break;
  611.  
  612.               default:strcpy( cpuStr, "Unknown 486/5x86 CPU" );
  613.                       break;
  614.             }
  615.             break;
  616.  
  617.     case 5: switch( modelid )
  618.             {
  619.               case 0: strcpy( cpuStr, "K5/SSA5 (PR75...PR100)" );
  620.                       break;
  621.  
  622.               case 1: strcpy( cpuStr, "K5 (PR120/PR133)" );
  623.                       break;
  624.  
  625.               case 2: strcpy( cpuStr, "K5 (PR150/PR166)" );
  626.                       break;
  627.  
  628.               case 3: strcpy( cpuStr, "K5 (PR200)" );
  629.                       break;
  630.  
  631.               case 6: strcpy( cpuStr, "K6 (166...233MHz)" );
  632.                       break;
  633.  
  634.               case 7: strcpy( cpuStr, "K6 (266...300MHz)" );
  635.                       break;
  636.  
  637.               case 8: strcpy( cpuStr, "K6-2 w/ 3DNow!" );
  638.                       break;
  639.  
  640.               case 9: strcpy( cpuStr, "K6-3 w/ 3DNow!" );
  641.                       break;
  642.  
  643.               case 13:strcpy( cpuStr, "K6-2+ / K6-III+ w/ 3DNow!" );
  644.                       break;
  645.  
  646.               default:strcpy( cpuStr, "Unknown K6 CPU" );
  647.                       break;
  648.             }
  649.             break;
  650.  
  651.     case 6: switch( modelid )
  652.             {
  653.               case 0:
  654.               case 1: strcpy( cpuStr, "Athlon (25um)" );
  655.                       break;
  656.  
  657.               case 2: strcpy( cpuStr, "Athlon (18um)" );
  658.                       break;
  659.  
  660.               case 3: strcpy( cpuStr, "Duron" );
  661.                       break;
  662.  
  663.               case 4: strcpy( cpuStr, "Athlon (Thunderbird)" );
  664.                       break;
  665.  
  666.               case 6: strcpy( cpuStr, "Athlon (Palomino)" );
  667.                       break;
  668.  
  669.               case 7: strcpy( cpuStr, "Duron (Morgan)" );
  670.                       break;
  671.  
  672.               default:strcpy( cpuStr, "Unknown Athlon" );
  673.                       break;
  674.             }
  675.             break;
  676.  
  677.     default:strcpy( cpuStr, "Unknown AMD CPU" );
  678.             break;
  679.   }
  680. }
  681.  
  682. void CCPUData::identifyCyrix()
  683. {
  684.   switch( familyid )
  685.   {
  686.     case 4: switch( modelid )
  687.             {
  688.               case 4: strcpy( cpuStr, "MediaGX" );
  689.                       break;
  690.  
  691.               default:strcpy( cpuStr, "Unknown Cyrix CPU" );
  692.                       break;
  693.             }
  694.             break;
  695.  
  696.     case 5: switch( modelid )
  697.             {
  698.               case 2: strcpy( cpuStr, "6x86/6x86L" );
  699.                       break;
  700.  
  701.               case 4: strcpy( cpuStr, "MediaGX MMX enh." );
  702.                       break;
  703.  
  704.               default:strcpy( cpuStr, "Unknown Cyrix CPU" );
  705.                       break;
  706.             }
  707.             break;
  708.      
  709.     case 6: switch( modelid )
  710.             {
  711.               case 0: strcpy( cpuStr, "m II" );
  712.                       break;
  713.  
  714.               case 5: strcpy( cpuStr, "VIA Cyrix M2 core" );
  715.                       break;
  716.  
  717.               case 6: strcpy( cpuStr, "WinChip C5A" );
  718.                       break;
  719.  
  720.               case 7: strcpy( cpuStr, "WinChip C5B" );
  721.                       break;
  722.  
  723.               default:strcpy( cpuStr, "Unknown Cyrix CPU" );
  724.                       break;
  725.             }
  726.             break;
  727.  
  728.     default:strcpy( cpuStr, "Unknown Cyrix CPU" );
  729.             break;
  730.   }
  731. }
  732.  
  733. void CCPUData::init()
  734. {
  735.   features = 0;
  736.   exfeatures = 0;
  737.   typid = 0;
  738.   modelid = 0;
  739.   steppingid = 0;
  740.   *vendorID = '\0';
  741.   vendor = -1;
  742.   maxIDVal = 0;
  743.   exlevel = 0;
  744.   brandID = 0;
  745.   exfeatures2 = 0;
  746.   brandStr = "";
  747.  
  748.   f_fpu = f_vme = f_de = f_pse = f_tsc = f_msr = f_pae = f_mce = f_c8x = f_apic = f_sep = 
  749.   f_mtrr = f_pge = f_mca = f_cmov = f_pse36 = f_psn = f_mmx = f_pat = f_fxsr = f_sse = f_sse2 = 
  750.   f_fsc = f_fcmov = f_mmxext = f_3dnowext = f_3dnow = f_cxmmx = f_ss = f_htt = f_tm = f_ia64 = 
  751.   f_acpi = FALSE;
  752. }
  753.  
  754. void CCPUData::getCPUFeatures()
  755. {
  756.   DWORD cpuff = 0;
  757.   DWORD cpuffext = 0;
  758.   DWORD bid = 0;
  759.   DWORD fam = 0;
  760.   BYTE vid[16] = "------------";
  761.   DWORD maxl = 0;
  762.  
  763.   __asm {      
  764.       pushad
  765.       xor eax,eax
  766.       CPU_ID
  767.       mov dword ptr vid,ebx
  768.       mov dword ptr vid[+4],edx
  769.       mov dword ptr vid[+8],ecx
  770.       mov dword ptr maxl,eax
  771.  
  772.       cmp eax,1
  773.       jl end_cpuff
  774.       xor eax,eax
  775.       inc eax
  776.       CPU_ID
  777.       mov cpuff,edx
  778.       mov cpuffext,ecx
  779.       mov bid,ebx
  780.       mov fam,eax
  781.  
  782.     end_cpuff:
  783.       popad
  784.   }
  785.  
  786.   strcpy( vendorID, (char*)vid );
  787.   family = fam;
  788.   brandID = bid;
  789.   features = cpuff;
  790.   exfeatures = cpuffext;
  791.   maxIDVal = maxl;
  792. }
  793.  
  794. /////////////////////////////////////////////////////////////////////////////
  795. void CCPUData::Message( LPCTSTR lpszMessage )
  796. {
  797.   strcat( flagText, lpszMessage );
  798.   strcat( flagText, "\r\n" );
  799. }
  800.  
  801.