TweetFollow Us on Twitter

Simple Porting
Volume Number:10
Issue Number:5
Column Tag:PowerPC Series

Related Info: Quickdraw

Simple Porting to The Power Mac

Runtime considerations and things you really want to know

By Chris Forden, Cupertino, California

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

About the author

Chris Forden is a Cupertino-based consultant who tested Power Mac system and application software for Apple prior to the Power Macintosh release. He is the principal author of Real Answer™, a shareware calculator and equation solver. He helped found ARSoftware and collaborates with them to advance ARC++, a superset of C++. Recently he has worked to connect Silicon Valley K-12 schools with engineers, scientists, and other community resources.

You can reach him at cforden@netcom.com or by phone at 408-255-4874, or 301-434-0949.

When Apple released the Power Macintoshes, it broke existing cost/performance barriers in desktop computer hardware. Simultaneously, Apple premiered many new, key software technologies that facilitate advanced and high performance applications. The high performance of the underlying PowerPC hardware will attract many users to the platform before most developers have learned to exploit the new software capabilities, or even do simple ports of their existing applications.

Despite wavering reviews in the Mac press about the relative performance of emulation mode on the Power Mac, few buyers will be disappointed in its speed, and knowledgeable critics will be impressed with its fidelity in imitating the behavior of the preceding 680x0 hardware. The Power Mac also will be a very attractive hardware purchase for users because it will run more major operating systems and user-interfaces than other platforms. For these and other reasons, the Power Mac will sell briskly.

The many buyers of these new machines will want to buy software that demonstrates and most fully exploits the awesome processing power of the hardware. By porting their existing 68K applications to native Power Mac code, Mac developers can often achieve radical speed increases over the performance of their 680x0 programs running in emulation mode. Especially attractive candidates for porting are programs that do many internal calculations to display complex graphics.

This article will discuss the pleasantly small number of changes developers must make to the execution-time behavior of their existing code to get their programs to execute successfully on the Power Mac in native mode. In particular, MixedMode will be examined. Sample code will be presented in the C language.

I have written this article “from the outside in”. By that I mean that it does not begin with a theoretical discussion of the underpinnings of the new RISC technologies, but rather with the simplest possible examples of how to change your source code so it runs on both the Power Mac and the 68K-based Macs. Then I discuss how the new programming style gets interpreted by MixedMode - the basic Power Mac software technology that will be most important early in its product life.

“From the outside in” also means that this article is intended for beleaguered Mac programmers who look upon the Power Mac with a mixture of trepidation and hope- hope that the new platform will bring strikingly new levels of speed and value to the user, but trepidation about possible new complexity in which programmers will be forced to immerse themselves. I hope to show that simple porting can be accomplished without a great deal of analysis done on the runtime environment of the new machine; the fear and loathing factor should be small.

For those readers who want a “from the inside out” discussion that explains the underlying technologies of the Power Mac, Apple has created an impressive array of literature. I also will leave to other authors the discussion of new development-tools that generate code for the Power Mac; as of this writing they are changing too rapidly for me to be of much help.

“Power” Nomenclature

The astute reader may notice that I use two different names - “PowerPC” on some occasions, and “Power Mac” on others. This dual nomenclature deserves some discussion. I have used “PowerPC” to refer to the 601 chip itself, its instruction set, and future, single-chip descendants of it, such as the low-power 603, more powerful 604, and full-64-bit 620. The antecedent of the 601 was a multiple-chip set that IBM called the “Power” architecture. Motorola and IBM documentation notes that the chip set had a slightly different instruction set, and many of the instructions it shares with the PowerPC had different mnemonic abbreviations.

Apple calls its new boxes “Power Macintoshes”, not “PowerPC Macintoshes”. That choice of wording does not imply that Apple is reverting to the older, more expensive IBM chip set. Instead, Apple presumably doesn’t want to market their computers as just “PC’s”. I use the term “Power Mac” to refer to a complete hardware and software system that includes not only the PowerPC chip, but also the major system software innovations that Apple has created to allow the new chip to function in a Macintosh that is compatible with previous Mac applications. I belabor this point because, as the marketing war heats up, the labels “Power” and “PowerPC” will be used in ways very different from their usage in instruction set documentation that we developers may read from time to time.

MixedMode

MixedMode is a new set of interfaces, structures, constants and built-in routines that allow Mac programmers to write source code that can jump back and forth between native execution on any given hardware platform and routines whose object code is in the instruction set of some other CPU. The Apple team who ported the Mac operating system and toolbox routines to the Power Mac used MixedMode extensively to minimize their task. Much of the previously written 68K code for the Mac OS and interface lives on in the Power Mac and executes on that new machine through the software emulator that translates 68K machine code instructions into PowerPC chip instructions as it runs them.

Because MixedMode is designed to support arbitrary combinations of hardware and emulated software instruction sets, the word “native” will become ambiguous sometime in the future. However, for the time being, when Mac programmers speak of “native” code they are speaking of object code compiled for and running on the Motorola/IBM 601 processor chip in the Power Mac. “Emulated” generally refers to 68K code running on the Power Mac. This article will always use those naming conventions.

For the next few years, MixedMode probably will be the most important feature of the Power Mac for Mac programmers to learn about. The efficiency of the emulator not only controls the performance of software running in emulated mode, but also influences the performance of native code. That is because some of the Toolbox code called by a native application will be 68K object code executed by the emulator. More importantly, MixedMode interfaces are the pathways through which the programmer directs the transitions between native and emulated modes. If you are porting your existing Mac application to native Power Mac, there will be two likely circumstances in which you will need to invoke header interface declarations created for MixedMode:

1. You have large sections of 68K assembly language code that you don’t want to translate into portable C. By invoking your routine through the MixedMode mechanisms, you can allow your 68K object code to run under emulation mode on the Power Mac. Bear in mind that you will suffer an approximately 5:1 performance degradation due to the emulation. (Apple engineers have been careful to port the speed-critical parts of the Toolbox to native code. They have left much code in its original 68K state, but only that code that is not frequently called or does not greatly affect the user’s perception of over-all system responsiveness.)

2. You need to pass to the Mac Toolbox, a ProcPtr to one of your callback routines. An example of a callback is the filterProc needed to imbue a dialog box with responsiveness not inherent in the ToolBox’s standard modal dialog box behavior. For instance, some applications allow users to select a button label in a modal dialog box by typing the first letter of its label instead of forcing the users to use only the mouse. Such an application creates its own, customized ModalDialog filterProc and passes a pointer to it as a parameter in its call of ModalDialog(). When the user responds to the dialog box, the Mac Toolbox will “call the custom filterProc routine back” to let it do its thing with the user event. We will shortly analyze how that callback ProcPtr gets declared, created, and passed in Power Mac code. Other examples of commonly used callbacks are TrackControl (necessary for scroll bars and other controls) and WordBreak (to customize TextEdit’s conception of where one word ends and another begins).

It should be obvious why some special mechanism must be established to handle the first case (unported 68K assembly code) listed above. Suppose the 601 chip in the Power Mac is happily chugging along, fetching and executing its own type of instructions and suddenly runs into 68K instructions. Those instructions make no sense at all to the 601 processor, so an exception is virtually guaranteed to occur within a few instructions and bring execution to a halt. (That exception is a good thing, because the alternative would be for the 601 chip to begin moving and writing data in haphazard locations; that could be worse than just program termination.) The programmer uses MixedMode to control which instruction set architecture attempts to execute a given chunk of code, and MixedMode makes sure that the appropriate protocol conversion takes place. MixedMode has you tell it where parameters are, where they should go, where to put results. MixedMode takes care of getting them into the right place, and getting results back to the caller.

It is less obvious why the callbacks mentioned in the second case should always be written with the MixedMode mechanisms. The reason is that much of the Macintosh Toolbox on the Power Mac will be emulated. If the software emulator were to branch to your subroutine written in native PowerPC code, it would try to interpret what it encountered as 68K instructions; the same sort of unpredictable program crash would soon happen. So, for callbacks, you should explicitly use MixedMode to tell the emulator that the routine about to be encountered contains native PowerPC code.

How do you use MixedMode to give those mode-change warnings? Apple has scattered MixedMode callback declarations throughout the new C header files. Those declarations substantially ease your job as a programmer in explicitly controlling the entry and departure from emulated mode. Take the previously mentioned filterProc passed to ModalDialog() for example. You used to just pass ModalDialog() the name of your filter procedure like this:

ModalDialog(myFilterProc, &itemHit);

From now on you should declare a pointer to your filter procedure like this:


/* 1 */
ModalFilterUPP myModalFilterUPP;

(“UPP” stands for “Universal ProcPtr”.) Then you should set that pointer at runtime to point indirectly to your filter procedure by executing this statement:


/* 2 */
myFilterProcUPP = NewModalFilterProc(myFilterProc);

Then you can call ModalDialog() in a way very similar to the way you used to:


/* 3 */
ModalDialog(myFilterProcUPP, &itemHit);

If you can follow the above example, you probably already know enough about the runtime environment of the Power Mac to do a simple port from the 68K Mac to the Power Mac if your app is written in C. Do a global search for “ProcPtr” in your source code. Make sure that the search’s “Entire Word” option is not checked because some recent headers use more specific names ending in “ProcPtr”. Such a search will identify almost all the callbacks that need to be redeclared and given additional runtime support for MixedMode. You can find the new “UPP” declarations in the header file for the relevant Toolbox Manager. That header file also will declare the routine to which you pass your callback ProcPtr. In the example we have just covered here, the relevant declarations were found in Dialogs.h.

I believe Apple has made the transition to the Power Mac easy from both a user’s and a programmer’s standpoints. One of the nice things they have created is a new, universal set of headers that when used, allows the same source code to compile for either the 68K Mac or the Power Mac. In the example above, when compiled for the 68K-based Mac, the new type, ModalFilterUPP, gets #defined to be just a ModalFilterProcPtr. Then NewModalFilterProc() gets #defined as a macro to be just a pointer cast expression. When compiling for the Power Mac however, the name “USESROUTINEDESCRIPTORS” gets defined and that forces a different set of macros in the universal headers to be used during preprocessing. Here is the relevant excerpt from the new Dialogs.h:


/* 4 */
#if USESROUTINEDESCRIPTORS
typedef UniversalProcPtr ModalFilterUPP;

#define CallModalFilterProc(userRoutine, theDialog,      \
  theEvent, itemHit) \
 CallUniversalProc(userRoutine, uppModalFilterProcInfo, \
 theDialog, theEvent, itemHit)

#define NewModalFilterProc(userRoutine)\
 (ModalFilterUPP) NewRoutineDescriptor(userRoutine,            
 uppModalFilterProcInfo, GetCurrentISA())
#else
typedef ModalFilterProcPtr ModalFilterUPP;

#define CallModalFilterProc(userRoutine, theDialog,      \
  theEvent, itemHit) \
 (*userRoutine)(theDialog, theEvent, itemHit)

#define NewModalFilterProc(userRoutine)\
 (ModalFilterUPP)(userRoutine)
#endif

As you can see above, when compiling for the Power Mac, ModalFilterUPP gets typedef’d to be a (generic) UniversalProcPtr. NewModalFilterProc() gets #defined as a specialized call of NewRoutineDescriptor(), an actual new Toolbox trap that executes at runtime to enable the Power Mac to integrate pieces of code that had been compiled into different machine-language instruction sets.

Now you are probably wondering what UniversalProcPtr’s are and what NewRoutineDescriptor() does at runtime. Good. Fortunately, both have names that suggest their true role in life. We use a UniversalProcPtr to (indirectly) point to a routine when we know that a routine will require a processing mode switch, i.e., that its instruction set is different from that of the routine that calls it. We also use UniversalProcPtr’s when we don’t know whether a mode switch will be necessary or not. (That possibility arises when interacting with Mac Toolbox code that may or may not have been ported to native code on the machine upon which your app is executing.)

As you can read in the above header fragment, when we call NewModalFilterProc() at runtime on the Power Mac, we end up calling NewRoutineDescriptor(). That means we build a Routine Descriptor at runtime. A Routine Descriptor is a structure in memory that (not surprisingly) describes a routine that is just about to be executed. It also alerts the processor or emulator that a mode switch may be about to occur. When a subroutine is called from emulated code through a UniversalProcPtr, the Power Mac’s emulator initially treats the Routine Descriptor as executable code. The first element in the Routine Descriptor is in fact a trap word - 0xAAFE, _MixedModeMagic. When the emulator hits that trap, it stops treating the Routine Descriptor as code, and instead examines the data in it. Here are the structure definitions from MixedMode.h, beginning with RoutineRecord, a data structure that is a member of RoutineDescriptor:


/* 5 */
struct RoutineRecord {
 ProcInfoType    procInfo;
 char   reserved1;
 ISATypeISA;
 RoutineFlagsTyperoutineFlags;
 ProcPtrprocDescriptor;
 unsigned long   reserved2;
 long   selector;
};

 

struct RoutineDescriptor {
 unsigned short  goMixedModeTrap;  /*0xAAFE*/
 char   version;
 RDFlagsTyperoutineDescriptorFlags;
 long   reserved1;
 char   reserved2;
 char   selectorInfo;
 short  routineCount;
 RoutineRecord   routineRecords[1];
};

Routine Descriptors provide needed information when switching the processing mode in either direction- both from emulated to native mode (as the above callbacks required), and also from native to emulate mode. In fact, Apple has taken care to make MixedMode very general; it may someday enable your Mac application to run on other processors.

RoutineDescriptor.RoutineRecord has as one of the first data elements a field that MixedMode examines is the ISAType sub-member. That tells which instruction set architecture (ISA) the routine to be executed is written in. If the instruction set is the same as that currently executing, most of the rest of the mode-switch process can be skipped, and the processor can jump to the executable code pointed to by the ProcPtr data sub-element nested inside the Routine Descriptor. Of more interest to us for this discussion however, is the case where the execution mode changes. In the ModalDialog callback example mentioned above, the Routine Descriptor we built for our ModalFilter callback routine directs the emulator to disengage and let the PowerPC chip execute myFilterProc in the 601’s native instruction set. At present, we can be sure that the emulator had been in operation because we know that the code for ModalDialog() has not been translated from 68K code to PowerPC code yet.

If you can be sure that a calling routine and its callee will both be in the same object instruction set, you can make the call directly, without need of Routine Descriptor. The universal headers make that happen when you compile for the 68K Macs. Note that you must control the source of both the caller and the callee; don’t allow direct branching between your code and someone else’s code. For instance, it may be tempting to keep some of your callback routines as 68K code, so that no processing mode switch will be necessary at runtime; the emulated Toolbox in ROM simply would branch to your emulated 68K code in your callback routine. Don’t succumb to that temptation; sometime in the future, the Mac Toolbox code that is now 68K object code on the Power Mac, and executed via the emulator, may get rewritten in C and recompiled into native PowerPC object code. At that time any apps that took such a shortcut will break.

You also may notice the presence of “CallUniversalProc” (and specific derivatives of it, e.g., “CallModalFilterProc”) in the new headers. Those are used for the less frequently encountered case when one wants to call a callback routine supplied by someone else and that routine might be written in a different kind of object code than the one presently executing. Clark and Mattson’s article in March, 1994, Vol. 10, No. 3, p. 80, gives a recommended discussion of their use.

Concerned about a build-up of Routine Descriptors that never get deallocated? In practice, the number of routines that need Routine Descriptors is not only finite, but small. When your program starts up you can allocate one Routine Descriptor for each callback or other routine that might cause an emulation transition. You never have to explicitly deallocate them; they will just disappear with the rest of your application heap when your program terminates.

Now what about the case where you have sections of 68K assembly code? Apple and I recommend that you convert such sections to C or C++. It is very tedious to manually create optimized PowerPC assembly language that matches the efficiency of code that the compilers for the PowerPC can produce. A major reason for that is that to achieve maximum time efficiency, one must carefully interleave different types of instructions so that the RISC processor can execute several concurrently. I can personally confirm that writing such assembly code by hand is a major mind-bender and time-sink for programmers. Once you leap to C or C++, on the other hand, you may be able to more easily port to other platforms as well. However, for those who really want to run large blocks of 68K code on the Power Mac and integrate them with native routines, MixedMode and the Code Fragment Manager provide ways of doing so, although I will not discuss them here.

Unification of Calling Conventions

When the Mac was first created, it was not possible to interact with all the low-level ToolBox functionality from high-level languages. Some help has been added over the intervening years to allow high-level language access to some of the low-level ToolBox details. The new, universal headers that Apple created for the Power Mac complete that process. Now virtually all the documented ways one can use the ToolBox can be done through techniques that the C headers coherently document and implement. As a result, advanced Macintosh programming is now that much easier.

Passing program control to and from ToolBox routines used to be done through several incompatible assembly language conventions, depending on the part of the ToolBox being used. Many routines that used non-standard calling setups were callback routines. One example would be wordBreak(), a procedure that defines the boundaries of words. It determines the boundaries at which double clicking selects just one word, and the letters at which text wraps around inside a window or text box, so that no words are broken in the middle. Every Text Edit Record (TERec) contains a pointer to a WordBreak() procedure. It can select the standard Mac WordBreak(), or you can set the pointer to your own wordBreak() procedure. The procedure pointed to by the TERec’s WordBreak parameter receives its parameters in A0 and D0 and returns its result in the Z bit of the Condition Code Register. Since those are not the standard parameter-passing conventions for subroutine calls, you cannot just write wordBreak() in C or Pascal and then assign its address into the wordBreak field of your TERec (despite the fact that Think Reference 2.0.1 says that you can). As a high-level language programmer you need to do one of two things on 68K Macs to get correct operation of any wordBreak procedure you write:

1. You can create some assembly-language glue to shuffle the values from the registers to the stack and back, or

2. You can call TESetWordBreak to install a pointer to a translation routine into your TERec’s wordBreak field. That protocol conversion routine will call your WordBreak() procedure. (TESetWordBreak() used to be called “SetWordBreak()”, but the new routine FindWordBreaks() has recently somewhat outmoded TESetWordBreak().)

After you compile your code for Power Macintoshes, MixedMode does the necessary protocol conversion (moving parameters to conform to the right runtime conventions) for you. Suppose you have written a routine called myWordBreak() and included it in a source file for compilation into native PowerPC code. Here is the way you should use the universal headers to get the subroutine called properly:


/* 6 */
TESetWordBreak(NewWordBreakProc(myWordBreak));  /* Preferred style */

A direct assignment into the TERec’s wordBreak field allegedly also now will work, but that is not recommended because it may break in some future version:


/* 7 */
/* Politically Incorrect alternative that might work for now! */
myTERec.wordBreak = NewWordBreakProc(myWordBreak);  
Let’s look at NewWordBreakProc(), which is a macro in the new TextEdit.h:

#define NewWordBreakProc(userRoutine)  \
 (WordBreakUPP) NewRoutineDescriptor((ProcPtr)userRoutine, \   uppWordBreakProcInfo, 
GetCurrentISA())

GetCurrentISA() is a macro defined in MixedMode.h that at compile time gets replaced by a number corresponding to the expected target native hardware. In this example, since we are compiling for the PowerPC, GetCurrentISA() gets replaced by “kPowerPCISA”, then the number 1 by the preprocessor. TextEdit.h has defined uppWordBreakProcInfo by compounding other macros into certain bit fields:


/* 8 */
uppWordBreakProcInfo = kRegisterBased|REGISTER_RESULT_LOCATION(kCCRegisterZBit) 
|REGISTER_ROUTINE_PARAMETER(1,kRegisterA0,3) |REGISTER_ROUTINE_PARAMETER(2,kRegisterD0,2)

The net result of the nested macros is to define uppWordBreakProcInfo as a certain bit pattern that describes the register calling conventions of the 68K wordBreak(). That bit-pattern gets stuffed into the procInfo field nested inside the routine descriptor created by NewWordBreakProc. When the 68K emulator jumps to the subroutine described by that descriptor, the contents of the emulator’s registers A0 and D0 are placed in the PowerPC native registers R3 and R4, the registers in which Power Mac native routines receive the two parameters. After the native wordBreak routine executes, its return value is placed in the Z bit of the Condition Code Register of the 68K emulator. The emulator then jumps back to the 68K code that called myWordBreak().

This methodology has permitted the Apple Power Mac software team to retain the 68K assembly language version of TextEdit for the time being. In the future, TextEdit may get translated into C and compiled into native PowerPC code. When our previously compiled code runs on that future Power Mac, the same routine descriptor we have described here will tell the system to stay in PowerPC native execution mode, and the register translation sequence will be skipped.

The use of the routine descriptor has not only eased Apple’s port of the Mac Toolbox, but it also has given the application programmer a new way of interfacing high level language callback routines to the 68K assembly-language calling conventions. For the wordBreak() example given, that was not very important, because of the availability of the SetWordBreak() routine. However, there are many callback routines that have no automatic way of interfacing the 68K assembly-language call conventions to high-level languages. For those, 68K Mac programmers were forced to write their own assembly-language glue. Examples of such Toolbox traps are the CaretHook and HighHook routines which allow custom insertion point drawing and highlighting; and those are just from the TextEdit manager. Now Power Mac programmers can always use MixedMode declarations and calls to do that interfacing. We no longer are forced to write any assembly language.

Globals

The Power Mac has several other features that ease the programmer’s life. One biggie: the application globals are always automatically available to the program. That means that you don’t have to worry about setting up A5 during completion and interrupt routines. Well, maybe that’s a slightly too broad generalization. Since some things need to make reference to well-known storage which is relative to A5, the emulator needs to have its emulated version of register A5 set up for those things.

There is one minor change you must make to your code to accommodate the new way the Power Mac handles globals; you must explicitly declare a global QDGlobals struct for your app’s QuickDraw globals to reside in, then do an InitGraf() on their port. On the old Mac, the QuickDraw globals were always referenced from A5 in the same way, so the compiler knew about them implicitly, and QuickDraw.h declared qd. In native PowerPC code, they are just another global struct that you get to declare for yourself. Here is how to set them up now:


/* 9 */
QDGlobals qd;
 
void main(void)
{
 
 InitGraf((Ptr) &qd.thePort);
 screenRect = qd.screenBits.bounds;
 
/*  Maybe you want your program to actually DO SOMETHING.
 In that case you should probably put some code here.  */
}

For a long time Apple has discouraged directly accessing low memory globals. In particular Apple has discouraged access of those low-memory globals not described in Inside Mac nor included in their official assembly files. Apple has provided an alternative to directly accessing the documented (public) low memory globals; the header file LowMem.h declares accessor functions. Now that these are available, use LowMem.h instead of SysEqu.h. In the first release of the Power Mac system software, all the public and private low memory globals actually exist in low memory, so old code that accesses them directly will still work (for a while longer). In fact, on 68K Macs now, if you use the accessor functions, they just get #defined by macros in LowMem.h to be direct memory accesses. It still is greatly preferable to use the accessor function forms in your code; when direct low-memory access finally breaks on some future Mac, you will only need to recompile, not rewrite your source code. If you do the right thing and use the accessor functions on the Power Mac, you’ll wind up using a shared library to get to low memory. Is that good? You bet it is. If Apple changes the rules about low memory, they can simply install a new shared library, and your program continues to work with no additional effort on your part.

Execution Speed

68K code runs about 4 to 5 times slower than native code on the PowerPC. (It’s interesting to note though, that 68K code is about twice as compact as PowerPC code; RISC machines generally suffer increased program size to achieve faster execution.) Every time a mode switch is made into or out of emulated mode, many hundred machine instructions get spent setting up and preserving the context of the emulator. If there is an extension in the system folder that patches a common trap call with 68K code, it may cause a substantial slow-down in performance because whenever that trap or any trap that calls it gets called, two additional context switches get executed. If that happens for every pixel in a drawing routine, for example, that adds up to a lot of machine cycles. Therefore if you have a 68K extension that installs a patch in a frequently called trap chain, you should create a native version. Or you can create a fat version. Fat versions contain both 68K and native PowerPC code and can run optimally on either kind of Mac. Space limitations preclude programming information about fat apps, resources, and patches in this article, however.

The PowerPC brings substantially faster execution of almost any code when converted to native code. However, it is particularly fast at executing floating-point instructions. That is important because many tasks that push the envelope of existing CPU technology can benefit from faster floating-point. In particular, animated 3D graphics and digital audio processing (for speech synthesis and recognition) have been beyond the reach of satisfactory performance from previous 68K CPU chips, but can be done on the PowerPC. Apple is including with each Power Mac a wonderful demo program, the Graphing Calculator, that showcases the PowerPC’s capability to animate 3D graphics. (My praise is not entirely unbiased; I provided software quality assurance for the Graphing Calculator.)

Clever programmers of 68K Macs have done the fastest calculations with integer arithmetic. For instance, the calculation of screen position of 2D CAD objects can be done quickest using the long (32 bit) integer arithmetic available on the 68020 and better. (The FixMath routines in those machines’s ROM automatically make use of the extended instructions.) Some programmers were even willing to put up with the aggravation of doing all the worst-case analyses of overflow and underflow needed to use fixed-point math routines reliably.

However, on the PowerPC, the floating point performance is so much improved that now you get faster execution by using floating point routines than by using fixed point arithmetic. Why? Because there are lots of cases where you would need to take precautions against overflow error or precision loss due to underflow. Those two enemies of integer arithmetic - overflow and underflow - ravage more fixed point math schemes than programmers expect a priori. Therefore calculating with floating point is generally much easier than adapting fixed-point arithmetic to one’s needs.

So how much faster is floating point? A friend of mine timed various implementations of an FFT-based image processing algorithm running on several Mac platforms. Here are his results tabularized, including single precision floating point, for a one-way 512 x 512 FFT:

IIci w/cache Power Mac proto

integer 52 sec 14.5 sec

single float 80 sec 3 sec

Integer arithmetic on the Power Mac prototype was about the same as the Quadra 840AV’s, but single precision float on the Power Mac was 4.5 times faster than the faster (integer with special long mul assembly) arithmetic on 840av. We were using a bottom-of-the-line Power Mac prototype, running at only 50 MHz.

Double-precision floating point on the PowerPC is only 0% to 20% slower than single-precision floating point. The 64 bits of the double-precision format mean you have great freedom from precision loss. The PowerPC also has a multiply-and-add instruction, often called “multiply and accumulate”. It combines a multiplication and an addition into a single instruction. Many signal processing programs for audio or images can make heavy use of that instruction, which optimizing compilers automatically generate when appropriate.

Note that the Power Mac’s emulator does not emulate 68881 FPU instructions. 68K code that contains floating point processor instructions for 68K floating point hardware and simply assume the presence of an FPU, will generally crash. You should always check for the presence of something like an FPUwith Gestalt before requiring it.

Reliability

How reliable is the Power Mac software? Most observers regarded the introduction of System 7 as a very successful introduction of impressively reliable software. I believe that the Power Mac software is even better. I worked at Apple on a six month contract testing parts of the Mac Toolbox interface on the Power Mac. I found the Power Mac software to be more reliable than the standard System 7 software. In other words, when I found a bug in the operation of system software on the Power Mac, usually it merely duplicated exactly an existing obscure bug on 68K Macs. Some beta-test users have made the same remark. This was in the summer and fall of 1993, six months before planned introduction of the Power Mac. Rare is the computer product that achieves such stability so long before market introduction.

Summary

The new MixedMode Manager allows the Power Mac to run applications and system software pieces that are native PowerPC object code, unconverted 68K code, or combinations of both types of code. Let’s briefly review the reason for MixedMode. If the PowerPC were to try to execute any 68K code directly, it would immediately crash. The basic function of MixedMode is to preface any at-risk block of object code with a special signal that invokes the proper processing mode and move parameters from where they are to where they need to be. Here, “at-risk” refers to blocks of code that either might require an emulation mode switch, or certainly will require such a mode switch.

The PowerPC chip has brought tremendous speed improvements which will greatly benefit processor-intensive tasks such as audio/video processing and complex graphics. The processing power of the new chip and the appearance of compilers which produce code optimized for the chip's pipelined processor have eliminated the advantage of programming in assembly language. Apple’s new interfaces enable the programmer to access every aspect of the Macintosh Toolbox and System directly through a high-level language. A richer, more uniform runtime environment provides automatic access to an application’s global variables at interrupt and completion time. The dawn of a new era of hardware power thereby also frees software writers from the need to concentrate on low-level details and empowers them to pursue their goals with tools and system support that let them concentrate on the tasks at hand.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Tokkun Studio unveils alpha trailer for...
We are back on the MMORPG news train, and this time it comes from the sort of international developers Tokkun Studio. They are based in France and Japan, so it counts. Anyway, semantics aside, they have released an alpha trailer for the upcoming... | Read more »
Win a host of exclusive in-game Honor of...
To celebrate its latest Jujutsu Kaisen crossover event, Honor of Kings is offering a bounty of login and achievement rewards kicking off the holiday season early. [Read more] | Read more »
Miraibo GO comes out swinging hard as it...
Having just launched what feels like yesterday, Dreamcube Studio is wasting no time adding events to their open-world survival Miraibo GO. Abyssal Souls arrives relatively in time for the spooky season and brings with it horrifying new partners to... | Read more »
Ditch the heavy binders and high price t...
As fun as the real-world equivalent and the very old Game Boy version are, the Pokemon Trading Card games have historically been received poorly on mobile. It is a very strange and confusing trend, but one that The Pokemon Company is determined to... | Read more »
Peace amongst mobile gamers is now shatt...
Some of the crazy folk tales from gaming have undoubtedly come from the EVE universe. Stories of spying, betrayal, and epic battles have entered history, and now the franchise expands as CCP Games launches EVE Galaxy Conquest, a free-to-play 4x... | Read more »
Lord of Nazarick, the turn-based RPG bas...
Crunchyroll and A PLUS JAPAN have just confirmed that Lord of Nazarick, their turn-based RPG based on the popular OVERLORD anime, is now available for iOS and Android. Starting today at 2PM CET, fans can download the game from Google Play and the... | Read more »
Digital Extremes' recent Devstream...
If you are anything like me you are impatiently waiting for Warframe: 1999 whilst simultaneously cursing the fact Excalibur Prime is permanently Vault locked. To keep us fed during our wait, Digital Extremes hosted a Double Devstream to dish out a... | Read more »
The Frozen Canvas adds a splash of colou...
It is time to grab your gloves and layer up, as Torchlight: Infinite is diving into the frozen tundra in its sixth season. The Frozen Canvas is a colourful new update that brings a stylish flair to the Netherrealm and puts creativity in the... | Read more »
Back When AOL WAS the Internet – The Tou...
In Episode 606 of The TouchArcade Show we kick things off talking about my plans for this weekend, which has resulted in this week’s show being a bit shorter than normal. We also go over some more updates on our Patreon situation, which has been... | Read more »
Creative Assembly's latest mobile p...
The Total War series has been slowly trickling onto mobile, which is a fantastic thing because most, if not all, of them are incredibly great fun. Creative Assembly's latest to get the Feral Interactive treatment into portable form is Total War:... | Read more »

Price Scanner via MacPrices.net

Early Black Friday Deal: Apple’s newly upgrad...
Amazon has Apple 13″ MacBook Airs with M2 CPUs and 16GB of RAM on early Black Friday sale for $200 off MSRP, only $799. Their prices are the lowest currently available for these newly upgraded 13″ M2... Read more
13-inch 8GB M2 MacBook Airs for $749, $250 of...
Best Buy has Apple 13″ MacBook Airs with M2 CPUs and 8GB of RAM in stock and on sale on their online store for $250 off MSRP. Prices start at $749. Their prices are the lowest currently available for... Read more
Amazon is offering an early Black Friday $100...
Amazon is offering early Black Friday discounts on Apple’s new 2024 WiFi iPad minis ranging up to $100 off MSRP, each with free shipping. These are the lowest prices available for new minis anywhere... Read more
Price Drop! Clearance 14-inch M3 MacBook Pros...
Best Buy is offering a $500 discount on clearance 14″ M3 MacBook Pros on their online store this week with prices available starting at only $1099. Prices valid for online orders only, in-store... Read more
Apple AirPods Pro with USB-C on early Black F...
A couple of Apple retailers are offering $70 (28%) discounts on Apple’s AirPods Pro with USB-C (and hearing aid capabilities) this weekend. These are early AirPods Black Friday discounts if you’re... Read more
Price drop! 13-inch M3 MacBook Airs now avail...
With yesterday’s across-the-board MacBook Air upgrade to 16GB of RAM standard, Apple has dropped prices on clearance 13″ 8GB M3 MacBook Airs, Certified Refurbished, to a new low starting at only $829... Read more
Price drop! Apple 15-inch M3 MacBook Airs now...
With yesterday’s release of 15-inch M3 MacBook Airs with 16GB of RAM standard, Apple has dropped prices on clearance Certified Refurbished 15″ 8GB M3 MacBook Airs to a new low starting at only $999.... Read more
Apple has clearance 15-inch M2 MacBook Airs a...
Apple has clearance, Certified Refurbished, 15″ M2 MacBook Airs now available starting at $929 and ranging up to $410 off original MSRP. These are the cheapest 15″ MacBook Airs for sale today at... Read more
Apple drops prices on 13-inch M2 MacBook Airs...
Apple has dropped prices on 13″ M2 MacBook Airs to a new low of only $749 in their Certified Refurbished store. These are the cheapest M2-powered MacBooks for sale at Apple. Apple’s one-year warranty... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, now available for $679 for 8-Core CPU/7-Core GPU/256GB models. Apple’s one-year warranty is included, shipping is free, and each... Read more

Jobs Board

Seasonal Cashier - *Apple* Blossom Mall - J...
Seasonal Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Seasonal Fine Jewelry Commission Associate -...
…Fine Jewelry Commission Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) Read more
Seasonal Operations Associate - *Apple* Blo...
Seasonal Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Read more
Hair Stylist - *Apple* Blossom Mall - JCPen...
Hair Stylist - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.