home *** CD-ROM | disk | FTP | other *** search
- ; CPUTYPE.INC/CPU586P6.ASM CPU/FPU Generation Detection v1.2e for
- ; CPU: 8086/80186, 80286, 80386, 80486, 80586 Pentium, 80686 P6 and higher(!)
- ; FPU: 8087, 80287, 80387, 80487, and higher (see 1.) and 2.))
- ;
- ; 1995 by XMAS coding (Dominik Freche, address see below)
- ;
- ; 1. How to determine CPU type
- ; 2. How to determine FPU type
- ; 3. !!!!! THIS SOURCECODE IS FREEWARE !!!!!
- ; 4. Including routines in high level languages (Pascal,C,C++,etc);
- ; 5. Address
- ; 6. Sourcecode of program
- ; Program to determine CPU (Central Processing Unit) type
- ; and FPU (Floating Point Unit(=math coprocessor)) type
- ; for all computer generations of the IBM standard,
- ; except pocket calculators like some earlier Personal Computers, so
- ; NOTE : the program does not differ between 8086/8088/80186/80188 and
- ; V20/V30-clones.
- ; Each release defines some new features. THIS PROGRAM HELPS TO
- ; TAKE ADVANTAGE OF IT. The following table contains the features of
- ; each new generation.
- ; 80286 Protected mode, hardware-multitasking, addressing of
- ; max. 16 MB of memory
- ; 80386 32-Bit instructions, addressing of max. 4 GB (GigaByte) of memory,
- ; Virtual86 mode (V86 - each task runs on an virtual 8086 processor;
- ; EMM driver, OS2 and Win'95 use this)
- ; 80486 Internal coprocessor
- ; 80586 System Management mode (SMM - a "Standby"-mode, an
- ; "Internal green PC"), very high performance
- ; 80686 Strongly high performance ("Pentium double speed"),
- ; ??? (other features are secret)
- ; 1.)
- ; How to determine the CPU(=main processor) type
- ; Each Generation defines some new flags. If a specific flag is
- ; set and the flag is not defined, the processor clears
- ; this flag to 0.
- ; Besides, the Pentium defines a new instruction to determine
- ; the type. If the ID-Bit in EFLAGS is set to 1 and EAX contains 1,
- ; the 80586-instruction "CPUID" returns a 5 in EAX for 80586, a 6
- ; for 80686 and so on. NOTE : even some newer i80486 (manufactured
- ; after may 1994) support the instruction "CPUID", so it is necessary
- ; to execute this instruction if the ID-Bit in EFLEGS can be set to 1.
- ; Intel will include this instruction in each processor after
- ; the i80486, so even following generations can be determined.
- ; 2.)
- ; How to determine the FPU(=math coprocessor) type
- ; Executing the coprocessor-instruction "FNINIT", the CPU-status word
- ; will be cleared and the CPU-control word will be updated
- ; (the program restores the old status word and control word after executing
- ; the initialization for compatibility). By comparing some flags in the
- ; CPU-control word the existence of a FPU can be determined. Determining the
- ; generation of coprocessor is quite simple. A CPU type after 80386 has got
- ; an internal math coprocessor for standard, except some 80486SX do not
- ; (SX=Single, no coprocessor - DX=Double, coprocessor exists),
- ; but an external 80487 does not exist (the 80487 is an 80486 with internal
- ; coprocessor). That means, if an 80486 or higher is detected and a FPU
- ; does exist, an internal 80487 or higher is installed. Other FPU
- ; generations (80387,80287,8087) are external coprocessors.
- ; For these coprocessors the program determines the FPU type because it is
- ; possible to combine different CPU and FPU types (e.g. 80386 and 80287).
- ; The program uses different execution results of the same instructions on
- ; different coprocessors to determine FPU type.
- ; 3.)
- ; If you believe this program to be useful, it can be copied freely !
- ; This sourcecode cannot be sold !
- ; !!!!! THIS SOURCECODE IS FREEWARE !!!!!
- ; 4.)
- ; For including the routines to determine CPU/FPU type in a high level
- ; language (like Pascal,C,C++,etc), just see CPUTYPE.INC.
- ; 5.)
- ; If you have got any problems or if you want to contact me, do not hesitate,
- ; please write to the following address :
- ; Dominik Freche
- ; Vondernstrasse 45
- ; 45357 Essen
- ; Germany, Europe
- ; or email to :
- ; heckenb@mi.uni-erlangen.de (Frank Heckenbach)
- ; since I do not have email access. Frank will forward your mails asap,
- ; but sometimes it may take up to some weeks (esp. during holidays ;-)
- ;
- ; Dominik Freche, Mar 26 1995
- ; ---------------------------------------------------------------
- ; Next release of CPU586P6.ASM will feature
- ; - Determining CPU/FPU type
- ; - Determining CPU frequency and FPU frequency in Mhz
- ; - CPU speed (Hi/Lo frequency)
- ; ---------------------------------------------------------------
- ; 6.) Program :
- LOCALS @@
-
- CPUID EQU DB 0FH,0A2H ;80586 Instruction to determine CPU type
-
- SSeg SEGMENT STACK
- SStack DB 64 DUP (0)
- SSeg ENDS
-
- DSeg SEGMENT
- Cpu8086 DB "8086/8088/80186/80188$"
- Cpu80286 DB "80286$"
- Cpu80386 DB "80386$"
- Cpu80486 DB "80486$"
- Cpu80586 DB "80586 Pentium$"
- Cpu80686 DB "80686 P6$"
- Cpu80x86 DB "80786 or higher$"
- FpuNone DB "None$"
- Fpu8087 DB "8087$"
- Fpu80287 DB "80287$"
- Fpu80387 DB "80387$"
- Fpu80487 DB "80487 (Internal)$"
- FpuInteg DB "Internal$"
-
-
- PrnMsg01 DB "CPU Generation Detection",13,10,"$"
- PrnMsg02 DB "1995 by XMAS coding (Dominik Freche)",13,10,"$"
- PrnMsg03 DB "!!!!! THIS SOURCECODE IS FREEWARE !!!!!",13,10,"$"
- PrnMsg04 DB 13,10,"CPU Type $"
- PrnMsg05 DB 13,10,"FPU Type $"
- PrnMsg06 DB 13,10,"CPU586P6.ASM v1.2e",13,10,"$"
- PrnMsg07 DB 13,10,"$"
-
- Temp DW 0FFFFH
- FEnv DW 7 DUP (0)
- DSeg ENDS
-
- CSeg SEGMENT
- ASSUME CS:CSeg,DS:DSeg,SS:SSeg
-
- .8086
-
- CPUType PROC ;>AX CpuType (1=86,2=286,3=386,4=486,5=586,6=686,etc.)
- MOV AX,1
- PUSHF
- POP BX
- AND BH,0FH
- PUSH BX
- POPF
- PUSHF
- POP CX
- AND CH,0F0H
- CMP CH,0F0H
- JE @@1 ;8086 or below 80286
- INC AX
- OR BH,0F0H
- PUSH BX
- POPF
- PUSHF
- POP CX
- AND CH,0F0H
- JE @@1 ;80286
- .386
- INC AX
- MOV EBX,ESP
- AND ESP,0FFFCH
- PUSHFD
- POP EDX
- MOV ECX,EDX
- XOR EDX,000040000H
- PUSH EDX
- POPFD
- PUSHFD
- POP EDX
- PUSH ECX
- POPFD
- XOR EDX,ECX
- AND EDX,000040000H ;Test Alignment Check Bit
- MOV ESP,EBX
- JZ @@1 ;80386
- ;.486
- INC AX
- PUSHFD
- POP EDX
- MOV ECX,EDX
- XOR EDX,000200000H
- PUSH EDX
- POPFD
- PUSHFD
- POP EDX
- PUSH ECX
- POPFD
- XOR EDX,ECX ;Test ID Bit
- JZ @@1 ;80486
- MOV EAX,1
- ;.586 or higher, CPUID returns Cpu Generation Number in AX Bits 8-11
- CPUID
- AND AH,0FH
- SHR AX,8
- .8086
- .8087
- @@1: RET
- CPUType ENDP
-
- FPUType PROC ;>AX FpuType (0=None (SX),1=87,2=287,3=387,
- ;4=487,5=586 or higher (FPU always internal))
- FNSTENV FEnv
- FNINIT
- FNSTSW Temp
- CMP BYTE PTR Temp,0
- JNE @@1
- FNSTCW Temp
- CMP BYTE PTR [Temp+1],3
- JNE @@1
- FLDENV FEnv ;FPU exists
- CALL CPUType ;Determine CPU type
- CMP AX,4 ;Test CPU(in AX)>=80486
- JAE @@2 ;CPU=80486,FPU exists=80487 (Internal)
- ;CPU>=80586,FPU=Internal
- MOV AX,3
- FLD1
- FLDZ
- FDIVP ST(1),ST
- FLD ST(0)
- FCHS
- FCOMPP
- FSTSW Temp
- FWAIT
- TEST Temp,100H
- JNZ @@2 ;80387
- DEC AX
- FLD1
- @@0: FISTP Temp
- FSTENV FEnv
- MOV BX,CS
- SHL BX,1
- SHL BX,1
- SHL BX,1
- SHL BX,1
- ADD BX,OFFSET @@0
- INC BX
- FWAIT
- CMP BX,[FEnv+6]
- JE @@2 ;80287
- DEC AX ;8087
- RET
- @@1: XOR AX,AX ;None
- @@2: RET
- FPUType ENDP
-
- ; Main Program
-
- CSegEntry:
- MOV AX,DSeg
- MOV DS,AX
- LEA DX,PrnMsg01
- CALL Write
- LEA DX,PrnMsg02
- CALL Write
- LEA DX,PrnMsg03
- CALL Write
- LEA DX,PrnMsg04
- CALL Write
-
- CALL CPUType
-
- CMP AX,1 ;Choose string and load offset
- JNE @@1
- LEA DX,Cpu8086
- @@1: CMP AX,2
- JNE @@2
- LEA DX,Cpu80286
- @@2: CMP AX,3
- JNE @@3
- LEA DX,Cpu80386
- @@3: CMP AX,4
- JNE @@4
- LEA DX,Cpu80486
- @@4: CMP AX,5
- JNE @@5
- LEA DX,Cpu80586
- @@5: CMP AX,6
- JNE @@6
- LEA DX,Cpu80686
- @@6: CMP AX,7
- JNAE @@7
- LEA DX,Cpu80x86
- @@7: CALL Write ;Write CPU type
- LEA DX,PrnMsg05
- CALL Write
-
- CALL FPUType
-
- OR AX,AX
- JNE @@8
- LEA DX,FpuNone
- @@8:
- CMP AX,1
- JNE @@9
- LEA DX,Fpu8087
- @@9: CMP AX,2
- JNE @@10
- LEA DX,Fpu80287
- @@10: CMP AX,3
- JNE @@11
- LEA DX,Fpu80387
- @@11: CMP AX,4
- JNE @@12
- LEA DX,Fpu80487
- @@12: CMP AX,5
- JNAE @@13
- LEA DX,FpuInteg
- @@13: CALL Write ;Write FPU type
- LEA DX,PrnMsg07 ;CR/LF
- CALL Write
- LEA DX,PrnMsg06 ;Version
- CALL Write
-
- MOV AX,4C00H
- INT 21H
- Write: MOV AX,0900H
- INT 21H
- RET
-
- CSeg ENDS
-
- END CSegEntry