added CPUID code from rbench and get_cpl to be used by the
[dosdemo] / src / cpuid_s.asm
diff --git a/src/cpuid_s.asm b/src/cpuid_s.asm
new file mode 100644 (file)
index 0000000..b7b9626
--- /dev/null
@@ -0,0 +1,131 @@
+       section .text
+; foo_ are watcom functions, _foo are djgpp functions
+
+F_ID equ 0x200000
+
+       global read_cpuid
+       global _read_cpuid
+       global read_cpuid_
+read_cpuid_:
+       push eax
+       call check_cpuid
+       pop eax
+       jnc read_cpuid_nocheck
+       mov eax, -1
+       ret
+
+_read_cpuid:
+read_cpuid:
+       call check_cpuid
+       mov eax, [esp + 4]
+       jnc read_cpuid_nocheck
+       mov eax, -1
+       ret
+
+       ; determine if cpuid is available. avail: cf=0, not avail: cf=1
+check_cpuid:
+       pushf
+       pop eax
+       mov edx, eax    ; keep a copy of the original eflags in edx
+       xor eax, F_ID
+       push eax
+       popf
+       pushf
+       pop eax
+       clc
+       cmp eax, edx
+       jnz .noerr
+       stc
+.noerr:        ret
+
+       ; enter with the cpuid_info structure pointer in eax
+read_cpuid_nocheck:
+       push ebp
+       mov ebp, esp
+       push ebx
+       push edi
+       push esi
+       push eax        ; save the original struct pointer
+       sub esp, 8
+       mov edi, eax    ; struct pointer -> edi
+
+       ; clear struct
+       cld
+       push edi
+       mov ecx, (32+48)/4
+       xor eax, eax
+       rep stosd
+       pop edi
+
+       xor eax, eax
+       mov [esp], eax  ; current index
+       cpuid
+
+       mov [edi], eax          ; maxidx
+       ; clamp to the size of our cpuid_info structure
+       cmp eax, 1
+       jbe .skipclamp
+       mov eax, 1
+.skipclamp:
+       mov [esp + 4], eax      ; maximum index
+
+       mov [edi + 4], ebx      ; vendor name
+       mov [edi + 8], edx
+       mov [edi + 12], ecx
+       add edi, 16
+
+.loop: mov eax, [esp]
+       inc eax
+       cmp eax, [esp + 4]
+       ja .loopend
+       mov [esp], eax
+       cpuid
+       mov [edi], eax
+       mov [edi + 4], ebx
+       mov [edi + 8], edx
+       mov [edi + 12], ecx
+       add edi, 16
+       jmp .loop
+.loopend:
+       ; try to retrieve the brand string (avail on P4 or newer)
+       mov eax, 80000000h
+       cpuid
+       test eax, 80000000h
+       jz .done        ; no extended cpuid functions
+       cmp eax, 80000004h
+       jb .done        ; no brand string available
+
+       ; brand string available
+       mov esi, esp            ; save esp to esi
+       mov esp, [esp + 8]      ; esp <- original struct pointer
+       add esp, 32+48          ; offset to end of brandstr
+       mov eax, 80000004h
+       cpuid
+       push edx
+       push ecx
+       push ebx
+       push eax
+       mov eax, 80000003h
+       cpuid
+       push edx
+       push ecx
+       push ebx
+       push eax
+       mov eax, 80000002h
+       cpuid
+       push edx
+       push ecx
+       push ebx
+       push eax
+       mov esp, esi    ; done restore esp
+
+.done: add esp, 8
+       pop eax
+       pop esi
+       pop edi
+       pop ebx
+       pop ebp
+       xor eax, eax
+       ret
+       
+; vi:ft=nasm: