⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.c

📁 著名物理引擎Hawk的源代码
💻 C
字号:
/* cpu.c, HAWK game engine
 *
 * Copyright 1997-1998 by Phil Frisbie, Jr.
 * for Hawk Software
 *
 */

#ifdef WIN32
#include <windows.h>
#endif
#include "hawk.h"
#include "internal.h"
#include "hardware.h"

#define CPUID __asm _emit 0x0f __asm _emit 0xa2

#define RDTSC __asm _emit 0x0f __asm _emit 0x31

static long name[4];
char		no_name[16] = "NoVendorName";
CPU			Cpu;

BOOL cpuHasCPUID(void)
{
	BOOL	has_cpuid = FALSE;

#ifdef GCC
#else
__asm{
		pushfd				; save eflags
		pop	eax				; save eflags
		mov	edx,eax 		; make a copy
		xor	eax,200000h		; toggle the bit
		push	eax			; save it
		popfd				; check if CPUID flag could toggle
		pushfd				; save it, so we can check it
		pop	eax				; get it
		xor	eax,edx 		; did bit toggle?
		jz	end_label		; can't use CPUID instruction
		mov has_cpuid, TRUE	; can use CPUID instruction
		end_label:
		popfd				; restore original EFLAGS value
	}
#endif
	return has_cpuid;
}

void cpuGetInfo(int level, int *a, int *b, int *c, int *d)
{
	long	A, B, C, D;
__asm{
		mov eax, level		; function (level)
		CPUID				; get the name
		mov A, eax			; copy register
		mov B, ebx			; copy register
		mov C, ecx			; copy register
		mov D, edx			; copy register
	}

	*a = A;
	*b = B;
	*c = C;
	*d = D;
}

long cpuGetName(void)
{
	long	a = 0, b, c, d;

__asm{
		mov eax, a			; function 0
		CPUID				; get the name
		mov a, eax			; copy register
		mov b, ebx			; copy register
		mov c, ecx			; copy register
		mov d, edx			; copy register
	}

	name[0] = b;
	name[1] = d;
	name[2] = c;
	name[3] = 0;
	Cpu.vendor = (char *)name;

	return a;
}

unsigned long rdtsc(void)
{
	unsigned long	a;

__asm{
		RDTSC				; get the count
		mov a, eax			; copy register
	}

	return a;
}

unsigned long cpuGetSpeed(void)
{
	unsigned long a, b, s;

#ifdef WIN32
	int tp, pp;
	HANDLE t, p;

	t = GetCurrentThread();
	tp = GetThreadPriority(t);
	SetThreadPriority(t, THREAD_PRIORITY_TIME_CRITICAL);
	p = GetCurrentProcess();
	pp = GetPriorityClass(p);
	SetPriorityClass(p, REALTIME_PRIORITY_CLASS);
#endif

	Mpause(1);
	a = rdtsc();	/* read the performance counter */
	Mpause(100);	/* pause 100 ms */
	b = rdtsc();	/* read the performance counter */
	if(a > b)		/* we wrapped past zero */
	{
		a = b;
		Mpause(100);/* pause 100 ms again */
		b = rdtsc();/* read again */
	}

	s = b - a;
#ifdef WIN32
	SetThreadPriority(t, tp);
	SetPriorityClass(p, pp);
#endif
	return s/100000;/* convert to MHz */
}

void cpuID(void)
{
	int levels;
	BOOL hasRDTSC = FALSE;

	if(!cpuHasCPUID())
	{
		Cpu.vendor = no_name;
		Cpu.hasMMX = FALSE;
		Cpu.has3DNow = FALSE;
		return;
	}
	levels = cpuGetName();
	if(levels)
	{
		int a, b, c, d;

		cpuGetInfo(1, &a, &b, &c, &d);
		Cpu.hasMMX = (d & 0x800000 ? TRUE:FALSE);
		hasRDTSC = (d & 0x10 ? TRUE:FALSE);
		Cpu.type = (a & 0xF00) >> 8;
		cpuGetInfo(0x80000000, &a, &b, &c, &d);
		if(a > 0x80000000)
		{
			cpuGetInfo(0x8000001, &a, &b, &c, &d);
			Cpu.has3DNow = (d & 0x80000000 ? TRUE:FALSE);
		}
		else
			Cpu.has3DNow = FALSE;

	}
	else
	{
		Cpu.hasMMX = FALSE;
		Cpu.has3DNow = FALSE;
	}
	if(hasRDTSC)
		Cpu.speed = cpuGetSpeed();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -