home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-09 | 32.2 KB | 951 lines | [TEXT/CWIE] |
- /* NameRegistryLib is in the VideoToolbox:Libs folder. */
- //#define NO_NAME_REGISTRY_LIB 1 /* Uncomment this if you're missing Apple's NameRegistryLib */
- /*
- Identify.c
-
- NOTE: several routines that use Apple's NameRegistryLib appear at the end of this file.
- If you don't have that file, then un-comment the first line above.
-
- Each routine returns an informative C string. Here are samples. (I suggest you
- use BreakLines() to printf the longer ones.)
-
- IdentifyCompiler:
- "Compiled by Metrowerks CodeWarrior C 7.00 for PowerPC, 4B int and 8B double."
-
- IdentifyOwner:
- "Denis Pelli"
-
- IdentifyModel:
- "PowerBook 170"
-
- IdentifyMachine:
- "Denis Pelli's PowerBook 170, 68030, 68882, System 7.1.0."
- "Mal's PowerMac 8500/120, ppc604, L2 cache, System 7.5.2."
-
- IdentifyVideo(device):
- "PowerBook 170 \"Macintosh D Built-In Video\" (.Display_Video_Apple_TIM) in slot 0"
- "PowerMac 8500/120 \"Built-in video\" (.Display_Video_Apple_Control)"
-
- The computer model appears only if the slot==0, which indicates built-in video.
- Quotes embrace the card name, and parentheses embrace the driver name.
- The driver's version number appears only if it's non-zero.
-
- HISTORY:
- 1/29/92 dgp wrote IdentifyCompiler.
- 2/25/92 dgp wrote IdentifyMachine.
- 8/26/92 dgp get owner and model name from the System file
- 2/20/93 dgp added ROM version
- 2/27/93 dgp merged IdentifyCompiler.c and IdentifyMachine.c into the new Identify.c,
- and added IdentifyVideo.
- 4/25/93 dgp IdentifyMachine reports 24/32-bit addressing.
- 12/14/93 dgp If THINK C compiler version is "5" I report "5 or 6.0" since Symantec
- forgot to increment the version number when they released 6.0. They
- fixed this in version 6.01.
- 3/2/94 dgp Extracted IdentifyOwner from within IdentifyMachine
- 7/28/94 dgp added support for Metrowerks CodeWarrior C compiler and PowerPC.
- Eliminated use of "#s" printf format, since it's not supported by
- Metrowerks CodeWarrior C.
- 9/5/94 dgp removed assumption in printf's that int==short.
- 9/6/94 dgp Enhanced IdentifyCompiler to specify the size of int.
- 9/6/94 dgp Disable cache checks on PowerPC, because those traps are undefined.
- 10/5/94 dgp Removed all floating point code from IdentifyCompiler().
- 11/5/94 dgp Suppressed ROM info in Identify.
- 11/9/94 dgp added IdentifyApplication().
- 1/15/95 dgp added test for version 5 of CodeWarrior
- 5/24/95 dgp added test for version 6 of CodeWarrior
- 6/14/95 dgp added GetCPUSpeed() to IdentifyMachine() and abbreviated the report,
- omitting a lot of boring stuff.
- 6/27/95 dgp adjusted UNIVERSAL_HEADERS conditional for GMT struct, to use old
- structure for version 1 universal headers.
- 7/20/95 dgp once again, made compatible with pre-universal headers
- 8/10/95 dgp updated IdentifyCompiler() for Symantec C.
- 9/26/95 dgp updated IdentifyCompiler() for CW7.
- 10/5/95 dgp minor editing of IdentifyVideo().
- 10/14/95 dgp added support for PCI Macs, using the NameRegistry. Since System 7.5 fails to
- adequately name most Macs, I've reverted to using a built-in table of names in
- IdentifyModel. IdentifyMachine now also prints the Gestalt machine number to
- resolve any residual ambiguities.
- IdentifyModel, IdentifyVideo, and IdentifyMachine now give complete information on all
- Macs, provided that when running on PCI Macs they are compiled as PPC code. This
- limitation is due to the (easy) way that I implemented the calls to Apple's
- NameRegistryLib. The NameRegistry-related routines appear in a long self-contained
- section at the end of this file.
- 10/24/95 dgp added pclk and bclk Gestalt calls, based on gestalt-selectors-31.
- 12/4/95 dgp As requested by David Brainard, changed "char *machineName[]" to
- "char machineName[][32]" so that it would compile as a code resource.
- 3/7/96 dgp report system version number in standard format, e.g. "7.5.3".
- 3/18/96 dgp IdentifyModel() now always reports actual clock speed if known.
- 5/14/96 dgp Added mach codes for new Macs from GestaltSelectorList 3.3.5.
- 5/28/96 dgp Added conditional UNIVERSAL_INTERFACES_VERSION>=0x0212
- */
- #include "VideoToolbox.h"
- #ifndef __TRAPS__
- #include <Traps.h> // _HWPriv
- #endif
- #include <Power.h>
- #if UNIVERSAL_HEADERS
- #include <LowMem.h>
- #else
- #define LMGetCurApName() ((StringPtr) 0x0910)
- #define gestaltNativeCPUtype 'cput'
- enum{
- gestaltCPU601 = 0x101,
- gestaltCPU603 = 0x103,
- gestaltCPU604 = 0x104
- };
- enum {
- gestaltSysArchitecture = 'sysa', /* Native System Architecture */
- gestalt68k = 1, /* Motorola MC68k architecture */
- gestaltPowerPC = 2 /* IBM PowerPC architecture */
- };
- #pragma parameter __D0 MaximumProcessorSpeed
- extern pascal short MaximumProcessorSpeed(void)={0x7010, 0xA09E};
- #endif
- void GetCPUProperties(char *cpuName,long *cpuHz,Boolean *hasL2Cache);
- void GetVideoProperties(GDHandle device,char *slotName,char *cardName,char *modelName);
- char *GetDeviceSlotName(GDHandle device);
- #define gestaltBusClockSpeed 'bclk' /* gestalt-selectors-31.etx */
- #define gestaltCPUClockSpeed 'pclk' /* gestalt-selectors-31.etx */
-
- // System 7.5 took a step backwards and lacks
- // specific names for many machines, so I used Rene Ros's Gestalt Selectors List
- // to list all currently available Macs.
- char machineName[][36]={
- "Unknown Mac"
- ,"Mac 128K"
- ,"Mac XL"
- ,"Mac 512KE"
- ,"Mac Plus"
- ,"Mac SE"
- ,"Mac II"
- ,"Mac IIx"
- ,"Mac IIcx"
- ,"Mac SE-30"
- ,"Mac Portable"
- ,"Mac IIci"
- ,"Unknown Mac" /* 12 */
- ,"Mac IIfx"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac Classic","Mac IIsi","Mac LC","Mac Quadra 900","PowerBook 170"
- ,"Mac Quadra 700","Mac Classic II","PowerBook 100","PowerBook 140","Quadra 950"
- ,"Mac LC III"
- ,"Unknown Mac"
- ,"Mac PowerBook 210"
- ,"Mac Centris 650"
- ,"Unknown Mac"
- ,"Mac PowerBook 230"
- ,"Mac PowerBook 180"
- ,"Mac PowerBook 160"
- ,"Mac Quadra 800" /* 35 */
- ,"Mac Quadra 650"
- ,"Mac LC II"
- ,"Mac PowerBook Duo 250"
- ,"PowerMac 9150"
- ,"PowerMac 8100/110" /* 40 */
- ,"PowerMac 5200" /* 41 */
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac IIvi"
- ,"Mac Performa 600"
- ,"Unknown Mac"
- ,"PowerMac 7100/80" /* 47 */
- ,"Mac IIvx"
- ,"Mac Color Classic"
- ,"Mac PowerBook 165c"
- ,"Unknown Mac"
- ,"Mac Centris 610"
- ,"Mac Quadra 610"
- ,"Mac PowerBook 145,145b"
- ,"PowerMac 8100/100" /* 55 */
- ,"Mac LC 520"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac Centris 660AV"
- ,"Unknown Mac"
- ,"Mac Performa 46x"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"PowerMac 8100/80" /* 65 */
- ,"Unknown Mac"
- ,"PowerMac 9500" /* 67 */
- ,"PowerMac 7500,7600" /* 68 */
- ,"PowerMac 8500" /* 69 */
- ,"Unknown Mac"
- ,"Mac PowerBook 180c"
- ,"Mac PowerBook 500,520,520c,540,540c" /* 72 */
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"PowerMac 6100/60" /* 75 */
- ,"Unknown Mac"
- ,"Mac PowerBook Duo 270c"
- ,"Mac Quadra 840AV"
- ,"Unknown Mac"
- ,"Mac LC/Performa 550"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac PowerBook 165"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac TV"
- ,"Mac LC/Performa 475"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac LC 575"
- ,"Unknown Mac"
- ,"Mac Quadra 605"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Mac LC/Quadra 630"
- ,"Unknown Mac"
- ,"PowerMac 6100/66" /* 100 */
- ,"PowerMac 6100" /* 80 MHz, discovered by clock chippers */
- ,"Mac PowerBook Duo 280"
- ,"Mac PowerBook Duo 280c"
- ,"PowerMac LC/Performa 475"
- ,"PowerMac LC/Performa 575"
- ,"PowerMac LC/Quadra 630"
- ,"Unknown Mac"
- ,"PowerMac 7200" /* 108, also PowerMac 8200/100 */
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"PowerMac 7100/66" /* 112 */
- ,"PowerMac 7100" /* 80 MHz, discovered by clock chippers */
- ,"Unknown Mac"
- ,"Mac PowerBook 150"
- ,"PowerMac Quadra700"
- ,"PowerMac Quadra900"
- ,"PowerMac Quadra950"
- ,"PowerMac Centris610"
- ,"PowerMac Centris650"
- ,"PowerMac Quadra610"
- ,"PowerMac Quadra650"
- ,"PowerMac Quadra800"
- ,"PowerBook 2300c" /* 124 */
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"Unknown Mac"
- ,"PowerBook 5300"
- };
-
- char fpuName[][32]={
- "no floating point unit","68881","68882","built-in floating point"
- ,"unknown floating point unit","Software FPU"
- };
-
- char *IdentifyCompiler(void)
- {
- static char string[200];
- char *compiler,*longs,*floating,version[4],*universal;
- double v=0;
- Boolean fractionalVersion=0;
-
- string[0]=0;
- compiler="";
- #if THINK_C && !SYMANTEC_C
- compiler="Symantec THINK C";
- if(THINK_C==1)v=4;
- else v=THINK_C;
- #endif
- #if THINK_CPLUS || SYMANTEC_C
- #if __cplusplus || THINK_CPLUS
- compiler="Symantec C++";
- #else
- compiler="Symantec C";
- #endif
- #if THINK_CPLUS
- v=THINK_CPLUS;
- #else
- fractionalVersion=1;
- v=SYMANTEC_C/0x100 + 0.1*(SYMANTEC_C/0x10%0x10) + 0.01*(SYMANTEC_C%0x10);
- #endif
- #endif
- #if applec
- compiler="MPW C";
- #endif
- #if __MWERKS__
- compiler="Metrowerks CodeWarrior C";
- #if __MWERKS__>1
- fractionalVersion=1;
- v=__MWERKS__/0x100 + 0.1*(__MWERKS__/0x10%0x10) + 0.01*(__MWERKS__%0x10);
- #else
- #if defined(__MC68K__)||defined(__POWERPC__)||defined(__INTEL__)
- v=6;
- #else
- if(!iscntrl(0))v=4; // bug in version 4.5 and earlier
- else v=5;
- #endif
- #endif
- #endif
- if(v>0){
- if(fractionalVersion)sprintf(version,"%.2f ",v);
- else sprintf(version,"%.0f ",v);
- }else sprintf(version,"");
- if(GENERATING68020)longs="68020";
- else{
- #if GENERATINGPOWERPC
- longs="PowerPC";
- #else
- longs="68000";
- #endif
- }
- if(GENERATING68881)floating=" and 68881";
- else floating="";
- universal="";
- if(sizeof(double)==12){
- #if THINK_C
- #if !__option(native_fp)
- universal="\"universal\"-format ";
- #endif
- #endif
- }
- sprintf(string,"Compiled by %s %sfor %s%s, %ldB int and %s%ldB double."
- ,compiler,version,longs,floating,sizeof(int),universal,sizeof(double));
- return string;
- }
-
- char *IdentifyModel(void)
- {
- int error;
- long machine=0,value;
- int machines=sizeof(machineName)/sizeof(machineName[0]);
- static char string[64];
- char cpuName[32]="";
- long cpuHz=0,busHz=0;
- Boolean hasL2Cache,powerMgrExists;
-
- #if 0
- /* Before System 7.5 the MacOS supplied the model name. Now it merely supplies a
- generic name, like "Power Macintosh". */
- if(!error){
- GetIndString((unsigned char *)string,kMachineNameStrID,machine);
- p2cstr((unsigned char *)string);
- if(strlen(string)==0){
- if(machine<0 || machine>=machines)machine=0;
- sprintf(string,"%s",machineName[machine]);
- }
- }
- #endif
- /* The model names in the machineName[] table include clock speed, where appropriate,
- for the pre-PCI Macs, e.g. 6100/60, but omit clock speed for the PCI Macs, since
- PCI Macs must run System 7.5.2 or better, which include gestaltCPUClockSpeed, whereas
- pre-PCI Macs may be running 7.5.1 which did not include gestaltCPUClockSpeed.
- If the actual clock speed is available we always use it, overwriting the nominal speed if
- necessary. */
- error=Gestalt(gestaltMachineType,&machine);
- strcpy(string,machineName[machine]);
- GetCPUProperties(cpuName,&cpuHz,&hasL2Cache); // useful only on PCI Macs
- error=Gestalt(gestaltBusClockSpeed,&busHz); // requires System 7.5.2 or better
- error=Gestalt(gestaltCPUClockSpeed,&cpuHz); // requires System 7.5.2 or better
- if(cpuHz==0){
- Gestalt(gestaltPowerMgrAttr,&value); // Only on powerbooks I think.
- powerMgrExists=value&(1L<<gestaltPMgrExists);
- if(powerMgrExists)cpuHz=1000000*GetCPUSpeed();
- }
- if(cpuHz>0){
- int i=strlen(string);
- // remove the nominal speed, if present, before appending the actual speed
- if(i>4 && string[i-4]=='/' && isdigit(string[i-3]) && isdigit(string[i-2]) && isdigit(string[i-1]))
- string[i-4]=0;
- if(i>3 && string[i-3]=='/' && isdigit(string[i-2]) && isdigit(string[i-1]))
- string[i-3]=0;
- sprintf(string,"%s/%ld",string,cpuHz/1000000);
- }
- return string;
- }
-
- char *IdentifyVideo(GDHandle device)
- // E.g. "PowerBook 170 \"Macintosh D Built-In Video\" (.Display_Video_Apple_TIM)"
- {
- static char string[256];
- long quickDraw;
- char *slotName;
-
- string[0]=0;
- Gestalt(gestaltQuickdrawVersion,&quickDraw);
- if(quickDraw<gestalt8BitQD){
- sprintf(string,"%s ",IdentifyModel());
- sprintf(string,"%s\"%s\"",string,"1-bit QuickDraw");
- }else{
- slotName=GetDeviceSlotName(device);
- if(strlen(slotName)==0 || strcmp(slotName,"0")==0)sprintf(string,"%s ",IdentifyModel());
- sprintf(string,"%s\"%s\"",string,GDCardName(device));
- if(GDVersion(device)==0)sprintf(string,"%s (%s)",string,GDNameStr(device));
- else sprintf(string,"%s (%s version %d)"
- ,string,GDNameStr(device),(int)GDVersion(device));
- if(strlen(slotName)>0 && strcmp(slotName,"0")!=0)sprintf(string,"%s slot %s",string,slotName);
- }
- return string;
- }
-
- char *IdentifyOwner(void)
- {
- static char string[64];
- unsigned char **owner;
-
- string[0]=0;
- owner=GetString(-16096); // Get owner's name from System file
- if(owner!=NULL && *owner[0]>0){
- memcpy(string,*owner,(*owner)[0]+1);
- p2cstr((unsigned char *)string);
- }
- return string;
- }
-
- char *IdentifyApplication(void) // Returns name of application.
- {
- static char string[32];
-
- memcpy(string,LMGetCurApName(),32);
- p2cstr((unsigned char *)string);
- return string;
- }
-
- char *IdentifyMachineAndType(void);
-
- char *IdentifyMachineAndType(void)
- {
- int error;
- long machine=0;
- char *s;
-
- s=IdentifyMachine();
- error=Gestalt(gestaltMachineType,&machine);
- sprintf(s,"%s GestaltMachineType %ld.",s,machine);
- return s;
- }
-
- char *IdentifyMachine(void)
- {
- int error;
- long fpu,processor=-1,system,value,sysArchitecture;
- int fpus=sizeof(fpuName)/sizeof(fpuName[0]);
- static char string[256];
- Boolean cacheData=1,cacheInstructions=1;
- long romSize,romVersion,qD;
- char *processorName,*owner,fpuString[32];
- char cpuName[32]="";
- long cpuHz=0,busHz=0;
- Boolean hasL2Cache;
- char cache[32]="";
-
- GetCPUProperties(cpuName,&cpuHz,&hasL2Cache); /* works only on PCI Macs */
- error=Gestalt(gestaltBusClockSpeed,&busHz); /* works only on PCI Macs */
- error=Gestalt(gestaltCPUClockSpeed,&cpuHz); /* works only on PCI Macs */
- string[0]=0;
- error=Gestalt(gestaltSystemVersion,&system);
- if(error)return string; /* Gestalt not available */
- sysArchitecture=gestalt68k; /* default */
- error=Gestalt(gestaltSysArchitecture,&sysArchitecture);
- switch(sysArchitecture){
- case gestalt68k:
- error=Gestalt(gestaltProcessorType,&processor);
- switch(processor){
- case 1: processorName="68000";break;
- case 2: processorName="68010";break;
- case 3: processorName="68020";break;
- case 4: processorName="68030";break;
- case 5: processorName="68040";break;
- default: processorName="unknown processor";break;
- }
- break;
- case gestaltPowerPC:
- error=Gestalt(gestaltNativeCPUtype,&processor);
- switch(processor){
- case gestaltCPU601: processorName="ppc601";break;
- case gestaltCPU603: processorName="ppc603";break;
- case 0x106: processorName="ppc603e";break;/* PowerBook 5300 */
- case gestaltCPU604: processorName="ppc604";break;
- default: processorName="unknown processor";break;
- }
- break;
- default:
- processorName="unknown processor";
- break;
- }
- Gestalt(gestaltFPUType,&fpu);
- if(fpu<0 || fpu>=fpus)fpu=fpus-2;
- if(fpu==1 && Gestalt('FPUE',&value)==0)fpu=fpus-1;// Software FPU by John Neil & Assoc.
- if(fpu>0)sprintf(fpuString,", %s",fpuName[fpu]);
- else fpuString[0]=0;
- owner=IdentifyOwner();
- if(strlen(owner)>0)sprintf(string,"%s's ",owner);
- sprintf(string,"%s%s",string,IdentifyModel());
- if(strlen(cpuName)>0){
- if(hasL2Cache)strcpy(cache,", L2 cache");
- else strcpy(cache,"");
- }
- sprintf(string,"%s, %s%s%s, System %lx.%lx"
- ,string,processorName,cache,fpuString,system/0x100,system%0x100/0x10);
- system%=0x10;
- if(system)sprintf(string,"%s.%lx",string,system);
- sprintf(string,"%s.",string);
- if(0){ // The rest is boring, so I've disabled it.
- Gestalt(gestaltROMSize,&romSize);
- Gestalt(gestaltROMVersion,&romVersion);
- sprintf(string,"%s, %ldK ROM version %ld+%ld*256."
- ,string,romSize/1024,romVersion%256,romVersion/256);
- if(TrapAvailable(_HWPriv)){
- #if !GENERATINGPOWERPC /* apparently these functions don't work on PowerPC */
- cacheData=SwapDataCache(1);
- SwapDataCache(cacheData);
- cacheInstructions=SwapInstructionCache(1);
- SwapInstructionCache(cacheInstructions);
- if(cacheData || cacheInstructions)sprintf(string,"%s Caching",string);
- else sprintf(string,"%s No caching",string);
- if(cacheData)sprintf(string,"%s data",string);
- if(cacheData && cacheInstructions)sprintf(string,"%s &",string);
- if(cacheInstructions)sprintf(string,"%s instructions",string);
- sprintf(string,"%s.",string);
- #endif
- }
- value=0;
- Gestalt(gestaltAddressingModeAttr,&value);
- {
- if(value&1L<<gestalt32BitAddressing)sprintf(string,"%s 32-bit addressing.",string);
- else sprintf(string,"%s 24-bit addressing.",string);
- }
- Gestalt(gestaltQuickdrawVersion,&qD);
- switch(qD/0x100){
- case 0:
- sprintf(string,"%s 1-bit QuickDraw.",string);
- break;
- case 1:
- sprintf(string,"%s 8-bit QuickDraw.",string);
- break;
- case 2:
- sprintf(string,"%s 32-bit QuickDraw 1.%02lx.",string,qD%0x100);
- break;
- default:
- sprintf(string,"%s QuickDraw 0x%lx.",string,qD);
- break;
- }
- }
- return string;
- }
-
- char *IdentifyVM(void)
- {
- // Based on gestalt-selectors-29.etx, available from Info-Mac.
- Boolean vm; // VM is on, possibly due to RAM Doubler
- Boolean ramDoubler; // RAM Doubler is on.
- long value;
- int error;
- char *s="";
-
- error=Gestalt(gestaltVMAttr,&value);
- vm=!error && value&(1L<<gestaltVMPresent);
- error=Gestalt('vmem',&value);
- ramDoubler=!error && value=='RaM2';
- if(vm){
- if(!ramDoubler)s="Using Virtual Memory. ";
- else s="Using RAM Doubler. ";
- }
- return s;
- }
-
- char *IdentifyGreenwichMeanTime(void)
- {
- MachineLocation location;
- long t;
- double hours;
- static char s[64];
-
- ReadLocation(&location);
- if(location.latitude!=0 || location.longitude!=0){
- #if UNIVERSAL_HEADERS>1
- t=location.u.gmtDelta & 0x00FFFFFF;
- #else
- t=location.gmtFlags.gmtDelta & 0x00FFFFFF;
- #endif
- if(t & 0x800000)t|=0xFF000000;
- hours=fabs(t/3600.0);
- if(hours==floor(hours))sprintf(s,"%.0f",hours);
- else sprintf(s,"%.1f",hours);
- if(t<0)sprintf(s,"%s hours west of Greenwich mean time.",s);
- else sprintf(s,"%s hours east of Greenwich mean time.",s);
- }else s[0]=0;
- return s;
- }
-
- /************************************************************************/
-
- /*
- Using Apple's NameRegistry
-
- void GetVideoProperties(GDHandle device,char *slotName,char *cardName,char *cardModel);
- void GetCPUProperties(char *cpuName,long *cpuHz,Boolean *hasL2Cache);
-
- Two routines that use the new Name Registry (available only on PCI PowerMacs) to
- determine the cpu clock rate, presence of L2 cache, and the name of the PCI video
- card. The routines return zeroes if the Name Registry is not available (i.e. on
- non-PCI Macs), or if compiled as 68k code.
-
- WARNING: to effectively use Apple's NameRegistry in your project you MUST have Apple's
- NameRegistryLib, which contains the glue code to access the MacOS. NameRegistryLib
- is in the VideoToolbox Libs folder; add it to your project and use the pop-up
- menu to select "import 'weak'".) As of 1/96, Apple has
- distributed NameRegistry.h and NameRegistryLib only as part of the Apple
- Developer Mailing and the SDK Subscription (either costs $250/year from APDA). These
- two files are not included with Metrowerks CodeWarrior 8. You don't need
- NameRegistry.h, because Identify.c includes the needed definitions, but you do need
- NameRegistryLib, which is in the VideoToolbox Libs folder. Alternatively,
- you may set the flag NO_NAME_REGISTRY_LIB to true, which will disable the rest of
- this file, but allows you to link and run your programs.
-
- Once compiled and linked with the NameRegistryLib glue, this code will run on any
- PCI PowerMac. A temporary #if section takes care of the missing header file, so
- you'll be able to compile, but I don't think you'll be able to link this unless
- you have NameRegistryLib. I confess to being somewhat unsure on the last point
- since there are suggestions in the original source files that NameRegistryLib
- could be installed in the System:Extensions folder of the target machine instead
- of being linked into the application itself. That is apparently what the call
- below to Code Fragment Manager is for. However, I don't really understand this
- arcane stuff (i.e. "weak linking"), and it didn't seem worth learning for the
- routines in this file. Metrowerks has a "weak-linking" option, but limited
- experimentation suggests that you have to have the library in order to weak-link
- to it, which is no help at all for someone who doesn't have the library.
-
- HISTORY:
- 10/13/95 dgp wrote GetVideoProperties() and GetCPUProperties(), based on general
- advice from Apple (below) and
- the PCISlotsUtils.cp source file for Apple's "PCI Slot Peek" demo,
- in the PCI developer's kit included on the September '95 Developer's CD.
-
- Hi Denis
-
- Thank you for your link (ID# 151426) concerning how to detect a L2 cache and
- get the processor speed.
-
- Let's look at the cache first. Before the introduction of the PCI Power
- Macintosh computers there was no API to detect the presents of this cache. On
- a PCI Macintosh there is the Name Registry. This registry contains this
- information in the form of a property. The property name is "name" and if
- there is a L2 cache the property value is "l2-cache". Look at the Developer CD
- for Sept 95. In the What's New folder there is the PCI DDK. There is a
- program called Display Name Registry that will show what I have just explained.
- Of course it must run on a PCI machine. There is also a document called
- "Designing PCI Cards&Drivers...." that shows examples of using the Name
- Registry to search for system resources.
-
- Now the CPU speed. Like the last case, before PCI Macs there was no direct
- call that could be made to determine CPU speed. There are Gestalt calls for
- CPU type if that's any help. However, there are CPU accelerator cards so that
- would present a problem. The two calls you mentioned (GetCPUSPeed &
- MaximumProcessSpeed) are both for portable Macs that use the Power Manager.
- The traps for these calls are not implemented on other Macs. At least not the
- 9500 that I tried. However, PCI Macs and the Name Registry contain this
- information also. Again go to Display Name Registry and look at the
- Devices:device-tree;PowerPC,604 property. Expand it and there is an additional
- sub property called "clock-frequency". My 9500 show 132000000.
-
- So you have what you want but starting with PCI Macs.
-
- Regards
-
- Wayne Flansburg
- Developer Technical Support
- Apple Computer
- 12 October 1995
- */
-
- #if UNIVERSAL_HEADERS>1
- #ifndef __CODEFRAGMENTS__
- #include <CodeFragments.h>
- #endif
- #else
- #undef NO_NAME_REGISTRY_LIB
- #define NO_NAME_REGISTRY_LIB 1
- #endif
- // The version macro UNIVERSAL_INTERFACES_VERSION is defined in Apple's ConditionalMacros.h,
- // but only since version 2.1 (which was distributed with CodeWarrior 8).
- #if UNIVERSAL_INTERFACES_VERSION>=0x0212
- #ifndef __NAMEREGISTRY__
- #include <NameRegistry.h>
- #endif
- #else
- #if !defined(NO_NAME_REGISTRY_LIB) && !defined(__NAMEREGISTRY__)
- // As of 10/13/95, Apple has distributed NameRegistry.h and NameRegistryLib only to
- // Apple Developers. Neither is included with Metrowerks CodeWarrior 7.
- // The following definitions and prototypes, copied from NameRegistry.h, are just
- // enough to allow compilation of this file without the header file. However,
- // you'll still need NameRegistryLib in order to link.
- // It's in the VideoToolbox Lib folder.
- typedef UInt32 RegIterationOp;
- typedef RegIterationOp RegEntryIterationOp;
- struct RegEntryIter {
- void *opaque;
- };
- typedef struct RegEntryIter *RegEntryIterPtr;
- typedef struct RegEntryIter RegEntryIter;
- struct RegEntryID {
- UInt8 opaque[16];
- };
- typedef struct RegEntryID RegEntryID, *RegEntryIDPtr;
- typedef char RegCStrPathName;
- typedef UInt32 RegPathNameSize;
- enum {
- kRegMaximumPropertyNameLength = 31, /* Max length of Property Name */
- kRegPropertyNameTerminator = 0x00, /* '\0' */
- kRegIterContinue = 0x1UL
- };
- typedef char RegPropertyName, *RegPropertyNamePtr, RegPropertyNameBuf[kRegMaximumPropertyNameLength + 1];
- typedef UInt32 RegPropertyValueSize;
- extern OSStatus RegistryEntryIterateCreate(RegEntryIter *cookie);
- extern OSStatus RegistryEntryIterateDispose(RegEntryIter *cookie);
- extern OSStatus RegistryEntryIterate(RegEntryIter *cookie, RegEntryIterationOp relationship, RegEntryID *foundEntry, Boolean *done);
- extern OSStatus RegistryEntryToPathSize(const RegEntryID *entryID, RegPathNameSize *pathSize);
- extern OSStatus RegistryCStrEntryToPath(const RegEntryID *entryID, RegCStrPathName *pathName, RegPathNameSize pathSize);
- extern OSStatus RegistryPropertyGetSize(const RegEntryID *entryID, const RegPropertyName *propertyName, RegPropertyValueSize *propertySize);
- extern OSStatus RegistryPropertyGet(const RegEntryID *entryID, const RegPropertyName *propertyName, void *propertyValue, RegPropertyValueSize *propertySize);
- extern OSStatus RegistryEntryIDDispose(RegEntryID *id);
- #endif
- #endif
- #include <stdio.h>
- #include <string.h>
- /*
- RegPropertyModifiers propertyModifiers;
- if(0 && !error){
- error=RegistryPropertyGetMod(&entry,foundProperty,&propertyModifiers);
- }
- */
-
- void GetVideoProperties(GDHandle device,char *slotName,char *cardName,char *cardModel);
- void GetCPUProperties(char *cpuName,long *cpuHz,Boolean *hasL2Cache);
-
- void GetVideoProperties(GDHandle device,char *slotName,char *cardName,char *cardModel)
- {
- #if NO_NAME_REGISTRY_LIB || !GENERATINGPOWERPC
- device;
- slotName[0]=0;
- cardName[0]=0;
- cardModel[0]=0;
- return;
- #else
- /*
- Assume we're running native on ppc.
- If this were compiled as 68k code, the calls to the NameRegistryLib, which is PPC code,
- would require intervention by the Mixed Mode Manager,
- and I decided not to bother with that complication, since there seems little point in
- compiling programs as 68k code to run on a PowerPC. TimeVideo is distributed as a fat
- binary, so it always runs native.
- */
- OSStatus error;
- RegEntryIter cookie;
- Boolean done;
- RegEntryIterationOp op;
- RegEntryID entry;
- RegCStrPathName *pathName;
- RegPathNameSize pathNameSize;
- RegPropertyNameBuf foundProperty;
- RegPropertyValueSize propertySize;
- long templong;
- short driverRef;
-
- slotName[0]=0;
- cardName[0]=0;
- cardModel[0]=0;
- if(device==NULL)return;
- {
- /*
- To determine whether you're running on a PCI Mac, you must first check if the
- NameRegistry exists. There is a Gestalt Manager selector for
- this, 'nreg'. If it exists, the value returned will be the version number
- (number 1 for now) of the Name Registry. Otherwise, you should get a
- gestaltUndefSelectorErr. If the Name Registry does not exist then you should
- assume that it is not a PCI based machine; it may have NuBus or no bus at all.
- */
- error=Gestalt(gestaltNameRegistryVersion,&templong);
- if(error)return; // No PCI slots
- /*
- *** I didn't add this yet --- dgp ***
- You can use the Name Registry to determine if a PCI bus exists. To do this you
- should use RegistryEntrySearch to locate an entry/node having a known
- property/value, propertyName = "devic-type", and propertyValue = "pci" If an
- entry is found that has that known property/value (noErr and done = "False"),
- there is a PCI bus.
- Wayne Flansburg
- DTS
- Apple Computer
- 1/26/96
- */
- }
- {
- // If NameRegistryLib is weak-linked, it may be missing at runtime, so we
- // check for the library, to prevent a crash if we try to access the library's exports.
- CFragConnectionID connID;
- Ptr mainAddr;
- Str255 errName;
-
- error=Gestalt(gestaltCFMAttr,&templong); // Code Fragment Manager?
- if(!error)error=GetSharedLibrary((ConstStr63Param)"\pNameRegistryLib"
- ,kAnyCFragArch,kFindCFrag,&connID,&mainAddr,errName);
- if(error)return; // No NameRegistryLib
- }
- op=kRegIterContinue;
- error=RegistryEntryIterateCreate(&cookie);
- if(!error){
- done=FALSE;
- while (!error && !done){
- error=RegistryEntryIterate(&cookie,op,&entry,&done);
- if(!error && !done){
- pathName=NULL;
- error=RegistryEntryToPathSize(&entry,&pathNameSize);
- if(!error){
- pathName=(RegCStrPathName *) NewPtr(pathNameSize);
- if(pathName==NULL)error=MemError();
- }
- if(!error){
- error=RegistryCStrEntryToPath(&entry,pathName,pathNameSize);
- //printf("%s\n",pathName); // debugging
- }
- if(!error){
- // Found a video device
- strcpy(foundProperty,"driver-ref");
- propertySize=0;
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error){
- assert(propertySize==sizeof(driverRef));
- error=RegistryPropertyGet(&entry,foundProperty,&driverRef,&propertySize);
- if(!error && driverRef==(*device)->gdRefNum){
- done=TRUE; // we found the correct driver
- strcpy(foundProperty,"name");
- propertySize=0;
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error)error=RegistryPropertyGet(&entry,foundProperty,cardName,&propertySize);
- strcpy(foundProperty,"model");
- propertySize=0;
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error)error=RegistryPropertyGet(&entry,foundProperty,cardModel,&propertySize);
- propertySize=0;
- strcpy(foundProperty,"AAPL,slot-name");
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error)error=RegistryPropertyGet(&entry,foundProperty,slotName,&propertySize);
- // PCI slot names on Power Macintosh currently are of form : A1,B1,C1,D2,E2,F2
- }
- }else error=noErr; // there is a card but NO display attached (no open driver)
- }
- if(pathName != NULL)DisposePtr((Ptr) pathName);
- RegistryEntryIDDispose(&entry);
- }
- }
- RegistryEntryIterateDispose(&cookie);
- }
- return;
- #endif
- } /* GetVideoProperties */
-
- void GetCPUProperties(char *cpuName,long *cpuHz,Boolean *hasL2Cache)
- {
- #if NO_NAME_REGISTRY_LIB || !GENERATINGPOWERPC
- cpuName[0]=0;
- *cpuHz=0;
- *hasL2Cache=0;
- return;
- #else
- /*
- Assume we're running native on ppc.
- If this were compiled as 68k code, the calls to the NameRegistryLib, which is PPC code,
- would require intervention by the Mixed Mode Manager,
- and I decided not to bother with that complication, since there seems little point in
- compiling programs as 68k code to run on a PowerPC. TimeVideo is distributed as a fat
- binary, so it always runs native.
- */
- OSStatus error;
- RegEntryIter cookie;
- Boolean done;
- RegEntryIterationOp op;
- RegEntryID entry;
- RegCStrPathName *pathName;
- RegPathNameSize pathNameSize;
- RegPropertyNameBuf foundProperty;
- RegPropertyValueSize propertySize;
- long templong;
- char *propertyValue[256];
-
- cpuName[0]=0;
- *cpuHz=0;
- *hasL2Cache=0;
- {
- // If the NameRegistryLib is weak-linked, and it is missing, we need to
- // check for the library, to prevent a crash if we try to access the library's exports;
- // currently the Finder reports if the library is missing
- CFragConnectionID connID;
- Ptr mainAddr;
- Str255 errName;
-
- error=Gestalt(gestaltCFMAttr,&templong); // Code Fragment Manager?
- if(!error)error=GetSharedLibrary((ConstStr63Param)"\pNameRegistryLib"
- ,kAnyCFragArch,kFindCFrag,&connID,&mainAddr,errName);
- if(error)return; // No NameRegistryLib
- }
- error=Gestalt(gestaltNameRegistryVersion,&templong);
- if(error)return; // No PCI slots
-
- op=kRegIterContinue;
- error=RegistryEntryIterateCreate(&cookie);
- if(!error){
- done=FALSE;
- while (!error && !done){
- error=RegistryEntryIterate(&cookie,op,&entry,&done);
- if(!error && !done){
- pathName=NULL;
- error=RegistryEntryToPathSize(&entry,&pathNameSize);
- if(!error){
- pathName=(RegCStrPathName *) NewPtr(pathNameSize);
- if(pathName==NULL)error=MemError();
- }
- if(!error){
- error=RegistryCStrEntryToPath(&entry,pathName,pathNameSize);
- //printf("%s\n",pathName); // debugging
- }
- if(!error){
- propertySize=0;
- strcpy(foundProperty,"device_type");
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error)assert(propertySize<=sizeof(propertyValue));
- if(!error){
- error=RegistryPropertyGet(&entry,foundProperty,propertyValue,&propertySize);
- // Is it what we want?
- if(!error && strcmp("cpu",(char *)propertyValue)!=0)error=-1; // no
- }
- if(!error){
- strcpy(foundProperty,"clock-frequency");
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- }
- if(!error)assert(propertySize==sizeof(*cpuHz));
- if(!error){
- error=RegistryPropertyGet(&entry,foundProperty,cpuHz,&propertySize);
- }
- if(!error){
- strcpy(foundProperty,"name");
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- }
- if(!error)assert(propertySize<256);
- if(!error){
- error=RegistryPropertyGet(&entry,foundProperty,cpuName,&propertySize);
- }
- if(!error){
- strcpy(foundProperty,"l2-cache");
- error=RegistryPropertyGetSize(&entry,foundProperty,&propertySize);
- if(!error)*hasL2Cache=1;
- else *hasL2Cache=0;
- }
- error=0;
- }
- if(pathName != NULL)DisposePtr((Ptr) pathName);
- RegistryEntryIDDispose(&entry);
- }
- }
- RegistryEntryIterateDispose(&cookie);
- }
- return;
- #endif
- } /* GetCPUProperties */
-