///////////////////////////////////////////////////////////////////////////////
/// @file deMachineWindowsCPU.cpp
///
/// @brief CPU Detector
///
/// @author Lightning
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Nov 2001
/// @author Lightning
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEMACHINEWINDOWSCPU_HPP
#define DEMACHINEWINDOWSCPU_HPP



//=================================================================================
// Includes
//=================================================================================

#include "deMachineWindows.hpp"



//=================================================================================
// Defines
//=================================================================================

//Intel Feature Flags
#define CPU_INTEL_FPU     0x00000001 // Bit 0 - Floating-Point unit on chip
#define CPU_INTEL_VME     0x00000002 // Bit 1 - Virtual Mode Extention
#define CPU_INTEL_DE      0x00000004 // Bit 2 - Debugging Extention
#define CPU_INTEL_PSE     0x00000008 // Bit 3 - Page Size Extention
#define CPU_INTEL_TSC     0x00000010 // Bit 4 - Time Stamp Counter
#define CPU_INTEL_MSR     0x00000020 // Bit 5 - Model Specific Registers
#define CPU_INTEL_PAE     0x00000040 // Bit 6 - Physical Address Extention
#define CPU_INTEL_MCE     0x00000080 // Bit 7 - Machine Check Exception
#define CPU_INTEL_CX8     0x00000100 // Bit 8 - CMPXCHG8 Instruction
#define CPU_INTEL_APIC    0x00000200 // Bit 9 - Software-accessible local APIC on Chip
#define CPU_INTEL_BIT_10  0x00000400 // Bit 10 - Reserved
#define CPU_INTEL_SEP     0x00000800 // Bit 11 - Fast System Call
#define CPU_INTEL_MTRR    0x00001000 // Bit 12 - Memory Type Range Registers
#define CPU_INTEL_PGE     0x00002000 // Bit 13 - Page Global Enable
#define CPU_INTEL_MCA     0x00004000 // Bit 14 - Machine Check Architecture
#define CPU_INTEL_CMOV    0x00008000 // Bit 15 - Conditional Move Instruction
#define CPU_INTEL_PAT     0x00010000 // Bit 16 - Page Attribute Table
#define CPU_INTEL_PSE36   0x00020000 // Bit 17 - 36-bit Page Size Extention
#define CPU_INTEL_PN      0x00040000 // Bit 18 - Processor Number
#define CPU_INTEL_CLFSH   0x00080000 // Bit 19 - CLFlush command support
#define CPU_INTEL_BIT_20  0x00100000 // Bit 20 - Reserved
#define CPU_INTEL_DS      0x00200000 // Bit 21 - Debug Store
#define CPU_INTEL_ACPI    0x00400000 // Bit 22 - ACPI Preprocessor Performance Modulation Registers
#define CPU_INTEL_MMX     0x00800000 // Bit 23 - MMX technology
#define CPU_INTEL_FXSR    0x01000000 // Bit 24 - Fast Floating Point Save and Restore
#define CPU_INTEL_SSE     0x02000000 // Bit 25 - Streaming SIMD Extension
#define CPU_INTEL_SSE2    0x04000000 // Bit 26 - SSE2
#define CPU_INTEL_SS      0x08000000 // Bit 27 - Self Snoop
#define CPU_INTEL_BIT_28  0x10000000 // Bit 28 - Reserved
#define CPU_INTEL_TM      0x20000000 // Bit 29 - Thermal Monitor
#define CPU_INTEL_BIT_30  0x40000000 // Bit 30 - Reserved
#define CPU_INTEL_BIT_31  0x80000000 // Bit 31 - Reserved


//AMD Feature Flags
#define CPU_AMD_FPU       0x00000001 // Bit 0 - Floating-Point unit on chip
#define CPU_AMD_VME       0x00000002 // Bit 1 - Virtual Mode Extention
#define CPU_AMD_DE        0x00000004 // Bit 2 - Debugging Extention
#define CPU_AMD_PSE       0x00000008 // Bit 3 - Page Size Extention
#define CPU_AMD_TSC       0x00000010 // Bit 4 - Time Stamp Counter
#define CPU_AMD_MSR       0x00000020 // Bit 5 - Model Specific Registers
#define CPU_AMD_PAE       0x00000040 // Bit 6 - Page Address Extension
#define CPU_AMD_MCE       0x00000080 // Bit 7 - Machine Check Exception
#define CPU_AMD_CX8       0x00000100 // Bit 8 - CMPXCHG8 Instruction
#define CPU_AMD_APIC      0x00000200 // Bit 9 - On-chip APIC
#define CPU_AMD_BIT_10    0x00000400 // Bit 10 - Reserved
#define CPU_AMD_SEP       0x00000800 // Bit 11 - Fast System Call
#define CPU_AMD_MTRR      0x00001000 // Bit 12 - Memory Type Range Registers
#define CPU_AMD_PGE       0x00002000 // Bit 13 - Page Global Enable
#define CPU_AMD_MCA       0x00004000 // Bit 14 - Machine Check Architecture
#define CPU_AMD_CMOV      0x00008000 // Bit 15 - Integer Conditional Move Instruction
#define CPU_AMD_PAT       0x00010000 // Bit 16 - Page Attribute Table
#define CPU_AMD_PSE36     0x00020000 // Bit 17 - 36-bit Page Size Extension
#define CPU_AMD_BIT_18    0x00040000 // Bit 18 - Reserved
#define CPU_AMD_BIT_19    0x00080000 // Bit 19 - Reserved
#define CPU_AMD_BIT_20    0x00100000 // Bit 20 - Reserved
#define CPU_AMD_BIT_21    0x00200000 // Bit 21 - Reserved
#define CPU_AMD_BIT_22    0x00400000 // Bit 22 - Reserved
#define CPU_AMD_MMX       0x00800000 // Bit 23 - MMX technology
#define CPU_AMD_FXSR      0x01000000 // Bit 24 - Fast floating point save and restore
#define CPU_AMD_SSE       0x02000000 // Bit 25 - Streaming SIMD Extention
#define CPU_AMD_BIT_26    0x04000000 // Bit 26 - Reserved
#define CPU_AMD_BIT_27    0x08000000 // Bit 27 - Reserved
#define CPU_AMD_BIT_28    0x10000000 // Bit 28 - Reserved
#define CPU_AMD_BIT_29    0x20000000 // Bit 29 - Reserved
#define CPU_AMD_BIT_30    0x40000000 // Bit 30 - Reserved
#define CPU_AMD_BIT_31    0x80000000 // Bit 31 - Reserved

//AMD Extended Feature Flags
#define CPU_AMD_EXT_FPU       0x00000001 // Bit 0 - Floating-Point unit on chip
#define CPU_AMD_EXT_VME       0x00000002 // Bit 1 - Virtual Mode Extention
#define CPU_AMD_EXT_DE        0x00000004 // Bit 2 - Debugging Extention
#define CPU_AMD_EXT_PSE       0x00000008 // Bit 3 - Page Size Extention
#define CPU_AMD_EXT_TSC       0x00000010 // Bit 4 - Time Stamp Counter
#define CPU_AMD_EXT_MSR       0x00000020 // Bit 5 - Model Specific Registers
#define CPU_AMD_EXT_PAE       0x00000040 // Bit 6 - Page Address Extension
#define CPU_AMD_EXT_MCE       0x00000080 // Bit 7 - Machine Check Exception
#define CPU_AMD_EXT_CX8       0x00000100 // Bit 8 - CMPXCHG8 Instruction
#define CPU_AMD_EXT_APIC      0x00000200 // Bit 9 - On-chip APIC
#define CPU_AMD_EXT_BIT_10    0x00000400 // Bit 10 - Reserved
#define CPU_AMD_EXT_SEP       0x00000800 // Bit 11 - Fast System Call
#define CPU_AMD_EXT_MTRR      0x00001000 // Bit 12 - Memory Type Range Registers
#define CPU_AMD_EXT_PGE       0x00002000 // Bit 13 - Page Global Enable
#define CPU_AMD_EXT_MCA       0x00004000 // Bit 14 - Machine Check Architecture
#define CPU_AMD_EXT_CMOV      0x00008000 // Bit 15 - Integer Conditional Move Instruction
#define CPU_AMD_EXT_PAT       0x00010000 // Bit 16 - Page Attribute Table
#define CPU_AMD_EXT_PSE36     0x00020000 // Bit 17 - 36-bit Page Size Extension
#define CPU_AMD_EXT_BIT_18    0x00040000 // Bit 18 - Reserved
#define CPU_AMD_EXT_MPCAPABLE 0x00080000 // Bit 19 - Multiprocessing Capable
#define CPU_AMD_EXT_BIT_20    0x00100000 // Bit 20 - Reserved
#define CPU_AMD_EXT_BIT_21    0x00200000 // Bit 21 - Reserved
#define CPU_AMD_EXT_AMIE      0x00400000 // Bit 22 - AMD Multimedia Instructions Extensions
#define CPU_AMD_EXT_MMX       0x00800000 // Bit 23 - MMX technology
#define CPU_AMD_EXT_FXSR      0x01000000 // Bit 24 - Fast floating point save and restore
#define CPU_AMD_EXT_BIT_25    0x02000000 // Bit 25 - Reserved
#define CPU_AMD_EXT_BIT_26    0x04000000 // Bit 26 - Reserved
#define CPU_AMD_EXT_BIT_27    0x08000000 // Bit 27 - Reserved
#define CPU_AMD_EXT_BIT_28    0x10000000 // Bit 28 - Reserved
#define CPU_AMD_EXT_BIT_29    0x20000000 // Bit 29 - Reserved
#define CPU_AMD_EXT_3DNOWEXT  0x40000000 // Bit 30 - AMD 3DNOW! Extensions
#define CPU_AMD_EXT_3DNOW     0x80000000 // Bit 31 - AMD 3DNOW! Technology


//Intel processor types
#define INTEL_486SL                 "486(TM) SL processor"
#define INTEL_DX2WB                 "Write-Back Enhanced DX2(TM) processor"
#define INTEL_DX4                   "DX4(TM) processor"
#define INTEL_DX4OVERDRIVE          "DX4(TM) OverDrive(R) processor"
#define INTEL_PENTIUM               "Pentium(R) processor"
#define INTEL_PENTIUMMMX            "Pentium(R) processor with MMX"
#define INTEL_PENTIUMOVERDRIVE		"Pentium(R) OverDrive(R) processor"
#define INTEL_PENTIUMOVERDRIVEMMX   "Pentium(R) OverDrive(R) processor with MMX"
#define INTEL_PPRO                  "Pentium(R) Pro processor"
#define INTEL_PII                   "Pentium(R) II processor"
#define INTEL_PIIOVERDRIVE          "Pentium(R) II OverDrive(R) processor"
#define INTEL_PIIXEON               "Pentium(R) II Xeon(TM) processor"
#define INTEL_CELERON               "Celeron(TM) processor"
#define INTEL_PIII                  "Pentium(R) III processor"
#define INTEL_PIIIXEON              "Pentium(R) III Xeon(TM) processor"
#define PROCESSOR_UNKNOWN           "Unknown processor"



//=================================================================================
// deMachineWindowsCPU Class
//
// CPU Detector - Windows Version
//=================================================================================

class deMachineWindowsCPU
{
public:
   deMachineWindowsCPU();

   deBoolean GetCreationResult(void) { return CreationResult; }
   deBoolean GetCPUInfo(deCPUInfo *Info);

private:
   void StartTimer(long *Time, __int64 *Clock);
   void GetVendorAndCPUInfo(void);
   void GetIntelCPUInfo(long LargestExtendedFunction);
   void GetEmbeddedCPUName(void);
   char *GetIntelCPUName(void);
   long GetIntelCPUCache(void);
   void GetIntelCPUCacheValues(void);
   void GetAMDCPUInfo(long LargestExtendedFunction);
   void GetAMDCPUCacheValues(long LargestExtendedFunction);
   void StopTimer(long *Time, __int64 *Clock);

   deBoolean CreationResult;
   deCPUInfo CPUInfo;
};



#endif  // End: DEMACHINEWINDOWSCPU_HPP