📄 _cpuinfo.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.
;*
;****************************************************************************
IDEAL
include "scitech.mac"
header _cpuinfo
begdataseg _cpuinfo ; Start of data segment
cache_id db "01234567890123456"
intel_id db "GenuineIntel" ; Intel vendor ID
cyrix_id db "CyrixInstead" ; Cyrix vendor ID
amd_id db "AuthenticAMD" ; AMD vendor ID
idt_id db "CentaurHauls" ; IDT vendor ID
CPU_IDT EQU 01000h ; Flag for IDT processors
CPU_Cyrix EQU 02000h ; Flag for Cyrix processors
CPU_AMD EQU 04000h ; Flag for AMD processors
CPU_Intel EQU 08000h ; Flag for Intel processors
enddataseg _cpuinfo
begcodeseg _cpuinfo ; Start of code segment
ifdef USE_NASM
%macro mCPU_ID 0
db 00Fh,0A2h
%endmacro
else
MACRO mCPU_ID
db 00Fh,0A2h
ENDM
endif
ifdef USE_NASM
%macro mRDTSC 0
db 00Fh,031h
%endmacro
else
MACRO mRDTSC
db 00Fh,031h
ENDM
endif
;----------------------------------------------------------------------------
; 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, sp
ifdef USE_NASM
and sp, ~3
else
and sp, not 3
endif
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
ret
cprocend
;----------------------------------------------------------------------------
; 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
ret
cprocend
;----------------------------------------------------------------------------
; 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
ret
cprocend
;----------------------------------------------------------------------------
; bool _CPU_haveCPUID(void)
;----------------------------------------------------------------------------
; Determines if we have support for the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart _CPU_haveCPUID
enter_c
ifdef 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 support
else
mov eax,0 ; CPUID requires 32-bit pmode
endif
@@Done: leave_c
ret
cprocend
;----------------------------------------------------------------------------
; 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
LEA_L esi,intel_id
cmp [DWORD esi], ebx
jne @@NotIntel
cmp [DWORD esi+4], edx
jne @@NotIntel
cmp [DWORD esi+8], ecx
jne @@NotIntel
mov eax,CPU_Intel ; Flag that we have GenuineIntel
jmp @@FoundVendor
; Check for CyrixInstead processors
@@NotIntel:
LEA_L esi,cyrix_id
cmp [DWORD esi], ebx
jne @@NotCyrix
cmp [DWORD esi+4], edx
jne @@NotCyrix
cmp [DWORD esi+8], ecx
jne @@NotCyrix
mov eax,CPU_Cyrix ; Flag that we have CyrixInstead
jmp @@FoundVendor
; Check for AuthenticAMD processors
@@NotCyrix:
LEA_L esi,amd_id
cmp [DWORD esi], ebx
jne @@NotAMD
cmp [DWORD esi+4], edx
jne @@NotAMD
cmp [DWORD esi+8], ecx
jne @@NotAMD
mov eax,CPU_AMD ; Flag that we have AuthenticAMD
jmp @@FoundVendor
; Check for CentaurHauls processors
@@NotAMD:
LEA_L esi,idt_id
cmp [DWORD esi], ebx
jne @@NotIDT
cmp [DWORD esi+4], edx
jne @@NotIDT
cmp [DWORD esi+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 @@Done
cprocend
;----------------------------------------------------------------------------
; uint _CPU_getCPUIDModel(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart _CPU_getCPUIDModel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -