Microsoft (R) Macro Assembler Version 6.14.8444		    06/30/00 13:01:25
cpudtect.asm						     Page 1 - 1


				;;
				;; THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
				;; PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
				;; TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
				;; INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE 
				;; DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). 
				;; THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
				;; EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
				;; FULL TEXT OF THE NON-WARRANTY PROVISIONS.  
				;; 
				;; USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
				;; RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
				;; TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
				;; AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
				;; SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
				;; THE UNITED STATES.  
				;; 
				;; COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
				;;
				;; $Header$
				;; $Log$
				;; Revision 1.1  2000/06/15 00:27:42  joseph
				;; Initial checkin into SourceForge.
				;;
				;; 
				;; 9     3/10/99 10:40a Peter
				;; detect katmai-ness
				;; 
				;; 8     1/20/99 5:50p Peter
				;; norbert's code for k6 and k7 (?) wc
				;; 
				;; 7     12/09/98 1:11p Peter
				;; cpu detection from Norbert for teh rest of the 3DNow!(tm) partners
				;; 
				;; 6     10/03/98 3:35p Peter
				;; First pass at dynamic detection of 3DNow!(tm)
				;; 
				;; 5     7/24/98 1:40p Hohn
				; 
				; 4     5/28/97 8:23a Peter
				; Merge w/ original glide source
				; 
				; 2     3/04/97 9:10p Dow
				;;
				;;
				
				TITLE  cpudtect.asm
				
				.586P
				.model FLAT,C                   ; Flat memory, mangle publics with leading '_'
				
				;;      Data for data segment goes here
				;_DATA   SEGMENT DWORD USE32 PUBLIC 'DATA'; 
				;_DATA   ENDS
				    
				;;; Some useful constants
				; CPU Type
 = FFFFFFFF			CPUTypeUnknown  = 0ffffffffh
 = 00000004			CPUTypePrePent  = 4h
 = 00000005			CPUTypeP5       = 5h    
 = 00000006			CPUTypeP6       = 6h    
				        
				;;; References to external data:
				    
 00000000			_TEXT   SEGMENT
				;;
				;;  _cpu_detect_asm - detect the type of CPU 
				;; 
				;;  USAGE:
				;;
				;;  int __cdecl _cpu_detect_asm(void);
				;;
				;;  returns 4 for non-pen
				
				PUBLIC  _cpu_detect_asm
 00000000			_cpu_detect_asm PROC NEAR
 00000000			P6Stuff:
				    .586
 00000000  56			    push   esi                          ; save registers that are not volatile
 00000001  57			    push   edi
 00000002  53			    push   ebx
 00000003  55			    push   ebp
				
				    ; First, determine whether CPUID instruction is available.
				    ; If it's not, then it's a 386 or 486.
 00000004  9C			    pushfd                              ; push original EFLAGS.
 00000005  58			    pop eax                             ; pop into eax
 00000006  8B C8		    mov ecx, eax                        ; save original EFLAGS in ecx
 00000008  35 00200000		    xor eax, 0200000h                   ; flip ID bit in EFLAGS
 0000000D  50			    push    eax                         ; put it back on stack
 0000000E  9D			    popfd                               ; pop into EFLAGS
 0000000F  9C			    pushfd                              ; get EFLAGS back
 00000010  58			    pop eax                             ; into eax
 00000011  33 C1		    xor eax, ecx                        ; check to see if we could toggle ID
 00000013  74 55		    jz  NotPentium                      ; Sorry, not P5 or P6.
				    
				    ;
				    ; Now determine whether it's an intel P6 CPU.
				    ;
				    ;;  Is it an Intel CPU?
 00000015  33 C0		    xor eax, eax                        ; eax = 0.
 00000017  0F A2		    cpuid                               ; get cpuid
 00000019  81 F3 756E6547	    xor ebx, 0756e6547h                 ; "Genu"
 0000001F  75 53		    jnz NotIntel
 00000021  81 F2 49656E69	    xor edx, 049656e69h                 ; "ineI"
 00000027  75 4B		    jnz NotIntel
 00000029  81 F1 6C65746E	    xor ecx, 06c65746eh                 ; "ntel"
 0000002F  75 43		    jnz NotIntel                        ;
				
				    ;;  Verifying architecture family
				    ;;      eax - type[13:12] family[11:8] model[7:4] revision[3:0]
				    ;;      edx - feature bits
 00000031  B8 00000001		    mov eax, 1
 00000036  0F A2		    cpuid                               ; get family/model/stepping
				    
 00000038  C1 E8 08		    shr eax, 8                          ; rid of model & stepping number
 0000003B  83 E0 0F		    and eax, 0fh                        ; use only family
 0000003E  83 F8 06		    cmp eax, 6
 00000041  7C 20		    jl     IsP5                         ; It's a P5
				    ;; Else it's a P6
				    
				    ; Intel P6 processor. 
				    ;; feature bits are in edx from the cpuid[1]
 00000043			IsP6:
				    ; Make sure it supports Memory Type Range Request registers (bit 12)    
 00000043  8B DA		    mov     ebx, edx
 00000045  F7 C3 00001000	    test    ebx, 1000h
				
				    ;; Hmmmm... p6 w/o mtrr's?
 0000004B  74 16		    jz      IsP5
				
				    ;; Check for katmai-ness (bit 25)
 0000004D  F7 C2 02000000	    test    edx, 2000000h
 00000053  74 07		    jz      noKNI
				
 00000055  B8 00000007		    mov     eax, 7
 0000005A  EB 13		    jmp     DoneCpu                         ; return
				    
 0000005C			noKNI:      
 0000005C  B8 00000006		    mov     eax, 6                          ; 
 00000061  EB 0C		    jmp     DoneCpu                         ; return 
				
 00000063			IsP5:   
 00000063  B8 00000005		    mov     eax, 5                          ; 
 00000068  EB 05		    jmp     DoneCpu
				
 0000006A			NotPentium:
 0000006A  B8 00000004		    mov     eax, 4
				
 0000006F			DoneCpu:
 0000006F  5D			    pop     ebp
 00000070  5B			    pop     ebx
 00000071  5F			    pop     edi
 00000072  5E			    pop     esi
 00000073  C3			    ret
				
				
 00000074			NotIntel:
				
				    ;; This is a non-Intel processor. Figure out whether it supports
				    ;; both MMX and 3DNow!, in which case we can use Norbert's cool
				    ;; MMX/3DNow!(tm) code
				    ;;
				    ;; The return value is split into two 16-bit fields. Bits [31:16]
				    ;; identify the processor vendor as follows:
				    ;;
				    ;; 8001h   AMD
				    ;; 8002h   Cyrix
				    ;; 8003h   IDT
				    ;;
				    ;; Bits [15:0] identify processor features as follows:
				    ;;
				    ;; 0001h   MMX
				    ;; 0002h   3DNow! (tm)
				    ;; 0004h   K6-style MTRRs
				    ;; 0008h   PentiumII-style MTRRs
				
 00000074  33 F6		    xor esi, esi     ; default feature flags
 00000076  33 FF		    xor edi, edi     ; default extended feature flags
				
				    ;; Test whether extended feature function is supported
				
 00000078  B8 80000000		    mov eax, 80000000h
 0000007D  0F A2		    cpuid
 0000007F  3D 80000000		    cmp eax, 80000000h
 00000084  76 09		    jbe NoExtendedFeatures
				
				    ;; execute extended feature function
				
 00000086  B8 80000001		    mov eax, 80000001h
 0000008B  0F A2		    cpuid
 0000008D  8B FA		    mov edi, edx
				
 0000008F			NoExtendedFeatures:
				
				    ;; execute standard feature function
				
 0000008F  B8 00000001		    mov eax, 1
 00000094  0F A2		    cpuid
 00000096  8B F2		    mov esi, edx
 00000098  8B E8		    mov ebp, eax           ; save family/model/stepping
				
				    ;; get the vendor string 
				 
 0000009A  B8 00000000		    mov eax, 0
 0000009F  0F A2		    cpuid
				
 000000A1			ChkAMD:
 000000A1  81 FB 68747541	    cmp ebx, 68747541h     ; 'htuA'
 000000A7  75 10		    jne ChkCyrix
 000000A9  81 FA 69746E65	    cmp edx, 69746E65h     ; 'itne'
 000000AF  75 08		    jne ChkCyrix
 000000B1  81 F9 444D4163	    cmp ecx, 444D4163h     ; 'DMAc'
 000000B7  74 68		    je  CPUisAMD
				
 000000B9			ChkCyrix:
 000000B9  81 FB 69727943	    cmp ebx, 69727943h     ; 'iryC'                   
 000000BF  75 14		    jne ChkIDT
 000000C1  81 FA 736E4978	    cmp edx, 736E4978h     ; 'snIx'
 000000C7  75 0C		    jne ChkIDT
 000000C9  81 F9 64616574	    cmp ecx, 64616574h     ; 'deat'
 000000CF  0F 84 00000094	    je  CPUisCyrix
				
 000000D5			ChkIDT:
 000000D5  81 FB 746E6543	    cmp ebx, 746E6543h     ; 'tneC'
 000000DB  0F 85 000000B0	    jne UnknownVendor
 000000E1  81 FA 48727561	    cmp edx, 48727561h     ; 'Hrua'
 000000E7  0F 85 000000A4	    jne UnknownVendor
 000000ED  81 F9 736C7561	    cmp ecx, 736C7561h     ; 'slua'
 000000F3  0F 85 00000098	    jne UnknownVendor
				
 000000F9			CPUisIDT:
 000000F9  B8 80030000		    mov  eax, 80030000h    ; vendor = IDT, features = none
 000000FE  F7 C6 00800000	    test esi, 00800000h    ; check for MMX bit in features
 00000104  0F 84 FFFFFF65	    jz   DoneCpu
 0000010A  83 C8 01		    or   eax, 1            ; set MMX feature flag
 0000010D  F7 C7 80000000	    test edi, 80000000h    ; check for 3DNow! bit in extended features
 00000113  0F 84 FFFFFF56	    jz   DoneCpu
 00000119  83 C8 02		    or   eax, 2            ; set 3DNow! feature flag
 0000011C  E9 FFFFFF4E		    jmp  DoneCpu
				
 00000121			CPUisAMD:
 00000121  B8 80010000		    mov  eax, 80010000h    ; vendor = AMD, features = none
 00000126  8B D5		    mov  edx, ebp          ; family/model/stepping information
 00000128  81 E2 00000FFF	    and  edx, 00000FFFh    ; extract family/model/stepping
 0000012E  81 FA 00000588	    cmp  edx, 00000588h    ; CXT, Sharptooth, or K7 ?
 00000134  72 10		    jb   AmdMTRRchkDone    ; nope, definitely no MTRRs
 00000136  81 FA 00000600	    cmp  edx, 00000600h    ; K7 or better ?
 0000013C  72 05		    jb   AmdHasK6MTRR      ; nope, but supports K6 MTRRs
 0000013E  83 C8 08		    or   eax, 8            ; set P2_MTRR feature flag
 00000141  EB 03		    jmp  AmdMTRRchkDone    ;
 00000143			AmdHasK6MTRR:
 00000143  83 C8 04		    or   eax, 4            ; set K6_MTRR feature flag
 00000146			AmdMTRRchkDone:
 00000146  F7 C6 00800000	    test esi, 00800000h    ; check for MMX bit in features
 0000014C  0F 84 FFFFFF1D	    jz   DoneCpu
 00000152  83 C8 01		    or   eax, 1            ; set MMX feature flag
 00000155  F7 C7 80000000	    test edi, 80000000h    ; check for 3DNow! bit in extended features
 0000015B  0F 84 FFFFFF0E	    jz   DoneCpu
 00000161  83 C8 02		    or   eax, 2            ; set 3DNow! feature flag
 00000164  E9 FFFFFF06		    jmp  DoneCpu
				
 00000169			CPUisCyrix:
 00000169  B8 80020000		    mov  eax, 80020000h    ; vendor = Cyrix, features = none
 0000016E  F7 C6 00800000	    test esi, 00800000h    ; check for MMX bit in features
 00000174  0F 84 FFFFFEF5	    jz   DoneCpu
 0000017A  83 C8 01		    or   eax, 1            ; set MMX feature flag
 0000017D  F7 C7 80000000	    test edi, 80000000h    ; check for 3DNow! bit in extended features
 00000183  0F 84 FFFFFEE6	    jz   DoneCpu
 00000189  83 C8 02		    or   eax, 2            ; set 3DNow! feature flag
 0000018C  E9 FFFFFEDE		    jmp  DoneCpu
				
 00000191			UnknownVendor:
 00000191  B8 FFFFFFFF		    mov  eax, 0ffffffffh
 00000196  E9 FFFFFED4		    jmp  DoneCpu
				
				        
 0000019B			_cpu_detect_asm ENDP
				
				
				;------------------------------------------------------------------------------   
				; this routine sets the precision to single
				; which effects all adds, mults, and divs
    align 4                 ; 
				    PUBLIC  single_precision_asm
 0000019C			single_precision_asm PROC NEAR
				.586
 0000019C  50			    push  eax       ; make room
 0000019D  DB E2		    fnclex          ; clear pending exceptions    
 0000019F  9B D9 3C 24		    fstcw WORD PTR [esp]
 000001A3  8B 04 24		    mov   eax, DWORD PTR [esp]
 000001A6  25 0000FCFF		    and   eax, 0000fcffh  ; clear bits 9:8
 000001AB  89 04 24		    mov   DWORD PTR [esp], eax
 000001AE  D9 2C 24		    fldcw WORD PTR [esp]
 000001B1  58			    pop   eax
 000001B2  C3			    ret   0
 000001B3			single_precision_asm ENDP
				
				;------------------------------------------------------------------------------   
				; this routine sets the precision to double
				; which effects all adds, mults, and divs
				    align 4                 ; 
				    PUBLIC  double_precision_asm
 000001B4			double_precision_asm PROC NEAR
				.586
 000001B4  50			    push  eax       ; make room
 000001B5  DB E2		    fnclex          ; clear pending exceptions    
 000001B7  9B D9 3C 24		    fstcw WORD PTR [esp]
 000001BB  8B 04 24		    mov   eax, DWORD PTR [esp]
 000001BE  25 0000FCFF		    and   eax, 0000fcffh  ; clear bits 9:8
 000001C3  0D 000002FF		    or    eax, 000002ffh  ; set 9:8 to 10
 000001C8  89 04 24		    mov   DWORD PTR [esp], eax
 000001CB  D9 2C 24		    fldcw WORD PTR [esp]
 000001CE  58			    pop   eax
 000001CF  C3			    ret   0
 000001D0			double_precision_asm ENDP
				    
 000001D0			_TEXT ENDS
				END
Microsoft (R) Macro Assembler Version 6.14.8444		    06/30/00 13:01:25
cpudtect.asm						     Symbols 2 - 1




Segments and Groups:

                N a m e                 Size     Length   Align   Combine Class

FLAT . . . . . . . . . . . . . .	GROUP
_DATA  . . . . . . . . . . . . .	32 Bit	 00000000 Para	  Public  'DATA'	
_TEXT  . . . . . . . . . . . . .	32 Bit	 000001D0 Para	  Public  'CODE'	


Procedures,  parameters and locals:

                N a m e                 Type     Value    Attr

_cpu_detect_asm  . . . . . . . .	P Near	 00000000 _TEXT	Length= 0000019B Public C
  P6Stuff  . . . . . . . . . . .	L Near	 00000000 _TEXT	
  IsP6 . . . . . . . . . . . . .	L Near	 00000043 _TEXT	
  noKNI  . . . . . . . . . . . .	L Near	 0000005C _TEXT	
  IsP5 . . . . . . . . . . . . .	L Near	 00000063 _TEXT	
  NotPentium . . . . . . . . . .	L Near	 0000006A _TEXT	
  DoneCpu  . . . . . . . . . . .	L Near	 0000006F _TEXT	
  NotIntel . . . . . . . . . . .	L Near	 00000074 _TEXT	
  NoExtendedFeatures . . . . . .	L Near	 0000008F _TEXT	
  ChkAMD . . . . . . . . . . . .	L Near	 000000A1 _TEXT	
  ChkCyrix . . . . . . . . . . .	L Near	 000000B9 _TEXT	
  ChkIDT . . . . . . . . . . . .	L Near	 000000D5 _TEXT	
  CPUisIDT . . . . . . . . . . .	L Near	 000000F9 _TEXT	
  CPUisAMD . . . . . . . . . . .	L Near	 00000121 _TEXT	
  AmdHasK6MTRR . . . . . . . . .	L Near	 00000143 _TEXT	
  AmdMTRRchkDone . . . . . . . .	L Near	 00000146 _TEXT	
  CPUisCyrix . . . . . . . . . .	L Near	 00000169 _TEXT	
  UnknownVendor  . . . . . . . .	L Near	 00000191 _TEXT	
double_precision_asm . . . . . .	P Near	 000001B4 _TEXT	Length= 0000001C Public C
single_precision_asm . . . . . .	P Near	 0000019C _TEXT	Length= 00000017 Public C


Symbols:

                N a m e                 Type     Value    Attr

@CodeSize  . . . . . . . . . . .	Number	 00000000h   
@DataSize  . . . . . . . . . . .	Number	 00000000h   
@Interface . . . . . . . . . . .	Number	 00000001h   
@Model . . . . . . . . . . . . .	Number	 00000007h   
@code  . . . . . . . . . . . . .	Text   	 _TEXT
@data  . . . . . . . . . . . . .	Text   	 FLAT
@fardata?  . . . . . . . . . . .	Text   	 FLAT
@fardata . . . . . . . . . . . .	Text   	 FLAT
@stack . . . . . . . . . . . . .	Text   	 FLAT
CPUTypeP5  . . . . . . . . . . .	Number	 00000005h   
CPUTypeP6  . . . . . . . . . . .	Number	 00000006h   
CPUTypePrePent . . . . . . . . .	Number	 00000004h   
CPUTypeUnknown . . . . . . . . .	Number	 FFFFFFFFh   
GDBG_INFO_ON . . . . . . . . . .	Text   	 
GLIDE_ALT_TAB  . . . . . . . . .	Text   	 
GLIDE_DEBUG  . . . . . . . . . .	Text   	 
GLIDE_INIT_HWC . . . . . . . . .	Text   	 
GLIDE_PACKED_RGB . . . . . . . .	Text   	 0
GLIDE_TRI_CULLING  . . . . . . .	Text   	 1

	   0 Warnings
	   0 Errors
