firstly, i apologize if a lot of this email is above the head of most
developers.

the contents of this email contains lots of un-documented features which
palmsource definately do not support. most of the information is available
all over the web - i can say in advance that we are doing stuff non-official.

On 1/14/07, Dmitry Grinberg <[EMAIL PROTECTED]> wrote:
> calling FrmSetDIAPolicyAttr() via PACE on a Tungsten|T3 with the DIA
> compatibility prc's installed gives the unit a FATAL EXCEPTION

strange, works fine for me.
i do it roughly like this to get it to work on all devices:

PceGet68KTrapHandler()
..write data to stack
handler();
..remove data from stack

it confused me originally at first - because; i have used PACE callbacks
from the very beginning of PACE native development (4+ years now).
the difference between then and now; is really the main event loop.

garnet was designed to allow users to run small pieces of ARM code
from within their 68k application. most developers still use this principle;
that is, have a 68k application that calls PceNativeCall() only when they
need some ARM code to be executed.

most of their UI code is 68k.

in our case; we've scrapped that idea - because running in 68K and
switching to ARM all the time creates overhead and really messy code.
so; our applications contain a small 68k stub that basically does:

result = errNone;
if (PACE_LoadArmResource(&armlet, &GOT))
 result = PceNativeCall((void *)armlet, (void *)GOT);
PACE_UnloadArmResource();

its 1372 bytes in size; which is responsible for loading the ARM code
and validating that everything is where it should be and that we are on
the right device.

the armlet itself is:

uint32
EntryPoint(const void *emustate, void *user, Call68KFuncType *call68K)
{
 uint32 result;

 // default return value
 result = 0;

 // we need to initialize a few things
 GOT = (void *)user;

 // initalize global variables
 g = (GlobalsType *)malloc(sizeof(GlobalsType));
 if (g != NULL)
 {
   memset(g, 0, sizeof(GlobalsType));

   // we may need these if we have to use PACE for something
   g -> PACE._68k = (void *)call68K;
   g -> PACE._emu = (void *)emustate;

   // run the application - direct link to previous application code
   result = PilotMain(sysAppLaunchCmdNormalLaunch, (void *)NULL, 0);

   // clean up globals variables
   free(g);
 }

 return result;
}

PilotMain()? yes. at this point we are in ARM and you have something
that looks similar to your old 68k code. we did this to minimize messing
around to moving to cobalt; but, that obviously fell through.

point is; the application truely starts in the PACE native code.

we ONLY need to call PACE if we do not know the r9 based lookup entry
in the rom itself - to date; for the purposes that i have needed there are
two sets of API's which i have needed which are not concrete in all versions
of devices running palmos 5.0+

A) SndStream API (officially introduced in 5.2)
B) PINS API (officially introduced in 5.3)

some devices have been put on the market and provide support for these
two API's via shared libraries or last minute hacks (T|T for SndStream).
either way; you cannot use r9 tables to call them, you have to use PACE.

for the SndStream stuff, we need to make some detections:

----
g_snd_stream_defined   = false;
g_snd_stream_available = false;

// check for sound manager feature
err = FtrGet(sysFileCSoundMgr, sndFtrIDVersion, &version);
g_snd_stream_available |= (err == errNone);

// Sony NX/NZ/TG: shipped with 5.0
// --> support http://www.aibohack.com/clie/modclieaud.htm
// Palm T|T:      shipped with 5.0
// --> support http://kb.palmsource.com/ .. p_faqid=378
g_snd_stream_available |= ((g -> ftr.comID == 'Palm') &&
                          (g -> ftr.devID == 'Frg1'));

// SndStream* are OS 5.1+ API (r9 table) must use PACE for 5.0
g -> PACE.snd_api = g_snd_stream_available &&
                   ((g -> ftr.osVer & 0xfff00000) == 0x05000000);
----

so. if is 5.0 g -> PACE.snd_api is set to true, otherwise false.
this means that any device that isn't 5.2+ needs to have the API's
available as a shared library.

when it comes to calling the appropriate API:

// create the stream
if (g -> PACE.snd_api)
 err = SndStreamCreate_PACE(&g_snd_stream_ref, sndOutput,
                           s_rate, s_format, s_mode, (void *)DAL_SndThread,
                           (void *)g -> snd, frames, true);
else
     err = SndStreamCreate(&g_snd_stream_ref, sndOutput,
                           s_rate, s_format, s_mode, (void *)DAL_SndThread,
                           (void *)g -> snd, frames, true);

there is a PACE version and there is a version of the API which is effectively
an r9 table entry stub. this works fine on every device i've tested on - and,
that includes those devices that use the 3rd party SndStream* API hacks.

now; with the T3 and FrmSetDIAPolicyAttr - it gives FATAL EXCEPTION.
the same code; on a Tapwave Zodiac (also 5.0) doesn't complain at all.

now; the PACE callback looks like this (without the macros')

UInt8 params[] =
{
   (((UInt32)(formP) >> 24) & 0xff),
   (((UInt32)(formP) >> 16) & 0xff),
   (((UInt32)(formP) >> 8) & 0xff),
   ( (UInt32)(formP) & 0xff),

   (((UInt16)(diaPolicy) >> 8) & 0xff),
   ( (UInt16)(diaPolicy) & 0xff),
};

((EmulStateType *)g -> PACE._emu) -> regD[2] = 14;
result = (Err)((Call68KFuncType *)g -> PACE._68k)
 ((void *)g -> PACE._emu,
  (0xA470 & (0x00000FFF)), &params, sizeof(params) | (0));

the FrmSetDIAPolicyAttr is a selector based callback - riding of the D2
register; many API's share the same trap number (0xA470).

dimitry; how does this differ from the manner in which you make the API
call? you mention PceGet68KTrapHandler, thats something that obviously
isn't officially public :)

i see an entry for:

extern Err PceGet68KTrapHandler(EmulStateRef emulState, UInt32 trapNumber,
                Pseudo68KCallAddrProcPtr *procPP);

in the mobile-stream SDK headers; can you give an example of it being used?
of course; PceGet68KTrapHandler() is an ARM only routine; in addition to
its appropriate r9 table reference.

you seem to be bypassing the offical way to call 68K from ARM directly -
which is why it may work. the manner in which palmsource expects us to
call it (as above); may actually be broken for FrmSetDIAPolicyAttr on a T3

--
// Aaron Ardiri

--
For information on using the PalmSource Developer Forums, or to unsubscribe, 
please see http://www.palmos.com/dev/support/forums/

Reply via email to