; calling convention:;; int chips( void );;; returns:;; tucked away neatly in your AX....;; you get back 8x if an 8088/8086; 18x if an 80186/80188; 28x if an 80286; 38x if an 80386; 20x for a NEC V20/V30; AND; xx0 if NO NDP is found; xx1 if an 8087; xx2 if an 80287; xx3 for an 80387;; OR.....;; >>> A return of 280 means you got an 80286 machine with no NDP, <<<; >>> 383 means you have an 80386/80387 rig to work with, and a <<<; >>> return of 81 sez that you have 8088/8086 CPU with an 8087. <<<; >>> A 200 tells you that you got an NEC V20/V30 without an NDP. <<<; >>> ETC., Etc., etc. <<<;; NOTE:;; There are lotsa ways of handling the way this function returns; it's data. For my purposes, I have elected this one because; it requires only int arithmetic on the caller's end to extract; all the info I need from the return value. I think that I'm; well enough 'commented' in the following code so that you will; be able to tinker and Putz until you find the best return tech; nique for Ur purposes without having to reinvent the wheel.;; >>>> Please see TEST.C, enclosed in this .ARC. <<<<;; REFERENCES:;; _chips is made up of two PROC's, cpu_type and ndp_type.;; cpu_type is based on uncopyrighted, published logic by; Clif (that's the way he spells it) Purkiser of Intel ; Santa Clara.;; ndp_type is adopted from Ted Forgeron's article in PC; Tech Journal, Aug '87 p43.;; In the event of subsequent republication of this function,; please carry forward reference to these two gentlemen as; original authors.;; Copr. 1987 Pat Shea  Psi! (that Copr. is on there cuz my; lawyer sez I should, but feel; free to hack away!!! pats.);; Update: 1/1/88  changed this code slightly so that it is; compilable using MASM 5.0, and the test.c; file using MSC 5.0. .MODEL SMALL.CODE PUBLIC _chips_chips PROCcontrol dw 0 ; control word needed for the NDP test push BP ; save where Ur at mov BP,SP ; going in..... push DI push SI push CX ; not really needed for MSC but kinda ; nice to do cuz someone else might ; want to use the function and we do ; use CX later on call cpu_type ; find out what kinda CPU you got and ; and save it in DX for future reference call ndp_type ; check for math coprocessor (NDP) type ; and hold that result in AX add AX,DX ; add the two results together and hold ; 'em in AX for Ur return to the caller pop CX ; put things back the way that you pop SI ; found 'em when you started this pop DI ; little drill off..... pop BP ; AND ret ; go back to where you came from.... ; ( ===> the calling program ) ; with Ur results sittin' in AX !!_chips endpcpu_type PROC pushf ; pump Ur flags register onto the stack xor DX,DX ; blow out Ur DX and AX to start off xor AX,AX ; with a clean slate push AX ; put AX on the stack popf ; bring it back in Ur flags pushf ; try to set bits 12 thru 15 to a zero pop AX ; get back Ur flags word in AX and AX, 0f000h ; if bits 12 thru 15 are set then you got cmp AX, 0f000h ; an Intel 8018x or a 808x or maybe even jz dig ; a NEC V20/V30 ???  gotta look more...; OTHERWISE....; Here's the BIG one.... 'tells the difference between an 80286 and; an 80386 !! mov AX, 07000h ; try to set FLAG bits 12 thru 14 ;  NT, IOPL push AX ; put it onto the stack popf ; and try to pump 07000H into Ur flags pushf ; push Ur flags, again pop AX ; and bring back AX for a compare and AX,07000h ; if Ur bits 12 thru 14 are set jnz got386 ; then Ur workin' with an 80386 mov DX, 0280 ; save 280 in DX cuz it's an 80286 jmp SHORT CPUbye ; and bail outgot386: mov DX, 0380 ; save 380 in DX cuz it's an Intel 80386 jmp SHORT CPUbye ; and bail out; here's we try to figger out whether it's an 80188/80186, an 8088/8086; or an NEC V20/V30  'couple of slick tricks from Clif Purkiser.....dig: mov AX, 0ffffh ; load up AX mov CL, 33 ; HERE's the FIRST TRICK.... this will ; shift everything 33 times if it's ; 8088/8086, or once for a 80188/80186! shl AX, CL ; on a shift of 33, all bits get zeroed jz digmor ; out so if anything is left ON it's ; gotta be an 80188/80186 mov DX,0180 ; save 180 in DX cuz it's an 80188/80186 jmp SHORT CPUbye ; and bail outdigmor: xor AL,AL ; clean out AL to set ZF mov AL,40h ; ANOTHER TRICK.... mul on an NEC duz NOT mul AL ; effect the zero flag BUT on an Intel jz gotNEC ; 8088/8086, the zero flag gets thrown mov DX,0080 ; 80 into DX cuz it's an Intel 8088/8086 jmp SHORT CPUbye ; and bail outgotNEC: mov DX,0200 ; it's an NEC V20/V30 so save 200 in DXCPUbye: popf ; putchur flags back to where they were ret ; and go back to where you came from ; (i.e., ===> _chips) with the CPU type ; tucked away in DX for future referencecpu_type endp; Check for an NDP.;; >>>>NOTE: If you are using an MASM version < 5.0, don't forget to; use the /R option or you will bomb cuz of the coprocessor instruc; tions. /R is not needed for version 5.0.<<<<<<<<<<<<<<<<<<<<<<<<<ndp_type PROCdo_we: fninit ; try to initialize the NDP mov byte ptr control+1,0 ; clear memory byte fnstcw control ; put control word in memory mov AH,byte ptr control+1 ; iff AH is 03h, you got cmp AH,03h ; an NDP on board !! je chk_87 ; found somethin', keep goin' xor AX,AX ; clean out AX to show a zero jmp SHORT NDPbye ; return (i.e., no NDP); 'got an 8087 ??chk_87: and control,NOT 0080h ; turn ON interrupts (IEM = 0) fldcw control ; load control word fdisi ; turn OFF interrupts (IEM = 1) fstcw control ; store control word test control,0080h ; iff IEM=1, 8087 jz chk287 ; 'guess not! March on.... mov AX,0001 ; set up for a 1 return to jmp SHORT NDPbye ; show an 8087 is on board; if not.... would you believe an 80287 maybe ??chk287: finit ; set default infinity mode fld1 ; make infinity fldz ; by dividing fdiv ; 1 by zero !! fld st ; now make a fchs ; negative infinity fcompp ; compare Ur two infinities fstsw control ; iff, for 8087 or 80287 fwait ; sit tight 'til status word is put away mov AX,control ; getchur control word sahf ; putchur AH into flags jnz got387 ; NO GOOD.... march on !! mov AX,0002 ; gotta be a 80287 cuz we already tested jmp SHORT NDPbye ; for an 8087; We KNOW that there is an NDP on board otherwise we would have bailed; out after 'do_we'. It isn't an 8087 or an 80287 or we wouldn't have; gotten this far. It's gotta be an 80387 !!got387: mov AX,0003 ; call it an 80387 and return 3NDPbye: ret ; and go back where you came from ; (i.e., ===> _chips) carrying the NDP ; type in Ur AX registerndp_type endp_text ends end
