📄 cpu.cpp
字号:
#include <stdio.h>
#include <string.h>
#include "gl.h"
extern CPUInfo cpu = {
"NoVendorName",
0, 0,
false,
false,
false,
false };
// Checks whether the cpuid instruction is available.
// return: 0: not supported 1: supported
static int IsCpuidSupported( void )
{
int result;
_asm{
pushfd; /* get extended flags */
pop eax;
mov ebx, eax; /* save current flags */
xor eax, 0x200000; /* toggle bit 21 */
push eax; /* put new flags on stack */
popfd; /* flags updated now in flags */
pushfd; /* get extended flags */
pop eax;
xor ebx, eax; /* if bit 21 r/w then supports cpuid */
jz nocpuid;
mov result, 1;
jmp iscpuid_end;
nocpuid:
mov result, 0;
iscpuid_end:
}
return result;
}
#define CPUID __asm _emit 0x0F _asm _emit 0xA2
static void GetCpuidInfo(long cpuid_levels, long *eax, long *ebx, long *ecx, long *edx)
{
int a, b, c, d;
__asm{
mov eax, cpuid_levels
CPUID;
mov a, eax
mov b, ebx
mov c, ecx
mov d, edx;
}
*eax = a;
*ebx = b;
*ecx = c;
*edx = d;
}
#undef CPUID
//Returns TRUE if this is a Cyrix processor.
static int IsCyrix( void )
{
int result;
__asm{
xor ax, ax;
sahf; /* bit 1 is always 1 in flags */
mov ax, 5;
mov bx, 2;
div bl; /* this does not change flags */
lahf; /* get flags */
cmp ah, 2; /* check for change in flags */
jne notcyrix; /* flags changed not Cyrix */
mov result, 1; /* TRUE Cyrix CPU */
jmp iscyrix_end;
notcyrix:
mov result, 0; /* FALSE NON-Cyrix CPU */
iscyrix_end:
}
return result;
}
// Returns TRUE if the CPU has floating point hardware.
static int IsFpu( void )
{
int result;
__asm{
fninit;
mov eax, 0x5a5a;
fnstsw ax;
cmp eax, 0;
jne nofpu;
mov result, 1;
jmp isfpu_end;
nofpu:
mov result, 0;
isfpu_end:
}
return result;
}
void CheckCPU( void )
{// I'm only concern about whether this CPU is Pentium-class+
// whether MMX and 3dnow are supported.
long cpuid_levels;
long eax0, ebx0, ecx0, edx0;
if( IsCpuidSupported() ){
cpu.cpuid = true;
eax0 = ebx0 = ecx0 = 0;
GetCpuidInfo( 0, &eax0, &ebx0, &ecx0, &edx0 );
*(long*)(&cpu.vendor[0]) = ebx0;
*(long*)(&cpu.vendor[4]) = edx0;
*(long*)(&cpu.vendor[8]) = ecx0;
cpu.vendor[12] = '\0';
cpuid_levels = eax0;
//printf( "%s ", cpu.vendor );
if( cpuid_levels != 0 ){
eax0 = ebx0 = ecx0 = edx0 = 0;
GetCpuidInfo( 1, &eax0, &ebx0, &ecx0, &edx0 );
cpu.family = ( eax0 & 0xf00 ) >> 8;
cpu.model = ( eax0 & 0xf0 ) >> 4;
cpu.fpu = ( edx0 & 1 ? true : false );
cpu.mmx = ( edx0 & 0x800000 ? true : false );
//printf( "CPU family:%d, model:%d\n", cpu.family, cpu.model );
//if( cpu.mmx )
// printf( "%s ", "MMX" );
}
GetCpuidInfo( 0x80000000, &eax0, &ebx0, &ecx0, &edx0 );
if( eax0 & 0x80000000 ){
GetCpuidInfo( 0x80000001, &eax0, &ebx0, &ecx0, &edx0 );
cpu._3dnow = ( edx0 & 0x80000000 ? true : false );
//if( cpu._3dnow )
//printf( "%s ", "3DNow!" );
}
if( IsCyrix() )
cpu.model = 14;
}
else{
// If this CPU does not support instruction CPUID,
// I just look it as x486.
cpu.family = 4;
cpu.fpu = IsFpu();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -