1 ; To assemble the code using MASM 5.10:
7 ; Author: Ben Lunt (Forever Young Software)
11 ; If you need an EXE to COM converter, you can get one here
13 ; The following code won't assemble with NBASM yet, since
14 ; I have not added all the FPU instructions. I hope to get to them soon.
15 ; Until then, you will have to use a different assembler. Sorry.
19 assume cs:CodeSeg, ds:CodeSeg, es:CodeSeg
22 start: mov ax,cs ; free unused part of Mem Block
23 mov es,ax ; for .COM file format
28 mov cx,0121h ; If CH can be shifted by 21h,
29 shl ch,cl ; then it's an 8086, because
30 jz short p1_8086 ; a 186+ limits shift counts.
31 push sp ; If SP is pushed as its
32 pop ax ; original value, then
33 cmp ax,sp ; it's a 286+.
35 mov ax,7000h ; if bits 12,13,14 are still set
36 push ax ; after pushing/poping to/from
37 popf ; the flags register then we have
42 jne short p1_286 ; it's a 386+
44 push bp ; Align stack to dword
51 mov ebx,eax ; EBX = eflags
52 xor eax,40000h ; Toggle AC bit
53 push eax ; Eflags = EAX
57 popfd ; Restore eflags
58 mov sp,bp ; Restore stack
60 cmp eax,ebx ; If the bit was not
61 je short p1_386 ; reset, it's a 486+
66 xor eax,200000h ; Toggle ID bit
67 push eax ; Eflags = EAX
71 popfd ; Restore eflags
72 cmp eax,ebx ; If the bit was not
73 jne short p1_486 ; reset, it's a 586+
74 mov dx,offset CPUType5 ; 586+
76 p1_486: mov dx,offset CPUType4 ; 486
78 p1_386: mov dx,offset CPUType3 ; 386
80 p1_286: mov dx,offset CPUType2 ; 286
82 p1_186: mov dx,offset CPUType1 ; 186
84 p1_8086: mov dx,offset CPUType0 ; 8086
87 .186 ; make sure we set proc back to 186
88 .8087 fninit ; Initialize FPU
89 mov _Junk,55AAh ; Set junk value
90 fnstsw _Junk ; Store status word
91 cmp _Junk,0 ; If it's not 0, no FPU
93 fnstcw _Junk ; Store control word
94 mov ax,_Junk ; If the bits are not the way
95 and ax,103Fh ; they should be, no FPU
99 and _Junk,0FF7Fh ; Clear interrupt bit
100 fldcw _Junk ; Load control word
101 fdisi ; Disable interrupts
102 fstcw _Junk ; Store control word
103 test _Junk,80h ; If it changed, it's an 8087
105 .286 ; allowes .287 also
106 finit ; Re-initialize
107 fld1 ; Divide 1 by 0 to get
108 fldz ; a positive infinity
110 fld st ; Get a negative infinity
112 fcompp ; Compare them
113 fstsw ax ; Store status word
114 sahf ; If the FPU thought that they
115 je short p2_287 ; were equal, it's a 287
116 mov dx,offset FPUType3 ; 387
117 finit ; Init processor
119 p2_287: mov dx,offset FPUType2 ; 287
120 finit ; Init processor
122 p2_8087: mov dx,offset FPUType0 ; 8087
123 finit ; Init processor
125 p2_nofpu: mov dx,offset FPUType
134 CPUType0 db 13,10,'You have an 8086/88 processor.$'
135 CPUType1 db 13,10,'You have an 186/88 processor.$'
136 CPUType2 db 13,10,'You have an 286 processor.$'
137 CPUType3 db 13,10,'You have an 386 processor.$'
138 CPUType4 db 13,10,'You have an 486 processor.$'
139 CPUType5 db 13,10,'You have an 586 or better processor.$'
141 FPUType db 13,10,"You don't have a math coprocessor.$"
142 FPUType0 db 13,10,'You have an 8087 math coprocessor.$'
143 FPUType2 db 13,10,'You have an 287 math coprocessor.$'
144 FPUType3 db 13,10,'You have an 387 or better math coprocessor.$'