You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('') and can be up to 35 characters long.
208 lines
8.7 KiB
208 lines
8.7 KiB
3 years ago

; 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.



;



.MODEL SMALL



.CODE



PUBLIC _chips






_chips PROC






control 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 endp









cpu_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 out






got386: 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 out






digmor: 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 out






gotNEC: mov DX,0200 ; it's an NEC V20/V30 so save 200 in DX






CPUbye: 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 reference



cpu_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 PROC






do_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 3






NDPbye: ret ; and go back where you came from



; (i.e., ===> _chips) carrying the NDP



; type in Ur AX register



ndp_type endp






_text ends



end
