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

📄 _cpuinfo.asm

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 ASM
字号:
;****************************************************************************;*;*					SciTech OS Portability Manager Library;*;*  ========================================================================;*;*    The contents of this file are subject to the SciTech MGL Public;*    License Version 1.0 (the "License"); you may not use this file;*    except in compliance with the License. You may obtain a copy of;*    the License at http://www.scitechsoft.com/mgl-license.txt;*;*    Software distributed under the License is distributed on an;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or;*    implied. See the License for the specific language governing;*    rights and limitations under the License.;*;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.;*;*    The Initial Developer of the Original Code is SciTech Software, Inc.;*    All Rights Reserved.;*;*  ========================================================================;*;* Language:    NASM or TASM Assembler;* Environment: Intel 32 bit Protected Mode.;*;* Description: Code to determine the Intel processor type.;*;****************************************************************************		IDEALinclude "scitech.mac"header		_cpuinfobegcodeseg  _cpuinfo          		; Start of code segmentifdef	USE_NASM%macro mCPU_ID 0db	00Fh,0A2h%endmacroelseMACRO	mCPU_IDdb	00Fh,0A2hENDMendififdef	USE_NASM%macro mRDTSC 0db	00Fh,031h%endmacroelseMACRO	mRDTSCdb	00Fh,031hENDMendifCPU_IDT		EQU	01000h				; Flag for IDT processorsCPU_Cyrix	EQU	02000h				; Flag for Cyrix processorsCPU_AMD		EQU	04000h				; Flag for AMD processorsCPU_Intel	EQU	08000h				; Flag for Intel processorsintel_id	db	"GenuineIntel"		; Intel vendor IDcyrix_id	db	"CyrixInstead"		; Cyrix vendor IDamd_id		db	"AuthenticAMD"		; AMD vendor IDidt_id		db	"CentaurHauls"		; IDT vendor ID;----------------------------------------------------------------------------; bool _CPU_check80386(void);----------------------------------------------------------------------------; Determines if we have an i386 processor.;----------------------------------------------------------------------------cprocstart	_CPU_check80386		enter_c		xor		edx,edx				; EDX = 0, not an 80386		mov 	bx, spifdef	USE_NASM		and		sp, ~3else		and		sp, not 3endif		pushfd						; Push original EFLAGS		pop     eax					; Get original EFLAGS		mov     ecx, eax			; Save original EFLAGS		xor     eax, 40000h			; Flip AC bit in EFLAGS		push    eax             	; Save new EFLAGS value on									;   stack		popfd                   	; Replace current EFLAGS value		pushfd						; Get new EFLAGS		pop     eax             	; Store new EFLAGS in EAX		xor     eax, ecx        	; Can't toggle AC bit,									;   processor=80386		jnz     @@Done				; Jump if not an 80386 processor		inc		edx					; We have an 80386@@Done:	push	ecx		popfd		mov		sp, bx		mov		eax, edx		leave_c		retcprocend;----------------------------------------------------------------------------; bool _CPU_check80486(void);----------------------------------------------------------------------------; Determines if we have an i486 processor.;----------------------------------------------------------------------------cprocstart	_CPU_check80486		enter_c; Distinguish between the i486 and Pentium by the ability to set the ID flag; in the EFLAGS register. If the ID flag is set, then we can use the CPUID; instruction to determine the final version of the chip. Otherwise we; simply have an 80486.; Distinguish between the i486 and Pentium by the ability to set the ID flag; in the EFLAGS register. If the ID flag is set, then we can use the CPUID; instruction to determine the final version of the chip. Otherwise we; simply have an 80486.		pushfd						; Get original EFLAGS		pop		eax		mov 	ecx, eax		xor		eax, 200000h		; Flip ID bit in EFLAGS		push	eax					; Save new EFLAGS value on stack		popfd						; Replace current EFLAGS value		pushfd						; Get new EFLAGS		pop     eax					; Store new EFLAGS in EAX		xor     eax, ecx			; Can not toggle ID bit,		jnz     @@1					; Processor=80486		mov		eax,1				; We dont have a Pentium		jmp		@@Done@@1:	mov		eax,0				; We have Pentium or later@@Done:	leave_c		retcprocend;----------------------------------------------------------------------------; bool _CPU_checkClone(void);----------------------------------------------------------------------------; Checks if the i386 or i486 processor is a clone or genuine Intel.;----------------------------------------------------------------------------cprocstart	_CPU_checkClone		enter_c		mov		ax,5555h			; Check to make sure this is a 32-bit processor		xor 	dx,dx		mov 	cx,2h		div		cx					; Perform Division		clc		jnz 	@@NoClone		jmp		@@Clone@@NoClone:		stc@@Clone:		pushfd		pop 	eax          		; Get the flags		and 	eax,1		xor	 	eax,1        		; EAX=0 is probably Intel, EAX=1 is a Clone		leave_c		retcprocend;----------------------------------------------------------------------------; bool _CPU_haveCPUID(void);----------------------------------------------------------------------------; Determines if we have support for the CPUID instruction.;----------------------------------------------------------------------------cprocstart	_CPU_haveCPUID		enter_cifdef flatmodel		pushfd						; Get original EFLAGS		pop		eax		mov 	ecx, eax		xor		eax, 200000h		; Flip ID bit in EFLAGS		push	eax					; Save new EFLAGS value on stack		popfd						; Replace current EFLAGS value		pushfd						; Get new EFLAGS		pop     eax					; Store new EFLAGS in EAX		xor     eax, ecx			; Can not toggle ID bit,		jnz     @@1					; Processor=80486		mov		eax,0				; We dont have CPUID support		jmp		@@Done@@1:	mov		eax,1				; We have CPUID supportelse		mov		eax,0				; CPUID requires 32-bit pmodeendif@@Done:	leave_c		retcprocend;----------------------------------------------------------------------------; uint _CPU_checkCPUID(void);----------------------------------------------------------------------------; Determines the CPU type using the CPUID instruction.;----------------------------------------------------------------------------cprocstart	_CPU_checkCPUID		enter_c		xor     eax, eax			; Set up for CPUID instruction		mCPU_ID						; Get and save vendor ID		cmp     eax, 1				; Make sure 1 is valid input for CPUID		jl      @@Fail				; We dont have the CPUID instruction		xor		eax,eax				; Assume vendor is unknown; Check for GenuineIntel processors		cmp		[DWORD intel_id], ebx		jne		@@NotIntel		cmp		[DWORD intel_id+4], edx		jne		@@NotIntel		cmp		[DWORD intel_id+8], ecx		jne		@@NotIntel		mov		eax,CPU_Intel		; Flag that we have GenuineIntel		jmp		@@FoundVendor; Check for CyrixInstead processors@@NotIntel:		cmp		[DWORD cyrix_id], ebx		jne		@@NotCyrix		cmp		[DWORD cyrix_id+4], edx		jne		@@NotCyrix		cmp		[DWORD cyrix_id+8], ecx		jne		@@NotCyrix		mov		eax,CPU_Cyrix		; Flag that we have CyrixInstead		jmp		@@FoundVendor; Check for AuthenticAMD processors@@NotCyrix:		cmp		[DWORD amd_id], ebx		jne		@@NotAMD		cmp		[DWORD amd_id+4], edx		jne		@@NotAMD		cmp		[DWORD amd_id+8], ecx		jne		@@NotAMD		mov		eax,CPU_AMD			; Flag that we have AuthenticAMD		jmp		@@FoundVendor; Check for CentaurHauls processors@@NotAMD:		cmp		[DWORD idt_id], ebx		jne		@@NotIDT		cmp		[DWORD idt_id+4], edx		jne		@@NotIDT		cmp		[DWORD idt_id+8], ecx		jne		@@NotIDT		mov		eax,CPU_IDT			; Flag that we have AuthenticIDT		jmp		@@FoundVendor@@NotIDT:@@FoundVendor:		push	eax		xor     eax, eax		inc		eax		mCPU_ID						; Get family/model/stepping/features		and		eax, 0F00h		shr     eax, 8				; Isolate family		and		eax, 0Fh		pop		ecx		or		eax,ecx				; Combine in the clone flag@@Done:	leave_c		ret@@Fail:	xor		eax,eax		jmp		@@Donecprocend;----------------------------------------------------------------------------; uint _CPU_getCPUIDModel(void);----------------------------------------------------------------------------; Determines the CPU type using the CPUID instruction.;----------------------------------------------------------------------------cprocstart	_CPU_getCPUIDModel		enter_c		xor     eax, eax			; Set up for CPUID instruction		mCPU_ID						; Get and save vendor ID		cmp     eax, 1				; Make sure 1 is valid input for CPUID		jl      @@Fail				; We dont have the CPUID instruction		xor     eax, eax		inc		eax		mCPU_ID						; Get family/model/stepping/features		and		eax, 0F0h		shr     eax, 4				; Isolate model@@Done:	leave_c		ret@@Fail:	xor		eax,eax		jmp		@@Donecprocend;----------------------------------------------------------------------------; uint _CPU_getCPUIDFeatures(void);----------------------------------------------------------------------------; Determines the CPU type using the CPUID instruction.;----------------------------------------------------------------------------cprocstart	_CPU_getCPUIDFeatures		enter_c		xor     eax, eax			; Set up for CPUID instruction		mCPU_ID						; Get and save vendor ID		cmp     eax, 1				; Make sure 1 is valid input for CPUID		jl      @@Fail				; We dont have the CPUID instruction		xor     eax, eax		inc		eax		mCPU_ID						; Get family/model/stepping/features		mov		eax, edx@@Done:	leave_c		ret@@Fail:	xor		eax,eax		jmp		@@Donecprocend;----------------------------------------------------------------------------; uint _CPU_have3DNow(void);----------------------------------------------------------------------------; Determines the CPU type using the CPUID instruction.;----------------------------------------------------------------------------cprocstart	_CPU_have3DNow		enter_c		mov		eax,80000000h		; Query for extended functions		mCPU_ID						; Get extended function limit		cmp		eax,80000001h		jbe		@@Fail				; Nope, we dont have function 800000001h		mov		eax,80000001h		; Setup extended function 800000001h		mCPU_ID						; and get the information		test	edx,80000000h		; Bit 31 is set if 3DNow! present		jz		@@Fail				; Nope, we dont have 3DNow support		mov		eax,1				; Yep, we have 3DNow! support!@@Done:	leave_c		ret@@Fail:	xor		eax,eax		jmp		@@Donecprocend;----------------------------------------------------------------------------; ulong _CPU_quickRDTSC(void);----------------------------------------------------------------------------; Reads the time stamp counter and returns the low order 32-bits;----------------------------------------------------------------------------cprocstart	_CPU_quickRDTSC		mRDTSC		retcprocend;----------------------------------------------------------------------------; void _CPU_runBSFLoop(ulong interations);----------------------------------------------------------------------------; Runs a loop of BSF instructions for the specified number of iterations;----------------------------------------------------------------------------cprocstart	_CPU_runBSFLoop		ARG		iterations:ULONG		push	_bp		mov		_bp,_sp		push	_bx		mov		edx,[iterations]		mov 	eax,80000000h		mov		ebx,edx		ALIGN	4@@loop:	bsf 	ecx,eax		dec		ebx		jnz		@@loop		pop		_bx		pop		_bp		retcprocend;----------------------------------------------------------------------------; void  _CPU_readTimeStamp(CPU_largeInteger *time);;----------------------------------------------------------------------------; Reads the time stamp counter and returns the 64-bit result.;----------------------------------------------------------------------------cprocstart	_CPU_readTimeStamp		mRDTSC		mov		ecx,[esp+4]		; Access directly without stack frame		mov		[ecx],eax		mov		[ecx+4],edx		retcprocend;----------------------------------------------------------------------------; ulong _CPU_diffTime64(CPU_largeInteger *t1,CPU_largeInteger *t2,CPU_largeInteger *t);----------------------------------------------------------------------------; Computes the difference between two 64-bit numbers.;----------------------------------------------------------------------------cprocstart	_CPU_diffTime64		ARG		t1:DPTR, t2:DPTR, t:DPTR		enter_c		mov		ecx,[t2]		mov 	eax,[ecx]		; EAX := t2.low		mov		ecx,[t1]		sub 	eax,[ecx]		mov 	edx,eax			; EDX := low difference		mov		ecx,[t2]		mov 	eax,[ecx+4]		; ECX := t2.high		mov		ecx,[t1]		sbb 	eax,[ecx+4]		; EAX := high difference		mov		ebx,[t]			; Store the result		mov		[ebx],edx		; Store low part		mov		[ebx+4],eax		; Store high part		mov		eax,edx			; Return low partifndef flatmodel		shld	edx,eax,16		; Return in DX:AXendif		leave_c		retcprocend;----------------------------------------------------------------------------; ulong _CPU_calcMicroSec(CPU_largeInteger *count,ulong freq);;----------------------------------------------------------------------------; Computes the value in microseconds for the elapsed time with maximum; precision. The formula we use is:;;	us = (((diff * 0x100000) / freq) * 1000000) / 0x100000);; The power of two multiple before the first divide allows us to scale the; 64-bit difference using simple shifts, and then the divide brings the; final result into the range to fit into a 32-bit integer.;----------------------------------------------------------------------------cprocstart	_CPU_calcMicroSec		ARG		count:DPTR, freq:ULONG		enter_c		mov		ecx,[count]		mov		eax,[ecx]		; EAX := low part		mov		edx,[ecx+4]		; EDX := high part		shld	edx,eax,20		shl		eax,20			; diff * 0x100000		div		[DWORD freq]	; (diff * 0x100000) / freq		mov		ecx,1000000		xor		edx,edx		mul		ecx				; ((diff * 0x100000) / freq) * 1000000)		shrd	eax,edx,20		; ((diff * 0x100000) / freq) * 1000000) / 0x100000ifndef flatmodel		shld	edx,eax,16		; Return in DX:AXendif		leave_c		retcprocend;----------------------------------------------------------------------------; int _CPU_inp(int port);----------------------------------------------------------------------------; Reads a byte from the specified port;----------------------------------------------------------------------------cprocstart	_CPU_inp		ARG		port:UINT		push	_bp		mov		_bp,_sp		xor		_ax,_ax		mov		_dx,[port]		in		al,dx		pop		_bp		retcprocend;----------------------------------------------------------------------------; void _CPU_outp(int port,int value);----------------------------------------------------------------------------; Write a byte to the specified port.;----------------------------------------------------------------------------cprocstart	_CPU_outp		ARG		port:UINT, value:UINT		push	_bp		mov		_bp,_sp		mov		_dx,[port]		mov		_ax,[value]		out		dx,al		pop		_bp		retcprocendendcodeseg  _cpuinfo		END

⌨️ 快捷键说明

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