- Joined
- Dec 19, 2005
- Messages
- 18,728
“One behavioral difference I found between an AMD Am486SX2-66 and an Intel i486SX (S-spec SX683) is that the former writes FP instruction/data pointers in FSTENV/FSAVE and the latter does not (only writes FFh words). Such differences are not surprising when one wades deep into undocumented behavior.
On the other hand, a Cyrix Cx486S seems to behave much like an AMD Am486SX2-66.
check87 proc near
push bp
mov bp,sp ; establish stack frame
xor ax,ax ; initialize with known value
push ax
fninit ; reset FPU
fnstcw word ptr [bp-2] ; save FPU control word
pop ax ; move FCW into AX
mov al,0 ; assume no FPU
cmp ah,3 ; 00h or FFh if no FPU
jnz nox87
mov al,1 ; indicate FPU present
nox87: mov ah,0 ; clear AH
mov sp,bp ; clean up stack
pop bp
ret
check87 endp
The key points are:
https://www.os2museum.com/wp/learn-something-old-every-day-part-xviii-how-does-fpu-detection-work/
Other Vendors
My one system with an IBM 486BL2 processor behaves slightly differently. The behavior is generally similar to a 386, but the values written to memory do not have all bits set. On my test system, the high byte of each word was FFh, but the low byte was inconsistent, though never zero. Therefore, one cannot rely on e.g. FNSTSW to always write FFFFh to memory on systems with no FPU.On the other hand, a Cyrix Cx486S seems to behave much like an AMD Am486SX2-66.
Safe FPU Detection
How to properly detect an FPU then, without running into problems on systems that don’t have one? Here’s one possible approach (16-bit, able to deal with 8086/8088):check87 proc near
push bp
mov bp,sp ; establish stack frame
xor ax,ax ; initialize with known value
push ax
fninit ; reset FPU
fnstcw word ptr [bp-2] ; save FPU control word
pop ax ; move FCW into AX
mov al,0 ; assume no FPU
cmp ah,3 ; 00h or FFh if no FPU
jnz nox87
mov al,1 ; indicate FPU present
nox87: mov ah,0 ; clear AH
mov sp,bp ; clean up stack
pop bp
ret
check87 endp
The key points are:
- FNINIT (not FINIT) must be used because the FPU may be in an unknown state and a WAIT instruction may hang
- Storage for the FPU status word must be initialized with a known value
- FNSTCW must be used instead of FSTCW
- After FNSTCW, no WAIT is needed for synchronization
Summary
While detecting the presence of an FPU is well understood, detecting its absence is much less obvious. It relies on CPU behavior which is effectively undocumented on 80826 and later processors. While the 8086 had a generic co-processor interface, the 286 and later have significant knowledge of x87 FPU instructions. That includes the 486SX, which cannot be equipped with an FPU. Even when there is no FPU present, FP instructions on the 80286 and later are far from no-ops and may behave in surprising ways.“https://www.os2museum.com/wp/learn-something-old-every-day-part-xviii-how-does-fpu-detection-work/