home *** CD-ROM | disk | FTP | other *** search
- comment *
- Purpose:
- To detect math coprocessor type (8087, 287, 387) and manufacturer
- (Intel, IIT)
-
- Author:
- Yousuf Khan. Source code based partly on Infoplus source code by
- Andrew Rossman, IIT detection routines entirely my own. Infoplus is
- freeware, therefore this source code is released as freeware,
- not public domain. Original authors must be acknowledged in any
- future work.
- *
-
- .model tiny
-
- .data
- fnone equ 0
- f8087 equ 1
- f80287 equ 2
- f80387 equ 3
- funk equ 0FFh
- ndp_cw dw ?
- ndp_sw dw ?
- mNDPCW dw ?
- mndp db ?
- ndpmsg db "Math coprocessor found: $"
- manmsg db "Manufacturer: $"
- _87 db "8087",13,10,"$"
- _287 db "80287",13,10,"$"
- _387 db "80387 or i486",13,10,"$"
- _funk db "What the hell kind of a copro is this?",13,10,"$"
- Intel db "Intel or clone",13,10,"$"
- IIT db "IIT or clone",13,10,"$"
-
- .code
- org 100h
-
- start:
-
- ; The next two 80x87 instructions cannot carry the WAIT prefix,
- ; because there may not be an 80x87 for which to wait. The WAIT is
- ; therefore emulated with a MOV CX,<value>! LOOP $ combination.
-
- .8087
- mov word ptr ndp_cw,0000H
- cli ;no interrupts during this test
-
- fninit ;initialize NDP
- mov cx,2
- loop $
-
- fnstcw ndp_cw ;store control word in ndp_cw
- ; mov cx,14h
- ; loop $
-
- sti
- mov ax,ndp_cw ;check for valid status word
- cmp ah,3 ;is NDP present?
- je short ndp_01 ;if 3, must be there
- mov mNDP,fnone
- jmp short ndp_done
-
- ndp_01:
- cmp ax,03FFH ;check if 8087
- jne short ndp_02
- mov mNDP,f8087
- jmp short ndp_04
-
- ndp_02:
- call iit_test
-
- .286P
- cmp ax,037FH ;check if 286/387/486
- jne short ndp_05 ;must be garbage
-
- ;detect 287 or 387
-
- fld1 ;Load +1.0 onto NDP stack
- fldz ;Load +0.0 onto NDP stack
- fdiv ;do +1/0
- fld1 ;Load +1.0 onto NDP stack
- fchs ;Change to -1.0
- fldz ;Load +0.0 onto NDP stack
- fdiv ;do -1/0
- fcom ;compare
- fstsw ndp_sw
- mov ax,ndp_sw
- and ah,41H ; C3, C0
- cmp ah,40H ; ST(0) = ST(1)
- jne short ndp_03
- mov mNDP,f80287
- jmp short ndp_04
-
- ndp_03:
- cmp ah,01H ; ST(0) < ST(1)
- jne short ndp_05
- mov mNDP,f80387
-
- ndp_04:
-
- .8087
- fstcw mNDPCW ;save status for INFOPLUS
- jmp short ndp_done
-
- ndp_05:
- mov mNDP,funk
-
- ndp_done:
- mov ah, 9
- mov dx, offset manmsg
- int 21h
- cmp [mman], 1 ;IIT=1?
- jne short intelman
- mov ah, 9
- mov dx, offset iit
- int 21h
- jmp short type_msgs
-
- intelman:
- mov ah, 9
- mov dx, offset intel
- int 21h
-
- type_msgs:
- mov ah, 9
- mov dx, offset ndpmsg
- int 21h
- cmp [mndp], 0FFh
- jne short not_funk
- mov ah, 9
- mov dx, offset _funk
- int 21h
- jmp short exit_prog
-
- not_funk:
- cmp [mndp], 3
- jne short not_387
- mov ah, 9
- mov dx, offset _387
- int 21h
- jmp short exit_prog
-
- not_387:
- cmp [mndp], 2
- jne short not_287
- mov ah, 9
- mov dx, offset _287
- int 21h
- jmp short exit_prog
-
- not_287:
- mov ah, 9
- mov dx, offset _87
- int 21h
- exit_prog:
- mov al, [mndp]
- mov ah, 4ch
- int 21h
-
- iit_test proc near
-
- .data
- fsb0 equ <dw 0E8DBh> ;bank 0 opcode
- fsb1 equ <dw 0EBDBh> ;bank 1 opcode
- fsb2 equ <dw 0EADBh> ;bank 2 opcode
- f4x4 equ <dw 0F1DBh> ;4x4 mat transform opcode
- f0 dd 9.9999
- f1 dd 10.0
- mman db 0 ;assume Intel=0 installed initially
-
- .code
- ;initialize two banks to zero
- wait
- fsb0 ;switch to bank 0, default on Intel
- finit
- fsb1 ;switch to bank 1
- finit
- ;store a 2.0 into bank 0 while placing a 1.0 into bank 1
- fsb0 ;switch to bank 0
- fld [f0] ;load value from [F2] into bank 0 stack
- fclex ;clear all math copro exceptions
-
- fsb1 ;switch to bank 1, should fail on Intel
- fld [f1] ;load a 1 into bank 1 stack
- fclex
-
- fsb0
- fcom [f0] ;compare, should be false on Intel
- fclex
-
- push ax
- .286p ;FNSTSW AX only works on 287+
- fnstsw ax ;store stat word in AX
- sahf ;transfer copro flags to CPU flags
- ja short is_intel
- mov [mman], 1 ;IIT=1, Intel=0 (default)
-
- is_intel:
- finit ;reset to original
- pop ax
- ret
- endp
- end start
-
-
- iit_test proc near
-
- .data
- fsb0 equ <dw 0E8DBh> ;bank 0 opcode
- fsb1 equ <dw 0EBDBh> ;bank 1 opcode
- fsb2 equ <dw 0EADBh> ;bank 2 opcode
- f4x4 equ <dw 0F1DBh> ;4x4 mat transform opcode
- f0 dd 9.9999
- f1 dd 10.0
- mman db 0 ;assume Intel=0 installed initially
-
- .code
- ;initialize two banks to zero
- wait
- fsb0 ;switch to bank 0, default on Intel
- finit
- fsb1 ;switch to bank 1
- finit
- ;store a 2.0 into bank 0 while placing a 1.0 into bank 1
- fsb0 ;switch to bank 0
- fld [f0] ;load value from [F2] into bank 0 stack
- fclex ;clear all math copro exceptions
-
- fsb1 ;switch to bank 1, should fail on Intel
- fld [f1] ;load a 1 into bank 1 stack
- fclex
-
- fsb0
- fcom [f0] ;compare, should be false on Intel
- fclex
-
- push ax
- .286p ;FNSTSW AX only works on 287+
- fnstsw ax ;store stat word in AX
- sahf ;transfer copro flags to CPU flags
- ja short is_intel
- mov [mman], 1 ;IIT=1, Intel=0 (default)
-
- is_intel:
- finit ;reset to original
- pop ax
- ret
- endp
- end start
-
- ; EOF COPRO.ASM
-