Dec 98 Tips
Volume Number: 14 (1998)
Issue Number: 12
Column Tag: Tips & Tidbits
Dec 98 Tips & Tidbits
by Jeff Clites, tips@mactech.com
WideAdd and WideSubtract Under 68K
If you use the PowerPC "wide arithmetic" routines WideAdd and WideSubtract (say to measure time intervals using the Microseconds() call) then you'll find that your code won't compile for 68K any more. Fortunately, this is easy to fix. The following code declares WideAdd and WideSubtract routines for 68K. They are extremely efficient to use because they generate inline 68K instructions, so using them doesn't even involve a function call.
#if __MC68K__
#pragma parameter WideAddInline(__A0, __A1)
local void WideAddInline(unsigned long *target_low_word,
const unsigned long *source_low_word)
THREEWORDINLINE(0x2011, 0xD190, 0xD189);
// move.l (a1),d0 add.l d0,(a0) addx.l -(a1),-(a0)
#define WideAdd(target, source) \
WideAddInline(&(target)->lo, &(source)->lo)
#pragma parameter WideSubtractInline(__A0, __A1)
local void WideSubtractInline(unsigned long
*target_low_word, const unsigned long *source_low_word)
THREEWORDINLINE(0x2011, 0x9190, 0x9189);
// move.l (a1),d0 sub.l d0,(a0) subx.l -(a1),-(a0)
#define WideSubtract(target, source) \
WideSubtractInline(&(target)->lo, &(source)->lo)
#endif
The three-word 68K inline routines first add the least significant words together (or subtract them), and then do and add with carry (or subtract) on the most significant words to get the final answer. Because 68K byte order stores the low word last, the actual routines WideAdd and WideSubtract are declared as macros which first calculate the addresses of the low words of the "Wide" parameters, and then pass those addresses to the inline routines that do the actual work. The end result of this is that you can use WideAdd and WideSubtract just the same as you do in your PPC code, without any source code changes:
WideSubtract(&target, &source);
Stuart Cheshire
cheshire@cs.stanford.edu
File Filters Under Navigation Services
There is one subtle, but important, difference between NavGetFile() and its Standard File equivalent-namely that NavGetFile() with a non-nil typeList only shows files matching the specified creator code! For example, if you include 'TEXT' in your typeList, along with your creator code, and expect NavGetFile() to show all text files, you'd be mistaken-you would only see those you created. The only easy way I know of around this is to dispense with the typeList, and do all file selection in your filter routine, something like this:
static pascal Boolean FilterTypes
(
AEDesc *TheItem,
void *info,
void *callBackUD,
NavFilterModes filterMode
)
/* file filter routine for Navigation Services that allows acceptance
of all text files, regardless of creator. */
{
Boolean IncludeIt;
NavFileOrFolderInfo * TheInfo = (NavFileOrFolderInfo*)info;
If (theItem->descriptorType != typeFSS){IncludeIt = true;}
else if (TheInfo->isFolder) {IncludeIt = true;}
else
{
IncludeIt =
(TheInfo->fileAndFolder.fileInfo.finderInfo.fdType
== 'TEXT');
}
return IncludeIt;
}
Note that the filter routine passes through all folders. My first attempt was mistakenly returning false for all folders, which not only was wrong, it also caused Navigation Services to crash. Also, don't forget to pass the routine to NavGetFile() using a routing descriptor rather than a raw function pointer, and to dispose of this routine descriptor using DisposeRoutineDescriptor() when you are finished with it:
NavObjectFilterUPP filterProc =
NewNavObjectFilterProc(FilterTypes);
Lawrence D'Oliveiro
ldo@geek-central.gen.nz