It looked like an m505, because it was built in an m505 case. But while an m505 was a common-at-the-time Palm device with a 160x160 display, this one was special. I had in my hands a device that was used at Palm to develop the High-Density API. This API is best known for supporting 320x320 screens of the PalmOS 5 devices, but in reality it was also supported in PalmOS 4. As the last device in the m500 family was the low-resolution m515, and this high-resolution device never shipped (or was even intended to ship), i called this one "m520".
Devices that shipped with PalmOS4 and High Density API are the Tungsten W and the Acer s65. The High Density API is documented in the PalmOS reference and further in the include files in the SDK. The first version of the High Density API is available in version 4 of the Window Manager. The device I had in front of me was wearing the skin of a Palm m505, bit it had a 320x320 screen. All the icons were low-resolution and upscaled, so the only thing the betrayed the device's high resolution was the text rendering - it was smooth and used the real screen resolution. The device was labeled using a permanent marker: "FONTS", so I suspect that it was used for development and testing of high-density fonts. Loading applications with High Density icons proves that basic High Density image drawing also works - the launcher successfully draws High Density icons.
However, most applications I loaded crashed or malfunctioned randomly. I spent some time investigating, and found something very interesting. What this device is, is sort of a missing-link between the final High Density API and the low-resolution devices that preceded it.
The High Density API on PalmOS4 is exposed via a single SysTrap - sysTrapHighDensityDispatch (0xA3EC). It takes a selector in d2 register that specifies the actual function to perform. As documented, the first version of the High Density API has the following functions with the following selectors:
The later "1.5 density feature set" (which could in theory be used on a 68k pre-PalmOS5 device, but never existed) added two more:
The WinScreenGetAttribute function itself takes a selector for what attribute is to be returned. The offical API defined the following attributes:
Given that the High Density API was misbehaving, it made sence to look at its implementation. In PalmOS 5+, the High Density API is simply part of the OS, but in PalmOS 4, it is a separate extension, contained in HighDensityDisplay.prc. This extension patches a large number of system functions to enable the High Density display to be used. I disasembled it, and found some interesting things. The API it exported was also called via sysTrapHighDensityDispatch, but the selectors were not the same. Here are the supported selectors on this device:
In addition, the selectors supported for WinScreenGetAttribute were:
The cool part is that this shows how the High Density API developed. This pre-release state seems like it is complete and usable. One can manage High Density bitmaps, scale coordinates, and change coordinate systems. It seems like it is enough. I imagine this was slated for release, until some internal developers tried to actually use it. They likely ran into a few issues. First: it is common in PalmOS development to generate bitmaps from raw data. One would normally use BmpCreate() for this. But such a bitmap will always, for backwards-compatibility, be a version two bitmap - always low-density. There is nothing in this API to create a version 3 bitmap (required to represent a High Density bitmap). Clearly something was needed. I imagine this is how BmpCreateBitmapV3() was born. Why was it added into the middle of the table? Well that I do not know, especially given that the other added API were added at the end. I suspect that it was only after BmpCreateBitmapV3() was added that the result was deemed to be the first version "stable enough to release". After this, only additions to the end of the table were possible, as there were likely already internal users of the new API. I suspect that density and pixel format selectors for WinScreenGetAttribute() were added around the same time as BmpCreateBitmapV3(), before the first "stable enough to release" API version. I guess that WinScaleCoord(), WinUnscaleCoord() were added as convenience utilities - they are simply a multiply/divide operation with rounding so they aren't mandatory. I guess WinPaintRoundedRectangleFrame() was a late addition, by someone's request, since WinDrawRectangleFrame() has a thickness limit of 2 pixels, which is very thin on a High Density display in High Density mode.
Clearly, this current code on this device is not binarily-compatible with any PalmOS software expecting to use the documented API. For example, an application attempting to call BmpCreateBitmapV3() would call sysTrapHighDensityDispatch with a selector of 0x07. On this device, that would be a call to WinSetCoordinateSystem(). The chances that the top 16 bits of a bitmap pointer (first parameter to BmpCreateBitmapV3()) are a valid density for a call to WinSetCoordinateSystem() are small, so WinSetCoordinateSystem() will just return the current coordinate system, which will be 72 or 144. Due to a peculiarity of the calling convention used by PalmOS, integers are returned in the d0 register, while pointers are returned in the a0 register. That means that the return value of WinSetCoordinateSystem() will not even be seen, and whatever garbage was left over in a0 will be seen as the return value by the calling application, after what it thought was a call to BmpCreateBitmapV3(). Treating random garbage as a Bitmap pointer is unlikely to end well. Any other function call past selector 7 will suffer the same fate. Any calls to WinScreenGetAttribute() with a selector value over 5 would also produce nonsense. Luckily almost nobody ever used WinScreenGetAttribute(). The existing code on the device did call the APIs correctly for this device, of course.
I wanted to allow normal High Density-supporting software to run on this device. But how? The dispatcher is at the very start of the code resource (important) and looks like this:
Well, I could just add a jump between the jumps to BmpSetTransparentValue and WinSetCoordinateSystem, append some code to the code resource, and thus implement BmpCreateBitmapV3(). With that, the ordering of all the calls will be correct and likely most applications will work. I did not add the additional selectors past EvtGetPenNative(), nor did I change WinScreenGetAttribute() at all. Even with this simple plan, it was actually a bit of a pain, binary-patching the code resource, but it worked. I reassembled the ROM using some tools I had made for rePalm, and it worked on the emulator.
Wait, what emulator? Indeed the conventional PalmOS emulator (POSE) does not support this device. But I was able to convince Christian Speckner (the author of CloudPilot - a web port and improvement on POSE) to support the device. Given the ROM and some time, it worked! You can actually load the ROM unto CloudPilot now and emulate it! This helped immensely with the testing. After some tweaking, the ROM booted with my patched HighDensityDisplay.prc and some applications ran. Many did not.
PalmOS devices divide the RAM into storage heap (where user data lives) and dynamic heap (where temporary allocations are made from). Typically in PalmOS 4, just under 1/16 of the RAM is allocated to dynamic heap, up to a max of 256K. The issue is that in devices with High Density, all images are 4x the size, so the dynamic heap would need to be bigger to avoid running out of memory quickly. As this device was an early development unit, this was not done, and it had a woefully-undersized dynamic heap. I patched BigHal.prc to adjust the heap to 1MB, and most things worked fully. Sweet. With emulator testing completed, it was time to flash the real device. The image works on the device (as you can see in the photo album). Since only one such device exists, modifying its ROM was a tough call. To make sure the stock ROM is never lost, I compressed it, and left it as a database in the new ROM. Now it can be recovered and flashed back at will.
If you'd like to play with this device in emulation, you can download both the stock and my ROMs here: [LINK]. If you'd like to see some pictures of the device inside and out, here is a photo album: [LINK]