TweetFollow Us on Twitter

Feb 02 Cover Story

Volume Number: 18 (2002)
Issue Number: 02
Column Tag: Palm Development

Palm OS for Mac OS Programmers

by Erik Sea

Similarities make Palm development natural to Mac programmers

So You Want to Program a Handheld...

I can remember the first time I saw an Apple //c, I had to have one. I must have used that machine more than any other at the time, despite the fact that the monitor weighed as much as a neutron star. Then, when I saw the PowerBook 170, I stood in line to get one of those as well. Newtons held some promise, but died on the vine before they had a chance to take off. Smaller (or at least lighter) PowerBooks have made their way through my collection, will continue to do so as long as they keep getting better (hard though that is to image). So, since a Palm OS device can do so much less than a PowerBook, why would I need a Palm? More importantly why would a Mac programmer want to program a Palm?

There is something intrinsically attractive about computing power that you can carry around with you. Now, my PowerBook G4 is a great device (I'm writing this article on it), but it doesn't go everywhere I go. The Palm can (actually, right now I carry around a Kyocera SmartPhone 6035 that runs Palm OS - see Figure 1). It's not a question of "switching" from Mac to Palm - the Palm is handy for quick, mobile access to data, but the Mac is better for creation and other "heavy lifting" tasks.


Figure 1. Kyocera SmartPhone running Palm OS.

So, I still do work on both. And thankfully for the would-be Palm programmer, there are a lot more similarities between the Mac and the Palm than you might realize (particularly if you're a veteran 68k programmer). Even more delightfully, the preferred development environment is a Mac! Of course, you can use Windows too, if you really want to...

Let's start with a sampling of what the Palm OS looks like from a runtime and API perspective, before we start talking about tools.

Palm OS Inside Out

One of the first things to realize about Palm Powered devices is that they aren't computers. Well, technically, they are computers, but this isn't a miniature laptop, and shouldn't be thought of like one. Palm has deliberately not tried to put versions of all the familiar desktop applications into its devices, and the OS is not designed to support feature-bloated wordprocessors or complex spreadsheets. In fact, lacking a keyboard by default, Palm devices are not well suited for intensive data entry; rather, they are intended for use as data retrievers.

Fundamentally, there are architectural differences because you use a Palm differently from the way you use a Mac. You can think of a Mac (or other desktop if you must) as an authoring device on which you create your data, and the Palm as the device you download that data to so that you can have it with you wherever you go.

The best way to get your head around what environment you've got to work with on a Palm is to think of the Macintosh of just over a decade ago.

You remember the 68000, right?

The original Macintosh was powered by a 68000 chip, and until the adoption of the PowerPC different Motorola 68k chips ran every Mac (and also the Lisa!). As luck would have it, the first Palm devices had a variation of the 68000 - the 68328 - as its processing core. Despite the different digits at the end, if you know 680x0 assembly language, then you know the 68328 and its architecture for the most part.

For the curious, the 68328 (also called a DragonBall) is more than just a processor - it has a number of built in peripherals, including a serial port, LCD controller, and real-time clock. Subsequent Palm OS devices from various manufacturers have featured newer chips, such as the 68EZ328 (DragonBall EZ) and the 68VZ328 (DragonBall VZ). Longer-term, Palm has announced a long-range plan to migrate its OS to the ARM RISC chip architecture - mirroring the Mac migration to PowerPC several years ago. History tends to repeat itself!

Getting and handle on memory?

Your classic Macintosh memory model consists of Pointers, which are fixed in memory, and Handles, which can be relocated to avoid memory fragmentation. Palm OS has the same ideas, and the same terminology, however, the Handles are "opaque" - they can be converted in to usable pointers only by locking them (which you probably ought to be doing anyway on the Mac), rather than by a simple deference (you don't need to know how handles are really implemented, and you shouldn't care):

MemHandle      aHandle   = NULL;
MemPtr            aPtr         = NULL;

aHandle = MemHandleNew (kSomeSizeInBytes);
aPtr = MemHandleLock (aHandle);
// Use aPtr...
(void) MemHandleUnlock (aHandle);
// aPtr is not guaranteed to still be good at this point...
(void) MemHandleFree (aHandle);

Another thing you'll notice from the above code snippet is that, in Palm OS, all calls are prefixed with the name of the manager to which the call belongs. For example, "Mem" prefixes memory manager calls, "Frm" prefixes form manager calls, and "Srm" prefixes serial manager calls. In this way, not only can you tell what header to look for the prototype, but the names tend to follow a predictable pattern, without need for contortions in the global API namespace. The same sort of conventions are followed for constants. Errors are assigned ranges by manager such that the first byte determines the manager "owning" the error, and the last byte determines the specific error within that manager (you really want to read these in Hex). Cool, no?

Palm OS also shares another legacy with Mac OS. Some of you may recall that the original Macintosh was based on a 24-bit addresses (because that's all the original 68000 chip had). This limited the amount of memory that a Mac could use, until "32-bit clean" versions of the ROM and OS shipped ('round about System 7 time). The reason this limitation persisted was that, as an optimization, the "unused" 8 bits of the address were used to track things such as whether or not a handle was locked, and so on. Because of this, Macs were limited to 8 MB for a long time. For similar reasons, the Palm OS through the present version, 4.0, is limited to 24 bits of address space, although the use of the remaining 8 bits is somewhat different and not quite so limiting, and a Palm device can have 16 MB of RAM (and more space for other storage, including ROM).

One user application at a time?

On a Palm device, you run on application at a time (actually, different tasks and processes can be launched into the background, including user applications, but we'll get to that in a moment). Does this sound like the Mac before the advent of MultiFinder? Users never actually quit the front application - they just perform an action that causes another application to launch: after all, why should one have to quit and then launch when launching with an implied quit achieves the same result in half as many steps?

You can, however, do multiple things with a Palm device at the same time, like (on devices with the appropriate hardware or add-on sleds or cards or modules or sticks or...) play music while you download your email and view pictures. There can, however, only be one process that interacts with the user running at a given time (this is called the HI Task) - but with a screen small enough to fit on a portable device, you probably don't want multiple applications cluttering up precious real estate anyway. Just know that your application might be asked to run in the background under some circumstances, and that has implications for what you can and cannot do.

Interprocess events, globals and shared memory?

One thing you'll see in a Palm program is that, unlike on the Mac (and most other places), your main routine can get called under different circumstances and with different parameters (I suppose that's like a command line interface). In fact, your main routine can even be re-entered under some circumstances: for example, if the user does a "Find" while you application is run, you will get reentered to do the Find without your main routine having a chance to exit.

However, if you start to think of these parameters as somewhat like Apple events, but without a separate handler mechanism, it doesn't seem quite so strange - it's just a simplified single-channel means of interprocess communication (although in most cases, communication is from the OS - much like the standard event suite on the Mac).

These parameters can ask your application to do all sorts of useful things. Or, you can send these launch codes to system applications, preference panels (which are actually just applications of a special class) or other applications you know about. It's generally OK if you don't handle most of these launch codes when you start developing your application, but study the sample applications that Palm provides and you'll get an idea of how you can use them and which ones it's important to support. The first of these parameters, or launch codes, determines what the other parameters mean. See Table 1 for a partial listing (any listing is going to be partial - new codes are added regularly).

SysAppLaunchCmdNormalLaunch a normal launch (nothing special)
SysAppLaunchCmdFind launch in the background to find a
string
SysAppLaunchCmdGo To launch and open a specific record
SysAppLaunchCmdSyncNotify notification that one of the
applications databases has changed
during HotSync
SysAppLaunchCmdTimeChange sent when the system time has
changed!
SysAppLaunchCmdSystemReset sent on a hard reset or a soft reset so
the application can validate its
databases or do whatever other
initialization it wants.
SysAppLaunchCmdSaveData sent to the foreground application
before a Find event (because a find
event might result in the user
launching another application)
SysAppLaunchCmdInitDatabase sent to an application when a
database with the same creator code
is created
SysAppLaunchCmdCustomBase all values above 0x8000 are available
for your application-specific use

Table 1 - Application Launch Codes

Not all is bliss in this world, however. Launches with some launch codes don't provide you with access to your global data, so you'll need to be creative above getting at it.

Palm OS, like the Macintosh 68k runtime architecture before it, sets up global data for the foreground application using offsets on register A5. Since all applications run in the same memory space, and some of these launch codes are sent to your application when it's not the foreground app, in those cases A5 will be for the other application, and not yours. You can get around this by saving your data elsewhere, or, if you know you've got a valid A5, you can save and restore it (this is not always as easy as it sounds - remember, your application quits when another one runs, so the next time you run you'll probably get a completely new A5).

The good news is that, although memory is shared, it's pretty hard to wipe out somebody else's data - there is protection of database memory, and pretty much everything on the Palm OS, except the heap, is in databases which have restrictions on how you can access them. Even applications are databases. The moral is that you should store important data in databases, rather than caching it in changeable memory. Database access is just about as fast as memory access, so there's not really a need for optimization.

Where do applications, files, and databases live?

One of the pretty interesting things about a Palm device is that there really is no file system to speak of (well, technically, OS 4.0 added a file system complete with VFS abstraction layer, and some devices had one before that, but the basic operational model is still one of no file system at all and we'll ignore the 4.0 file system for this discussion). Applications are stored in addressable memory, and they run from that memory in place. Unlike conventional systems, there is no copying of applications and data from disk or other secondary storage to memory and back for a program to run. This simplifies the OS dramatically, and makes applications launch very quickly.

Addressable memory isn't necessarily "RAM" though. As discussed earlier, present-day Palm devices can have up to 16 MB of RAM, but they can also have up to 16 MB of ROM (in most cases, this is flash ROM of some sort), and all of it's addressable at the same time. The OS and most built in applications live in ROM, and they run directly from this ROM space. See Figure 2.


Figure 2. Typical Palm OS Memory Map.

On a Palm device, RAM is preserved at all costs - user data and installed applications live in RAM, and even under reset (except for a "hard" reset which restores a device to factory configuration), the contents of RAM are preserved. It is a common misconception that applications get installed into Flash ROM in order to be persistent - this is not the case. If the user runs down their battery, they lose their installed applications and their data (which is why users are encouraged to HotSync their devices frequently, in order to keep a backup in case they forget to charge their device for a couple of weeks!)

Some details: application code segments are limited to 64K in size (for reasons similar to the 32K limit on the 68k Mac), but you can build multi-segment applications to get around that limit. Palm applications, though, tend to be quite small - think about how much simpler a program could be if it could still manipulate data but didn't need any knowledge of a file system!

Of course, as mentioned above, on OS 4.0 (and selected earlier devices), there is a file system for dealing with various expansion media. Interestingly, since the Palm evolved a programming model without a file system, the question of file names and forks never arose except in some contexts, so the designers were free to invent some new ideas - although at least the building blocks should look familiar.

How does my application get "found" if it's not a file?

A good question. Without a file system, it was necessary to divide memory into logical units which could be accessed in a reliable way. These units are called "databases", and every application is a database, and the data which an application processes lives in one or more databases too. Even the system preferences are stored as records in a database.

These databases do have names, and the names need to be unique, but there's another concept here that should be familiar to Mac programmers: databases have four character creator codes and four character types. Application databases are of type ‘appl', for example. Creators are registered for your own use (sound familiar?). Now, there are some additional properties of creators on a Palm device that you haven't seen on a Mac - if you remove an application with a specific creator code, then all databases with that creator code will be removed. (Now, don't you wish that the Mac had some reliable means of tidying up the preferences folder?) The down side of this is that all means all - if you have multiple applications with the same creator, all of them will be removed when one is removed (but maybe you've developed a multi-application package and want that to happen as some sort of "uninstall"?)

How do I localize my application?

Once you start looking at the various pieces that make up these databases, you'll notice another familiar component: databases are divided into resources, which are identified by integers and four character codes. The user interface resources can thus be localized independently of the code. In OS 4.0, there is even a system of "overlays" whereby it is possible to have the localizable code for multiple different languages stored in different databases from the code, and let the system switch between them at runtime. However, since memory is precious, this particular technique is generally only useful for the ROM of the shipped product.

Palm OS does not, however, have the idea of separate resource forks and data forks, primarily because there were no files, just databases. If anything, you can think of Palm OS as only having resource forks, and when databases are backed up to desktop computers, those resource forks are just peculiarly formatted files stored in the data fork, avoiding the whole multiple fork issue for the most part (except during development, but that's getting ahead of ourselves).

What if I need to change some part of the OS?

With the 68k architecture comes the whole idea of A-trap exception handling, which the original Mac used to implement the operating system - and so does a Palm device. No, the traps will be different numbers, but you've got the ability to patch traps if you really need to, just like on the Mac.

However, I would caution you not to do this. You'll probably break under future versions of the OS, and you could break on different devices that have various background processes which run periodically. Unlike on the Mac (or, just like the original Mac or a Mac OS Extension), when you patch a Palm trap, you patch it globally.

The good news about patching is that, because the OS was written with a single runtime, there is no funky confusion of Pascal and C calling conventions to deal with. There are some places where parameters are in registers, but that's not usually needed (and you can always revert to writing assembly glue).

Palm OS also has Extensions and Shared Libraries for customizing and plugging in to various parts of the OS, but as these are fairly specialized I won't go into them here.

How do I handle user events?

Event handling is a bit different in Palm OS than Mac OS, but the good news is that Palm OS event processing is somewhat similar to the Mac's new Carbon event model. Every form (as the basic HI elements of a Palm screen are called - this is really the contents of a window and not the window itself) has its own handler, and events are passed to that handler which can either process them or let the system handle them. If the system handles them, an action could occur, or the event might be requeued as a more specific event. For example, a pen down event might change to a control select event which might be translate to a control change value event and so on.

OK, what about all those special Palm OS features?

Sure, there probably are no Mac equivalents to things like Beaming (transmission over Infrared or maybe Bluetooth) or synchronization with a desktop (HotSync). The good news is that many applications don't need to do anything to work within these environments - your application will be beamable, and your application and its databases will be backed up by HotSync without you doing anything. You do need to do work to beam records back and forth between instances of your application on two different devices, but that is relatively well documented and you should be able to just modify an example.

If you need to be able to have your data reformatted for sharing with a desktop application, you'll need to delve into the area of HotSync Conduits, which are pieces of code that live on the desktop and are linked to Palm-based databases by creator code. You'll need to write conduits for each desktop platform you plan to support, and it can become a fairly involved process.

It is far more important, at least initially, to realize that you're not writing a desktop application than it is to try to take advantage of all of these features. Your screen is 160 pixels square on most devices (some devices provide a bit more real estate, or even high resolution 320 pixels on a side), and on some devices the physical dimensions are really quite tiny. Consider that your application might be used in a jostling car, or in poor light conditions. Also, the pen you tap with does not move a cursor around like a mouse does (except, conceptually, in the case of a stroke), so that does change what you might be used to in terms of interface behavior. Read some of the books on Palm programming, and study design decisions in sample applications!

This sounds almost too good to be true?

It's not. Sure, there are some differences, and if you do work on both platforms you'll find yourself forgetting what those differences are at inconvenient times, but that is mostly because the systems are so very similar.

The Palm and the Mac evolved under similar circumstances: limited processing power and memory, and the need to make do with less. It is not surprising that the solutions to these problems were so similar (particularly with the model of the Mac's evolution to follow and in some cases improve on). Why reinvent the wheel? Why indeed. And the same can be said for development tools.

Tools

As a Mac programmer, you've probably played with CodeWarrior. You might even have written a PowerPlant application and used MetroWerks Constructor. And, at some level, you've probably played with Macsbug. So, these first 3 tools should look like old friends.

MetroWerks CodeWarrior for Palm OS!

The same 68k compiler as provided for the Mac, plus a number of extra plugins and tools give you a very familiar application development environment. The MetroWerks source level debugger allows you to step through code as it is executed on a device connected over a serial link, or you can dispense with the device and run your application on the Palm OS Emulator (discussed shortly).

In order to take advantage of as many existing tools as possible, you can create .rsrc files using tools like Constructor and ResEdit to edit resources, and the linker itself generates code resources which all get merged into an output file. You can also write resources in .r files and compile them with PalmRez, very much like the .r files native to Mac development.

That output file, though, is just a temporary file and requires some post processing to put it into "Palm" format (usually a "prc" file if an application), and that is done using the PalmRez Post Linker. The panel for this conversion tool is one of the ones where you need to make some changes almost immediately when you start a new project or else things won't work quite right. The most important thing is to fill in or change the database name - this is the name of the database that is your application, and it must be unique on the device. A common convention is to include the creator code (which should also be unique and registered, as discussed earlier). See Figure 3 for the PalmRez Post Linker panel.


Figure 3. PalmRez Post Linker settings.

Other settings are pretty self-explanatory - the first editable text field ("Mac Resource Files") is the name of the temporary output file that was specified in the "68K Target" panel (in this case, "Starter.tmp"), and the final output file is in the third editable text field (here, "Starter.prc"). The various checkboxes are pretty well explained by balloon help.

Demo or limited versions of CodeWarrior for Palm OS come with several of the Palm programming books which you can buy. MetroWerks CodeWarrior for Palm OS is a completely separate product from the Mac and Windows (and embedded systems) versions and, although you probably could merge tools and create a hybrid development environment, chances are you've already got more than one Mac version of CodeWarrior installed in order to handle separate projects, so why not just keep the Palm version(s) separate as well?

Constructor for Palm OS!

Originally developed for PowerPlant on the Mac, Constructor was easily modified to support the forms needed for the Palm OS user interface. If you've worked with PowerPlant, you will find Palm OS Constructor familiar in functionality, but of course all of the objects and components are pretty different.

The main project resource window in Figure 4 has a number of important settings you'll want to play around with. "Application Icon Name", is the user-displayed name that shows up in the Palm OS launcher with all the other applications. You can also use constructor to generate headers with relevant constants for these forms, which can be quite handy for maintenance.


Figure 4. Palm OS Constructor resource file.

The various data types in the resource file have specific editors; you'll find the menu editors quite familiar (of course, there are no key equivalents, but there are Grafitti shortcut equivalents). Figure 5 shows a blank form, ready for controls to be deposited on it.


Figure 5. Empty Form window ready for edit.

When you finally decide to put items on the form, you can select from the Catalog window, much as you do in Constructor for PowerPlant, except the selection of items is much smaller, as can be seen in Figure 6.


Figure 6. Palm OS Constructor available items.

Palm OS Debugger!

Once you've built a Palm OS application, you'll probably need to debug it. Most of the time, you should be able to make do with the source-level debugger built into CodeWarrior, but sometimes such as after a bad crash you'll need lower level tools. In steps the Palm OS Debugger, which comes up with three windows: Registers, Debugger, and Console. Usually, you'll type commands into the Debugger window, but another set of commands can be typed into the Console window. Some commands work both places.

The easy way to see what commands are available, is to type "Help". After typing a command, you must hit "Enter", and not "Return" - this should make you feel like you're using MPW again, just like the old days. For reference, the commands available from the Debugger window are shown in Listing 1, and from the Console window, Listing 2.

Flow Control Commands
  att                               ;Attach to Remote
  g [<addr>]                        ;Go
  gt <addr>                         ;Go Till
  s                                 ;Step Into
  t                                 ;Step Over
  br <addr>                         ;Set Breakpoint
  cl [<addr>]  -or- brc [<addr>]    ;Clear Breakpoint(s)
  brd                               ;Display Breakpoints
  atb [<”funcName”> | <A-trap #>]   ;Set A-Trap break
  atc [<”funcName”> | <A-trap #>]   ;Clear A-Trap break
  atd                               ;Display A-Trap breakpoints
  dx                                ;Turn DbgBreaks on/off
  reset                             ;Reset the Pilot

Memory Commands
  il [<addr> [<lineCount>]]         ;Instruction List
  dm <addr> [<count>] [<template>]  ;Display Memory
  db <addr> <value>                 ;Display UInt8
  dw <addr> <value>                 ;Display UInt16
  dl <addr> <value>                 ;Display Int32
  sb <addr> <value>                 ;Set UInt8
  sw <addr> <value>                 ;Set UInt16
  sl <addr> <value>                 ;Set Int32
  fill <addr> <nbytes> <value>      ;Fill Memory
  fb <value> <addr> <nbytes> <\flags>   ;Find UInt8
  fw <value> <addr> <nbytes> <\flags>   ;Find UInt16
  fl <value> <addr> <nbytes> <\flags>   ;Find Int32
  ft <text>  <addr> <nbytes> <\flags>   ;Find Text
  sc6 [<addr> [<frames>]]           ;Stack Crawl A6
  sc                                ;Alias for sc6
  sc7 [<addr> [<frames>]]           ;Stack Crawl A7
  wh [<”funcName”> | <A-trap #> | \a <address>]    ;Where is routine
  atr <”funcName”> <A-trap #>       ;Register routine name with an A-trap number

Template Commands
  typedef <template> [@...]<”name”> [<[elts]>]      ;Indirect template definition
  typedef struct <”name”>                           ;Begin structure definition block
  > <template> [@...]<”name”> [<[elts]>] [\-]       ;Field definition
  typeend                                             ;End structure definition block
  sizeof <template>                                 ;Display template size

Register Commands
  reg                               ;Display all Registers

Utility Commands
  load <"filename"> <addr>          ;Load File Data Fork from Host into RAM
  save <”filename”> <addr> <bytes>  ;save RAM to file on Host
  bootstrap <”filename”> <addr>     ;Load & execute image using EZ bootstrap mode
  flash <”filename”> <addr>         ;Load File Data Fork from Host into FLASH memory
  run <”filename”>                  ;Execute a Pilot Debugger script
  alias <”name”> [<”text”>]         ;Define/list an alias
  var <”name”> [<initializer>]      ;Define a variable
  aliases                           ;List all alias names
  templates                         ;List all template names
  variables                         ;List all variable names
  keywords                          ;List all keywords

Console Commands
  CardInfo <cardNo>                 ;Display memory card information
  StoreInfo <cardNo>                ;Display memory store information
  HL <cardNo>                       ;Heap List
  HD <heapID> [\c]                  ;Heap Dump
  HT <heapID> [\c]                  ;Heap Total
  HChk <heapID> [\c]                ;Heap Check
  Info <chunkPtr>                   ;Display chunk information
  Info <localID> \card <cardNo>     ;Display chunk information
  Dir <cardNo> [<options>]          ;Display database directory
  Opened                            ;List open databases

Miscellaneous Debugger Commands
  help                              ;Display a summary of debugger commands
  {help <cmd>} | {<cmd> ?}          ;Display debugger command help
  ?                                 ;Abbreviation for the help command
  penv                              ;Display debugger Environment Information

Debugger Environment Variables:
  DebOut                            ;debugger-debug style output enabeld(true/false)
  SymbolsOn                         ;disassembly symbol printing enabled(true/false)
  StepRegs                          ;show registers after every step
  ReadMemHack                       ;read memory hack enabled(true/false)

Predefined Constants:
  true                              ;integer value 1
  false                             ;integer value 0
  srTmask                           ;status reg Trace bit
  srSmask                           ;status reg Supervisor bit
  srImask                           ;status reg Interrupt field mask
  srXmask                           ;status reg eXtend bit
  srNmask                           ;status reg Negative bit
  srZmask                           ;status reg Zero bit
  srVmask                           ;status reg oVerflow bit
  srCmask                           ;status reg Carry bit

Listing 1 - Palm OS Debugger "Debugger" commands

= Heap Utilities ==============
HeapList
HeapInitialize
HeapDump
HT
HC
HChk
HTorture
HS
HF

= Chunk Utilities =============
New
Free
Lock
Unlock
Info
Resize
SetOwner

= Database Utilities ==========
Import
Importall
Export
Exportall
Create
Del
Dir
Open
Close
Opened
SetInfo

= Record Utilities ============
AttachRecord
DetachRecord
AddRecord
DelRecord
ChangeRecord
ListRecords
SetRecordInfo
MoveRecord
FindRecord

= Resource  Utilities =========
GetResource
ListResources
SetResourceInfo
AttachResource
DetachResource
AddResource
DelResource
ChangeResource

= Card Info ===================
CardFormat
CardInfo
StoreInfo

= System ======================
Reset
Doze
Sleep
Performance
Exit
PowerOn
ColdBoot
Launch
Switch
Battery
Ping
Feature
KInfo

= Debugging  Utilities ========
DM
SB
MDebug

= Miscellaneous Utilities =====
SimSync
SysAlarmDump

= Host Control=================
Log
Help

= Gremlins Commands =================
Gremlin
GremlinOff
Help

Listing 2 - Palm OS Debugger "Console" commands

If you've played with Macsbug much, a lot of these commands should look pretty familiar - not surprising given that Macsbug came from Motorola (the "Mac" part is a coincidental acronym). Typing "sc" produces a stack crawl as you might expect; here's one I generated by dropping into the debugger while I had the Find dialog open:

Current UI App stack: size = #4560
Calling chain using A6 Links:
 A6 Frame   Frame Size     Caller
 0003C6C6   #0000003292   10D06562  __Startup__+00D0
 0003C69A   #0000000044   10D06DC4  PilotMain+00F4
 0003C66A   #0000000048   10D0E08C  EventLoop+01A8
 0003C612   #0000000088   10C10B4A  SysHandleEvent+0014
 0003C5FE   #0000000020   10C11370  
 0003C500   #0000000254   10C67574  Find+00C2
 0003C4B4   #0000000076   10C61460  FrmDoDialog+0080
 0003C46E   #0000000070   10C61104  PrvHandleModalEvent+0042
 0003C454   #0000000026   10C10B4A  SysHandleEvent+0014
 0003C440   #0000000020   10C1151C  

Another handy trick is that (remembering Figure 2), the addresses in ROM normally start at 1, and the RAM addresses start with 0.

The command "il" similarly produces an instruction list from the point where you entered the debugger:

10C1151C  *MOVEQ.L   #$01,D0                | 7001 
10C1151E   BRA.W     *+$0402    ; 10C11920  | 6000 0400 
10C11522   TST.B     D3                     | 4A03 
10C11524   BEQ.S     *+$0006    ; 10C1152A  | 6704 
10C11526   _SysLaunchConsole    ; $10C1020A | 4E4F A0BE 
10C1152A   MOVEQ.L   #$01,D0                | 7001 
10C1152C   BRA.W     *+$03F4    ; 10C11920  | 6000 03F2 
10C11530   TST.B     D3                     | 4A03 
10C11532   BEQ.S     *+$0016    ; 10C11548  | 6714 
10C11534   MOVE.B    #$1E,-(A7) ; ‘.'       | 1F3C 001E 

And the very useful "hd 0" command produces a heap display quite like that of Macsbug (see Listing 3).

Displaying Heap ID: 0000, mapped to 00001B00, first free: 00002736
                             req    act   lck                       resType/  #resID/
 start    MemHandle localID  size   size  cnt own flags type  index attr ctg  uniqueID name
——————————————————————————————————————————————
*00001E38 00001B14 00001B15 000010 000018  #1  #0    fM DmOpenRef: ‘System'
*00001E50 00001B18 00001B19 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘System'
*00001E7C 00001B1C 00001B1D 00013C 000144  #1  #0    fM MemHandle Table: ‘System'
*00001FC0 00001B20 00001B21 000010 000018  #1  #0    fM DmOpenRef: ‘System_enUS'
*00001FD8 00001B24 00001B25 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘System_enUS'
*00002004 00001B28 00001B29 000284 00028C  #1  #0    fM MemHandle Table: ‘System_enUS'
*00002290 00001B2C 00001B2D 000010 000018  #1  #0    fM DmOpenRef: ‘Latin Locale Module'
*000022A8 00001B30 00001B31 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘Latin Locale Module'
*000022D4 00001B48 00001B49 000010 000018  #1  #0    fM DmOpenRef: ‘Latin Locale Module_enUS'
-000022EC 00001B38 00001B39 000022 00002A  #0  #0    fM Alarm Table
*00002316 00001B34 00001B35 000074 00007C  #1  #0    fM MemHandle Table: ‘Latin Locale Module'
*00002392 00001B4C 00001B4D 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘Latin Locale Module_enUS'
*000023BE 00001B50 00001B51 000014 00001C  #1  #0    fM MemHandle Table: ‘Latin Locale Module_enUS'
-000023DA 00001B3C 00001B3D 0002EA 0002F2  #0  #0    fM Notify Manager Globals (SysNotifyGlobalsType)
*000026CC 00001B68 00001B69 000010 000018  #1  #0    fM DmOpenRef: ‘Launcher'
*000026E4 00001B5C 00001B5D 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘Launcher'
-00002710 00001B40 00001B41 00001E 000026  #0  #0    fM DataMgr Protect List (DmProtectEntryPtr*)
 00002736 ———— 00002736 000000 000008  #0  #0    FM —> 00003BDE
*0000273E 00001B58 00001B59 000038 000040  #1  #0    fM App Globals: UI Shell
-0000277E 00001B6C 00001B6D 000456 00045E  #0  #1    fM Graffiti Private
*00002BDC 00001B44 00001B45 000030 000038  #1  #0    fM MemHandle Table: ‘Launcher'
*00002C14 00001B64 00001B65 000010 000018  #1  #0    fM DmOpenRef: ‘Launcher_enUS'
*00002C2C 00001B70 00001B71 000024 00002C  #1  #0    fM DmOpenInfoPtr: ‘Launcher_enUS'
*00002C58 00001B54 00001B55 00015C 000164  #1  #0    fM MemHandle Table: ‘Launcher_enUS'
*00002DBC 00001B60 00001B61 000900 000908  #1  #0    fM App Globals: Current UI App
*000036C4 00001B84 00001B85 0003A4 0003AC  #1  #2    fM Form "1:08 am"
*00003A70 00001B80 00001B81 0000EE 0000F6  #1  #2    fM Form "Find"
*00003B66 00001B74 00001B75 000028 000030  #1  #2    fM UI: Window (160x64)
*00003B96 00001B88 00001B89 000010 000018  #1  #2    fM
*00003BAE 00001B78 00001B79 000028 000030  #1  #2    fM UI: Window (2x11)
 00003BDE ———— 00003BDE 034E78 034E80  #0  #0    FM —> 0003955E
•00038A5E ———— 00038A5E 000AF8 000B00 #15  #2    fm UI: Bitmap (160x64x8) for window 3B66
 0003955E ———— 0003955E 001CE2 001CEA  #0  #0    FM —> 00040004
•0003B248 ———— 0003B248 000026 00002E #15  #2    fm UI: Bitmap (2x11x8) for window 3BAE
•0003B276 ———— 0003B276 000200 000208 #15  #0    fm Serial Manager receive buffer
•0003B47E ———— 0003B47E 00007C 000084 #15  #0    fm Serial Manager open port (SrmOpenPortType)
•0003B502 ———— 0003B502 0011D0 0011D8 #15  #0    fm Stack: Current UI App
•0003C6DA ———— 0003C6DA 00003C 000044 #15  #0    fm SysAppInfoPtr: Current UI App
•0003C71E ———— 0003C71E 000020 000028 #15  #0    fm
•0003C746 ———— 0003C746 000586 00058E #15  #0    fm Bluetooth Exchange Library globals
•0003CCD4 ———— 0003CCD4 000018 000020 #15  #0    fm
•0003CCF4 ———— 0003CCF4 00003E 000046 #15  #1    fm BtTransport H4 globals
•0003CD3A ———— 0003CD3A 000016 000022 #15  #0    fm Serial Manager driver data (DrvrPrivateGlobs)
•0003CD5C ———— 0003CD5C 000020 000028 #15  #0    fm
•0003CD84 ———— 0003CD84 000074 00007C #15  #1    fm Graffiti Glue Globals (GrfGlobalsType)
•0003CE00 ———— 0003CE00 0007D0 0007D8 #15  #0    fm Stack: UI Shell
•0003D5D8 ———— 0003D5D8 00003C 000044 #15  #0    fm SysAppInfoPtr: UI Shell
•0003D61C ———— 0003D61C 00003A 000042 #15  #0    fm Attention Mgr Globals
•0003D65E ———— 0003D65E 000168 000170 #15  #0    fm UI: Color table stack
•0003D7CE ———— 0003D7CE 000064 00006C #15  #0    fm UI: Undo buffer
•0003D83A ———— 0003D83A 000118 000120 #15  #0    fm UI: Event Queue
•0003D95A ———— 0003D95A 00000C 000014 #15  #0    fm Shortcuts Library globals
•0003D96E ———— 0003D96E 000004 00000C #15  #0    fm Application defined sub-font list
•0003D97A ———— 0003D97A 000010 000018 #15  #0    fm UI: AppFontTable
•0003D992 ———— 0003D992 000020 000028 #15  #0    fm UI: SysFontTable
•0003D9BA ———— 0003D9BA 000006 00000E #15  #0    fm Net.lib globals
•0003D9C8 ———— 0003D9C8 000028 000030 #15  #0    fm IrDA Library globals
•0003D9F8 ———— 0003D9F8 00000E 000016 #15  #0    fm ExgLocal Library-locl globals
•0003DA0E ———— 0003DA0E 00001A 000022 #15  #0    fm Sound Manager Globals (SndGlobalsType)
•0003DA30 ———— 0003DA30 000024 00002C #15  #0    fm Key Manager Globals (KeyGlobalsType)
•0003DA5C ———— 0003DA5C 000040 000048 #15  #0    fm Keyboard Queue (KeyQueueType)
•0003DAA4 ———— 0003DAA4 000100 000108 #15  #0    fm Pen Queue (PenQueueType)
•0003DBAC ———— 0003DBAC 000028 000030 #15  #0    fm System Event Manager Globals (SysEvtMgrGlobalsType)
•0003DBDC ———— 0003DBDC 000200 000208 #15  #0    fm Screen Driver: color translation table (8-bit)
•0003DDE4 ———— 0003DDE4 000020 000028 #15  #0    fm Screen Driver: color translation table (4-bit)
•0003DE0C ———— 0003DE0C 000008 000010 #15  #0    fm Screen Driver: color translation table (2-bit)
•0003DE1C ———— 0003DE1C 000004 00000C #15  #0    fm Screen Driver: color translation table (1-bit)
•0003DE28 ———— 0003DE28 0000A0 0000A8 #15  #0    fm UI: Draw state stack
•0003DED0 ———— 0003DED0 000028 000030 #15  #0    fm UI: Window (160x160)
•0003DF00 ———— 0003DF00 0000B2 0000BA #15  #0    fm Screen Driver: row pattern buffer
•0003DFBA ———— 0003DFBA 0000B2 0000BA #15  #0    fm Screen Driver: expanded scan line
•0003E074 ———— 0003E074 0004C4 0004CC #15  #0    fm Screen Driver Globals (ScrGlobalsType)
•0003E540 ———— 0003E540 000039 000042 #15  #0    fm Interrupt Handler Notifications Queue
•0003E582 ———— 0003E582 000092 00009A #15  #0    fm Int'l Mgr Globals (Variable - IntlGlobalsType)
•0003E61C ———— 0003E61C 00002C 000034 #15  #0    fm Pen Manager Globals (PenGlobalsType)
•0003E650 ———— 0003E650 000009 000012 #15  #0    fm Serial Manager port description: "Infrared"
•0003E662 ———— 0003E662 000007 000010 #15  #0    fm Serial Manager port description: "Serial"
•0003E672 ———— 0003E672 00007E 000086 #15  #0    fm Serial Globals (SerGlobalsType or SrmGlobalsType)
•0003E6F8 ———— 0003E6F8 000010 000018 #15  #0    fm Alarm Manager Globals (AlmGlobalsType)
•0003E710 ———— 0003E710 000018 000020 #15  #0    fm Time Manager Globals (TimGlobalsType)
•0003E730 ———— 0003E730 001748 001750 #15  #0    fm Kernel Globals
•0003FE80 ———— 0003FE80 00003C 000044 #15  #0    fm SysAppInfoPtr: AMX
•0003FEC4 ———— 0003FEC4 000030 000038 #15  #0    fm Battery Data (SysBatteryDataStruct)
•0003FEFC ———— 0003FEFC 000038 000040 #15  #0    fm PowerMgr globals
•0003FF3C ———— 0003FF3C 0000C0 0000C8 #15  #0    fm System Library Table

Heap Summary: 
  flags:              2000
  size:               03E500
  numHandles:         #200 
  Free Chunks:        #3      (036B72 bytes)
  Movable Chunks:     #29     (001D9E bytes)
  Non-Movable Chunks: #53     (0058BC bytes)
  Owner  0:           0060F2 bytes
  Owner  1:           000520 bytes
  Owner  2:           001048 bytes

  Unlabeled System Chunks: #3   

Listing 3 - Output of command "hd 0"

Palm OS Emulator!

With the tools already discussed, you have enough to do everything you need. But wait, there is one tool that is so useful, you should be aware of it, and that is the Palm OS Emulator (usually called "POSE" or "POSER"). This tool takes a Palm ROM file (obtainable from the Palm OS developer site mentioned in the "For More Information" section) and allows you to simulate a Palm device on your Mac, as shown in Figure 7. You can even use the CodeWarrior debugger, and the Palm OS debugger with POSE.


Figure 7. Palm OS Emulator "POSE".

Why would you want to use POSE rather than a real device? Well, you probably should use a real device for at least some of your development/testing, because POSE simply will not simulate a device perfectly. However, during initial development, it is much more convenient to be able to compile and run an application in the emulator than it is to compile an app, HotSync it to a device, and then run it. You can "install" files in the emulator, too, just by dragging them to the window.

But in addition to mere convenience, POSE also provides additional parameter checking on API calls before passing them to the ROM, and many problems or potential problems can be detected that way. To top it off, POSE provides a psuedorandomized test method called "Gremlins" which can be used to stress an application or group of applications. You can create a "Hoarde" of Gremlins and leave it run for hours or days at a time. And, by using the same seeds (the "Range" in Figure 8), you can run the exact same test repeatedly (provided you reset POSE so that all initial conditions are the same).


Figure 8. POSE Gremlin test window.

You May Already be A Palm OS Programmer

So, as you can see, if you're a Mac programmer you already have a distinct advantage should you want to start programming Palm Powered devices. And, since you can do it all with tools you know, and do it on your favorite computer, why wouldn't you? Although there is an effort to maintain tool parity, Palm OS itself is developed and built on Macintoshes.

More pragmatically, many people believe that the handheld market is going to exceed the size of the desktop computer market in the coming years, and since Palm OS currently holds nearly 90% of that market, learning Palm OS is a good investment or skill diversification. And, it's fun.

I'd like to thank Chris Simmons, Linus Anderson, and Paul McLellan for taking the time to provide input and suggestions on this article.

For More Information

  • http://www.palmos.com/dev/ is the Web site for Palm OS developers - download agreement to get access to various developer tools, including ROM image files for use with POSE. You can also obtain Debug ROMs, which have a lot more error checking which may be useful in development.
  • http://www.fatbrain.com/palmdeveloper/ has Palm OS documentation available in printed form.
  • Palm Programming: The Developer's Guide, 1999 by Neil Rhodes and Julie McKeehan, is one of the first, and most broad-ranging Palm OS books written. This edition is a bit dated (based on Palm OS 3.0), but it provides good coverage and is still pretty relevant. It includes a demo version of MetroWerks CodeWarrior for Palm.

Erik is a long-time Mac programmer who recently joined Palm Inc., where he is a project manager working with Palm OS licensees. He lives in Zephyr Cove, Nevada, where he trains Bluetooth-equipped slinkys to form ad-hoc wireless piconets with stranded skiers and then feed them brandy. You can reach Erik at sea@acm.org.

 

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.