THINK Pascal & CodeWarrior Pascal
Steve Makohin, Water's
Edge Software
June 1997
by Steve Makohin
Water's Edge Software
2441 Lakeshore Rd., West #70022
Oakville, Ontario, Canada, L6L 6M9
Section 1 - Comparing THINK Pascal to CodeWarrior Pascal
Section 2 - Migrating To CodeWarrior Pascal
Water's Edge Software, creators of Tools Plus, has extensive experience using CodeWarrior
compilers (C/C++/Pascal for 680x0 & PPC). We originally came from a THINK Pascal
background and we've spent a lot of time with CW Pascal specifically, so we can make
a fare comparison between the two. Here are our thoughts:
THINK Pascal: 230 secs CW Pascal...: 162 secs (42% faster)
THINK Pascal: 132,818 bytes CW Pascal...: 142,583 bytes (7% larger)
If you are thinking about making the transition from THINK Pascal to CodeWarrior,
or if you want to use THINK Pascal for your 68K work and CodeWarrior for your PowerPC
work and have both use the same source code, here are the areas when you need to
be aware of the differences:
Uses Controls, Dialogs, Fonts, Lists, Menus, Packages, Processes, QuickDraw, Resources, SegLoad, TextEdit, ToolUtils, Windows;
Fortunately, CW also lets you turn on "Used Propagation" so you can have all these items listed once in your application's "globals" unit which in turn will be used by each unit in your project.
NOTE: If your source code must be compiled by both THINK Pascal and CW, you'll want to take a different approach:
{$IFC THINK_Pascal}
{$ENDC}
You will put all your "unifying" code between these brackets. THINK Pascal will now understand how to use the new Universal Pascal Interfaces without actually having to deal with the complexities of true UPI's in THINK Pascal.
Function GetControlValue (theControl: ControlRef): SInt16;
inline $A960;
This lets you use the new routine names found in the new Universal Pascal Interfaces while continuing to use the original (and simpler) Apple interfaces with THINK Pascal. The inline code maps the new routine name to the original traps in the toolbox. The net result is that the old routines are available with the new names found in the Universal Pascal Interfaces.
SetClikLoop(@myProc, hTE);
@myProc is simply a pointer to a Pascal routine. When using the new UPIs, they take PowerPC differences into account, and with a PowerPC, it is possible to call a routine that is made of either 68K or PowerPC native executable code. The caller has to know this, so PowerPC introduces the Mixed Mode Manager.
When using the UPIs, you have to create something called a Universal Procedure Pointer (UPP). When compiled into 680x0 code, it is nothing more than a pointer to the routine, just like it has been in the past. When compiled into PowerPC native code, creating a UPP actually allocates a structure that tells the calling routine what kind of code it will call (68K or PowerPC) and how the parameters are passed.
Remember that on PowerPC, a UPP is an _allocated_ _structure_ that points to a routine. It's not just a pointer. The same UPP can be used throughout your application, so it's a smart idea to allocate the UPP only once early in your app, then use that one UPP throughout your app as required. Here's the code you can use to allocate the UPP early in your app:
{$IFC THINK_Pascal}
DragProcPtr := @myProc;
{$ELSEC}
DragProcPtr := NewTEClickLoopProc(@myProc);
{$ENDC}
Later, you can use the DragProcPtr as follows:
{$IFC THINK_Pascal}
SetClikLoop(DragProcPtr, hTE);
{$ELSEC}
TESetClickLoop(DragProcPtr, hTE);
{$ENDC}
If you ever need to deallocate the UPP so save memory, use the following code:
{$IFC NOT THINK_Pascal}
DisposeRoutineDescriptor(DragProcPtr);
{$ENDC}
InitGraf(@qd.thePort); InitFonts; InitWindows; InitMenus; TEInit; InitDialogs(nil); MaxApplZone;
By default, this is done automatically in THINK Pascal. If your code must run on both THINK Pascal and CW, write your main program as follows:
{$IFC THINK_Pascal}
{Don't do automatic toolbox initialization}
{$I-}
{$ENDC}
BEGIN
{$IFC THINK_Pascal}
InitGraf(thePort);
{$ELSEC}
InitGraf(@qd.thePort);
{$ENDC}
InitFonts;
InitWindows;
InitMenus;
TEInit;
InitDialogs(nil);
MaxApplZone;
If you are using Tools Plus, you can skip the InitGraf through MaxApplZone code by including initMacToolbox in the Spec parameter of Tools Plus' InitToolsPlus routine.
for x := 1 to 12 do MoreMasters;
IF SectRect(ButtonRect, Bounds, IntersectingRect) and EqualRect(ButtonRect, IntersectingRect) THEN
EqualRect depends on a correct answer from SectRect being evaluated first. In CW Pascal, you must use short circuit evaluation to guarantee a correct left-to-right evaluation, such as:
IF SectRect(ButtonRect, Bounds, IntersectingRect) & EqualRect(ButtonRect, IntersectingRect) THEN
| Water's Edge Software | Voice: 1-416-219-5628 |
| 2441 Lakeshore Rd. West #70022 | Fax: 1-905-847-1638 |
| Oakville, Ontario | Internet: WaterEdg@interlog.com |
| Canada, L6L 6M9 | CIS: 73424,2507 |
|
|
|