It is cute. The main issue (which the creators of the previous PalmOS HLE - "styletap" inevitably found), and that any Wine developer will tell you about at length, is that in any HLE, compatibility as per official API docs is only 10% of the work. The remaining 90% is bug-compatibility. The long tail of that ... it is almost infinite in length.
Eg:
"DmNewHandle()" - seemingly a simple API in PalmOS - will take NULL as first parameter in PalmOS 2.0+, but will not in 1.0+. Applications written for 1.0 will expect entirely different behaviour. PalmOS 2.0+ will detect such applications and offer them that behaviour. This is not documented anywhere.
Or, "TxtPrepFindString()". In PalmOS 3.5 and later its prototype is "UInt16 (const UInt8 * , UInt16, UInt8 * , UInt16)", while in 3.3 and before, it is "void (const UInt8 * , UInt16, UInt8 * )". Once again this is not documented, but each app needs to see what it expected of the API it was compiled with. And unlike Android/iOS there is no per-app manifest indicating which SDK version it was built with.
And: some SysTraps over time were entirely replaced with incompatible functions at the same SysTrap number. PalmOS 2.0 changed PsrClose into SysLibLoad. PalmOS 3.0 changed PsrGetCommand into SndPlaySmf and PsrSendReply into SndCreateMidiList. PalmOS 3.1 changed PsrInit into IntlDispatch. A proper HLE will need to somehow detect OS version the app targets to provide the proper functionality when one of these SysTraps is made... Doable, but not trivial... (When working on RetroFix, I came up with A solution. Since these 4 calls are only reasonable in a certain order, an app is flagged as "1.0 app" if it calls PsrInit. But how to tell that apart from IntlDispatch? IntlDispatch takes a "selector" in D2, and at the time of PalmOS 1.0 SDK, writing the selector into D2 was REQUIRED to be the very preceding instruction to the trap, using a MOVEQ instruction. At the same time, PalmOS ABI will not preserve D2 across calls, so if you are calling an API that does not take a D2-selector, writing D2 would be pointless as it is about to be destroyed. So, I check for a MOVEQ to D2 register in the previous instruction to where the trap is.)
This goes on almost forever. This is why an HLE (of anything, not just PalmOS) is a project with no"completion date.
Plus MotionApps Classic is technically also HLE. Plus Garnet VM for ARM, which may be the same anyway. Apparently HLE of PalmOS is reasonably easy for the initial 99% of apps at least, since we do have a number of "successful" implementations already.
Not sure if anyone really cares about the 1% of appls which wouldn't work on OS5 anyway.
Eg:
"DmNewHandle()" - seemingly a simple API in PalmOS - will take NULL as first parameter in PalmOS 2.0+, but will not in 1.0+. Applications written for 1.0 will expect entirely different behaviour. PalmOS 2.0+ will detect such applications and offer them that behaviour. This is not documented anywhere.
Or, "TxtPrepFindString()". In PalmOS 3.5 and later its prototype is "UInt16 (const UInt8 * , UInt16, UInt8 * , UInt16)", while in 3.3 and before, it is "void (const UInt8 * , UInt16, UInt8 * )". Once again this is not documented, but each app needs to see what it expected of the API it was compiled with. And unlike Android/iOS there is no per-app manifest indicating which SDK version it was built with.
And: some SysTraps over time were entirely replaced with incompatible functions at the same SysTrap number. PalmOS 2.0 changed PsrClose into SysLibLoad. PalmOS 3.0 changed PsrGetCommand into SndPlaySmf and PsrSendReply into SndCreateMidiList. PalmOS 3.1 changed PsrInit into IntlDispatch. A proper HLE will need to somehow detect OS version the app targets to provide the proper functionality when one of these SysTraps is made... Doable, but not trivial... (When working on RetroFix, I came up with A solution. Since these 4 calls are only reasonable in a certain order, an app is flagged as "1.0 app" if it calls PsrInit. But how to tell that apart from IntlDispatch? IntlDispatch takes a "selector" in D2, and at the time of PalmOS 1.0 SDK, writing the selector into D2 was REQUIRED to be the very preceding instruction to the trap, using a MOVEQ instruction. At the same time, PalmOS ABI will not preserve D2 across calls, so if you are calling an API that does not take a D2-selector, writing D2 would be pointless as it is about to be destroyed. So, I check for a MOVEQ to D2 register in the previous instruction to where the trap is.)
This goes on almost forever. This is why an HLE (of anything, not just PalmOS) is a project with no"completion date.