ADC Home > Reference Library > Technical Notes > Legacy Documents > Mac OS 9 & Earlier >
Legacy Document
Important: This document is part of the Legacy section of the ADC Reference Library. This information should not be used for new development.
Current information on this Reference Library topic can be found here:
|
1. Write in ANSI C or C++This is a bit of a religious issue. There are some people who I have heard say that they will be dead and cold before their assembler can be taken from their fist. Unfortunately, assembly code is very hard to port to new CPUs and Pascal is falling out of favor with the people inside of Apple who make the Macintosh compilers and write system software. It is very likely that Pascal will continue to be supported by third-party developers, but the Macintosh Operating System is slowly being converted to C and C++. In making this conversion, the special features of C are being used. As a result, Pascal programmers and compiler writers will need to think in C and make the appropriate conversions of the data and function calls to connect the C conventions with those of Pascal. Religious or not, the Macintosh Operating System is being written in C and C++ and to make sure that your code is more compatible with our system, we recommend that you learn to love C. If you make the investment now you are assured the easiest transition possible to new platforms. Besides, it is also very hard to make hand-tuned assembly that is better than code produced by a good optimizing C compiler, especially on RISC-type machines. You should take full advantage of the features ANSI C provides. For example,
you should turn on compiler options to require prototypes and make sure that all your own
functions have prototypes. Be aware that use of "old style" function definitions in MPW C
will defeat prototype checking. For example, the following definition of
To get the most out of prototyping, you must always use "new style" function declarations and definitions:
Do not assume the C compiler understands Pascal calling conventions. In particular, do not assume the C compiler will automatically pass toolbox structures larger than 4 bytes by reference; do it yourself. Never use the type Using direct functions in MPW C or inline assembly in Think C is often unavoidable with the current Toolbox, but it is not portable. You should isolate and conditionalize such code. If you write assembly routines for performance reasons, considering writing a C version, for portability, at the same time you write the assembly version. 2. Align Data StructuresThe Motorola 68K microprocessors have always been very tolerant of misaligned data structures, but modern, cached computer architectures don't like having to support misaligned data structures. Chances are that the microprocessors that Apple uses in its CPUs will continue to support misaligned data structures, but you will probably find that applications will run considerably faster if the data structures are aligned. This is already the case in the 68040, and it will become more and more important in the future. So if your structure declarations look something like:
Then you may want to change them to look more like:
The problem with the first example is that the long field 3. Don't Depend on 68K Run-time Model (Stacks, A5, Segmentation...)The 68K run-time model contains many features that are extremely machine dependent (such as A5 worlds) or don't make sense in a modern operating system (such as segmentation). Such features should continue to work in a 68K environment, but when you port code to other platforms, assumptions you make about the run-time environment may no longer be valid. Beware of the assumptions made in the following areas:
4. Isolate and Minimize Use of Low MemoryFor as many years as the Macintosh has been shipping there have been applications that have depended on direct access to low-memory globals. Apple has said for a long time that developers must not depend on these global variables, but unfortunately there are many cases where applications must access these variables to function. Shared low memory is one area we must wean developers from before we can provide modern features like protected address spaces and preemptive multitasking. Low-memory usage falls into three categories:
Because many applications depend on low memory, we can't just pull the rug from under you because every application would break. So, what's a developer to do? Isolate and minimize your dependence on low memory. If accessor functions exist, you should use them. For example,
Eventually, Apple will provide a new API that will include accessor functions
for documented low-memory globals and you should use those when available. In the meantime,
you might consider using macros to do the same thing. For example, to access
This at least lets you isolate dependencies on 5. Isolate and Minimize Use of Internal Toolbox Data StructuresIf it isn't documented, don't use it. The data structures that are not documented aren't documented because we expect they may change in the future. This means that if your application is dependent on any internal data structures never changing, then it is very likely that your product will break in the future. There are some major changes being considered for the Macintosh Operating System and any major change will include the internal data structures, so beware of any undocumented features on which you depend. 6. Don't Intermix Data and CodeIt will make it easier for the Operating System to move to a memory protection model if code does not write to itself. The issue is not just writing instructions into a code segment (that is, self-modifying code), but writing data into the segment. A robust operating system write-protects code segments, but Apple can't provide that benefit to applications that depend on writing to their code segments. The restriction does not apply to static, read-only data stored in code segments. For example, if you store strings in your code segments, but never modify them, this is not a problem. 7. Isolate Dependencies on 80 and 96-bit ExtendedDifferent FPUs are going to have different preferred formats. On 68K, extended offers the best precision as well as the best performance and is therefore the "natural" choice. On other platforms, this may not be the case, so you should be prepared to take these differences into account. For most of you this is not a problem, but it does mean there may be differences in the size of fields in data structures and on disk, as well as in the size of parameters passed to functions. You should try to isolate and avoid dependencies on the size of floating-point numbers. For some developers there is an issue with the perception that your applications need very high precision. There are cases where extended number precision is very useful (such as 3-D and CAD), but it is possible to make a fully 3-D graphics application that does not need extended numbers. If you find that you can not live without extended numbers, then you may find that you will need to live with slow calculations. 8. Don't Depend on Interrupt Level or Supervisor ModeInterrupt levels, supervisor mode, and exception handling are all very dependent on the microprocessor that is being used in the computer your code is running on. If your code thinks that it knows how to manipulate the hardware and system in supervisor mode, then it will find that it is wrong on the next generation of microprocessors. If you think your code can alter the interrupt levels, then once again you will be sadly mistaken. If your code changes the exception handlers, then your code is too dependent on the hardware on which it is running and will more than likely break on Apple's future products. Many applications also assume they can lock out interrupts for long periods of time. Doing so will break input/output on future systems. You should do only the most critical tasks with interrupts locked out and then only for the shortest possible time. You can also use the Deferred Task Manager to handle some interrupt level processing at a later time when there are no pending interrupts. One common violation of supervisor mode is the use of privileged instructions. In practice, because of compatibility reasons, some instructions may be emulated, but you should not rely on that fact. The following are the only privileged instructions that are likely to be supported in the future. Other privileged instructions will likely cause Illegal Instruction exceptions.
Notes:
9. 32-bit Clean MandatoryApple has been saying for many years that all applications need to be able to run in a 32-bit address environment. Not only is this important because it allows users to take full advantage of the memory of the machine, but it allows Apple to transition from one memory model (24-bit) to another memory model (32-bit). Supporting two different memory models has allowed Apple to maintain compatibility, but the cost has been a lot of extra code in the ROM and some performance penalty. So now we're preparing to take the next step--32-bit only addressing. Most developers have by now removed any dependency on a 24-bit environment, but some developers have cheated a bit. Rather than making use of the upper 8-bits of an address they use the upper bit, on the assumption (valid for the most part) that everything happens in the lower 2 gigabytes of the 4 gigabyte address space. In other words, they are only 31-bit clean. This is very bad as future operating system releases will take full advantage of the 4 gigabyte range of addresses. The message is, not only will we be 32-bit only, but we really mean 32-bit. 10. Don't Hit the Hardware DirectlyApple has warned developers for a long time to lay off the hardware. You should
always access hardware indirectly, through a manager or driver. For example,
some applications persist in generating sound by accessing the old sound buffer
pointed to by the We realize developers sometimes feel they need to access the hardware directly to squeeze the most performance out of the machine. But doing so severely limits Apple's ability to advance the hardware platform and it hurts customers in the long run because your applications break when new hardware is released. Think twice before accessing the hardware directly. The pain will probably outweigh the gain. 11. Don't Directly Patch the ROMDo not access the trap tables directly. Use Below is a sample of the correct way to patch a trap. This code is from the 7.0 sample for making an INIT/cdev.
An alternate piece of sample code that works very well for Think C follows:
12. Don't Depend on Resources Being in the System FileIn a future version of the ROM we plan to put parts of System 7 into the ROM. This means that if you expect to see a resource in the System file, then you may find yourself in trouble. Some System 7 resources and packages will soon reside in the ROM. To specifically request resources from the ROM, you must set the low-memory global RomMapInsert (Inside Macintosh Volume VI, page VI-19) as follows:
If you want to search both the system file and the ROM for a resource, you can
use 13. Don't Make Assumptions About the Contents and Size of ROMThe current Quadra ROMs are 1 megabyte in size. As we add portions of System 7 to ROM, they will grow even bigger. Not only will they grow, but things will be rearranged in the ROM. Don't assume you know the layout or location of entry points in the ROM. If you're dependent on knowing the ROM version number you may break on future ROMs. 14. SCSIThere are some things that you should already know about SCSI, but it is important to reiterate some potential problems that you may have already experienced and probably will continue to see in the future. SCSIStat: Although the Protocol: Another problem that some developers had with SCSI on the Quadra computers was related
to their not following the SCSI specification on protocol. The Target is in control of the bus and
all the driver does is call the appropriate routines in the correct order. If you depend on these
routines being synchronous and providing feedback as they are being called, then your product had
problems on the Quadra computers. On the Quadra models, the SCSI operations are queued up until
the It is very important to follow the SCSI specification. Patches: If your products patch any part of the SCSI Manager at this time, be aware that the SCSI Manager is soon going to go through a major overhaul. Your patches may cause problems with the new SCSI Manager, so keep an eye out for all documentation that Apple generates on the SCSI Manager. If you feel that you may need some advance warning about the new SCSI Manager, then we highly recommend that you contact Apple Evangelism and make sure they understand that you feel you might have problems with the new SCSI Manager and that you would like to receive any documentation they have when it is available. 15. VIAsThere are some third-party products that like to interrogate the VIAs for information about ADB activity or get high-resolution timing from the VIAs. There are other products that use the VIAs to change the interrupt levels of the hardware. Any products that depend on the VIAs in any way are going to have a great deal of trouble in the future as Apple hardware gradually depends less and less on having VIAs. You may have started to see some of the Macintosh computers either eliminating one of the VIAs or emulating the VIAs in a big ASIC. As the hardware continues to evolve, these VIAs will become even less available. 16. Do the Right Thing"WHY ASK WHY," "JUST DO IT" If you need to find out if something is available for your use, then use Gestalt to find out. If Gestalt does not tell you what you need to know, then you may be looking for something that you should not be worrying about. There are some cases where this is not true, but in most cases it is. It is also important that you look for the exact information that you need to know. If you want to know if there is an FPU, then check for that--nothing else will tell you the truth. Last, but not least--when in doubt ask! ReferencesDevices Technical Note "Fear No SCSI" (M.DV.FearNoSCSI) Downloadables
|