Getting the CPU and FPU type
This small routine is a simple way of detecting between the different Intel CPU and FPU chips (80/88, 186, 286, etc.)
There are ways to detect between the closer family of chips. For instance; detecting between an 8086 and an 8088 (8-bit bus and 16-bit processors), and the 80186 and 80188 (just check the size of the instruction queue). I do not do this in this routine, but if you need some help on doing this, let me know.
The code is quite commented so with out any more blaa blaa....
; To assemble the code using MASM 5.10:
; MASM cputype;
; LINK cputype;
; EXE2COM cputype;
; Version: 1.00b
; Author: Ben Lunt (Forever Young Software)
; Date: 20 Nov 1997
; If you need an EXE to COM converter, you can get one here
;
; The following code won't assemble with NBASM yet, since
; I have not added all the FPU instructions. I hope to get to them soon.
; Until then, you will have to use a different assembler. Sorry.
;
CodeSeg segment
assume cs:CodeSeg, ds:CodeSeg, es:CodeSeg
.186
org 100h
start: mov ax,cs ; free unused part of Mem Block
mov es,ax ; for .COM file format
mov bx,4096 ;
mov ah,4Ah ;
int 21h ;
mov cx,0121h ; If CH can be shifted by 21h,
shl ch,cl ; then it's an 8086, because
jz short p1_8086 ; a 186+ limits shift counts.
push sp ; If SP is pushed as its
pop ax ; original value, then
cmp ax,sp ; it's a 286+.
jne short p1_186
mov ax,7000h ; if bits 12,13,14 are still set
push ax ; after pushing/poping to/from
popf ; the flags register then we have
pushf ; a 386+
pop ax
and ax,7000h
cmp ax,7000h
jne short p1_286 ; it's a 386+
.386
push bp ; Align stack to dword
mov bp,sp
and sp,0FFFCh
pushfd ; Save eflags
cli ; No interrupts
pushfd ; EAX = eflags
pop eax
mov ebx,eax ; EBX = eflags
xor eax,40000h ; Toggle AC bit
push eax ; Eflags = EAX
popfd
pushfd ; EAX = eflags
pop eax
popfd ; Restore eflags
mov sp,bp ; Restore stack
pop bp
cmp eax,ebx ; If the bit was not
je short p1_386 ; reset, it's a 486+
pushfd ; Save eflags
cli ; No interrupts
pushfd ; EAX = eflags
pop eax
xor eax,200000h ; Toggle ID bit
push eax ; Eflags = EAX
popfd
pushfd ; EBX = eflags
pop ebx
popfd ; Restore eflags
cmp eax,ebx ; If the bit was not
jne short p1_486 ; reset, it's a 586+
mov dx,offset CPUType5 ; 586+
jmp short cpudone
p1_486: mov dx,offset CPUType4 ; 486
jmp short cpudone
p1_386: mov dx,offset CPUType3 ; 386
jmp short cpudone
p1_286: mov dx,offset CPUType2 ; 286
jmp short cpudone
p1_186: mov dx,offset CPUType1 ; 186
jmp short cpudone
p1_8086: mov dx,offset CPUType0 ; 8086
cpudone: mov ah,09
int 21h
.186 ; make sure we set proc back to 186
.8087 fninit ; Initialize FPU
mov _Junk,55AAh ; Set junk value
fnstsw _Junk ; Store status word
cmp _Junk,0 ; If it's not 0, no FPU
jne short p2_nofpu
fnstcw _Junk ; Store control word
mov ax,_Junk ; If the bits are not the way
and ax,103Fh ; they should be, no FPU
cmp ax,3Fh
jne short p2_nofpu
and _Junk,0FF7Fh ; Clear interrupt bit
fldcw _Junk ; Load control word
fdisi ; Disable interrupts
fstcw _Junk ; Store control word
test _Junk,80h ; If it changed, it's an 8087
jnz short p2_8087
.286 ; allowes .287 also
finit ; Re-initialize
fld1 ; Divide 1 by 0 to get
fldz ; a positive infinity
fdiv
fld st ; Get a negative infinity
fchs
fcompp ; Compare them
fstsw ax ; Store status word
sahf ; If the FPU thought that they
je short p2_287 ; were equal, it's a 287
mov dx,offset FPUType3 ; 387
finit ; Init processor
jmp short fputypeD
p2_287: mov dx,offset FPUType2 ; 287
finit ; Init processor
jmp short fputypeD
p2_8087: mov dx,offset FPUType0 ; 8087
finit ; Init processor
jmp short fputypeD
p2_nofpu: mov dx,offset FPUType
fputypeD: mov ah,09
int 21h
.186
.8087
ret
_Junk dw 00h
CPUType0 db 13,10,'You have an 8086/88 processor.$'
CPUType1 db 13,10,'You have an 186/88 processor.$'
CPUType2 db 13,10,'You have an 286 processor.$'
CPUType3 db 13,10,'You have an 386 processor.$'
CPUType4 db 13,10,'You have an 486 processor.$'
CPUType5 db 13,10,'You have an 586 or better processor.$'
FPUType db 13,10,"You don't have a math coprocessor.$"
FPUType0 db 13,10,'You have an 8087 math coprocessor.$'
FPUType2 db 13,10,'You have an 287 math coprocessor.$'
FPUType3 db 13,10,'You have an 387 or better math coprocessor.$'
CodeSeg ends
end start