/**
 * pentium.cpp : jni methods in nativepentium.dll
 * Must have previously generated the pentium.h file with
 * javah. Get a clean compile, then
 * javah.exe -jni -o pentium.h com.mindprod.pentium.Pentium
 * You must have
 * J:\Program Files\Java\jdk1.6.0_06\include\
 * and
 * J:\Program Files\Java\jdk1.6.0_06\include\win32
 * in the include list e.g.
 * in Tools | options  | Projects and Solutions | VC++ directories | include files
 * or
 * in tools | options | directories | include
 * For project as a whole:
 * In project | settings | general | no MFC
 * In project | settings | link | output filename | should end in DLL
 * copyright (c) 2004-2008 Roedy Green Canadian Mind Products
 */

// JNI prototypes generated by javah
#include "pentium.h"

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuIdVendor
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_mindprod_pentium_Pentium_cpuIdVendor
   (JNIEnv * env, jclass theClass )
   {
   jint vendorId[4];
   _asm
   {
      mov   eax,0
         cpuid
         mov   vendorId,ebx        ; GenuineIntel AuthenticAMD
         mov   vendorId+4,edx      ; goofy order eax, edx, ecx.
         mov   vendorId+8,ecx
         mov   vendorId+12,0       ; terminating null
   }
   return  env->NewStringUTF( (char *)vendorId );
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuIdBrand
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_mindprod_pentium_Pentium_cpuIdBrand
   (JNIEnv * env, jclass theClass )
   {
   jint brand[12+1];
   _asm
   {
         mov   eax,0x80000000
         cpuid

         cmp   eax,0x80000004    ; max supported
         jae   hasBrand
         mov   brand,0
         jmp   done

      hasbrand:
         mov   eax,0x80000002
         cpuid
         mov   brand,eax
         mov   brand+4,ebx
         mov   brand+8,ecx
         mov   brand+12,edx

         mov   eax,0x80000003
         cpuid
         mov   brand+16,eax
         mov   brand+20,ebx
         mov   brand+24,ecx
         mov   brand+28,edx

         mov   eax,0x80000004
         cpuid
         mov   brand+32,eax
         mov   brand+36,ebx
         mov   brand+40,ecx
         mov   brand+44,edx

         mov   brand+48,0       ; terminating null
         done:
   }
   return  env->NewStringUTF( (char *)brand );
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuIdStep
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdStep
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         and   eax,0xf              ; in low order 4 bits
   }
   // return with value in eax
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuIdModel
 * Signature: ()I
 */

JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdModel
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         shr   eax,4             ; in bits 7:4 bits
         and   eax,0xf
   }
   // return with value in eax
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuIdFamily
 * Signature: ()I
 */

JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdFamily

   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         shr   eax,8             ; in low order bits 11:8 bits
         and   eax,0xf
   }
   // return with value in eax
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    cpuSerNo
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_com_mindprod_pentium_Pentium_cpuSerNo
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         sub   eax,eax     ; check that level 3 CPUID is supported
         cpuid             ; result in ecx:edx
         cmp   eax,3
         jge   hasSerno
         mov   eax,0       ; not Pentium with serial number, return 0.
         mov   edx,0
         jmp   done
         hasSerno:
         mov   eax,1
         cpuid
         mov   eax,ecx
         done:
   }
   // return with result in edx:eax
   }

/*
 * Class:     com_mindprod_pentium_Pentium
 * Method:    rdtsc
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_com_mindprod_pentium_Pentium_rdtsc
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
      rdtsc           ; result in edx:eax
   }
   // return with result in edx:eax
   }

// not class, so no final }