.586
.model flat,C
option casemap:none

.code

include VOCBUFP.INC

ifdef static
    if PRO
	GetSIMD textequ <GetSIMD_pro>
	MXinit textequ <MXinitPro>
	MXprocess textequ <MXprocessPro>
	VocInit textequ <MXinit_pro>
	VocProcess_fpu textequ <MXprocess_fpu_pro>
	VocProcess_k3d textequ <MXprocess_k3d_pro>
	VocProcess_sse textequ <MXprocess_sse_pro>
    endif
endif

extern VocInit: proc
extern VocProcess_fpu: proc
extern VocProcess_k3d: proc
extern VocProcess_sse: proc


ifndef static

DLLEntry proc	stdcall hInstDLL:DWORD, reason:DWORD, reserved1:DWORD
DLLEntry endp

	mov	eax,1
	ret	3*dword
else
	DLLEntry textequ <>
endif


MXinit proc

	call	GetSIMD

	push	ebx
	mov	ebx,[esp+2*dword]
	mov	[ebx].VB.fpu,0
	.if eax==001b || eax==011b || eax==101b	
		mov	[ebx].VB.fpu,1
	.elseif eax & 010b
		mov	[ebx].VB.fpu,2
	.endif
	pop	ebx
	jmp	VocInit

MXinit endp


MXprocess proc

	mov	eax,[esp+dword]
	mov	al,[eax].VB.fpu

	cmp	al,1
	je	VocProcess_k3d

	cmp	al,2
	je	VocProcess_sse

	jmp	VocProcess_fpu

MXprocess endp


; GetSIMD - returns information about CPU SIMD capabilities
; Result: bit 0 - 3DNow! technology supported
;	  bit 1 - Streaming SIMD Extensions supported
;	  bit 2 - Processor family is 7 or above. This bit can be used to
; 		  choose between SSE and 3DNow! when both are present
;
GetSIMD	proc	uses ebp ebx ecx edx

	xor	ebp,ebp
	pushfd
	pop	eax
	mov	ebx,eax
	xor	eax,00200000h
	push	eax
	popfd
	pushfd
	pop	eax

	.if eax != ebx
		mov	eax,1
		cpuid
		and	ah,0Fh
		add	ah,-7
		adc	ebp,3			; Set bit 2 if Processor Family >= 7
		and	ebp,4
		shr	edx,24
		and	edx,2
		or	ebp,edx			; Set bit 1 if SSE supported
		mov	eax,80000000h
		cpuid
		.if eax > 80000000h
			mov	eax,80000001h
			cpuid
			shr	edx,31
			or	ebp,edx		; Set bit 0 if 3DNow! supported
		.endif
	.endif

	mov	eax,ebp
	ret

GetSIMD endp

end DLLEntry
