Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

softdrv.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  softdrv.c                                                                           */
00003 /*                                                                                      */
00004 /*  Author:       John Pollard, Ken Baird                                               */
00005 /*  Description:  Init, mode, and cpu identification code                               */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 #include <Windows.h>
00023 #include <Assert.h>
00024 #include <stdio.h>
00025 #include <mmsystem.h>
00026 #include <math.h>
00027 
00028 #include "SoftDrv.h"
00029 #include "System.h"
00030 #include "DCommon.h"
00031 #include "Sal.h"
00032 
00033 #include "Register.h"
00034 #include "Scene.h"
00035 #include "Render.h"
00036 #include "dmodes.h"
00037 
00038 static  DRV_CacheInfo   CacheInfo;
00039 static  VidEnumInfo             VidInfo[16];
00040 static  VidEnumInfo             *VInfo;
00041 
00042 extern  VidModeList             *cmode;
00043 extern  DRV_Window              ClientWindow    ={ 0 };
00044 extern  CPUInfo                 ProcessorInfo   ={ 0 };
00045 extern  int                             NumDevices              =0;
00046 
00047 S32                                     LastError;
00048 char                            LastErrorStr[200];
00049 
00050 BOOL DRIVERCC EnumSubDrivers(DRV_ENUM_DRV_CB *Cb, void *Context);
00051 BOOL DRIVERCC EnumModes(S32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context);
00052 BOOL DRIVERCC SetDrvRenderState(S32 State, U32 Flag);
00053 BOOL DRIVERCC GetDrvRenderState(S32 State, U32 *Flag);
00054 BOOL DRIVERCC EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context);
00055 
00056 typedef unsigned __int64 QWORD;
00057 //#define RDTSC _asm _emit 0fh _asm _emit 031h
00058 #define CPUID _asm _emit 0fh _asm _emit 0a2h
00059 
00060 BOOL DRIVERCC   ScreenShot(const char *Name);
00061 static U32              GetCPUIDEAX(U32 funcNum);
00062 static U32              GetCPUIDEDX(U32 funcNum);
00063 static U32              GetCPUIDString(U32 funcNum, char *szId);
00064 static void             GetCPUIDStringAMD(U32 funcNum, char *szId);
00065 //static QWORD  GetRDTSC(void);
00066 //static U32            GetRDTSCOverHead(void);
00067 //static U32            GetProcessorSpeed(void);
00068 static void             GetCPUInfo(void);
00069 
00070 extern  __int64 QZBufferPrec    =0;
00071 extern  __int64 QFixedScale             =0;
00072 extern  __int64 QFixedScale16   =0;
00073 extern  __int64 Q128                    =0;
00074 extern  double  Magic, MipMagic, MipMagic2;
00075 
00076 void    SetupMiscConstants(void)
00077 {
00078         *(((geFloat *)((&QZBufferPrec)))+1)     =-ZBUFFER_PREC;
00079         *((geFloat *)(&QZBufferPrec))                   =-ZBUFFER_PREC;
00080 
00081         *(((geFloat *)((&QFixedScale16)))+1)    =4096.0f;
00082         *((geFloat *)(&QFixedScale16))          =4096.0f;
00083 
00084         *(((geFloat *)((&QFixedScale)))+1)      =65536.0f;
00085         *((geFloat *)(&QFixedScale))                    =65536.0f;
00086 
00087         *((geFloat *)&Q128)                                     =128.0f;
00088         *(((geFloat *)((&Q128)))+1)                     =128.0f;
00089 
00090         Magic           =ldexp(1.5, 60);
00091         MipMagic        =ldexp(1.5, 52-16);
00092         MipMagic2       =ldexp(1.5, 52-12);
00093 }
00094 
00095 
00096 //big chunk of duplicated code to resetup stuff that
00097 //gets nuked when the driver is freed
00098 BOOL DRIVERCC DrvInit(DRV_DriverHook *Hook)
00099 {
00100         RECT    window_rect;    //for resetting (thanks mike!)
00101         BOOL    result;
00102 
00103         VInfo           =&VidInfo[Hook->Driver];
00104         VInfo->bpp      =16;
00105 
00106         GetCPUInfo();
00107 
00108         window_rect.left = -1;
00109         window_rect.top = -1;
00110         window_rect.right = -1;
00111         window_rect.bottom = -1;
00112                 
00113         SetLastError( ERROR_SUCCESS );
00114 
00115         DoEnumeration(VInfo);
00116         DoModeEnumeration(VInfo);
00117 
00118         //check for windowed mode
00119         if(Hook->Mode==VInfo->NumVidModes)
00120         {
00121                 bWindowed       =TRUE;
00122 
00123                 if (!SAL_startup(FALSE))
00124                 {
00125                         SetLastDrvError(DRV_ERROR_INIT_ERROR, "SOFT_DrvInit:  Could not initialize SAL.");
00126                         DumpErrorLogToFile("softdrv.log");
00127                         return FALSE;
00128                 }
00129 
00130                 result = GetClientRect(Hook->hWnd, &window_rect);
00131                 if( !result || window_rect.right == -1 || window_rect.bottom == -1 )
00132                 {
00133                         // This means you probably passed in an illegal hwnd.
00134                         int err = GetLastError();
00135                         assert( result );
00136                         DumpErrorLogToFile("softdrv.log");
00137                         return FALSE;
00138                 }
00139 
00140                 SAL_set_main_window(Hook->hWnd);
00141                 ClientWindow.Width  = (window_rect.right  - window_rect.left);
00142                 ClientWindow.Height = (window_rect.bottom - window_rect.top);
00143 
00144                 assert( ClientWindow.Width > 0 );
00145                 assert( ClientWindow.Height > 0 );
00146 
00147                 if(ProcessorInfo.Has3DNow)
00148                 {
00149                         if(!SAL_set_display_mode(ClientWindow.Width,
00150                                                                         ClientWindow.Height,
00151                                                                         32,
00152                                                                         SAL_WINDOW,
00153                                                                         TRUE))
00154                         {
00155                                 SetLastDrvError(DRV_ERROR_INIT_ERROR, "SOFT_DrvInit:  Could not set display mode.");
00156                                 DumpErrorLogToFile("softdrv.log");
00157                                 return  FALSE;
00158                         }
00159                 }
00160                 else
00161                 {
00162                         if(!SAL_set_display_mode(ClientWindow.Width,
00163                                                                         ClientWindow.Height,
00164                                                                         16,
00165                                                                         SAL_WINDOW,
00166                                                                         TRUE))
00167                         {
00168                                 SetLastDrvError(DRV_ERROR_INIT_ERROR, "SOFT_DrvInit:  Could not set display mode.");
00169                                 DumpErrorLogToFile("softdrv.log");
00170                                 return  FALSE;
00171                         }
00172                 }
00173         }
00174         else
00175         {
00176                 if(!DoDDrawInit(Hook->hWnd, VInfo))
00177                 {
00178                         DumpErrorLogToFile("softdrv.log");
00179                         return  FALSE;
00180                 }
00181                 ClientWindow.Width = Hook->Width;
00182                 ClientWindow.Height = Hook->Height;
00183                 if(VInfo->VidModes[Hook->Mode].flags & STRETCHMODE)
00184                 {
00185                         if(VInfo->VidModes[Hook->Mode].width > 640)
00186                         {
00187 //                              ClientWindow.Width      =640;
00188 //                              ClientWindow.Height     =(((geFloat)ClientWindow.Width)/(geFloat)Hook->Width)*(geFloat)Hook->Height;
00189                         }
00190                 }
00191 
00192                 if(!SetDDrawMode(Hook->Mode, VInfo))
00193                 {
00194                         return  FALSE;
00195                 }
00196                 ClientWindow.PixelPitch =VInfo->VidModes[Hook->Mode].pitch>>2;
00197                 cmode   =&VInfo->VidModes[Hook->Mode];
00198         }
00199 
00200         if(!SysInit())
00201         {       // LastDriverError should be set in here...
00202                 DumpErrorLogToFile("softdrv.log");
00203                 return  FALSE;          // so just return false, and assume it's set
00204         }
00205 
00206         SetLastDrvError(DRV_ERROR_NONE, "SOFT_DrvInit:  No error.");
00207         SetupMiscConstants();
00208 
00209         return  TRUE;
00210 }
00211 
00212 BOOL DRIVERCC DrvShutdown(void)
00213 {
00214         SysShutdown();
00215 
00216         if(bWindowed)
00217         {
00218                 SAL_shutdown();
00219         }
00220         else
00221         {
00222                 FreeDDraw(VInfo);
00223         }
00224 
00225         DumpErrorLogToFile("softdrv.log");
00226 
00227         return  TRUE;
00228 }
00229 
00230 void DRIVERCC ErrorBox(char *Str)
00231 {
00232         DrvShutdown();
00233         DumpErrorLogToFile("softdrv.log");
00234 }
00235 
00236 BOOL DRIVERCC SetGamma(geFloat Gamma)
00237 {
00238         return TRUE;
00239 }
00240 
00241 BOOL DRIVERCC GetGamma(geFloat *Gamma)
00242 {
00243         assert(Gamma);
00244 
00245         *Gamma = 1.0f;
00246 
00247         return TRUE;
00248 }
00249 
00250 geBoolean       DRIVERCC DrvUpdateWindow(void)
00251 {
00252         return  GE_TRUE;
00253 }
00254 
00255 geBoolean DRIVERCC Drv_SetFogEnable(geBoolean Enable, geFloat r, geFloat g, geFloat b, geFloat Start, geFloat End)
00256 {
00257         Enable,r,g,b,Start,End;
00258         return GE_FALSE;
00259 }
00260 
00261 DRV_Driver SOFTDRV = 
00262 {
00263         "Software driver. v"DRV_VMAJS"."DRV_VMINS". Copyright 1999, WildTangent Inc.; All Rights Reserved.",
00264         DRV_VERSION_MAJOR,
00265         DRV_VERSION_MINOR,
00266 
00267         DRV_ERROR_NONE,
00268         NULL,
00269         
00270         EnumSubDrivers,
00271         EnumModes,
00272         EnumPixelFormats,
00273 
00274         DrvInit,
00275         DrvShutdown,
00276         DrvResetAll,
00277         DrvUpdateWindow,
00278         DrvSetActive,
00279 
00280         CreateTexture,
00281         DestroyTexture,
00282 
00283         LockTextureHandle,
00284         UnLockTextureHandle,
00285 
00286         SetPalette,
00287         GetPalette,
00288         SetAlpha,
00289         GetAlpha,
00290 
00291         THandle_GetInfo,
00292 
00293         BeginScene,
00294         EndScene,
00295         BeginWorld,
00296         EndWorld,
00297         BeginMeshes,
00298         EndMeshes,
00299         BeginModels,
00300         EndModels,
00301 
00302         RenderGouraudPoly,
00303         RenderWorldPoly,
00304         RenderMiscTexturePoly,
00305 
00306         DrawDecal,
00307 
00308         0,0,0,
00309         
00310         &CacheInfo,
00311 
00312         ScreenShot,
00313 
00314         SetGamma,
00315         GetGamma,
00316 
00317         Drv_SetFogEnable,
00318 
00319         NULL,
00320         NULL,                                                           // Init to NULL, engine SHOULD set this (SetupLightmap)
00321         NULL
00322 };
00323 
00324 DRV_EngineSettings      EngineSettings;
00325 
00326 DllExport BOOL DriverHook(DRV_Driver **Driver)
00327 {
00328         EngineSettings.CanSupportFlags = (DRV_SUPPORT_ALPHA|DRV_SUPPORT_COLORKEY);
00329         EngineSettings.PreferenceFlags = (DRV_PREFERENCE_NO_MIRRORS | DRV_PREFERENCE_DRAW_WALPHA_IN_BSP);
00330 
00331         SOFTDRV.EngineSettings = &EngineSettings;
00332 
00333         *Driver = &SOFTDRV;
00334 
00335         // Make sure the error string ptr is not null, or invalid!!!
00336         SOFTDRV.LastErrorStr = LastErrorStr;
00337 
00338         SetLastDrvError(DRV_ERROR_NONE, "SOFT_DRV:  No error.");
00339 
00340         return TRUE;
00341 }
00342 
00343 void SetLastDrvError(S32 Error, char *ErrorStr)
00344 {
00345         LastError = Error;
00346         
00347         if (ErrorStr)
00348         {
00349                 strcpy(LastErrorStr, ErrorStr);
00350         }
00351         else
00352                 LastErrorStr[0] = 0;
00353 
00354         SOFTDRV.LastErrorStr = LastErrorStr;
00355         SOFTDRV.LastError = LastError;
00356 }
00357 
00358 BOOL DRIVERCC ScreenShot(const char *Name)
00359 {
00360         return FALSE;
00361 }
00362 
00363 BOOL DRIVERCC EnumSubDrivers(DRV_ENUM_DRV_CB *Cb, void *Context)
00364 {
00365         int             i;
00366         char    szTemp[256];
00367 
00368         NumDevices      =0;
00369 
00370         GetCPUInfo();
00371         if (ProcessorInfo.Has3DNow)
00372         {
00373                 DoEnumeration(VidInfo);
00374                 for(i=0;i < NumDevices;i++)
00375                 {
00376                         sprintf(szTemp, "Software AMD 3DNow!(tm) v"DRV_VMAJS"."DRV_VMINS"."); //, VidInfo[i].DeviceInfo.szDescription);
00377                         if(!Cb(i, szTemp, Context))
00378                         {
00379                                 return  TRUE;
00380                         }
00381                 }
00382                 if(!NumDevices)
00383                 {
00384                         sprintf(szTemp, "Software AMD 3DNow!(tm) v"DRV_VMAJS"."DRV_VMINS".");
00385                         if(!Cb(i, szTemp, Context))
00386                         {
00387                                 return  TRUE;
00388                         }
00389                 }
00390         }
00391         return  TRUE;
00392 }
00393 
00394 BOOL DRIVERCC EnumModes(S32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context)
00395 {
00396         int             i;
00397         RECT    window_rect;    //for resetting (thanks mike!)
00398         char    szTemp[256];
00399 
00400         window_rect.left = -1;
00401         window_rect.top = -1;
00402         window_rect.right = -1;
00403         window_rect.bottom = -1;
00404                 
00405         SetLastError( ERROR_SUCCESS );
00406         VInfo           =&VidInfo[Driver];
00407         VInfo->bpp      =16;
00408 
00409         GetCPUInfo();
00410         if (!ProcessorInfo.Has3DNow)
00411                 return TRUE;
00412                 
00413         if(NumDevices)
00414         {
00415                 DoModeEnumeration(VInfo);
00416         }
00417 
00418         for(i=0;i < VInfo->NumVidModes;i++)
00419         {
00420                 if(VInfo->VidModes[i].flags & MODEXMODE)
00421                 {
00422                         sprintf(szTemp, "%dx%dx%d ModeX", VInfo->VidModes[i].width, VInfo->VidModes[i].height, VInfo->VidModes[i].bpp);
00423                         if(ProcessorInfo.Has3DNow)
00424                         {
00425                                 //strcat(szTemp, " 3DNow!");
00426                         }
00427                         Cb(i, szTemp, VInfo->VidModes[i].width, VInfo->VidModes[i].height, Context);
00428                 }
00429                 else if(VInfo->VidModes[i].flags & STRETCHMODE)
00430                 {
00431                         sprintf(szTemp, "%dx%dx%d Stretched", VInfo->VidModes[i].width, VInfo->VidModes[i].height, VInfo->VidModes[i].bpp);
00432                         if(ProcessorInfo.Has3DNow)
00433                         {
00434                                 //strcat(szTemp, " 3DNow!");
00435                         }
00436                         Cb(i, szTemp, VInfo->VidModes[i].width, VInfo->VidModes[i].height, Context);
00437                 }
00438                 else
00439                 {
00440                         sprintf(szTemp, "%dx%dx%d", VInfo->VidModes[i].width, VInfo->VidModes[i].height, VInfo->VidModes[i].bpp);
00441                         if(ProcessorInfo.Has3DNow)
00442                         {
00443                                 //strcat(szTemp, " 3DNow!");
00444                         }
00445                         Cb(i, szTemp, VInfo->VidModes[i].width, VInfo->VidModes[i].height, Context);
00446                 }
00447         }
00448         Cb(i, "Window Mode", -1, -1, Context);
00449 
00450         SetLastError( ERROR_SUCCESS );
00451 
00452         return TRUE;
00453 }
00454 
00455 geBoolean DRIVERCC EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context)
00456 {
00457         geRDriver_PixelFormat   Pixie;
00458 
00459         if(!cmode && !bWindowed)
00460         {
00461                 //no mode set 
00462                 return  GE_FALSE;
00463         }
00464         else
00465         {
00466                 if(ProcessorInfo.Has3DNow)
00467                 {
00468                         Pixie.PixelFormat       =GE_PIXELFORMAT_8BIT;
00469                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP;
00470                         if(!Cb(&Pixie, Context))
00471                         {
00472                                 return  GE_TRUE;
00473                         }
00474                         Pixie.Flags                     =RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY;
00475                         if(!Cb(&Pixie, Context))
00476                         {
00477                                 return  GE_TRUE;
00478                         }
00479                         Pixie.Flags                     =RDRIVER_PF_3D;
00480                         if(!Cb(&Pixie, Context))
00481                         {
00482                                 return  GE_TRUE;
00483                         }
00484                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_ALPHA;
00485                         if(!Cb(&Pixie, Context))
00486                         {
00487                                 return  GE_TRUE;
00488                         }
00489                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_HAS_ALPHA;
00490                         if(!Cb(&Pixie, Context))
00491                         {
00492                                 return  GE_TRUE;
00493                         }
00494 
00495                         Pixie.PixelFormat       =GE_PIXELFORMAT_32BIT_XRGB;
00496                         Pixie.Flags                     =RDRIVER_PF_PALETTE;
00497                         if(!Cb(&Pixie, Context))
00498                         {
00499                                 return  GE_TRUE;
00500                         }
00501 
00502                         Pixie.PixelFormat       =GE_PIXELFORMAT_32BIT_ARGB;
00503                         Pixie.Flags                     =RDRIVER_PF_PALETTE;
00504                         if(!Cb(&Pixie, Context))
00505                         {
00506                                 return  GE_TRUE;
00507                         }
00508 
00509                 }
00510                 else
00511                 {
00512                         if(ClientWindow.G_mask == 0x3e0)        //555
00513                         {
00514                                 Pixie.PixelFormat       =GE_PIXELFORMAT_16BIT_555_RGB;
00515                         }
00516                         else
00517                         {
00518                                 Pixie.PixelFormat       =GE_PIXELFORMAT_16BIT_565_RGB;
00519                         }
00520 
00521                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP;
00522                         if(!Cb(&Pixie, Context))
00523                         {
00524                                 return  GE_TRUE;
00525                         }
00526 
00527                         Pixie.Flags                     =RDRIVER_PF_3D;
00528                         if(!Cb(&Pixie, Context))
00529                         {
00530                                 return  GE_TRUE;
00531                         }
00532 
00533                         Pixie.Flags                     =RDRIVER_PF_2D;
00534                         if(!Cb(&Pixie, Context))
00535                         {
00536                                 return  GE_TRUE;
00537                         }
00538 
00539                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP | RDRIVER_PF_CAN_DO_COLORKEY;
00540                         if(!Cb(&Pixie, Context))
00541                         {
00542                                 return  GE_TRUE;
00543                         }
00544 
00545                         Pixie.Flags                     =RDRIVER_PF_3D | RDRIVER_PF_CAN_DO_COLORKEY;
00546                         if(!Cb(&Pixie, Context))
00547                         {
00548                                 return  GE_TRUE;
00549                         }
00550 
00551                         Pixie.Flags                     =RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY;
00552                         if(!Cb(&Pixie, Context))
00553                         {
00554                                 return  GE_TRUE;
00555                         }
00556                 }
00557 
00558                 Pixie.PixelFormat       =GE_PIXELFORMAT_24BIT_RGB;
00559                 Pixie.Flags                     =RDRIVER_PF_LIGHTMAP;
00560                 if(!Cb(&Pixie, Context))
00561                 {
00562                         return  GE_TRUE;
00563                 }
00564         }       
00565         return  TRUE;
00566 }
00567 
00568 BOOL DRIVERCC SetDrvRenderState(S32 State, U32 Flag)
00569 {
00570         return TRUE;
00571 }
00572 
00573 BOOL DRIVERCC GetDrvRenderState(S32 State, U32 *Flag)
00574 {
00575         *Flag = 0;
00576         return TRUE;
00577 }
00578 
00579 int Flag_CPUID = FALSE; 
00580 int Flag_RDTSC = FALSE;
00581 
00582 
00583 void Test_CPU_bits(void)
00584 {
00585         Flag_CPUID = FALSE;
00586         Flag_RDTSC = FALSE;
00587 _asm
00588     {
00589         pushad                    // (1) play nice and save everything
00590     pushfd                    // eax = ebx = extended flags
00591     pop     eax                              
00592     mov     ebx,eax
00593 
00594     xor     eax,200000h       // toggle bit 21
00595 
00596     push    eax               // extended flags = eax
00597         popfd
00598     xor     eax,ebx           // if bit 21 r/w then eax <> 0
00599 
00600     jz      done              // can't toggle id bit (21) no cpuid here
00601     mov     eax,1             // get standard features
00602     mov     Flag_CPUID,eax    // (and set cpuid flag to true)
00603 
00604         CPUID
00605     test    edx,10h           // is rdtsc available?
00606     jz      done
00607 
00608     mov     Flag_RDTSC,1
00609 done:
00610         popad                     // (1) restore everything
00611     }
00612 }
00613 
00614 
00615 
00616 
00617 static U32      GetCPUIDEAX(U32 funcNum)
00618 {
00619         U32     retval;
00620 
00621         Test_CPU_bits();
00622         if (Flag_CPUID)
00623                 {
00624                         __try
00625                         {
00626                                 _asm
00627                                 {
00628                                         mov     eax,funcNum
00629                                         CPUID
00630                                         mov     retval,eax
00631                                 }
00632                         }__except(EXCEPTION_EXECUTE_HANDLER)
00633                         {
00634                                 retval  =0;
00635                         }
00636                 }
00637         else
00638                 {
00639                         retval = 0;
00640                 }
00641 
00642         return  retval;
00643 }
00644 
00645 static U32      GetCPUIDEDX(U32 funcNum)
00646 {
00647         U32     retval;
00648 
00649         Test_CPU_bits();
00650         if (Flag_CPUID)
00651                 {
00652                         __try
00653                         {
00654                                 _asm
00655                                 {
00656                                         mov     eax,funcNum
00657                                         CPUID
00658                                         mov     retval,edx
00659                                 }
00660                         }__except(EXCEPTION_EXECUTE_HANDLER)
00661                         {
00662                                 retval  =0;
00663                         }
00664                 }
00665         else
00666                 {
00667                         retval = 0;
00668                 }
00669         
00670         return  retval;
00671 }
00672 
00673 static U32      GetCPUIDString(U32 funcNum, char *szId)
00674 {
00675         U32     retval;
00676 
00677         Test_CPU_bits();
00678         if (Flag_CPUID)
00679                 {
00680                         __try
00681                         {
00682                                 _asm
00683                                 {
00684                                         mov     eax,funcNum
00685                                         CPUID
00686                                         mov     retval,eax
00687                                         mov     eax,szId
00688                                         mov     dword ptr[eax],ebx
00689                                         mov     dword ptr[eax+4],edx
00690                                         mov     dword ptr[eax+8],ecx
00691                                 }
00692                         }__except(EXCEPTION_EXECUTE_HANDLER)
00693                         {
00694                                 retval  =0;
00695                         }
00696                 }
00697         else
00698                 {
00699                         retval = 0;
00700                 }
00701 
00702         return  retval;
00703 }
00704 
00705 static void     GetCPUIDStringAMD(U32 funcNum, char *szId)
00706 {
00707         U32     retval;
00708         
00709         Test_CPU_bits();
00710         if (Flag_CPUID)
00711                 {
00712                         __try
00713                                 {
00714                                         _asm
00715                                         {
00716                                                 mov eax,funcNum
00717                                                 CPUID
00718                                                 mov     retval,eax
00719                                                 mov     eax,szId
00720                                                 mov     dword ptr[eax+4],ebx
00721                                                 mov     dword ptr[eax+8],ecx
00722                                                 mov     ebx,retval
00723                                                 mov     dword ptr[eax+12],edx
00724                                                 mov     dword ptr[eax],ebx
00725                                         }
00726                                 }__except(EXCEPTION_EXECUTE_HANDLER)
00727                                 {
00728                                         retval  =0;
00729                                 }
00730                 }
00731         else
00732                 {
00733                         retval = 0;
00734                 }
00735 }
00736 
00737 // For out of order processors, the cpuid does serliaization
00738 // On all processors, additional overhead is added
00739 /*
00740 static QWORD    GetRDTSC(void)
00741 {
00742         QWORD   clock;
00743 
00744         _asm
00745         {
00746                 push    ebx
00747                 push    ecx
00748                 xor             eax,eax
00749                 CPUID
00750                 RDTSC
00751                 mov             dword ptr clock,eax
00752                 mov             dword ptr clock+4,edx
00753                 xor             eax,eax
00754                 CPUID
00755                 pop             ecx
00756                 pop             ebx
00757         }
00758         return  clock;
00759 }
00760 */
00761 
00762 /*
00763 static U32      GetRDTSCOverHead(void)
00764 {
00765         U32             elap, MinOverhead       =0xffffff;
00766         QWORD   start;
00767         int             x;
00768 
00769         for(x=0;x < 50;x++)
00770         {
00771                 start           =GetRDTSC();
00772                 elap            =(U32)(GetRDTSC() - start);
00773                 MinOverhead =min(MinOverhead, elap);
00774         }
00775         return  MinOverhead;
00776 }
00777 */
00778 
00779 /*
00780 static U32      GetProcessorSpeed(void)
00781 {
00782         QWORD   StartClock, ElapClock;
00783         U32             StartTime, RetVal, times        =0;
00784         
00785         // try to get rid of the variability
00786         StartClock      =GetRDTSC();
00787         StartTime       =timeGetTime();
00788 
00789         // this loop should take 1 sec +- 1 ms
00790         while(timeGetTime() < StartTime + 250);
00791 
00792         ElapClock       =GetRDTSC() - StartClock + 500000;
00793         
00794         // try to get rid of the variability
00795         StartClock      =GetRDTSC();
00796         StartTime       =timeGetTime();
00797 
00798         // this loop should take 1 sec +- 1 ms
00799         while(timeGetTime() < StartTime + 1000);
00800 
00801         ElapClock       =GetRDTSC() - StartClock + 500000;
00802         RetVal          =(U32)(ElapClock/1000000);
00803         return          RetVal;
00804 }
00805 */
00806 
00807 static  char    buffer[32768];          //this is ... cautious
00808 static  char    buf3[4096];
00809 
00810 void ErrorPrintf(char *text, ...)
00811 {
00812         va_list argptr;
00813 
00814         va_start(argptr,text);
00815         vsprintf(buf3, text,argptr);
00816         va_end(argptr);
00817 
00818         strcat(buffer, buf3);
00819 }
00820 
00821 void DumpErrorLogToFile(char *fname)
00822 {
00823         FILE            *f;
00824         SYSTEMTIME      Time;
00825 
00826         f       =fopen(fname, "a+t");
00827 
00828         if(f)
00829         {
00830                 GetSystemTime(&Time);
00831 
00832                 fprintf(f,"=================================================================\n");
00833                 fprintf(f,"Time: %2i:%2i:%2i\n", Time.wHour, Time.wMinute, Time.wSecond);
00834                 fprintf(f,"Date: %2i-%2i-%4i\n", Time.wMonth, Time.wDay, Time.wYear);
00835 
00836                 fwrite(buffer, 1, strlen(buffer), f);
00837                 fclose(f);
00838         }
00839 }
00840 
00841 static void     GetCPUInfo(void)
00842 {
00843         memset(&ProcessorInfo, 0, sizeof(ProcessorInfo));
00844 
00845         ProcessorInfo.MaxCPUIDVal               =GetCPUIDString(0, ProcessorInfo.VendorString);
00846         ProcessorInfo.VendorString[13]  =0;
00847         if(strncmp(ProcessorInfo.VendorString, "AuthenticAMD", 12)==0)
00848         {
00849                 U32     TypeFlags       =GetCPUIDEAX(0x80000000);
00850                 if(TypeFlags)   //extended functions supported
00851                 {
00852                         TypeFlags       =GetCPUIDEDX(0x80000001);
00853                         GetCPUIDStringAMD(0x80000002, ProcessorInfo.ProcName);
00854                         GetCPUIDStringAMD(0x80000003, ProcessorInfo.ProcName+16);
00855                         GetCPUIDStringAMD(0x80000004, ProcessorInfo.ProcName+32);
00856                         ErrorPrintf("CPU Family:  %s\n", ProcessorInfo.ProcName);
00857                         ProcessorInfo.HasMMX            =TypeFlags & (1<<23);
00858                         ProcessorInfo.Has3DNow          =TypeFlags & (1<<31);
00859                         ProcessorInfo.HasFCMOV          =TypeFlags & (1<<16);
00860                         ProcessorInfo.HasRDTSC          =TypeFlags & (1<<4);
00861                 }
00862                 else
00863                 {
00864                         U32     TypeFlags                               =GetCPUIDEDX(0x1);
00865                         ProcessorInfo.HasMMX            =TypeFlags & (1<<23);
00866                         ProcessorInfo.HasFCMOV          =((TypeFlags & (1<<15 | 1))==(1<<15 | 1))? TRUE : FALSE;
00867                         ProcessorInfo.HasRDTSC          =TypeFlags & (1<<4);
00868                 }
00869                 TypeFlags                                       =GetCPUIDEAX(1);
00870                 ProcessorInfo.ProcType          =(TypeFlags>>12)&0x3;
00871                 ProcessorInfo.ProcFamily        =(TypeFlags>>8)&0xf;
00872                 ProcessorInfo.ProcModel         =(TypeFlags>>4)&0xf;
00873                 ProcessorInfo.ProcStepping      =(TypeFlags)&0x7;
00874                 //ProcessorInfo.ProcSpeed               =GetProcessorSpeed();
00875         }
00876         else if(strncmp(ProcessorInfo.VendorString, "GenuineIntel", 12)==0)
00877         {
00878                 U32     TypeFlags                               =GetCPUIDEDX(0x1);
00879                 ProcessorInfo.HasMMX            =TypeFlags & (1<<23);
00880                 ProcessorInfo.HasFCMOV          =((TypeFlags & (1<<15 | 1))==(1<<15 | 1))? TRUE : FALSE;
00881                 ProcessorInfo.HasRDTSC          =TypeFlags & (1<<4);
00882 
00883                 TypeFlags                                       =GetCPUIDEAX(1);
00884                 ProcessorInfo.ProcType          =(TypeFlags>>12)&0x3;
00885                 ProcessorInfo.ProcFamily        =(TypeFlags>>8)&0xf;
00886                 ProcessorInfo.ProcModel         =(TypeFlags>>4)&0xf;
00887                 ProcessorInfo.ProcStepping      =(TypeFlags)&0x7;
00888                 //ProcessorInfo.ProcSpeed               =GetProcessorSpeed();
00889 
00890                 ErrorPrintf("CPU Family:  %d\n", ProcessorInfo.ProcFamily);
00891                 ErrorPrintf("CPU Model:  %d\n", ProcessorInfo.ProcModel);
00892         }
00893         else
00894         {
00895                 U32     TypeFlags       =GetCPUIDEAX(0x80000000);
00896                 if(TypeFlags)   //extended functions supported
00897                 {
00898                         TypeFlags       =GetCPUIDEDX(0x80000001);
00899                         GetCPUIDStringAMD(0x80000002, ProcessorInfo.ProcName);
00900                         GetCPUIDStringAMD(0x80000003, ProcessorInfo.ProcName+16);
00901                         GetCPUIDStringAMD(0x80000004, ProcessorInfo.ProcName+32);
00902                         ErrorPrintf("CPU Family:  %s\n", ProcessorInfo.ProcName);
00903                         ProcessorInfo.HasMMX            =TypeFlags & (1<<23);
00904                         ProcessorInfo.Has3DNow          =TypeFlags & (1<<31);
00905                         ProcessorInfo.HasFCMOV          =TypeFlags & (1<<16);
00906                         ProcessorInfo.HasRDTSC          =TypeFlags & (1<<4);
00907                 }
00908                 else
00909                 {
00910                         U32     TypeFlags                               =GetCPUIDEDX(0x1);
00911                         ProcessorInfo.HasMMX            =TypeFlags & (1<<23);
00912                         ProcessorInfo.HasFCMOV          =((TypeFlags & (1<<15 | 1))==(1<<15 | 1))? TRUE : FALSE;
00913                         ProcessorInfo.HasRDTSC          =TypeFlags & (1<<4);
00914                 }
00915                 TypeFlags                                       =GetCPUIDEAX(1);
00916                 ProcessorInfo.ProcType          =(TypeFlags>>12)&0x3;
00917                 ProcessorInfo.ProcFamily        =(TypeFlags>>8)&0xf;
00918                 ProcessorInfo.ProcModel         =(TypeFlags>>4)&0xf;
00919                 ProcessorInfo.ProcStepping      =(TypeFlags)&0x7;
00920                 //ProcessorInfo.ProcSpeed               =GetProcessorSpeed();
00921         }
00922 
00923         ErrorPrintf("CPU Vendor String:  %s\n", ProcessorInfo.VendorString);
00924         ErrorPrintf("Processor Speed:  %d\n", ProcessorInfo.ProcSpeed);
00925         ErrorPrintf("Stepping:  %d\n", ProcessorInfo.ProcStepping);
00926         if(ProcessorInfo.HasMMX)
00927         {
00928                 ErrorPrintf("MMX instructions detected\n");
00929         }
00930         if(ProcessorInfo.Has3DNow)
00931         {
00932                 if (VInfo!=NULL)
00933                 {
00934                         VInfo->bpp      =32;
00935                         ErrorPrintf("3DNow instructions detected\n");
00936                 }
00937         }
00938         if(ProcessorInfo.HasFCMOV)
00939         {
00940                 ErrorPrintf("FCMOV feature detected\n");
00941         }
00942         if(ProcessorInfo.HasRDTSC)
00943         {
00944                 ErrorPrintf("Time Stamp Counter feature detected\n");
00945         }
00946 }

Generated on Tue Sep 30 12:36:22 2003 for GTestAndEngine by doxygen 1.3.2