cpuid.asm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. ;/***********************************************\
  2. ;??? cpuid.asm
  3. ; checks for cpuid
  4. ; if an id is not found, the program assumes a x86
  5. ;\***********************************************/
  6. ; parts taken from intel's AP-485
  7. ;put checks for cmov and mmx support ????
  8. .486
  9. .MODEL flat, SYSCALL, os_dos
  10. .CODE
  11. IDEAL
  12. NAME x86cpuid
  13. MASM
  14. PUBLIC getCPUID_
  15. PUBLIC _getCPUID
  16. INCLUDE proc.ash
  17. EXTRN c cpuFeatures:DWORD
  18. _486 EQU 4h
  19. PENT EQU 50h
  20. PENTMMX EQU 54h
  21. PENTPRO EQU 61h
  22. PENTII EQU 63h
  23. AMD_K63D EQU 58h
  24. AMD_K6 EQU 56h
  25. AMD_K5 EQU 50h ; K5 has models 0 - 6
  26. _6X86 EQU 52h
  27. _6X86MX EQU 60h
  28. .DATA
  29. _vendor_id db "------------"
  30. intel_id db "GenuineIntel"
  31. amd_id db "AuthenticAMD"
  32. cyrix_id db "CyrixInstead"
  33. getCPUID_:
  34. _getCPUID:
  35. push esi ;safety sh*&
  36. push edi
  37. push ebp
  38. push ebx
  39. push ecx
  40. push edx
  41. ;------------------------------------------------
  42. ; Intel486 processor check
  43. ; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
  44. ; which indicates the presence of a processor with the CPUID
  45. ; instruction.
  46. ;------------------------------------------------
  47. .486
  48. check_80486:
  49. pushfd ; push original EFLAGS
  50. pop eax ; get original EFLAGS
  51. mov ebp,X86 ; rv
  52. mov ecx, eax ; save original EFLAGS
  53. xor eax, 200000h ; flip ID bit in EFLAGS
  54. push eax ; save new EFLAGS value on stack
  55. popfd ; replace current EFLAGS value
  56. pushfd ; get new EFLAGS
  57. pop eax ; store new EFLAGS in EAX
  58. xor eax, ecx ; can not toggle ID bit,
  59. je end_cpu_type486 ; processor=80486
  60. ;------------------------------------------------
  61. ; Execute CPUID instruction to not determine vendor, family,
  62. ; model, stepping and features. For the purpose of this
  63. ; code, only the initial set of CPUID information is saved.
  64. ;------------------------------------------------
  65. ; push ebx ; save registers
  66. ; push esi
  67. ; push edi
  68. ; push edx
  69. ; push ecx
  70. ; mov ebp,X86 ; rv
  71. mov eax, 0 ; set up for CPUID instruction
  72. CPU_ID ; get and save vendor ID
  73. mov DWORD PTR _vendor_id, ebx
  74. mov DWORD PTR _vendor_id[+4], edx
  75. mov DWORD PTR _vendor_id[+8], ecx
  76. cmp DWORD PTR intel_id, ebx
  77. jne IsProc_AMD
  78. cmp DWORD PTR intel_id[+4], edx
  79. jne end_cpuid_type
  80. cmp DWORD PTR intel_id[+8], ecx
  81. jne end_cpuid_type ; if not equal, not an Intel processor
  82. cmp eax, 1 ; make sure 1 is valid input for CPUID
  83. jl end_cpuid_type ; if not, jump to end
  84. mov eax, 1
  85. CPU_ID ; get family/model/stepping/features
  86. shr eax, 4 ; isolate family and model
  87. mov ebp,PII ; assume PII
  88. and eax,0ffh ;mask out type and reserved
  89. nop
  90. cmp eax,PENTII
  91. jge end_cpuid_type
  92. mov ebp,PPRO
  93. cmp eax,PENTPRO
  94. je end_cpuid_type
  95. mov ebp,PMMX
  96. cmp eax,PENTMMX
  97. je end_cpuid_type
  98. mov ebp,X86
  99. ; cmp eax,PENT
  100. ; jge end_cpuid_type
  101. end_cpuid_type:
  102. mov eax,ebp
  103. mov [cpuFeatures],edx
  104. pop edx ;safety sh*&
  105. pop ecx
  106. pop ebx
  107. pop ebp
  108. pop edi
  109. pop esi
  110. ret
  111. end_cpu_type486:
  112. mov eax,ebp
  113. pop edx ;safety sh*&
  114. pop ecx
  115. pop ebx
  116. pop ebp
  117. pop edi
  118. pop esi
  119. ret
  120. ;------------------------------------------------
  121. IsProc_AMD:
  122. cmp DWORD PTR amd_id, ebx
  123. jne IsProc_CYRIX
  124. cmp DWORD PTR amd_id[+4], edx
  125. jne end_cpuid_type
  126. cmp DWORD PTR amd_id[+8], ecx
  127. jne end_cpuid_type ; if not equal, not an AMD processor
  128. cmp eax, 1 ; make sure 1 is valid input for CPUID
  129. jl end_cpuid_type ; if not, jump to end
  130. mov eax, 1
  131. CPU_ID ; get family/model/stepping/features
  132. shr eax, 4 ; isolate family and model
  133. mov ebp,AMDK63D
  134. and eax,0ffh ;mask out type and reserved
  135. nop
  136. cmp eax,AMD_K63D
  137. jge end_cpuid_type
  138. mov ebp,AMDK6
  139. nop
  140. cmp eax,AMD_K6
  141. jge end_cpuid_type
  142. mov ebp,X86
  143. nop
  144. cmp eax,AMD_K5
  145. jge end_cpuid_type
  146. mov ebp,X86
  147. jmp end_cpuid_type
  148. ;------------------------------------------------
  149. IsProc_CYRIX:
  150. cmp DWORD PTR cyrix_id, ebx
  151. jne end_cpuid_type
  152. cmp DWORD PTR cyrix_id[+4], edx
  153. jne end_cpuid_type
  154. cmp DWORD PTR cyrix_id[+8], ecx
  155. jne end_cpuid_type ; if not equal, not an CYRIX processor
  156. cmp eax, 1 ; make sure 1 is valid input for CPUID
  157. jl end_cpuid_type ; if not, jump to end
  158. mov eax, 1
  159. CPU_ID ; get family/model/stepping/features
  160. shr eax, 4 ; isolate family and model
  161. mov ebp,C6X86MX
  162. and eax,0ffh ;mask out type and reserved
  163. nop
  164. cmp eax,_6X86MX
  165. je end_cpuid_type
  166. mov ebp,X86
  167. jmp end_cpuid_type
  168. ;************************************************
  169. END