This is the past DOS era of the compilation of source code, although has passed, but for the study of the assembly is still helpful, assembly language is just a basic programmer language, most people can grasp, not necessarily in-depth research.
; calling convention:
;
; int chips (void);
;
; Returns
;
; Tucked away neatly in your AX ....
;
; You have back 8x if a 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 a 80387
;
; OR .....
;
; >>> A Return of 280 means your got A 80286 machine with no NDP, <<<
; >>> 383 means you have a 80386/80387 rig to work with, and a <<<
; >>> return of Bayi sez that your have 8088/8086 CPU with a 8087. <<<
; >>> A tells you are got an NEC v20/v30 without A 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 of the info I need from the return value. I "I" I "M"
; Enough ' commented ' in the following code so
; Be able to tinker and Putz until your find the best return tech-
; Nique for your purposes without has to reinvent the wheel.
;
; >>>> please 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 ' p43.
;
; In the event of subsequent republication of this function,
; Please carry forward reference to two gentlemen as
; Original authors.
;
; Copr. 1987 Pat shea-psi! (That Copr. are on there cuz my
; Lawyer SEZ I should, but feel
; Free to hack away!!! Pats.)
;
; Update:1/1/88-changed This code slightly so, it is
; Compilable using MASM 5.0, and the TEST.C
; File using MSC 5.0. <albert stein>
. 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 todo cuz someone else might
; Want to with the function and we do
; Use CX-Later on
Call CPU_type; Find out what kinda CPU for 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 your return to the caller
Pop CX; Put things back the way so you
Pop SI; Found ' em when you are started this
Pop DI; Little Drill off ...
Pop BP
; and
RET; Go back to where you came from ....
; (===> the Calling program)
; With your 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-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 thru to a zero
Pop AX; Get back your flags word in AX
and AX, 0f000h; If bits thru 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 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 thru are set
JNZ got386; Then Ur Workin ' with a 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 a 80188/80186, an 8088/8086
; Or a NEC v20/v30-' couple of slick tricks from Clif purkiser ....
Dig:mov AX, 0FFFFH; Load up AX
mov CL, 33; Here ' s The trick ... this'll
; Shift everything if it ' s
; 8088/8086, or once for a 80188/80186!
SHL AX, CL; On a shift of the all bits get zeroed
JZ Digmor; Out I if anything is left on it ' s
; Gotta is 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 a 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; into DX cuz it's an Intel 8088/8086
JMP short Cpubye; and bail out
Gotnec:mov dx,0200; It ' s NEC v20/v30 so save 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 a MASM version < 5.0, don ' t forget to
; Use THE/R option or you'll bomb cuz of the the coprocessor instruc-
; tions. /R is isn't 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, 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 a 8087 is on board
; If not ... would you believe a 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 a NDP on board otherwise we would have bailed
; Out after ' Do_we '. It isn ' t an 8087 or a 80287 or we wouldn ' t have
; Gotten this far. It ' s gotta be a 80387!!
Got387:mov ax,0003; Call it a 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