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